SCIboard(TM): mbed base board data logger - Altimeter: MPL3115A2 - Accelerometer: LSM303DLHC - Gyro: L3G4200D - 4 High Current MOSFET switches

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* SCIboard(TM) main.cpp
00002 Copyright (c) 2013 K. Andres
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020 THE SOFTWARE.
00021 */
00022 
00023 /* OVERVIEW
00024     Displays on USB serial (9600 bps) 
00025         MPL3115A2 ident 0xC4
00026         LSM303 ident 0x48 0x34 0x33
00027         L3G4200DTR ident 0xD3
00028     then collects 20 seconds of data from accelerometer and magnetometer
00029     
00030     Filename on Local: OUTxx.csv (csv format allows easy import into spreadsheets)
00031     Format: microseconds,record type, variable length data\r\n 
00032     Rec type 1= altimeter data altitude (meters) and semiconductor temperature (deg C)
00033     Rec type 2= accelerometer data x, y, and z in g's
00034     Rec type 3= magnetometer data x, y, and z
00035     Rec type 4= gyro data x, y, z in degrees per second (dps)
00036     Rec type 5= MOSFET switch events
00037     
00038     Items under development...
00039     MOSFET switch
00040     ublox GPS
00041 */
00042 
00043 #include "mbed.h"
00044 #include "math.h"
00045 
00046 #include "SCIboard_I2C.h"
00047 #include "SCIboard_MPL3115A2.h"
00048 #include "SCIboard_LSM303DLHC.h"
00049 #include "SCIboard_L3G4200DTR.h"
00050 
00051 #include "SCIboard_DataLogger.h"
00052 #include "SCIboard_ConfigFile.h"
00053 #include "SCIboard_MOSFET.h"
00054 
00055 #include "SCIboard_ubloxGps.h"
00056 
00057 // LEDs
00058 DigitalOut led1(LED1);
00059 DigitalOut led2(LED2);
00060 DigitalOut led3(LED3);
00061 DigitalOut led4(LED4);
00062 
00063 // PWM out
00064 PwmOut pwm1(p26);
00065 PwmOut pwm2(p25);
00066 PwmOut pwm3(p24);
00067 PwmOut pwm4(p23);
00068 PwmOut pwm5(p22);
00069 PwmOut pwm6(p21);
00070 
00071 Serial gps(p13, p14);
00072 // Serial Xbee(p9, p10);
00073 
00074 // Buzzer
00075 DigitalOut alert(p29);      // CAN_RD
00076 
00077 // MOSFET controls
00078 DigitalOut fet_out1(p15);   // ADC1
00079 DigitalOut fet_out2(p12);   // SPI2_MISO
00080 DigitalOut fet_out3(p11);   // SPI2_MOSI
00081 DigitalOut fet_out4(p8);    // GPIO8
00082 
00083 // ADC inputs
00084 AnalogIn batt_mon(p16);     // ADC2
00085 AnalogIn fet_mon1(p17);     // ADC3
00086 AnalogIn fet_mon2(p18);     // ADC4
00087 AnalogIn fet_mon3(p19);     // ADC5
00088 AnalogIn fet_mon4(p20);     // ADC6
00089 
00090 //
00091 Serial pc(USBTX, USBRX);    // Default 9600 bps
00092 
00093 // Timers
00094 Timer t;
00095 int time_ms;
00096 
00097 
00098 // I2C interface
00099 //#define sdaPin p9
00100 //#define sdcPin p10
00101 #define sdaPin p28
00102 #define sdcPin p27
00103 
00104 SCIboard_I2C i2cBus(sdaPin, sdcPin);
00105 
00106 // Altimeter
00107 SCIboard_MPL3115A2 alt(&i2cBus);
00108 InterruptIn MPL3115A2_INT1(p5);
00109 void MPL3115A2_INT1_INTERRUPT(void);
00110 //InterruptIn MPL3115A2_INT2();
00111 
00112 const int accAltDecimate=5;
00113 #define ALT_RATE    10
00114 int accCnt=0;
00115 
00116 
00117 // Accelerometer and magnetometer
00118 SCIboard_LSM303DLHC lsm303(&i2cBus);
00119 InterruptIn LSM303DLHC_DRDY(p7);
00120 void LSM303DLHC_DRDY_INTERRUPT(void);
00121 //InterruptIn LSM303DLHC_INT1(p6);
00122 //void LSM303DLHC_INT1_INTERRUPT(void);
00123 // INT2 n/c
00124 
00125 
00126 // Gyro
00127 SCIboard_L3G4200DTR l3g4200dtr(&i2cBus, GYR_DR_100HZ, GYR_BW_0, GYR_FS_250DPS);
00128 //InterruptIn L3G4200DTR_INT();
00129 //InterruptIn L3G4200DTR_DRDY(p24);
00130 //void L3G4200DTR_INTERRUPT(void);
00131 
00132 
00133 // Configuration data
00134 void ReadConfigfile(void);
00135 float fMachDelay, fMainDeploymentAlt, fLowVoltageAlarm, fAltLog, fAccelLog, fMagLog, fGyroLog, fUBLOXlog;
00136 
00137 char *cfgKeyStr[]={
00138 "MACH DELAY (s)",
00139 "MAIN DEPLOYMENT (ft)",
00140 "LOW VOLTAGE ALARM (v)",
00141 "ALT LOG (1|0)",
00142 "ACCEL LOG (1|0)",
00143 "MAG LOG (1|0)",
00144 "GYRO LOG (1|0)",
00145 "UBLOX LOG (1|0)",
00146 //"SSID",
00147 //"PASSWD",
00148 };
00149 
00150 float *cfgFloatPtr[] = {
00151 &fMachDelay, &fMainDeploymentAlt, &fLowVoltageAlarm, &fAltLog, &fAccelLog, &fMagLog, &fGyroLog, &fUBLOXlog};
00152 
00153 // MOSFET switchs and ADC
00154 SCIboard_Mosfet mosfet;
00155 
00156 // UBLOX GPS
00157 SCIboard_ubloxGps ubloxGps;
00158 
00159 //---------------------------------------------------------------------
00160 int main() {
00161     unsigned char data[10];
00162     float f[3];
00163     char str[132];
00164     int currentTime;
00165     int lastTime=0;
00166     float gyro_store[3];
00167     bool bGyroDataStored=false;
00168 
00169     // Ensure interrupts are off
00170     MPL3115A2_INT1.fall(NULL);
00171     LSM303DLHC_DRDY.fall(NULL);
00172 //    LSM303DLHC_INT1.rise(NULL);
00173 //    L3G4200DTR_DRDY.fall(NULL);
00174     
00175 //    pc.baud(38400);
00176 
00177     ReadConfigfile();
00178 
00179     // DataLogger
00180     nextFilename();
00181     log_open();
00182     
00183     // Get I2C device IDs
00184     sprintf(str, "MPL3115A2 Ident 0x%X\r\n", alt.getDeviceID());
00185 //    pc.printf(str);
00186     log_write(str);
00187     
00188     lsm303.getDeviceID(data);
00189     sprintf(str, "LSM303DLHC Ident 0x%X 0x%X 0x%X\r\n", data[0], data[1], data[2]);
00190 //    pc.printf(str);
00191     log_write(str);
00192     
00193     sprintf(str, "L3G4200DTR Ident 0x%X\r\n", l3g4200dtr.getDeviceID());
00194 //    pc.printf(str);
00195     log_write(str);
00196     
00197     // Setup accelerometer and magnetometer
00198     lsm303.setAccMode(ACC_4G, ACC_50HZ);
00199     lsm303.setMagMode(MAG_1p3G, MAG_75HZ);
00200     
00201     // Setup altimeter
00202     alt.setMode(ALT_MODE, OS4);
00203     alt.OST();  // initiate first conversion
00204     MPL3115A2_INT1.fall(MPL3115A2_INT1_INTERRUPT);
00205     
00206     if(fUBLOXlog) {
00207         ubloxGps.gps_startup();
00208     }
00209     
00210     t.start();  // start timer
00211     
00212     if(fMagLog) {
00213         LSM303DLHC_DRDY.fall(LSM303DLHC_DRDY_INTERRUPT);    // Magnetometer
00214     }
00215     
00216 //    LSM303DLHC_INT1.rise(LSM303DLHC_INT1_INTERRUPT);    // Accelerometer
00217 
00218 
00219     // Collect some data then close file system to allow mbed to be visible on USB connected PC for demo app only
00220     while(t.read()<20) {
00221         time_ms = t.read_ms();
00222         currentTime = t.read();
00223         if(currentTime!=lastTime) {
00224             lastTime = currentTime;
00225             led2 = !led2;   // slow blink led
00226         }
00227 
00228         __disable_irq();
00229      
00230         // Accelerometer
00231         if(lsm303.bAccDataAvailable()) {
00232             lsm303.getAccData(f);
00233             if(fAccelLog) {
00234                 sprintf(str,"%u,2,%.3f,%.3f,%.3f\r\n", time_ms, f[0], f[1], f[2]);
00235                 log_write(str);
00236             }
00237             if(++accCnt >= accAltDecimate) {
00238                 accCnt = 0;
00239                 alt.OST();
00240             }            
00241         }
00242 
00243 
00244         #ifdef NON_DRDY_MAG  
00245         // Magnetometer      
00246         data[0] = lsm303.getMagStatus();
00247         pc.printf("MagStatus=%X\r\n", data[0]);
00248 
00249         if(lsm303.bMagDataAvailable()) {
00250             lsm303.getMagData(f);
00251             pc.printf("MAG: %.3f %.3f %.3f  %.0f\r\n", f[0], f[1], f[2], atan2(f[1],f[0])*180.0/PI);
00252         }
00253         #endif
00254         
00255         // Gyro
00256         if(fGyroLog) {
00257             if(l3g4200dtr.getStatus() & STATUS_REG_ZYXDA)
00258             {
00259                 if(bGyroDataStored) {
00260                     l3g4200dtr.getData(f);
00261                     sprintf(str, "%u,4,%.3f,%.3f,%.3f\r\n", time_ms, f[0]+gyro_store[0], f[1]+gyro_store[1], f[2]+gyro_store[2]);
00262                     log_write(str);
00263                     bGyroDataStored = false;
00264                 }
00265                 else {
00266                     l3g4200dtr.getData(gyro_store);
00267                     bGyroDataStored = true;
00268                 }
00269             }
00270         }
00271 
00272         __enable_irq();
00273     }
00274 
00275     // Ensure interrupts are off
00276     MPL3115A2_INT1.fall(NULL);
00277     LSM303DLHC_DRDY.fall(NULL);
00278 //    LSM303DLHC_INT1.rise(NULL);
00279 //    L3G4200DTR_DRDY.fall(NULL);
00280 
00281     if(fUBLOXlog) {
00282         ubloxGps.gps_close();
00283     }
00284     
00285     wait(.1);
00286     log_close();
00287     
00288     // Demo MOSFET
00289 /*    pc.printf("Battery voltage=%f\r\n", mosfet.getBattVoltage());
00290     pc.printf("MOSFET voltage=%f\r\n", mosfet.getFetVoltage(4));
00291     mosfet.setFet(4, 2.0);
00292     pc.printf("MOSFET 4 on for 2 seconds.\r\n");
00293     pc.printf("MOSFET voltage=%f\r\n", mosfet.getFetVoltage(4));
00294     wait(3);
00295     pc.printf("MOSFET voltage=%f\r\n", mosfet.getFetVoltage(4));
00296 
00297     pc.printf("Done.\r\n");
00298     */
00299     led2=0;
00300         
00301     // Signal program done
00302     led1 = 1;
00303     led4 = led3 = led2 =0;
00304     while(1) {
00305         wait(0.2);
00306         data[0] = led4;
00307         led4 = led3;
00308         led3 = led2;
00309         led2 = led1;
00310         led1 = data[0];
00311     }
00312 }
00313 
00314 
00315 // Altimeter interrupt service ----------------------------------------
00316 void MPL3115A2_INT1_INTERRUPT(void)
00317 {
00318     float f[3];
00319     char str[80];
00320     
00321     __disable_irq();
00322 
00323     alt.getData(f);
00324     if(fAltLog) {
00325         sprintf(str, "%u,1,%.1f,%.1f\r\n", time_ms, f[0], f[1]);
00326         log_write(str);            
00327     }
00328    
00329     __enable_irq();
00330 }
00331 
00332 
00333 // Magnetometer interrupt service -------------------------------------
00334 void LSM303DLHC_DRDY_INTERRUPT(void)
00335 {
00336     float f[3];
00337     char str[80];
00338     
00339     __disable_irq();
00340     lsm303.getMagData(f);
00341     sprintf(str, "%u,3,%.3f,%.3f,%.3f\r\n", time_ms, f[0], f[1], f[2]);
00342     log_write(str);
00343     __enable_irq();
00344 }
00345 
00346 
00347 // Accelerometer interrupt service ------------------------------------
00348 /*void LSM303DLHC_INT1_INTERRUPT(void)
00349 {
00350     float f[3];
00351     unsigned char src;
00352     char str[80];
00353     
00354     __disable_irq();
00355 
00356     src = lsm303.getInt1Src();
00357     if(lsm303.bAccDataAvailable()) {
00358         lsm303.getAccData(f);
00359         sprintf(str,"%u,2,%.3f,%.3f,%.3f,%x\r\n", time_ms, f[0], f[1], f[2], src);
00360         log_write(str);
00361         if(++accCnt >= accAltDecimate) {
00362             accCnt = 0;
00363             alt.OST();
00364         }
00365     }
00366     
00367     __enable_irq();
00368 }
00369 */
00370 
00371 
00372 // Read configuration file --------------------------------------------
00373 void ReadConfigfile(void) {
00374     ConfigFile cfgFile("/local/SCIbdCfg.txt");
00375     int n;
00376     float f;
00377     
00378     for(n=0; n<sizeof(cfgKeyStr)/sizeof(char*); n++) {
00379         if(cfgFile.getValue(cfgKeyStr[n], &f))
00380         {
00381             if(f < 0) f = 0;
00382             *(cfgFloatPtr[n]) = f;
00383             pc.printf("Found: %s: %f\r\n", cfgKeyStr[n], f);
00384         }
00385     }
00386     cfgFile.closeFile();
00387     
00388     if(fMachDelay > 15.0)
00389         fMachDelay = 15;
00390     
00391     if(fMainDeploymentAlt < 300)
00392         fMainDeploymentAlt = 300;
00393     else if(fMainDeploymentAlt > 2000)
00394         fMainDeploymentAlt = 2000;
00395 
00396     // save config file if not found?
00397    
00398 }