Help with non-blocking delay

TJF1960

Active Member
Hello,
 
Since non-blocking delay is not available for AIPx I am looking for some guidance in programming.
I have AIP3 monitoring AC mains voltage via a wall wart. The value is of AIP3 is converted to a single digit number (1-4) and added to ram and sent.
 
The programming I have is working very well but I would like to delay the single digits from changing for 5 or 10 seconds.
 
Here is the snippet of code for AIP3
 
 
MOD VAR2 10 RAM1
            TSTLE AIP3 74
            SET RAM1 1
            TSTGE AIP3 75
            SET RAM1 2
            TSTGE AIP3 107
            SET RAM1 3
            TSTGE AIP3 129
            SET RAM1 4 
 
Unfortunately all ram and variables are used for other storage used throughout the program. I thought about using the one OP7 that is not used but non-blocking won’t work the way I want it to.  I have a couple of IPx which are not used, the one OP7 which is not used and the URAM which is not used.
 
Thanks,
Tim
 
Bitwise operator is documented in the user guide:
AND a[] b[] (d[])
Logical AND's a with b and optionally puts Boolean result into d. Zero bit updated.
ANDB a[] b[] (d[])
Bitwise AND's a with b and optionally puts bitwise AND result into d. Zero bit updated.
OR a[] b[] (d[])
Logical OR's a with b and optionally puts Boolean result into d. Zero bit updated.
ORB a[] b[] (d[])
Bitwise OR's a with b and optionally puts bitwise OR result into d. Zero bit updated.
XOR a[] b[] (d[])
Logical XOR's a with b and optionally puts Boolean result into d. Zero bit updated.
XORB a[] b[] (d[])
Bitwise XOR's a with b and optionally puts bitwise result into d. Zero bit updated
 
combined with
ROTL a b c
a: source register, b: number of bits; c: result register rotate to the left, overflow bits will be feed into right
ROTR a b c
a: source register, b: number of bits; c: result register rotate to the right, overflow bits will be feed to the left
 
You can move the bit in a variable.
 
 
 
In short, your RAM1 appears to be limited to 4 values.  That is a 2 bit number.  RAM values are 31 bit max (32nd bit is +/- signage), so you are wasting 29 bits.  If you have other RAM's that are using 29 or fewer bits, you can put the 2 together and free one of them up.
 
Hi Guys,
 
Thank you both for your reply. I for some reason still have a mental block on bitwise usage.
This webcontrol board has a lot of functions and the code I wrote for it was last year, learning as I went. I have a bad feeling that if I tried to implement bitwise now I would probably have to rewrite most all of the code, which I don't want to do right now. But just in case I am making this out to be bigger than it really is perhaps you could provide a simple example of how to use it.
 
Most var's and ram are already 9 digits. I do have a couple of ram that are basically place holders, each have 3 numbers, each digit represents a different function.
ram1 =123
ram2 = 456
 
how can I merge them, freeing up a ram but at the same time be able to update each digit randomly?
 
Thanks,
Tim
 
TJF1960 said:
Hi Guys,
 
Thank you both for your reply. I for some reason still have a mental block on bitwise usage.
This webcontrol board has a lot of functions and the code I wrote for it was last year, learning as I went. I have a bad feeling that if I tried to implement bitwise now I would probably have to rewrite most all of the code, which I don't want to do right now. But just in case I am making this out to be bigger than it really is perhaps you could provide a simple example of how to use it.
 
Most var's and ram are already 9 digits. I do have a couple of ram that are basically place holders, each have 3 numbers, each digit represents a different function.
ram1 =123
ram2 = 456
 
how can I merge them, freeing up a ram but at the same time be able to update each digit randomly?
 
Thanks,
Tim
 
Can you elaborate a bit.  I don't really understand what you are doing.
 
TJF1960 said:
Hi Guys,
 
Thank you both for your reply. I for some reason still have a mental block on bitwise usage.
This webcontrol board has a lot of functions and the code I wrote for it was last year, learning as I went. I have a bad feeling that if I tried to implement bitwise now I would probably have to rewrite most all of the code, which I don't want to do right now. But just in case I am making this out to be bigger than it really is perhaps you could provide a simple example of how to use it.
 
Most var's and ram are already 9 digits. I do have a couple of ram that are basically place holders, each have 3 numbers, each digit represents a different function.
ram1 =123
ram2 = 456
 
how can I merge them, freeing up a ram but at the same time be able to update each digit randomly?
 
Thanks,
Tim
 
When you are using computers, you have to think of numbers as base-2 (binary) not base-10.
 
So open up windows calculator in programmer mode, Dec value, Dword type and type in different base-10 numbers to see how they map to base-2 (shown under the number display).  Now as you can see, different ranges of numbers only require certain bits.  So you can divide the number up into different sections of bits.  Now every time you add a bit the number of possible values doubles.  So for example 3 bits represents 2^3 or 8 distinct values, decimal numbers 0-7.  Bitwise operators make it easy to chop out these different sections of bits and do things to them and then put them back together.
 
So it seems like you are already trying to do something similar to bitwise by having different base-10 decades represent different things but it is much more efficient to do this using base-2 because that is the computer's native format and bitwise operations already exist. 
 
Thank you for the reply. I think Lou is right and I need to post a better example and explanation. This board currently has 8 temp sensors. If the temp is 75.5F the code stores 76F, if it is 75.4 it stores 75F. 3 temp sensors each needed 3 digit space,  which equals 9 digits per ram or variable, which I store in ram until they are sent to webset then they are stored in a variable for future comparison. So the 8 temp sensors require 3 variables currently. If I understand correctly I am storing the temp results as base 10. Will using bitwise allow me to save on ram/var in this example? Sorry, I still am not getting it.
 
Thanks again,
Tim
TEMPTEST:
 ADD T1 5 RAM1
 DIV RAM1 10 RAM1
 MUL RAM1 1000000 RAM1
 ADD T2 5 RAM2
 DIV RAM2 10 RAM2
 MUL RAM2 1000 RAM2
 ADD RAM1 RAM2 RAM3
 ADD T3 5 RAM1
 DIV RAM1 10 RAM1
 ADD RAM3 RAM1 RAM3
 TSTNE RAM3 VAR4
 WEBSET URL4 RAM3
 SET VAR4 RAM3
 ADD T4 5 RAM1
 DIV RAM1 10 RAM1
 MUL RAM1 1000000 RAM1
 ADD T5 5 RAM2
 DIV RAM2 10 RAM2
 MUL RAM2 1000 RAM2
 ADD RAM1 RAM2 RAM3
 ADD T6 5 RAM1
 DIV RAM1 10 RAM1
 ADD RAM3 RAM1 RAM3
 TSTNE RAM3 VAR5
 WEBSET URL5 RAM3
 SET VAR5 RAM3
 MUL AIP1 1000000 RAM1
 ADD T7 5 RAM2
 DIV RAM2 10 RAM2
 MUL RAM2 1000 RAM2
 ADD RAM1 RAM2 RAM3
 ADD T8 5 RAM1
 DIV RAM1 10 RAM1
 ADD RAM3 RAM1 RAM3
 TSTNE RAM3 VAR6
 WEBSET URL6 RAM3
 SET VAR6 RAM3
 GOTO LOOP
 
 
Do you need 1000 possible values for each one (000 to 999)?  For example, if the temp is measuring something that at most goes up and down by 64 degrees, then you only need 6 bits allowing you to store all 8 values on 2 rams (using 24 bits of each).  That still leaves you 7 bits on each of those 2 rams for other uses.
 
And what are your 5 other ram values doing?
 
You are doing the same thing in base 10 that would be more compact in base 2.  In binary you would shift your bits to the left or right using the bitshifting function to get the 6 bits you want at the end, then ANDB it against 0000000000000000000000000111111 (3F in hex or 0x3F as it is coded in PLC) which chops off all but the last 6 bits.
 
TJF1960 said:
Thank you for the reply. I think Lou is right and I need to post a better example and explanation. This board currently has 8 temp sensors. If the temp is 75.5F the code stores 76F, if it is 75.4 it stores 75F. 3 temp sensors each needed 3 digit space,  which equals 9 digits per ram or variable, which I store in ram until they are sent to webset then they are stored in a variable for future comparison. So the 8 temp sensors require 3 variables currently. If I understand correctly I am storing the temp results as base 10. Will using bitwise allow me to save on ram/var in this example? Sorry, I still am not getting it.
 
Thanks again,
Tim
 
You didn't do the windows calculator thing, did you?  :P  Once you stopped thinking of numbers as 10's digits and think of them as bits, then you get it.  Also a lot of binary number tutorials and videos out there on the web.
 
 
Here's an 8 second loop which requires 1-bit storage and I guess you could use an output.  But better to learn about bits and find a free one somewhere else.
 
Code:
START
  ROTR CTS 3 RAM1
  ANDB RAM1 1 RAM1
  XOR RAM1 OP7
  SET OP7 RAM1
  CNZ 8SECLOOP
END

8SECLOOP:
  RET
 
Here's another way to do it with an output:
Code:
START
  AND 1 OP7
  CZ 8SECLOOP
END

8SECLOOP:
  SET OP7[8000] 1
  RET
 
Tim,
 
Do you have any question? If there is any problem, please let us know. We will always happy to help you.  Analog has no non-blocking delay, due to its value is constantly changing.
 
Hi CAI,
 
Thank you for the nudge, no, no problems except for time. I did find a temporary work around for the original question in this post. But I am very intrigued by the use of bitwise and such. So I am, when I can, studying up on binary and shifting bits and usages.
 
az1324,
 
Yes I did pull out the calculator and play with whole numbers to see the binary equivalents. Still trying to let it all sink in. I know it will hit me like a ton of bricks and it will seem all so obvious once it sinks in. Thank you for your help, and thanks for the examples. I coded the first one and of course it works like a charm…I just need to sit down and figure out why though, for myself so I can fully understand what is taking place.  
 
Lou,
 
You helped me a great deal last year on the UDI forums when WEBSET became available. I am still using your examples for collecting and sending data from webcontrol to ISY. All inputs/analog inputs/outputs and temps are being held in 5 variables, 5 ram are keeping track of any changes which haven’t been WEBSET yet, once they are the variables are updated.
I put all the coding together at the time the best I could and without understanding or realizing bitwise might help.
 
All,
Thank you all very much for your help and guidance and I am sorry I didn't post sooner however I was hoping to have something positive to report (like I Finally Got It!) but the old saying cant teach a old dog new tricks is getting in the way. I will though.
Thanks again,
 
Tim
 
Hi Tim,
 
Bitwise is not too hard.  Basically, you decide which bit position represents which state.  Say you have 8 emails, using bit 8-15 to represent them.  You will first get each bit value using scientific mode X^y:
2^8 = 256
2^9 = 512
...
2^15 = 32768
Say you have VAR8 to store the flags, to check email 1 sent or not on bit 8, you can do:
ANDB VAR8 256
You don't have to store the result, since ANDB will update the zero bit.  If you use zero meaning "email not send yet", then
BZ sendmail1
...
BZ will jump to the sendmail1 section code to send email. You could in that
section do a
XOR VAR8 256 VAR8
to update that bit 8 on VAR8.
 
You can use RAM instead of VAR. VAR has one advantage during debugging, you can see on screen then put that value into calculator programmer mode, change the display to binary, you can see immediately which bit is set.
 
You can use CZ instead of BZ for call the subroutine, which will return back to next line of your code after the subroutine finished.
 
I think I am starting to get it now. So as an example, right now I am storing the 8 outputs as whole numbers on say Var1, using bitwise I could store all 8 outputs and all 8 inputs (digital in) on var1 and still have 15 bits to play with?
 
The outputs are either on or off as are the digital inputs. So all of them can be stored using a single bit each. So yes you can store all of them in 16 bits.
 
Back
Top