Fragt mithilfe des u-blox c027 über den CAN-Bus den Status der Batterieladung eines Think City Elektroautos ab und informiert per SMS den Halter. Bitte vor der ersten Verwendung die Handynummer anpassen. ---- Uses the u-blox c027 connected over can bus to a Think City electric car to inform a mobile number via SMS about the battery charging. Please change the mobile number to your mobile number before first use. Comments and messages are written in german.

Dependencies:   C027 C027_Support mbed

Files at this revision

API Documentation at this revision

Comitter:
sleepyhead
Date:
Sat Oct 18 12:03:43 2014 +0000
Commit message:
First version of GSMCAN for the u-blox c027 connected to the can bus of a think city electric car. Comments and messages are written in german.

Changed in this revision

C027.lib Show annotated file Show diff for this revision Revisions of this file
C027_Support.lib 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
diff -r 000000000000 -r 4791fa520995 C027.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C027.lib	Sat Oct 18 12:03:43 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/ublox/code/C027/#89c45165ee87
diff -r 000000000000 -r 4791fa520995 C027_Support.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C027_Support.lib	Sat Oct 18 12:03:43 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/ublox/code/C027_Support/#f524fd9aa13d
diff -r 000000000000 -r 4791fa520995 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Oct 18 12:03:43 2014 +0000
@@ -0,0 +1,471 @@
+/*
+   Dieses Programm überwacht die CAN Bus Nachrichten des Think City (Elektroauto). Es sendet beim aktivieren des u-blox C027 ein SMS mit dem aktuellen Status.
+   Ein weiteres SMS wird gesendet, wenn die Ladung abgebrochen oder beendet wurde.
+   Während des Ladevorgang kann der Status mit einer SMS abgefragt werden, dabei spielt der Inhalt der SMS keine Rolle, sie muss nur von der Nummer in der Variable strMobilenumber kommen.
+*/
+
+#include "mbed.h"
+#include "GPS.h"
+#include "MDM.h"
+#include "C027.h"
+C027 c027;
+CAN can1(CANRD, CANTD);
+void recieve1();
+
+// SIM PIN, NULL wenn keiner gesetzt wurde
+#define SIMPIN      NULL
+
+// APN für GPRS, wird momentan nicht verwendet
+#define APN         "gprs.swisscom.ch"
+
+// Benutzername für APN
+#define USERNAME    NULL
+
+// Passwort für APN
+#define PASSWORD    NULL 
+
+// Verhindert die Ausgabe von Debugnachrichten über USB, falls das Modem ebenfalls darüber arbeitet
+#define DOTRACE ((USBRX!=MDMRXD)&&(USBTX!=MDMTXD))
+#define TRACE     (!DOTRACE)?:printf
+
+// An die Nummer strMobilenumber werden die SMS gesendet und auch nur von dieser SMS akzeptiert
+char strMobilenumber[32] = "+41765377278";
+unsigned char idxSendSmsNow = 1;
+#define MAX_SMS_LEN  160
+
+// Endzeit
+time_t timeStop;
+
+/*
+intCarStatus:
+0 = Entladend
+1 = Ladend
+2 = Laden beendet
+3 = Laden abgebrochen
+4 = undefiniert
+
+float und int:
+999 = undefiniert
+
+char:
+4 = undefiniert
+*/
+unsigned char intCarStatus = 4;
+float         fltStartlevel = 999;
+
+// CAN Bus Daten
+float         fltSOC = 999;
+float         fltBatteryTemp = 999;
+unsigned int  intChargeLimitA = 999;
+float         fltBatteryV = 999;
+float         fltBatteryA = 999;
+float         fltBatteryMaxChargeA = 999;
+float         fltMaxChargeV = 999;
+unsigned int  intFailedCells = 999;
+float         fltBatteryTemp1 = 999;
+float         fltBatteryTemp2 = 999;
+unsigned int  intReleasedBatteries = 999;
+float         fltMinDischargeV = 999;
+float         fltMaxDischargeA = 999;
+float         fltChargerPwm = 999;
+float         fltMaxGeneratorV = 999;
+unsigned int  intHighEstErrCat = 999; // 0 = no faults, 1 = Reserved, 2 = Warning, 3 = Delayed switch off, 4 = immediate switch off
+float         fltPcuV = 999;
+float         fltSpeed = 999;
+float         fltPcuTemp = 999;
+unsigned int  intMainsV = 999;
+float         fltMainsA = 999;
+unsigned int  intBmiState = 999; // 0 = idle state, 1 = discharge state (contactor closed), 15 = fault state
+unsigned int  intBatteryType = 999;
+float         fltBmiTempError = 999;
+float         fltZebraTempError = 999;
+char          strShifter[24] = "00 00 00 00 00 00 00 00";
+/* char          str301[24] = "00 00 00 00 00 00 00 00";
+char          str302[24] = "00 00 00 00 00 00 00 00";
+char          str303[24] = "00 00 00 00 00 00 00 00";
+char          str304[24] = "00 00 00 00 00 00 00 00";
+char          str305[24] = "00 00 00 00 00 00 00 00";
+char          str311[24] = "00 00 00 00 00 00 00 00";
+char          str263[24] = "00 00 00 00 00 00 00 00"; */
+
+// Status
+unsigned char idxReducedNumberOfBatteries = 4;
+unsigned char idxEoc = 4;
+unsigned char idxSocGreater102 = 4;
+unsigned char idxChargeEn = 4;
+unsigned char idxOcvMeasurement = 4;
+unsigned char idxAc = 4;
+unsigned char idxChargeEnabled = 4;
+unsigned char idxFastChargeEnabled = 4;
+unsigned char idxDischargeEnabled = 4;
+unsigned char idxIsoTest = 4;
+unsigned char idxAcHeaterRelay = 4;
+unsigned char idxAcHeaterSwitch = 4;
+unsigned char idxRegenBrakeEnabled = 4;
+unsigned char idxDcDcEnabled = 4;
+unsigned char idxFanActive = 4;
+
+// Fehler
+unsigned char idxEpoEmerg = 4; // emergency power off happened
+unsigned char idxCrash = 4;
+unsigned char idxGeneralError = 4;
+unsigned char idxIntIsoError = 4;
+unsigned char idxExtIsoError = 4;
+unsigned char idxThermalIsoError = 4;
+unsigned char idxIsoError = 4;
+unsigned char idxTooManyFailedCells = 4;
+
+// Informationen
+unsigned char idxChargeWaitTempPCU = 4;
+unsigned char idxReachEocPlease = 4;
+unsigned char idxWaitTempDischarge = 4;
+unsigned char idxChargeWaitTempBattery = 4;
+
+// Warnungen
+unsigned char idxNoChargeCurrent = 4;
+unsigned char idxChargeOvervoltage = 4;
+unsigned char idxChargeOvercurrent = 4;
+
+unsigned char readBit(char strByte, char intRow) // Gibt ein Bit aus einem Byte aus, von rechts gezählt, intRow = 0 - 7
+{
+    return strByte >> intRow & 1;
+}
+
+int main(void)
+{
+    int intRet;
+#ifdef TARGET_LPC1768
+    char buf[2048] = "";
+#else
+    char buf[512] = "";
+#endif
+
+    // Startet die serielle Verbindung über USB, falls das Modem nicht über USB angeschlossen ist 
+    if (DOTRACE) {
+        Serial pc(USBTX,USBRX);
+        pc.baud(115200);
+    }
+    
+    wait_ms(1000);
+    
+    TRACE("GSMCAN startet...\r\n");
+    
+    // Schaltet das Modem und GPS ein
+    c027.mdmPower(true);
+    c027.gpsPower(true);
+
+    wait(2);
+    
+    // Erstellt das GPS Objekt
+#if GPSADR    // GPSI2C class
+    GPSI2C gps(GPSSDA,GPSSCL,GPSADR); 
+#elif GPSBAUD // GPSSerial class 
+    GPSSerial gps(GPSTXD,GPSRXD,GPSBAUD); 
+#else
+    #warning "Bitte GPS Pins definieren"
+#endif
+    
+    // Erstellt das Modem Objekt
+    MDMSerial mdm(MDMTXD,MDMRXD,MDMBAUD
+#if DEVICE_SERIAL_FC
+                ,MDMRTS,MDMCTS
+#endif
+                );
+    
+    // Initialisert das Modem
+    TRACE("Modem wird initialisiert...\r\n");
+    MDMParser::DevStatus devStatus;
+    MDMParser::NetStatus netStatus;
+    bool mdmOk = mdm.init(SIMPIN, &devStatus);
+    if (mdmOk)
+    {
+        if (DOTRACE) mdm.dumpDevStatus(&devStatus);
+        
+        // Wartet bis das Netz verbunden ist
+        TRACE("Warte auf GSM Netz...\r\n");
+        while (!mdm.checkNetStatus(&netStatus))
+            wait_ms(1000);
+    
+        if (DOTRACE) mdm.dumpNetStatus(&netStatus);
+    }
+    else {
+        // Wenn das Modem nicht gestartet werden kann, versuchen wir eine Neustart
+        TRACE("Modem Initialisierung fehlgeschlagen, Neustartversuch...\r\n");
+        c027.mdmReset();
+        wait(5);
+        mdmOk = mdm.init(SIMPIN, &devStatus);
+        if (DOTRACE) mdm.dumpDevStatus(&devStatus);
+        if (mdmOk) {
+            while (!mdm.checkNetStatus(&netStatus))
+            wait_ms(1000);
+            if (DOTRACE) mdm.dumpNetStatus(&netStatus);
+        }
+    }
+    TRACE("GSM Modem bereit, starte CAN\r\n");
+    DigitalOut can_standby(CANS);
+    can1.frequency(500000);
+    can1.mode(CAN::Normal);
+    can1.attach(&recieve1);
+    can_standby = 0;
+    
+    char link[128] = "";
+    unsigned int i = 0xFFFFFFFF;
+    const int wait = 100;
+    bool abort = false;
+    while (!abort) {
+        if (i == 10000/wait) {
+            while ((intRet = gps.getMessage(buf, sizeof(buf))) > 0)
+            {
+                int len = LENGTH(intRet);
+                if ((PROTOCOL(intRet) == GPSParser::NMEA) && (len > 6) && !strncmp("$GPGLL", buf, 6))
+                {
+                    double la = 0, lo = 0;
+                    char ch;
+                    if (gps.getNmeaAngle(1,buf,len,la) && 
+                        gps.getNmeaAngle(3,buf,len,lo) && 
+                        gps.getNmeaItem(6,buf,len,ch) && ch == 'A')
+                    {
+                        TRACE("GPS Location: %.5f %.5f\r\n", la, lo); 
+                        sprintf(link, "https://maps.google.com/?q=%.5f,%.5f", la, lo); 
+                    }
+                }
+            }
+        }
+        // Status bestimmen
+        if (fltSOC != 999 && idxAc != 4 && idxEoc != 4 && (i++ > 10000/wait)) {
+            i = 0;
+            if (idxAc == 1 && idxEoc == 0 && intCarStatus != 1) {
+                intCarStatus = 1;
+                fltStartlevel = fltSOC;
+                set_time(1);
+                TRACE("Ladend; Anfangsstand: %.1f%%\r\n", fltStartlevel);
+            }
+            else if (idxEoc == 1 && intCarStatus <= 1) {
+                intCarStatus = 2;
+                timeStop = time(NULL)/60;
+                TRACE("Laden beendet; Anfangsstand: %.1f%%; Zeit: %d Minuten\r\n", fltStartlevel, timeStop);
+                if (fltStartlevel < 90) {
+                    idxSendSmsNow = 1;
+                }
+            }
+            else if (idxAc == 0 && intCarStatus == 1) {
+                intCarStatus = 3;
+                timeStop = time(NULL)/60;
+                TRACE("Laden abgebrochen; Anfangsstand: %.1f%%; Zeit: %d Minuten\r\n", fltStartlevel, timeStop);
+                if (timeStop > 1) {
+                    idxSendSmsNow = 1;
+                }
+            }
+            else if (idxAc == 0 && intCarStatus == 2) {
+                intCarStatus = 0;
+                fltStartlevel = fltSOC;
+                TRACE("Entladend; Anfangsstand: %.1f%%\r\n", fltStartlevel);
+            }
+            if (intCarStatus == 4 && idxAc == 0) {
+                intCarStatus = 0;
+                fltStartlevel = fltSOC;
+                TRACE("Entladend; Anfangsstand: %.1f%%\r\n", fltStartlevel);
+            }
+            else if (intCarStatus == 4 && idxEoc == 1) {
+                intCarStatus = 2;
+                fltStartlevel = fltSOC;
+                TRACE("Laden beendet; Anfangsstand: %.1f%%\r\n", fltStartlevel);
+            }
+            else if (intCarStatus == 4 && idxAc == 1 && idxEoc == 0) {
+                intCarStatus = 1;
+                fltStartlevel = fltSOC;
+                set_time(1);
+                TRACE("Ladend; Anfangsstand: %.1f%%\r\n", fltStartlevel);
+            }
+            switch (intCarStatus) {
+                case 0:
+                    TRACE("Entladend; Anfangsstand: %.1f%%; Stand: %.1f%%; PCU: %.1fV\r\n", fltStartlevel, fltSOC, fltPcuV);
+                    break;
+                case 1:
+                    TRACE("Ladend; Anfangsstand: %.1f%%; Stand: %.1f%%; PCU: %.1fV\r\n", fltStartlevel, fltSOC, fltPcuV);
+                    break;
+                case 2:
+                    TRACE("Laden beendet; Anfangsstand: %.1f%%; Zeit: %d Minuten; PCU: %.1fV\r\n", fltStartlevel, timeStop, fltPcuV);
+                    break;
+                case 3:
+                    TRACE("Laden abgebrochen; Anfangsstand: %.1f%%; Schlussstand: %.1f%%; Zeit: %d Minuten; PCU: %.1fV\r\n", fltStartlevel, fltSOC, timeStop, fltPcuV);
+                    break;
+                case 4:
+                    TRACE("undefiniert;\r\n");
+                    break;
+            }
+            if (mdmOk) {
+                // Status des GSM Modems ausgeben
+                if (mdm.checkNetStatus(&netStatus)) {
+                    if (DOTRACE) mdm.dumpNetStatus(&netStatus);
+                }
+                    
+                // Ungelesene SMS prüfen
+                int ix[8];
+                int n = mdm.smsList("REC UNREAD", ix, 8);
+                if (8 < n) n = 8;
+                while (0 < n--)
+                {
+                    char num[32];
+                    if (mdm.smsRead(ix[n], num, buf, sizeof(buf))) {
+                        TRACE("SMS von \"%s\" mit dem Text \"%s\"\r\n", num, buf);
+                        TRACE("Loesche SMS %d\r\n", ix[n]);
+                        mdm.smsDelete(ix[n]);
+                        // Sende den aktuellen Status, wenn die SMS von der strMobilenumber gekommen ist
+                        if (strcmp(num, strMobilenumber)==0) {
+                            idxSendSmsNow = 1;
+                        }
+                    }
+                }
+            }
+            if (mdmOk && idxSendSmsNow == 1 && intCarStatus != 4) {
+                idxSendSmsNow = 0;
+                char strReply[160];
+                switch (intCarStatus) {
+                case 0:
+                    snprintf(strReply, MAX_SMS_LEN, "Entladend; Anfangsstand: %.1f%%; Stand: %.1f%%; PCU: %.1fV; %s", fltStartlevel, fltSOC, fltPcuV, link);
+                    mdm.smsSend(strMobilenumber, strReply);
+                    break;
+                case 1:
+                    snprintf(strReply, MAX_SMS_LEN, "Ladend; Anfangsstand: %.1f%%; Stand: %.1f%%; PCU: %.1fV; %s", fltStartlevel, fltSOC, fltPcuV, link);
+                    mdm.smsSend(strMobilenumber, strReply);
+                    break;
+                case 2:
+                    snprintf(strReply, MAX_SMS_LEN, "Laden beendet; Anfangsstand: %.1f%%; Zeit: %d Minuten; PCU: %.1fV; %s", fltStartlevel, timeStop, fltPcuV, link);
+                    mdm.smsSend(strMobilenumber, strReply);
+                    break;
+                case 3:
+                    snprintf(strReply, MAX_SMS_LEN, "Laden abgebrochen; Anfangsstand: %.1f%%; Schlussstand: %.1f%%; Zeit: %d Minuten; PCU: %.1fV; %s", fltStartlevel, fltSOC, timeStop, fltPcuV, link);
+                    mdm.smsSend(strMobilenumber, strReply);
+                    intCarStatus = 0;
+                    fltStartlevel = fltSOC;
+                }
+                TRACE("Sende SMS-Antwort \"%s\" an \"%s\"\r\n", strReply, strMobilenumber);
+                delete[] strReply;
+            }
+            // Gebe den aktuellen Status aller CAN Bus Nachrichten aus
+            //TRACE("0x301: str301=%s\r\n", str301);
+            TRACE("0x301: fltBatteryA=%.1f, fltBatteryV=%.1f, fltSOC=%.1f, fltBatteryTemp=%.1f\r\n", fltBatteryA, fltBatteryV, fltSOC, fltBatteryTemp);
+            //TRACE("0x302: str302=%s\r\n", str302);
+            TRACE("0x302: idxGeneralError=%d, idxIsoError=%d, fltMinDischargeV=%.1f, fltMaxDischargeA=%.1f\r\n", idxGeneralError, idxIsoError, fltMinDischargeV, fltMaxDischargeA);
+            //TRACE("0x303: str303=%s\r\n", str303);
+            TRACE("0x303: fltBatteryMaxChargeA=%.1f, fltMaxChargeV=%.1f, idxChargeEnabled=%d, idxRegenBrakeEnabled=%d, idxDischargeEnabled=%d, idxFastChargeEnabled=%d, idxDcDcEnabled=%d, idxAc=%d, intReleasedBatteries=%d, idxReducedNumberOfBatteries=%d, idxEpoEmerg=%d, idxCrash=%d, idxFanActive=%d, idxSocGreater102=%d, idxIsoTest=%d, idxChargeWaitTempPCU=%d\r\n", fltBatteryMaxChargeA, fltMaxChargeV, idxChargeEnabled, idxRegenBrakeEnabled, idxDischargeEnabled, idxFastChargeEnabled, idxDcDcEnabled, idxAc, intReleasedBatteries, idxReducedNumberOfBatteries, idxEpoEmerg, idxCrash, idxFanActive, idxSocGreater102, idxIsoTest, idxChargeWaitTempPCU);
+            //TRACE("0x304: str304=%s\r\n", str304);
+            TRACE("0x304: fltMaxGeneratorV=%.1f, intHighEstErrCat=%d, idxEoc=%d, idxReachEocPlease=%d, idxChargeWaitTempBattery=%d, idxTooManyFailedCells=%d, idxAcHeaterRelay=%d, idxAcHeaterSwitch=%d, fltBatteryTemp1=%.1f, fltBatteryTemp2=%.1f\r\n", fltMaxGeneratorV, intHighEstErrCat, idxEoc, idxReachEocPlease, idxChargeWaitTempBattery, idxTooManyFailedCells, idxAcHeaterRelay, idxAcHeaterSwitch, fltBatteryTemp1, fltBatteryTemp2);
+            //TRACE("0x305: str305=%s\r\n", str305);
+            TRACE("0x305: fltChargerPwm=%.1f, idxIntIsoError=%d, idxExtIsoError=%d, idxChargeEn=%d, idxOcvMeasurement=%d, idxNoChargeCurrent=%d, idxChargeOvervoltage=%d, idxChargeOvercurrent=%d, intFailedCells=%d, idxWaitTempDischarge=%d, idxThermalIsoError=%d, intBmiState=%d, intBatteryType=%d, fltBmiTempError=%.1f, fltZebraTempError=%.1f\r\n", fltChargerPwm, idxIntIsoError, idxExtIsoError, idxChargeEn, idxOcvMeasurement, idxNoChargeCurrent, idxChargeOvervoltage, idxChargeOvercurrent, intFailedCells, idxWaitTempDischarge, idxThermalIsoError, intBmiState, intBatteryType, fltBmiTempError, fltZebraTempError);
+            //TRACE("0x311: str311=%s\r\n", str311);
+            TRACE("0x311: intChargeLimitA=%d\r\n", intChargeLimitA);
+            //TRACE("0x263: str263=%s\r\n", str263);
+            TRACE("0x263: fltPcuV=%.1f, fltSpeed=%.1f, fltPcuTemp=%.1f, intMainsV=%d, fltMainsA=%.1f\r\n", fltPcuV, fltSpeed, fltPcuTemp, intMainsV, fltMainsA);
+            TRACE("0x264: strShifter=%s\r\n", strShifter);
+        }
+        wait_ms(wait);
+    }
+    mdm.powerOff();
+    gps.powerOff();
+    TRACE("Schalte Modem und GPS aus...\r\n");
+#ifdef C027_USEONBOARD
+    c027.mdmPower(false);
+    c027.gpsPower(false);
+#endif    
+    return 0;
+}
+
+// Hier werden die CAN Nachrichten verarbeitet und in die Variablen gespeichert
+void recieve1() {
+    CANMessage canMsg;
+    if (can1.read(canMsg)) {
+       switch (canMsg.id) {
+       case 0x301:
+         fltBatteryA = ((float)(((int) canMsg.data[0] << 8) + canMsg.data[1]) / 10);
+         fltBatteryV = ((float)(((int) canMsg.data[2] << 8) + canMsg.data[3]) / 10);
+         fltSOC = 100.0f - ((float)(((int) canMsg.data[4] << 8) + canMsg.data[5]) / 10);
+         fltBatteryTemp = ((float)(((int) canMsg.data[6] << 8) + canMsg.data[7]) / 10);
+         //snprintf(str301, 24, "%X %X %X %X %X %X %X %X" , canMsg.data[0], canMsg.data[1], canMsg.data[2], canMsg.data[3], canMsg.data[4], canMsg.data[5], canMsg.data[6], canMsg.data[7]);
+         break;
+       case 0x302:
+         idxGeneralError = readBit(canMsg.data[0], 0);
+         idxIsoError = readBit(canMsg.data[2], 0);
+         fltMinDischargeV = ((float)(((int) canMsg.data[4] << 8) + canMsg.data[5]) / 10);
+         fltMaxDischargeA = ((float)(((int) canMsg.data[6] << 8) + canMsg.data[7]) / 10);
+         //snprintf(str302, 24, "%X %X %X %X %X %X %X %X" , canMsg.data[0], canMsg.data[1], canMsg.data[2], canMsg.data[3], canMsg.data[4], canMsg.data[5], canMsg.data[6], canMsg.data[7]);
+         break;
+       case 0x303:
+         fltBatteryMaxChargeA = ((float)(((int) canMsg.data[0] << 8) + canMsg.data[1]) / 10);
+         fltMaxChargeV = ((float)(((int) canMsg.data[2] << 8) + canMsg.data[3]) / 10);
+         idxChargeEnabled = readBit(canMsg.data[4], 0);
+         idxRegenBrakeEnabled = readBit(canMsg.data[4], 1);
+         idxDischargeEnabled = readBit(canMsg.data[4], 2);
+         idxFastChargeEnabled = readBit(canMsg.data[4], 3);
+         idxDcDcEnabled = readBit(canMsg.data[4], 4);
+         idxAc = readBit(canMsg.data[4], 5);
+         intReleasedBatteries = canMsg.data[5];
+         idxReducedNumberOfBatteries = readBit(canMsg.data[6], 0);
+         idxEpoEmerg = readBit(canMsg.data[6], 3);
+         idxCrash = readBit(canMsg.data[6], 4);
+         idxFanActive = readBit(canMsg.data[6], 5);
+         idxSocGreater102 = readBit(canMsg.data[6], 6);
+         idxIsoTest = readBit(canMsg.data[6], 7);
+         idxChargeWaitTempPCU = readBit(canMsg.data[7], 0);
+         //snprintf(str303, 24, "%X %X %X %X %X %X %X %X" , canMsg.data[0], canMsg.data[1], canMsg.data[2], canMsg.data[3], canMsg.data[4], canMsg.data[5], canMsg.data[6], canMsg.data[7]);
+         break;
+       case 0x304:
+         fltMaxGeneratorV = ((float)(((int) canMsg.data[0] << 8) + canMsg.data[1]) / 10);
+         intHighEstErrCat = ((unsigned char) canMsg.data[2]);
+         idxEoc = readBit(canMsg.data[3], 0);
+         idxReachEocPlease = readBit(canMsg.data[3], 1);
+         idxChargeWaitTempBattery = readBit(canMsg.data[3], 2);
+         idxTooManyFailedCells = readBit(canMsg.data[3], 3);
+         idxAcHeaterRelay = readBit(canMsg.data[3], 4);
+         idxAcHeaterSwitch = readBit(canMsg.data[3], 5);
+         fltBatteryTemp1 = ((float)(((int) canMsg.data[4] << 8) + canMsg.data[5]) / 10);
+         fltBatteryTemp2 = ((float)(((int) canMsg.data[6] << 8) + canMsg.data[7]) / 10);
+         //snprintf(str304, 24, "%X %X %X %X %X %X %X %X" , canMsg.data[0], canMsg.data[1], canMsg.data[2], canMsg.data[3], canMsg.data[4], canMsg.data[5], canMsg.data[6], canMsg.data[7]);
+         break;
+       case 0x305:
+         fltChargerPwm = ((float)(((int) canMsg.data[0] << 8) + canMsg.data[1]) / 10);
+         intBmiState = canMsg.data[2] & 15;
+         idxIntIsoError = readBit(canMsg.data[2], 4);
+         idxExtIsoError = readBit(canMsg.data[2], 5);
+         idxChargeEn = readBit(canMsg.data[3], 0);
+         idxOcvMeasurement = readBit(canMsg.data[3], 1);
+         idxNoChargeCurrent = readBit(canMsg.data[3], 2);
+         idxChargeOvervoltage = readBit(canMsg.data[3], 3);
+         idxChargeOvercurrent = readBit(canMsg.data[3], 4);
+         intFailedCells = ((int) canMsg.data[4]<<8) + canMsg.data[5];
+         idxWaitTempDischarge = readBit(canMsg.data[6], 6);
+         idxThermalIsoError = readBit(canMsg.data[6], 5);
+         intBatteryType = (canMsg.data[3] & 224) * 0.03125;
+         fltBmiTempError = (canMsg.data[6] & 6) / 2;
+         fltZebraTempError = (canMsg.data[6] & 24) * 0.125;
+         //snprintf(str305, 24, "%X %X %X %X %X %X %X %X" , canMsg.data[0], canMsg.data[1], canMsg.data[2], canMsg.data[3], canMsg.data[4], canMsg.data[5], canMsg.data[6], canMsg.data[7]);
+         break;
+       case 0x311:
+         intChargeLimitA = ((unsigned char) canMsg.data[1]) * 0.2 ;
+         //snprintf(str311, 24, "%X %X %X %X %X %X %X %X" , canMsg.data[0], canMsg.data[1], canMsg.data[2], canMsg.data[3], canMsg.data[4], canMsg.data[5], canMsg.data[6], canMsg.data[7]);
+         break;
+       case 0x263:
+         fltPcuV = ((float)((int) canMsg.data[3]) / 10);
+         fltSpeed = ((float)((int) canMsg.data[5]) / 2);
+         fltPcuTemp = ((float)((int) canMsg.data[2]) / 2);
+         intMainsV = ((unsigned char) canMsg.data[1]);
+         fltMainsA = ((float)((int) canMsg.data[0]) * 2 / 10);
+         //snprintf(str263, 24, "%X %X %X %X %X %X %X %X" , canMsg.data[0], canMsg.data[1], canMsg.data[2], canMsg.data[3], canMsg.data[4], canMsg.data[5], canMsg.data[6], canMsg.data[7]);
+         break;
+       case 0x264:
+         snprintf(strShifter, 24, "%X %X %X %X %X %X %X %X" , canMsg.data[0], canMsg.data[1], canMsg.data[2], canMsg.data[3], canMsg.data[4], canMsg.data[5], canMsg.data[6], canMsg.data[7]);
+       // Mit folgendem Block können alle unbekannten Nachrichten ausgegeben werden, bremst allerdings das Programm merklich ab
+       /* default:
+         TRACE("ID: 0x%x", canMsg.id);
+         TRACE(" Len: %d", canMsg.len);
+         TRACE(" Type: %d", canMsg.type);
+         TRACE(" Format: %d", canMsg.format);
+         TRACE(" Data:");
+         for (int count = 0; count < canMsg.len; count++) {
+             TRACE(" %x", canMsg.data[count]);
+         }
+         TRACE("\r\n"); */
+       }
+    }
+}
\ No newline at end of file
diff -r 000000000000 -r 4791fa520995 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Oct 18 12:03:43 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1
\ No newline at end of file