Mbed project to control a hoverboard

Dependencies:   mbed wave_player Servo 4DGL-uLCD-SE LSM9DS1_Library_cal HC_SR04_Ultrasonic_Library

Revision:
0:808403b99108
Child:
1:de52879ff5ec
diff -r 000000000000 -r 808403b99108 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue Apr 28 20:15:24 2020 +0000
@@ -0,0 +1,256 @@
+#include "mbed.h"
+#include "wave_player.h"
+#include "SDFileSystem.h"
+//#include "Motor.h"
+//#include "RGBLed.h"
+#include "Servo.h"
+#include "ultrasonic.h"
+#include "uLCD_4DGL.h"
+#include "LSM9DS1.h"
+
+#define PI 3.14159
+#define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA.
+int sonar_flag = 0; //1 = display distance, 0 = avoid colission
+float range = 0.0005; // for servo/motors calibration
+float position = 0.5; // for servo/motors calibration
+
+Serial pc(USBTX, USBRX);
+uLCD_4DGL uLCD(p13,p14,p11); // serial tx, serial rx, reset pin;
+//ultrasonic mu(p15, p16, .1, 1, &dist); //sonar
+DigitalOut led1(p18);
+DigitalOut led2(p19);
+
+Servo dcmotorBottom(p21); // pwm
+Servo servoBottom(p22); // pwm
+Servo dcmotorBack(p23); // pwm
+
+// Setup to play wav file from SD Card
+AnalogOut DACout(p26);
+wave_player waver(&DACout);
+SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
+ 
+// Setup for bluetooth
+Serial blue(p28,p27);
+DigitalOut myled1(LED1);
+DigitalOut myled2(LED2);
+DigitalOut myled3(LED3);
+DigitalOut myled4(LED4);
+
+void playSound(char * wav)
+{
+    FILE *wave_file;
+    wave_file = fopen(wav,"r");
+    waver.play(wave_file);
+    fclose(wave_file);
+}
+
+void bottom_motor_on()
+{
+    for (float i=0; i<=0.8; i+=0.1) {
+        dcmotorBottom = i;
+        wait(0.1);
+    }
+}
+
+void dist(int distance) 
+{   if(sonar_flag ==1) { //display distance
+    //put code here to happen when the distance is changed
+    printf("Distance changed to %dmm\r\n", distance); //print to pc for debugging
+    uLCD.cls();
+    uLCD.printf("Distance changed to %dmm\r\n", distance); //print to uLCD
+    wait(2);
+    } else { //avoid colision: beep and stop motor
+        if(distance < 2){   
+        playSound("/sd/Beeping.wav");
+        dcmotorBack = 0.0;
+        }
+    }
+    
+}
+
+float 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);
+    return heading;
+}
+
+void display_compass()
+{   
+    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));
+    float heading = 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));
+    double a = heading * 0.0174533; //deg to rad
+    x2 = x_c + r*cos(a);
+    y2 = y_c + r*sin(a);
+    uLCD.cls();
+    uLCD.circle(x_c, y_c, r, WHITE);
+    uLCD.line(x_c, y_c, (int)x2, (int)y2, BLUE);
+    wait(0.001);
+}
+
+
+int main()
+{   
+    // this part of the display compass script only needs to be set up once
+    int x_c = 60;
+    int y_c = 60;
+    int r = 30;
+    uLCD.circle(x_c, y_c, r, WHITE);
+    int z = 0;
+    double x2 = x_c + r*cos((double)z);
+    double y2 = x_c + r*sin((double)z);
+    uLCD.line(x_c, y_c, (int)x2, (int)y2, BLUE);
+    LSM9DS1 IMU(p9, p10, 0xD6, 0x3C);
+    IMU.begin();
+    if (!IMU.begin()) {
+        pc.printf("Failed to communicate with LSM9DS1.\n");
+    }
+    IMU.calibrate(1);
+    IMU.calibrateMag(0);
+
+    //calibrate motors
+    dcmotorBack.calibrate(range, position);
+    dcmotorBottom.calibrate(range, position);
+    servoBottom.calibrate(range, position)
+    
+    bottom_motor_on(); // bottom motor always on
+    float servoAngle = 90.0; // ranges from 0 to 180 degrees where 90 is center
+    mu.startUpdates(); // start mesuring the distance
+    char bnum = 0;
+    char bhit = 0;
+    while(1) 
+    {   
+        sonar_flag = 0;
+        mu.checkDistance();
+        display_compass(); // this part of the compass script needs to be done repeatedly
+        servoBottom.position(servoAngle);
+        if (blue.getc() == '!') {
+            if (blue.getc() == 'B') { //button data packet
+                bnum = blue.getc(); //button number
+                bhit = blue.getc(); //1=hit, 0=release
+                if (blue.getc() == char(~('!' + 'B' + bnum + bhit))) { //checksum OK?
+                    myled = bnum - '1'; //current button number will appear on LEDs
+                    switch (bnum) {
+                        case '1': //number button 1: speeds up motor
+                            if (bhit=='1') {
+                                //add hit code here
+                                motorSpeed += 0.2; // speed up
+                                myRGBled.write(0.0,1.0,0.0); //green
+                            } else {
+                                //add release code here
+                            }
+                            break;
+                        case '2': //number button 2: slows down motor
+                            if (bhit=='1') {
+                                //add hit code here
+                                motorSpeed -= 0.2; // speed down
+                                myRGBled.write(0.0,0.0,1.0); //blue
+                            } else {
+                                //add release code here
+                            }
+                            break;
+                        case '3': //number button 3: display distance from sonar
+                            if (bhit=='1') {
+                                //add hit code here   
+                                sonar_flag = 1; 
+                                mu.checkDistance();
+                            } else {
+                                //add release code here
+                            }
+                            break;
+                        case '4': //number button 4: play honking sound
+                            if (bhit=='1') {
+                                //add hit code here                              
+                                playSound("/sd/Honk.wav"); //write name of sound file
+                            } else {
+                                //add release code here
+                            }
+                            break;
+                        case '5': //button 5 up arrow: turn on bottom servo and back motor
+                            if (bhit=='1') {
+                                //add hit code here  
+                                for(float p=0; p<1.0; p += 0.1) {
+                                    dcmotorBack = p;
+                                    wait(0.2);
+                                }
+                                myled1 = 1;                             
+                            } else {
+                                //add release code here
+                            }
+                            break;
+                        case '6': //button 6 down arrow: switch it off (turn off back motor)
+                            if (bhit=='1') {
+                                //add hit code here
+                                dcmotorBack = 0.0;
+                                myled1 = 0;
+                                myled2 = 1;
+                            } else {
+                                //add release code here
+                            }
+                            break;
+                        case '7': //button 7 left arrow: turns servo leftwards
+                            if (bhit=='1') {
+                                //add hit code here
+                                if (servoAngle > 0.0) {
+                                    servoAngle -= 30; //turn servo left
+                                }
+                                myled3 = 1;
+                                myled4 = 0;
+                            } else {
+                                //add release code here
+                            }
+                            break;
+                        case '8': //button 8 right arrow: turns servo rightwards
+                            if (bhit=='1') {
+                                //add hit code here
+                                if (servoAngle < 180.0) {
+                                    servoAngle += 30.0; //turn servo right
+                                }
+                                myled4 = 1;
+                                myled3 = 0;
+                            } else {
+                                //add release code here
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file