Sunday, February 19, 2012

Compass Controlled Robot

The the compass breakout HMC6352 from Sparkfun is easy to use and works well to control the direction of a robot. Here is a picture of the test robot used with the compass breakout. The robot robot uses the Arduino UNO with the Adafruit motor shield. External power is supplied to the motor shield with a 7.2v battery.

The compass breakout HMC6352 can be powered with 2.7 to 5.2 volts. The Arduino UNO that was used here operates at 5 volts, but it does have a 3.3 volt supply pin. Unfortunately the motor shield covered up the Arduino 3.3v power supply. There were a few comments about using the compass breakout at 5 volts. Most comments said it is within the stated operating limits and it should work at 5 volts. One comment said their compass breakout ran fine at 5 volts for about 30 minutes, then went up in a puff of smoke.

So as an alternative to using 5 volts, a voltage divider was used. The calculations were done using Hyperphysics Voltage Divider with R1 being 3 parallel 1 k ohm resisters and R2 being a single 1 k ohm resister, using 5 volts this would give a high load resistance voltage of about 3.7 volts. The compass breakout uses about 1 mA of current which at 3.7 volts is equivalent to a resistance of about 3 k ohms. Assuming 3 k ohms as the load resistance gives an operating voltage of about 3.5 volts. This is well within the operating voltage of the compass breakout. The equivalent resistance of the voltage divider is 1.333 k ohms, so at 5 volts it would waste 3.75 mA of current. The compass breakout uses about 1 mA, so that is a total current draw of about 4.75 mA. The Arduino 5 volt pin should not be used to supply more that 30 mA, so this seems well within the limits there too.

The simple BLDR program was used to test the compass breakout. That wiring diagram was also used, except for the voltage divider. After seeing that the compass breakout was working, the motor control was added to control the direction of the robot using the compass. This program has the robot drive using the compass heading of 180 degrees, that is magnetic south. The speed numbers will vary depending on the motors used and the voltage driving the motors.

A jumper switch was added from Arduino A0 to control the motors. When the jumper switch connected to a ground pin, the motors will not run. This allows you to start and stop the motors while testing the movement.


#include
#include
int HMC6352SlaveAddress = 0x42;
int HMC6352ReadAddress = 0x41; //"A" in hex, A command is:

int headingValue;

AF_DCMotor motorR(3, MOTOR12_64KHZ); // create motor #1, 64KHz pwm
AF_DCMotor motorL(1, MOTOR12_64KHZ); // create motor #3, 64KHz pwm

int switchPin = A0; // select the input pin for the potentiometer
int switchValue = 0; // variable to store the value coming from the sensor

int speedL = 190;
int speedR = 200;
int speedD = 50;

void setup() {
// "The Wire library uses 7 bit addresses throughout.
// If you have a datasheet or sample code that uses 8 bit address,
// you'll want to drop the low bit (i.e. shift the value one bit to the right),
// yielding an address between 0 and 127."
// I know 0x42 is less than 127, but this is still required
HMC6352SlaveAddress = HMC6352SlaveAddress >> 1;
Wire.begin();

Serial.begin(9600); // set up Serial library at 9600 bps

motorR.setSpeed(speedL); // set the speed to 200/255
motorL.setSpeed(speedR); // set the speed to 200/255
}


void loop() {
switchValue = analogRead(switchPin); // read the value from the sensor
if (switchValue > 0) {

//"Get Data. Compensate and Calculate New Heading"
Wire.beginTransmission(HMC6352SlaveAddress);
Wire.send(HMC6352ReadAddress); // The "Get Data" command
Wire.endTransmission();

//time delays required by HMC6352 upon receipt of the command
//Get Data. Compensate and Calculate New Heading : 6ms
delay(6);

Wire.requestFrom(HMC6352SlaveAddress, 2); //get the two data bytes, MSB and LSB
//"The heading output data will be the value in tenths of degrees
//from zero to 3599 and provided in binary format over the two bytes."
byte MSB = Wire.receive();
byte LSB = Wire.receive();

float headingSum = (MSB << 8) + LSB; //(MSB / LSB sum)
float headingInt = headingSum / 10;
Serial.print(headingInt);
Serial.println(" degrees");
if (headingInt < 180) {
Serial.println("Right");
motorR.setSpeed(speedR+speedD); // set the speed to 200/255 motorL.setSpeed(speedL-speedD); // set the speed to 200/255
} else if (headingInt > 180) {
Serial.println("Left");
motorR.setSpeed(speedR-speedD); // set the speed to 200/255
motorL.setSpeed(speedL+speedD); // set the speed to 200/255
} else {
Serial.println("Straight");
motorR.setSpeed(speedR); // set the speed to 200/255
motorL.setSpeed(speedL); // set the speed to 200/255
}

motorR.run(FORWARD); // turn it on going forward
motorL.run(FORWARD);
delay(100);
}
motorR.run(RELEASE);
motorL.run(RELEASE);
}

Monday, February 6, 2012

Alternative to Robot Tank Mode Driving

Many people seem to be unaccustomed to robot tank mode driving, where the left stick controls the left motor and the right stick controls the right motor.

Robot Tank Mode Driving
When the stick is moved forward, the corresponding motor speed is increased in the forward direction. When the stick is moved backward, the corresponding motor speed is increased in the backward direction. When the two control sticks are both pushed forward the robot moves forward. When the two control sticks are moved in opposite directions, one wheel rotates forward, the other rotates backward, and the robot turns.

An Alternative to Tank Mode Driving
People that play video games ask about having the controls set up so that the left stick controls speed forward and backward, and the right stick control turning by moving the stick left and right. This alternative method creates some interesting questions about how exactly to make this happen. In playing with this a bit, the following equations were developed. The next step would be to try out these relationships and see how the driving "feels".

Friday, December 23, 2011

Arduino Mini Pro Testing


Setup Arduino Pro Mini

Soldered a right angle header on the serial connection side of the Arduino Pro Mini (3.3V) which allowed connection of the Sparkfun FDTI Basic (3.3V) board. Downloaded the Arduino software for Windows (using WinXP) and installed. Connected the FDTI Basic board to computer via the USB cable. Ardunio appears to be powered.

For the 3.3V versions of the Arduino Pro Mini:
Tools > Board menu
Select Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ATmega328

Arduino Pro Mini Tutorial:
http://www.sparkfun.com/tutorials/244

Arduino Pro Mini Schematic:
http://www.sparkfun.com/datasheets/DevTools/Arduino/Arduino-Pro-Mini_328-v11.pdf

Pinouts from schematic


Blk Side (JP7)
12 TX0
11 RXI
10 RST
9 GND
8 Digital 2
7 Digital 3
6 Digital 4
5 Digital 5
4 Digital 6
3 Digital 7
2 Digital 8
1 Digital 9

Grn Side (JP6)
1 Raw voltage input
2 GND
3 Reset
4 VCC
5 Analog 3
6 Analog 2
7 Analog 1
8 Analog 0
9 SCK
10 MISO
11 MOSI
12 Digital 10

Center (JP2)
1 Analog 4 - SDA
2 Analog 5 - SCL

Program Testing

Sample Program from Arduino examples/1.Basics folder
Blink.ino

void setup() {
// initialize the digital pin as an output.
// Pin 13 has an LED connected on most Arduino boards:
pinMode(13, OUTPUT);
}

void loop() {
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(200); // wait for a second

}


Power Connection to CEENBoT

Breakout board V1.00 to Arduino Pro Mini
GND and 3.3V pins to GRN (JP6) GND (2) and VCC (4)

Sunday, September 18, 2011

AVRISP mkII Status Light Flashing or Blinking Red and Orange

A couple students were using the AVRISP mkII to program a CEENBoT. They were using AVR Studio 4 and when they connected to the programmer, AVR Studio 4 asked them to upgrade the programmer. They started the upgrade process, but it did not finish completely. The AVRISP mkII was left in the upgrade mode and the status light at the ISP cable end was blinking between red and orange.

The fix for this is in the AVRISP mkII User Guide on the Atmel website.
Web search and download: AVRISP mkII User Guide

In the User Guide under Hardware Description they provide a table of status lights and what each light means including the blinking red and orange, which means the device is in upgrade mode.

In the Manual Firmware Upgrade section they provide the steps required to complete the upgrade of firmware. You have to open the AVRISP mkII plastic case, use a paperclip to jumper across holes 1 and 3 on the circuit board, then use AVR Studio 4 > Tools Menu > Upgrade AVRISP mkII to complete the upgrade. Remove the jumper, close the plastic case, power cycle the AVRISP mkII, and you are back in business.

Sunday, August 14, 2011

Using the Adafruit USBtinyISP

The new CEENBoT Commander uses an open source AVR mkII ISP driver that is not compatible with the regular AVR driver. When you try to run both the new CEENBoT Commander and AVR Studio 4 on the same computer, the AVR proprietary driver will load and CEENBoT Commander will not be able to program the CEENBoT. When you have both CEENBoT Commander and AVR Studio 4 installed on a computer you will need to use AVR Studio 4 to send the programs to the robot.

Well I figured that if I have to use AVR Studio 4 anyway, I might as well use the Adafruit USBtinyISP. I had built one of these kits earlier and had gotten it to work using directions from the USBtinyISP page. I used the Windows directions here.

It is really not too bad leaving CEENBoT Commander to go over to AVR Studio 4 to upload programs. And when I want to program the CEENBoT with the API using C, I can do that too using the USBtinyISP.

The next generation of CEENBoT will have the ISP programmer built in and accessible through a USB cable. So eventually the ISP programmer will not be needed anyway.

Connecting using USBtinyISP


Setup USBtinyISP Programmer
Install drivers and check that the USBtinyISP appears in the Windows device manager

Setup a COM bridge (COM2 <> COM6)
Install com0com bridge (Unclick the CNCA0<>CNCB0 checkbox during install)
Check Windows device manager for COM ports in use
Use com0com bridge command: install PortName=COM2 PortName=COM6
Windows will setup the ports (Answer No, do not search Internet, then Install automatically)
Device manager should now show the ports

Setup USBtiny500 Emulator
Install the software and run USBtiny500
Select one of the ports for the USBtiny500 emulator like COM2
Once the port is selected the USBtiny500 emulator will look for a USBtiny
The other port will be used in AVR Studio for the programmer: STK500 on COM6
The USBtiny should be found on a USB port, USBtiny500 should show: Status: Ready
If it fails to find the USBtiny on a USB port, unplug and reconnect the USBtiny interface

Setup the AVR Programmer in AVR Studio 4
Use Tools menu > Program AVR > Connect (or use Con button on toolbar)
Select Platform: STK500 and Port COM6

Verify AVR Programmer Setup by Connecting to CEENBot
Use Tools menu > Program AVR > Auto Connect (or use AVR button on toolbar)
Click Cancel if an upgrade warning message box is desplayed

Turn on CEENBoT
Connect ISP cable (6 pin)  to ISP port on CEENBoT, match the red stripe with pin 1
Under the Main tab select device: ATmega324P and Programming Mode: ISP mode
Click Read Signature button to check the connectivity to the CEENBoT
The Read Signature button may need to be clicked a few times to get the proper reading
The USB connection to the computer may need to be unplugged and reconnected
The signature returned should match selected device: ATmega324P