Robot Challenge 003

Today I worked on a few necessary but rather boring parts of the construction.

I got the Sparkfun compass module from Proto-Pic and spent a few hours setting it up and calibrating it.

I used the HMC5883L Arduino library example to generate the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <Wire.h>
#include <HMC5883L.h>
 
HMC5883L compass;
int error = 0;
 
void setup()
{
  Serial.begin(9600);
  Wire.begin(); // Start the I2C interface.
  compass = HMC5883L(); // Construct a new HMC5883 compass.
  error = compass.SetScale(1); // Set the scale of the compass. Was 1.3 in the original
  error = compass.SetMeasurementMode(Measurement_Continuous); 
}
 
// Our main program loop.
void loop()
{
  MagnetometerRaw raw = compass.ReadRawAxis();
  float heading = atan2(raw.YAxis, raw.XAxis);
 
  if(heading < 0)
    heading += 2*PI;
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)
    heading -= 2*PI;
 
  int headingDegrees = int(heading * 180/M_PI); 
  Serial.println("@|"+ String(headingDegrees) + "|#");
 
}

I wasn’t getting the readings I wanted though. I was hoping to get 0 for North, 90 for East, 180 for South and 270 for West, with an offset or something.This is what I was getting: N=330, E=90, S=200 and W=265, which meant that the distances N-E, E-S, S-W, W-N were not 90 and were not equal. Not sure why, but for my project it doesn’t make much difference, given I’ll be using a Raspberry Pi for the brain.

I wrote the following python script for calibrating the arduino results:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import serial
from time import sleep
 
def xmap(OldValue, OldMin, OldMax, NewMin, NewMax):
	t =  ((OldValue - OldMin) * (NewMax - NewMin))
	t = t / (OldMax - OldMin) + NewMin
	return t
 
 
ser = serial.Serial(2, 9600, timeout=0)
 
data = ""
while True:
	try:
		data = data + ser.read(9999)
		if data.find("@")>-1 and data.find("#")>-1: 
			data = data.strip(' \t\n\r')
			x = data.split("@")[1]
			x = x.split("#")[0]
			x = x.split("|")[1]
			x = (float(x)/10 + 3)%36
 
			if 0<=x<12: y = xmap(x,0,12,0,90)
			if 12<=x<23: y = xmap(x,12,23,90,180)
			if 23<=x<29.4: y = xmap(x,23,29.4,180,270)
			if 29.4<=x<36: y = xmap(x,29.4,36,270,360)
 
			print int(round(y,0))
			data = ""
	except: pass
 
ser.close()

The above script actually gives very acceptable results. If you use it, just ensure you feed the xmap function the information you observe in your compass.

In the final project, the compass module will be detecting the rotation of the robot and report it to the main python script. if the robot has rotated by mistake then the main python script will make the necessary adjustments.

On the battery front: I received the battery I ordered from VEX. Originally I was thinking of using sealed led acid batteries, but I didn’t want to use high voltage on the motors. Tomorrow I’ll time the battery to see how long it lasts when it powers 2 motors together.

I think I’m now ready to build the body of the robot and setup the main Python script on the Raspberry Pi for the RC mode. When that’s all done, I will add the proximity sensors and the autonomous mode on the main Python script.

The plan is also to buy an Arduino Mega, as I will need 8 digital ports for the motors, 2 ports for the compass,