Shop OBEX P1 Docs P2 Docs Learn Events
RF communication — Parallax Forums

RF communication

kt88seampkt88seamp Posts: 112
edited 2010-03-31 03:53 in Propeller 1
I am going to be building a radio transmitter/receiver with a LINX rf module. For experimentation, I bought 2 parallax RF transceivers.

For an experiment, I will build a circuit that transmits a random byte to the receiver. Eight LEDs will light when the data arrives. Next, the receiver will transmit back a random byte to the transmitter. Eight LEDs will light on that when the data arrives. Since RF is highly susceptible to interference, what are some good error checking methods to ensure the byte arrived intact?

Comments

  • LeonLeon Posts: 7,620
    edited 2010-03-30 07:57
    Send blocks of data and use CRC.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Leon Heller
    Amateur radio callsign: G1HSM
  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2010-03-30 15:25
    I've been down this road and it's not at all straightforward.
    Which Lynx module(s) are you using for Transmit & Receive?
    Jim-

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent!
    Send $1 to CannibalRobotics.com.
  • kt88seampkt88seamp Posts: 112
    edited 2010-03-30 16:53
    The Linx module I am using is the transceiver.

    An idea I have for transmitting a byte is:

    - First you transmit the byte.

    - Next, the receiver transmits the byte back.

    - If the two match, transmit the next byte.

    - If the two do not match, or the transmitter does not receive the byte in a certain time, retransmit the the byte. Repeat this process 10 or so times. IF it repeats 10 times, declare the RF link dead.
  • CannibalRoboticsCannibalRobotics Posts: 535
    edited 2010-03-30 17:44
    OK,
    I have used, and been abused by, the TRM-433 Transceiver. It's a cool product but there are several things you need to really pay attention to.
    - My first mistake was to use FullDuplexSerial, I discovered FDS will not drive it reliably. FDSerial has a very cool feature where it is jumping to sample the receive pin while it's transmitting. So, there is just no way for transmit and receive to share a pin. Don't even think about trying to gang them on the outside of the prop your receive buffer will get blown out by the transmitter and the transmitter output cannot be overcome by the Lynx output.
    - Advertised data rates and real data rates are vastly different but it sounds like you may not need allot of speed.
    - There are sync pulses that have to be strictly observed when switching from R to T mode. The transmitter has to send out a pulse to allow the receiver to latch onto the signal. The first start bit isn't going to cut it and the receiver software needs to understand this sync issue.
    - There are also R->T transition delays in the Lynx product. You need to make sure you time the In->Out transition of your data port properly. If you switch the prop port from in to out before the Lynx has changed over they get into a force fight which can mess up either or both chips.
    - If I was to go back and do it all again I would probably use a Pulse Width encoding scheme as opposed to a simple on/off bit transition scheme.
    - Leon's comment is dead on, CRC is a good one if your packets are small - like bytes. I'd use some form of forward error correction scheme because you're right, there is allot of noise and generally you can bet there will be errors. A big headache is switching back and forth for acknowledgement. I used a 9-14 byte packets that relayed the previous packet checksum back for verification. If the checksum failed over x packets I slowed the data rate. Multiple successful relays caused the data rate to go up. Since it was a control application, not a data transfer system, I could afford to toss lost packets. I was sending a complete set of control criteria in each packet so I was only interested in the latest valid packet anyway.
    - I'd recommend you buy an extra receiver just to watch everything on the scope. It's almost impossible to tease out what's working or not with just the operational Receiver and Transmitter. I would have never figured out the delay problem without the 'third-eye'
    - Your application sounds like it might be better served by sending all 10 bytes and some error overhead then checking and requesting a whole packet retransmit.
    This is not meant to discourage you, I think the Lynx products are very cool and I'd love to hear about your progress - it sounds likeit might be applicable to something else I've been asked to do.
    If you want me to try to dig up some code, I'll be glad to. Be warned, it's mostly PASM, well commented but not SPIN.

    Jim-

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Signature space for rent!
    Send $1 to CannibalRobotics.com.

    Post Edited (CannibalRobotics) : 3/30/2010 5:56:40 PM GMT
  • James NewmanJames Newman Posts: 133
    edited 2010-03-30 17:44
    This sort of thing has been studied thoroughly in the past, and is still being improved upon.

    One problem with the method you propose is that latency will eat you alive. You have to send a byte, wait for it to arrive, send it back, wait for it to arrive, repeat if needed... before you can even think of sending the next byte. This will really really limit your bandwidth.

    Sending a crc signature with each packet (several bytes atleast) allows you to check if the data is genuine and correct without having to call home. This means you don't have to resend unless you absolutely have to. Adding some buffers of memory allows you to still be receiving data while doing checking/requesting previous packets. Even if you have to get a retransmit on a few packets here and there, others may be good and can be received in the background. Some handshaking needs to be mixed in to make sure you don't miss anything entirely, and to keep your order of packets strait. Finally, some flow control to be able to throttle back the transmit rate if your buffer is full.

    Look into UDP and TCP protocols for ideas, algorithmically they're pretty robust and feature rich.

    Post Edited (James Newman) : 3/30/2010 5:53:51 PM GMT
  • kt88seampkt88seamp Posts: 112
    edited 2010-03-30 18:59
    I am actually transmitting data over the airwaves. The data will be stored in an EEPROM after it is received. The quantity of data being transmitted is very small, at the very maximum, 1968 bytes (an estimate). I plan on transmitting it one byte at a time, since the EEPROM stores data that way. My device will do this:

    - Recieve the data to transmit from the USB port on a PC via a FT232RL.

    - Transmit the data to the reciever.

    - If all the data arrives intact, write it to the EEPROM.

    What the data is for, if you are curious, it is instructions that direct a propeller to perform holiday lights animations via a triac. I just finished a device that does this only instead of wireless, it is programmed directly via the USB port. Only difference between my wireless plan and the current device? Everything is the same except for that the programming is done via radio.

    What code do you have? I have never attempted wireless communication of any kind, so is there any code or objects that can get me started? Also there will be about six receivers as one strand of holiday lights will be plugged into each device.

    Post Edited (kt88seamp) : 3/30/2010 7:06:44 PM GMT
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2010-03-30 23:22
    I'd try and break your data down into packets. The CRC is on a packet. A packet would contain some signature starting byte or word. Then perhaps a node address followed by a command. After that add the payload for the command. In your case the command could be a byte that represents "store data".

    Your application of the RF programming sounds cool.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" 16:9 LCD Composite video display, eProto for SunSPOT, PropNET, PolkaDOT-51
    www.tdswieter.com
  • kt88seampkt88seamp Posts: 112
    edited 2010-03-31 01:34
    Lets say a packet is 32 bits. So the packet could be formatted a such?

    <signature> <reciever address byte 1> <reciever address byte 2> <data>

    Lets say the signature is a * character. So at the receiver end you check to see if the * character matches. If it doesn't, you send out a retransmit request?
  • James NewmanJames Newman Posts: 133
    edited 2010-03-31 01:39
    No, that won't help if your data behind the signature gets garbled. The signature is just to signify the start of a packet, otherwise how do you know that you didn't miss the first few bits of a packet? All your packets could be off by a few bits making them all invalid asfar as your receiver is concerned. Look up crc checks, you need to do one on the data, and include the generated crc check data in the packet. The receiver gets the packet, generates it's own crc calculation on the data, then compares it to the crc check data sent. If they match you have a good packet.
  • LeonLeon Posts: 7,620
    edited 2010-03-31 01:54
    Here's the C code for a 32-bit CRC that I've used with an ARM application:

    //---------------------------- CRC functions --------------------------------//
    
    u_long crc32_table[noparse][[/noparse]256];
    /* Initialized first time "crc32()" is called. If you prefer, you can
     * statically initialize it at compile time. [noparse][[/noparse]Another exercise.]
     */
    
    u_long crc32(u_char *buf, int len)
    {
            u_char *p;
            u_long  crc;
    
            if (!crc32_table)    /* if not already done, */
                    init_crc32();   /* build table */
            crc = 0xffffffff;       /* preload shift register, per CRC-32 spec */
            for (p = buf; len > 0; ++p, --len)
                    crc = (crc << 8) ^ crc32_table[noparse][[/noparse](crc >> 24) ^ *p];
            return ~crc;            /* transmit complement, per CRC-32 spec */
    }
    
    /*
     * Build auxiliary table for parallel byte-at-a-time CRC-32.
     */
    #define CRC32_POLY 0x04c11db7     /* AUTODIN II, Ethernet, & FDDI */
    
    void init_crc32(void)
    {
            int i, j;
            u_long c;
    
            for (i = 0; i < 256; ++i) {
                    for (c = i << 24, j = 8; j > 0; --j)
                            c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
                    crc32_table[i] = c;
            }
    }
    
    [/i]
    



    The polynomial is a good one, some aren't.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Leon Heller
    Amateur radio callsign: G1HSM

    Post Edited (Leon) : 3/31/2010 1:59:36 AM GMT
  • kt88seampkt88seamp Posts: 112
    edited 2010-03-31 02:21
    I currently am reading about CRC, what it is, and how it works.
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2010-03-31 03:53
    kt88seamp said...
    Lets say a packet is 32 bits. So the packet could be formatted a such?

    <signature> <reciever address byte 1> <reciever address byte 2> <data>

    Close, I would say the following would work:

    <signature> <reciever address byte 1> <reciever address byte 2> <data><8bit crc>

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" 16:9 LCD Composite video display, eProto for SunSPOT, PropNET, PolkaDOT-51
    www.tdswieter.com
Sign In or Register to comment.