Building the Arduino sketch

It's now time to build the final sketch for our project. To be really precise, we should say sketches because we will have to develop two of them: one for the Uno board and one for the Yún board. You just have to make one simple change to the hardware at this point: connect the ultrasonic sensor directly to the Yún board by connecting the signal pin to the pin A0 of the Yún board.

Let's first focus on the Arduino Uno sketch. The sketch is inspired by the test sketch we wrote before, so it already includes the functions to control the two DC motors. To communicate between the two boards, we have to include the Wire library that is in charge of handling I2C communications:

#include <Wire.h>

Then, in the setup() part of the sketch, we need to declare that we are connecting to the I2C bus and start listening for incoming events. The Uno board will be configured as a slave, receiving commands from the Yún board, which will act as the master. This is done by the following piece of code:

Wire.begin(4);
Wire.onReceive(receiveEvent);

Let's see the details of this receiveEvent part, which is actually a function that is passed as an argument to the onReceive() function of the Wire library. This function will be called whenever an event is received on the I2C bus. What this function does is basically read the incoming data from the Yún, which has to follow a specific format like you can see in the following example:

speed_motor_1,direction_motor_1,speed_motor_2,direction_motor_2

For example, the first part of the previous message is read back with the following code:

int pwm1 = Wire.read();
Serial.print(pwm1);
char c = Wire.read();
Serial.print(c);

These commands that come from the Yún are then applied to the motors as follows:

send_motor_command(speed_motor1,direction_motor1,pwm1,dir1); send_motor_command(speed_motor2,direction_motor2,pwm2,dir2);

Let's now focus on the Yún sketch. This sketch is inspired by the Bridge sketch that comes with the Arduino IDE and is based on the REST API of the Arduino Yún. To make things easier, we are going to create a new kind of REST call named robot. This way, we are going to be able to command the robot by executing calls like the following in your browser:

myarduinoyun.local/arduino/robot/stop

First, we need to include the correct libraries for the sketch as follows:

#include <Wire.h>
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

Then, create a web server on the board:

YunServer server;

In the setup() function, we also join the I2C bus:

Wire.begin();

Then, we start the bridge:

Bridge.begin();

The setup() function ends by starting the web server as follows:

server.listenOnLocalhost();
server.begin();

Then, the loop() function consists of listening to incoming connections as follows:

YunClient client = server.accept();

The requests that come from these clients can be processed with the following command:

if (client) {
  // Process request
  process(client);

  // Close connection and free resources.
  client.stop();
  }

If a client is connected, we process it to check whether or not a robot command was received, as follows:

String command = client.readStringUntil('/');

if (command == "robot") {   
  robotCommand(client);
}

This function processes the REST call to see what we need to do with the motors of the robot. For example, let's consider the case where we want to make the robot go forward at full speed. We need to send the following message to the Arduino Uno board:

255,0,255,0

This is done by the following piece of code:

if (command == "fullfw") {
  Wire.beginTransmission(4);
  Wire.write(255);
  Wire.write(",");
  Wire.write(0);
  Wire.write(",");
  Wire.write(255);
  Wire.write(",");
  Wire.write(0);
  Wire.endTransmission();
}

We included three other commands for this simple REST API: stop (which obviously stops the robot), turnleft (which makes the robot turn left at moderate speed), turnright (which makes the robot turn right), and getdistance to return the distance coming from the ultrasonic sensor. We also inserted the measure_distance function in the sketch to read data that comes from the ultrasonic sensor.

We are now ready to upload the code to the robot. Remember that you have to upload two sketches here: one for the Uno board and one for the Yún board. The order doesn't matter that much, just upload the two Arduino sketches successfully by carefully ensuring that you are uploading the correct code to the correct board.

Both sketches are available in the following repository on GitHub: https://github.com/openhomeautomation/geeky-projects-yun/tree/master/chapter4/remote_control.

You can then test that the Yún board is correctly relaying commands to the Uno board. At this point, you can disconnect all cables and power the robot with the battery only. Then, go to a web browser and type the following code:

myarduinoyun.local/arduino/robot/turnright

The robot should instantly start turning to the right. To stop the robot, you can simply type the following code:

myarduinoyun.local/arduino/robot/stop

You can also type the following code:

myarduinoyun.local/arduino/robot/getdistance

This should print the value of the distance in front of the robot on your web browser. If you can see a realistic distance being printed on your web browser, it means that the command is working correctly.