433MHz receiver and transmitter

Wireless transmission is getting more and more popular. I will try to show you how does it work using coupled receiver and transmitter which are both working on the same frequency (433MHz).

2015-01-04 14.43.10

The carrier frequency

The 433MHz frequency is the carrier frequency. This means it is a frequency which is used to transport the data. For example when using amplitude modulation (AM) the amplitude of signal is changing. Knowing this you can determine if 0 or 1 is being send.

Radio modules

I will focus on two modules:

Receiver: RRFQ1-433

Transmitter: RTFQ2-433

Those two modules use FSK (frequency shift keying) frequency modulation to encode the data into the carrier frequency. To send logical ‘1’ it uses a frequency slightly higher then the carrier frequency. While sending logical ‘0’ the frequency transmitted is slightly lower than the carrier frequency.

Practical approach

A simple device was assembled. We can distinguish two sides: the side of the transmitter and the side of the receiver. Both parts are equipped witch Arduino. The task is simple. The transmitter reads analog value of a joystick which is connected to one of ADC channels, after that the read value is send using the transmitter module. On the other side the receiver gets the data and displays it using a LED. The read data is used to change the brightness of the LED by changing the duty of a PWM signal. Also a RC servo is connected that moves accordingly to the joystick’s movements.

Radio module library

A library was used in this project which delivers the interface for communication with the radio modules.

This library allows you to transfer the data via radio waves. Let’s say that we have a string which we want to send. The transmitter sends byte after byte and to be more precise a bit by bit. For example we want to send a string which starts with capital later ‘A’. ‘A’ has ASCII code equal to 0x41 which in binary is equal to 0b01000001. To send this letter we need to send :
One 0,
One 1,
Five 0s,
One 1.

The 0s and 1s are encoded by patterns which can be easily distinguished on the receiver side. For example, if you would like to send logical one you first set the input of transmitter module to high state which lasts for period of time t. Then it is followed by a low state which last period of time equal to 3t. When you would like to send logical zero then you set the transmitter’s input to high for 3t and then to low for t. Below you have a quick summary:

1 – 1H, 3L
0 – 3H, 1L

You can of course switch the patterns (this is done in RCSwitch Arduino library).

Interferences / Noises

During communication you may experience some data lost. It is due to the interferences. One way of dealing with such phenomenon is to change the duration of the low and high state while transmitting data. Another way is to change patterns. All of this does not come without cost. You pay for robustness with a longer transmission time. All of those mentioned techniques are implemented in an Arduino library RCSwitch.

The source code

There are two Arduino boards. Both, the receiver and the transmitter are based on the Arduino platform while extended with two software libraries:

  • RCSwitch – allows you to handle the wireless communication,
  • SimpleTimer – enables event based programming. You can create routines and add them to the simple scheduler which handles the execution of those routines. Something similar to what was described in A small operating system.

Receiver

2015-01-04 14.43.20

Below you can see a snippet of the code.

#include "SimpleTimer.h"
#include "RCSwitch.h"
#include "Servo.h"

#define X_AXIS    10
#define Y_AXIS    11
#define SW_AXIS    4

RCSwitch mySwitch = RCSwitch();

SimpleTimer timer;

Servo servo;

void setup()
{
    timer.setInterval(100, DoWork);

    pinMode( A0, INPUT);
    pinMode( A1, OUTPUT);

    pinMode( SW_AXIS, OUTPUT);
    pinMode( X_AXIS, OUTPUT);
    pinMode( Y_AXIS, OUTPUT);

    mySwitch.enableReceive(0);

    servo.attach(7);
}

void loop()
{
    timer.run();
}

void DoWork( void)
{
    static int state;

    static long int data;
    static int x, y, sw;

    state = 0;

    if (mySwitch.available())
    {
        data = mySwitch.getReceivedValue();

        //first 12 bits carry x value
        x  = data & 0xFFF;
        //another 12 bits carry y value
        y  = (data << 12) & 0xFFF;
        //one bit carry switch state
        sw = (data << 24) & 0x01;

        //data ready
        state = 1;

        mySwitch.resetAvailable();
    }

    if(state == 1)
    {
        //control RC servo
        x = map(x, 0, 1023, 0, 180);
        servo.write(x);

        //control LED with PWM
        y = y << 2;
        analogWrite(Y_AXIS, y);

        //control LED
        digitalWrite(SW_AXIS, sw);
    }
}

 

Transmitter

2015-01-04 14.44.16

Snipped of code for transmitter part:

#include "TimerOne.h"
#include "RCSwitch.h""

#define X_AXIS            0
#define Y_AXIS            1
#define SW_BUTTON        A2

RCSwitch mySwitch = RCSwitch();

int counter;

void setup()
{      
    Timer1.initialize(100000);
    Timer1.attachInterrupt(DoWork);
    
    pinMode(SW_BUTTON, INPUT_PULLUP);
    
    mySwitch.enableTransmit(10);
    mySwitch.setProtocol(1, 250);
}

void loop()
{
    delay(100);
}

void DoWork( void)
{
    static int x, y, sw;
    static long int data;
    
    x = analogRead(X_AXIS);
    y = analogRead(Y_AXIS);
    sw = digitalRead(SW_BUTTON);
    sw ^= 0x01; //togle bit
    
    //send via wireless connection
    data = x & 0xFFF;
    data |= ((long int)(y) & 0xFFF) << 12;
    data |= ((long int)(sw) & 0x01) << 24; 
    mySwitch.send(data, 25);
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.