help with Xbee and multiple cogs
JBWolf
Posts: 405
I am having a very odd problem i just cannot figure out.
I have 2 props communicating via xbee just fine right now.... I'm using buttons on one to set a variable status of 1 or 0 then transmit.
Right now this is setup as one way communication, the "transmitter" prop station has buttons and a repeat loop with:
The "Receiver" prop station has a repeat loop with:
Since this works perfectly, I decided to add a function to allow the receiver station to send it's current variable values back to the transmitter station if the transmitter is power cycled.
Since both stations reset all button states and variables on a power cycle, the transmitter station would lose track of the receiver station variables if it was powercycled and the receiver was not.
i.e.. transmitter sets button state #3 to ON... receiver gets the data and turns on device corresponding to button #3. powercycle transmitter station and it thinks button #3 status is OFF on the receiver.
I thought this would be a simple deal by sending a decimal value to the receiver station. the receiver and transmitter stations would then reverse roles for 3 decimal values only, then resume normal operation.
Both the receiver and transmitter are running 2 cogs each... one cog for xbee communication, another cog for actions.
I am using Long's to facilitate passing variable values between cogs.
I have tried over and over every possible method I could think of and finally decided to break it down to the most simple method imaginable... but this still will not work:
Receiver station:
Transmitter Station:
I added an LCD for debugging and am finding that the transmitter station is not receiving a value back from the receiver.
I dont understand why. I have tried directly sending with XB.DEC(long[device1]), I have tried moving the data from the long to a local variable and then sending with XB.DEC(tempvalue).... I can not get these to work.
everything else works fine... I cut the button input and device outa operations from the code above since it's about 3 pages long, I'm using over 2 dozen buttons/devices all together.
Everything else works great... I press a button on the transmitter which sets the long[state] variable to a value of 1 through 10 and the wireless cog transmits... the receiver gets it and moves to long[input] where the actions cog operates devices correctly corresponding to received value. But I just cannot get it to reverse. When I added an LCD to the transmitter station and had it display the received DEC, it was blank... it is not getting anything.
Please help, I am at my wits end... been 2 nights now wasted on this
If you would like the full code let me know... it seriously long though
I have 2 props communicating via xbee just fine right now.... I'm using buttons on one to set a variable status of 1 or 0 then transmit.
Right now this is setup as one way communication, the "transmitter" prop station has buttons and a repeat loop with:
Repeat if ina[button] == 1 device1 := 1 state := 1 XB.Tx("!") ' Send start delimiter XB.Dec(State) ' Send decimal value of button state XB.CR ' Send Carriage Return
The "Receiver" prop station has a repeat loop with:
repeat ' Start Wireless Receiving DataIn := XB.Rx ' Accept incoming byte If DataIn == "!" ' If start delimiter DataIn := XB.RxDec ' Accept value if DataIn <> -1 ' If wasn't time out XB.CR ' Carraige Return Input := DataIn ' Move data XB.RxFlush case input 1: !outa[device1] device1tracker++ if device1tracker > 2 device1tracker := 1 2: !outa[device2] device2tracker++ if device2tracker > 2 device2tracker := 1 3: ..... 4: .....
Since this works perfectly, I decided to add a function to allow the receiver station to send it's current variable values back to the transmitter station if the transmitter is power cycled.
Since both stations reset all button states and variables on a power cycle, the transmitter station would lose track of the receiver station variables if it was powercycled and the receiver was not.
i.e.. transmitter sets button state #3 to ON... receiver gets the data and turns on device corresponding to button #3. powercycle transmitter station and it thinks button #3 status is OFF on the receiver.
I thought this would be a simple deal by sending a decimal value to the receiver station. the receiver and transmitter stations would then reverse roles for 3 decimal values only, then resume normal operation.
Both the receiver and transmitter are running 2 cogs each... one cog for xbee communication, another cog for actions.
I am using Long's to facilitate passing variable values between cogs.
I have tried over and over every possible method I could think of and finally decided to break it down to the most simple method imaginable... but this still will not work:
Receiver station:
VAR Long Input PUB Main(Input) | DataIn XB.start(XB_Rx, XB_Tx, 0, XB_Baud) ' Initialize comms for XBee waitcnt(clkfreq / 500 + cnt) Cognew(Actions, @stack[200]) ' Initialize Actions Processor - Uses incoming data waitcnt(clkfreq / 500 + cnt) repeat ' Start Wireless Receiving DataIn := XB.Rx ' Accept incoming byte If DataIn == "!" ' If start delimiter DataIn := XB.RxDec ' Accept value if DataIn <> -1 ' If wasn't time out XB.CR ' Carraige Return Input := DataIn ' Move data XB.RxFlush If DataIn == 11 ' If Recover Received Input := DataIn waitcnt(clkfreq * 2 + cnt) waitcnt(clkfreq / 1000 + cnt) Pub Actions Repeat ' Start program - endless loop tmp1 := long[@Input] ' move new incoming data to tmp1 long[@Input] := -1 ' clear buffer Case tmp1 11: ' Data Recover Initiate waitcnt(clkfreq / 100 + cnt) XB.Tx("!") ' Send start delimiter XB.Dec(99) ' Send recovery ack XB.CR ' Carraige Return waitcnt(clkfreq / 100 + cnt) '------------ XB.Tx("!") ' Send start delimiter XB.Dec(device1) ' Send #1 Status XB.CR ' Carraige Return waitcnt(clkfreq / 100 + cnt) '------------ XB.Tx("!") ' Send start delimiter XB.Dec(device2) ' Send #2 Status XB.CR ' Carraige Return waitcnt(clkfreq / 100 + cnt) '------------ XB.Tx("!") ' Send start delimiter XB.Dec(device3) ' Send #3 Status XB.CR ' Carraige Return
Transmitter Station:
VAR Long ButtonState Pub Main Cognew(Buttons(@ButtonState), @stack[200]) ' Start Button Monitor Cognew(Wireless(@ButtonState), @stack[400]) ' Start Wireless Repeat PUB Wireless(BtnIn) | State, DataIn, Temp, RecovTrack, StartRecov State := -1 XB.start(XB_Rx, XB_Tx, 0, XB_Baud) ' Initialize XBee waitcnt(clkfreq / 100 + cnt) Temp := 0 StartRecov := 1 RecovTrack := 0 Repeat State := long[BtnIn] IF State > -1 and State < 12 ' If ButtonState range 0-11 XB.Tx("!") ' Send start delimiter XB.Dec(State) ' Send decimal value of PB state XB.CR ' Send Carriage Return IF State == 11 ' If Recovery Startup waitcnt(clkfreq * 2 + cnt) State := -1 ' Clear Output Buffer 'State' long[BtnIn] := -1 ' Reset Buttons Input Value waitcnt(clkfreq / 500 + cnt) ' Matched with receiver PUB Buttons(State) | Device1, Device2, Device3 StartRecovery := 1 Repeat if StartRecovery > 0 long[State] := 11 'waitcnt(clkfreq / 400 + cnt) DataIn := XB.Rx ' Accept incoming byte If DataIn == "!" ' If start delimiter DataIn := XB.RxDec ' Accept value if DataIn <> -1 ' If wasn't time out XB.CR ' Send Carriage Return XB.RxFlush ' Clear Buffer if dataIn == 99 repeat TempQ from 1 to 3 DataIn := XB.Rx ' Accept incoming byte If DataIn == "!" ' If start delimiter DataIn := XB.RxDec ' Accept value if DataIn <> -1 ' If wasn't time out XB.CR ' Send Carriage Return XB.RxFlush ' Clear Buffer Case TempQ 1: Device1 := DataIn 2: Device2 := DataIn 3: Device3 := DataIn waitcnt(clkfreq / 100 + cnt) StartRecovery := 0 long[State] := Temp1 ' Move to Wireless cog waitcnt(clkfreq / 500 + cnt) ' Matched with Receiver Temp1 := -1 ' Erase temporary button input
I added an LCD for debugging and am finding that the transmitter station is not receiving a value back from the receiver.
I dont understand why. I have tried directly sending with XB.DEC(long[device1]), I have tried moving the data from the long to a local variable and then sending with XB.DEC(tempvalue).... I can not get these to work.
everything else works fine... I cut the button input and device outa operations from the code above since it's about 3 pages long, I'm using over 2 dozen buttons/devices all together.
Everything else works great... I press a button on the transmitter which sets the long[state] variable to a value of 1 through 10 and the wireless cog transmits... the receiver gets it and moves to long[input] where the actions cog operates devices correctly corresponding to received value. But I just cannot get it to reverse. When I added an LCD to the transmitter station and had it display the received DEC, it was blank... it is not getting anything.
Please help, I am at my wits end... been 2 nights now wasted on this
If you would like the full code let me know... it seriously long though
Comments
Since I can get this to work fine, it driving me crazy not being able to simply send back other variables.
Heres how I am running the temp probe.
Transmitter station:
Receiver Station:
buttons = 0-200
wireless = 201-400
temperature = 401 - 500
and if it does mark the start of the stack and not the end.... how could display be invalid... is 500 the maximum?
Wouldnt display be 500+
Thanks for pointing out. I have corrected it and tried again, no luck
Any ideas as to why im not getting any results back from that restore attempt?
Is XB.DEC(long[variable]) a valid use?
Yes, that's valid if "variable" is the address of the long you want to send.
It looks like you're passing addresses okay but you don't need to pass variable address between cogs running Spin. You only need to pass address the way you are between objects.
Nothing else in the code above sticks out to me.
what do you mean by "you don't need to pass variable address between cogs"... I dont completely follow. can you quote a piece of code and show correct way?
I have been doing it via:
If I do xb.rx instead of xb.rxtime(ms)
does it wait/pause until any data is received? or does it just do a check at that moment and moves on?
Found the receiver code was fine, it was the timing between cogs on the transmitter that was causing the issue.
Gobal variables may be used by any method within an object irrespective of which cog is using the variable. You can run into problems when you have multiple cogs that can change a global variable but multiple cogs testing the value of the variable shouldn't be a problem.
Here's the "transmitter station" code from post #1 without the use of "long[variableAddress]". This code would work exactly the same as the code in post #1. The "long[variableAddress]" trick is needed when you're using a method in a different object than where the global variable is declared.
The above code wastes a cog. The "repeat" at the end of the Main method keeps the cog alive but the cog isn't doing anything. I suggest changing the method to:
I didn't fix the stack issues in any of the above code.
In FullDuplexSerial, the method "rx" waits for a byte to be received. If no data is received it blocks the progress of the program. I don't recall if the XBee object works the same way. My guess is the "rx" method in the XBee object behaves the same as the "rx" method in FullDuplexSerial.