Shop OBEX P1 Docs P2 Docs Learn Events
reliable RF (Xbee) communication. — Parallax Forums

reliable RF (Xbee) communication.

DgswanerDgswaner Posts: 795
edited 2008-08-18 17:38 in Propeller 1
I have one last issue before my web controlled bot is finally to a point I'd call finished. the issue is reliable RF communication. So I'm looking for some pointers.
I'm currently using 9600 baud xbee to xbee. and from what I can tell the sending and receiving gets out of sync. even though I'm using ask-answer type of communication (don't know the technical term). the bot ask for the direction command from the receiver, and then waits for an answer. I think something gets garbled, junk gets sent and then junk gets received and then it just repeats.

I'm wondering if I need to speed up the communication, slow it down or perhaps I need to add pauses in between each command. I have to add that I can get the control to work just fine is that's all that's happening. I started adding LEDs to indicates modes, and timeout's and this is when I ran in to issues. I know I could add checksums but that just adds communication and CPU time. and I'm already concerned with Lag when web controlled.

when I use XT.RX (FDS) it hold up the processing until something is received, if the bot thinks it just sent a command and the receiver didn't get it, they both end up in wait loops. if I use XB.RXtime(30) it waits for the full 30ms before it continues. this either adds a big delay and really slows down communication or if I lessen the time, won't work for all the different commands.

any thoughts?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"A complex design is the sign of an inferior designer." - Jamie Hyneman, Myth Buster

DGSwaner

Comments

  • heaterheater Posts: 3,370
    edited 2008-08-18 05:29
    I would forget the idea of requests and responses (ask-answer). No idea what you have to communicate but at the simplest level there must be telemetry data coming up from the bot, position, speed, direction, sensor inputs, whatever. Then there must be commands coming back from the PC.

    So send your telemetry data from the bot at regular intervals say 10 or 100 times per second. Depending on message length and baud rate.
    Don't bother with the bot waiting for any confirmation of reception by the PC. Lets just assume a high proportion of the message packets arrive at the PC intact else we have a problem anyway. There is no point in resending old data if the PC fails to respond what matters is the state now.

    Leave some time between the telemetry packets from the bot to PC for the PC to send commands.
    The PC must wait for telemetry data before sending a command in the gaps between packets received.

    Now, what if the commands from the PC are not received ? Well either A) the PC works this out from the incoming telemetry data and sends the commands again or B) Bot sends an OK bit/byte in the telemetry data.

    I think I prefer A). For example PC sends STOP command to bot. PC notices from telemetry data that the bot continues to move. PC sends STOP command again, and again if need be, and again....

    In B) PC sends STOP command, bot then includes an OK bit/byte in the telemetry data. But what if it continues to move?....And how do you know which received "OK" belongs to which command sent?. Well then you need command identifiers and/or sequence numbers on the packets and the whole job gets more complicated.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-08-18 05:30
    I've never seen an XBee receive garbled data. I've seen it drop bytes if it's out of range but never get bad ones. In a master/slave situation like yours, I'd have the two units in constant communication, even if the command is, "Can you hear me now?" Also, make sure that every command is met with a response, even if it's just "OK". If you have range issues, a protocol involving checksums may be called for. If the received checksum doesn't match, or if the transmission times out, the receiving unit sends a "NOTOK", so the transmitter knows to retransmit the packet.

    You can learn a lot by studying the protocols used by industrial PLCs. AutomationDirect's DirectNet protocol is but one example.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • DgswanerDgswaner Posts: 795
    edited 2008-08-18 05:54
    thanks heater and Phil, I don't think it's a hard ware issue, the XBEE is getting what it is sent, I think the problem is that it at some point it starts receiving 1/2 way through a transmit and see it as some other character. range is not an issue, they are 10' apart. Thanks for the input! I'm current sending/recieving the following:

    a move command: F,B,L,R
    CamX position: 0-255
    CamY Position: 0-255
    Pingdata: tells receiver to receive PING data
    then sends 5 Pings value:A-H

    the problem I'm running into with sending back an "OK" is that one the program waits for a response, if something happens and one isn't received, the bot just locked up. or if I use RXtime it adds a big delay. even if I used 10MS that adds almost a 100ms by time it waits 10ms for each piece of data.

    I'll work on these and see what happens. I wand to send a lot more data but if I can get this to work adding data will only make it worse.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "A complex design is the sign of an inferior designer." - Jamie Hyneman, Myth Buster

    DGSwaner
  • heaterheater Posts: 3,370
    edited 2008-08-18 05:57
    I would always include some form of checksum on the packets.

    The master/slave concept requires knowing which is master and which is slave. At a high level the PC "master" sends commands to the bot "slave" but at a communications level perhaps the bot is the master. For example sending requests for commands in Dgswaner's current set up or controlling packet timing in my simple suggestion.

    I'm not convinced of the value of complicated protocols with time outs, ACKs/NACKs, retries, sequence numbers etc in cases like this. As I said there is no point in resending old bot data messages. It's state is changing all the time. Might as well send the current state continuously. I could argue that sending old commands from PC to bot when they get lost is not necessarily useful either. E.g. The PC commands a STOP, but the bot continues to move(Lost message maybe). Do we really want to command STOP again? perhaps by that time stopping is not the best course of action, perhaps its time for FULL SPEED REVERSE or perhaps the operator (human or otherwise) has changed his mind and wants to go LEFT instead.

    However one end has to be "master" of the time slots in which data is sent to avoid packet collisions. Or is an xbee full duplex ?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • DgswanerDgswaner Posts: 795
    edited 2008-08-18 06:03
    I agree with you on the resending old data, espically with a web controlled bot, every ms counts. it take 1/2 as long to just as long to send the current value as it does to say hey I didn't get it resend it.

    and yes my PC (PINK + PROP + XBEE) is the master, but as far as the communication my bot does all the asking. at least for now.

    .... no on mentioned baud? would changing the baud help?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "A complex design is the sign of an inferior designer." - Jamie Hyneman, Myth Buster

    DGSwaner
  • heaterheater Posts: 3,370
    edited 2008-08-18 06:16
    DirectNet is interesting. Never heard of it before. What I have done is have to fix up/replace a lot of "home grown" simple minded serial line protocols used in industry that produced all kinds of problems when under stress or on somehow unreliable lines.

    Things might get tricky if you have more than one bot. Then the PC should be probably be the master of communications timing and indicate which bot can transmit next.

    I know nothing of XBEE so cannot speak on the baud rates in might be happy with. At 9600 you have about 1000 bytes/characters per second which seems plenty enough for your application. But perhaps XBEE is more reliable at slower speeds.

    By the way what is "PINK" ?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-08-18 06:29
    I would definitely make the PC the master and the bot the slave, rather than having the bot request commands. Also, the response to every command should include the new state resulting from execution of that command. That response, and not the commanded state, then becomes the new state duplicated in the master. For example, if the master sends "!X130", the slave should respond with "!X130", once the new position has been attained. Not until then should the master update its mirror state with the new data. This will help to keep the states in sync.

    The master's command set should also include a "query" command, which tells the slave to respond with the current states of all its settings. This would be the command to use when the master first communicates with the slave on startup or after it loses contact. From there, an occasional "ENQ/ACK" command/response is all that's needed during quiet times when no other commands are being sent.

    The XBee is transparently full-duplex on the device side — probably half-duplex on the RF side.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • jazzedjazzed Posts: 11,803
    edited 2008-08-18 07:10
    Ask-answer or "synchronous communications" is not always necessary, but can help. Here is a protocol I used with UDP for "reliable" communications a decade ago (TCP is better for reliability, but darn slow). This is one way to do it, and Phil already mention something similar. This is all from memory and it's late, so if I've missed a corner condition, please be kind.

    {{
    Simple Sequence Messaging Protocol
    }}
    Primary transmitter
      clear resend flag
      repeat
        If message ready to send or resend flag then
          Send message with index
          If next rx message index > index and crc ok
            increment index
            clear resend flag
          Else
            set resend flag
    Secondary receiver
      repeat
        Get message with index & crc
        If index == last index or crc bad
          do not perform command
          respond with last index
        Else
          perform command
          increment index
          send index in next message
    
    



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • heaterheater Posts: 3,370
    edited 2008-08-18 07:16
    Yep, make the PC the master.
    Yep, bot returns it's state after every command.

    But Phil, why do we need a special "query" command on start up or interruption? Seems to me there is enough bandwidth here to reply the complete state after every command anyway. In effect the complete state returned is the "ACK" and the periodic commands are the "ENQ".

    In fact I think it's almost a requirement to have the full state all the time, not just that which pertains to a command. This is a bot in the real world I guess, slipping on it's wheels and bumping into obstacles etc. The controller needs to know all this all the time.

    I'm going to assume commands are sent 10 or 100 times per second CONTINUOUSLY. Perhaps if only a "NULL" command, when nothing new needs to happen. Keep sending a STOP command until the returned state indicates zero speed, or the same POSITION command until it is seen that the position is reached. Then send do nothing (NULL) commands. Maybe slightly more tricky with things like LEFT and RIGHT. Do you keep sending LEFT till the bot has actually turned through, say, 90 degrees or until it has replied with "I'm turning left now" included in its state data? You don't want multiple LEFT commands causing it to spin around forever!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • DgswanerDgswaner Posts: 795
    edited 2008-08-18 14:46
    ok I can see a need for a complete rewrite. here are some of my challenges. and be kind with me also. I'm only sending one character/number for each command. I know !X125 would be ideal, but I found it difficult to extract the X and 125 from !X125. I finally figured out converting "123" to 123 (String to number) down but, I never could it working with my PINK (Parallax Internet NetBurner Kit...web server). The pink needs to use characters, even for numeric values. but I couldn't get it to work, and that's why I send the pink values as a character not a value.

    I'm getting no where near 1000 Xmits per second. more like 2-3 a cycles. I know I'm losing a lot of time reading 5 ping sensors, so I think I'll work on getting that done in a separate cog. as well as sending data to the PINK.

    I'm definitely going to need to offload some of the work to a separate cog, on both sides.

    thanks for the input, I'm going to start simple and then build on that.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "A complex design is the sign of an inferior designer." - Jamie Hyneman, Myth Buster

    DGSwaner
  • Jimmy W.Jimmy W. Posts: 112
    edited 2008-08-18 14:48
    Does the bot have GPS to get absolute data or are we speaking of relative data? I prefer the pelco method ie 1 long contains all the information about the bot, 1 bit each for forward,back,left,right,raise,lower, 1 nibble each for speed of direction left/right, forward/reverse, and if you have gps throw a byte in for absolute direction, have the pc send what the current status should be everytime, to stop just clear all the forward back/left,right bits.
    as far as xbee goes I have managed to get 1/2mile with no problems with the 60mw wire ant versions @ 19200, ymmv but not that much [noparse]:)[/noparse] if you have to sparkfun xbee breakout boards they have a stress test feature you can use that spams both side hard to check the radios



    Jimmy
  • Ken PetersonKen Peterson Posts: 806
    edited 2008-08-18 15:04
    Not sure if this would help you, but most serial protocols I see usually assemble all data into packets formatted into some sort of message.· The messages would always begin with one or more start bytes for synchronization to avoid getting confused after receiving half of a message.· You would also have an "end of message" byte to confirm that you got the complete message, as well as some form of checksum to verify the message is intact.· The coding is easier with fixed-length messages because once you detect the message-start byte or phrase, you just dump a fixed number of characters to a buffer and process it afterwords.

    I would also consider setting up·timing where you are always·sending a message at regular intervals along with a "heartbeat" message if no data or commands need to be sent.· When something is sent, it should be sent at that regular interval.· This can free your code up to do other things without having to constantly monitor the channel.· Once the receiver synchronizes on that message interval, it only needs to check for messages when they are due to arrive.



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."

    - Bjarne Stroustrup
  • Mike GreenMike Green Posts: 23,101
    edited 2008-08-18 17:23
    I don't really understand why you're having so much trouble. I have a Propeller BoeBot with an xBee link to a MacBook. Admittedly, I only use it for a console link replacement for BoeBotBasic, but it's worked flawlessly whether I'm downloading Basic source or displaying debug information. The xBee assembles and disassembles packets and does its own error checking that's invisible to the MacBook and Propeller. I have increased the FDS buffer size to 64 bytes. I'm not sure what the internal buffer size is for the xBee, but the FDS buffer may be too small at 16 bytes without flow control (which the normal FDS doesn't have). There's now a 4 channel FDS object in the Object Exchange that includes optional flow control. You might try substituting that or increasing the normal receive buffer size to see if that helps.
  • DgswanerDgswaner Posts: 795
    edited 2008-08-18 17:38
    Trouble follows me where ever I go! if all I'm doing is sending a couple of commands it works great. it's when I add things like time outs(not RXtime) and send more data, that when things get messed up. I'll tidy up my code, and post it when I get home perhaps there is something simple I'm doing wrong.

    for what I'm doing I though that the ask-answer method would be more than adequate.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "A complex design is the sign of an inferior designer." - Jamie Hyneman, Myth Buster

    DGSwaner
Sign In or Register to comment.