From 05f2a73ba662a98e672b05f52aa209a56abeaaef Mon Sep 17 00:00:00 2001 From: Dave Astels Date: Thu, 6 Sep 2018 15:19:42 -0400 Subject: [PATCH] Forgot to update the file. --- CPX_Compass/CPX_Compass.ino | 50 +++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/CPX_Compass/CPX_Compass.ino b/CPX_Compass/CPX_Compass.ino index d0fe8276f..31925cada 100644 --- a/CPX_Compass/CPX_Compass.ino +++ b/CPX_Compass/CPX_Compass.ino @@ -1,3 +1,15 @@ +/* Circuit Playground Express compass. */ + +/* Adafruit invests time and resources providing this open source code. */ +/* Please support Adafruit and open source hardware by purchasing */ +/* products from Adafruit! */ + +/* Written by Dave Astels for Adafruit Industries */ +/* Copyright (c) 2018 Adafruit Industries */ +/* Licensed under the MIT license. */ + +/* All text above must be included in any redistribution. */ + #include #include #include @@ -7,12 +19,12 @@ /* Assign a unique ID to this sensor at the same time */ Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(12345); -float raw_mins[3] = {1000.0, 1000.0, 1000.0}; -float raw_maxes[3] = {-1000.0, -1000.0, -1000.0}; +float raw_mins[2] = {1000.0, 1000.0}; +float raw_maxes[2] = {-1000.0, -1000.0}; -float mins[3]; -float maxes[3]; -float corrections[3] = {0.0, 0.0, 0.0}; +float mins[2]; +float maxes[2]; +float corrections[2] = {0.0, 0.0}; // Support both classic and express @@ -27,6 +39,7 @@ float corrections[3] = {0.0, 0.0, 0.0}; // example for more information on possible values. Adafruit_NeoPixel strip = Adafruit_NeoPixel(10, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); +// Map direction pie slices (of 30 deg each) to a neopixel, or two for the missing ones at USB & power. int led_patterns[12][2] = {{4, 5}, {5, -1}, {6, -1}, {7, -1}, {8, -1}, {9, -1}, {9, 0}, {0 -1}, {1, -1}, {2, -1}, {3, -1}, {4, -1}}; #define BUTTON_A 4 @@ -39,6 +52,9 @@ void fill(int red, int green, int blue) { } +// Do some initial reading to let the magnetometer settle in. +// This was found by experience to be required. +// Indicated to the user by blue LEDs. void warm_up(void) { sensors_event_t event; @@ -50,10 +66,14 @@ void warm_up(void) } +// Find the range of X and Y values. +// User needs to rotate the CPX a bunch during this. +// Can be refined by doing more of the saem by pressing the A button. +// Indicated to the user by green LEDs. void calibrate(void) { sensors_event_t event; - float values[3]; + float values[2]; fill(0, 128, 0); @@ -103,10 +123,12 @@ void setup(void) } -float normalize(float value, float in_min, float in_max, float out_min, float out_max) { - float mapped = (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; - float max_clipped = mapped < out_max ? mapped : out_max; - float min_clipped = max_clipped > out_min ? max_clipped : out_min; +// Map a value from the input range to the output range +// Used to map MAG values from the calibrated (min/max) range to (-100, 100) +float normalize(float value, float in_min, float in_max) { + float mapped = (value - in_min) * 200 / (in_max - in_min) + -100; + float max_clipped = mapped < 100 ? mapped : 100; + float min_clipped = max_clipped > -100 ? max_clipped : -100; return min_clipped; } @@ -123,20 +145,22 @@ void loop(void) float x = event.magnetic.x; float y = event.magnetic.y * -1; - float z = event.magnetic.z * -1; if (x == 0.0 && y == 0.0) { return; } - float normalized_x = normalize(x - corrections[0], mins[0], maxes[0], -100.0, 100.0); - float normalized_y = normalize(y - corrections[1], mins[1], maxes[1], -100.0, 100.0); + float normalized_x = normalize(x - corrections[0], mins[0], maxes[0]); + float normalized_y = normalize(y - corrections[1], mins[1], maxes[1]); int compass_heading = (int)(atan2(normalized_y, normalized_x) * 180.0 / 3.14159); // compass_heading is between -180 and +180 since atan2 returns -pi to +pi // this translates it to be between 0 and 360 compass_heading += 180; + // We add 15 to account to the zero position being 0 +/- 15 degrees. + // mod by 360 to keep it within a circle + // divide by 30 to find which pixel corresponding pie slice it's in int direction_index = ((compass_heading + 15) % 360) / 30; // light the pixel(s) for the direction the compass is pointing