ECE 4180 Final Project - Georgia Institute of Technology by LZ and EM
Dependencies: mbed Motor BNO055 SDFileSystem LSM9DS1_Library_cal HC_SR04_Ultrasonic_Library
main.cpp
- Committer:
- elisham11
- Date:
- 2019-12-03
- Revision:
- 0:2266b80b252e
File content as of revision 0:2266b80b252e:
#include "mbed.h" #include "ultrasonic.h" #include "SDFileSystem.h" #include <string> #include "Motor.h" #include "LSM9DS1.h" #define PI 3.14159 #define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA. Serial pc(USBTX, USBRX); DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); //H-bridge Motor m_left(p21, p15, p16); // pwm,fwd,rev pwmA Motor m_right(p22, p19, p20); // pwm,fwd,rev //Photo transistor AnalogIn photocell(p18); //Timer Timer t; //t.start(), t.stop(), t.read() //SD Card SDFileSystem sd(p5, p6, p7, p8, "sd"); RawSerial Bluetooth(p13,p14); // tx, rx //Global variables for bluetooth control bool sonarOn = false; //Indicates when sonar is taking measurements char heading = '0'; //Indicates rough direction of the robot; 'f' = forward, 'l' = left, 'r' = right, 'b' = backwards, '0' = not moving bool running = true; //Keeps main while loop going //Code for interrupt routine for Bluetooth input enum statetype {start = 0, got_exclm, got_B, got_one, got_two, got_three, got_five, got_six, got_seven, got_eight, got_11, got_21, got_31, got_51, got_61, got_71, got_81}; statetype state = start; //Interrupt routine to parse message with one new character per serial RX interrupt void parse_message() { switch (state) { case start: if (Bluetooth.getc()=='!') { //led2 = 1; state = got_exclm; } else state = start; break; case got_exclm: if (Bluetooth.getc() == 'B') { state = got_B; } else state = start; break; case got_B: { char recv = Bluetooth.getc(); if (recv == '1') state = got_one; else if (recv == '2') state = got_two; else if (recv == '3') state = got_three; else if (recv == '5') state = got_five; else if (recv == '6') state = got_six; else if (recv == '7') state = got_seven; else if (recv == '8') state = got_eight; else state = start; } break; case got_one: if (Bluetooth.getc() == '1') { //Make sure motors are stopped m_left.speed(0.0); m_right.speed(0.0); sonarOn = false; heading = '0'; running = false; } else state = start; break; case got_two: //Stop everything if (Bluetooth.getc() == '1') { } else state = start; break; case got_three: //currently unimplemented if (Bluetooth.getc() == '1') { } else state = start; break; case got_five: //up arrow pressed { char recv = Bluetooth.getc(); if (recv == '1') //Button pressed or held { sonarOn = true; heading = 'f'; m_left.speed(0.42); m_right.speed(0.4); } else if (recv == '0') //Button released { //sonarOn = false; heading = '0'; m_left.speed(0.0); m_right.speed(0.0); } else state = start; } break; case got_six: //down arrow pressed { char recv = Bluetooth.getc(); if (recv == '1') //Button pressed or held { sonarOn = true; heading = 'b'; m_left.speed(-0.42); m_right.speed(-0.4); } else if (recv == '0') { //sonarOn = false; heading = '0'; m_left.speed(0.0); m_right.speed(0.0); } else state = start; } break; case got_seven: //turn left { char recv = Bluetooth.getc(); //sonarOn = false; if (recv == '1') { heading = 'l'; m_left.speed(-0.3); m_right.speed(0.3); } else if (recv == '0') { heading = '0'; m_left.speed(0.0); m_right.speed(0.0); } else state = start; } break; case got_eight: //turn right { char recv = Bluetooth.getc(); //sonarOn = false; if (recv == '1') { heading = 'r'; m_left.speed(0.3); m_right.speed(-0.3); } else if (recv == '0') { heading = '0'; m_left.speed(0.0); m_right.speed(0.0); } else state = start; } break; default: Bluetooth.getc(); state = start; } } //To see serial output on Mac, run ls /dev/tty.usbmodem* once the mbed is connected //to find its location. Then run screen <mbed location> to see serial output. int Left[1000]; float Time[1000]; char Head[1000]; float Light[1000]; float Mag[1000]; int j = 0; int k = 0; volatile bool startTime = false; void distL(int distance) { if (sonarOn && startTime) { Left[j] = distance; Time[j] = t.read(); Head[j] = heading; Light[j] = (float)photocell; j++; printf("Distance %i mm, Time %f s, Light %0.3f ,Heading %c \r\n", distance, t.read(), (float)photocell, heading);//code here to execute when distance changes } } //IMU void printAttitude(float ax, float ay, float az, float mx, float my, float mz) { if(sonarOn && startTime) { 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); wait(0.3); Mag[k] = heading; k++; } } //sample 10 times every 3 seconds ultrasonic mu_L(p11, p12, .3, 1, &distL); //Set the trigger pin to D8 and the echo pin to D9 //have updates every .1 seconds and a timeout after 1 //second, and call dist when the distance changes int main() { LSM9DS1 IMU(p28, p27, 0xD6, 0x3C); led = 0.0 IMU.begin(); if (!IMU.begin()) { pc.printf("Failed to communicate with LSM9DS1.\n"); } IMU.calibrate(1); IMU.calibrateMag(0); led1 = 1.0; wait(0.5); led1 = 0.0; //t.start(); //start timer mu_L.startUpdates(); //start measuring the distance with sonar sensor Bluetooth.attach(&parse_message,Serial::RxIrq); //attach bluetooth interrupt while(running) { mu_L.checkDistance(); //call checkDistance() as much as possible, as this is where //the class checks if dist needs to be called. //Start the timer only once sonar has turned on and the timer has not been previously started while(!IMU.tempAvailable()); IMU.readTemp(); while(!IMU.magAvailable(X_AXIS)); IMU.readMag(); while(!IMU.accelAvailable()); IMU.readAccel(); while(!IMU.gyroAvailable()); IMU.readGyro(); 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)); if (sonarOn && !startTime) { startTime = true; t.start(); } } //Store values into SD card //Open a new file to store the data mkdir("/sd/mydir", 0777); FILE *left = fopen("/sd/mydir/left.txt", "w"); if(left == NULL) //If there is an error in opening the file, throw error { error("Could not open file left for write\n"); } fprintf(left, "sonar, \t time, \t light, \t heading \n"); //Loop through array values and store into each line of text for (int i=0; i<1000; i++) { fprintf(left, "%i, %0.4f, %0.4f, %0.4f, %c \n", Left[i], Time[i],Light[i] , Mag[i], Head[i]); } //Close file fclose(left); }