We've decided to use a tilt-compensated compass module that consists of an accelerometer and a magnetometer. This particular module is a Pololu LSM303DLH #1250. It's no longer available for sale, but details are still on their website. It needed calibration based on its maximum and minimum values which were obtained by spinning the module in all directions. After the values were obtained, the heading can be accurately determined by some sample code in their Arduino library.
A few modifications were made and the Arduino interfaces with the serial port. Any UART sending it the appropriate commands will receive the desired response. As of now, the only valid command is getting the heading direction. The code looks like this:
#include <Wire.h>
#include <LSM303.h>
LSM303 compass;
char iscommand;
char command;
char a;
int count = 0;
void setup() {
Serial.begin(115200);
Wire.begin();
compass.init();
compass.enableDefault();
// Calibration values. Use the Calibrate example program to get the values for
// your compass.
compass.m_min.x = -705; compass.m_min.y = -539; compass.m_min.z = -337;
compass.m_max.x = +325; compass.m_max.y = +546; compass.m_max.z = 605;
}
void loop() {
//compass must be read constantly to get updated position
//so regardless of a need for data stream, this line is needed
compass.read();
int heading = compass.heading((LSM303::vector){0,-1,0});
//& signifies the beginning of the command
if( Serial.peek( ) == '&' )
{
//this just gets rid of the & char
Serial.read( );
//command is the next char in buffer
command = Serial.read( );
if ( command == '1' )
{
Serial.print( "Heading: " );
Serial.println(heading);
}
else
Serial.println( "Invalid command" );
}
//get rid of anything that's not part a command
else if( Serial.peek( ) != -1 )
{
Serial.read( );
}
//delay needed because processing speed > transfer speed
delay( 25 );
}
#include <Wire.h>
#include <LSM303.h>
LSM303 compass;
char iscommand;
char command;
char a;
int count = 0;
void setup() {
Serial.begin(115200);
Wire.begin();
compass.init();
compass.enableDefault();
// Calibration values. Use the Calibrate example program to get the values for
// your compass.
compass.m_min.x = -705; compass.m_min.y = -539; compass.m_min.z = -337;
compass.m_max.x = +325; compass.m_max.y = +546; compass.m_max.z = 605;
}
void loop() {
//compass must be read constantly to get updated position
//so regardless of a need for data stream, this line is needed
compass.read();
int heading = compass.heading((LSM303::vector){0,-1,0});
//& signifies the beginning of the command
if( Serial.peek( ) == '&' )
{
//this just gets rid of the & char
Serial.read( );
//command is the next char in buffer
command = Serial.read( );
if ( command == '1' )
{
Serial.print( "Heading: " );
Serial.println(heading);
}
else
Serial.println( "Invalid command" );
}
//get rid of anything that's not part a command
else if( Serial.peek( ) != -1 )
{
Serial.read( );
}
//delay needed because processing speed > transfer speed
delay( 25 );
}