10Hz GPS, MEgasquirt, SD Card, ADxl345, 20x4 LCD datalogger

Dependencies:   ADXL345 10HzGPSdatalogger mbed

Files at this revision

API Documentation at this revision

Comitter:
jpnovak
Date:
Sat Nov 28 17:07:15 2015 +0000
Commit message:
10HzGPS Megasquirt adxl345 SD card LCD;

Changed in this revision

ADXL345.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
SerialBuffered.cpp Show annotated file Show diff for this revision Revisions of this file
SerialBuffered.h Show annotated file Show diff for this revision Revisions of this file
TextLCD.cpp Show annotated file Show diff for this revision Revisions of this file
TextLCD.h Show annotated file Show diff for this revision Revisions of this file
data.h Show annotated file Show diff for this revision Revisions of this file
gps.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADXL345.lib	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/aberk/code/ADXL345/#bd8f0f20f433
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/jpnovak/code/10HzGPSdatalogger/#0a80ad1a887a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.cpp	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,108 @@
+
+#include "mbed.h"
+#include "SerialBuffered.h"
+ 
+extern Serial loggerSerial;
+ 
+SerialBuffered::SerialBuffered( size_t bufferSize, PinName tx, PinName rx ) : Serial(  tx,  rx ) 
+{
+    m_buffSize = 0;
+    m_contentStart = 0;
+    m_contentEnd = 0;
+    m_timeout = 1.0;
+   
+    
+    attach( this, &SerialBuffered::handleInterrupt );
+    
+    m_buff = (uint8_t *) malloc( bufferSize );
+    if( m_buff == NULL )
+    {
+        //loggerSerial.printf("SerialBuffered - failed to alloc buffer size %d\r\n", (int) bufferSize );
+    }
+    else
+    {
+        m_buffSize = bufferSize;
+    }
+}
+
+
+SerialBuffered::~SerialBuffered()
+{
+    if( m_buff )
+        free( m_buff );
+}
+
+void SerialBuffered::setTimeout( float seconds )
+{
+    m_timeout = seconds;
+}
+    
+size_t SerialBuffered::readBytes( uint8_t *bytes, size_t requested )
+{
+    int i = 0;
+
+    for( ; i < requested; )
+    {
+        int c = getc();
+        if( c < 0 )
+            break;
+        bytes[i] = c;
+        i++;
+    }
+    
+    return i;
+        
+}
+
+
+int SerialBuffered::getc()
+{
+    m_timer.reset();
+    m_timer.start();
+    while( m_contentStart == m_contentEnd )
+    {
+      
+
+        wait_ms( 1 );
+        if( m_timeout > 0 &&  m_timer.read() > m_timeout )
+            return EOF;
+    }
+
+    m_timer.stop();
+   
+    uint8_t result = m_buff[m_contentStart++];
+    m_contentStart =  m_contentStart % m_buffSize;
+
+   
+    return result;    
+}
+
+
+int SerialBuffered::readable()
+{
+    return m_contentStart != m_contentEnd ;
+}
+
+void SerialBuffered::handleInterrupt()
+{
+    
+    while( Serial::readable())
+    {
+        if( m_contentStart == (m_contentEnd +1) % m_buffSize)
+        {
+           loggerSerial.printf("SerialBuffered - buffer overrun, data lost!\r\n" );
+           Serial::getc();
+
+        }
+        else
+        {
+          
+            m_buff[ m_contentEnd ++ ] = Serial::getc();
+            m_contentEnd = m_contentEnd % m_buffSize;
+            
+           
+           
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.h	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,39 @@
+#pragma once
+
+// This is a buffered serial reading class, using the serial interrupt introduced in mbed library version 18 on 17/11/09
+
+// In the simplest case, construct it with a buffer size at least equal to the largest message you 
+// expect your program to receive in one go.
+
+class SerialBuffered : public Serial
+{
+public:
+    SerialBuffered( size_t bufferSize, PinName tx, PinName rx );
+    virtual ~SerialBuffered();
+    
+    int getc();     // will block till the next character turns up, or return -1 if there is a timeout
+    
+    int readable(); // returns 1 if there is a character available to read, 0 otherwise
+    
+    void setTimeout( float seconds );    // maximum time in seconds that getc() should block 
+                                         // while waiting for a character
+                                         // Pass -1 to disable the timeout.
+    
+    size_t readBytes( uint8_t *bytes, size_t requested );    // read requested bytes into a buffer, 
+                                                             // return number actually read, 
+                                                             // which may be less than requested if there has been a timeout
+    
+
+private:
+    
+    void handleInterrupt();
+    
+   
+    uint8_t *m_buff;            // points at a circular buffer, containing data from m_contentStart, for m_contentSize bytes, wrapping when you get to the end
+    uint16_t  m_contentStart;   // index of first bytes of content
+    uint16_t  m_contentEnd;     // index of bytes after last byte of content
+    uint16_t m_buffSize;
+    float m_timeout;
+    Timer m_timer;
+
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.cpp	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,188 @@
+/* draft mbed TextLCD 
+ * (c) 2007/8, sford
+ */
+ 
+#include "TextLCD.h"
+
+#include "mbed.h"
+
+using namespace mbed;
+
+/*
+ * useful info found at http://www.a-netz.de/lcd.en.php
+ *
+ *
+ * Initialisation
+ * ==============
+ *
+ * After attaching the supply voltage/after a reset, the display needs to be brought in to a defined state
+ *
+ * - wait approximately 15 ms so the display is ready to execute commands
+ * - Execute the command 0x30 ("Display Settings") three times (wait 1,64ms after each command, the busy flag cannot be queried now). 
+ * - The display is in 8 bit mode, so if you have only connected 4 data pins you should only transmit the higher nibble of each command.
+ * - If you want to use the 4 bit mode, now you can execute the command to switch over to this mode now.
+ * - Execute the "clear display" command
+ *
+ * Timing
+ * ======
+ *
+ * Nearly all commands transmitted to the display need 40us for execution. 
+ * Exceptions are the commands "Clear Display and Reset" and "Set Cursor to Start Position" 
+ * These commands need 1.64ms for execution. These timings are valid for all displays working with an 
+ * internal clock of 250kHz. But I do not know any displays that use other frequencies. Any time you 
+ * can use the busy flag to test if the display is ready to accept the next command.
+ * 
+ * _e is kept high apart from calling clock
+ * _rw is kept 0 (write) apart from actions that uyse it differently
+ * _rs is set by the data/command writes
+ */
+
+
+//wait(0.05);
+
+TextLCD::TextLCD(PinName rs, PinName rw, PinName e, PinName d0, PinName d1, 
+    PinName d2, PinName d3, int columns, int rows) : _rw(rw), _rs(rs), 
+    _e(e), _d(d0, d1, d2, d3), _columns(columns), _rows(rows) {
+
+    _rows = 4;
+    _columns = 20;
+wait(0.05);
+    _rw = 0;
+    _e  = 1;
+    _rs = 0; // command mode
+wait(0.05);
+    // Should theoretically wait 15ms, but most things will be powered up pre-reset
+    // so i'll disable that for the minute. If implemented, could wait 15ms post reset
+    // instead
+    // wait(0.015); 
+        
+    // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
+    for(int i=0; i<3; i++) {
+        writeNibble(0x3);
+        wait(0.005);      // this command takes 1.64ms, so wait for it
+    }
+    wait(0.1);
+    writeNibble(0x2); // 4-bit mode
+wait(0.001);            
+    writeCommand(0x28);    // Function set 001 BW N F - -  
+wait(0.001);
+    writeCommand(0x0C);
+    wait(0.001);
+    writeCommand(0x6);  //  Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes
+    cls();
+}
+
+
+
+int TextLCD::_putc(int value) {
+    if(value == '\n') {
+        newline();
+    } else {
+        writeData(value);
+    }
+    return value;
+}
+
+int TextLCD::_getc() {
+    return 0;
+}
+
+void TextLCD::newline() {
+    _column = 0;
+    _row++;
+    if(_row >= _rows) {
+        _row = 0;
+    }
+    locate(_column, _row); 
+}
+
+void TextLCD::locate(int column, int row) 
+{
+   /* if(column < 0 || column >= _columns || row < 0 || row >= _rows) {
+        ERROR("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows);
+        return;
+    }*/
+    
+    _row = row;
+      _column = column;
+      int address=0;
+      
+      if (_rows > 2) {
+        // row 0 : 0x0->0x13
+        // row 1 : 0x40->0x53
+        // row 2 : 0x14->0x27
+        // row 3 : 0x54->0x67
+        
+        switch (_row) {
+            case (0) : address = 0x80 + _column;
+            break;
+            case (1) : address = 0xc0 + _column;
+            break;
+            case (2) : address = 0x94 + _column;
+            break;
+            case (3) : address = 0xd4 + _column;
+            break;
+        }        
+                
+      }
+      else {
+         // memory starts at 0x80, and is 40 chars long per row
+          address = 0x80 + (_row * 40)  + _column; 
+      }
+      
+      writeCommand(address);            
+}
+
+
+void TextLCD::rows(int rows) {
+    _rows = rows;
+}
+
+
+void TextLCD::columns(int columns) {
+    _columns = columns;
+}
+
+
+
+
+void TextLCD::cls() {
+    writeCommand(0x01); // Clear Display
+    wait(0.00164f);        // This command takes 1.64 ms
+      locate(0, 0);
+}
+
+void TextLCD::reset() {
+    cls();
+}
+
+void TextLCD::clock() {
+    wait(0.00010);
+    _e = 0;
+    wait(0.00010);  // most instructions take 40us
+    _e = 1;    
+}
+
+void TextLCD::writeNibble(int value) {
+    _d = value;
+    clock();
+}
+
+void TextLCD::writeByte(int value) {
+    writeNibble(value >> 4);
+    writeNibble(value >> 0);
+}
+
+void TextLCD::writeCommand(int command) {
+    _rs = 0;
+    writeByte(command);
+}
+
+void TextLCD::writeData(int data) {
+    _rs = 1;
+    writeByte(data);
+    _column++;
+    if(_column >= _columns) {
+        newline();
+    } 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.h	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,51 @@
+/* draft mbed TextLCD 
+ * (c) 2007/8, sford
+ */
+ 
+#ifndef MBED_TEXTLCD_H
+#define MBED_TEXTLCD_H
+
+#include "Stream.h"
+#include "DigitalOut.h"
+#include "BusOut.h"
+
+namespace mbed {
+
+class TextLCD : public Stream {
+
+public:
+
+    TextLCD(PinName rs, PinName rw,PinName e, PinName d0, PinName d1, PinName d2, PinName d3, int columns, int rows);
+    void rows(int rows);
+    void columns(int columns);
+            
+    virtual void locate(int row, int column);
+    virtual void cls();    
+    virtual void reset();
+//    virtual void init_Display();
+ 
+        
+protected:
+
+    void clock();
+    void writeData(int data);
+    void writeCommand(int command);
+    void writeByte(int value);
+    void writeNibble(int value);
+    virtual int _putc(int c);        
+    virtual int _getc();
+    virtual void newline();
+             
+            
+    int _rows;
+    int _columns;
+    int _row;
+    int _column;    
+    DigitalOut _rw, _rs, _e;
+    BusOut _d;
+
+};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data.h	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,31 @@
+#ifndef _DATA_H_
+#define _DATA_H_
+    char gpsString[1024];
+    char gsv1[1024];
+    char * gsv2;
+    char rmc1[1024];
+    char * rmc2;
+    char gga1[1024];
+    char * gga2;
+    char * fix;
+    char vtg1[1024];
+    char * vtg2;
+    char gsa1[1024];
+    char * gsa2;
+    int sep;
+    int mode = 1;
+    char * status;
+    char * Lat;
+    char * Long;
+    char * Lat_h;
+    char * Long_h;
+    char * timeGPS;
+    char * speed_k;
+    char * speed_mph;
+    char * heading;
+    char * time_GPS;
+    char heading_int;
+  
+  
+        
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gps.h	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,93 @@
+#include "mbed.h"
+#include "data.h"
+
+Serial gps(p9, p10);
+
+void parseRMC(void)
+{
+    rmc2 = strtok(rmc1, ",");
+    while (rmc2 != NULL) {
+        sep++;
+        switch (sep) {
+            case 1:
+                // Time
+
+                time_GPS = rmc2;
+
+                break;
+            case 2 :
+                // Status
+                status = rmc2;
+                break;
+            case 3 :
+                // Lattitude
+                Lat = rmc2;
+
+                break;
+            case 4 :
+                // Hemisphere
+                Lat_h = rmc2;
+
+                break;
+            case 5 :
+                // Longitude
+                Long = rmc2;
+
+                break;
+            case 6:
+                //Hemisphere
+                Long_h = rmc2;
+
+                break;
+            case 7:
+                //speed in Knots
+                speed_k = rmc2;
+
+                break;
+            case 8:
+                //heading
+                heading = rmc2;
+                /*
+                                fgets ( rmc2, 256, heading_int );
+                                i = atoi (rmc2);
+                                pc.printf ("heading:%d.\n",i);
+                                //return 0;*/
+
+
+
+                //pc.printf("Heading:%s  ",heading);    // Heading degrees
+
+                break;
+            case 9:
+                //pc.printf("UTS Date:%s  \n",rmc2); //Date
+                break;
+        }
+        rmc2 = strtok(NULL, ",");
+    }
+    sep = 0;
+    return;// *rmc2;
+}
+
+
+
+
+void getGPSstring(int str)
+{
+    if (gps.scanf("%s", &gpsString) ==1) {
+
+        if (str == 1) {
+            if (sscanf(gpsString, "$GPRMC,%s",rmc1) >= 1) {
+                sep = 0;
+                parseRMC();
+
+            }
+            return ;//*rmc2;
+        }
+
+
+    }
+
+
+
+    return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,804 @@
+//Code Designed to display run-time variables from a Megasquirt Fuel Injection controller.
+//This is the base code to load variables and print to LCD and write them to a file.  File format is .FRD for import into EFI Analytics tuner Studio
+
+#include "mbed.h"
+#include "gps.h"  //////////////////////include for GPS Code /////////////////////////////
+#include "data.h" //////////////////////include for GPS Code /////////////////////////////
+#include "TextLCD.h"
+#include "SDFileSystem.h"
+#include "SerialBuffered.h"
+#include "ADXL345.h"
+
+
+//SD Card pin assignment
+SDFileSystem sd(p11, p12, p13, p14, "sd");//DI, D0, SCK, CS
+
+//local file system.
+
+LocalFileSystem local("local");
+
+
+
+AnalogIn SDenable(p20);//define SD card switch
+DigitalOut myled1(LED1);//define LED
+Serial loggerSerial(USBTX, USBRX);
+Timer t;
+
+
+Serial pc(USBTX, USBRX);
+TextLCD lcd(p21, p22, p23, p24, p25, p26, p30, 20 ,4);  //Define LCD pins
+
+
+
+//Acclerometer - SparkFun ADXL345 16G pin assignment
+ADXL345 accelerometer(p5, p6, p7, p8);  //SPI DI, D0, SCK, CS
+
+//Serial usb(USBTX, USBRX); //define USB connection pins
+SerialBuffered megasquirt(120, p28, p27);  // RS232 TX/RX  that 120 is the size of the read buffer it will make for you
+
+DigitalOut usb_activity(LED1); //define USB activity
+DigitalOut megasquirt_activity(LED2); //define Megasquirt activity
+
+
+int column;
+int row;
+int i;
+char c;
+int dataflag;
+
+/////////////////////////////////////Define GPS Variables//////////////////////////////////
+float time1;
+char statusGPS;
+float Lat1;
+float Long1;
+char Lat_h1;
+char Long_h1;
+float time_GPS1;
+float speed_k1;
+float speed_mph1;
+float heading1;
+
+
+///////////////////define buffers//////////////////////////
+unsigned char      tmp_data[16];
+int tmp;
+unsigned char       buf[120];
+float Time;
+
+
+
+////////////////////////////define MS variables////////////////////////
+long float SecL; //get secoonds
+long float        PW;//get pulseWidth1
+long float        PW2; //get pulseWidth2
+int        RPM; //get Rpm
+int DutyCycle; //Injector Duty Cycle
+int DutyCycle2; //Injector Bank2 Duty  Cycle
+long float        SparkAdv; //get advance
+float        squirt; //get squirt
+float        Engine; //get squirt
+float       afrtgt1; //get AFR target - Table 1
+float        afrtgt2; //get AFR target - Table 2
+float        wbo2_en1; //get WideBand Valid1
+float        wbo2_en2; //get WideBand Valid2
+long float       barometer; //get Barometer
+long float        MAP; //get manifold absolute pressure MAP
+long float        MAT; //get manifold absolute temperature (MAT)
+long float      CLT; //get coolant temperature (CLT)
+long float        TP; //get Throttle Position Sensor (TPS)
+long float        vBatt; //get BAttery Voltage
+long float        AFR; //get Realtime AFR for VE1
+long float        AFR2; //get Realtime AFR for VE2
+long float        knock; //get Knock Threshold Value
+long float       Gego; //get egoCorrrection1 amount %
+long float        Gego2; //get egoCorrrection2 amount %
+long float       Gair; //get air correction (G_air)
+long float        Gwarmup; //get Warmup Enrichment
+long float        TPSacc; //get accel enrichment (ms)
+long float        TPScut; //get TPS based fuel cut %
+long float       Gbaro; //get baroCorrection %
+long float       Gammae; //get gammaEnrich %
+long float        veCurr1; //get Current VE value Table 1
+long float        veCurr2; //get Current VE value Table 2
+long float        IAC; //get IAC Step %
+long float        ColdAdv; //get Cold Ignition Advance
+long float       tpsDOT;    //get Rate of Change TPS
+long float        mapDOT;  //get Rate of Change MAP
+long float        Dwell; //get Ignition Dwell
+long float        maf; //get MAF - Mass Air Flow
+long float       fuelload; //get MAP/TPS Blend %
+long float        Ethanol; //get fuel load percent alchohol
+char                portstatus; //get Spare Port Status
+char        knockRetard; //get Knock timing retard (deg)
+long float        EAEFuelCorr; //get EAE Fuel correction
+long float        egoV; //get egoV
+long float        egoV2; //get egoV2
+char        status1; //get Status1
+char        status2; //get Status2
+char        status3; //get Status3
+char        status4; //get Status4
+long float        looptime; //get looptime
+char        status5; //get Status5
+long float        tpsADC; //get tpsADC
+long float        fuelload2; //get fuelload2
+long float        ignload; //get ignload
+long float        ignload2; //get ignload2
+char        syncstatus; //get Sync-Status (0 - sync-error, 1 - syncstatus)
+float        deltaT; //get deltaT
+long float        wallfuel; //get wallfuel
+
+int runtime;
+unsigned char data_out;
+int n;
+char MSII_288Header[] = {0x46,0x52,0x44,0x00,0x00,0x00,0x00,0x01,0x4b,0x61,0xf1,0x63,0x4d,0x53,0x49,0x49,0x20,0x52,0x65,0x76,0x20,0x32,0x2e,0x38,0x38,0x30,0x30,0x30,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x00,0x70};//file header
+char MSIIExtraHeader[] = {0x46,0x52,0x44,0x00,0x00,0x00,0x00,0x01,0x4b,0x6a,0xf3,0xa8,0x4d,0x53,0x32,0x45,0x78,0x74,0x72,0x61,0x20,0x52,0x65,0x6c,0x20,0x32,0x2e,0x31,0x2e,0x31,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x00,0x91};
+char parse_header[] = {0x01,0x00};//data header
+
+//////////////////////////define accelerometer variables/////////////////////
+float x1;// new variable for math for acceleration parameters
+float y1;// new variable for math for acceleration parameters
+float z1;// new variable for math for acceleration parameters
+float x2;// new variable for math for acceleration parameters
+float y2;// new variable for math for acceleration parameters
+float z2;// new variable for math for acceleration parameters
+
+/////////////////////////define accelerometer variables/////////////////////
+int readings[3] = {0, 0, 0};
+float XaccelADC;
+float YaccelADC;
+float ZaccelADC;
+float Xaccel_g;
+float Yaccel_g;
+float Zaccel_g;
+
+
+
+
+/*LCD 4x20 parallel code pin assignment*/
+//TextLCD lcd(p21, p22, p23, p24, p25, p26, p30, 20, 4); // (rs, rw, e, d0, d1, d2, d3, n_column, n_rows)
+//define file write
+//AnalogIn file_writeenable(p20);//define SD card switch
+
+
+//enter main loop
+int main()
+{  ////start main program loop
+
+//Acceleromater setup
+
+    //Go into standby mode to configure the device.
+    accelerometer.setPowerControl(0x00);
+
+    //Full resolution, +/-16g, 4mg/LSB.
+    accelerometer.setDataFormatControl(0x0B);
+
+    //3.2kHz data rate.
+    accelerometer.setDataRate(ADXL345_3200HZ);
+
+    //Measurement mode.
+    accelerometer.setPowerControl(0x08);
+
+
+    ///////////////////////////GPS setup////////////////////
+
+
+    pc.baud(115200);
+    gps.baud(115200); //////////////////////include for GPS Code /////////////////////////////
+
+
+/////Startup Screen////////////
+    lcd.cls();
+//lcd.init_Display();
+//DigitalOut myled(LED1);
+    lcd.cls();
+    lcd.printf("    Dashview V3    ");
+    wait(1.5);
+    lcd.cls();
+    lcd.printf("    Hello    ");
+    wait(0.5);
+    lcd.locate(0,1);
+    lcd.printf("Have A Great Drive");
+    wait(2.0);
+    lcd.cls();
+
+
+////////////End Startup Screen//////////
+
+
+
+    megasquirt.baud(115200); //define MEgasquirt serial speed
+    loggerSerial.baud(115200); //define  connection speed
+
+//    unsigned char tmp;
+//    unsigned char data_in;
+
+
+/////////file header setup
+/////Setup file header for Datalog.
+/////File header is comma delimited for import to Excel or most video editing software overaly.
+
+    FILE *fp = fopen("/sd/datalog.csv", "a");
+    //print header for MS.csv file
+    fprintf(fp, "MSII Rev 2.88000, \ntime1,Lat1,Long1,speed_mph1,heading1,Xaccel_g, Yaccel_g, Zaccel_g,\n");
+    fclose(fp);
+
+    t.start();
+    dataflag=0;
+    i = 0;
+    while (1) {  ///start functional loop
+
+////////turn on swtich to Pin 20 to write to SD card///////////////
+////////file formate is .csv for import into Excel and also MegaLog Viewer
+        if (SDenable > 0.5) { //switch enable = ON
+            dataflag = 1;
+            myled1 = 1;
+//            printf("Opening File...\n"); // Drive should be marked as removed
+            FILE *fp = fopen("/sd/datalog.csv", "a"); ///open file
+            //write xls buffer from Megasquirt
+
+            if(fp == NULL) {
+                error("Could not open file for write\n");
+            }
+            //if (dataflag == 1) {
+///////Begin Dataflag loop//////////////////
+
+//                for (i = 0; i<5 ; i++)
+//{
+                ///start for loop count 
+/////////////////BEGIN DATA COLLECTION LOOP #1/////////////////////////////////////
+
+                    ///////////////////////////////GPS Code/////////////////////////////////////
+                    
+                        getGPSstring(1);
+
+///////convert string format to floating to perform math functions /////////////////////
+                        if (sscanf(gpsString, "$GPRMC,%s",rmc1) >= 1) {
+                            sep = 0;
+                            parseRMC();
+                            sscanf(time_GPS, "%f", &time1);
+                            sscanf(status, "%c", &statusGPS);
+                            sscanf(Lat, "%f", &Lat1);
+                            sscanf(Lat_h, "%c", &Lat_h1);
+                            sscanf(Long, "%f", &Long1);
+                            sscanf(Long_h, "%c", &Long_h1);
+                            sscanf(time_GPS, "%f", &time_GPS1);
+                            sscanf(speed_k, "%f", &speed_k1);
+                            sscanf(heading, "%f", &heading1);
+
+                        }
+
+
+                        speed_mph1 = speed_k1 * 1.15077; ////convert Knots to mph
+                        Lat1 = Lat1/100; /////Convert format for google maps overlay
+                        Long1 = Long1/-100;  /////Convert format for google maps overlay
+
+                        lcd.locate(10,1);
+                        lcd.printf("Spd:%4.1f", speed_mph1);
+                        //pc.printf("time:%8.1f Lat:%9.6f Long:%9.6f Spd:%4.1f heading:%5.1f \r\n",time1,Lat1,Long1,speed_mph1,heading1);
+
+
+                     ///////////////////////////////////End GPS Code///////////////////////////////////////////////
+
+
+
+///////////////Accelerometer code begin here////////////////////////////////////
+                    {
+                        accelerometer.getOutput(readings);
+
+                        XaccelADC = (int16_t)readings[0];
+                        YaccelADC = (int16_t)readings[1];
+                        ZaccelADC = (int16_t)readings[2];
+
+                        Xaccel_g = (XaccelADC/256);
+                        Yaccel_g = (YaccelADC/256);
+                        Zaccel_g = (ZaccelADC/256);
+
+
+// uncommment to display Accelerometer
+
+
+//        lcd.locate(0,0);/// define LCD location
+//        lcd.printf("%4.2f, %4.2f, %4.2f", Xaccel_g, Yaccel_g, Zaccel_g);
+
+///////Lateral Acceleration bar Graph ///////////////////////
+
+///////////////X-direction accleration bar graph/////////////////
+                        /*
+                                x1 = Xaccel_g * 10;//scale one g to display resolution
+                                if (x1 < 0);//for negative g values
+                                {
+                                    x2 = 10 + x1;//offset negative values for positive graph
+                                    lcd.locate(0,3); /// define LCD location
+                                    for (i=0; i<10; i++) {
+                                        if (i < x2) lcd.putc(0x20);//write single space character
+                                        else lcd.putc(0xFF);//write single clock space
+                                    }
+                                }
+
+                                if (x1 > 0);//for positive g values
+                                {
+                                    lcd.locate(10,3);/// define LCD location
+                                    for (i=0; i<10; i++) {
+                                        if (i < x1) lcd.putc(0xFF);//write single block character
+                                        else lcd.putc(0x20);//write single blank space
+                                    }
+                                }
+                        */
+////////////Forward/Braking Acceleration bar Graph ///////////////////////
+                        y1 = Yaccel_g * 10;//scale one g to display resolution
+                        if (y1 < 0);//for negative g values
+                        {
+                            y2 = 10 + y1;//offset negative values for positive graph
+                            lcd.locate(0,3); /// define LCD location
+                            for (i=0; i<10; i++) {
+                                if (i < y2) lcd.putc(0x20);//write single space character
+                                else lcd.putc(0xFF);//write single clock space
+                            }
+                        }
+
+                        if (y1 > 0);//for positive g values
+                        {
+                            lcd.locate(10,3);/// define LCD location
+                            for (i=0; i<10; i++) {
+                                if (i < y1) lcd.putc(0xFF);//write single block character
+                                else lcd.putc(0x20);//write single blank space
+                            }
+                        }
+ ////////////End Accelerometer code //////////////////////////////////////////////
+ 
+ 
+
+
+
+                    
+                    fprintf(fp, "%.3f, %9.6f, %9.6f, %3.1f,%4.1f, %.3f,  %.3f,  %.3f", time1,Lat1,Long1,speed_mph1,heading1,Xaccel_g, Yaccel_g, Zaccel_g);
+                    pc.printf("%.3f, %9.6f, %9.6f, %3.1f,%4.1f, %.3f,  %.3f,  %.3f, \r\n", time1,Lat1,Long1,speed_mph1,heading1,Xaccel_g, Yaccel_g, Zaccel_g);
+       ////////Get Megasquirt Runtime data buffer//////////////
+
+
+        //poll serial device for data stream (a,0,6) to (request, return, confirm)
+        megasquirt.putc(97);//send 97 for run parameters, 83 for board revision, 81 code for revision number
+        wait(0.005);
+        megasquirt.putc(0);
+        wait(0.005);
+        megasquirt.putc(6);
+        int actuallyRead = megasquirt.readBytes( buf, 112); // where 112 is the number of bytes you are expecting from MSII outpc buffer
+
+
+//decodeMS Runtime Data Buffer();
+
+        Time = t.read();//read value from timer in ms
+
+////////Decode MS Runtime Data Buffer////
+
+////The following code will parse the runtime data buffer from MSExtra-2
+//Position of the runtime bits given on msextra.com
+//Scalar math completed where known
+
+//get seconds - runtime of MS
+        tmp = buf[0];
+        tmp = tmp << 8;
+        SecL = tmp | buf[1];
+        //MSseconds = MSseconds/256;
+//get pulseWidth1
+        tmp = buf[2];
+        tmp = tmp << 8;
+        tmp = tmp | buf[3];
+        PW = tmp*0.000666;
+
+
+//get pulseWidth2
+        tmp = buf[4];
+        tmp = tmp << 8;
+        tmp = tmp | buf[5];
+        PW2 = tmp*0.000666;
+//get Rpm
+        tmp = buf[6];
+        tmp = tmp << 8;
+        RPM = tmp | buf[7];
+
+//Calculate DutyCycle
+        DutyCycle = (PW * (RPM / 60)) / 10;
+
+//Calculate DutyCycle2
+        DutyCycle2 = (PW2 * (RPM / 60)) / 10;
+
+
+//get advance
+        tmp = buf[8];
+        tmp = tmp << 8;
+        tmp = tmp | buf[9];
+        SparkAdv = tmp/10;
+
+//get manifold absolute pressure MAP
+        tmp = buf[18];
+        tmp = tmp << 8;
+        MAP = tmp | buf[19];
+        MAP = MAP/10;
+//get manifold absolute temperature (MAT)
+        tmp = buf[20];
+        tmp = tmp << 8;
+        MAT = tmp | buf[21];
+        MAT = MAT/10; ///for Farenheit
+        //  MAT = 0.555*(MAT - 32); //for Celcius
+//get coolant temperature (CLT)
+        tmp = buf[22];
+        tmp = tmp << 8;
+        CLT = tmp | buf[23];
+        CLT = CLT/10;
+        //CLT = 0.555*(CLT - 32); //for Celciuss
+//get Throttle Position Sensor (TPS)
+        tmp = buf[24];
+        tmp = tmp << 8;
+        TP = tmp | buf[25];
+        TP = TP / 10;
+//get BAttery Voltage
+        tmp = buf[26];
+        tmp = tmp << 8;
+        vBatt = tmp | buf[27];
+        vBatt = vBatt /10,
+//get Realtime AFR for VE1
+        tmp = buf[28];
+        tmp = tmp  << 8;
+        AFR = tmp | buf[29];
+        AFR = AFR /10;
+//
+/////////////// Print Display Variables //////////////////
+
+
+
+///print bargraph of TPS
+        /*       lcd.locate(15,1);
+        //    for (i=0; i<20; i++){
+        //    if (i<TPS) lcd.printf(0xFF);
+        //    else lcd.printf(0x20);
+        //    }
+               lcd.printf("%i ",TPS);
+        */
+
+//get Rpm
+
+        lcd.locate(0,0);
+        lcd.printf("RPM= %i ",RPM);
+
+//get AFR
+
+        //AFR = tmp/10;
+        lcd.locate(10,0);
+        lcd.printf("AFR= %4.1f", AFR);
+
+//get Map
+
+        //MAP = MAP/10;
+        ///will print MAP at atmospheric and Boost on turbo (Bar)
+        if (MAP >100) {
+            MAP = (MAP - 100)/100;
+            lcd.locate (0,1);
+            lcd.printf("%.1f Bar",MAP);
+        } else {
+            lcd.locate(0,1);
+            lcd.printf("MAP= %4.1f", MAP);
+        }
+
+//get Clt
+
+        //CLT = CLT/10;
+        lcd.locate(0,2);
+        if (CLT < 120) {
+            lcd.printf(" Warm Up  ");
+        } else {
+            lcd.printf("CLT= %4.1f", CLT);
+        }
+
+//get MAT
+        lcd.locate(10,2);
+            lcd.printf("MAT= %4.1f", MAT);
+
+//////////////Template to print variable///////////
+//Use code to add variable to display output /////
+        /*
+        //get Variable
+
+                //MAP = MAP/10;
+                lcd.locate(10,1);  position on LCD
+                lcd.printf("Variable= %4.1f", Variable); //format print X.Y is number of data characters total and how many are past decimal point
+
+        */
+/////////////////////////end MS Code////////////////////////////////
+fprintf(fp, "%8.3f, %i, %4.1f, %3f, %4.1f, %4.1f, %5.1f, %5.1f, %f, %.3f, %.3f,\r\n", Time, RPM, MAP, TP, vBatt, AFR, MAT, CLT, PW, DutyCycle, SparkAdv);
+
+/////////////////END DATA COLLECTION LOOP #1/////////////////////////////////////
+
+
+
+ }      ///end for loop count                
+
+
+
+                    //pc.printf("print complete");//debug statement
+
+                ///////end Dataflag loop//////////////////
+
+            
+
+            
+            //pc.printf("close file"); // debug statement
+
+            fclose(fp); ///close file
+            dataflag = 0;  //close flag and reset counter
+            i=0; ///reset counter i
+            ///end datalog - return to function
+                      
+
+        } // end switch enable loop
+        
+ //       
+//        else //If switch NOT enabled begin else loop 2
+
+//        {
+            myled1 = 0;
+            /////////////////BEGIN DATA COLLECTION LOOP #2/////////////////////////////////////
+
+
+            ///////////////////////////////GPS Code/////////////////////////////////////
+            getGPSstring(1);
+
+///////convert string format to floating to perform math functions /////////////////////
+            if (sscanf(gpsString, "$GPRMC,%s",rmc1) >= 1) {
+                sep = 0;
+                parseRMC();
+                sscanf(time_GPS, "%f", &time1);
+                sscanf(Lat, "%f", &Lat1);
+                sscanf(Lat_h, "%c", &Lat_h1);
+                sscanf(Long, "%f", &Long1);
+                sscanf(Long_h, "%c", &Long_h1);
+                sscanf(time_GPS, "%f", &time_GPS1);
+                sscanf(speed_k, "%f", &speed_k1);
+                sscanf(heading, "%f", &heading1);
+
+            }
+
+
+            speed_mph1 = speed_k1 * 1.15077; ////convert Knots to mph
+            Lat1 = Lat1/100; /////Convert format for google maps overlay
+            Long1 = Long1/-100;  /////Convert format for google maps overlay
+
+            lcd.locate(10,1);
+            lcd.printf("Spd:%4.1f  ", speed_mph1);
+            //pc.printf("time:%8.1f Lat:%9.6f Long:%9.6f Spd:%4.1f heading:%5.1f %.3f, %.3f, %.3f \r\n",time1,Lat1,Long1,speed_mph1,heading1,Xaccel_g, Yaccel_g, Zaccel_g, );
+
+            ///////////////////////////////////End GPS Code///////////////////////////////////////////////
+
+
+            ///////////////Accelerometer code begin here////////////////////////////////////
+
+            accelerometer.getOutput(readings);
+
+            XaccelADC = (int16_t)readings[0];
+            YaccelADC = (int16_t)readings[1];
+            ZaccelADC = (int16_t)readings[2];
+
+            Xaccel_g = (XaccelADC/256);
+            Yaccel_g = (YaccelADC/256);
+            Zaccel_g = (ZaccelADC/256);
+
+
+// uncommment to display Accelerometer
+
+
+//        lcd.locate(0,0);/// define LCD location
+//        lcd.printf("%4.2f, %4.2f, %4.2f", Xaccel_g, Yaccel_g, Zaccel_g);
+
+///////Lateral Acceleration bar Graph ///////////////////////
+
+///////////////X-direction accleration bar graph/////////////////
+            /*
+                    x1 = Xaccel_g * 10;//scale one g to display resolution
+                    if (x1 < 0);//for negative g values
+                    {
+                        x2 = 10 + x1;//offset negative values for positive graph
+                        lcd.locate(0,3); /// define LCD location
+                        for (i=0; i<10; i++) {
+                            if (i < x2) lcd.putc(0x20);//write single space character
+                            else lcd.putc(0xFF);//write single clock space
+                        }
+                    }
+
+                    if (x1 > 0);//for positive g values
+                    {
+                        lcd.locate(10,3);/// define LCD location
+                        for (i=0; i<10; i++) {
+                            if (i < x1) lcd.putc(0xFF);//write single block character
+                            else lcd.putc(0x20);//write single blank space
+                        }
+                    }
+            */
+////////////Forward/Braking Acceleration bar Graph ///////////////////////
+            y1 = Yaccel_g * 10;//scale one g to display resolution
+            if (y1 < 0);//for negative g values
+            {
+                y2 = 10 + y1;//offset negative values for positive graph
+                lcd.locate(0,3); /// define LCD location
+                for (i=0; i<10; i++) {
+                    if (i < y2) lcd.putc(0x20);//write single space character
+                    else lcd.putc(0xFF);//write single clock space
+                }
+            }
+
+            if (y1 > 0);//for positive g values
+            {
+                lcd.locate(10,3);/// define LCD location
+                for (i=0; i<10; i++) {
+                    if (i < y1) lcd.putc(0xFF);//write single block character
+                    else lcd.putc(0x20);//write single blank space
+                }
+            }
+
+
+            pc.printf("%.3f, %9.6f, %9.6f, %3.1f,%4.1f, %.3f,  %.3f,  %.3f, \r\n", time1,Lat1,Long1,speed_mph1,heading1,Xaccel_g, Yaccel_g, Zaccel_g);
+       ////////Get Megasquirt Runtime data buffer//////////////
+
+
+        //poll serial device for data stream (a,0,6) to (request, return, confirm)
+        megasquirt.putc(97);//send 97 for run parameters, 83 for board revision, 81 code for revision number
+        wait(0.005);
+        megasquirt.putc(0);
+        wait(0.005);
+        megasquirt.putc(6);
+        int actuallyRead = megasquirt.readBytes( buf, 112); // where 112 is the number of bytes you are expecting from MSII outpc buffer
+
+
+//decodeMS Runtime Data Buffer();
+
+        Time = t.read();//read value from timer in ms
+
+////////Decode MS Runtime Data Buffer////
+
+////The following code will parse the runtime data buffer from MSExtra-2
+//Position of the runtime bits given on msextra.com
+//Scalar math completed where known
+
+//get seconds - runtime of MS
+        tmp = buf[0];
+        tmp = tmp << 8;
+        SecL = tmp | buf[1];
+        //MSseconds = MSseconds/256;
+//get pulseWidth1
+        tmp = buf[2];
+        tmp = tmp << 8;
+        tmp = tmp | buf[3];
+        PW = tmp*0.000666;
+
+
+//get pulseWidth2
+        tmp = buf[4];
+        tmp = tmp << 8;
+        tmp = tmp | buf[5];
+        PW2 = tmp*0.000666;
+//get Rpm
+        tmp = buf[6];
+        tmp = tmp << 8;
+        RPM = tmp | buf[7];
+
+//Calculate DutyCycle
+        DutyCycle = (PW * (RPM / 60)) / 10;
+
+//Calculate DutyCycle2
+        DutyCycle2 = (PW2 * (RPM / 60)) / 10;
+
+
+//get advance
+        tmp = buf[8];
+        tmp = tmp << 8;
+        tmp = tmp | buf[9];
+        SparkAdv = tmp/10;
+
+//get manifold absolute pressure MAP
+        tmp = buf[18];
+        tmp = tmp << 8;
+        MAP = tmp | buf[19];
+        MAP = MAP/10;
+//get manifold absolute temperature (MAT)
+        tmp = buf[20];
+        tmp = tmp << 8;
+        MAT = tmp | buf[21];
+        MAT = MAT/10; ///for Farenheit
+        //  MAT = 0.555*(MAT - 32); //for Celcius
+//get coolant temperature (CLT)
+        tmp = buf[22];
+        tmp = tmp << 8;
+        CLT = tmp | buf[23];
+        CLT = CLT/10;
+        //CLT = 0.555*(CLT - 32); //for Celciuss
+//get Throttle Position Sensor (TPS)
+        tmp = buf[24];
+        tmp = tmp << 8;
+        TP = tmp | buf[25];
+        TP = TP / 10;
+//get BAttery Voltage
+        tmp = buf[26];
+        tmp = tmp << 8;
+        vBatt = tmp | buf[27];
+        vBatt = vBatt /10,
+//get Realtime AFR for VE1
+        tmp = buf[28];
+        tmp = tmp  << 8;
+        AFR = tmp | buf[29];
+        AFR = AFR /10;
+//
+/////////////// Print Display Variables //////////////////
+
+
+
+///print bargraph of TPS
+        /*       lcd.locate(15,1);
+        //    for (i=0; i<20; i++){
+        //    if (i<TPS) lcd.printf(0xFF);
+        //    else lcd.printf(0x20);
+        //    }
+               lcd.printf("%i ",TPS);
+        */
+
+//get Rpm
+
+        lcd.locate(0,0);
+        lcd.printf("RPM= %i ",RPM);
+
+//get AFR
+
+        //AFR = tmp/10;
+        lcd.locate(10,0);
+        lcd.printf("AFR= %4.1f", AFR);
+
+//get Map
+
+        //MAP = MAP/10;
+        ///will print MAP at atmospheric and Boost on turbo (Bar)
+        if (MAP >100) {
+            MAP = (MAP - 100)/100;
+            lcd.locate (0,1);
+            lcd.printf("%.1f Bar",MAP);
+        } else {
+            lcd.locate(0,1);
+            lcd.printf("MAP= %4.1f", MAP);
+        }
+
+//get Clt
+
+        //CLT = CLT/10;
+        lcd.locate(0,2);
+        if (CLT < 120) {
+            lcd.printf(" Warm Up  ");
+        } else {
+            lcd.printf("CLT= %4.1f", CLT);
+        }
+
+//get MAT
+        lcd.locate(10,2);
+            lcd.printf("MAT= %4.1f", MAT);
+
+//////////////Template to print variable///////////
+//Use code to add variable to display output /////
+        /*
+        //get Variable
+
+                //MAP = MAP/10;
+                lcd.locate(10,1);  position on LCD
+                lcd.printf("Variable= %4.1f", Variable); //format print X.Y is number of data characters total and how many are past decimal point
+
+        */
+/////////////////////////end MS Code////////////////////////////////
+
+
+
+
+/////////////////END DATA COLLECTION LOOP #2/////////////////////////////////////
+ //       }  ///end else loop 2
+///////////////end datalog code///////////////////////////////////////////////
+
+    } ///exit while loop
+
+}
+//exit main loop
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Nov 28 17:07:15 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f
\ No newline at end of file