Mbed electronic "bubble level." Uses LSB9DS1 9-degrees-of-freedom IMU to determine orientation and prints bubble display to LCD screen.

Dependencies:   4DGL-uLCD-SE LSM9DS1_Library_cal mbed

Files at this revision

API Documentation at this revision

Comitter:
wschon
Date:
Sat Feb 13 18:47:31 2016 +0000
Commit message:
bubble level;

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
LSM9DS1_Library_cal.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 8079f51a9835 4DGL-uLCD-SE.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/4DGL-uLCD-SE.lib	Sat Feb 13 18:47:31 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#2cb1845d7681
diff -r 000000000000 -r 8079f51a9835 LSM9DS1_Library_cal.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM9DS1_Library_cal.lib	Sat Feb 13 18:47:31 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/4180_1/code/LSM9DS1_Library_cal/#36abf8e18ade
diff -r 000000000000 -r 8079f51a9835 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Feb 13 18:47:31 2016 +0000
@@ -0,0 +1,115 @@
+#include "mbed.h"
+#include "LSM9DS1.h"
+#include "uLCD_4DGL.h"
+#define PI 3.14159
+// Earth's magnetic field varies by location. Add or subtract
+// a declination to get a more accurate heading. Calculate
+// your's here:
+// http://www.ngdc.noaa.gov/geomag-web/#declination
+#define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA.
+
+DigitalOut myled(LED1);
+Serial pc(USBTX, USBRX);
+float accel_x, accel_y, accel_z;
+int outer_radius = 9;
+int radius = 3;
+uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin;
+int x,y;
+
+// Calculate pitch, roll, and heading.
+// Pitch/roll calculations taken from this app note:
+// http://cache.freescale.com/files/sensors/doc/app_note/AN3461.pdf?fpsp=1
+// Heading calculations taken from this app note:
+// http://www51.honeywell.com/aero/common/documents/myaerospacecatalog-documents/Defense_Brochures-documents/Magnetic__Literature_Application_notes-documents/AN203_Compass_Heading_Using_Magnetometers.pdf
+void printAttitude(float ax, float ay, float az, float mx, float my, float mz)
+{
+    float roll = atan2(ay, az);
+    float pitch = atan2(-ax, sqrt(ay * ay + az * az));
+// touchy trig stuff to use arctan to get compass heading (scale is 0..360)
+    mx = -mx;
+    float heading;
+    if (my == 0.0)
+        heading = (mx < 0.0) ? 180.0 : 0.0;
+    else
+        heading = atan2(mx, my)*360.0/(2.0*PI);
+    //pc.printf("heading atan=%f \n\r",heading);
+    heading -= DECLINATION; //correct for geo location
+    if(heading>180.0) heading = heading - 360.0;
+    else if(heading<-180.0) heading = 360.0 + heading;
+    else if(heading<0.0) heading = 360.0  + heading;
+
+
+    // Convert everything from radians to degrees:
+    //heading *= 180.0 / PI;
+    pitch *= 180.0 / PI;
+    roll  *= 180.0 / PI;
+
+    pc.printf("Pitch: %f,    Roll: %f degress\n\r",pitch,roll);
+    pc.printf("Magnetic Heading: %f degress\n\r",heading);
+}
+
+
+
+
+int main()
+{
+    // basic printf demo = 16 by 18 characters on screen
+    
+    //LSM9DS1 lol(p9, p10, 0x6B, 0x1E);
+    LSM9DS1 IMU(p28, p27, 0xD6, 0x3C);
+    IMU.begin();
+    if (!IMU.begin()) {
+        pc.printf("Failed to communicate with LSM9DS1.\n");
+    }
+    IMU.calibrate(1);
+    IMU.calibrateMag(0);
+    while(1) {
+        while(!IMU.tempAvailable());
+        IMU.readTemp();
+        while(!IMU.magAvailable(X_AXIS));
+        IMU.readMag();
+        while(!IMU.accelAvailable());
+        IMU.readAccel();
+        while(!IMU.gyroAvailable());
+        IMU.readGyro();
+        pc.printf("\nIMU Temperature = %f C\n\r",25.0 + IMU.temperature/16.0);
+        pc.printf("        X axis    Y axis    Z axis\n\r");
+        pc.printf("gyro:  %9f %9f %9f in deg/s\n\r", IMU.calcGyro(IMU.gx), IMU.calcGyro(IMU.gy), IMU.calcGyro(IMU.gz));
+        pc.printf("accel: %9f %9f %9f in Gs\n\r", IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az));
+        pc.printf("mag:   %9f %9f %9f in gauss\n\r", IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz));
+        printAttitude(IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az), IMU.calcMag(IMU.mx),
+                      IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz));
+        myled = 1;
+        wait(2.5);
+        myled = 0;
+        wait(0.5);
+
+        while(1) {
+            while(!IMU.accelAvailable());
+            IMU.readAccel();
+            accel_x = IMU.calcAccel(IMU.ax);
+            accel_y = IMU.calcAccel(IMU.ay);
+            accel_z = IMU.calcAccel(IMU.az);
+            pc.printf("accel: %9f %9f %9f in Gs\n\r", IMU.calcAccel(IMU.ax), IMU.calcAccel(IMU.ay), IMU.calcAccel(IMU.az));
+            //draw ball
+            x = 64 + 64*accel_x;
+            y = 64 + 64*accel_y;
+            uLCD.circle(64, 64, outer_radius, RED);
+            uLCD.filled_circle(x,y, radius, BLUE);
+            //bounce off edge walls and slow down a bit?
+           // if ((x<=radius+1) || (x>=126-radius)) vx = -.90*vx;
+           // if ((y<=radius+1) || (y>=126-radius)) vy = -.90*vy;
+            //erase old ball location
+          //  uLCD.filled_circle(x, y, radius, BLACK);
+            //move ball
+          //  fx=fx+vx;
+           // fy=fy+vy;
+         //   x=(int)fx;
+         //   y=(int)fy;
+            wait(0.1);
+           uLCD.filled_circle(x,y, radius, BLACK);
+
+        }
+    }
+}
+
diff -r 000000000000 -r 8079f51a9835 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Feb 13 18:47:31 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/f141b2784e32
\ No newline at end of file