ECE 4180 Lab 2 Part 3 Extra Credit

Dependencies:   4DGL-uLCD-SE LSM9DS1_Library_cal mbed

Fork of uLCD144G2_demo by jim hamblen

main.cpp

Committer:
abraha2d
Date:
2018-10-09
Revision:
10:a35b7bd001ba
Parent:
8:31e63caf37e2

File content as of revision 10:a35b7bd001ba:

#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.

Serial pc(USBTX, USBRX);
uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin;

// Calculate heading.
// 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
float calcHeading(float mx, float my, float mz)
{
    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);
    heading -= DECLINATION;
    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;
    return heading;
}

float rotate_point_x(float x, float y, float a)
{
    return x * cos(a * PI/180.0) - y * sin(a * PI/180.0);
}

float rotate_point_y(float x, float y, float a)
{
    return y * cos(a * PI/180.0) + x * sin(a * PI/180.0);
}

int main()
{
    uLCD.cls();
    uLCD.printf("Baud rate: 3000000");
    uLCD.baudrate(3000000);

    uLCD.printf("Calibrating IMU...\n");
    LSM9DS1 IMU(p28, p27, 0xD6, 0x3C);
    bool success = IMU.begin();
    if (!success) {
        uLCD.printf("Failed to communicate with LSM9DS1.\n");
    }
    IMU.calibrate(1);
    IMU.calibrateMag(0);

    wait(0.5);
    uLCD.cls();
    while(1) {
        while(!IMU.magAvailable(X_AXIS));
        IMU.readMag();
        float heading = calcHeading(IMU.calcMag(IMU.mx), IMU.calcMag(IMU.my), IMU.calcMag(IMU.mz));
        pc.printf("%f                                                                      ", heading);
        uLCD.circle(64, 64, 48, WHITE);
        uLCD.triangle(
            64 + rotate_point_x(-5, 10, heading), 64 + rotate_point_y(-5, 10, heading),
            64 + rotate_point_x(5, 10, heading), 64 + rotate_point_y(5, 10, heading),
            64 + rotate_point_x(0, -15, heading), 64 + rotate_point_y(0, -15, heading),
            RED);
        wait(0.05);
        uLCD.triangle(
            64 + rotate_point_x(-5, 10, heading), 64 + rotate_point_y(-5, 10, heading),
            64 + rotate_point_x(5, 10, heading), 64 + rotate_point_y(5, 10, heading),
            64 + rotate_point_x(0, -15, heading), 64 + rotate_point_y(0, -15, heading),
            BLACK);
    }
}