Archive

Author Archive

Make:it Robotics Starter Kit – Download Files

September 15, 2014 1 comment

Apparently Radio Shack has changed the link to where you can download the program code for the Make:it Robotics Starter Kit.  I will put the zip file here on my site so everyone can download the files directly from my blog site.

WordPress does not allow the uploading of .zip files so I renamed the file as Program_Files.doc.

To download just click on the below link.  Once downloaded just double click on the files to unzip or rename .doc to .zip, if you want to keep the .zip file for archive and cannot remember that the extension name change.

Enjoy

Program_Files

Categories: Robots

Make:it Robotics Starter Kit – Sending Sensor Data Wirelessly

July 29, 2014 Leave a comment

In this blog post we are going to take what we learned in “Make:it Robotics Starter Kit – Wireless Connectivity” and “Make:it Robotics Starter Kit – Capturing Sensor Data” and combine this data to capture sensor data in real time and send this data to a program running on our computer wirelessly.

So if you do not have your robot configured to use the Transmitter and receiver, take a look at the blog post “Make:it Robotics Starter Kit – Capturing Sensor Data” and re-configure your robot and FTDI cable.

In order to send sensor data to our computer we again have to make a few small changes to our lineFollow.ino Arduino program:

Comment out the following line, as we no longer need our counter variable.


// int counter;

Comment out the variable initialization of the counter variable:


// counter = 0;

In the loop() function of the program comment out the following lines:

// mySerial.println(counter, DEC);
// counter++;

Add the following line to the loop() function:


mySerial.println(action1, HEX);

if(action1 != action2)
{
if (action1 == 3 )
line_following.go_forward(50);
if (action1 == 1)
line_following.line_following_turn_left(50);
if (action1 == 2)
line_following.line_following_turn_right(50);
if (action1 == 0)
line_following.go_forward(50);
}
action2=action1;
}

When we run the robot our sensor data will be send out wirelessly to our computer, but we do not want to just capture the serial data using the Serial Monitor with the results being displayed as hex numbers.

We want to display in real time the actual directions the robot is being given based on the sensor data.

In order to do this we cannot use the Serial Monitor. We must write a program that has similar logic as our lineFollow.ino program.

So we are going to develop a Python program that reads the serial port data and print out the directions that the Robot is being given in plain English.

Here is the Python program, we will analyze the program in a bit.

If you have not done so, refer to the earlier blog post “Make:it Robotics Starter Kit – Binary Part 1″ and watch the Video on how to setup Python on your computer.


'''
Program: readSerial.py
Author: Joe Pitz
Description:

reads the serial port and prints out the
direction the robot is turning.
go forward, turn right, turn left.

'''

import serial
import time

def main():

    ser = serial.Serial('COM3', 1200, timeout=0)
    while 1:
        value = ser.read(1)
        if value >= '0' and value <= '3':
            if value == '0' or value == '3':
                print "Go Forward"
            if value == '1':
                print "Turn Left"
            if value == '2':
                print "Turn Right"

if __name__ == "__main__":
main()


import serial
import time

The import statements provide library functions that our Python program need in order to communicate to the serial port.


def main():

The statement defines a function called main()


ser = serial.Serial('COM3', 1200, timeout=0)

This statement creates a serial object and tells the object what serial port to listen on, what baud rate to use and timeout=0 is used to read the data when it is available without waiting.


while 1:

The while 1: statement is used to start a loop that repeats and does not end as the condition of 1 is always true.


value = ser.read(1)

Here we read one byte of data from the serial port and store this value to the value variable.


if value >= '0' and value <= '3':

If the contents of the value variable is between 0 and 3 execute the contents of the if statement


if value == '0' or value == '3'
print "Go Forward"

If the value variable is either 1 or 3 then execute the print “Go Foward”
message.


if value == '1':
print "Turn Left"

If the value variable is 1 then print the message “Turn Left”


if value == '2':
print "Turn Right"

If the value variable is 2 then print the message “Turn Right”


if __name__ == "__main__":
main()

If this program is being executed and not a library file then execute the main function.

Remember Python is an indent sensitive sensitive language. If your indentation is not correct your program will generate syntax errors when you try to execute it. Count your indentation spaces when coping the code in your text editor.

Remember when you plug your USB cable into to program the Arduino you will have to make sure your serial port is correct for the Serial Port Settings in the Arduino IDE. Refer to the blog post “Make:it Robotics Starter Kit- Capturing Sensor Data” for information on how to determine the correct Serial Port and how to setup the Arduino IDE.

If you use a different USB Port for your FTDI USB cable, your Serial Port will be different as well.

Place your readSerial.py program in a folder on your computer and start a Command Prompt and change directory to the same folder location of your readSerial.py program.

Run the command from your Command Prompt:


Python runSerial.py

If you encounter any errors, check that your runSerial.py program is set to the correct serial port. make sure you have your driver board and FTDI cable wired correctly. If you are getting strange characters being printed to your command prompt, check to make sure your baud rate is the same in the Arduino lineFollow.ino and readSerial.py programs.

If you did everything correct, when your robot is following the black line your Python program should output something like the following:

pythonserial

Categories: Robots

Make:it Robotics Starter Kit – Wireless Connectivity

July 23, 2014 Leave a comment

In this blog post we are going to take the information that we learned in the earlier blog post entitled “Make:it Robotics Starter Kit – Software Part 2″ and capture real time sensor data and send this data wirelessly to our computer.

In order to complete this section we need to purchase a few items:

RF Radio Transmitter and Receiver, (5 volt, not a 3.3 volt)
Male Female jumper wires

In addition we will need our FTDI USB cable, or a FTDI USB dongle.

I did a bit of searching on the web and found a RF Data Module Tx/Rx kit. This kit has a 315 MHz transmitter and receiver. I paid $9.00 plus shipping for this kit.

(Click on the Images to make them larger)

R315_RxTx-500

dupmf-1

FTDI

ftdimale

This male FTDI USB adapter would be more compact and have a nicer form factor for your computer. But since I already had the FTDI USB cable I will use this for the tutorial. Later if you want to make a permanent configuration, you can always order the male version of the FTDI adapter.

You can purchase any frequency transmitter/receiver kit as long as the frequencies are the same between transmitter/receiver.

This blog post will explain in detail how to connect the RF radios to the robot and your computer. We will make a few small modifications to our original lineFollow.ino program. But the changes to get the robot communicating using the RF radios is pretty easy.

First we must identify the components of the radios. Your kit might be different than mine, My kit did not come with any documentation. So I had to do a bit of searching on the web to find out pin configuration, transmitter/receiver identification etc.

The nice thing is there is lots of info out on the web about configuring RF radios.

First let us determine which board is our transmitter and which board is our receiver.

Look very closely at the pin labels on both boards that you have:

pins

This is an image of the boards that I received. Your boards might look different.
Size and number of pins will not determine which board is a transmitter or receiver.

On the above image look at the pin labels on the smaller board. The pins are labeled VCC, GND, DATA and ANT.

VCC is voltage applied to the board.
GND is the ground (earth) connector.
DATA is the pin that transmits the data to the outside world
ANT is the Antenna.

Chances are that the board that has the Antenna pin is your transmitter.

Lets look at the other larger board.

GND, OUT, OUT, VCC

This board is the receiver.
Important, your boards may be configured differently. On your receiver you may only have one OUT, or data pin.

Check the instructions that came with your RF kit or perform the same identification process that we just did in this post.

Looking at our driver board, we need to find the following pins.

DriverboarfRF

powerpins

pins

We will now wire our transmitter to the robot. Get three female to male jumpers, Red, Black and Green, if you have them, if not choose three different color jumpers and write the colors down.

Take the (Red wire) female socket end of the jumper, plug it into the pin labeled VCC on the transmitter, take the male end of the same jumper and plug it into the 5V socket on your driver board.

Take the (Black wire) female socket end of the jumper and plug it into the pin labeled GND on the transmitter, take the male end of same jumper and plug it into either GND socket on the driver board.

Take the (Green wire) female socket end of the jumper and plug it into the pin labeled DATA on the transmitter, take the male end of the same jumper and plug it into pin 5 (lower right header bank) of the driver board.

Your transmitter has been wired to the robot.

For the time being I just laid the transmitter on the top of the driver board for testing. Once we want to run the robot we will tuck the transmitter in away from the wheels.

Transmitter

Let us wire the receiver to our USB cable.

Select three more female to male jumpers, Red, Black and Yellow, again if you do not have these colors choose 3 different colors and write down their use.

USBConn

Take the (Red wire) female socket end of the jumper and connect it to the VCC pin on the receiver, take the male end of the same jumper and plug into the socket of the FTDI connector that has the Red wire.

Take the (Black wire) female socket end of the jumper and connect it to the GND pin on the receiver, take the male end of the same jumper and plug it into the socket of the FTDI connector that has the black wire.

Take the (Yellow wire) female socket end of the jumper and connect it to the OUT pin on the receiver, take the male end of the same jumper and plug it into the socket of the FTDI connector that has the Yellow wire.

Your receiver has been wired to your USB FTDI.

We now need to modify our lineFollow.ino program as the RF radio kit has slightly different requirements than our hard coded serial port does.

Here are the changes we need to make:


#include "SoftwareSerial.h"
#include "MakeItRobotics.h"

#define rxPin 4
#define txPin 5

MakeItRobotics line_following;

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
int counter;

In our definition section we need to add a counter variable that will be used to test the wireless serial port. This counter will have a data type of int.


void setup()
{
Serial.begin(10420); //tell the Arduino to communicate with Make: it PCB
delay(500); //delay 500ms
line_following.line_following_setup(); //initialize the status of line following robot
line_following.all_stop(); //all motors stop

pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);

// set the data rate for the SoftwareSerial port
// mySerial.begin(9600);

mySerial.begin(1200);
counter = 0;

}

In our setup() function we need to make the following changes:

We need to comment out the mySerial.begin(9600); command and add the following command:
mySerial.begin(1200);

1200 is the baud rate (speed of data transfer) that the RF radios can communicate with each other. This value may be different for your radios. Check your documentation. In my situation the radio came with no documentation, so I first tried 2400 baud, which did not work, so I then lowered the baud rate to 1200 baud, which did work.

We also initialize the counter variable to a value of 0.

In the Loop() function we need to add the following:


// mySerial.println(sensor_in, HEX);

mySerial.println(counter, DEC);
counter++;

First we comment out the mySerial.printLn(sensor_in, HEX); line and add the following line:
mySerial.printLn(counterm DEC);

In order to test that we configured our RF radios properly we just want to send some numbers to our workstation. Later when we make sure that our RF connections are working we will change the mySerial.printLn() back to what it was before.

These are all of the changes we need to make.

Just attach the USB cable to the Arduino USB connector on your robot. we will first compile and upload the program to our Arduino.

Remember we need to check to make sure that we are using the correct serial port number, Check the earlier blog entry “Make:it Robotics Starter Kit – Software Part 2″ for details on how to accomplish this task.

Remember you do not need to turn on the battery box switches in order to have the robot communicate across the serial port.

Once your lineFollow.ino program has uploaded to the Arduino, plug your FTDI USB cable into your computer. Load the Arduino IDE, select the correct serial port and open the Serial Monitor program.

Select the correct baud rate, in my case I selected 1200 baud.

If you performed all of the tasks correctly then you should see the following in your serial monitor program. Your program should look a bit different as this screen shot was taken from the ATMEL Studio IDE:

serialwi

If your serial monitor is receiving, what appears to be a lot of junk characters or a bunch of question marks. Then either your baud rate on the serial monitor does not match the baud rate you set in your lineFollow.ino program or you need to change the baud rate that the program is using as the RF radios may not support this baud rate:

In the next blog, tutorial we will setup the lineFollow.ino program to send sensor data to our computer while the robot is running around the black circle sending real time data to our computer wirelessly.

Stay Tuned.

Categories: Robots

Make:it Robotics Starter Kit – Driver board Familiarization

July 21, 2014 Leave a comment

In this blog post we will take a look at the driver board that comes with the Make:it Robotics Starter Kit. There is no documentation that comes with the Start kit concerning the Driver board other than the schematic.

Unless you have some experience reading schematics the task of understanding what is on the driver board and how to use it beyond the kits that Radio Shack provides might be a bit daunting.

So we are going to show some images of the driver board and the schematic and point out some of important parts and map these to the schematic so everyone can follow along and learn more about the driver board.

Lets start out easy:
(Click on the images for a larger view of the image)

Here is a an image of the motor board with some terminal connectors marked in red and yellow.

driverboard1

schmatic1

The yellow box drawn on the driver board image is the terminal connector for power into the driver board from the battery boxes.

If you remember when you built the robot, you wired the two battery boxes in series (the black lead from one battery box was wired to the red lead of the other battery box. Then one lead from each box was wired to the terminal connectors on the driver board). If you take a voltage reading on the two connectors of the driver board, you should get a reading of around 12 volts.

Unless you are interested in understanding how the power circuit was built, you really do not need to speed too much time reading the schematic.

The two red boxes drawn on the image of the driver board are the motor terminal connectors. The left terminal connector is for motors 1 and 2. The right terminal connector is for motors 3 and 4. Below are images of the schematics of the motor driver circuit. Again if you are not interested in learning how the circuit is designed then you should not have to spend much time looking over the schematic.

schnatic2

schnatic3

Let us now look at some more built in sensor inputs that our driver board has. Look at the below driver board image, I have drawn some square boxes on the image:

driverboard2

If you have built the line following robot than you should be familiar with the 4 sets of pins on the right side of the board, marked in red. These are the connectors for the two line following optical sensors.

The 4 sets of pins on the left side of the board, marked in yellow are for the the IR (infrared) proximity sensors. These sensor pins are not used in the Make:it Robotics Starter Kit. They are used on one or both of the later add on kits that are available from Radio Shack or the Maker Shed store.

At the time of this writing, I have not purchased the add on kits. I will update this section after I purchase the kits.

The 4 sets of pins, marked in green are for LED (light emitting diodes), again not used in the Make:it Robot Starter Kit.

The three pins, marked in blue are for the remote IR sensor, another add-on kit that you can purchase.

I have not included a schematic for these sets of pins, as the schematics are quite large. But the connectors are labeled quite clearly on the schematic. If you are interested, take a look at the schematic to become familiar with what other components they connect to.

One of the most critical jumper pins on the Driver board is marked in red below:

driverboard3

These jumpers when connected, as shown, allow the program running on the Arduino to communicate through the serial port to the driver board.

If the pins are not jumpered as shown in the image, the robot will not move when you turn on the battery boxes. The purpose of the jumpers, when removed, is to allow you to use the USB port on the Arduino, to upload a new program to the robot. After uploading the program you should re-attach the jumpers as shown so the Arduino can communicate to the driver board.

One of the nice features of the Driver board that comes with the Make:it Robotics Starter Kit is that there are extra Arduino pins on the Driver board that are not used. These extra port pins can then be used to enhance the robot with features of your own design.

For those that are not familiar with the Arduino design. A board that plugs into the Arduino is called a Shield. The Arduino family of micro-controller boards have rows of female headers around the board. These header pins are used to interface sensors and other external devices that can be used to communicate to the outside world.

An Arduino shield has male header pins on the bottom of the board that fit directly into the female header pins on the Arduino.

In the case of the Driver board that comes with the Make:it Robotics Starter Kit, not all of the port pins are used.

So if we want to add some new sensors or external devices, like Wifi communications to your robot, the extra port pins are available to do so.

These extra pins are not documented anywhere except on the Schematic. So this blog post will show the Driver board image and the schematic image and map these available port pins so everyone see where they are on the Driver board.

Below is the image with the port pins marked in red on the Driver board, and an image of the same header pins from the schematic:

driverboard4

schematic4

One method that is common on printed circuit boards (PCB) is to label the connections. If you look at the schematic and closely on the Driver board you can see some of these labels. Note some of the labels are covered up by the actual black female header port pin sockets. You will just have to make an educated guess by comparing these ports with other pins where the labels are actually visible.

Notice on the Driver board image, the upper left header pins, marked in red, If you look closely you can see the soldered male pins that are on the bottom of the driver board. These pins are also shown on the schematic. Notice that these pins are attached to the female header sockets on the schematic by a single black line.

On the schematic the female header pin sockets are labeled A, B, C, and D.

You should have no trouble in matching these header pin sockets, on the driver board to the ones shown in the schematic.

Remember in the earlier blog post, “Make:it Robotics Starter Kit – Software Part 2″ we used pins 4 and 5 so we could send our sensor data to our software serial port and then on to our computer. By looking at the schematic I was able to determine that pins 4 and 5 are extra pins not used by the driver board.

Notice that in section A on the schematic that all pins, upper left bank, are used, so there are no extra pins that we can use in this section for data port pins, But the pins marked 3.3 V, 5 V and GND can be used to power sensors or devices that we want to connect to any available port pins in section B and D.

If we look at section B, we can see that pin A0 is being used. The A pins are analog pins, All other pins on the Arduino are digital pins.

Google the difference if you need an understanding.

That means that pins A1 – A5 are not being used and we could use these analog pins for our own modifications to our robot.

Also look at section C. Notice that all port pins are being used in section C. So we cannot use these port pins for our own use.

Look now at section D, Notice that port pins 2 and 3 are being used, in fact port pins 2 and 3 are being used to communicate between the processor on the driver board to the Arduino.

The rest of the port pins 4 – 7 are available for use to use.

By looking at the schematic, port pins 1 and 2 appear to be not used on the driver board. Remember the driver board is a shield and plugs directly into the Arduino. On the Arduino pins 1 and 2 are used to communicate to the outside world using the built in hardware serial port. So we normally do not want to use port pins 1 and 2 on the Driver board.

More to come.

Categories: Robots

Make:it Robotics Starter Kit – Binary Part 2

July 19, 2014 2 comments

In the last post we started analyzing the bitwise operations in the lineFollow.ino sketch. We looked how the sensor readings are interpreted to make the robot go forward.

In this tutorial we are going to continue our analysis in looking how the lineFollow.ino program interprets when the black in under the left sensor.

By again referring to the output from our readOptical.py Python program when the third and fourth sensor readings are 0x00 and 0x100. (refer to the readOptical.py program if you need a reminder.

We will again start at the top of the for loop again:


optValues = [0xff, 0x100, 0x00, 0x100, 0xff, 0x100]

for elem in optValues:

sensor _in = 0x0
action1 = 0x3
action2 = 0x3
sensorValue1 = 0xff
sensorValue2 = 0x0

0x0 & 0xf00
0x0 = 0b0000000000000000
0xf00 = 0b0000111100000000
if 0x0 & 0xf00 == 0
inside if sensor_in & 0xf00 == 0
0x0 & 0xff
sensorValue1 = 0b0000000000000000
& 0b0000000011111111
——————
0b0000000000000000
sensorValue1 = 0x0

The sensor_in value is 0x00 and we again perform an AND & operation with the value of 0xf0. As we said before we are checking if sensor_in data is an 8 bit or 16 bit value. Of course 0x00 is an 8 bit value as shown above, (all zeros). So the & AND operation returns a 0x00. So sensorValue1 is equal to 0x00.

Since sensorValue1 is equal to 0x00
we execute the if statement


if (sensorValue1 == 0x00)

inside sensorValue1 == 0x00
0x3 & 0xfe
action1 = 0b0000000000000011
& 0b0000000011111110
——————
0b0000000000000010
action1 = 0x2

Now here is an interesting bit, notice that from the past loop action1 was 0x3, so we now AND & action1 with 0xfe, notice the bit mask, 0xfe has all eight bit set to 1 with the exception of the bit 0 position. So when we AND & the two values we get action1 = 0x2. As we said, the sensor values have special meanings, In this case we are setting up our action for a right turn.

Since sensorValue1 is not equal to 0xff we skip the next if statement.

sensorValue2 is equal to 0x00 so lets jump inside of the if statement.


if (sensorValue2 == 0x00)

inside of sensorValue2 == 0x00
0x2 | 0x02
action1 = 0b0000000000000010
| 0b0000000000000010
——————
0b0000000000000010
action1 = 0x2

Since action1 is now equal to 0x2, when we OR & with 0x02 we of course get a value of 0x02.

The last if statement of course returns false so we skip it.

We now can move on the the second set of if statements:


if(action1 != action2)
{
if (action1 == 3 )
line_following.go_forward(50);
if (action1 == 1)
line_following.line_following_turn_left(50);
if (action1 == 2)
line_following.line_following_turn_right(50);
if (action1 == 0)
line_following.go_forward(50);
}
action2=action1;

Since action1 is equal to 0x02 the “turn Right” command is given.

Let’s jump back up the the top of the if statement and look as the next sensor_in value if 0x100.

sensor _in = 0x100
action1 = 0x2
action2 = 0x2
sensorValue1 = 0x0
sensorValue2 = 0x0

0x100 & 0xf00
0x100 = 0b0000000100000000
0xf00 = 0b0000111100000000
if 0x100 & 0xf00 == 0
inside elif

0x100 & 0xff
sensorValue2 = 0b0000000100000000
& 0b0000000011111111
——————
0b0000000000000000
SensorValue2 = 0x0

Take note of the values of action1, action2, sensorValue1 and sensorValue2. As before they will influence the values when we run through the if statements again.

sensor_in is now equal to a value of 0x100, as we noted before this is a 16 bit number, so when we evaluate the first if statement the else if statement will be true.

After processing the AND & operation, sensorValue2 now contains the value of 0x00.

Again as we process the reminder of the if statements, we set the values of sensorValue1 and sensorValue2. As a result sensorValue1 and sensorValue2 have the values of 0x00 so action1 final result is 0x02.

Now as in the last time we processed the second sensor value, action1 and action2 both contain the same values, so the motor control if statement is skipped and no motor commands are given.

At this point the robot is moving back towards the black line. So are last set of values in the readOptical.py program simulate this situation. Both sensors read values as though sensor1 and sensor2 return white values.

You can refer to the first time we ran through the if statements when the sensor values were 0xff and 0x100 to see the results.

Again keep an eye on the previous values of sensorValue1, sensorValue2, action1 and action2 as these values determine whether the motor if statements are executed or not.

Now lets take a look at the second readOptical.py results where we have the following sensor values set in the optValues array:


optValues = [0xff, 0x100, 0xff, 0x1ff, 0xff, 0x100]

We start out again assuming the robot is straddling the black line, then as the black line curves in a circle we then assume the right sensor goes black. The readOptical.py program then processes the if statements and ends up with the third set of values again simulating the robot straddling the center line again.

Open up your readOptical.py output file that we saved earlier and let review the if logic again.

Since we have already discussed the logic of both sensor1 and sensor2 being white, simulating the robot straddling the center line, you can review this code on your own by looking at the earlier analysis.

Let us now look at the second set of values when the right sensor is black.

Again keep an eye of the previous values of sensorValue1, sensorValue2, action1 and action2.

sensor _in = 0xff
action1 = 0x3
action2 = 0x3
sensorValue1 = 0xff
sensorValue2 = 0x0

0xff & 0xf00
0xff = 0b0000000011111111
0xf00 = 0b0000111100000000
if 0xff & 0xf00 == 0
inside if sensor_in & 0xf00 == 0
0xff & 0xff
sensorValue1 = 0b0000000011111111
& 0b0000000011111111
——————
0b0000000011111111
sensorValue1 = 0xff

Third pass through the loop using a sensor_in value of 0xff.
Note we have run through our logic before with sensor_in being set to 0xff, the result of action1 is still 0x03, but because action1 and action2 values are set to the same values, the motor if statement does not execute this time. So no motor control is sent to the robot.

Now we run through the loop for the forth time where sensor_in value is 0x1ff.

sensor _in = 0x1ff
action1 = 0x3
action2 = 0x3
sensorValue1 = 0xff
sensorValue2 = 0x0

0x1ff & 0xf00
0x1ff = 0b0000000111111111
0xf00 = 0b0000111100000000
if 0x1ff & 0xf00 == 0
inside elif

0x1ff & 0xff
sensorValue2 = 0b0000000111111111
& 0b0000000011111111
——————
0b0000000011111111
SensorValue2 = 0xff

As before, sensor_in is set to a 16 bit number so we execute the else if logic.

sensorValue2 value is now set to 0xff. So now sensorValue1 and sensorValue2 are set to 0xff.


if (sensorValue1 == 0xFF)

so the above if statement is executed.

inside of sensorValue1 == 0xff
0x3 | 0x01
action1 = 0b0000000000000011
| 0b0000000000000001
——————
0b0000000000000011
action1 = 0x3

action1 is now set to 0x03.

The next if statement is then executed:


if (sensorValue2 == 0xFF)

0x3 & 0xfd
action1 = 0b0000000000000011
& 0b0000000011111101
——————
0b0000000000000001
action1 = 0x1

As a result of the AND & operation, action1 is now set to a value of 0x1.

Since action1 and action2 are different, the motor logic if statement is executed and as you can see the motor instruction of “go Left” is executed.

The third set of values are the same as before and give instructions for the robot to “Go Foward” If you want you can review the logic on your own.

So we have now evaluated all of the logic that controls the robot in the lineFollow.ino program.

How to we proceed from here?

Should we care very much why the engineer designed the motor driver/senor the way he or she did. Not really. Now that we understand what the logic is doing, in future projects that use the sensors we now know how to use this logic to read and interpret the sensor1 and sensor2 data.

If in the future we want to design our own driver board then we can look into why the engineer designed the board the way he or she did.

But now you have enough knowledge to write new programs to use the sensor data with your robot.

In future blog posts we will continue to look at working with the Make:it Robotics Starter Kit.

Enjoy.

Categories: Robots

Make:it Robotics Starter Kit – Binary Part 1

July 14, 2014 Leave a comment

In our last blog post we captured some sensor data from the three different positions that our robot can encounter when following the black line, (left sensor black, left sensor/right sensor white, right sensor black).

In this blog post we are going to take that sensor data and run it thorough our readOptical.py Python program and evaluate what is happening in our lineFollow.ino program.

We are going to look at the following sections of code:


if((sensor_in & 0xf00) == 0)
sensorValue1 = sensor_in & 0xff;
else if((sensor_in & 0xf00) >> 8 == 1)
sensorValue2 = sensor_in & 0xff;
if (sensorValue1 == 0x00)
action1 = action1 & 0xfe;
if (sensorValue1 == 0xFF)
action1 = action1 | 0x01;
if (sensorValue2 == 0x00)
action1 = action1 | 0x02;
if (sensorValue2 == 0xFF)
action1 = action1 & 0xfd;

if(action1 != action2)
{
if (action1 == 3 )
line_following.go_forward(50);
if (action1 == 1)
line_following.line_following_turn_left(50);
if (action1 == 2)
line_following.line_following_turn_right(50);
if (action1 == 0)
line_following.go_forward(50);
}
action2=action1;

Our readOptical.py Python program pretty much contains the above code, but also calculates the Bitwise operators and converts the program statements (expressions) to binary so we can easily see what the program is really doing.

If you have not do so already, install Python and create the readOptical.py program using your favorite text editor, If you are using Windows, notepad is fine. Create a folder on your computer and place this readOptical.py program in this folder.

I am using Python 2.7, install the latest 2.x of Python from the below web site:

https://www.python.org/download/

Here is a YouTube video, how to install Python and include Python in your Path. This is assuming you are running Windows operating system.

In order to run our program we need to start a Command Prompt, (located in All Programs->Accessories-Command Prompt) Launch this program type the following command at the prompt in the window:

You want to change to the location of the folder where you placed your readOptical.py program.
On my computer I created the folder C:\Code\Python\readOptical. So I would type in the following command at the Command Prompt:


>cd \Code\Python\ReadOptical

We are now going to edit our readOptical.py program to include the sensor readings that we wrote down when we captured the sensor data.

So using your favorite text editor, edit readOptical.py and edit the below line to include your sensor readings.

We are going to run our readOptical.py two times, Once with data from our sensors for when both sensors are white and the left sensor black, and a second time with data from our sensors when both sensors are white and the right sensor is black.

This way we can view all of the readOptical.py program output without any data being cut off from the command prompt window.

Edit this line in your readOptical.py program:

optValues = [0xff, 0x100, 0x00, 0x100, 0xff, 0x100]

We have included sensor readings from when both sensors are white, when the sensors on the left sensor is black and again when both sensors are white.

The reason we are doing this is the give you a real example of what the robot would see as it is following a line.

First the robot would see both sensors white (robot straddling the black line) then as the circle turns the robot would see the left sensor become black, at which the robot would turn right until both sensors would see white again. (again I am using Left and Right sensors as I look at the front of the robot.

After editing our readOptical.py program we would type the following at the Command Prompt, (you should be sitting at your folder location where you put your readOptical.py program)


>Python readOptical.py

At this point the program should run and you should see the following output in the Command Prompt.

Copy the output and paste it in another Windows Notepad window, so we can look at this in a minute.

If you receive any errors, edit your readOptical.py program. Python is sensitive to indentation, Python uses space indentation to determine how the program should behave when it executes.

If you receive any indentation errors, you are going to have to go back and check that you pasted the readOptical.py program into your text exitor, that you did not move any indentation on any line of code.

Our first program output should look like the following:
(just look this over for now, we are going to dig deeper in a bit)
(Also refer to your output, it will be formatted so the columns line up better)


Sensor readings (where black strip is located)
Center Left Center

C:\Code\Python\readOptical\src>python readoptical.py

sensor _in = 0xff
action1 = 0x0
action2 = 0x0
sensorValue1 = 0x0
sensorValue2 = 0x0

0xff & 0xf00
0xff = 0b0000000011111111
0xf00 = 0b0000111100000000
if 0xff & 0xf00 == 0
inside if sensor_in & 0xf00 == 0
0xff & 0xff
sensorValue1 = 0b0000000011111111
& 0b0000000011111111
------------------
0b0000000011111111
sensorValue1 = 0xff

inside of sensorValue1 == 0xff
0x0 | 0x01
action1 = 0b0000000000000000
| 0b0000000000000001
------------------
0b0000000000000001
action1 = 0x1

inside of sensorValue2 == 0x00
0x1 | 0x02
action1 = 0b0000000000000001
| 0b0000000000000010
------------------
0b0000000000000011
action1 = 0x3

go forward

sensor _in = 0x100
action1 = 0x3
action2 = 0x3
sensorValue1 = 0xff
sensorValue2 = 0x0

0x100 & 0xf00
0x100 = 0b0000000100000000
0xf00 = 0b0000111100000000
if 0x100 & 0xf00 == 0
inside elif

0x100 & 0xff
sensorValue2 = 0b0000000100000000
& 0b0000000011111111
------------------
0b0000000000000000
SensorValue2 = 0x0

inside of sensorValue1 == 0xff
0x3 | 0x01
action1 = 0b0000000000000011
| 0b0000000000000001
------------------
0b0000000000000011
action1 = 0x3

inside of sensorValue2 == 0x00
0x3 | 0x02
action1 = 0b0000000000000011
| 0b0000000000000010
------------------
0b0000000000000011
action1 = 0x3

sensor _in = 0x0
action1 = 0x3
action2 = 0x3
sensorValue1 = 0xff
sensorValue2 = 0x0

0x0 & 0xf00
0x0 = 0b0000000000000000
0xf00 = 0b0000111100000000
if 0x0 & 0xf00 == 0
inside if sensor_in & 0xf00 == 0
0x0 & 0xff
sensorValue1 = 0b0000000000000000
& 0b0000000011111111
------------------
0b0000000000000000
sensorValue1 = 0x0

inside sensorValue1 == 0x00
0x3 & 0xfe
action1 = 0b0000000000000011
& 0b0000000011111110
------------------
0b0000000000000010
action1 = 0x2

inside of sensorValue2 == 0x00
0x2 | 0x02
action1 = 0b0000000000000010
| 0b0000000000000010
------------------
0b0000000000000010
action1 = 0x2

turn right

sensor _in = 0x100
action1 = 0x2
action2 = 0x2
sensorValue1 = 0x0
sensorValue2 = 0x0

0x100 & 0xf00
0x100 = 0b0000000100000000
0xf00 = 0b0000111100000000
if 0x100 & 0xf00 == 0
inside elif

0x100 & 0xff
sensorValue2 = 0b0000000100000000
& 0b0000000011111111
------------------
0b0000000000000000
SensorValue2 = 0x0

inside sensorValue1 == 0x00
0x2 & 0xfe
action1 = 0b0000000000000010
& 0b0000000011111110
------------------
0b0000000000000010
action1 = 0x2

inside of sensorValue2 == 0x00
0x2 | 0x02
action1 = 0b0000000000000010
| 0b0000000000000010
------------------
0b0000000000000010
action1 = 0x2

sensor _in = 0xff
action1 = 0x2
action2 = 0x2
sensorValue1 = 0x0
sensorValue2 = 0x0

0xff & 0xf00
0xff = 0b0000000011111111
0xf00 = 0b0000111100000000
if 0xff & 0xf00 == 0
inside if sensor_in & 0xf00 == 0
0xff & 0xff
sensorValue1 = 0b0000000011111111
& 0b0000000011111111
------------------
0b0000000011111111
sensorValue1 = 0xff

inside of sensorValue1 == 0xff
0x2 | 0x01
action1 = 0b0000000000000010
| 0b0000000000000001
------------------
0b0000000000000011
action1 = 0x3

inside of sensorValue2 == 0x00
0x3 | 0x02
action1 = 0b0000000000000011
| 0b0000000000000010
------------------
0b0000000000000011
action1 = 0x3

go forward

sensor _in = 0x100
action1 = 0x3
action2 = 0x3
sensorValue1 = 0xff
sensorValue2 = 0x0

0x100 & 0xf00
0x100 = 0b0000000100000000
0xf00 = 0b0000111100000000
if 0x100 & 0xf00 == 0
inside elif

0x100 & 0xff
sensorValue2 = 0b0000000100000000
& 0b0000000011111111
------------------
0b0000000000000000
SensorValue2 = 0x0

inside of sensorValue1 == 0xff
0x3 | 0x01
action1 = 0b0000000000000011
| 0b0000000000000001
------------------
0b0000000000000011
action1 = 0x3

inside of sensorValue2 == 0x00
0x3 | 0x02
action1 = 0b0000000000000011
| 0b0000000000000010
------------------
0b0000000000000011
action1 = 0x3

Like i said in an earlier blog, I have done all of the math and logic for you, all you have to do is follow along.

Here is your chance to get use to reading binary and hexadecimal numbers. At first is looks like gibberish, but you will get use to it. If you are having problems, Read the tutorials that I have made reference to in my earlier blog posts. If you do not want to go into this great of detail then just look for the sections of output where the results indicate either “go forward”, “turn left” or “turn right”

Lets analyze what is happening inside the program:

First off lets look at the comments of the readOptical() method in our lineFollow.ino program:

0x000 optical1 black
0xff optical1 white
0x100 optical1 white
0x1ff optical1 black
0x2XX not ready; don't use this value

Notice that three optical sensor readings start with either 0x1 or 0x2 hex. The rest start with 0x0 or 0xf.

If you convert these numbers to binary you will see a pattern.
Load Python Idle and type the following:

>>> format(oxff, ‘#018b’)

The format parameter ‘#018b’ indicates to show the passed number as a binary 16 bit number

so the format command will return the following:
‘0b0000000011111111′

Notice that there are 8 zeros followed by 8 1’s.
This 16 bit number has the least significant 8 bits set to 1.
If you type in the following in Python:

>>>hex(int(‘11111111′,2))

You will get:
‘0xff’

Now lets try the following:

>>>format(0x0, ‘#018b’)

Python will return:

‘0b0000000000000000′

Lets try the other two values that the readOptical() function returns.

>>>format(0x1ff, ‘#018b’)
‘0b0000000111111111′

>>> format(0x100, ‘#018b’)
‘0b0000000100000000′

How many 1’s are shown in the binary representation of 0x1ff?
What position is the 1 in, counting from the right, for 0x100?

Correct, In both cases 1 is showing up in the ninth bit position from the right.

The readOptical() method in the lineFollow.ino only returns values that have a distinct pattern.

Optical 1 sensors only return numbers that are set within 8 bits
Optical 2 sensors can have numbers that are set in the ninth bit position, or 16 bit numbers.

Let’s start looking at our results from the readOptical.py Python program.

First we look at the variables that are setup in the beginning of the lineFollow.ino program:

sensor _in = 0xff
action1 = 0x0
action2 = 0x0
sensorValue1 = 0x0
sensorValue2 = 0x0

The first sensor value we are reading is 0xff, the rest of the variables are 0x0
The first If statement performs an BitWise AND on two values:


if((sensor_in & 0xf00) == 0)

Look at the output again:
0xff & 0xf00
0xff = 0b0000000011111111
0xf00 = 0b0000111100000000
if 0xff & 0xf00 == 0
inside if sensor_in & 0xf00 == 0
0xff & 0xff
sensorValue1 = 0b0000000011111111
& 0b0000000011111111
——————
0b0000000011111111
sensorValue1 = 0xff

Look closely at the AND bitwise operation, we are checking to see if any of the upper 8 bits of the 16 bit number sensor_in is set. In this case the AND comparison return 0 as there are no bits greater than the lest significant 8 bits set in the variable sensor_in. So the first part of the if statement will only be true if sensor_in contains 0x000 or 0xff.

Since the first if statement is true, we execute the command of:

sensorValue1 = sensor_in & 0xff;

ANDing a number with itself gives us the same number, sensorValue1 = 0xff

0xff & 0xff
sensorValue1 = 0b0000000011111111
& 0b0000000011111111
——————
0b0000000011111111
sensorValue1 = 0xff

Let’s move on to the second if statement:

if (sensorValue1 == 0x00)

If we look at the sensorValue1 variable, it contains 0xff so this if statement is false and does not get executed.

Moving on:

if (sensorValue1 == 0xFF)

sensor_in is equal to 0xff so we execute the if statement:

action1 = action1 | 0x01;

In this case we are setting the variable of action1 to equal action and apply the Bitwise OR operator to the value of 0x01.
Looking at the results of the OR operation action1 gets set to a value of 0x01.

inside of sensorValue1 == 0xff
0x0 | 0x01
action1 = 0b0000000000000000
| 0b0000000000000001
——————
0b0000000000000001
action1 = 0x1

On the next if statement:

if (sensorValue2 == 0x00)

We check if sensorValue2 is equal to 0x00, and of course currently sensorValue2 is equal to 0x00 so we execute the if statement:

action1 = action1 | 0x02;

inside of sensorValue2 == 0x00
0x1 | 0x02
action1 = 0b0000000000000001
| 0b0000000000000010
——————
0b0000000000000011
action1 = 0x3

In the last if statement we check:

if (sensorValue2 == 0xFF)

sensorValue2 is not equal to 0xff so we move on.

The final value of action1 is 0x03, we exit the last if statement and proceed on the the next set of if statements:


if(action1 != action2)
{
if (action1 == 3 )
line_following.go_forward(50);
if (action1 == 1)
line_following.line_following_turn_left(50);
if (action1 == 2)
line_following.line_following_turn_right(50);
if (action1 == 0)
line_following.go_forward(50);
}
action2=action1;
}

action1 = 0x3
action2 = 0x0

We check the first if statement:

if(action1 != action2)

This is true so we enter the nested if statement:

action1 = 0x3 so we execute the true if statement:

line_following.go_forward(50);

Now in our readOptical.py program we return to the top of the for loop and we begin again with the next value:

sensor_in = 0x100
action1 = 0x3
action2 = 0x3
sensorValue1 = 0xff
sensorValue2 = 0x0

In this case sensor_in variable is equal to 0x100

Let’s look at the first if statement again:

if((sensor_in & 0xf00) == 0)
sensorValue1 = sensor_in & 0xff;
else if((sensor_in & 0xf00) >> 8 == 1)
sensorValue2 = sensor_in & 0xff;

As we pointed out during the last loop, the first if statement is looking for either 0xff or 0x00. In this case the if statement is false, so we jump to the else if statement:

In this case the if statement is doing a Bitwise AND and a Right Shift 8 bits. So we are taking the 1 in the 9 bit location and shifting it 8 times to the right,

0x100 = 0b0000000100000000
0xf00 = 0b0000111100000000
————————–
& 0b0000000100000000

Right Shift
0b0000000000000001

This value does equal 1 so we execute the if statement.

sensorValue2 = sensor_in & 0xff;

0x100 & 0xff
sensorValue2 = 0b0000000100000000
& 0b0000000011111111
——————
0b0000000000000000
SensorValue2 = 0x0

Moving down the if statements, we check the next if statement:

if (sensorValue1 == 0x00)

sensorValue1 equals 0xff so we skip this if statement.

Next if statement:

if (sensorValue1 == 0xFF)
action1 = action1 | 0x01;

The if statement is true so we execute the if statement

inside of sensorValue1 == 0xff
0x3 | 0x01
action1 = 0b0000000000000011
| 0b0000000000000001
——————
0b0000000000000011
action1 = 0x3

Next if statement:


if (sensorValue2 == 0x00)
action1 = action1 | 0x02;

The if statement is true so we execute the if statement

inside of sensorValue2 == 0x00
0x3 | 0x02
action1 = 0b0000000000000011
| 0b0000000000000010
——————
0b0000000000000011
action1 = 0x3

We finish up the if statements and move on the the next set of if statements:

if(action1 != action2)

In this case action1 is equal to action2 so we skip the if statement that sends motor instructions.

We loop back around to the for loop again and select the next sensor_in value.

At this point we have sent the motor driver one set if instructions to go forward, as the sensors are both reading white.

In the next blog post we will move on reading the sensor values when the left sensor is black.

Categories: Robots

Make:it Robotics Starter Kit – Capture Sensor Data

July 12, 2014 2 comments

Last blog entry we discussed a bit about what the linefollow.ino program is doing. I presented a Python script that will allow us to analyze the bitwise if statements to see how the value that the read_Optical() method returns gets converted to the values of 0, 1, 2 or 3.

Now we are going to put all of this together and see what is really happening on the robot.

Sometimes when looking over a program that someone else developed, it is sort of hard to visualize what the program is doing. So one of the things I like to do is actually watch what the program is doing while it is executing.

In our below example we are going to take a look at what data the sensors are sending to our lineFollow.ino program through the read_Optical() method.

Well there are several ways of doing this. Some development environments have sophisticated debuggers and hardware debuggers that allow you to watch the program execute on the microprocessor. But if you do not have these tools there is an easier way accomplish this.

Most micro-controllers, including the Arduino, include built-in hardware that allows you to send communications to the outside world using a serial port.

In fact that is how the Arduino Uno communicates with the Motor driver/sensor board on the Robot.

There is another micro-controller that is on the motor driver/sensor board that is responsible for controlling the motors and capturing the signals from the sensors on the robot. The linefollow.ino program running on the Arduino Uno uses the serial port to send commands to the motor driver/sensor board, to control the motors and requests the outputs from the sensors.

In fact there are jumper pins that you must make sure are in place that connect the Serial port to the motor driver/sensor board. As the instructions indicate you must disconnect these jumpers when you want to upload a program to the Arduino.

So in this case how can we listen in on the serial port from our own personal computer when the Arduino and motor driver/sensor board is using the serial port all of the time?

The Arduino library comes with some methods that provide a software based serial port. Instead of using the build in hardware based serial port, we can pick any available two pins on the Arduino Uno and use these pins to to act just like a hardware based serial port to also communicate to the outside world. In order for our lineFollow.ino program to send messages to our Personal Computer we need a special USB cable that has an adapter built in.

This cable is called an FTDI USB cable: (just google for this cable, many online vendors sell these cables for around $15.00 – $20.00)

FTDI

Once you have your cable we can modify our linefollow.ino program to send our personal computer messages on what the sensors are doing.

First we will modify our lineFollow.ino program to enable the software serial port.

Looking at the Schematic drawing that came with the software download, we notice that pins 4 and 5 on
header J4 are available so we will make these our transmit and receive pins for out software serial port.

pins

Looking at the front of the robot, these are on the right lower set of header pins.

We are going to make pin 4 the receive pin and pin 5 the transmit pin:

Here is our code modifications:


#include <SoftwareSerial.h>
#include "MakeItRobotics.h"//include library

#define rxPin 4
#define txPin 5

MakeItRobotics line_following;//declare object

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

Place this code in the declaration/include section discussed in the last blog post:

We tell our lineFollow.ino program to include the SoftwareSerial.h header file. This gives us the resources we need for Serial Port methods.

Then we define two variables rxPin and txPin to have values of 4 and 5

Then we create a new object called mySerial with the following statement:
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

Lets move on to the setup() function.
Add the following lines of code to the bottom of the setup() function (inside of the braces {})

pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);

The pinMode() functions setup the rxPin as Input and txPin as output.
We then setup the mySerial object to use 9600 baud as the speed that we want to communicate over the software serial port.

Now we just have to add one line to our loop() function:


sensor_in=line_following.read_optical();
mySerial.println(sensor_in, HEX);

Right below the sensor_in=line_following.read_Optical(); line add the:
mySerial.println(sensor_in, HEX); command

Compile and upload your program to your Robot.

There one more physical connection we need to make.

Grab your new FTDI USB cable and focus on the black connector opposite the USB connector.
You will see some female pins sockets and some colored wires behind these connectors.

We only need to make two connections. Get yourself some male/male jumper wires, if you do not already have some.

Jumper_Wires

Notice the Orange and Yellow wires on the FTDI USB cable. Plug a jumper wire into the orange and yellow sockets on the FTDI USB cable.

Now the tricky part. You have to switch the transmit and receive wires between the connector and the header pins on your motor driver/sensor board. That is the receive pin on the motor driver/sensor board goes to the transmit pin on the USB connector. And the transmit ping on the motor driver/sensor board goes to the receive pin on the USB connector.

To make it easy, The orange wire goes to pin 4 and the yellow wire goes to pin 5.

I have placed my robot on a set of blocks to get the wheels up off of the ground so I can side some paper under the sensors.

IMAG0173

Also notice I have photocopied a small section of the black line from the circle. We are going to use this line to measure what the sensors are reading in our tests.

Notice that the right wheel has been removed. The paper is resting on the wheel to get the line close to the sensors.

Center the black line between the sensors as we want to get a reading of white on both sensors first.

When running these tests you do not need to turn on the batteries, so the wheels are not going to turn. But the sensors are going to function just fine.

Open your Arduino IDE if it is not opened already. Plug in just the usb cable that you use for programming your robot to the USB port on the Arduino. If you are running Windows, Open your device manager utility, Control Panel->Systems And Security->Device Manager. Expand the Ports (COM & LPT) icon. Note which COM Port your Arduino is connected to. Write this port down.

Now connect the FTDI USB cable to your personal computer. Open the Device Manager and write down the COM Port of your FTDI USB cable.

Open the Tools->Port menu option on your Arduino IDE and select the proper port for your FTDIUSB cable. On my computer is was COM port 3. Now Select the Tools->Serial Monitor Menu option and select a Baud rate of 9600 in the lower right hand corner. If you did everything correct you should see the output in the below image.

output

Now move the paper so the black line is under the right sensor, write down your measurements and then do the same for the left Sensor.

IMAG0174

IMAG0175

After taking all of your measurements you should have a total of 6 sensor readings:

Left and Right Measurements are taken looking at the front of the robot.

Center = FF and 100
Right = FF and 1FF
Left = 0 and 100

These number are in hexadecimal, Read my tutorial and the links that it points to.

Next Blog post will be to take our sensor readings and run them through our ReadOptical.py program.

Stay Tuned.

Categories: Robots
Follow

Get every new post delivered to your Inbox.

Join 50 other followers