Bitwise commands - Trying to understand
As many of you know, I have been playing with the prop for some time, but still having a hard time understanding how to use the binary commands. I am now working on a project that controls 12 DMX LED lights (each red/green/blue). Although I got the code working, I really think it can be cleaned up A LOT by the use of binary operators instead of the way I am doing it.
As an example, this is what I did to make it work. I created a variable that has 12 bytes, and really it only needs to control if the lights is on or off. So I use the following piece of code to turn the LED's on or off.
To turn all the LED's on, I use the same as above, just with ledonoff := 255
This is what I use to send the dmx code:
Now the learning part... I have been trying to revise the code to use a 3 byte array and use control the lights like this:
This is what I think I should use to send the dmx code:
I am just trying to understand how to convert some of these for loops into a binary array so it will be much easier to control the lights in chases, etc. I know it is working now, but I want to get a better understanding also...
THANKS in advance for any explination you can have to step me closer to understanding this...
As an example, this is what I did to make it work. I created a variable that has 12 bytes, and really it only needs to control if the lights is on or off. So I use the following piece of code to turn the LED's on or off.
pub alloff | i
repeat i from 0 to 11 'repeat 12 times
ledonoff[i] := 0 'set all bytes to 0
senddmxout 'send ledonoff var out
waitcnt(clkfreq / (dmxin.read(5)+1) + cnt) 'used dmx channel 5 to change speed, mainly for chases
main
To turn all the LED's on, I use the same as above, just with ledonoff := 255
This is what I use to send the dmx code:
pub senddmxout | light, chan, total, r, g, b
chan := 0
repeat light from 0 to 11
r := 0
g := 0
b := 0
total := dmxin.read(4)
if ledonoff[light] > 0
r := dmxin.read(1) 'red channel in
g := dmxin.read(2) 'green channel in
b := dmxin.read(3) 'blue channel in
if total < r
r := total
if total < g
g := total
if total < b
b := total
dmxout.write(chan++, r)
dmxout.write(chan++, g)
dmxout.write(chan++, b)
pause(10)
return
Now the learning part... I have been trying to revise the code to use a 3 byte array and use control the lights like this:
ledonoff === %0000_0000_0000 'would turn all lights off ledonoff === %1111_1111_1111 'would turn all lights on
This is what I think I should use to send the dmx code:
pub senddmxout | light, chan, total, r, g, b
chan := 0
repeat light from 0 to 11
r := 0 'set local red variable to 0
g := 0 'set local green variable to 0
b := 0 'set local blue variable to 0
total := dmxin.read(4) 'set dmx total
if ledonoff[light]-> 'check if variable is a 1 or 0, rotate right after checking 'PROBLEM LINE
r := dmxin.read(1) 'red channel in
g := dmxin.read(2) 'green channel in
b := dmxin.read(3) 'blue channel in
if total < r
r := total
if total < g
g := total
if total < b
b := total
dmxout.write(chan++, r)
dmxout.write(chan++, g)
dmxout.write(chan++, b)
pause(10)
return
I am just trying to understand how to convert some of these for loops into a binary array so it will be much easier to control the lights in chases, etc. I know it is working now, but I want to get a better understanding also...
THANKS in advance for any explination you can have to step me closer to understanding this...

Comments
pub getbit(target, pos) '' returns bit value (0..1) of target.pos if ((pos => 0) and (pos =< 31)) return (target >> pos) & 1 else return 0If all of your red channel bits are stored in a word, you could do something like this:
repeat idx from 0 to 11 red[idx] := getbit(redbits, idx) * 255If you don't want to be bothered with the getbit() method, there's always...
repeat idx from 0 to 11 if (redbits & (|< idx)) red[idx] := 255 else red[idx] := 0<< is move all bits to the left. 000111 << 2 == 011100 (moved the bits left two positions)
>> is move all bits to the right. 001100 >> 1 == 000110 (moved the bits right one position)
To produce a number with a single bit position ON, use 1 << x, where x is the bit position to turn on. (1 << 5) produces 00010000.
To produce a number with a single bit position OFF, use ~(1 << x).
~ is the NOT operator - it means "produce the bitwise opposite", like this:
~0010000 == 1101111
| is "or". It mushes all the bits together, like this:
001110
| 010000
011110 Bits that were on in EITHER input come out in the result.
So, to set a specific bit in a number, use | (or) (1 << x) where x is the bit position from 0 to 31
& is "and" - it takes the left argument and applies the right argument as a mask, like this:
001110
& 001000
001000 Only the bits that were on in BOTH numbers come out in the result.
You can use this to test if a bit is on, like this:
if( (bunchOfBits & (1 << 5)) > 0 )
// Bit 5 is on...
To turn off a specific bit, use & ~(1 << x) - it takes that single bit, NOTs it to turn on all the other bits, leaving that single one off, then ANDs the original value by it.
In JonnyMac's example, |< idx is a SPIN shortcut for (1 << idx).
Sorry if this is simpler than you were looking for, but if you don't have a good handle on binary numbers, this is the place to start.