IAN LANG ELECTRONICS

That low-cost pair from Maplin that we used in the last chapter can be used to make a multi-channel radio control unit with a pair of Arduinos.

Actually the phrase multi channel is a bit of a misnomer, as it implies that the frequency of the radio signal changes. It doesn't, it remains the same throughout. What does change is the data we send down it, and this is what simulates the effect of having several different channels. In theory, if we used shift registers, we could have as many as 40 different channels; and if we hooked some on through we could double that. Clever use of AND and OR gates could increase it even more. Just by using the bare pin count on the UNO I could actually get 17, and here's a demonstration of just three.

An Easy Multi Channel RC TX and RX

Go Back www.maplin.co.uk/transmitter-and-receiver-pair-22965

As you saw, I've used two UNO platforms for this, but it'll work with any Arduino board you like. The three buttons on the transmitter are wired like this:

GND

GND

5V

5V

Pin

Pin

Left if you're using mini-tactile switches and right if you're using bigger 2 terminal like I do. Either way these are designed to keep the pins reliably low when the button's not being pressed and high when it is. You'll need three of them wired in the same way if you want to copy the circuit above, and the pin leads from one go to pin 7 of the Arduino, the next to pin 8 and the last to pin 9. If you want to alter this designation, you'll need to alter the transmitter sketch too. More on that later.

 

You need on the receiver side three LEDs, it doesn't matter what colour they are I just used blue, red and green to distinguish in the making stage. They're wired like this:

The three LEDs I used were at pins 10, 11 and 12 of the Arduino at the receiver side. Although here I've shown a 680 ohm forward resistor, in point of fact I used a 560 and the LEDs came to no harm (Fritzing, for some reason, does not have a 560 ohm resistor).

 

Ive made this remote work a few LEDs. In fact it could work anything wirelessly. Adding a motor driver IC gives us a motor controller, and a relay or power transistor gives us the possibility of switching much higher power devices.

 

The two Arduinos together form a complete unit of transmitter (TX) and receiver (RX). What's fairly different about this is that there is only one radio frequency which is 433.92 MHz and that never varies.

 

I don't know if there's a proper name for what we are about to do, so I'm calling it the Singular Hetorodyne Intangible Transfer System or for short the acronym SHI....   oh wait, better think of another name........

We'll call it VDS, or Varying Data Solution. In short, instead of changing the frequency, or the modulation thereof, we send a short, one-character string through the transmitter which is picked up by the receiver. To stop intererence, we send a start byte and four stop bytes. But we only send the stop bytes when a button is not being pressed. That way, even if intererence causes a false start, it's stamped out so quickly it's as if nothing's happened. In effect what we are doing is devising a protocol, and as such we have to make sure that both receiver and transmitter can work with it. Here's the sketch for the TX side:

 

// Transmitter Code

 

 

void setup(){

Serial.begin(2400);

}

void loop(){

  //send out to transmitter

if (digitalRead(7)==1){

  Serial.print("#");

Serial.print("A");

 

}

if (digitalRead(8)==1){

  Serial.print("#");

Serial.print("B");

 

}

if (digitalRead(9)==1){

  Serial.print("#");

Serial.print("C");

 

}

if(digitalRead(8)==0&&digitalRead(9)==0&&digitalRead(7)==0){

Serial.print("~");

Serial.print("~");

Serial.print("~");

Serial.print("~");

}

}

 

There isn't a deal of it. There's a conditional for each button, and one for if no button is pressed. You'll gather then that the more buttons you have, the more conditionals you need. Every one of them works the same way, so we just need to canter through one and we've done them all. Here goes:

 

if (digitalRead(7)==1){

 

Because of the way we wired our buttons, the only way pin 7 can read 1 (which is another way of saying HIGH) is if the button is pressed. So, if the button is pressed, run the code under the conditional:

 

  Serial.print("#");

Serial.print("A");

 

}

 

 

So, this kicks out to the transmitter a hash (#) and a capital A. Respectively they are ASCII codes 35 and 65. The others kick out the hash too, but following on is B (ASCII 66) and C (ASCII 67). This will be important at the RX side.

 

If there isn't any button being pressed, it kicks out just four tildes (~~~~). These are the stop bytes. We might get away with one and four is certainly overkill, but it works. The tilde is ASCII 126.

 

We're using a Baud rate of 2400 because it's a good compromise between speed and accuracy. It's about half the maximum the RX/TX pair can handle, it gets data there at a nice quick rate and not much corruption.

 

Let's look at the RX sketch:

 

int incomingByte = 0;

boolean writeout=false;

void setup(){

  pinMode(12,OUTPUT);

  pinMode(11,OUTPUT);

  pinMode(10,OUTPUT);

Serial.begin(2400);

}

void loop(){

incomingByte=Serial.read();

incomingByte=incomingByte,DEC;

if (incomingByte==35){writeout=true;}

if (incomingByte==126){writeout=false;}

if (incomingByte!=35&&writeout==true){

if (incomingByte==65&&writeout==true){digitalWrite (12,1);}

if (incomingByte==66&&writeout==true){digitalWrite (11,1);}

if (incomingByte==67&&writeout==true){digitalWrite (10,1);}}

if (writeout==false){digitalWrite(12,0);digitalWrite(11,0);digitalWrite(10,0);}

}

 

It looks a bit more fierce, but it's just seven conditionals; two to do with the stop bytes, two to do with the start byte and one for each button on the RX side. Let's canter through:

 

int incomingByte = 0;

boolean writeout=false;

void setup(){

  pinMode(12,OUTPUT);

  pinMode(11,OUTPUT);

  pinMode(10,OUTPUT);

Serial.begin(2400);

}

 

All we do first is set up a boolean and an int variable. The boolean switches states if the serial read contains a start byte, and again if there's a stop. The int gets assigned a numeric value according to what the current serial read is. Then we set the pins the LEDs are attached to to output to get the required current, and match the Baud rate with the TX side.

 

void loop(){

incomingByte=Serial.read();

 

Easy one this. The RX pin of the Arduino is attached to the data out pin of the RX of the pair. So whatever has been sent by the TX will be picked up by the RX, sent to the RX pin of the Arduino and buffered where the Arduino board can read it. Then the numerical value is assigned to the variable incomingByte.

 

if (incomingByte==35){writeout=true;}

 

If it's 35 that's a # and that's our start byte. So set writeout to true.

 

if (incomingByte==126){writeout=false;}

 

126 is ~ so set writeout to false as that's a stop byte.

 

if (incomingByte!=35&&writeout==true){

 

Don't do anything if what's just been read is #, but if not:

 

if (incomingByte==65&&writeout==true){digitalWrite (12,1);}

if (incomingByte==66&&writeout==true){digitalWrite (11,1);}

if (incomingByte==67&&writeout==true){digitalWrite (10,1);}}

 

If an A is read, set 12 HIGH, if it's a B, set 11 HIGH and if it's a C, set 10 HIGH. That's the end of these conditionals, and every time the loop circles it sees this:

 

if (writeout==false){digitalWrite(12,0);digitalWrite(11,0);digitalWrite(10,0);}

}

 

The variable writeout can only be false under two conditions; on startup and when a stop byte is read.A stop byte can only be sent by the TX if no button's being pressed. Ergo, no button being pressed, switch off all the LEDS.

 

There are two upshots to doing it this way. Firstly run the RX without powering the TX. Because the RX/TX pair is noisy, The LEDs will eventually come on. Power up the TX, and they'll go off. A future development would now be to stop the RX working unless it gets a regular signal of readiness from the TX. Secondly, power up both and press any button, and keep it depressed. The LED will light. Now, keeping the first button depressed, press the other two. All three will come on, until you let the first one you pressed go. It's because no stop byte is sent until all buttons are released.

This is a simple way to go about it, and cheap. But it isn't without problems. In the next few weeks I'll be looking at how we can use XBees to do this job more effectively if at increased cost.

 

Ian Lang, Feb 2012.