Cannot get if x bit set or if x & $ then to work

LEH

Member
#Picaxe 40X2
symbol test = w10
if test BIT 1 SET then does not work, the word SET is green
also tried
if test & $0001 <> 0 then also not accepted.
 

lbenson

Senior Member
This works in the PE6 simulator.
Code:
#Picaxe 40X2 
  symbol test = w10
  test = 2
  if test BIT 1 SET then '  does not work, the word SET is green
    sertxd("test:1 is SET")
  else
    sertxd("test:1 is NOT SET")
  endif
Are you sure you are testing the right bit?
 

Goeytex

Senior Member
Best I can tell there is no simple read access to individual bits of variables other than B0,B1,B2,B2 and/or W0 and W1.

There are 32 bit variables available, Bit0 to Bit31 where Bit0 to bit7 represent variable B0 and so on.
Therefore bit0 to Bit15 will represent variable W0. And Bit16 to Bit31 will represent variable W1.

It is sometimes a good idea to reserve variables B0,B1,B2 & B3 (W0,W1) for bit testing and maniputulation.

Here is one way to do what you want.


Code:
#Picaxe 08M2
#No_Data


Symbol TempWord0 = W0     '// reserve as reusable temp variable
Symbol TestVar = W10

Do
     inc TestVar       '// Increment by 1 
     TempWord0 = TestVar     
     If bit1 = 1 then 
        Sertxd ("Bit1 is SET",13,10)
     Else 
        Sertxd ("Bit1 is Clear",13,10) 
     End if
     pause 1000  
Loop

Another option is to simply use W0 for TestVar ....

Goey
 

AllyCat

Senior Member
Hi,

Yes, it seems to compile/simulate OK in PE5 as well Are you sure you're completing the IF... syntax with a GOTO (or address label), a GOSUB or ... ENDIF/ELSE .?

Cheers, Alan.
 

techElder

Well-known member
LEH, you can't just invent your own language. PICAXE BASIC has a certain format for all of it's commands, etc. You have to follow that syntax to get the intended results. The BIT statements are an example.

The syntax available is in the manual and available at this forum.


#Picaxe 40X2
symbol test = w10
if test BIT 1 SET then does not work, the word SET is green
also tried
if test & $0001 <> 0 then also not accepted.
 

hippy

Technical Support
Staff member
#Picaxe 40X2
symbol test = w10
if test BIT 1 SET then does not work, the word SET is green
also tried
if test & $0001 <> 0 then also not accepted.
I would guess it is perhaps because a value of 1 sets bit 0, not bit 1. It all worked when I tried it, in simulation in PE6 and on a real chip.

Code:
#Picaxe 28X2
#Terminal 9600

Symbol test = w10

Pause 2000
SerTxd("Starting...", CR, LF )

Do
  test = 0
  If test Bit 1 Set Then
    SerTxd( "Set FAIL when bit = 0", CR, LF )
  Else
    SerTxd( "Set Okay when bit = 0", CR, LF )
  End If
  test = 2
  If test Bit 1 Set Then
    SerTxd( "Set Okay when bit = 1", CR, LF )
  Else
    SerTxd( "Set FAIL when bit = 1", CR, LF )
  End If
  test = 0
  If test Bit 1 Clear Then
    SerTxd( "Clr Okay when bit = 0", CR, LF )
  Else
    SerTxd( "Clr FAIL when bit = 0", CR, LF )
  End If
  test = 2
  If test Bit 1 Clear Then
    SerTxd( "Clr FAIL when bit = 1", CR, LF )
  Else
    SerTxd( "Clr Okay when bit = 1", CR, LF )
  End If
  Pause 5000
  SerTxd( "---", CR, LF )
Loop
 

westaust55

Moderator
To possibly clarify to some extent what others have stated above:

Yes, the IF bit is a valid test function for any byte/word variable in a X1 or X2 part.
http://www.picaxe.com/BASIC-Commands/Program-Flow-Control/if-bit/


A byte variable has 8 bits numbered from the left as:
bit7, bit6 . . . Bit1, bit0
And word variables have
Bit15, bit14 . . . Bit1, bit0

Thus a test on bit 1 is in fact testing the second lowest/least significant bit.

By comparison, test AND $0001 is masking off all but bit 0, the least significant bit.

PICAXE BASIC does not permit math to be performed within an IF ... THEN statement. Only simple tests are permitted.
The part "test AND $0001" is a math function whereas "<>" (or =, <, >, <= etc) are test operators.
 

Circuit

Senior Member
Best I can tell there is no simple read access to individual bits of variables other than B0,B1,B2,B2 and/or W0 and W1.

Goey
Yes, that command is something I missed in the manual for quite some time and I was delighted when I discovered it; it is there in the manual; page 107 manual 2;

Additional option on X1/X2 parts only :
IF variable BIT value SET THEN
{code}
ELSEIF variable BIT value CLEAR THEN
{code}
ELSE
{code}
ENDIF​

Quite a useful command option, especially when used with setbit and clearbit. I found these commands to be very useful in manipulating word variables when controlling 16 output (2x ports) i2c chips such as MCP23017 port expanders or stacked shift registers.
 

AllyCat

Senior Member
Hi,

It may be a "useful" command, but it occupies significantly more codespace (and is probably slower) than the "normal" syntax. For example:

IF w10 BIT 4 SET THEN : ENDIF uses 16 bytes of program space, whilst:

w0 = w10 : IF bit4 = 0 THEN : ENDIF uses only 9 bytes (and remains compatible with M2 code). And it's only 6 bytes if you declare w0 as the variable at the start.

Cheers, Alan.
 

westaust55

Moderator
Hi,

It may be a "useful" command, but it occupies significantly more codespace (and is probably slower) than the "normal" syntax. For example:

IF w10 BIT 4 SET THEN : ENDIF uses 16 bytes of program space, whilst:

w0 = w10 : IF bit4 = 0 THEN : ENDIF uses only 9 bytes (and remains compatible with M2 code). And it's only 6 bytes if you declare w0 as the variable at the start.

Cheers, Alan.
As Circuit suggests it can be a useful construct for some in terms of readability.

Then as Allycat/Alan suggests:
the If . . BIT set/Clear THEN . . . construct is not only around (16/6= ) 2.67 times larger in code space

After a 'quick and dirty' speed check his presumption is correct also by a similar magnitude.
At 8 MHz clock frequency:
an IF . . BIT set/Clear THEN . . . . ELSE . . . ENDIF (with no actions) takes roughly 1.1 msec whereas
an IF Bit1 = 1 THEN . . . . ELSE . . . ENDIF (with no actions) takes around 0.4 msec
so the speed difference where the value is already in variable w0, is of the order of (1.1 / 0.4 = ) = 2.75 times longer.

That said, there are very few times where my code has entirely filled a PICAXE chip (yes I know others have filled multiple slots), and not too many projects (my model railway DCC accessory decoder is an exception) where speed has been paramount.
 

stan74

Senior Member
I don't get the question. W10 is b20 and b21 so why not if b20 and bit value ie 1,2,4,8 then whatever, can't see the issue except tex's reply. What am I missing?
 

lbenson

Senior Member
I don't get the question. W10 is b20 and b21 so why not if b20 and bit value ie 1,2,4,8 then whatever, can't see the issue except tex's reply. What am I missing?
Can you repeat your solution with actual code which runs in the simulator?
 

LEH

Member
Thanks to every one who replied. The manual indicates that if var BIT 1 SET then should work, but the editor would not accept it. Decided to go with:
let w0 = col1
if BIT1 <> 0 then
low row1
else
high row1
endif etc.
let w0 = col2 etc.
 

lbenson

Senior Member
Glad you have a solution, but several have shown that "if var BIT 1 SET then" does work on the right picaxe (X1, X2) with appropriate conditions. The editor definitely accepts it.
 

hippy

Technical Support
Staff member
The manual indicates that if var BIT 1 SET then should work, but the editor would not accept it.
From an earlier post it appears you are using a PICAXE 40X2 and PE6 definitely accepts it for a 40X2.

Perhaps detail what software you are using and which version, and what error message you are receiving when you try to use it. Then someone may be able to explain what the issue is.
 

stan74

Senior Member
Can you repeat your solution with actual code which runs in the simulator?

w10=1
b0=b20 and 255
b1=b21 and 255
sertxd ("w10 low=",#b0," w10 high=",#b1,cr,lf)
if b20=1 then sertxd ("bit 0 w10 set",cr,lf):end if
 
Last edited:

lbenson

Senior Member
Doesn't work if both bits 0 and 1 are on.
Code:
w10=1
 b0=b20 and 255
 b1=b21 and 255
 sertxd ("w10 low=",#b0," w10 high=",#b1,cr,lf)
 if b20=1 then sertxd ("bit 0 w10 set",cr,lf):end if
w10 = w10 + 2
 b0=b20 and 255
 b1=b21 and 255
 sertxd ("w10 low=",#b0," w10 high=",#b1,cr,lf)
 if b20=1 then sertxd ("bit 0 w10 set",cr,lf):end if
Output:
Code:
w10 low=1 w10 high=0
bit 0 w10 set
w10 low=3 w10 high=0
 

AllyCat

Senior Member
Hi,

It may run in the simulator but it doesn't give the desired result (try any value with bit0 set other than 1).

b0=b20 and 255
b1=b21 and 255
That's identical to w0 = w10 AND $FFFF wihich is then the same as w0 = w10 , but perhaps you like writing slow, inefficient and confusing code. ;)

What we're really waiting for from the OP is an actual program example with legitimate command syntax that the editor will not accept. My suspicion is that he's used either invalid command structure (e.g. a missing <newline> ), or a reserved word.

Cheers, Alan.
 

Buzby

Senior Member
I don't get the question. W10 is b20 and b21 so why not if b20 and bit value ie 1,2,4,8 then whatever, can't see the issue except tex's reply. What am I missing?
Using 'AND 1,2,4,8' etc. is a very limited way of testing bits.

Try re-writing the code below using AND's ...

Code:
[color=Navy]#picaxe [/color][color=Black]28x2[/color]
[color=Navy]#no_table
#no_data[/color]

[color=Blue]symbol [/color][color=Purple]MyBitNum [/color][color=DarkCyan]= [/color][color=Purple]b4

w10 [/color][color=DarkCyan]= [/color][color=Navy]%1111000010101010[/color]

[color=Blue]for [/color][color=Purple]MyBitNum [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]to [/color][color=Navy]15

      [/color][color=Blue]if [/color][color=Purple]w10 [/color][color=DarkCyan]BIT [/color][color=Purple]MyBitNum [/color][color=DarkCyan]SET [/color][color=Blue]then 
            sertxd([/color][color=Red]"1"[/color][color=Blue])
      else
            sertxd([/color][color=Red]"0"[/color][color=Blue])
      endif

next[/color]
 

inglewoodpete

Senior Member
Thanks to every one who replied. The manual indicates that if var BIT 1 SET then should work, but the editor would not accept it. Decided to go with:
let w0 = col1
if BIT1 <> 0 then
low row1
else
high row1
endif etc.
let w0 = col2 etc.
It would help members if you could post the exact code that you are trying to use. You only mention your code in discussion, saying that it doesn't work. Since we know that the correct syntax DOES work, it would help us to help you.
 

stan74

Senior Member
"Doesn't work if both bits 0 and 1 are on." use and 3. I still can't see what the problem with finding the value of w10. I'm obviously missing the point. Sorry
 

techElder

Well-known member
"Doesn't work if both bits 0 and 1 are on." use and 3. I still can't see what the problem with finding the value of w10. I'm obviously missing the point. Sorry

If you have a group of boys with shirts on AND three of them have BLUE shirts on, how MANY boys are in the room?


PS. Sorry, Stan! :D
 

hippy

Technical Support
Staff member
I don't get the question. W10 is b20 and b21 so why not if b20 and bit value ie 1,2,4,8 then whatever, can't see the issue except tex's reply. What am I missing?
Te issue is that this only works if there is only one bit set in the variable.

If more than one bit is set then simply comparing the variable with 1, 2, 4, 8 etc will not work. The individual bits need to be checked.
 

LEH

Member
I think I have found an even better solution
let pinB.n = BITn etc
should be very fast and use little code space.
 

stan74

Senior Member
"If more than one bit is set then simply comparing the variable with 1, 2, 4, 8 etc will not work. The individual bits need to be checked." So if you want to check if bit 0 and bit 6 set then anding the var with 65 won't work?
 

Goeytex

Senior Member
I think I have found an even better solution
let pinB.n = BITn etc
should be very fast and use little code space.
Complete Code to Test:


Code:
#Picaxe 40x2

Symbol TestVar  = W0

DIRSB = %00000010

Do
  Inc TestVar    '//Increment
  Let PinB.1 = Bit1
  Pause 1000
Loop
Seems Good in the Simulator
 

Technical

Technical Support
Staff member
"If more than one bit is set then simply comparing the variable with 1, 2, 4, 8 etc will not work. The individual bits need to be checked." So if you want to check if bit 0 and bit 6 set then anding the var with 65 won't work?
The common way to test bits is to AND out only the bits of interest and then check for the desired value, so a two step process such as

b2 = b1 AND %01000001
if b2 = %01000001 then

if you don't AND out first, any of the other 6 bits being equal to 1 will not give you the 65 value (as those other bits still add in to the total as well).
 

stan74

Senior Member
Yes Technical.In the manual the shown way to test say port b is var=pinsb and %xxxxxxxx not case if portb.0 =1 etc
 
Top