Archive

Author Archive

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 0×00 and 0×100. (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 = 0×0
action1 = 0×3
action2 = 0×3
sensorValue1 = 0xff
sensorValue2 = 0×0

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

The sensor_in value is 0×00 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 0×00 is an 8 bit value as shown above, (all zeros). So the & AND operation returns a 0×00. So sensorValue1 is equal to 0×00.

Since sensorValue1 is equal to 0×00
we execute the if statement


if (sensorValue1 == 0x00)

inside sensorValue1 == 0×00
0×3 & 0xfe
action1 = 0b0000000000000011
& 0b0000000011111110
——————
0b0000000000000010
action1 = 0×2

Now here is an interesting bit, notice that from the past loop action1 was 0×3, 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 = 0×2. 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 0×00 so lets jump inside of the if statement.


if (sensorValue2 == 0x00)

inside of sensorValue2 == 0×00
0×2 | 0×02
action1 = 0b0000000000000010
| 0b0000000000000010
——————
0b0000000000000010
action1 = 0×2

Since action1 is now equal to 0×2, when we OR & with 0×02 we of course get a value of 0×02.

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 0×02 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 0×100.

sensor _in = 0×100
action1 = 0×2
action2 = 0×2
sensorValue1 = 0×0
sensorValue2 = 0×0

0×100 & 0xf00
0×100 = 0b0000000100000000
0xf00 = 0b0000111100000000
if 0×100 & 0xf00 == 0
inside elif

0×100 & 0xff
sensorValue2 = 0b0000000100000000
& 0b0000000011111111
——————
0b0000000000000000
SensorValue2 = 0×0

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 0×100, 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 0×00.

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 0×00 so action1 final result is 0×02.

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 0×100 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 = 0×3
action2 = 0×3
sensorValue1 = 0xff
sensorValue2 = 0×0

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 0×03, 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 = 0×3
action2 = 0×3
sensorValue1 = 0xff
sensorValue2 = 0×0

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
0×3 | 0×01
action1 = 0b0000000000000011
| 0b0000000000000001
——————
0b0000000000000011
action1 = 0×3

action1 is now set to 0×03.

The next if statement is then executed:


if (sensorValue2 == 0xFF)

0×3 & 0xfd
action1 = 0b0000000000000011
& 0b0000000011111101
——————
0b0000000000000001
action1 = 0×1

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

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 0×1 or 0×2 hex. The rest start with 0×0 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(0×0, ‘#018b’)

Python will return:

’0b0000000000000000′

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

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

>>> format(0×100, ‘#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 0×100?

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 0×0
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 0×000 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 0×01.
Looking at the results of the OR operation action1 gets set to a value of 0×01.

inside of sensorValue1 == 0xff
0×0 | 0×01
action1 = 0b0000000000000000
| 0b0000000000000001
——————
0b0000000000000001
action1 = 0×1

On the next if statement:

if (sensorValue2 == 0x00)

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

action1 = action1 | 0x02;

inside of sensorValue2 == 0×00
0×1 | 0×02
action1 = 0b0000000000000001
| 0b0000000000000010
——————
0b0000000000000011
action1 = 0×3

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 0×03, 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 = 0×3
action2 = 0×0

We check the first if statement:

if(action1 != action2)

This is true so we enter the nested if statement:

action1 = 0×3 so we execute the true if statement:

line_following.go_forward(50);

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

sensor_in = 0×100
action1 = 0×3
action2 = 0×3
sensorValue1 = 0xff
sensorValue2 = 0×0

In this case sensor_in variable is equal to 0×100

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 0×00. 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,

0×100 = 0b0000000100000000
0xf00 = 0b0000111100000000
————————–
& 0b0000000100000000

Right Shift
0b0000000000000001

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

sensorValue2 = sensor_in & 0xff;

0×100 & 0xff
sensorValue2 = 0b0000000100000000
& 0b0000000011111111
——————
0b0000000000000000
SensorValue2 = 0×0

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
0×3 | 0×01
action1 = 0b0000000000000011
| 0b0000000000000001
——————
0b0000000000000011
action1 = 0×3

Next if statement:


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

The if statement is true so we execute the if statement

inside of sensorValue2 == 0×00
0×3 | 0×02
action1 = 0b0000000000000011
| 0b0000000000000010
——————
0b0000000000000011
action1 = 0×3

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 – Software Part 2

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. Om 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

Make:it Robotics Starter Kit Software – Part 1

July 11, 2014 Leave a comment

This blog post is a continuation on my tinkering with the Make:it Robotics Kit. Hopefully I can pass on some of the information that I have learned so it will make it easier for others to get up to speed on working with the Robotics Kit.

After building the line following robot, the manual had a link to download the software for the robot. I tried to navigate to the link and it was not available: http://shack.net/MakeitRobotics. This is a common problem when manufactures are writing documents, links seem to change and revisions often miss each other.

Not a problem Radio Shack was good enough to provide a link to the download files on their web site: http://blog.radioshack.com/2014/05/radioshack-make-magazine-launch-make-robotics/

I will not post the entire source code here as you can download it and follow along.

The source code contains library and include files for the Main Robotics Kit, Project 1 and Project 2 Kits and the Sensor Kit. There are individual Arduino Sketch files for each robot provided in the kits. All of the sketches depend on the a MakeItRobotics.cpp file and a MakeItRobotics.h file.

If you need assistance understanding what these files are, google for .cpp file and .h include file.

If you need further help drop me an email on this site.

Since I built the line following robot this blog post will discuss the line following code, which is named linefollow.ino. This file is a text file that the Arduino IDE reads or any development environment can read.

The linefollow.ino file is documented and should provide a basic understanding of what is going on with the program. But I did find a typo that could cause some confusion. Also I will try to provide some additional information for those folks that are rather new to robotics, Arduino and programming in general.

=== This Section is for folks new to Arduino ===

The linefollow.ino is pretty much a standard Arduino Sketch file, at the beginning of the file is a main comments section, a declaration/include section, a setup() function and a loop() function.

The declaration/include section includes header files, which include definitions and resources that the sketch will used during program execution. Global objects and variables can also be declared and initialized at this location as well. For example in the linefollow.ino sketch the line_following object is created (or in programming language, this is called instantiated)

Everything in the setup() function is run once when the Arduino first powers up. The setup() function is where you place start up code that initialize things that your loop program needs for program execution. For Example the Arduino needs to talk to the robot motor driver/sensor board using the serial port. So the setup() function calls the Serial.begin(10420) method to setup the serial port so the Arduino can take with the motor driver board.

The loop() function is where all of the action in the program takes place. the loop() function loops or repeats over and over without stopping until the power is removed from the Arduino.

This is why the function is called loop().

=== End of section ===

As I said there is are a few typos in the comments of the code in linefollow.ino.
Every loop the program calls the following function:

sensor_in=line_following.read_optical();

The comments for this read_optical() method reads the following:

Returns
0×000 optical1 black
0x0ff optical1 white
0×100 optical1 white
0x1ff optical1 black
0x2XX not ready; don’t use this value

Actually is should be the following

Returns
0×000 optical1 black
0xff optical1 white
0×100 optical2 white
0x1ff optical2 black
0x2XX not ready; don’t use this value
(either sensor can return this value)

Actually 0x0ff should be 0xff
Refer to blog post Software Part 3

You will see in the below paragraphs the importance of these typos.
(has to do with reading every other sensor)

On the line following robot there are two optical sensors, every time the loop() function executes the linefollow.ino sketch calls a method to see if one of the sensors is seeing light or dark.

On a microcontroller, such as the Arduino, one second is a very long time. The loop() function can execute many thousand times a second. Just how long each loop takes depends on how many program instructions take place. Some instructions take longer to execute than other instructions.

Instruction (what functions and methods are made up of) execution time is measured in CPU clock cycles. The Arduino by default operates at 16 MHz or 16 million clock cycles a second.

The linefollow.ino sketch performs some pretty simple logic. After setting up some variables, the loop() calls a function to see if one sensor is light or dark, Depending on the answer some fancy logic is executed to reduce the answer to a value of 0, 1, 2 or 3. These values are then used to tell the motors to either go forward, turn left or right.

Every 15 milliseconds the loop program is told to switch and read the other sensor. So you have a program that loops reading first one sensor, converts the answer to 0, 1, 2 or 3 ,tell the motors what to do, and then read the other sensor, convert the answer to 0, 1, 2 or 3 and then tell the motors what to do.

In many cases, depending on the values of the action1 and action2 variables, the instructions to control the motors are skipped.  Refer to a later blog post.

These operations are done again at thousands of times a second.

The rest of this blog and later blogs  are going to teach you what is happening with the fancy logic that reads the sensor and converts the answer to 0, 1, 2, or 3.

The following code segment is the fancy code that converts the sensor readings to a value of
0, 1, 2 or 3. This code involves some program instructions that can be quite confusing for new
micro-controller programmers.

Please refer another blog entry that I wrote called “Tutorial – Bit Banging and Boolean Math without the Math”

This tutorial goes hand in hand with understanding the following code segment:


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;

This segment of code uses three special operators (instructions that operate on given values)

The code uses the following binary operators: & Bitwise AND operator, | Bitwise OR operator
and the >> Bitwise Right Shift operator. (Read the tutorial)

To make this easier so you do not have to convert this by hand I wrote a Python program that does all of the math for you and shows you what is taking place at the binary level, so all you have to do is look at the results.

Install Python on your computer, it is free. Read the tutorial, Everything is explained on how to get started with Python.

I have done all of the work for you.


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

parses the valid values of the readOptical()
prints out logic and binary results
that determine if robot turns right, left
or goes forward

”’
def main():
# declare and initialize array
sensor_in = 0
sensorValue1 = 0
sensorValue2 = 0
action1 = 0
action2 = 0

optValues = [0x000, 0x0ff, 0x100, 0x1ff, 0x200]

for elem in optValues:
sensor_in = elem
print “\n”
print “sensor _in = ” + str(hex(sensor_in))
print “action1 = ” + str(hex(action1))
print “action2 = ” + str(hex(action2))
print “sensorValue1 = ” + str(hex(sensorValue1))
print “sensorValue2 = ” + str(hex(sensorValue2))
print “\n”
print str(hex(sensor_in)) + ” & ” + str(hex(0xf00))
print str(hex(sensor_in)) + ” = ” + format(sensor_in, ‘#018b’)
print str(hex(0xf00)) + ” = ” + format(0xf00, ‘#018b’)
print “if ” + hex(sensor_in) + ” & ” + hex(0xf00) + ” == 0 “

if (sensor_in & 0xf00 == 0):
print “inside if sensor_in & 0xf00 == 0″
print str(hex(sensor_in)) + ” & ” + str(hex(0xff))
print “sensorValue1 = ” + format(sensor_in, ‘#018b’)
print ” & ” + format(0xff, ‘#018b’)
print ” ——————”
print ” ” + format(sensor_in & 0xff, ‘#018b’)
sensorValue1 = sensor_in & 0xff
print “sensorValue1 = ” + str(hex(sensorValue1))
print “\n”
elif ((sensor_in & 0xf00) >> 8 == 1):
print “inside elif\n”
print str(hex(sensor_in)) + ” & ” + str(hex(0xff))
print “sensorValue2 = ” + format(sensor_in, ‘#018b’)
print ” & ” + format(0xff, ‘#018b’)
print ” ——————”
print ” ” + format(sensor_in & 0xff, ‘#018b’)
sensorValue2 = sensor_in & 0xff
print “SensorValue2 = ” + str(hex(sensorValue2))
print “\n”
if (sensorValue1 == 0×00):
print “inside sensorValue1 == 0×00″
print str(hex(action1)) + ” & 0xfe”
print “action1 = ” + format(action1, ‘#018b’)
print ” & ” + format(0xfe, ‘#018b’)
print ” ——————”
print ” ” + format(action1 & 0xfe, ‘#018b’)
action1 = action1 & 0xfe
print “action1 = ” + str(hex(action1))
print “\n”
if (sensorValue1 == 0xff):
print “inside of sensorValue1 == 0xff”
print str(hex(action1)) + ” | 0×01″
print “action1 = ” + format(action1, ‘#018b’)
print ” | ” + format(0×01, ‘#018b’)
print ” ——————”
print ” ” + format(action1 | 0×01, ‘#018b’)
action1 = action1 | 0×01
print “action1 = ” + str(hex(action1))
print “\n”
if (sensorValue2 == 0×00):
print “inside of sensorValue2 == 0×00″
print str(hex(action1)) + ” | 0×02″
print “action1 = ” + format(action1, ‘#018b’)
print ” | ” + format(0×02, ‘#018b’)
print ” ——————”
print ” ” + format(action1 | 0×02, ‘#018b’)
action1 = action1 | 0×02
print “action1 = ” + str(hex(action1))
print “\n”
if (sensorValue2 == 0xff):
print “inside of sensorValue2 == 0xff”
print str(hex(action1)) + ” & 0xfd”
print “action1 = ” + format(action1, ‘#018b’)
print ” & ” + format(0xfd, ‘#018b’)
print ” ——————”
print ” ” + format(action1 & 0xfd, ‘#018b’)
action1 = action1 & 0xfd
print “action1 = ” + str(hex(action1))
print “\n”

if (action1 != action2):
if (action1 == 3 ):
print “go forward”
if (action1 == 1):
print “turn left”
if (action1 == 2):
print “turn right”
if (action1 == 0):
print “go forward”

action2 = action1

if __name__ == “__main__”:
main()

In the next blog post, we will read sensor data from the robot in near real time.  In later blog posts we will run this data through our readOptical.py Python program, to get an understanding of what is happening with our robot.

Categories: Robots

Make:it Robotics Starter Kit

July 10, 2014 Leave a comment

I finely got some spare time to start working on C/C++ embedded systems and robots. So in browsing around at Radio Shack I stumbled upon the Make:it Robotics Starter Kit. Apparently a joint collaboration between Radio Shack and the folks at Maker Media, Inc. The same people who bring you Make: Magazine.

makeit

When I got home I quickly broke open the box and started looking over the contents. The kit comes with everything you need to build two robots with the exception of an Arduino Uno and 8 AA batteries.

In Starter Kit you can build either a line following robot or a walking robot. I choose to build the line following robot first.

It took me two leisurely evenings to put the robot together.

The assembly instructions were great. All of the robot parts were first class, the robot frame is black powder coated metal angle and flat brackets, similar erector set style. The only plastic parts were the battery boxes, the wheels and the motor cases.

The only comment was with adult sized hands it was a bit tough fastening the corner nuts and bolts. But if you are assisting your son or daughter with the building steps, this will be great for little hands.

Once you finish building either robot, there is a link in the manual where you can download the software for the robot. Within this download there are some example programs, a readme file, and circuit diagrams for the sensors and motor/sensor shield.

There is no documentation available concerning the hardware, consisting of an Arduino motor driver, sensor shield. In order to get the specifications you must read the schematic. For the person who wants to take the robot building process further than just assembling the provided kits and running the provided software, there is little information provided. You must figure this out for yourself,  by reading the schematic, a bit daunting for someone just starting out with electronics.

Loading the line following program, to the Arduino is easy using the Arduino IDE or if you are an advanced user you can use one of several available development packages such as the freely available Atmel Studio, which is what I use.

In my next post I will go further into reverse engineering the software provided.

After tracking down 8 AA batteries my robot was ready run run. The Make:it Robotics Kit even comes with a sheet of heavy duty white paper with a 360 degree circle for the line following robot to follow.

The instructions indicate that the optical sensors that come with the line following robot are very sensitive to light an if the robot is not functioning properly to lower the ambient light around the robot.

I placed the robot on the white paper just off of the black circle and turned the robot on.

My robot would only make it about 1/4 the way around the circle before loosing track of the black line.

I tired several times, but still no luck. I turned off the room lights and tried again. Still no luck.

I double checked my wiring and everything was wired ok. But the best the robot could do was only make it about 1/4 around the black line circle.

Time to do some modifications:

Here is an image of the stock robot with the sensors exposed to the ambient light.

IMAG0169

I have played around with line following robots before and there is a trick to shield the sensors to the ambient light.

So I took some duct tape and covered the sensors from the top:

IMAG0167

After this modification the robot was able to make it 3/4 of the way around the circle, ambient lights on or off, better but still not good.

Time to do some more hacking.

The kit comes with some additional parts for the walking robot. I noticed that there were some shorter posts, (referred to as “Column B” in the manual). So I changed the longer posts with the shorter posts thinking this might help with optical sensors. Nope it made it worse, But the change was less than 1/4 of an inch. So I tried something else. I left the shorter posts on the robot and added 1/4 posts to each post. I picked these up locally at Fry’s Electronics. Radio Shack did not carry these parts in the store.

IMAG0170

Fired up the robot and success, ambient light on or off the robot was able to make multiple passes around the circle without loosing it way.

In the next blog post I will do some hacking on the software.

Categories: Robots

Word Frequency Analysis program in C++

December 10, 2013 Leave a comment

I wanted to do some more work with the STL in C++, so I decided to put together a program that uses several STL containers.  I also wanted this program to do some searching and sorting of the containers so I could get a change check the performance of different STL containers.

I wrote a word and character frequency analysis program that takes two parameters, a text file that contains the text that will be parsed and analyzed and a log file that will contain the analysis.

I first looked at using a STL map, as it seemed to be close to a hash table which is the way you would write this type of algorithm in C.  But I found out that in order to sort the data by the number of occurrences of words and characters by a descending order would have forced me to perform an extra copy to a STL vector,  so I decided to use the vector from the start.

The program parses the file line by line, splitting each line into a vector of strings.   A structure is created that contains a string, for the word and a int variable to keep track of the count, each time the word is found in the text. The structure is then inserted into a vector that contains the structure  Each word is then parsed by character, and placed in a similar structure consisting of a char and a int variable that keeps track of each time the same character is discovered.

The find_if() method is used to see if the word or character already exists in the vector.  If it existed the counter is incremented, If the word or character does not exist a new structure is inserted into the vector.

In the example code I included a message file that contains the Declaration of Independence.  The program parses this file in around 1/10 of a second, Running on a 64bit Apple Mini with 8 gigs of memory.

I have placed the code out in my GitHub repository at:

https://github.com/jpitz31/Word-Frequency-Analysis

Categories: C/C++

Caesar Cipher written in C++

December 1, 2013 Leave a comment

Just submitted my last assignment for my Data Structures and Algorithms C class.  I plan on taking some time off from school so I can write some code and apply all of this great information that I have learned in the last year of attending UCSD extension program. I finished the C/C++ certification program and decided to take one more class, which was the Data Structures and Algorithms class.

Over the Thanksgiving holiday I decided to take a Caesar Cipher program I found out on the web, that I have played around with an convert it to C++.  I figure the more I write the more I will learn.

So I finished the application and posted it out on GitHub.

https://github.com/jpitz31/CaesarCipher

Instructions and an explanation of how the application functions is posted as a readme file on the GiHub site.

There is also a link to the Caesar Cipher wikipedia site.

For my C/C++ classes I used Visual Studio 2013 Express version and Professional version at work.

But at home I enjoy working on the Mac with OS X.  I have started working with Qt and Qt Creator.

I really like Qt and the cross platform environment.  So I plan on working on some C++ GUI applications  using Qt.

 

Categories: C/C++

Data Driven XPATH XML Parsing in C++

June 18, 2013 Leave a comment

Since I have been taking a C++ certificate course at UCSD, I have really begun to enjoy writing  C++.  At work I have been setting up InstallAnywhere scripts to build a Java application and we needed to put together a Continuous Integration build process that will run on a CRM server.

Out of the box, InstallAnywhere standard edition is pretty brain dead when it comes to automating build install executables.    The vendor wants you to spend twice the money and upgrade to the enterprise edition.

So I decided to look into writing some custom code to automate the build  process.  It turns out that InstallAnywhere creates a very large .XML file that it uses to build the install executable.

After doing some parsing and manual .XML file modification I found out that I could modify the .XML profile file that InstallAnywhere uses without impacting the execution of building the install package.

Every time we do a build we need to increment the build version, and on a the Windows version, we need to change the install location to include the version number.  This way users can install and maintain multiple versions of the same program on their workstations.

Also if the source location, where the Java application is built, ever changes we need to also modify the location where InstallAnywhere loads the application files from.

The InstallAnywhere profile .XML file is around 5400 lines long and the Windows profile has 16 different source file locations that need to changed if the build location ever changes.  There are also three different locations that relate to Installer name and install path.  These locations have to be updated with new version names.

The XML element tags are nested quite deep and using regular XML element tag looping would have been quite difficult.  So I decided use XPATH searching instead.  Since we are building the application for different OS platforms, and each OS platform has slightly different files that are required as part of the build process, different InstallAnywhere XML profile files had to be created.

I decided to use an open source project called pugixml that allows rapid, easy parsing of XML files:
Instead of creating different programs or having the program support different logic in the code to handle these XPATH differences.  I decided to create a program that would be data driven.

I created a text file that contained one line for each location to be changed,  Each line contained the full XPATH to be searched for, followed by a comma and the path to be changed within the .XML profile file.

This way I could create separate text files for each OS platform and run the program by passing in the .XML profile file and the name of the XPATH text file.

Below is a sample of the XPATH Text file, each XPATH is over 300 characters, so I will abbreviate these lines for readability.

I will also include the full C++ source code:


/InstallAnywhere_Deployment_Project/installationObjects/object/visualChildren/
object[@objectID='e40534579ff1']/.../property,C:\5.4_final\bin\components\

.../installChildren/object[@objectID='e40534589ff1']/installChildren/
object[@objectID='e40534589ff2']/installChildren/
object[@objectID='2a51ba45bc17']/property,C:\5.4_final\bin\components\

.../installChildren/object[@objectID='e40534589ff2']
/installChildren/object[@objectID='2a51ba46bc17']
/property,C:\5.4_final\bin\components\


Here is the source code:

// ****************************************
// Program: ChangePath.cpp
// Author: Joe Pitz
// Description: Updates source QTF path information of QTF
// for InstallAnywhere profile
//
// Parameters:
// Name of Profile file = QTFInstall64_0.5.3.iap_xml
// XPATH Profile File = WinXPATHProfile.txt
//
// Last Updated:
// Created Program: 06/14/2013 - Joe Pitz
//
// ***************************************

#include "pugixml.hpp"

#include <iostream>
#include <string>
#include <iostream>
#include <fstream>

using std::cout;
using std::cin;
using std::string ;
using std::ifstream ;
using std::cerr;
using std::getline;

// constants
const size_t BUFF = 255;
const int LNGBUFF = 500;
const size_t ARGCNT = 3;
const char *STRELEM = "string";
const char *SRCPATH = "sourcePath";

void modifyElement(const pugi::xml_document &doc, const char *Node, const char *Value);

void modifyElement(const pugi::xml_document &doc, const char *Node, const char *Value)
{
try
{
pugi::xpath_node_set PropNode = doc.select_nodes(Node);

for (pugi::xpath_node_set::const_iterator it = PropNode.begin(); it != PropNode.end(); ++it)
{
pugi::xpath_node node = *it;

if (strcmp(node.node().first_attribute().value(), SRCPATH) == 0)
{
node.node().child(STRELEM).text() = Value;
}
}
}
catch (std::exception ex)
{
std::cerr << ex.what();
}
}
int main(int argc , char * argv [])
{
// declare variables
size_t cnt = 0;
pugi::xml_document doc;
pugi::xml_node ObjNode;
string line;
int found;
string one;
string two;
char node[LNGBUFF];
char value[BUFF];

// check for valid command line arguments
if (argc < ARGCNT)
{
std::cerr << "* * * ERROR - Incorrect number of parameters * * * \n";
std::cerr << "Usage: " << argv [0] << " name of IntstallAnywhere File, XPATH File " << "\n";
std::cerr << "Usage: " << argv [0] << " QTFInstall64_0.5.3.iap_xml WinXPATHProfile.txt " << "\n";
return 1;
}

one = argv[1];
two = argv[2];
// open .xml file
if (!doc.load_file(argv[1]))
{
cerr << "Could not open " << argv[1] << "\n";
return -1;
}

// open file
ifstream PFile ( argv[2]);
if (PFile.is_open())
{
while ( PFile.good() )
{
// read line
getline (PFile, line);

// split line on comma
found = line.find_last_of(",");
strcpy_s(node, line.substr(0, found).c_str());
strcpy_s(value, line.substr(found + 1).c_str());

// call modifyelement
modifyElement(doc, node, value);

}
PFile.close();
}
else
{
cerr << "Unable to open file " << PFile << "\n" ;
return 1;
}

// save xml profile file
doc.save_file(argv[1]);

// debug code
// Wait for user response
cout << "\n" << "Press enter to continue...";
cin.get();
}

Categories: C/C++
Follow

Get every new post delivered to your Inbox.

Join 43 other followers