4180 Lab 2
Dependencies: mbed wave_player Servo 4DGL-uLCD-SE Motor SDFileSystem LSM9DS1_Library_cal PinDetect X_NUCLEO_53L0A1
part3.h
- Committer:
- emilywilson
- Date:
- 2020-02-04
- Revision:
- 2:de355b6fbd87
- Parent:
- 1:6d8f645530b8
File content as of revision 2:de355b6fbd87:
#include "mbed.h"
#include "LSM9DS1.h"
#include "uLCD_4DGL.h"
#include "PinDetect.h"
#include <stdio.h>
#define PI 3.14159
#define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA.
class Line {
public:
int x;
int y;
};
uLCD_4DGL uLCD(p28,p27,p30);
LSM9DS1 IMU(p9, p10, 0xD6, 0x3C);
Serial pc(USBTX, USBRX);
PinDetect pb(p16, PullUp);
int outer_radius = 15;
int inner_radius = 10;
int center = (int)floor(127.0 / 2.0);
int max_diff = 66536;
int radius = 10;
int line_length = 20;
float getAttitude(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);
return heading;
}
float compensated_heading(float ax, float ay, float az, float mx, float my, float mz) {
float p_ax, p_ay, p_az, p_mx, p_my, p_mz;
p_ax = ax; p_ay = ay; p_az = az;
p_mx = mx; p_my = my; p_mz = mz;
float roll = atan2(p_ay, p_az);
float iSin = sin(roll);
float iCos = cos(roll);
float f_my = (int)((p_my * iCos) - (p_mz * iSin)) >> 15;
p_mz = (int)((p_my * iSin) + (p_mz * iCos)) >> 15;
p_az = (int)((p_ay * iSin) + (p_az * iCos)) >> 15;
float pitch = atan2(-p_ax, sqrt(p_ay * p_ay + p_az * p_az));
iSin = sin(pitch);
iCos = cos(pitch);
if (iCos < 0) iCos = -iCos;
float f_mx = (int)((p_mx * iCos) + (p_mz * iSin)) >> 15;
float heading = atan2(-f_my, f_mx)*360 / (2*PI);
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;
return heading;
}
int calc_x(float heading, int line_length) {
float rad = (PI*heading/180);
return (int)(line_length * cos(rad));
}
int calc_y(float heading, int line_length) {
float rad = (PI*heading/180);
return (int)(line_length * sin(rad));
}
int run_part3() {
IMU.begin();
if (!IMU.begin()) {
pc.printf("Failed to communicate with LSM9DS1.\n");
}
IMU.calibrate(1);
IMU.calibrateMag(0);
pc.printf("finished imu begin");
int center = (int)floor(127.0 / 2.0);
int curr_x = center;
int curr_y = center;
while(1) {
while (!IMU.accelAvailable());
IMU.readAccel();
uLCD.filled_circle(curr_x, curr_y, inner_radius, BLACK);
uLCD.circle(center, center, outer_radius, WHITE);
int y_diff = IMU.calcAccel(IMU.ay) * 3.0;
int x_diff = IMU.calcAccel(IMU.ax) * 3.0;
curr_x = center + y_diff;
curr_y = center - x_diff;
uLCD.filled_circle(curr_x, curr_y, inner_radius, WHITE);
wait(0.01);
}
}
int run_part3_EC() {
IMU.begin();
IMU.calibrate(1);
IMU.calibrateMag(0);
uLCD.background_color(BLACK);
Line curr_line;
curr_line.x = center;
curr_line.y = center + line_length;
while (1) {
uLCD.line(center, center, curr_line.x, curr_line.y, BLACK);
uLCD.filled_circle(center, center, radius, BLACK);
uLCD.circle(center, center, radius, WHITE);
IMU.readMag();
IMU.readAccel();
float heading = getAttitude(IMU.ax, IMU.ay, IMU.az, IMU.mx, IMU.my, IMU.mz);
curr_line.x = center + calc_x(heading, line_length);
curr_line.y = center + calc_y(heading, line_length);
uLCD.line(center, center, curr_line.x, curr_line.y, WHITE);
char buffer[50];
sprintf(buffer, "Heading: %f", heading);
uLCD.text_string(buffer, 100, 10, 12, WHITE);
wait(0.1);
}
}
int run_pb_EC() {
IMU.begin();
IMU.calibrate(1);
IMU.calibrateMag(0);
int curr_x = center;
int curr_y = center;
uLCD.background_color(BLACK);
Line curr_line;
curr_line.x = center;
curr_line.y = center + line_length;
int prev_pb = pb;
int mode = 0;
while (1) {
if (pb ^ prev_pb) {
mode = !mode;
}
if (mode == 0) {
uLCD.line(center, center, curr_line.x, curr_line.y, BLACK);
uLCD.filled_circle(center, center, radius, BLACK);
uLCD.circle(center, center, radius, WHITE);
IMU.readMag();
IMU.readAccel();
float heading = compensated_heading(IMU.ax, IMU.ay, IMU.az, IMU.mx, IMU.my, IMU.mz);
curr_line.x = center + calc_x(heading, line_length);
curr_line.y = center + calc_y(heading, line_length);
uLCD.line(center, center, curr_line.x, curr_line.y, WHITE);
char buffer[50];
sprintf(buffer, "Heading: %f", heading);
uLCD.text_string(buffer, 100, 10, 12, WHITE);
wait(0.1);
} else {
while (!IMU.accelAvailable());
IMU.readAccel();
uLCD.filled_circle(curr_x, curr_y, inner_radius, BLACK);
uLCD.circle(center, center, outer_radius, WHITE);
int y_diff = IMU.calcAccel(IMU.ay) * 3.0;
int x_diff = IMU.calcAccel(IMU.ax) * 3.0;
curr_x = center + y_diff;
curr_y = center - x_diff;
uLCD.filled_circle(curr_x, curr_y, inner_radius, WHITE);
wait(0.01);
}
}
}
int run_time_EC() {
set_time(1580736096);
int center = (int)floor(127.0 / 2.0);
while (1) {
time_t seconds = time(NULL);
char buffer[50];
sprintf(buffer, "Time: %s", ctime(&seconds));
uLCD.text_string(buffer, center, center, 10, RED);
wait(0.2);
uLCD.rectangle(0, 0, 127, 127, BLACK);
}
}