Bitwise use with AIPx

TJF1960

Active Member
I have bit locations 0-15 in RAM1 used for the 8 inputs and 8 outputs leaving 16 bits for other uses. I have 3 analog inputs but for simplicity lets take one as an example. AIP1 is sampled and the value is converted to a number between 1 and 5. I would like that number to be added to RAM1 using bit locations 16-19.
 
This is what I came up with. I haven't tested it yet but wanted to see what you all thought before I continued on this path. The board is a .16C so it has some of the new commands but not all and I haven't yet decided whether I am going to replace it with a newer board yet or not (a lot of manual labor to replace it).
 
 SET RAM4 0                                                          to clear any previous entries from ram4
 ORB RAM4 0X10000 RAM4                                  to set bit locations 16-19 to 1 so that RAM4 has a value of at least 1 for an end result.
 TSTGE AIP1 3
 ORB RAM4 0X20000 RAM4                                  If true set bit locations 16-19  to 2
 TSTGE AIP1 130
 ORB RAM4 0X30000 RAM4                                  "             "                  "              " 3
 TSTGE AIP1 142
 ORB RAM4 0X40000 RAM4                                  "             "                  "              " 4
 TSTGE AIP1 185
 ORB RAM4 0X50000 RAM4                                  "             "                  "              " 5
 ANDB RAM1 0XFFF0FFFF RAM1                        Clear bit locations 16-19 in RAM1
 ORB RAM4 RAM1 RAM1                                      Set  bit locations 16-19 in RAM1 with result of RAM4
 
I am not 100% sure I explained it right but hopefully it makes sense.
My questions are: Did I approach this in the proper manner? Are there any faults with this approach? Is there an easier or better method?
Any comments or feedback welcome.
 
Thanks,
Tim
 
I think you have a logic problem.
 
Say AIP1 is 190
 
TSTGE AIP1 3
 ORB RAM4 0X20000 RAM4                                  If true set bit locations 16-19  to 2              turns on bit 17  16-19 will be 0010 = 2
 TSTGE AIP1 130
 ORB RAM4 0X30000 RAM4                                  "             "                  "              " 3             turns on bit 16.  Bit 17 is already on, it stays on, that is ok   16-19 will be 0011=3
 TSTGE AIP1 142
 ORB RAM4 0X40000 RAM4                                  "             "                  "              " 4           turns on bit 18, but does not turn off 16 and 17, so bits 16-19 will be 0111 = 7
 TSTGE AIP1 185
 ORB RAM4 0X50000 RAM4                                  "             "                  "              " 5          bits 16, 17, 18 are all on already, this line does nothing.  16-19 will be 0111=7
 
 
Instead try
TSTGE AIP1 142
XORB RAM4 0x70000 RAM4                                  "             "                  "              " 4           toggles bit 16, 17, 18.  So 16 and 17 turn off, 18 turns on. 0100= 4
TSTGE AIP1 185
ORB RAM4 0X50000 RAM4                                  "             "                  "              " 5          turns 16 on, bit 18 is on already and stays on, 16-19 will be 0101=5
 
Just to note you could reduce it to 3 bits.
 
SET RAM4 1
TSTGE AIP1 3
ADD 1 RAM4 RAM4
TSTGE AIP1 130
ADD 1 RAM4 RAM4
TSTGE AIP1 142
ADD 1 RAM4 RAM4
TSTGE AIP1 185
ADD 1 RAM4 RAM4
ROTL RAM4 16 RAM4    or    MUL RAM4 0x10000 RAM4
ANDB RAM1 0XFFF0FFFF RAM1                      
ORB RAM4 RAM1 RAM1
 
I also have to ask, why are using bits 16-19 of RAM4?  Since you are clearing RAM4 to 0 at the start of this, then you could just use regular decimal 1, 2, 3, 4 for RAM4 as az1234 said.  
 
Then you are transfering your result to RAM1.  Except, if RAM1 is not already 0000 at 16-19, you might not be transfering the result since ORB only turns bits on, and if they aren't off to start with, you may get extra ones on.
 
Why don't you just put your result directly into RAM1 in the first place.  But first you need to clear just bits 16-19 in RAM1.  You don't need RAM4 at all.
 
ANDB RAM1 0xFFF0FFFF RAM1  clears 16-19, leaves others unchanged.
 
That is true I suppose.
 
ANDB RAM1 0XFFF0FFFF RAM1
ADD 0x10000 RAM1 RAM1
TSTGE AIP1 3
ADD 0x10000 RAM1 RAM1
TSTGE AIP1 130
ADD 0x10000 RAM1 RAM1
TSTGE AIP1 142
ADD 0x10000 RAM1 RAM1
TSTGE AIP1 185
ADD 0x10000 RAM1 RAM1
 
az1324 said:
Just to note you could reduce it to 3 bits.
 
SET RAM4 1
TSTGE AIP1 3
ADD 1 RAM4 RAM4
TSTGE AIP1 130
ADD 1 RAM4 RAM4
TSTGE AIP1 142
ADD 1 RAM4 RAM4
TSTGE AIP1 185
ADD 1 RAM4 RAM4
ROTL RAM4 16 RAM4    or    MUL RAM4 0x10000 RAM4
ANDB RAM1 0XFFF0FFFF RAM1                      
ORB RAM4 RAM1 RAM1
 
Thanks az1324, I am all for it but the board this is going into doesn't accept ROTL commands. I do have a .17 board to test with but ultimately its going into a .16C board and I haven't yet decided to swap it with a newer board. Also I am trying to keep programming the same (or at least similar) between all my boards which are in use (all .16C) to make changes in the future easier.
 
Lou, "I also have to ask, why are using bits 16-19 of RAM4?"
 
Well, I was trying to put lines down which were in logical (or at least logical in my head). I was using those bits of ram4 because in my mind it would be simple then at the end of the process to orb ram4 to ram1. In other words I wasn't sure how to set ram1 bits 16-19 from ram4 value of say 5.
 
"Why don't you just put your result directly into RAM1 in the first place."
 
The reason I was going this route was because ram1 gets webset every 2 seconds when there is a change in value (only websets once per 2 seconds and only if there is a change in value). I only want AIP1 to update ram1 every 15 seconds or so. So I was using ram4 as a holder til it was 15 seconds. But now that you brought it up I will just have the AIPxx sub run once every 15 seconds instead which will serve the same purpose.
 
Thanks, you guys have given me more to think about and play with, I appreciate all the suggestions!
 
Is there a way for the isy to do the math in 1 program to pull the 3 bit locations and display the result? I have not come up with it yet.
 
If
- No Conditions - (To add one, press 'Schedule' or 'Condition')

Then
​ $Int_56 = $Int_55
$Int_56 &= 983040
$Int_56 /= 65536

Else
- No Actions - (To add one, press 'Action')



So if CAI websets the values to ISY at $Int_55, this program would convert it to your desired value (1,2,3,4) and save it at $Int_56.  
 
First it copies the value over from int 55 to int 56
 
Then, anding with 983040 (11110000000000000000) will clear all bits except 16-19
 
Dividing by 65536 (10000000000000000) will get rid of all the trailing zeros so all is left is bits 16-19 moved over to the 0-3 position.
 
You guys make it look so simple!
 
Using the 3 bit positions as az1324 suggest I was able to figure out from your example how to change the values. For bits 16-18 I need to AND with 458752 then divide with 65536. For bits 19-21 AND with 3670016 then divide with 524288, etc.
 
Thank you both so much for your patience and guidance and generosity of your time!
 
Lou Apo said:
If
- No Conditions - (To add one, press 'Schedule' or 'Condition')

Then
​ $Int_56 = $Int_55
$Int_56 &= 983040
$Int_56 /= 65536

Else
- No Actions - (To add one, press 'Action')



So if CAI websets the values to ISY at $Int_55, this program would convert it to your desired value (1,2,3,4) and save it at $Int_56.  
 
First it copies the value over from int 55 to int 56
 
Then, anding with 983040 (11110000000000000000) will clear all bits except 16-19
 
Dividing by 65536 (10000000000000000) will get rid of all the trailing zeros so all is left is bits 16-19 moved over to the 0-3 position.
 
Personally I would do the divide first and then and with 15 to avoid big strange numbers (as much as possible).
 
az1324 said:
Personally I would do the divide first and then and with 15 to avoid big strange numbers (as much as possible).
I think the number 983040 would take offense to being called "big and strange".
 
Back
Top