PDA

View Full Version : ! bitwise operator, problem using this



mikea
03-28-2012, 02:00 PM
in the redled pub block i commented my problem. i want to toggle pins 8,9 off and on with the ! operator for efficiency rather than type it all out the long way. what additionally do i have to do besides put" !" in front of the" outa "? also in the lcd method below, i put "-------------------------here" so you could find it easier, i cant figure out how to play the note only one time, when the if statement is true .....currently it will constantly play the note as well as display message.in other words i want the message on always when appropriate but the note should only be a single time like a prompt to get attention. -mike




code:
{Object_Title_and_Purpose}

CON
_clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
baud=19_200
TX_pin = 0
obj pst:"parallax serial terminal"
LCD : "FullDuplexSerial.spin"
pub main
pst.start(19200)
dira[28]:=0
repeat

pst.dec(ina[28]) 'display pin state in terminal window
waitcnt(clkfreq/20 +cnt) 'wait so i can read it
pst.clear 'clear # so they dont pile up across the screen
redled
lcd1
pub redled
dira[9]~~
dira[8]~~
dira[28]:=0
if ina[28]==1

outa[9]~~ 'i want to toggle pins 8,9 with the ! operator, !outa[9]~~
outa[8]~ 'when i put the bitwise operator in front it expects "end of the line" !outa[8]~ !outa[8]~
waitcnt(clkfreq/2+cnt) 'not sure how to proceed....
outa[9]~
else
outa[9]~

PUB lcd1
LCD.start(TX_PIN, TX_PIN, %1000, 19_200)
waitcnt(clkfreq / 100 + cnt) ' Pause for FullDuplexSerial.spin to initialize
LCD.tx(22) 'set diplay no cursor, no blink
LCD.tx(17) 'turn on back light
dira[28]:=0
if ina[28]==1
LCD.tx(212) 'tone length----------------------------------------------------------------------------------------------here
LCD.tx(220) 'note

LCD.tx(12) 'clear screen
LCD.str(string("motion detected by girls room")) 'display message
waitcnt(clkfreq/2+cnt) 'slow down so screen doesnt pulse
else

LCD.tx(12) 'clear screen
LCD.str(string("all is cool.")) 'display message
waitcnt(clkfreq/2+cnt) 'slow down

Mike Green
03-28-2012, 02:11 PM
First of all, you must put the [ code ] and [ /code ] tags around your program (without the extra spaces inside the []). Otherwise, as you may have noticed, all the indenting is lost and that makes it difficult at best to make sense of your program.

The error message is correct. You can have OUTA[9]~ (to set the I/O pin to low) or you can have OUTA[9]~~ (to set the I/O pin to high) or you can have !OUTA[9] (to toggle the I/O pin's value), but you can't combine them like !OUTA[9]~ or !OUTA[9]~~. It doesn't make sense.

Cluso99
03-28-2012, 02:12 PM
You are trying to do two conflicting things at once
The ! operator will invert the bit(s).
The ~ operator sets the bit off.
So only use one at a time.

MagIO2
03-28-2012, 02:23 PM
Have a look at the exclusive or operator. With this you can toggle two pins at the same time.

mikea
03-28-2012, 02:27 PM
thank you both.(ill make sure next time the code is submitted correctly, thanks for the tip)-mike

turbosupra
03-28-2012, 05:58 PM
Hi Mike,

I'm not 100% clear on what you are trying to do? I loosely wrote this based on the fact that it sounds like you have a daughter that is sneaking out of the house or something? I don't have the bell to test with, but if I understood you correctly, you want 2 led's alternating back and forth and they will turn on when pin 28 == 0? As well as sound a chime and write something on the terminal alerting you to this? Am I correct in my interpretation? Below is my code, I had to tweak a couple of things to fit my setup. If I interpreted wrong, please let me know, but if I interpreted correctly and you have questions about my code, post here. Also, if you can elaborate a little more about what you are trying to do, that would help.




CON
_clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
baud=19_200
TX_pin = 0
'LEDPIN1 = 8
'LEDPIN2 = 9
LEDPIN1 = 16
LEDPIN2 = 17

obj pst:"parallax serial terminal"
LCD : "FullDuplexSerial.spin"

pub main
'pst.start(19200)
pst.start(115200)

pst.str(string("Pin state is: "))
pst.dec(ina[28]) 'display pin state in terminal window
pst.char(13)
pst.char(13)
waitcnt(clkfreq/1 +cnt) 'wait so i can read it


dira[28]:=0
repeat

'pst.dec(ina[28]) 'display pin state in terminal window
'waitcnt(clkfreq/20 +cnt) 'wait so i can read it
'pst.clear 'clear # so they dont pile up across the screen

redled
lcd1

pub redled
dira[LEDPIN1]~~
dira[LEDPIN2]~~
dira[28]~
outa[LEDPIN1]~~
outa[LEDPIN2]~

'if ina[28]==1

if ina[28]==0 ' I don't have an input for this pin, so it has to be equal to 0 for my developement board
!outa[LEDPIN1] 'i want to toggle pins 8,9 with the ! operator, !outa[9]~~
!outa[LEDPIN2] 'when i put the bitwise operator in front it expects "end of the line" !outa[8]~ !outa[8]~
waitcnt(clkfreq/2+cnt) 'not sure how to proceed....
!outa[LEDPIN1]
!outa[LEDPIN2]
waitcnt(clkfreq/2+cnt)
else
outa[LEDPIN1]~
outa[LEDPIN2]~

PUB lcd1
'LCD.start(TX_PIN, TX_PIN, %1000, 19_200)
'waitcnt(clkfreq / 100 + cnt) ' Pause for FullDuplexSerial.spin to initialize
'LCD.tx(22) 'set diplay no cursor, no blink
'LCD.tx(17) 'turn on back light
'dira[28]:=0
{ if ina[28]==0
LCD.tx(212) 'tone length----------------------------------------------------------------------------------------------here
LCD.tx(220) 'note

LCD.tx(12) 'clear screen
LCD.str(string("motion detected by girls room")) 'display message
waitcnt(clkfreq/2+cnt) 'slow down so screen doesnt pulse
else

LCD.tx(12) 'clear screen
LCD.str(string("all is cool.")) 'display message
waitcnt(clkfreq/2+cnt) 'slow down }

pst.str(string("Pin state is: "))
pst.dec(ina[28])
pst.char(13)

if ina[28]==1
LCD.tx(212) 'tone length----------------------------------------------------------------------------------------------here
LCD.tx(220) 'note

'LCD.tx(12) 'clear screen
pst.str(string("motion detected by girls room")) 'display message
pst.char(13)
waitcnt(clkfreq/2+cnt) 'slow down so screen doesnt pulse
else

'LCD.tx(12) 'clear screen
pst.str(string("all is cool.")) 'display message
pst.char(13)
waitcnt(clkfreq/2+cnt) 'slow down
pst.clear

mikea
03-28-2012, 06:42 PM
thank you turbosupra, the intent is to p.i.r. monitor portions of the house with separate p.i.r. units and prompt me with a note or two with the piezo speaker if im asleep, (also flashing lights) to look at lcd display which should say what zone set it off...thank you for your response....im away from my stuff so ill check it out in a little bit.-mike

MagIO2
03-28-2012, 07:01 PM
Do you have 2 accounts here? Are you stuartX? Have a look: http://forums.parallax.com/showthread.php?138945-Propeller-LED-Program-1st-Program post #15

;o)

turbosupra
03-28-2012, 08:13 PM
Ok, well you should be using different cogs for this in my opinion.

A cog to monitor the infrared sensors, a cog to control the LED's and a cog to do com data. Are you familiar with using cognew? If you had a layout of which pins were doing what, I could probably give example code.

mikea
03-29-2012, 01:06 PM
magi02: no...only one account.thanks for the link. looks similar and helpful.
turbosupra: i haven't used additional cogs yet, but would like to get into the swing of that.


pin 28 reads the state of the p.i.r. .....1 for high(motion sensed) , 0 for low

pins 8,9 flashed leds, one on while one off ...alternating during motion sense, or steady green when no motion pin 7

pin 0 is output to parallax lcd 27977-rt with built in piezospeaker, 1)displays a secure message if no motion sensed
2)motion detected by girls room (for now i only have one sensor, but will likely add more for different locations)
when motion is sensed it should alternately flash two leds , play only a couple notes and stop(possibly to wake me up), and display motion sense message.
when nothing sensed it would be cool to have a steady green led.

....turbosupra, thanks in advance i would like to see what that looks like with separate cogs...if i left something out let me know please.-mike

mikea
03-29-2012, 01:55 PM
magl02 ":Have a look at the exclusive or operator. With this you can toggle two pins at the same time"

........could you show a short example of this, ive looked up the "or" and tried to include it for use but not doing something right to make it toggle pins...thanks.-mike

Mike Green
03-29-2012, 02:06 PM
OUTA[9..8] ^= %11

This selects I/O pins 8 and 9 as a 2 bit value with 9 as the MSB and 8 as the LSB. It then exclusive ors those bits with the constant %11 which toggles both of them. You could also do

OUTA ^= %11_0000_0000

This does the same thing, but exclusive ors the two bits (in the right bit positions) with the whole OUTA register.

mikea
03-29-2012, 02:44 PM
thanks mike...is there a way with this outa[9..8]^= to alternately toggle pins 8,9 so when 8 is on 9 is off and conversely?-mike
one more question....if you added another "1" to the right of the "11" in place of a "0" so it was outa ^_1000_0000 would that be high for i/o pins 9,8,7?
thats binary that starts from the right at bit ,pin "0" and sets high or low in order up to 31? is that right? thanks- mike

MagIO2
03-29-2012, 04:48 PM
You simply have to initialize pins 8 and 9 correctly before you toggle, so when movement is detected first time:
outa[9..7] := %010
As long as the sensor detects movement you toggle
outa[9..8] ^= %11
When sensor says 'no more movement'
oua[9..7] := %001

Of course xor in this case works the same way as the bitwise not. It's speciality being a programable inverter is not needed in this case. But nevertheless it's usefull to know this detail.

turbosupra
03-29-2012, 06:14 PM
I only ended up using 1 extra cog, as that is all that is really necessary. You are going to have to tweak the LCD object stuff and piezo buzzer, as I don't have that, but the rest should work. You could always test it with a push button. You will also have to comment out the pins I am using and use the pin numbers that your setup is configured for.

Let me know if you have any questions about my code or why I did something the way that I did. You can uncomment the pst lines if you want to see what is going on, but you'll have to get rid of the pst.clear in the main method.




CON
_clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
'baudrate=19_200
'TX_pin = 0
'STEADYLEDPIN1 = 7
'ALTERNATELEDPIN1 = 8
'ALTERNATELEDPIN2 = 9
'PIRPIN = 28
baudrate = 115200
STEADYLEDPIN1 = 16
ALTERNATELEDPIN1 = 17
ALTERNATELEDPIN2 = 20
PIRPIN = 7

obj
pst:"parallax serial terminal"
LCD : "FullDuplexSerial.spin"


VAR



long redLedStack[100] ' I usually set this to an array value of 100 unless I'm running low on space


pub main
'pst.start(19200)
pst.start(baudrate)

pst.str(string("Pin state is: "))
pst.dec(ina[PIRPIN]) 'display pin state in terminal window
pst.char(13)
pst.char(13)

waitcnt(clkfreq/1 +cnt) 'wait so i can read it

cognew(redLed, @redLedStack) ' name of method, method stack which is an allocated space for memory for this method

repeat

if ina[PIRPIN]==1
'LCD.tx(212) 'tone length----------------------------------------------------------------------------------------------here
'LCD.tx(220) 'note
'LCD.tx(12) 'clear screen
pst.str(string("motion detected by girls room")) 'display message
pst.char(13)
waitcnt(clkfreq/2+cnt) 'slow down so screen doesnt pulse
else

'LCD.tx(12) 'clear screen
pst.str(string("all is cool.")) 'display message
pst.char(13)
waitcnt(clkfreq/2+cnt) 'slow down
pst.clear

pub redLed

dira[ALTERNATELEDPIN1]~~ ' set pin to output
dira[ALTERNATELEDPIN2]~~ ' set pin to output
dira[STEADYLEDPIN1]~~ ' set pin to output
dira[PIRPIN]~~ ' set pin to output

outa[ALTERNATELEDPIN1]~ ' initialize pin to low
outa[ALTERNATELEDPIN2]~ ' initialize pin to low
outa[STEADYLEDPIN1]~ ' initialize pin to low
outa[PIRPIN]~ ' initialize pin to low


repeat

if ina[PIRPIN]==0 ' I don't have an input for this pin, so it has to be equal to 0 for my developement board
outa[STEADYLEDPIN1]~ ' turn off steady state led
outa[ALTERNATELEDPIN1]~~ ' pin high/on
'pst.str(string("Pin1 On, Pin2 Off"))
'pst.char(13)
waitcnt(clkfreq/2+cnt) ' wait 1/2 a second
outa[ALTERNATELEDPIN1]~ ' pin low/off

outa[ALTERNATELEDPIN2]~~ ' pin high/on
'pst.str(string("Pin1 Off, Pin2 On"))
'pst.char(13)
waitcnt(clkfreq/2+cnt)
outa[ALTERNATELEDPIN2]~ ' pin low/off
else
outa[STEADYLEDPIN1]~~ ' turn on steady state led

{
PUB lcd1
'LCD.start(TX_PIN, TX_PIN, %1000, 19_200)
'waitcnt(clkfreq / 100 + cnt) ' Pause for FullDuplexSerial.spin to initialize
'LCD.tx(22) 'set diplay no cursor, no blink
'LCD.tx(17) 'turn on back light
'dira[28]:=0
{ if ina[28]==0
LCD.tx(212) 'tone length----------------------------------------------------------------------------------------------here
LCD.tx(220) 'note

LCD.tx(12) 'clear screen
LCD.str(string("motion detected by girls room")) 'display message
waitcnt(clkfreq/2+cnt) 'slow down so screen doesnt pulse
else

LCD.tx(12) 'clear screen
LCD.str(string("all is cool.")) 'display message
waitcnt(clkfreq/2+cnt) 'slow down }

pst.str(string("Pin state is: "))
pst.dec(ina[PIRPIN])
pst.char(13)

if ina[PIRPIN]==1
LCD.tx(212) 'tone length----------------------------------------------------------------------------------------------here
LCD.tx(220) 'note

'LCD.tx(12) 'clear screen
pst.str(string("motion detected by girls room")) 'display message
pst.char(13)
waitcnt(clkfreq/2+cnt) 'slow down so screen doesnt pulse
else

'LCD.tx(12) 'clear screen
pst.str(string("all is cool.")) 'display message
pst.char(13)
waitcnt(clkfreq/2+cnt) 'slow down
pst.clear

}




turbosupra: i haven't used additional cogs yet, but would like to get into the swing of that.


pin 28 reads the state of the p.i.r. .....1 for high(motion sensed) , 0 for low

pins 8,9 flashed leds, one on while one off ...alternating during motion sense, or steady green when no motion pin 7

pin 0 is output to parallax lcd 27977-rt with built in piezospeaker, 1)displays a secure message if no motion sensed
2)motion detected by girls room (for now i only have one sensor, but will likely add more for different locations)
when motion is sensed it should alternately flash two leds , play only a couple notes and stop(possibly to wake me up), and display motion sense message.
when nothing sensed it would be cool to have a steady green led.

....turbosupra, thanks in advance i would like to see what that looks like with separate cogs...if i left something out let me know please.-mike

mikea
03-30-2012, 12:40 PM
cool, thanks turbosupra....gonna get this going and install this stuff in my house. hopefully extra wire length wont change anything(wireless p.i.r. would be cool but prob expensive). what does the line pst.char(13) do? also, looks like you can start a cog with a "method"(pub or pri) that is included in the same obj? ......it doesnt have to be something saved in a .spin file outside the current obj? thanks for the help!

Mike Green
03-30-2012, 02:28 PM
Cogs and objects are really orthogonal. You can have a program all in one .spin file (no objects) that busily starts and stops all sorts of cogs all over the place. You can also have a program with lots of objects in lots of .spin files and it uses only the initial cog started by the bootloader. The only restriction is that the method called by a COGNEW as the starting point for the new cog must reside in the same .spin file as the COGNEW. Once that starts executing, it can call anything that it normally would call. The usual caveats apply about two cogs trying to simultaneously change the same variable(s) or I/O pin(s) ... confusion reigns.

mikea
03-30-2012, 03:28 PM
i think i get it...sounds more flexible than i thought .thanks mike...-mike

turbosupra
03-31-2012, 04:29 AM
pst.char(13) is a carriage return to the parallax serial terminal, I believe it translates literally to "\r" or it might be "\n" which if you've done any .net programming will look familiar.

Wire length obviously changes resistance, but you can compensate for that with the proper hardware. Yes you can start a public or private method, the cog loads the method and if there is a repeat function in it, it will continue until stopped. I can be a method local to the parent or root spin file.



cool, thanks turbosupra....gonna get this going and install this stuff in my house. hopefully extra wire length wont change anything(wireless p.i.r. would be cool but prob expensive). what does the line pst.char(13) do? also, looks like you can start a cog with a "method"(pub or pri) that is included in the same obj? ......it doesnt have to be something saved in a .spin file outside the current obj? thanks for the help!