Color Compass

Views: 2142 Difficulty: 4 Status: Pipeline
Screen_shot_2013-03-01_at_7.27.14_pm

Coupling the HMC5883L Compass with our color library turns the TFT LCD screen into wearable navigation.

Compasses help us orient ourselves in the world. The HMC 5883L is an affordable 3-axis compass. Bildr has a great tutorial and library to get you started. You can get the compass from sparkfun or digikey. We connect the compass to a SMD package arduino hooked up to a TFT LCD Screen. We use our arduino color library to color the compass hand rainbow colors depending on where it is facing.

Rainbow Compass

Compassy
  • Compassy
    Compassy
    Rainbow Compass
    Rainbows show you the cardinal directions.
  • Screen_shot_2013-03-02_at_6.49.54_am
    Screen_shot_2013-03-02_at_6.49.54_am
    Compass PCB Footprint
    See the little footprint of the tiny HMC5883L compass. It is tough but not impossible to solder by hand. A hot air gun and lots of flux will definitely help.
  • Screen_shot_2013-03-02_at_6.50.12_am
    Screen_shot_2013-03-02_at_6.50.12_am
    More Footprints
    The accelerometer and the lithium battery charge controller live on these little SMD footprints, pre-soldered but unpopulated. We pre-solder because we do reflow soldering with a hot air gun. It is called reflow because the solder is applied first then flows again (or reflows) as heat is applied.
  • Screen_shot_2013-04-02_at_6.07.09_pm
    Screen_shot_2013-04-02_at_6.07.09_pm
    The Compass With its Piezo Horn
    The piezo horn is included because this PCB is designed to be a bike computer.
Rainbows show you the cardinal directions.

Compass Video

Color compass accelerated. Strong magnets will confuse it.

Arduino Code

This code relies on several libraries: the very thorough HMC5883L library from bildr, adafruit's ST7735 TFT LCD Screen library, our color library, and the standard arduino SPI library. Okay now that we got the dependencies down, we got some functions to talk about:
int get_color_from_angle(int angle){
  Color cur_color=Color(0,0,0);
  cur_color.convert_hcl_to_rgb((float)angle/360,0.95,0.7);
  return cur_color.get_color_16bit(); 
}
This function translates from a degree ((0-360) that we got from the compass which represents our heading) and a color. Using the HSB color mode the above code maps each heading to a different hue. Then once we have read the heading from the compass (it is given in radians) we draw a ray and two orbiting circles rotated by the heading:
float headingDegrees = heading * 180/M_PI; 
  draw_ray(64,80, headingDegrees, 40);
  draw_orbiter(64,80, headingDegrees, 22,6);
  draw_orbiter(64,80, headingDegrees, 32,3);
/* LucidTronix color compass 
 * Rainbow colored wearable navigator 
 * For instructions, details and schematic, See:
 * http://www.lucidtronix.com/tutorials/30
 * Uses the HMC5883L.h library from bildr
 */
#include <color.h>
#include <ST7735.h>
#include <SPI.h>

#define cs 10   // for MEGAs you probably want this to be pin 53
#define dc 9
#define rst 8  // you can also connect this to the Arduino reset

ST7735 tft = ST7735(cs, dc, rst);

// Reference the I2C Library
#include <Wire.h>
// Reference the HMC5883L Compass Library
#include <HMC5883L.h>

// Store our compass as a variable.
HMC5883L compass;
// Record any errors that may occur in the compass.
int error = 0;

int btnPin0 = 0;
int btnPin1 = 1;

int mode = 0;
int num_modes = 4;

unsigned int last_press = 0;

int background_color = 0xFF;
int color = 0xFF;

int backlight_pwm_pin = 3;
char* stringy = "nothinghere";
void setup(){
  pinMode(btnPin1,INPUT);
  pinMode(btnPin0,INPUT);
  tft.initR();               // initialize a ST7735R chip
  tft.writecommand(ST7735_DISPON); 
  delay(1000);
  tft.fillScreen(BLACK);
  tft.drawString(4, 4, "Starting up...", CYAN,1);
  Wire.begin(); // Start the I2C interface.
  compass = HMC5883L(); // Construct a new HMC5883 compass.
  float scalar = 4.0;
  //not checking errors you should if you have issues.
  error = compass.SetScale(scalar); // Set the scale of the compass.
  error = compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous
  delay(500);
}
void loop(){
  if ( digitalRead(btnPin0) == HIGH)tft.fillScreen(WHITE);
  MagnetometerRaw raw = compass.ReadRawAxis();
  // Retrived the scaled values from the compass (scaled to the configured scale).
  MagnetometerScaled scaled = compass.ReadScaledAxis();
  // Values are accessed like so:
  int MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis)
  // Calculate heading when the magnetometer is level, then correct for signs of axis.
  float heading = atan2(scaled.YAxis, scaled.XAxis);
  float declinationAngle = 0.0457;
  heading += declinationAngle;
  // Correct for when signs are reversed.
  if(heading < 0)
    heading += 2*PI;
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)
    heading -= 2*PI;
  float headingDegrees = heading * 180/M_PI; 
  draw_ray(64,80, headingDegrees, 40);
  draw_orbiter(64,80, headingDegrees, 22,6);
  draw_orbiter(64,80, headingDegrees, 32,3);
}

void draw_ray(int ax, int ay, int angle, int radius ){
  float ray_x = cos(((float)angle*PI)/180.0f)*(float)radius;
  float ray_y = sin(((float)angle*PI)/180.0f)*(float)radius;
  int c = get_color_from_angle(angle);
  tft.drawLine(ax,ay,ax+ray_x, ay+ray_y, c);
}

void draw_orbiter(int ax, int ay, int angle, int radius, int a_size){
  float ray_x = cos(((float)angle*PI)/180.0f)*(float)radius;
  float ray_y = sin(((float)angle*PI)/180.0f)*(float)radius;
  int c = get_color_from_angle(angle);
  tft.fillCircle(ax+ray_x, ay+ray_y, a_size, c);
}

int get_color_from_angle(int angle){
  Color cur_color=Color(0,0,0);
  cur_color.convert_hcl_to_rgb((float)angle/360,0.95,0.7);
  return cur_color.get_color_16bit(); 
}

Parts

Title Description # Cost Link Picture
TFT LCD Screen 1.8 inch 160 x 128 pixels LCD screen. ST7735R driver. JDT-1800. 1 $9.95 Link Id618_lrg
PCB SMD Bike The circuit board for the bike computer. 1 $8.0 Link Screen_shot_2013-02-15_at_5.34.51_pm
HMC5883L-TR IC COMPASS 3 AXIS I2C 16LCC SMD Value: 2.16 V ~ 3.6 V ±8G Compass - Three Axis 1 $3.44 Link Screen_shot_2012-12-28_at_7.35.30_pm
Accelerometer ±4g, 9g Value: X, Y 1 $3.22 Link Screen_shot_2012-12-28_at_7.34.36_pm
ATMEGA328P-AU Integrated Circuits (ICs) MCU AVR 32K FLASH 32TQFP Value: 1.8 V ~ 5.5 V 20MHz 1 $3.05 Link Screen_shot_2012-12-28_at_7.31.33_pm
USB connector USB Mini type B Value: female 1 $0.68 Link Usb-m26ftr
Voltage Regulator 3v3 SMD IC REG LDO 3.3V .15A SOT23 Up to 6V input output 3.3V 150mA (Max) Value: 3.3V 1 $0.46 Link Sot-23-3_pkg
CD4050 IC BUFF/CONVERTER HEX 16SOICN 8mA, 48mA Value: 3 V ~ 18 V 1 $0.45 Link 16-soic_(7.5mmwidth)
Resistor Chip Resistor - Surface Mount RES 10K OHM 1/8W 5% 0805 SMD Value: 10k 1 $0.1 Link Screen_shot_2012-12-28_at_7.29.44_pm
Permalink: http://lucidtronix.com/tutorials/30
Viewed: 4:46PM, May 22
Viewed: 4:44PM, May 22
Viewed: 4:43PM, May 22
Viewed: 4:43PM, May 22
Viewed: 4:43PM, May 22
Viewed: 4:42PM, May 22
Viewed: 4:37PM, May 22
Viewed: 4:24PM, May 22
Viewed: 4:19PM, May 22
Viewed: 4:13PM, May 22
Viewed: 4:10PM, May 22
Viewed: 4:02PM, May 22
Viewed: 3:35PM, May 22
Viewed: 3:21PM, May 22
Viewed: 3:10PM, May 22
Go to page: 1 2 3