This project was a spin off from the use of the Adafruit 3 axis magnetometer navigation element in our current robot, the plant watering robot. The Adafruit magnetometer is an amazing sensor, built on a tiny break out board complete with TTL level conversion and direct I2C interface to your microcontroller. The best part? its only $9. I bought two of them and while one went into C-Bot, the other is included as the primary sensor in this project. This project takes the compass data, and sends it serially over the RS232 TX line using the UART at 9600kb as two bytes which represent the 0 - 360 degree data x 100. Then on the receive side, your main micro controller takes the data and divides by 100 to get the full 0 - 360 with two decimals.
The purpose of all of this was to offload the huge 3k of compass driver from the main processor and allow it to have much more program space, and not have to deal with this complex driver code with its two big math libraries. Shown here is the actual compass chip, followed by a typical main processor, the 16F887 receiving the data.
Left: Bench setup with compass chip (PIC16F876a) in a housing with the Adafruit compass board at the top of the box, just above the compass processor. The top large processor is the receive chip, and is a PIC16F887 which sends it data to the LCD on the right.
Showing the received data in degrees as received from the main processor.
Schematic for the compass chip - Click to Enlarge.
Schematic for the 887 receive chip - click to enlarge.
CCS-C code for the Compass Chip:
//**************************************************************************** /*Description of this Program: This version - Sends 5 digits serially of compass data from the Adafruit compass module */
//I/O Designations
--------------------------------------------------- // RB0: // RC0: Status
LED output
//-------------------------------------------------------------------- //Include Files: //Directives and Defines: #fuses NOPROTECT,HS,NOWDT
//xtal is used //set up i2c -
data, clock pins are here hardware on 877a.part uses slow spec.
#use fast_io(ALL) //must define tris below in main when using this // HMC5883 required
Registers //for LCD:
//**************************************************************************** //**************************************************************************** //for compass only:
//Clears LCD Display: //Sets LCD to line
2 start point
//**************************************************************************** void main(void) { // Set TRIS
I/O directions, define analog inputs, compartors: //Initialize
variables and Outputs: -------------------------------------- //MAIN: hmc5883_init(); //Initialize compass settings. while (true) { read_reg();
//read compass registers, calc xyz LCDCLR(); } //elihw //********* Functions which have prototypes at top of program ****************
//for compass only: float calc_heading()
{ } |
//**************************************************************************** /*Description of this Program: This version - receivs serial compass data at 9600kb with updates around once every 68ms*/
//I/O Designations
--------------------------------------------------- // RB0: (AN12,EXT
INT) Status LED output // RC0: // RD0: // RE0: (AN5) //-------------------------------------------------------------------- //Include Files: //Directives and Defines: #fuses NOPROTECT,HS,NOWDT
//xtal is used //for LCD: //For reciving
compass data on pin A0: //NO_ANALOGS is default in device file...(All I/Os are digital)
//***Global Variables:******************************************************** //***Functions/Subroutines,
Prototypes:*************************************** //Sets LCD to line
2 start point void GETCOMPASS(void);
//this function gets the raw compass value and converts
//**************************************************************************** void main(void) { // Set TRIS
I/O directions, define analog inputs, compartors: //Initialize
variables and Outputs: --------------------------------------
//Main Program
while (true) { GETCOMPASS();
//go get compass data serially } //while //********* Functions which have prototypes at top of program **************** void GETCOMPASS(void)
{ compasstimeout = 0; //reset timeout while (!kbhit(COMPASS)
&& (++compasstimeout < 50000)) //half second wait
IF NO SIGNAL |
HOME