Help with AND statement

rfeyer

Active Member
Hello all,
 
am working with another board and new code.
 
Before giving specifics, can anyone tell me if the AND can combine two statements?
 
i.e.:  TSTEQ CH 8 AND TSTEQ CM 30
 
Is that possible?
 
Rainer
 
No, each PLC command can only stay in its own line.  You can not have more than one in the same line.
You can code your logic in another way to get same result
 
TSTNE CH 8
GOTO NOMATCH
TSTNE CM 30
GOTO NOMATCH
....
 
NOMATCH:
...
 
AND and ANDB are logical operators on the whole value or bitwise.  They must stay on its own line of PLC code.
 
TY CIA support
 
another code basics question:
 
at the below code, since as I understand code continues to cycle through, would somesub be continuously called?
 
==
START
  CALLSUB SOMESUB
END
 
SUMSUB:
 SET OP1[1000] 1
 SET OP1[1000] 0
 RET
 
Yes, according the CAI documentation.
 
I prefer to do my loop in easy to understand code and I trust it to work.
Code:
START
LOOP:
  CALLSUB SOMESUB
  GOTO LOOP
END

SUMSUB:
 SET OP1[1000] 1
 SET OP1[1000] 0
 RET
 
That is fine, too.  PLC will GOTO LOOP and repeat that way.
This has one advantage, if you have some initialization code, it can be placed between "START" and "LOOP;"
 
TY both - that really helps!
I am having a difficult time with the continuous inherent loop of the program, and trying to figure out what gets repeated and when - I think a lot has to do with Zero bit, which I still don't understand but will continue reading.
 
Much appreciated!
 
Rainer
 
Zerobit is set in most operations to indicate the result of last operation.  0 means false, 1 means true. TSTxy, AND, OR, etc all set that value for next PLC command to reference if needed. In addition, certain operation will set ZEROBIT to 0, like I2CWRITE to indicate the targeted device exist pulled I2C bus lower.
If your PLC code doesn't need that, you don't have to worry about it.
 
Here.
Try something like this simple loop. You should be able to watch your LED as a debug indicator to use anywhere you want to prove the program counter walked though that spot in your code.
 
First, go to the "general Setup" page and put something like 50 into UROM1
Second cut and paste the program into the "Program Page" box and hit Send.
You can change UROM1 value while you watch the LED and it is running.
 
Play with it. Change the DELAYs, variables and watch your on board LED to verify it is doing what you think it should.
Keep adding stuff to experiment. You can't hurt it.
 
Soon you will be writing code that will do things for you. Keep reading the manual with the OPCODES and try different ones to prove what you think they mean.
Code:
START  
INIT:  
        DELAY 5000
	SET RAM2 UROM1  
FLASH:
	SETLED 0   
	DELAY 50   
	SETLED 1   
	DELAY 50   
	DEC RAM2     #This instruction sets the zero bit   
	BNZ  FLASH   #This instruction uses the zero bit, the rest do not care what it is
        GOTO INIT 
END
 
And TY to both of you again!
 
As the ZeroBit is concerned - my confusion is here: anything changes the value of Zerobit - essentially all set commands. So, why use the Zerobit instead of using RAM or UROM values? It appears to me very difficult to trace Zerobit's value?
 
As for sample codes in manual - I keep reading the 10 samples and have already written a delay type code sequence earlier in the year; I am now trying to get away from delay so I don't stop the program progression.
Also, I really do not understand the BNZ Flash:  -  I understand that DEC RAM2 would set ZeroBit to 1 (I assume), and, since RAM2 is changed, BNZ would be true, so, the program would Loop up to Flash again and it will go in continuum. Am I understanding this correctly?

However, Larry, I absolutely appreciate the little snippet, and, did not know that I can manipulate the on board LED with SETLED - that REALLY helps with program progression testing.

Is there a listing of additional programming codes?
 
Rainer
 
If you have need to track ZEROBIT, you can set a bit value in RAM1, so that each bit representing a state. However, in most case, ZEROBIT is for next instruction to know what was last state. With PLC code executes many thousands line repeatedly each second, it is impossible to track all that value change in even a short period of time.  However, it does provide important information for PLC logic to determine what to do next, if it needs to be known.
 
To avoid blocking delay, you can put [] on input value, output value, and VAR value change, that way, you don't block anything executing, let WC kernel track those time for you on state change.
 
To avoid delays and distribute WEBSET Ethernet traffic congestion I wote a timeslicing dispatch main routine.
 
This may be quite complicated for newbies but the code is fairly repetitive for each segment.
 
 
 
Subroutines can be called each exact second. This is necessary to integrate time from my anemometer pulses.
The flags used are a little complicated to get your head wrapped around. They are "job done: flags to eliminate the subroutines from repetitively running during each full second's timeslice.
 
Up to 15 (UROM1) timeslices can be impleented
Code:
Resources used:
	UROM1 = user set sample time in seconds, should be divisible into 60, recommend 5,6,10,12, or 15
	UROM2 = deadband, +/- value change (in counts) for transmission update, recommend 3
	UROM3 = scaling factor to correct humidity sensor probe input as temperature, set 174
	UROM4 = forced transmission update period in minutes, must be divisible into 60, recommend set 15 

	RAM1B1-RAM1B6 = 1 bit flags to avoid repeating Tx during each time slice
	RAM1B7 = 1 bit flag signifies to force value Tx regardless of no change

	RAM2-RAM3 = scratchpad for speed scaling and averaging calcs.
		
---------------------------------
START    
	SET RAM2 20  
FLASH:
	SETLED 0     # flash LED to indicate a reboot to local watcher
	DELAY 50   
	SETLED 1   
	DELAY 50   
	DEC RAM2   
	BNZ  FLASH  

	SETLED 0   
	DELAY 1000   
	WEBSET URL1 -1  # tells my ISY it rebooted.
	DELAY 1000   
MAINRESET:
	SET COUNTER 0  

MAINLOOP:    
	GOTO SEND_ALL      # only allows two labels to exist right after another
SEND_ALL:                  # label used for description only
	MOD CM UROM4 RAM2  # check for every UROM4 minutes
	BNZ RAM2 SEND_DUN  # nope = bypass this
	TSTGE CS UROM1     # in the first UROM1 seconds?
	GOTO SEND_DUN      # nope = bypass this
	SET RAM1B7 1       # set the force sends flag
	GOTO SEC0   
SEND_DUN:
	SET RAM1B7 0       # clear the force sends flag
SEC0:
	MOD CS UROM1 RAM2 # RAM2 carries the remainder of Current Second / 15 seconds
	TSTNE RAM2 0      # is timeslice 0 ?
	GOTO SEC0_DUN     # nope = bypass
	BNZ RAM1B1 SEC1   # not the first time here this slice = bypass
	CALLSUB CLOCK1   
	SET RAM1B1 1      # mark it done
	GOTO MAINLOOP   
SEC0_DUN:
	SET RAM1B1 0      # mark it not done for next time slice comes
SEC1:                     # timeslice 1
	TSTNE RAM2 1  
	GOTO SEC1_DUN   
	BNZ RAM1B2 SEC2  
	CALLSUB GUST8   
	SET RAM1B2 1  
	GOTO MAINLOOP     # always start again as RAM2 may be ruined in subroutine
SEC1_DUN:
	SET RAM1B2 0  
SEC2:
	TSTNE RAM2 2  
	GOTO SEC2_DUN   
	BNZ RAM1B3 SEC3  
	CALLSUB OUTEMP2   
	SET RAM1B3 1  
	GOTO MAINLOOP   
SEC2_DUN:
	SET RAM1B3 0  
SEC3:
	TSTNE RAM2 3  
	GOTO SEC3_DUN   
	BNZ RAM1B4 SEC4  
	CALLSUB HUMID5   
	CALLSUB INTEMP6   
	SET RAM1B4 1  
	GOTO MAINLOOP   
SEC3_DUN:
	SET RAM1B4 0  
SEC4:
	TSTNE RAM2 4  
	GOTO SEC4_DUN   
	BNZ RAM1B5 RESET_TIM  
	CALLSUB WIND7   
	SET RAM1B5 1  
	GOTO MAINLOOP   
SEC4_DUN:
	SET RAM1B5 0  
RESET_TIM:
	BNZ CH RESET_DUN    # is hour 0?
	BNZ CM RESET_DUN    # is miunute 0?
	BNZ CS RESET_DUN    # is second 0?
	BNZ RAM1B8 RESET_X  # have we been here before = bypass
	SET RAM1B8 1        # flag subroutines to force send
	GOTO MAINRESET   
RESET_DUN:
	SET RAM1B8 0        # clear flag = not (hr = min = sec = 0)
RESET_X:
	GOTO MAINLOOP       # repeat until CPU burns out
 
Ah, getting much closer to understanding - TY both!  Larry - nice program which I partially understand and will use as a training/ learning tool!!
 
One more non-specific question: Are subroutines run even if not called?
 
for instance:
Start
  callsub one
End
 
Callsubone:
  do this
 
Callsub 2:
  do something else
 
 
In the above - would callsub2 be activated even though it has not been run? In the language I am used to it would not, though I have seen several examples on this forum where SUBs are run and I don't see where they are called.
 
And an additional question to the above SUBROUTINE question:
 
I quickly attached a voltmeter to OP8 and ran the following code:
 
START
 CALLSUB CHECKTIMER
END
 
CHECKTIMER:
  SET OP8[2000] 1
RET
 
I EXPECTED THE OP8 TO activate for 2 seconds and then shut off, but instead it activated without shutting off.
Since it is non-blocking, what is the purpose of the time limiter?
 
Back
Top