Summer Robotics Project #5 – Compass Module

(another long, wordy post.. just a heads up)

As you may know, when testing the 16×2 LCD display we bought for the project, we managed to get it to print readings from the Ultrasonic sensor. We then figured that it would be more useful to have the LCD print bearings from the compass than distances from the sensor. By doing this, we can easily read our bearings without needing to access the serial monitor through the Arduino IDE. The compass module used, HMC5883L, only required four connections – Power, Ground, Data and Clock. The breadboard we were currently using with the Arduino was starting to get a bit busy, and accessing the different components and numerous wires that were attached to it proved to be fiddly, so we attached another breadboard for the LCD and compass module. We connected the first breadboard to the second so that it could use the same power supply (as the Arduino only has one 5V pin), and we also connected the data and clock connections on the first breadboard to the second (again, due to the Arduino only having one data and one clock pin).

Once we had mounted the compass, it needed to be calibrated due to it’s location being offset, which was done using a code found online (I will post a link to this when I find it). After calibrating the compass and finding out our offsets, we input these values into our Arduino sketch. We, then, proceeded to use a code found on the Hobbylogs website to get readings from the compass module. When run, the compass takes the readings and sends values for X, Y and Z and also your heading to the serial monitor. We modified the code so that the LCD prints the readings for heading.

Once we got the readings to be printed, we wanted to control the turns made by the wheels using the compass. Currently, the turns are being executed using odometry – the same method we used for Eurobot. It isn’t as accurate as it uses counts to judge how far to rotate each wheel. Our aim was to use the compass module to tell the motors to rotate when within a given range, and then to halt when it is outside of that range, meaning the rotation has been completed. It took a lot of trial and error, trying to figure out the right code. At first, we were able to get the compass to respond to the range but not the motors. After tweaking the code a little, we were able to get some response from the motors, but not what we had hoped – they kept running and didn’t stop when they were outside of the range. We overcame this issue by initially serial printing certain values, such as the current bearing, the angle we wanted the robot to rotate and the angle it was rotating by. We examined these values closely to try and develop a solution to our problem and ended up writing the following piece of code:

float getAngle(){
 compass_heading();
 float refAngle = bearing - initialAngle;
}

The code above takes the current bearing, and the angle the robot is facing on startup and finds the difference between them. On startup, the value of refAngle is zero – we found that setting the initial value to zero was the best way to overcome the problems we faced earlier. As the values for refAngle can vary outside of the 0 and 360 degree range, we also wrote this within the same getAngle() function, after defining refAngle, to keep the values within the required range:

if(refAngle < 0){
 refAngle += 360;
 return refAngle;}
 
else if(refAngle > 360){
 refAngle -= 360;
 return refAngle;}
else{
 return refAngle;}
 }

Using this function, and also another function that was written to set the motor speeds, we wrote a Turn function, which takes the variables angle – the angle we want to rotate – and a bool value to let the robot know whether it is rotating clockwise or anti-clockwise. This function utilises a ‘do{} while()’ loop, where the motors run while the getAngle() value is either less than or greater than the angle we want the robot to rotate. We decided not to use “less (greater) than or equal to (<= >=)”, as the motors will not stop instantaneously. By using > or <, we can allow for the time it takes the motors to come to a complete stop and should lessen the loss of accuracy a bit more. Once the value of getAngle() has exceeded this range, the motors stop spinning, completing the turn.

void Turn(float angle, bool clockwise){ 
// This function turns the platform right by a previously set angle
 Serial.println("Turning Right");
 if (clockwise){
     float(targetAngle) = angle;

//------ SERIAL PRINTS ------//
 Serial.print("Target Angle: ");
 Serial.println(targetAngle);
 Serial.print("Current Angle: ");
 Serial.println(getAngle());
 Serial.println(" ");

//----- MOTOR COMMANDS -----//
     do{
       setMotorSpeed(-20, 90); // cwise = set speed1 as -ve, & so on
       } while(getAngle() < targetAngle);
 }
else{
    float(targetAngle) = 360 - angle;

//------ SERIAL PRINTS ------//
 Serial.print("Target Angle: ");
 Serial.println(targetAngle);
 Serial.print("Current Angle: ");
 Serial.println(getAngle());
 Serial.println(" ");

//----- MOTOR COMMANDS -----//
    do{
       setMotorSpeed(20, -20);
      } while(getAngle() > targetAngle);
 }
  stopMotor();
  encodeReset();
 }

When we ran the code, though it was hard to judge at first, we noticed from the serial monitor values that readings fluctuated by a maximum of a degree either way. Due to this, the initial value for getAngle() fluctuated between 359 and 1 degree, and was never exactly at 0 degrees. Though this created a slight delay in the turn, it didn’t affect the turn too much. During the fluctuations, when the compass read a value greater 0 degrees (when turning clockwise) or less than 360 (when turning anticlockwise), the motors would rotate the slightest bit. This, with wheels attached, turn rotate the robot a little in the direction of rotation. After about one round of fluctuations, the robot would have rotated enough for the reading to be within the range needed, and the turn manoeuvre can continue as normal. We have yet to find a way to overcome these slight fluctuations in value, but for now, we’re testing the robot with the slight delay.

Advertisements

One thought on “Summer Robotics Project #5 – Compass Module

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s