Robohaat – From Software to electronic gadgets Part IV : Working with LEDs

Let’s look at an improved version of the previous sketch:

iv

sketch and upload it to your board to test it.

If you understood the first sketch then you can probably figure out what this version does easily.

In the setup function in addition to initializing the serial port like before I’m also initializing pin 13 as an output pin. Recall that digital pins can be used as inputs or outputs, so whenever you need to use a pin you have to configure it for the intended use. In this case I’m making it an output pin, which means that I can write a value to this pin, and the value I write will affect the electrical current coming out it. See the pinMode documentation for details on this.

The loop function prints the message to the serial port like before, but then sets pin 13 to a HIGHstate with the digitalWrite function. In most Arduino boards this lights the on-board LED. Then the program pauses for 500 milliseconds, or half a second. Then the state of pin 13 is changed toLOW to turn the LED off. Then the program sleeps for another half a second.

The loop function is called over and over again, so what the above code does is make the LED blink! It blinks at a rate of one blink per second, staying on for the first half second, then off for the other half.

Programming the Distance Sensor

Now you know how to do the basic stuff that appears in every Arduino introductory tutorial. Are you ready to do something real with your Arduino? I hope you are!

I’m going to show you how to program the HC-SR04 distance sensor. Recall that I will be using this sensor to help my robot “see” and avoid walls and obstacles.

For most devices that connect to the Arduino board there are already appropriate libraries of functions incorporated into the Arduino software. You can see what libraries are included by going to the Sketch menu, “Import Library…” submenu. You will see libraries there for motors, LCDs and a variety of other devices.

Unfortunately there is nothing for distance sensors. So how can one control such a device?

In most cases manufacturers of Arduino compatible devices provide the required libraries to control their products. Other times developers write their own libraries and make them available as open source. The documentation of the device is the first place to go, but as always in cases like this, Google is your best friend.

Searching around I’ve found not one but three open source Arduino libraries for my distance sensor, here, here and here. I quickly reviewed them and out of the three the arduino-new-pinglibraryappeared to be the most complete, so I decided to give that one a try first. If that one does not work I can always go get one of the other two.

The library comes in a zip file, available as a download link in the page linked above. To install it and make it available in the Arduino software you just need to unzip it and copy the top folder (called NewPing) inside the libraries folder in your Arduino sketches folder. The Arduino sketches folder is in your home directory, see the documentation for details.

After you install the NewPing library close and reopen the Arduino software so that it can recognize it.

Now start a new sketch, go to the Sketch menu and select “Import Library…”. You should now see NewPing in the list. If you select this library the following line will be added to your sketch:

#include<NewPing.h>

This is telling the C++ compiler that you will be using the functions from the NewPing third party library. Note that you don’t have to go through the menus to get this text written for you, if you prefer you can write it yourself.

Before I show you the sketch that controls the distance sensor take a look at the following wiring diagram:

Distance Sensor

 

As you see in the diagram I’m using the breadboard and some jumper cables to make all the connections.

First I connected the 5V output from the Arduino to the “red” side of the top section of the breadboard, and the GND line to the “blue” side. The top and bottom sections of the breadboard have “red” and “blue” sides, and these are typically used to distribute power and ground lines to the whole breadboard. Plugging the 5V output to one of the red pins makes the 5V available to all the red pins in that row, and likewise, connecting GND to a blue pin makes GND available in all the blue pins in the row.

Next I transferred the 5V and GND lines to the bottom part of the breadboard with two more jumper cables. This is always a good practice when prototyping, setting up the breadboard like this ensures that you can always grab your power and ground lines from the side that is most convenient.

The distance sensor plugs nicely into four consecutive pins in the middle of the breadboard. The two middle sections of the breadboard connect groups of five vertically aligned pins together, so to make a connection to one of the sensor pins I just plug one end of the jumper cable into any of the remaining four pins in the same group.

The leftmost pin is labeled VCC, this is the pin that should be connected to the 5V line. So to do that I connect a jumper cable to this pin from the sensor to one of the red pins in the breadboard bottom. The next two pins are labeled Trig and Echo. These connect to any two available pins in the Arduino board. Since any pins will do, I will be using analog pins 0 and 1, which as I said before can double up as digital pins 14 and 15. The rightmost pin is labeled GND, so the connection can go to any of the blue pins at the top or bottom of the breadboard.

Here is an actual picture of how this circuit looks in real life:

Du

So far it’s been pretty easy, right?

Let’s see what the sketch looks like:

cod

There are a couple new things in this sketch that I haven’t used in the previous ones, but overall things are largely similar.

The #include statement at the top tells the C++ compiler that I will be using a third party library. The NewPing.h between the angle brackets refers to a header file that is inside this library. This file contains the definitions for all the functions provided by the library. If a library does not have documentation, chances are there is information at the top of this file.

Next there are a few #define lines. If you recall the LED blinking sketch from above, I have written the pin number 13 in a couple of places there. Instead of using the number directly I could have defined a constant. That’s what #define does. You use it to give a value a meaningful name, then in the rest of the sketch you can write the name instead of the value. This is useful to make the code more readable, but also makes it very easy to change the pin assignments, because then you just go to the top of the sketch and update the numbers in just one place.

In this sketch we have three #define statements. The first two create constants for the Trig andEcho pins of the distance sensor which I connected to pins 14 and 15 respectively (analog pins 0 and 1). The third #define is to set a constant for the maximum distance that I want the sensor to recognize, which I set to 2 meters, using centimeter units.

Next we have the following statement:

NewPingDistanceSensor(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

This statement creates an object that represents the distance sensor. The syntax for object creation requires the class of the object first (NewPing in this case), then the name I want to give the object (DistanceSensor) and then any arguments enclosed in parenthesis. The arguments that the NewPing object requires are the trigger pin, the echo pin and the maximum distance to consider, all in that order and separated with commas. These happen to be the three constants defined above, so I can write the names instead of the values.

Note that the object is created outside of any functions. Objects can exist only at the level they are created, so creating the object inside the loop function would make it disappear when that function ends. The next time loop is called a new object would be created and initialized, which would be a waste of time and effort. Putting the object creation outside of any functions makes it aglobal object that persists across function calls.

The setup function is exactly like the one I used before, it just sets up the serial communication so that we can see output from the Arduino board in the Serial Monitor.

The loop function starts with a type of instruction that I haven’t used before:

unsignedint cm =DistanceSensor.ping_cm();

Let’s analyze this statement one piece at a time. To the right of the = sign I am invoking a function called ping_cm provided by the DistanceSensor object created above. This function is slightly different than functions I used before, because in addition to doing something it returns a result, which in this case is the distance to the closest object measured in centimeters.

Since I intend to use this distance result later in the sketch I have to store it somewhere, so to the left of the = sign I have created a variable, which is basically a space in memory where a value can be stored. The C++ syntax for variable creation requires me to provide the type of values this variable will store first (unsigned int in this case, a positive integer) and then the variable name, which is any name of my choosing that I will use later to refer to the value stored in the variable.

As a side note, the distance sensor library documentation indicates that there is also a ping_infunction that is equivalent to ping_cm but returns the distance result in inches. Another option provided by the library is a function ping, which just returns the time it took the ultrasonic signal to make a round trip back to the sensor in microseconds. You can then divide this time by the time it takes sound to travel twice the distance units of your choice to get the distance in those units. For my purposes having the distance in centimeters is accurate enough.

Next in the loop function I have three consecutive prints to the serial port. The first two prints use the Serial.print function and the last uses Serial.println. That means that the second and third prints will go to the same line as the first, and after the third message is printed the cursor will move to the next line.

The first and last print statements print text messages like in the previous sketches. The middle print, however, prints the cm variable, in which I have the result of the distance sensor ping_cmfunction.

The final line in the loop function does a delay of one second, exactly like before.

When you run this sketch on your board and move your hand or some other object closer and farther away from the sensor you will see something like this in the serial monitor:

Distance:28cm

Distance:28cm

Distance:21cm

Distance:18cm

Distance:15cm

Distance:15cm

Distance:12cm

Distance:12cm

Distance:24cm

Fun with motors

Let’s move on to something else. The vehicle kit that I’m using for my project comes with two wheels, each with an attached motor.

The motor driver board that I have is the Adafruit Motor Shield, which comes with its own library, called AF_Motor. If you are using the same motor controller then go ahead and install this library in your Arduino environment. If you are using a different motor controller then you’ll have to find the library that works for your hardware.

Most motor controllers come as a shield, which means that the motor board plugs right on top of the Arduino board, connecting to both rows of pins, even though many of the pins are not used to control motors. The nicer motor shields provide pass-thru headers with access to all the Arduino pins. Unfortunately the Adafruit shield does not give access to the pins, so connecting additional components becomes difficult. This is a problem I’ll have to work around.

The Adafruit motor controller can drive up to four DC motors, labeled M1 through M4 in the board. I need just two, so for convenience I’m going to connect my two motors one on each side of the board, using the M1 and M3 connectors.

To test the motors on the assembled kit I turned it upside down, so that I can see the wheels turn without the vehicle moving while the Arduino is connected to the USB power. The motor connections are extremely simple, each motor has just two connections:

Dec

The Arduino board is hidden underneath the motor shield in this picture.

Here is the sketch that I used to test the motors:

#include<AFMotor.h>

AF_DCMotorMotor1(1);

AF_DCMotorMotor2(3);

void setup(){}

void loop()

{

Motor1.setSpeed(255);

Motor2.setSpeed(255);

Motor1.run(FORWARD);

Motor2.run(FORWARD);

delay(1000);

Motor1.run(BACKWARD);

Motor2.run(BACKWARD);

delay(1000);

Motor1.run(FORWARD);

Motor2.run(BACKWARD);

delay(1000);

Motor1.run(BACKWARD);

Motor2.run(FORWARD);

delay(1000);

Motor1.setSpeed(0);

Motor2.setSpeed(0);

Motor1.run(BRAKE);

Motor2.run(BRAKE);

delay(1000);

}

I don’t think I need to explain every line in this sketch, since it does not have any new C++ constructs. Like the distance sensor, each motor requires an object to be created, this time one of class AF_DCMotor. The only argument is the motor number, from 1 to 4. I created two motors, numbers 1 and 3 to match the motors connected to ports M1 and M3 of the controller.

The motors are controlled with two functions, setSpeed and run. The setSpeed function takes a numeric argument with range 0 to 255, indicating the speed the motor should turn. The runfunction configures the mode in which the motor runs, which can be FORWARD, BACKWARD, BRAKEor RELEASE.

The sketch above makes the wheels do a few tricks: one second of both wheels going forward, then one second of both wheels going backwards, then one wheel forward and the other backwards, then each wheel reverses direction, then the wheels stop for a second. Then the cycle repeats with the next invocation of the loop function.

Remote Control over Bluetooth

The final piece of hardware that I intend to use in my Android robot vehicle is the Bluetooth slave, which connects to my smartphone to receive remote control commands.

I expected bluetooth communication would be the most complex aspect of my project, but after reading the one page documentation that came with my device I was proved wrong. Turns out the bluetooth slave works over the standard serial communication protocols in the Arduino board, which means you use the functions in the Serial class like I used in all the previous sketches. When the Arduino board with Bluetooth is paired with a smartphone a Serial.print command will send the data not to the PC but to the phone! The Serial class also has functions to read data from the other end, so I will use these functions to receive commands from the smartphone.

The wiring of the bluetooth slave is pretty simple:

Remote Control over Bluetooth

Note how the RX and TX pins in the Bluetooth slave go to digital pins 0 and 1 respectively, the pins that are dedicated to serial communications.

This is how my actual circuit looks like with everything connected, noting that in the picture below the Bluetooth dongle is facing the other side, so the connections appear reversed from the diagram above:

Bluetooth

 

An example sketch that allows remote communication is below:

bluetooth code

bluetooth code1

The setup function does not have anything I haven’t done before. From reading it you can guess that I’m going to be playing with the pin 13 LED again.

In the loop function I’m introducing a new type of C++ statement, the if statement, sometimes also called conditional. A conditional is useful when you want the program to do something only when a condition is true.

What follows after the if keyword is the condition, enclosed in parenthesis. In my sketch the condition that I’m checking is Serial.available() > 0. To know if this condition is true or not the Arduino will invoke the function Serial.available, which returns the number of data bytes that have been received in the serial port, and compare that number against 0. If the number of available bytes is greater than 0 then the condition is true, so the instructions that are between the opening and closing curly brackets will be executed. If the condition is not true, then the whole group of instructions inside the curly brackets will be skipped.

Do you understand why a conditional makes sense in this case? The Serial.available function will return a positive number only when the master on the other end of the serial communication has sent data. Saying if Serial.available() > 0 in C++ is the same as saying “if there is data available” in English. If the condition is not true (which is the same as saying it is false), then it means that at that moment the remote controller has not sent any data, so in that case I have nothing to do and skip the whole thing.

So what happens when the condition is true?

The very first thing I do inside the if block is read a byte from the serial port, using theSerial.read function. Note that I use a variable to store the result, but this time I declared the variable with the type char, which in C++ is the type that represents one byte of data.

Once I have my byte of data I print it, using our old friends the print and println functions.

After I print the data received I have another conditional (note how I indent my sketch to make it very clear that I have one if statement inside another). This time my condition is ch == ‘a’, which as I’m sure you guessed, will be true only when the lower case letter a is the data received. In that case I set pin 13 to HIGH, which turns the LED on.

The else statement that follows is an extension to the if. I said before that when the ifcondition is false the instructions inside the curly brackets are skipped. When a conditional has both if and else blocks the condition determines which of the two blocks executes. If the condition is true the block that follows the if executes and the block that follows the else is skipped. If the condition is false the block that follows the if is skipped and the block that follows the else executes.

Do you see what this conditional does, then? When the Arduino receives an a it will turn on the pin 13 LED. Any other data received will turn it off. With this simple sketch I built a remote control for the LED in the Arduino board!

When trying to upload this sketch to my Arduino I’ve found that often the upload failed. I believe this is a result of a collision between the serial communication established by the computer and the one from the Bluetooth slave. It appears that the Bluetooth slave wins and prevents the computer from talking to the Arduino. I have found that disconnecting the RX and TX pins from the Bluetooth slave when I need to upload a new sketch solves the issue.

Are you ready to try this?

Go ahead and install BlueTerm in your Android device. This app works exactly like the Serial Monitor from the Arduino software. I suppose there is an equivalent app for iOS, if you have found one that works please let me know in the comments below.

Update: It appears that nBlueTerm is an equivalent application for iOS devices, though I haven’t had a chance to test it yet.

If you don’t have a smartphone or the Bluetooth slave you can try this sketch using the serial communication to the computer and the Serial Monitor.

Once you have the app in your Android device and the sketch uploaded to the Arduino you are ready to go. Start by powering up the Arduino (via USB cable or power supply). The red LED in the Bluetooth slave will blink rapidly, indicating it is ready to pair with another device. Start BlueTerm in your smartphone and select “Connect Device” from the menu. The Bluetooth pairing window should appear and should show a device with name linvor. Select this device to establish a connection. Use 1234 as pairing code.

Once the connection is established the LED in the Bluetooth slave goes steady, and on the smartphone you have a terminal like the one in the Serial Monitor. Any letters that you type are sent over to the Arduino, and the Arduino responds back with a message that confirms that it has received the same letter. When you type the lower case letter a in addition to the above the LED in the Arduino board lights up. When you press any other key the LED goes off. Pretty cool, right?

Final words

I hope you found the information in this article useful. Please let me know if you have any questions below in the comments.

In the next article I’ll be discussing a much lighter topic. I will show you how I mounted and connected all the hardware into the vehicle kit platform. Then after that I ‘ll show you how I developed the firmware for my robot from scratch!

As always, I thank you for being a loyal reader. I hope to see you next time!!!!

admin

Leave a Reply

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