Kartik Sastry / Mbed 2 deprecated 4180Final

Dependencies:   4DGL-uLCD-SE LSM9DS1_Library-KVS MBed_Adafruit-GPS-Library PinDetect X_NUCLEO_53L0A1 mbed-rtos mbed

Committer:
ksastry3
Date:
Wed Dec 06 02:21:17 2017 +0000
Revision:
0:8a797b9e2fe4
Child:
1:abc522e41d63
Version 0 by Kartik V. Sastry on 12/5/2017, 9:21 PM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ksastry3 0:8a797b9e2fe4 1 /* Code for ECE 4180-A Final Design Project */
ksastry3 0:8a797b9e2fe4 2 /* Kartik Sastry, Robert Walsh, Krishna Peri */
ksastry3 0:8a797b9e2fe4 3 /* mbed Based Fitness Wearable Prototype */
ksastry3 0:8a797b9e2fe4 4
ksastry3 0:8a797b9e2fe4 5 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 6 /* Devices Used and Pin Assignments */
ksastry3 0:8a797b9e2fe4 7 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 8 /*
ksastry3 0:8a797b9e2fe4 9 - mbed LPC1768 Microcontroller
ksastry3 0:8a797b9e2fe4 10 - Adafruit VL53L0X Time of Flight Distance Sensor (LIDAR)
ksastry3 0:8a797b9e2fe4 11 I2C p9, p10
ksastry3 0:8a797b9e2fe4 12 DigitalOut p26
ksastry3 0:8a797b9e2fe4 13 - Heart Rate Sensor / Pulse Oximeter - Maxim MAXREFDES117#
ksastry3 0:8a797b9e2fe4 14 I2C p9, p10
ksastry3 0:8a797b9e2fe4 15 - LSM9DS1 9 degrees-of-freedom Inertial Measurement Unit (IMU)
ksastry3 0:8a797b9e2fe4 16 I2C p9, p10
ksastry3 0:8a797b9e2fe4 17 - Adafruit Ultimate GPS Breakout V3 (GPS)
ksastry3 0:8a797b9e2fe4 18 Serial 14, 15
ksastry3 0:8a797b9e2fe4 19 - 4D Systems 4DGL-uLCD LCD Display (LCD)
ksastry3 0:8a797b9e2fe4 20 Serial p27, p28, p30
ksastry3 0:8a797b9e2fe4 21 - Pushbutton (Wire one switch pole to p7, the other directly to ground. No need for external pullup resistor.)
ksastry3 0:8a797b9e2fe4 22 PinDetect p7
ksastry3 0:8a797b9e2fe4 23 */
ksastry3 0:8a797b9e2fe4 24
ksastry3 0:8a797b9e2fe4 25 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 26 /* Libraries and Include Files */
ksastry3 0:8a797b9e2fe4 27 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 28 #include "mbed.h"
ksastry3 0:8a797b9e2fe4 29 #include "rtos.h"
ksastry3 0:8a797b9e2fe4 30 //#include "SDFileSystem.h"
ksastry3 0:8a797b9e2fe4 31 #include "uLCD_4DGL.h"
ksastry3 0:8a797b9e2fe4 32 #include "LSM9DS1.h"
ksastry3 0:8a797b9e2fe4 33 #include "MBed_Adafruit_GPS.h"
ksastry3 0:8a797b9e2fe4 34 #include "XNucleo53L0A1.h"
ksastry3 0:8a797b9e2fe4 35 #include "math.h"
ksastry3 0:8a797b9e2fe4 36 #include <stdio.h>
ksastry3 0:8a797b9e2fe4 37 #include "PinDetect.h"
ksastry3 0:8a797b9e2fe4 38
ksastry3 0:8a797b9e2fe4 39 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 40 /* I/O Object Declarations */
ksastry3 0:8a797b9e2fe4 41 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 42 Serial pc(USBTX, USBRX); // Interface to PC over virtual COM
ksastry3 0:8a797b9e2fe4 43 uLCD_4DGL uLCD(p28, p27, p30); // LCD
ksastry3 0:8a797b9e2fe4 44 LSM9DS1 imu(p9, p10, 0xD6, 0x3C); // IMU
ksastry3 0:8a797b9e2fe4 45 //Serial * gps_Serial; // GPS
ksastry3 0:8a797b9e2fe4 46 #define VL53L0_I2C_SDA p9 // LIDAR
ksastry3 0:8a797b9e2fe4 47 #define VL53L0_I2C_SCL p10 // I2C sensor pins for LIDAR
ksastry3 0:8a797b9e2fe4 48 DigitalOut shdn(p26); // This VL53L0X board test application performs a range measurement in polling mode
ksastry3 0:8a797b9e2fe4 49 // Use 3.3(Vout) for Vin, p9 for SDA, p10 for SCL, P26 for shdn on mbed LPC1768
ksastry3 0:8a797b9e2fe4 50 PinDetect myPushbutton(p7); // For Mode Selection Feature
ksastry3 0:8a797b9e2fe4 51
ksastry3 0:8a797b9e2fe4 52 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 53 /* Global Variables (Carefully Managed) */
ksastry3 0:8a797b9e2fe4 54 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 55 // Globals for IMU
ksastry3 0:8a797b9e2fe4 56 float new_x = 0, new_y = 0, new_z = 0;
ksastry3 0:8a797b9e2fe4 57 bool start = 0;
ksastry3 0:8a797b9e2fe4 58 int count = 0;
ksastry3 0:8a797b9e2fe4 59
ksastry3 0:8a797b9e2fe4 60 // Globals For GPS
ksastry3 0:8a797b9e2fe4 61 // Declare
ksastry3 0:8a797b9e2fe4 62 Serial gps_Serial(p13,p14); // Serial object for use w/ GPS
ksastry3 0:8a797b9e2fe4 63 Adafruit_GPS myGPS(&gps_Serial); // Object of Adafruit's GPS class
ksastry3 0:8a797b9e2fe4 64 Timer refresh_Timer; // Sets up a timer for use in loop; how often do we print GPS info?
ksastry3 0:8a797b9e2fe4 65 const int refresh_Time = 2000; // refresh time in ms
ksastry3 0:8a797b9e2fe4 66 char c; // when read via Adafruit_GPS::read(), the class returns single character stored here
ksastry3 0:8a797b9e2fe4 67
ksastry3 0:8a797b9e2fe4 68 // Globals For LIDAR
ksastry3 0:8a797b9e2fe4 69 static XNucleo53L0A1 *board=NULL;
ksastry3 0:8a797b9e2fe4 70 int status;
ksastry3 0:8a797b9e2fe4 71 uint32_t distance;
ksastry3 0:8a797b9e2fe4 72
ksastry3 0:8a797b9e2fe4 73 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 74 /* Necessary Mutex Locks */
ksastry3 0:8a797b9e2fe4 75 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 76 Mutex mySerialMutex; // On PC com port
ksastry3 0:8a797b9e2fe4 77 Mutex myLCDMutex; // On uLCD
ksastry3 0:8a797b9e2fe4 78
ksastry3 0:8a797b9e2fe4 79 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 80 /* Device Selection / Thread Control */
ksastry3 0:8a797b9e2fe4 81 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 82 enum DATA_ACQ_MODE {MODE_IMU_SELECT, MODE_GPS_SELECT, MODE_LIDAR_SELECT}; // by default mapped to {0, 1, 2}
ksastry3 0:8a797b9e2fe4 83 volatile int myMode = MODE_IMU_SELECT; // To be changed by pushbutton presses
ksastry3 0:8a797b9e2fe4 84
ksastry3 0:8a797b9e2fe4 85 // Short ISR - serviced when interrupt given by myPushbutton hit
ksastry3 0:8a797b9e2fe4 86 void changeMode_ISR(void) {
ksastry3 0:8a797b9e2fe4 87 myMode = (myMode + 1) % 3; // mod 3 makes it periodic (0,1,2,0,1,2)
ksastry3 0:8a797b9e2fe4 88 }
ksastry3 0:8a797b9e2fe4 89
ksastry3 0:8a797b9e2fe4 90 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 91 /* Function Prototypes of Threads */
ksastry3 0:8a797b9e2fe4 92 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 93 void IMU_THREAD();
ksastry3 0:8a797b9e2fe4 94 void GPS_THREAD();
ksastry3 0:8a797b9e2fe4 95 void LIDAR_THREAD();
ksastry3 0:8a797b9e2fe4 96 void LCD_THREAD();
ksastry3 0:8a797b9e2fe4 97
ksastry3 0:8a797b9e2fe4 98 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 99 /* Main Thread: Initialization and Heart Rate */
ksastry3 0:8a797b9e2fe4 100 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 101 int main() {
ksastry3 0:8a797b9e2fe4 102
ksastry3 0:8a797b9e2fe4 103 // Set up IMU
ksastry3 0:8a797b9e2fe4 104 uLCD.baudrate(300000);
ksastry3 0:8a797b9e2fe4 105 imu.begin();
ksastry3 0:8a797b9e2fe4 106 if (!imu.begin()) {
ksastry3 0:8a797b9e2fe4 107 pc.printf("(IMU) Failed to communicate with LSM9DS1.\n");
ksastry3 0:8a797b9e2fe4 108 }
ksastry3 0:8a797b9e2fe4 109 imu.calibrate();
ksastry3 0:8a797b9e2fe4 110 imu.readAccel();
ksastry3 0:8a797b9e2fe4 111
ksastry3 0:8a797b9e2fe4 112 // Set up GPS
ksastry3 0:8a797b9e2fe4 113 myGPS.begin(9600); // sets baud rate for GPS communication; note this may be changed via Adafruit_GPS::sendCommand(char *)
ksastry3 0:8a797b9e2fe4 114 // a list of GPS commands is available at http://www.adafruit.com/datasheets/PMTK_A08.pdf
ksastry3 0:8a797b9e2fe4 115 myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); // these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation
ksastry3 0:8a797b9e2fe4 116 myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
ksastry3 0:8a797b9e2fe4 117 myGPS.sendCommand(PGCMD_ANTENNA);
ksastry3 0:8a797b9e2fe4 118 pc.printf("(GPS) Connection established at 9600 baud...\n");
ksastry3 0:8a797b9e2fe4 119 Thread::wait(1*1000);
ksastry3 0:8a797b9e2fe4 120 refresh_Timer.start(); // starts the clock on the timer
ksastry3 0:8a797b9e2fe4 121
ksastry3 0:8a797b9e2fe4 122 // Set up LIDAR
ksastry3 0:8a797b9e2fe4 123 DevI2C *device_i2c = new DevI2C(VL53L0_I2C_SDA, VL53L0_I2C_SCL); // LIDAR Objects:
ksastry3 0:8a797b9e2fe4 124 board = XNucleo53L0A1::instance(device_i2c, A2, D8, D2); // creates the 53L0A1 expansion board singleton obj
ksastry3 0:8a797b9e2fe4 125 shdn = 0; // must reset sensor for an mbed reset to work
ksastry3 0:8a797b9e2fe4 126 Thread::wait(0.1*1000);
ksastry3 0:8a797b9e2fe4 127 shdn = 1;
ksastry3 0:8a797b9e2fe4 128 Thread::wait(0.1*1000);
ksastry3 0:8a797b9e2fe4 129
ksastry3 0:8a797b9e2fe4 130 status = board->init_board(); // init the 53L0A1 board with default values
ksastry3 0:8a797b9e2fe4 131 while (status) {
ksastry3 0:8a797b9e2fe4 132 pc.printf("(LIDAR) Failed to init board! \r\n");
ksastry3 0:8a797b9e2fe4 133 status = board->init_board();
ksastry3 0:8a797b9e2fe4 134 }
ksastry3 0:8a797b9e2fe4 135
ksastry3 0:8a797b9e2fe4 136 // Set up Mode Selecting Pushbutton (Debounced, Interrupt Based)
ksastry3 0:8a797b9e2fe4 137 myPushbutton.mode(PullUp); // Use internal pullups for pushbutton
ksastry3 0:8a797b9e2fe4 138 Thread::wait(.01*1000); // Delay for initial pullup to take effect
ksastry3 0:8a797b9e2fe4 139 myPushbutton.attach_deasserted(&changeMode_ISR); // Setup Interrupt Service Routines. PullUp implies 1->0 change means hit
ksastry3 0:8a797b9e2fe4 140 myPushbutton.setSampleFrequency(); // Start sampling pushbutton inputs using interruptsUsing default 50 Hz (20 ms period)
ksastry3 0:8a797b9e2fe4 141
ksastry3 0:8a797b9e2fe4 142 // Launch Threads
ksastry3 0:8a797b9e2fe4 143 Thread IMU_THREAD(IMU_THREAD);
ksastry3 0:8a797b9e2fe4 144 Thread GPS_THREAD(GPS_THREAD);
ksastry3 0:8a797b9e2fe4 145 Thread LIDAR_THREAD(LIDAR_THREAD);
ksastry3 0:8a797b9e2fe4 146 Thread LCD_THREAD(LCD_THREAD);
ksastry3 0:8a797b9e2fe4 147
ksastry3 0:8a797b9e2fe4 148 // Main Thread
ksastry3 0:8a797b9e2fe4 149 while(true) {
ksastry3 0:8a797b9e2fe4 150 // <DO THINGS!>
ksastry3 0:8a797b9e2fe4 151 Thread::wait(5000);
ksastry3 0:8a797b9e2fe4 152 }
ksastry3 0:8a797b9e2fe4 153 }
ksastry3 0:8a797b9e2fe4 154
ksastry3 0:8a797b9e2fe4 155 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 156 /* Thread 2: IMU Measurement */
ksastry3 0:8a797b9e2fe4 157 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 158 void IMU_THREAD() {
ksastry3 0:8a797b9e2fe4 159 // Change Axis..............................................................................................................
ksastry3 0:8a797b9e2fe4 160 while (myMode == MODE_IMU_SELECT) {
ksastry3 0:8a797b9e2fe4 161 imu.readAccel();
ksastry3 0:8a797b9e2fe4 162 new_x = imu.calcAccel(imu.ax);
ksastry3 0:8a797b9e2fe4 163 new_y = imu.calcAccel(imu.ay);
ksastry3 0:8a797b9e2fe4 164 new_z = imu.calcAccel(imu.az);
ksastry3 0:8a797b9e2fe4 165 mySerialMutex.lock();
ksastry3 0:8a797b9e2fe4 166 pc.printf("z: %f\r\n", new_z);
ksastry3 0:8a797b9e2fe4 167 mySerialMutex.unlock();
ksastry3 0:8a797b9e2fe4 168 if (new_z > 1.25){
ksastry3 0:8a797b9e2fe4 169 start = 1;
ksastry3 0:8a797b9e2fe4 170 }
ksastry3 0:8a797b9e2fe4 171 if (start == 1 & new_z < .90){
ksastry3 0:8a797b9e2fe4 172 count += 1;
ksastry3 0:8a797b9e2fe4 173 start = 0;
ksastry3 0:8a797b9e2fe4 174 }
ksastry3 0:8a797b9e2fe4 175 mySerialMutex.lock();
ksastry3 0:8a797b9e2fe4 176 pc.printf("count: %d\r\n", count);
ksastry3 0:8a797b9e2fe4 177 mySerialMutex.unlock();
ksastry3 0:8a797b9e2fe4 178 Thread::wait(.1*1000);
ksastry3 0:8a797b9e2fe4 179 }
ksastry3 0:8a797b9e2fe4 180 }
ksastry3 0:8a797b9e2fe4 181
ksastry3 0:8a797b9e2fe4 182 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 183 /* Thread 3: GPS Measurement */
ksastry3 0:8a797b9e2fe4 184 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 185 void GPS_THREAD() {
ksastry3 0:8a797b9e2fe4 186 // pc.baud(9600); // sets virtual COM serial communication to high rate; this is to allow more time to be spent on GPS retrieval
ksastry3 0:8a797b9e2fe4 187
ksastry3 0:8a797b9e2fe4 188 while (myMode == MODE_GPS_SELECT) {
ksastry3 0:8a797b9e2fe4 189 c = myGPS.read(); // queries the GPS
ksastry3 0:8a797b9e2fe4 190
ksastry3 0:8a797b9e2fe4 191 // if (c) { pc.printf("%c", c); } // this line will echo the GPS data if not paused
ksastry3 0:8a797b9e2fe4 192
ksastry3 0:8a797b9e2fe4 193 // check if we recieved a new message from GPS, if so, attempt to parse it,
ksastry3 0:8a797b9e2fe4 194 if ( myGPS.newNMEAreceived() ) {
ksastry3 0:8a797b9e2fe4 195 if ( !myGPS.parse(myGPS.lastNMEA()) ) {
ksastry3 0:8a797b9e2fe4 196 continue;
ksastry3 0:8a797b9e2fe4 197 }
ksastry3 0:8a797b9e2fe4 198 }
ksastry3 0:8a797b9e2fe4 199
ksastry3 0:8a797b9e2fe4 200 // check if enough time has passed to warrant printing GPS info to screen
ksastry3 0:8a797b9e2fe4 201 // note if refresh_Time is too low or pc.baud is too low, GPS data may be lost during printing
ksastry3 0:8a797b9e2fe4 202 if (refresh_Timer.read_ms() >= refresh_Time) {
ksastry3 0:8a797b9e2fe4 203 refresh_Timer.reset();
ksastry3 0:8a797b9e2fe4 204 mySerialMutex.lock();
ksastry3 0:8a797b9e2fe4 205 pc.printf("Time: %d:%d:%d.%u\n\r", myGPS.hour, myGPS.minute, myGPS.seconds, myGPS.milliseconds);
ksastry3 0:8a797b9e2fe4 206 pc.printf("Date: %d/%d/20%d\n\r", myGPS.day, myGPS.month, myGPS.year);
ksastry3 0:8a797b9e2fe4 207 pc.printf("Fix: %d\n\r", (int) myGPS.fix);
ksastry3 0:8a797b9e2fe4 208 pc.printf("Quality: %d\n\r", (int) myGPS.fixquality);
ksastry3 0:8a797b9e2fe4 209 if (myGPS.fix) {
ksastry3 0:8a797b9e2fe4 210 pc.printf("Location: %5.2f%c, %5.2f%c\n\r", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon);
ksastry3 0:8a797b9e2fe4 211 pc.printf("Speed: %5.2f knots\n\r", myGPS.speed);
ksastry3 0:8a797b9e2fe4 212 // pc.printf("Angle: %5.2f\n", myGPS.angle);
ksastry3 0:8a797b9e2fe4 213 // pc.printf("Altitude: %5.2f\n", myGPS.altitude);
ksastry3 0:8a797b9e2fe4 214 pc.printf("Satellites: %d\n\r", myGPS.satellites);
ksastry3 0:8a797b9e2fe4 215 }
ksastry3 0:8a797b9e2fe4 216 mySerialMutex.unlock();
ksastry3 0:8a797b9e2fe4 217 }
ksastry3 0:8a797b9e2fe4 218 }
ksastry3 0:8a797b9e2fe4 219 }
ksastry3 0:8a797b9e2fe4 220
ksastry3 0:8a797b9e2fe4 221 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 222 /* Thread 4: LIDAR Measurements */
ksastry3 0:8a797b9e2fe4 223 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 224 void LIDAR_THREAD() {
ksastry3 0:8a797b9e2fe4 225 // loop taking and printing distance
ksastry3 0:8a797b9e2fe4 226 while (myMode == MODE_LIDAR_SELECT) {
ksastry3 0:8a797b9e2fe4 227 status = board->sensor_centre->get_distance(&distance);
ksastry3 0:8a797b9e2fe4 228 if (status == VL53L0X_ERROR_NONE) {
ksastry3 0:8a797b9e2fe4 229 mySerialMutex.lock();
ksastry3 0:8a797b9e2fe4 230 pc.printf("D=%ld mm\r\n", distance);
ksastry3 0:8a797b9e2fe4 231 mySerialMutex.unlock();
ksastry3 0:8a797b9e2fe4 232 }
ksastry3 0:8a797b9e2fe4 233 }
ksastry3 0:8a797b9e2fe4 234 }
ksastry3 0:8a797b9e2fe4 235
ksastry3 0:8a797b9e2fe4 236 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 237 /* Thread 5: LCD Display */
ksastry3 0:8a797b9e2fe4 238 /******************************************************************************/
ksastry3 0:8a797b9e2fe4 239 void LCD_THREAD() {
ksastry3 0:8a797b9e2fe4 240
ksastry3 0:8a797b9e2fe4 241 }