Introduction: Arduino Radio Controlled Robot

About: JavaScript developer and Arduino enthusiast

Working as a developer, not so long but nevertheless, I’ve realized that most important qualities in our profession, and probably in all professions, is the ability to learning, and a wish to do it. By that I mean the endless curiosity, the main driving force of human development in all areas. If you have such feeling, if you have a desire to know how such mundane thing as LED lamp, radio, cellphone or even computer works, then we have something in common.

Recently I’ve discovered an open-source platform used for building electronics projects called “Arduino”. Open source means that anyone can modify and produce derivatives of Arduino boards. That’s why it’s so popular and cheap (you can buy it for 5 dollars on ebay). But the main advantage of it is simplicity. It doesn’t require any deep knowledge or skills in programming or electronics to write your first sketch and make the LED blink. So it is a great starting point of learning programming, electronics and electrical engineering. At some point you will get tired lightning LED’s and you’ll want to create something new, something that can move and interact with environment, something like a robot. If so, you are in the right place. In this article I will show you how to create and program Arduino-based robot which can be remotely controlled from your computer.

Step 1:

First of we need an arduino board itself, it can be Mega, Uno, Nano, or any other kind. In my case it will be Uno. Next we need chassis for our robot. Luckily, there are plenty of different robo-kits on ebay which already include motors, reducers, wheels and encoder wheels. You can choose any type, for example 4 wheels or caterpillar chassis, it doesn’t matter. The only requirement is that it should be enough space for placing our arduino board and other modules. I will stop on 2-wheel chassis like on pic-1.

Step 2:

Like most kits this includes very common DC brush motors. This means that to make them run we need to connect one wire of motor to 5 volts and another to ground. If we change the order it will be spinning in another direction. In order to turn left or right our robot will be running the first motor forward and the second one reverse and vice versa. But how to achieve this using Arduino? The first thing that comes to mind is to connect two motor wires to arduino digital pins and pass HIGH to one and LOW to another. But we shouldn’t do so, because it can damage our pin or even destroy whole board. Arduino input/output pins can handle only 40mA of current. In case of our motors it will be approximately 200mA which is too much. There are ready solution for this problem - the motor driver. It’s a module, the main function of which is to take a low-current control signal and then turn it into a higher-current that can drive a motor. To change the polarity of current flow and change the direction of spinning we need H-bridge motor driver. The L298D, shown on pic. 2, is suitable for all our requirements.

This module can drive 2 DC-motors with current about 2A and voltage of 30V which is more than enough for our purposes. Also it comes with integrated 5V voltage regulator and output from which very we can supply our arduino. But this is the case only if we supply our driver with voltage less than 12V. We will be using 2 Li-ion batteries with voltage around 3.7V in parallel, so the resulting voltage will be around, 7.4V which is ok.

Step 3:

Now it’s time to connect our driver, motors and batteries. On pic-3 you can see where each pin of arduino should be connected.

Notice that we’ve connected 5V from driver directly to 5V pin on our arduino and not to Vin pin. Because Vin pin is connected with arduino’s built-in voltage regulator, and we already have regulated 5 volts from our driver, so we simply bypass it.

Step 4:

Next step will be the radio module for remote control. As radio module we will be using nrf2401l. It is very cheap but still great module which can act as receiver and transmitter with range up to 60 meters, and bandwidth rate up to 2Mbit/s. But there is one issue, nrf2401l is powered by 3.3V. Arduino has 3.3V pin and we can supply it using this pin, but the module current requirement rises sharply while transmitting and Arduino cannot supply it (3.3V pin on most Arduino boards can supply only up to 50 mV), so it won’t work in such way. Fortunately there is simple solution to this issue. We need to solder 10µF electrolytic capacitor in parallel to power supply. You can solder it directly to module’s VCC and GND pins as I did (pic. 4), but don’t forget about the polarity of capacitor.

Step 5:

Of course, you can simply use some external 3.3 V supply. Also there are small 3.3 voltage regulator modules available on market (pic. 5) which you can connect directly to 5V of Arduino and VIN of radio module.

Step 6:

Once we finished with power supply it is time to connecting it up. Follow the scheme shown on pic. 6.

Step 7:

So now we have our arduino connected with motor driver and radio module. Let’s place it on our chassis. You can use screws, or hot glue to stick it in place. On picture 7 you can see how my robot looked like at this stage.

In order to control it remotely from computer we need another arduino board with nrf2401l radio module. You already know how to connect it so it should not be a problem. This arduino board will be our “base”. Once you connected it we can finally start to write some code. Let’s start with our robot. Open your Arduino IDE and create a new sketch. Create two new tabs named “Motor.h” and “Motor.cpp”. As you can guess, it will be our class for working with motors. Open tab “Motor.h” and define the next class:

class Motor {
private: byte throttlePin, forwardPin, reversePin; byte throttle; public: void attach(byte, byte, byte); void setThrottle(int throttle); void forward(); void backward(); void stop(); };

The code is very simple. In order to run motor forward we need to pass HIGH signal to forward pin and LOW to the reverse pin. These pins are connected to corresponding motor driver’s pins (IN[1-4]). Throttle is connected to driver’s EN[1-2] by which we can control the voltage passed to each motor. As our motors are capable only for 6 volt, we don’t pass max possible value (eq. 255). For now, let it be 200. Our next class will be the “Chassis”. Create new tabs, “Chassis.h” and “Chassis.cpp” and write the next code:

#include "Motor.h"

void Motor::attach(byte throttlePin, byte forwardPin, byte backwardPin) { this->throttlePin = throttlePin; this->forwardPin = forwardPin; this->reversePin = reversePin; this->maxThrottle = maxThrottle; pinMode(throttlePin, OUTPUT); analogWrite(throttlePin, 200); // throttlePin sets the voltage on motor, let it be 200 for now pinMode(forwardPin, OUTPUT); pinMode(reversePin, OUTPUT); }

void Motor::forward() { digitalWrite(forwardPin, HIGH); digitalWrite(reversePin, LOW); }

void Motor::reverse() { digitalWrite(forwardPin, LOW); digitalWrite(reversePin, HIGH); }

void Motor::stop(){ digitalWrite(forwardPin, LOW); digitalWrite(reversePin, LOW); }

Here we define simple interface for our chassis. Now, in order to move forward we can simply call “chassis.forward()” from our main sketch file. To facilitate our work with radio module we will be using a library. Download it here, and add to Arduino library folder.

Next to add a new folder to Arduino libraries, called “Message”. Open this folder and create a new file “Message.h”, then define next class:

#ifndef MESSAGE_H
#define MESSAGE_H

enum MessageType { MOVE_FORWARD_MESSAGE, MOVE_BACKWARD_MESSAGE, TURN_LEFT_MESSAGE, TURN_RIGHT_MESSAGE, STOP_MESSAGE };

struct Message { byte type; int payloadL; int payloadH; };

#endif

It is a class for radio-message. We will be sending it from our base to our robot using the NRF2401L library. Our message size is 5 bytes. First byte is for the type and the rest for the payload, which is for later use. We have added it to library folder in order to not duplicate it in two sketches, for the robot and for the base. Now we can start writing our main sketch file:

#include
#include "Message.h" #include "Chassis.h"

RF24 radio(7,8);

byte addresses[][6] = {"1Node","2Node"}; // Each radio module must have an address. “1Node” is our robot address and “2Node” is the base address

Chassis chassis;

void setup() { radio.begin(); radio.setPayloadSize(sizeof(Message)); // Default payload size is 32 bytes. If we don’t specify it, unused bytes of the message will be filled with zeros radio.openWritingPipe(addresses[1]); radio.openReadingPipe(1,addresses[0]); radio.startListening(); // Entering receiver mode chassis.setEncoderDataListener(sendEncoderData); chassis.attachLeftMotor(6, 4, 0); chassis.attachRightMotor(5, 1, A0); }

void loop() { Message inRadiomessage; if(radio.available()) { // If there is a received message in message buffer while(radio.available()) { radio.read(&inRadiomessage,sizeof(Message)); // Get the most recent message from buffer } processMessage(inRadiomessage); } }

void processMessage(Message msg) { switch(msg.type) { case MOVE_FORWARD_MESSAGE: chassis.forward(); break; case MOVE_BACKWARD_MESSAGE: chassis.backward(); break; case TURN_LEFT_MESSAGE: chassis.turnLeft(); break; case TURN_RIGHT_MESSAGE: chassis.turnRight(); break; case STOP_MESSAGE: chassis.stop(); break; } }

That’s it for the robot, now it is ready for receiving messages from the base. So let’s start with new arduino sketch for our base. Here’s the code for it:

#include "RF24.h"
#include "Message.h"

RF24 radio(7,8);

byte addresses[][6] = {"1Node", "2Node"};

void setup() { Serial.begin(115200); radio.begin(); radio.setPayloadSize(5); radio.openWritingPipe(addresses[0]); radio.openReadingPipe(1,addresses[1]); radio.stopListening(); // Entering transmitter mode }

void loop() { if(Serial.available()) { // If there is some data in serial buffer char serialInMsg[16]; byte length = Serial.readBytesUntil('\n', serialInMsg, sizeof(serialInMsg)); // Waiting until whole message received serialInMsg[length] = '\0'; // Making it null-terminated Message outRadioMessage = getMessageFromSerial(serialInMsg); radio.write( &outRadioMessage, sizeof(Message)); return; } }

Message getMessageFromSerial(char * serialInMsg) { Message msg; char *msgType = strtok(serialInMsg, ","); // Splits message by ‘,’ symbol switch(msgType[0]) { // First indicates the message type case 'F': { msg.type = MOVE_FORWARD_MESSAGE; } break; case 'B': { msg.type = MOVE_BACKWARD_MESSAGE; } break; case 'L': { msg.type = TURN_LEFT_MESSAGE; } break; case 'R': { msg.type = TURN_RIGHT_MESSAGE; } break; case 'S': { msg.type = STOP_MESSAGE; } break; } return msg; }

Base is waiting for incoming messages from serial port and sends them via radio module to robot. The serial message format is simple: first character is the message type, then zero or more parameters separated by “,” symbol, “/n” indicates the end of the message. For now we won’t pass any parameters. The final part is the computer program which will be sending messages via serial port to our base. As programming language we will be using Processing as it allows to create simple program for our purposes in a couple of minutes.

Open Processing IDE, create new sketch and enter the next code:

import processing.serial.*;

Serial port;

IntList pressedKeys = new IntList();

void setup() { port = new Serial(this, {Enter serial port}, 115200); // Initialize serial port } void keyPressed() { if(!pressedKeys.hasValue(keyCode)) { pressedKeys.push(keyCode); } sendMoveMessage(keyCode); }

void keyReleased() { pressedKeys.removeValue(keyCode); if (pressedKeys.size() > 0) { int lastPressedButton = pressedKeys.get(pressedKeys.size()-1); sendMoveMessage(lastPressedButton); } else { sendStopMessage(); } }

void sendMoveMessage(int pressedKeyCode) { switch(pressedKeyCode) { case 87: // W key port.write("F\n"); break; case 65: // A key port.write("L\n"); break; case 83: // S key port.write("B\n"); break; case 68: // D key port.write("R\n"); break; } }

void sendStopMessage() { port.write("S\n"); }

Don’t forget to change serial port in this code. It should be port to which arduino base is connected. You can check it in arduino IDE Tools->Port. On Windows it should look like “COM[number]” and on Linux “/dev/ttyUSB[number]”.

That’s all code we need to send messages to our base via serial port. It can be even fewer, but because of Processing has not really good built-in key pressing handling, we have to write this extra code to handle it manually.

You can try to start this program and press “WASD” on your keyboard, if you connected all right robot should be moving, finally.

In this article we have created our arduino based robot which can be controlled remotely via computer. I hope you had a nice time by creating it and also learned something new and useful.

In the next part we will try to make our robot sense the environment and send some data, based on this information, back to the computer program.