After having some problems with negative temperatures I attempted to investigate how the CAI WC PLC handled negative integers conversion back and forth between 32 bit to 16 bit variables.
Well it turns out that a negative integer represented as a 32 bit two's complement number converts to a 16 bit variable just fine due to simple truncation of the upper 16 bits works out mathematically correct. This math, of course only works for integers closer to zero (making use of less then 16 bits) than +3276710 (0xFFFF 7FFF) and -3276810 (0xFFFF 8000)
However, conversion in reverse, becomes a problem for the WC PLC. 16 bit signed values are not converted correctly when being converted from 16 bit to 32 bit or being sent elsewhere (using the WEBSET opcode) to get data into my ISY994i home automation computer. My ISY994i seemed to be receiving some really weird and incorrect results into it's assigned variable locations.
Some investigation proved the conversion process has forgotten to extend the sign bit when converting from 16 bit to 32 bits. The conversion works just fine when values are positive or used as unsigned representations but when my temperature reading goes below zero it becomes a problem.
Here's an sample math demo of this
Converting 32 bit value --> 16 bit value (eg: SET RAM1L RAM2)
-12810 = 0xFFFF 8000 --> 0x8000 = -12810
Converting 16 bit value --> 32 bit value (eg: SET RAM2 RAM1L)
-12810 = 0x8000 --> 0x0000 8000 = +3276910 an incorrect result !!!
To correct this problem here is a work there is a workaround, inside the test code (below), I set up to verify what was happening. It should also be noted I tried many different register data massaging methods to identify any results along the way. I have included a snapshot of the variable results, showing negative four degrees (-4) found in my ISY994i HA controller to demonstrate the result of many data automatic conversions in the CAI WC.
My solution:
-Copy 16 bit register to a 32 bit register,
SET RAM5 RAM4H
-Test the original value for negative
TSTGE RAM4H 0x8000
If negative extend the sign bit into the 32 bit variable's upper 16 bits
ORB RAM5 0xFFFF8000 RAM5
Enjoy!
Well it turns out that a negative integer represented as a 32 bit two's complement number converts to a 16 bit variable just fine due to simple truncation of the upper 16 bits works out mathematically correct. This math, of course only works for integers closer to zero (making use of less then 16 bits) than +3276710 (0xFFFF 7FFF) and -3276810 (0xFFFF 8000)
However, conversion in reverse, becomes a problem for the WC PLC. 16 bit signed values are not converted correctly when being converted from 16 bit to 32 bit or being sent elsewhere (using the WEBSET opcode) to get data into my ISY994i home automation computer. My ISY994i seemed to be receiving some really weird and incorrect results into it's assigned variable locations.
Some investigation proved the conversion process has forgotten to extend the sign bit when converting from 16 bit to 32 bits. The conversion works just fine when values are positive or used as unsigned representations but when my temperature reading goes below zero it becomes a problem.
Here's an sample math demo of this
Converting 32 bit value --> 16 bit value (eg: SET RAM1L RAM2)
-12810 = 0xFFFF 8000 --> 0x8000 = -12810
Converting 16 bit value --> 32 bit value (eg: SET RAM2 RAM1L)
-12810 = 0x8000 --> 0x0000 8000 = +3276910 an incorrect result !!!
To correct this problem here is a work there is a workaround, inside the test code (below), I set up to verify what was happening. It should also be noted I tried many different register data massaging methods to identify any results along the way. I have included a snapshot of the variable results, showing negative four degrees (-4) found in my ISY994i HA controller to demonstrate the result of many data automatic conversions in the CAI WC.
My solution:
-Copy 16 bit register to a 32 bit register,
SET RAM5 RAM4H
-Test the original value for negative
TSTGE RAM4H 0x8000
If negative extend the sign bit into the 32 bit variable's upper 16 bits
ORB RAM5 0xFFFF8000 RAM5
Enjoy!
START
TSYNC:
TSTLE CYEAR 2013
GOTO TSYNC
INIT:
DELAY 3000
SET RAM1 10
LOOP:
SUB RAM1 1 RAM1
WEBSET URL1 RAM1
WEBSET URL2 RAM1H
WEBSET URL3 RAM1L
RAM2:
SET RAM2 RAM1
WEBSET URL4 RAM2
RAM3L:
SET RAM3L RAM2
WEBSET URL5 RAM3L
RAM4H:
SET RAM4H RAM3L
WEBSET URL6 RAM4H
RAM5:
SET RAM5 RAM4H
WEBSET URL7 RAM5
TSTGE RAM4H 0x8000
ORB RAM5 0xFFFF8000 RAM5
WEBSET URL8 RAM5
DELAY 5000
GOTO LOOP
END