Wierd result when inverting an input
Bell var portB.0
Report var byte
(PortB.0 is pulled up)
Report = !Bell + 48 or Report = (!Bell) + 48
The value of variable Report = "0" (ascii 48) when portB.0 = True
The value of variable Report = "/" (ascii 47) when portB.0 = False (I was expecting ascii 49)
Is this a bug in PBP3 or I am using wrongly the not notation?
Cheers
Al
Re: Wierd result when inverting an input
Al, I believe you have to use the BITWISE operator of "~" for that operation.
Re: Wierd result when inverting an input
Thank you Dave for the suggestion, but no luck it doesn't work either. With "~" I get ascii 46 when portB.0 is false and the same ascii 47 when the portB.0 is True.
Looking into the manual the character for the NOT is "!", I could not find any reference to "~" as a NOT notation.
Cheers
Al.
Re: Wierd result when inverting an input
Quote:
Originally Posted by
aratti
Thank you Dave for the suggestion, but no luck it doesn't work either. With "~" I get ascii 46 when portB.0 is false and the same ascii 47 when the portB.0 is True.
Looking into the manual the character for the NOT is "!", I could not find any reference to "~" as a NOT notation.
Cheers
Al.
The "tilde" character ~ is a BITWISE NOT. pp35 in the old green book, have misplaced my PBP3 book.
This works:
Code:
Bell var portB.6
Report var byte
main:
Report = ~~(Bell + 48)
debug report
pause 500
goto main
Re: Wierd result when inverting an input
Code:
Bell var portB.6
Report var byte
main:
Report = ~~(Bell + 48)
debug report
pause 500
goto main
Thank you Archangel for your snippet.
I tried with one tilde character ~(Bell + 48) and it does't work. (Just strange characters)
I tried with two tildes, as per your example, and what I get is the original Logic state of the pin. It seems that two tildes are simply ignored.
So, at the moment I have used the IF/THEN/ELSE/ENDIF workaround. Conclusion we cannot invert a pin alias and convert it to ascii using the "!" or the bitwise "~"
Cheers
Al.
Re: Wierd result when inverting an input
Quote:
It seems that two tildes are simply ignored.
not at all !
Quote:
PORTB = ~ PORTB ' Invert every bit in PORTB
result = ~ (PORTB & %00001111)
'Invert the result of the & operation
manual $ 3.2.4 ...
if you invert twice ... you get the original value !!!
did you try ...
Code:
Report = (~ Bell ) + 48 ...
probably not !
Alain
Re: Wierd result when inverting an input
Alain, the result of your example : Report = (~ Bell ) + 48 gives 46 when input is high and 47 when the input is low.
Cheers
Al.
Re: Wierd result when inverting an input
Al, It makes me wonder if the TRIS register is set correctly for the port? You always get the same response no mater what state you place on it.
Re: Wierd result when inverting an input
Just thinking here....
What you might be seeing is that in a single statement "Report = (~Bell) + 48", is that PBP is treating the combination of the alias and the assignment to "Report" as a byte output computation.
If that is the case, then the output is as expected.
Byte variables are unsigned, so a bitwise not of 0 = 255 and 1 = 254.
Which would give you the 47 and 46 values you are seeing. 255+48=47, 254+48=46
This is most likely also happening for the Logical Not as well.
To test:
Bell var PORTB.6
Report var byte
MyPin var bit
MyPin = Bell
MyPin = ~MyPin 'this will force the bitwise Not at the bit variable level
Report = MyPin + 48
MyPin = Bell
MyPin = !Mypin 'This will force the logical Not at the bit variable level
Report = MyPin + 48
Output the two operations and see what you get then.
Re: Wierd result when inverting an input
Hi, Al
I played somewhat with that and end with ...
Code:
Report = 47 - (~Bell)
found funny things like ~N = 65535 - N ...
Have a good night
Alain
Re: Wierd result when inverting an input
Dave, the tris register is set correctly and the pic18f2620 just do what it should do when the inputs change Logic state. I need to invert the Logic state of the display (it is much more simple to have a "True" when the external sensor is close instead having a "False".
As I said in a previous post, I solved the problem using the following workaround:
Code:
If Bell = false then
Report = "1"
Else
Report = "0"
ENDIF
Definetly less elegant than the "NOT" notation but at least it works!
Since I always toggle the flashing led with led = !led and it works fine I wrongly assumed that it could work also with an alias. Very likely I should copy the pin state in a bit variable to have it working. I will give a tray (NOT NOW)
Cheers
Al.
Re: Wierd result when inverting an input
Code:
MyPin = Bell
MyPin = !Mypin 'This will force the logical Not at the bit variable level
Report = MyPin + 48
Thank you Tabsoft for the above snippet. Tested and it works. I have already replaced the IF/THEN/ELSE code that I could not stand with.
Now that a more elegant workaround has been found, the question remains: PBP3 cannot handle pin alias. Is it a bug?
Cheers
Al
Re: Wierd result when inverting an input
Glad it worked.
I have a theory, but will want to test it and look at the disassembled code to see.
I think it is the fact that the NOT operator (logical or bitwise) against the alias is being evaluated in an assignment statement to a byte.
This may be having the compiler use a generic macro that is handling the NOT operation as a byte or word output.
The test code above should force a two-step process.
1. Force the NOT operation/assignment to a bit variable.
2. Assign the value + 48 to the Report byte variable.
My guess is that since "Report = !Bell + 48" has the Report byte variable on the left, PBP might be assuming that the interim steps are at a byte (or word) level.
We will see, or I could be totally wrong. :-0
Either way I don't think we should have to burn another variable and cycles to perform what should be a simple function.
Re: Wierd result when inverting an input
Well, it was as I expected.
It's all about the assignment statement.
Whatever "Type" the left side of the assignment statement is drives the operation.
If you are assigning the value to a Byte, then the compiler does the steps as a byte.
If you are assigning the value to a BIT, then the compiler does the steps as a bit.
Here is a simple test program.
The "Destination" of the value is tested against a Byte variable or a Bit variable.
The "Source" of the value is tested against a Byte variable, a Port Alias and a Bit Alias.
Code:
myBit var bit
myByte var byte
TRISB = $FF
TestPin var PORTB.6
TestByte var byte
TestBit var TestByte.6
'Test Variable Alias with direct assignment to byte variable
TestByte = %01000000
'Assign Logical NOT (!) bit value to byte variable
myByte = !TestBit
'Assign Bitwise NOT (~) bit value to byte variable
myByte = ~TestBit
'Test Port Alias with direct assignment to byte variable
'Assign Logical NOT (!) bit value to byte variable
myByte = !TestPin
'Assign Bitwise NOT (~) bit value to byte variable
myByte = ~TestPin
'Test Variable Alias with direct assignment to bit variable
TestByte = %01000000
'Assign Logical NOT (!) bit value to bit variable
myBit = !TestBit
'Assign Bitwise NOT (~) bit value to bit variable
myBit = ~TestBit
'Test Port Alias with direct assignment to bit variable
'Assign Logical NOT (!) bit value to byte variable
myBit = !TestPin
'Assign Bitwise NOT (~) bit value to byte variable
myBit = ~TestPin
Here is the PBP assembler listing for the above code.
Notice that there are (2) macros for each operator type (! or ~)
LNOT?TB and LNOT?TT (Logical NOT !)
NOT?TB and NOT?TT (Bitwise NOT ~)
The TB stands for biT in and Byte out. The input is a Bit type and the Output is a Byte type.
This is when you get the results that are not what you might expect.
The TT stands for biT in and biT out. The input is a Bit type and the Output is a Bit type.
Code:
;assembler variables
_myByte EQU RAM_START + 01Ah
PB01 EQU RAM_START + 01Bh
_TestByte EQU RAM_START + 01Ch
;assembler defines
#define _myBit PB01, 000h
#define _TestPin _PORTB??6
#define _TestBit _TestByte??6
#define _PORTB??6 PORTB, 006h
#define _TestByte??6 _TestByte, 006h
; 00022 TestByte = %01000000
MOVE?CB 040h, _TestByte
; 00025 myByte = !TestBit
LNOT?TB _TestBit, _myByte
; 00028 myByte = ~TestBit
NOT?TB _TestBit, _myByte
; 00033 myByte = !TestPin
LNOT?TB _TestPin, _myByte
; 00036 myByte = ~TestPin
NOT?TB _TestPin, _myByte
; 00039 TestByte = %01000000
MOVE?CB 040h, _TestByte
; 00042 myBit = !TestBit
LNOT?TT _TestBit, _myBit
; 00045 myBit = ~TestBit
NOT?TT _TestBit, _myBit
; 00050 myBit = !TestPin
LNOT?TT _TestPin, _myBit
; 00053 myBit = ~TestPin
NOT?TT _TestPin, _myBit
Here are the actual macros that are called above.
I made some comments, not for everything but some.
Code:
NOT?TB macro Regin, Bitin, Bout
CHK?RP Regin
movlw -1 ;load dec 255 into w register
btfsc Regin, Bitin ;If Regin.Bitin = 0, skip the next instruction
movlw -2 ;load dec 254 into w register
MOVE?AB Bout ;Move W to Bout
endm
NOT?TT macro Regin, Bitin, Regout, Bitout
CHK?RP Regin
clrw ;Clear the w register
btfss Regin, Bitin ;If Regin.Bitin = 1, skip the next instruction
addlw 1 ;Load dec 1 into the w Register
CHK?RP Regout
btfsc STATUS, Z
bcf Regout, Bitout ;Clear Regout.Bitout
btfss STATUS, Z
bsf Regout, Bitout ;Set Regout.Bitout
endm
LNOT?TB macro Regin, Bitin, Bout
CHK?RP Regin
clrw
btfss Regin, Bitin
movlw -1
MOVE?AB Bout
endm
LNOT?TT macro Regin, Bitin, Regout, Bitout
CHK?RP Regin
clrw
btfss Regin, Bitin
addlw 1
CHK?RP Regout
btfsc STATUS, Z
bcf Regout, Bitout
btfss STATUS, Z
bsf Regout, Bitout
endm
Re: Wierd result when inverting an input
Thank you Tabsoft for the deep search!
I think that this finding should call for an update of the manual (at least)
Cheers
Al.
Re: Wierd result when inverting an input
BTW,
I remember Darrel had written a post about this kind of behaviour.
he used a "!!" to get rid of the problem.
does somebody remember where it was shown ???
Alain
Re: Wierd result when inverting an input
That post would be interesting to read.
I don't see how it would alleviate the issue.
I think without an interim step to force the assignment to a bit type variable it will perform the operation as a byte.
I might take a look through the PBP library macros for Logical and bitwise NOTs to see if there is another macro that would hand the situation. If there is, it would be a matter of what syntax would cause the compiler to pick that macro instead.
Re: Wierd result when inverting an input
It would seem that the simple way around this is:
Report = 48 + !Mypin
Wouln't that force
Picbasic to evaluate Report as a byte, not as a bit?
Re: Wierd result when inverting an input
No, not really.
That has been the point of this discussion.
We would not want PBP to do the interim calculations as a byte, we would want PBP to do them as a bit.
The issue is that in this statement "Report = 48 + !Mypin"
Report is a byte variable, 48 will be treated as a constant and Mypin is a bit.
Sounds good so far, but, when PBP looks at this statement it will treat the !Mypin as a byte output in the calculation step.
It does this because "Report" on the left side is a byte variable.
What we want is if Mypin = 0 then Report = 49; If Mypin = 1 then Report = 48.
But here is what happens.
Pseudocode for the PBP ASM Macros used for the following Statement: Report = 48 + !Mypin
Code:
Step 1. Perform a Logical NOT on Mypin.
Clear the W register (Set it to 0)
If Mypin is a zero then
Store 255 decimal in the W register 'This is because Report will ultimately get the value, so PBP starts treating all the output variables as bytes
else
Store 0 in W register
endif
Move W register to a temporary "byte" variable T1
Step 2. Add 48 to temporary "byte" variable T1
Step 3. Move Temporary "byte" variable T1 to "byte" variable Report
So if you start with Mypin = 0, then
Code:
Step 1. T1 = 255
Step 2. T1 = 255 + 48 = 47 ' This is because a byte variable is unsigned in PBP
Step 3. Report = 47 'We wanted Report to equal 49 not 47
If you start with Mypin = 1
Step 1. T1 = 0
Step 2. T1 = 0 + 48 = 48
Step 3. Report = 48 'This is what we wanted.
So the issue as I can see is that to perform this logic as we "want" it to work, you need to manually perform an interim step
and store the current value of Mypin in a "bit" variable. Then perform a logical NOT on the "bit" variable. Then add 48 and the "bit" variable
and store the answer in report.
myBit var bit
Mypin var PORTB.6
Report var byte
myBit = Mypin
myBit = !myBit
Report = 48 + myBit
This works.
Re: Wierd result when inverting an input
And the answer is....
Mypin var Portb.6
Report var byte
Report = 48 + (Mypin ^ 1)
There is NO need to be changing variable types. Mypin just needs to be inverted. So why not invert it as if it is a bit. Wow all of this typing for something so simple......