SparkFun Forums 

Where electronics enthusiasts find answers.

All things pertaining to wireless and RF links
By sapphire327
#33997
I just bought two of each frequency of the RF Links for a project.

I wrote a simple program on two Arduinos: one sends out serial data every 500ms and blinks an LED, and the other waits for serial data and blinks an LED when it receives data.

The setup works great when I connect the TX to the RX with a wire. However, I can't get it to work when replacing the wire with the RF Links! I have tried several things now, with no luck.

I tried several bitrates. 2400bps which is what is stated on Sparkfun, 2800bps which this guy says he used. I also tried 4800bps and 1200bps just for the heck of it. Every time, when I connect the two Arduinos with a wire it works fine, but replacing the wire with the RF modules doesn't work. I have tried with and without a 30cm wire antenna, and I've tried all three frequency modules. I also tried tuning one of them manually.

I'm running out of variables to try. Has anyone else used these successfully? Thanks for your help.

Aaron
By busonerd
#34013
You really need a bunch of sync bytes at the beginning of your packet - any DC balanced data byte should work - like 0x55 or 0xAA. Just send a bunch of those to let the receiver AGC lock, and then have an start of packet byte or two, then the message.

Cheers,

--David Carne
By sapphire327
#34020
That's a good idea. Unfortunately it hasn't made a difference yet. Here is a snippet of my code:
Code: Select all
#define SYNC 0x55
#define NUL  0x00
#define SOD  0x01
#define EOD  0x03
#define LEDPIN 13

void serialSend(byte data) 
{
  for( int i=0; i<100; i++ ) {
    Serial.print(SYNC, BYTE); 
  }
  Serial.print(NUL,  BYTE);
  Serial.print(NUL,  BYTE);
  Serial.print(SOD,  BYTE);
  Serial.print(SOD,  BYTE);
  Serial.print(data, BYTE);
  Serial.print(EOD,  BYTE);
}
I tried sending 20 and 100 of the SYNC bytes. Is sending it as a BYTE (Serial.print(data, BYTE)) the correct thing to do? It seemed like it to me.

In my final application, I'm going to want to be sending a continuous stream of numbers from the transmitter. Will I need just one set of SYNC bytes at power-on to get them in sync, or do I need to send them before every value sent?

Thanks,

Aaron
By riden
#34023
You don't need to send so many SYNC bytes. As David said, the purpose of the bytes is to allow the receiver to come on line and adjust to the signal level of the transmitter. I sent 3 sync bytes. After that is done, you can send data as long as the bits are balanced (e.g., send a byte and then its complement). What are you observing on the receiving end?

An important thing to know is that these devices share the frequency spectrum with other devices. If you transmit continuously, you could interfere with nearby weather stations, door bells, and other devices that use the same frequency.
By sapphire327
#34024
Ah, so what is this about sending the complement byte? I haven't encountered that in anything I've read so far.

So if I wanted to send the value 35, (binary 00100011), I should actually send 00100011 11011100? Both bytes would reach the other side, though, correct? What is the purpose of this?

btw,
An important thing to know is that these devices share the frequency spectrum with other devices. If you transmit continuously, you could interfere with nearby weather stations, door bells, and other devices that use the same frequency.
By "a continuous stream", I mean that the device will be on for ~30 minutes at a time, during which it will need to be sending a constant stream of data.
By riden
#34027
sapphire327 wrote:So if I wanted to send the value 35, (binary 00100011), I should actually send 00100011 11011100? Both bytes would reach the other side, though, correct? What is the purpose of this?
Correct on both counts. The reason that you want to send the complement is to keep the 1 to 0 bit ratio balanced. These receivers have an aggressive AGC and expect a somewhat balanced distribution of the data bits. Other techniques like Manchester Encoding can also be employed, but sending the complement is an easy way to go. Another benefit is that since both the data byte and its complement are sent, you can perform a simple check to see if you received the proper data. Adding the two bytes together should result in 0. If you don't get 0, that byte wasn't received properly.
sapphire327 wrote:By "a continuous stream", I mean that the device will be on for ~30 minutes at a time, during which it will need to be sending a constant stream of data.
Besides the issue of exceeding the active/quiet duty cycle specified for these devices by the FCC (in the U.S.), if you are going to sending data for 30 minutes, you must employ some type of data redundancy. It is highly unlikely that you will have 30 minutes of error free data transmission so you need to plan for that. I think you may find a ZigBee solution a better choice for this type of application.
By sapphire327
#34036
Besides the issue of exceeding the active/quiet duty cycle specified for these devices by the FCC (in the U.S.), if you are going to sending data for 30 minutes, you must employ some type of data redundancy. It is highly unlikely that you will have 30 minutes of error free data transmission so you need to plan for that. I think you may find a ZigBee solution a better choice for this type of application.
I do not necessarily need error-free transmission. I can verify the data was sent correctly by adding the bits and checking if they equal 0 as you suggest, and if there was an error sending that byte, I will just drop it.

Basically I'm sending the data from three ultrasonic distance sensors as fast as I can back to a receiver plugged into a computer. The data will then be fed to Max/MSP and used to manipulate music.

These RF devices seemed like the perfect thing for this application, since I only need one-way communication, and it does not need to be error-free. I also didn't want to have to deal with pairing devices (e.g. bluetooth). I'll admit I am very new to this scene, so I may be mistaken. I haven't looked in to Zigbee at all.

Is it possible that I am having trouble getting the devices to talk to each other because they are too close to each other? They are sitting on the same breadboard at the moment, getting power from separate USB cables going in to my computer.
By MrSteveSmall
#34601
You do need to send some synch bytes. I use 3. Earlier today I had the same problem you did, but after reading this thread I fixed it and decided to post how. Mine are on the same breadboard less than 1 inch away from each other.

on transmitter end:

-Send synch bytes (I used three 55h packets)
-Send a start byte (make something up, like E7h)
-Send the data byte and it's compliment (like 55h and then AAh)
-(optional) send stop byte

on receiver end:

-Check for first byte received to be the start byte (ie, E7h).
-Check the next 2 bytes to be compliments of eachother by reading them in and then logic AND them together. If result is 0, then data success.
-(optional) check for stop bit.

You wont get 100% transmission with this because of signal attenuation and all the other RF signals floating through, but you will ONLY get the data you want this way and none of the random bytes you may be seeing already. I've been sending a constant stream which is updated every millisecond or so for the past few hours and I have yet to accept a bad packet. Also, using this method, I noticed that if you had to send two bytes at once, use the same process outlined above, but bring the synch bytes low instead of the 55h (like, send a few 00h) after the first byte sent.

EXAMPLE CODE:

Transmitter:
Code: Select all
Timer0_interrupt:
    push ACC
    mov A,R7
    push ACC

    acall SendSynch
                                                                           
    mov R7,#10111110b
    mov A,Lap2
    acall SendDigit

    acall SendLOW        

    mov R7,#10111101b
    mov A,Lap1
    acall SendDigit

    mov TH0, #164
    mov TL0, #164
    clr TF0
    setb TR0
    pop ACC
    mov R7,A
    pop ACC
    reti

SendSynch:
    clr TI
    mov SBUF,#55h
    jnb TI,$
    clr TI
    mov SBUF,#55h
    jnb TI,$
    clr TI
    mov SBUF,#55h
    jnb TI,$
    clr TI
    ret

SendLOW:
    clr TI
    mov SBUF,#00h
    jnb TI,$
    clr TI
    mov SBUF,#00h
    jnb TI,$
    clr TI
    mov SBUF,#00h
    jnb TI,$
    clr TI
    ret

SendDigit:

    CLR TI
    mov SBUF,R7
    jnb TI,$
    clr TI

    orl A,#30h
    mov SBUF,A
    jnb TI,$
    clr TI

    cpl A
    mov SBUF,A
    jnb TI,$
    clr TI
    
    mov SBUF,#01000010b
    jnb TI,$
    clr TI

    ret
Receiver:
Code: Select all
monitor:

    jnb RI,$                                ;wait to read in a byte of data
    mov R0,SBUF
    clr RI

    mov A,R0                                ;move the byte to register A

    cjne A,#10111110b,L2                    ;compare the byte to the start byte we want
    mov R2,#27h                             ; and restart if it's not correct
    sjmp getBytes
L2: cjne A,#10111101b,monitor
    mov R2,#26h
getBytes:

    jnb RI,$                                ;read in the next byte of data
    mov R0,SBUF
    clr RI
    
    jnb RI,$                                ;read in the 2nd byte of data as well
    mov R1,SBUF
    clr RI

    mov A,R0                                ;move the first byte to the accumulator

    anl A,R1                                ;logic AND the first byte with the second byte

    jnz monitor                             ;if the result is not zero, then restart
        

    jnb RI,$                                ;Read in the last byte
    mov R1,SBUF
    clr RI

    mov A,R1

    cjne A,#01000010b,monitor               ;compare the byte to the stop byte we want
                                            ;and restart if it's not correct

    mov A,R2
    mov R1,A
    mov A,R0
    mov @R1,A

    lcall WriteLaps

sjmp monitor
By saipan59
#34617
Is it possible that I am having trouble getting the devices to talk to each other because they are too close to each other?
That definitely *may* be a problem.
Try separating them by several feet or more, depending on what you use for an antenna. While debuggin things at close range, I'd recommend no antenna at all.

In doing a roll-your-own RF link like this, you generally need to do these things:
1) Send sync bytes. I use 0xAA repeated 4 times. This gets the receiver 'ready' to receive actual data.
2) Send a 'sync' byte. I use 0xFF. This lets the receiver UART know where the beginning/end of the bytes are.
3) Send a 'preamble'. This a sequence of bytes that lets the receiver code know that it is receiving real data. I use 0xA9 0x56 0xB2. You want the preamble to have roughly 'neutral disparity' (the bits must change fairly often), and it should be something that you don't expect to occur often in random data. With the pattern I'm using, it never goes more than 2 bits in the same state.
4) Send the actual data bytes, using a 'neutral disparity' encoding. The simplest way is to send each data byte, followed by it's complement. Manchester encoding would be fine too. 8/10 encoding is better, but is more complicated.
5) Do the above steps in a single burst, at the appropriate baud rate. If there is any significant dead time (when your xmtr is not transmitting), the rcvr will start getting random garbage, and lose sync with your data. I suspect that some people have trouble because they follow steps 1 thru 4, but their SW allows for big gaps between bytes.
6) Your rcvr needs a way to know when a packet has completed. The easiest way is to use fixed-length packets at all times. This also makes it easy to add a checksum, if desired.
7) The rcvr must deal with the reception of random garbage any time your xmtr is not transmitting. This includes clearing overrun errors and such.
8 ) Be aware that running the rcvr too close to the xmtr can 'swamp' the input to the rcvr, and you may get nothing. If possible, separate them by several feet while debugging.
9) Consider including a 'sequence number' in your data packet. This is an arbitrary number that increments each time a packet is sent. If a packet has to be re-sent for some reason, the sequence number stays the same, so the rcvr knows that it is a repeat of the last packet, rather than a new packet.
10) If you have more than 2 devices, include an 'source address', so that everybody knows who sent a particular packet. Maybe also include a 'destination address', to indicate who is supposed to receive the packet.

Pete