Mbed project to control a hoverboard
Dependencies: mbed wave_player Servo 4DGL-uLCD-SE LSM9DS1_Library_cal HC_SR04_Ultrasonic_Library
main.cpp
- Committer:
- msafwan3
- Date:
- 2020-04-29
- Revision:
- 1:de52879ff5ec
- Parent:
- 0:808403b99108
- Child:
- 2:726636c1c83c
File content as of revision 1:de52879ff5ec:
#include "mbed.h" #include "wave_player.h" #include "SDFileSystem.h" #include "Servo.h" #include "ultrasonic.h" #include "uLCD_4DGL.h" #include "LSM9DS1.h" #include "rtos.h" Serial pc(USBTX, USBRX); uLCD_4DGL uLCD(p13,p14,p11); // serial tx, serial rx, reset pin; DigitalOut led1(p26); DigitalOut led2(p19); LSM9DS1 IMU(p9, p10, 0xD6, 0x3C); Servo dcmotorBottom(p21); // pwm Servo dcmotorBack(p22); // pwm Servo servoBottom(p23); // pwm AnalogOut DACout(p18); wave_player waver(&DACout); SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card Serial blue(p28,p27); BusOut myleds(LED1,LED2,LED3,LED4); char bnum=0;//for blue Mutex my_mutex; int dist_flag = 0; void col_ESC() { dcmotorBottom = 0.0; dcmotorBack = 0.0; wait(0.5); //ESC detects signal //Required ESC Calibration/Arming sequence //sends longest and shortest PWM pulse to learn and arm at power on dcmotorBottom = 1.0; //send longest PWM dcmotorBack = 1.0; //send longest PWM wait(8); dcmotorBottom = 0.0; //send shortest PWM dcmotorBack = 0.0; //send shortest PWM wait(8); } void dist(int distance) { while(1){ //put code here to execute when the distance has changed printf("Distance %d mm\r\n", distance); if(distance <50){ dist_flag=1; } } } ultrasonic mu(p15, p16, .1, 1, &dist); //sonar #define PI 3.14159 #define DECLINATION -4.94 // Declination (degrees) in Atlanta,GA. double x2; double y2; int x_c; int y_c; int r; int z; 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); } void IMU_fun(void const *args){//thread 1 x_c = 60; y_c = 60; r = 30; uLCD.circle(x_c, y_c, r, WHITE); z = 0; x2 = x_c + r*cos((double)z); y2 = x_c + r*sin((double)z); uLCD.line(x_c, y_c, (int)x2, (int)y2, BLUE); IMU.begin(); if (!IMU.begin()) { pc.printf("Failed to communicate with LSM9DS1.\n"); } IMU.calibrate(1); IMU.calibrateMag(0); while(1){ if(dist_flag==0){ display_compass(); } } } void dcmotorBottom_fun(void const *args){//thread2 while (1) { if(dist_flag ==0){ for (float p=0.0; p<=0.9; p += 0.05) { //Throttle up slowly to full throttle dcmotorBottom = p; wait(1.0); } } if(dist_flag ==1){ for (float p=0.9; p>=0.0; p -= 0.05) { //Throttle down slowly from full throttle dcmotorBottom = p; wait(1.0); } } } } void dist_flag1(void const *args){//thread3 while(1) { if(dist_flag==1){ for(int i=0; i<4; ++i) { //open wav file and play it FILE *wave_file; printf("\n\n\nHello, wave world!\n"); wave_file=fopen("/sd/beep.wav","r"); waver.play(wave_file); fclose(wave_file); Thread::wait(1925); } led1 =!led1; led2 =!led2; wait(0.25); } }//while }//fun void Blue_control(void const *args){//thread4 float servo_p = 0.5; while(1) { if(bnum=='1'){ dist_flag =0; } if(dist_flag==0){ if(bnum =='2'){ for(int i=0; i<4; ++i) { //open wav file and play it FILE *wave_file; printf("\n\n\nHello, wave world!\n"); wave_file=fopen("/sd/honk.wav","r"); waver.play(wave_file); fclose(wave_file); Thread::wait(1925); } } if(bnum=='3'){ led1 =!led1; led2 =!led2; } if(bnum=='5'){ for (float p=0.0; p<=0.3; p += 0.025) { //Throttle up slowly to full throttle dcmotorBack = p; wait(1.0); } } if(bnum=='6'){ for (float p=0.3; p>=0.3; p -= 0.025) { //Throttle dowm slowly from full throttle dcmotorBack = p; wait(1.0); } } if(bnum=='7' && servo_p>0.0){ servo_p = servo_p+0.05; servoBottom = servo_p; } if(bnum=='8' && servo_p<1.0){ servo_p = servo_p-0.05; servoBottom = servo_p; } } }//while(1) }//func int main()//thread5 { mu.startUpdates();//start measuring the distance col_ESC(); led1=0; led2=0; Thread t1(IMU_fun); //start thread1 Thread t2(dcmotorBottom_fun); //start thread2 Thread t3(dist_flag1); //start thread2 Thread t4(Blue_control); //start thread2 char bhit=0;//for blue while(1) { mu.checkDistance(); my_mutex.lock(); 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? my_mutex.unlock(); myleds = bnum - '0'; //current button number will appear on LEDs } } } }//for while(1) }//for int main()