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

Committer:
sleepyhead
Date:
Sat Oct 18 12:03:43 2014 +0000
Revision:
0:4791fa520995
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.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sleepyhead 0:4791fa520995 1 /*
sleepyhead 0:4791fa520995 2 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.
sleepyhead 0:4791fa520995 3 Ein weiteres SMS wird gesendet, wenn die Ladung abgebrochen oder beendet wurde.
sleepyhead 0:4791fa520995 4 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.
sleepyhead 0:4791fa520995 5 */
sleepyhead 0:4791fa520995 6
sleepyhead 0:4791fa520995 7 #include "mbed.h"
sleepyhead 0:4791fa520995 8 #include "GPS.h"
sleepyhead 0:4791fa520995 9 #include "MDM.h"
sleepyhead 0:4791fa520995 10 #include "C027.h"
sleepyhead 0:4791fa520995 11 C027 c027;
sleepyhead 0:4791fa520995 12 CAN can1(CANRD, CANTD);
sleepyhead 0:4791fa520995 13 void recieve1();
sleepyhead 0:4791fa520995 14
sleepyhead 0:4791fa520995 15 // SIM PIN, NULL wenn keiner gesetzt wurde
sleepyhead 0:4791fa520995 16 #define SIMPIN NULL
sleepyhead 0:4791fa520995 17
sleepyhead 0:4791fa520995 18 // APN für GPRS, wird momentan nicht verwendet
sleepyhead 0:4791fa520995 19 #define APN "gprs.swisscom.ch"
sleepyhead 0:4791fa520995 20
sleepyhead 0:4791fa520995 21 // Benutzername für APN
sleepyhead 0:4791fa520995 22 #define USERNAME NULL
sleepyhead 0:4791fa520995 23
sleepyhead 0:4791fa520995 24 // Passwort für APN
sleepyhead 0:4791fa520995 25 #define PASSWORD NULL
sleepyhead 0:4791fa520995 26
sleepyhead 0:4791fa520995 27 // Verhindert die Ausgabe von Debugnachrichten über USB, falls das Modem ebenfalls darüber arbeitet
sleepyhead 0:4791fa520995 28 #define DOTRACE ((USBRX!=MDMRXD)&&(USBTX!=MDMTXD))
sleepyhead 0:4791fa520995 29 #define TRACE (!DOTRACE)?:printf
sleepyhead 0:4791fa520995 30
sleepyhead 0:4791fa520995 31 // An die Nummer strMobilenumber werden die SMS gesendet und auch nur von dieser SMS akzeptiert
sleepyhead 0:4791fa520995 32 char strMobilenumber[32] = "+41765377278";
sleepyhead 0:4791fa520995 33 unsigned char idxSendSmsNow = 1;
sleepyhead 0:4791fa520995 34 #define MAX_SMS_LEN 160
sleepyhead 0:4791fa520995 35
sleepyhead 0:4791fa520995 36 // Endzeit
sleepyhead 0:4791fa520995 37 time_t timeStop;
sleepyhead 0:4791fa520995 38
sleepyhead 0:4791fa520995 39 /*
sleepyhead 0:4791fa520995 40 intCarStatus:
sleepyhead 0:4791fa520995 41 0 = Entladend
sleepyhead 0:4791fa520995 42 1 = Ladend
sleepyhead 0:4791fa520995 43 2 = Laden beendet
sleepyhead 0:4791fa520995 44 3 = Laden abgebrochen
sleepyhead 0:4791fa520995 45 4 = undefiniert
sleepyhead 0:4791fa520995 46
sleepyhead 0:4791fa520995 47 float und int:
sleepyhead 0:4791fa520995 48 999 = undefiniert
sleepyhead 0:4791fa520995 49
sleepyhead 0:4791fa520995 50 char:
sleepyhead 0:4791fa520995 51 4 = undefiniert
sleepyhead 0:4791fa520995 52 */
sleepyhead 0:4791fa520995 53 unsigned char intCarStatus = 4;
sleepyhead 0:4791fa520995 54 float fltStartlevel = 999;
sleepyhead 0:4791fa520995 55
sleepyhead 0:4791fa520995 56 // CAN Bus Daten
sleepyhead 0:4791fa520995 57 float fltSOC = 999;
sleepyhead 0:4791fa520995 58 float fltBatteryTemp = 999;
sleepyhead 0:4791fa520995 59 unsigned int intChargeLimitA = 999;
sleepyhead 0:4791fa520995 60 float fltBatteryV = 999;
sleepyhead 0:4791fa520995 61 float fltBatteryA = 999;
sleepyhead 0:4791fa520995 62 float fltBatteryMaxChargeA = 999;
sleepyhead 0:4791fa520995 63 float fltMaxChargeV = 999;
sleepyhead 0:4791fa520995 64 unsigned int intFailedCells = 999;
sleepyhead 0:4791fa520995 65 float fltBatteryTemp1 = 999;
sleepyhead 0:4791fa520995 66 float fltBatteryTemp2 = 999;
sleepyhead 0:4791fa520995 67 unsigned int intReleasedBatteries = 999;
sleepyhead 0:4791fa520995 68 float fltMinDischargeV = 999;
sleepyhead 0:4791fa520995 69 float fltMaxDischargeA = 999;
sleepyhead 0:4791fa520995 70 float fltChargerPwm = 999;
sleepyhead 0:4791fa520995 71 float fltMaxGeneratorV = 999;
sleepyhead 0:4791fa520995 72 unsigned int intHighEstErrCat = 999; // 0 = no faults, 1 = Reserved, 2 = Warning, 3 = Delayed switch off, 4 = immediate switch off
sleepyhead 0:4791fa520995 73 float fltPcuV = 999;
sleepyhead 0:4791fa520995 74 float fltSpeed = 999;
sleepyhead 0:4791fa520995 75 float fltPcuTemp = 999;
sleepyhead 0:4791fa520995 76 unsigned int intMainsV = 999;
sleepyhead 0:4791fa520995 77 float fltMainsA = 999;
sleepyhead 0:4791fa520995 78 unsigned int intBmiState = 999; // 0 = idle state, 1 = discharge state (contactor closed), 15 = fault state
sleepyhead 0:4791fa520995 79 unsigned int intBatteryType = 999;
sleepyhead 0:4791fa520995 80 float fltBmiTempError = 999;
sleepyhead 0:4791fa520995 81 float fltZebraTempError = 999;
sleepyhead 0:4791fa520995 82 char strShifter[24] = "00 00 00 00 00 00 00 00";
sleepyhead 0:4791fa520995 83 /* char str301[24] = "00 00 00 00 00 00 00 00";
sleepyhead 0:4791fa520995 84 char str302[24] = "00 00 00 00 00 00 00 00";
sleepyhead 0:4791fa520995 85 char str303[24] = "00 00 00 00 00 00 00 00";
sleepyhead 0:4791fa520995 86 char str304[24] = "00 00 00 00 00 00 00 00";
sleepyhead 0:4791fa520995 87 char str305[24] = "00 00 00 00 00 00 00 00";
sleepyhead 0:4791fa520995 88 char str311[24] = "00 00 00 00 00 00 00 00";
sleepyhead 0:4791fa520995 89 char str263[24] = "00 00 00 00 00 00 00 00"; */
sleepyhead 0:4791fa520995 90
sleepyhead 0:4791fa520995 91 // Status
sleepyhead 0:4791fa520995 92 unsigned char idxReducedNumberOfBatteries = 4;
sleepyhead 0:4791fa520995 93 unsigned char idxEoc = 4;
sleepyhead 0:4791fa520995 94 unsigned char idxSocGreater102 = 4;
sleepyhead 0:4791fa520995 95 unsigned char idxChargeEn = 4;
sleepyhead 0:4791fa520995 96 unsigned char idxOcvMeasurement = 4;
sleepyhead 0:4791fa520995 97 unsigned char idxAc = 4;
sleepyhead 0:4791fa520995 98 unsigned char idxChargeEnabled = 4;
sleepyhead 0:4791fa520995 99 unsigned char idxFastChargeEnabled = 4;
sleepyhead 0:4791fa520995 100 unsigned char idxDischargeEnabled = 4;
sleepyhead 0:4791fa520995 101 unsigned char idxIsoTest = 4;
sleepyhead 0:4791fa520995 102 unsigned char idxAcHeaterRelay = 4;
sleepyhead 0:4791fa520995 103 unsigned char idxAcHeaterSwitch = 4;
sleepyhead 0:4791fa520995 104 unsigned char idxRegenBrakeEnabled = 4;
sleepyhead 0:4791fa520995 105 unsigned char idxDcDcEnabled = 4;
sleepyhead 0:4791fa520995 106 unsigned char idxFanActive = 4;
sleepyhead 0:4791fa520995 107
sleepyhead 0:4791fa520995 108 // Fehler
sleepyhead 0:4791fa520995 109 unsigned char idxEpoEmerg = 4; // emergency power off happened
sleepyhead 0:4791fa520995 110 unsigned char idxCrash = 4;
sleepyhead 0:4791fa520995 111 unsigned char idxGeneralError = 4;
sleepyhead 0:4791fa520995 112 unsigned char idxIntIsoError = 4;
sleepyhead 0:4791fa520995 113 unsigned char idxExtIsoError = 4;
sleepyhead 0:4791fa520995 114 unsigned char idxThermalIsoError = 4;
sleepyhead 0:4791fa520995 115 unsigned char idxIsoError = 4;
sleepyhead 0:4791fa520995 116 unsigned char idxTooManyFailedCells = 4;
sleepyhead 0:4791fa520995 117
sleepyhead 0:4791fa520995 118 // Informationen
sleepyhead 0:4791fa520995 119 unsigned char idxChargeWaitTempPCU = 4;
sleepyhead 0:4791fa520995 120 unsigned char idxReachEocPlease = 4;
sleepyhead 0:4791fa520995 121 unsigned char idxWaitTempDischarge = 4;
sleepyhead 0:4791fa520995 122 unsigned char idxChargeWaitTempBattery = 4;
sleepyhead 0:4791fa520995 123
sleepyhead 0:4791fa520995 124 // Warnungen
sleepyhead 0:4791fa520995 125 unsigned char idxNoChargeCurrent = 4;
sleepyhead 0:4791fa520995 126 unsigned char idxChargeOvervoltage = 4;
sleepyhead 0:4791fa520995 127 unsigned char idxChargeOvercurrent = 4;
sleepyhead 0:4791fa520995 128
sleepyhead 0:4791fa520995 129 unsigned char readBit(char strByte, char intRow) // Gibt ein Bit aus einem Byte aus, von rechts gezählt, intRow = 0 - 7
sleepyhead 0:4791fa520995 130 {
sleepyhead 0:4791fa520995 131 return strByte >> intRow & 1;
sleepyhead 0:4791fa520995 132 }
sleepyhead 0:4791fa520995 133
sleepyhead 0:4791fa520995 134 int main(void)
sleepyhead 0:4791fa520995 135 {
sleepyhead 0:4791fa520995 136 int intRet;
sleepyhead 0:4791fa520995 137 #ifdef TARGET_LPC1768
sleepyhead 0:4791fa520995 138 char buf[2048] = "";
sleepyhead 0:4791fa520995 139 #else
sleepyhead 0:4791fa520995 140 char buf[512] = "";
sleepyhead 0:4791fa520995 141 #endif
sleepyhead 0:4791fa520995 142
sleepyhead 0:4791fa520995 143 // Startet die serielle Verbindung über USB, falls das Modem nicht über USB angeschlossen ist
sleepyhead 0:4791fa520995 144 if (DOTRACE) {
sleepyhead 0:4791fa520995 145 Serial pc(USBTX,USBRX);
sleepyhead 0:4791fa520995 146 pc.baud(115200);
sleepyhead 0:4791fa520995 147 }
sleepyhead 0:4791fa520995 148
sleepyhead 0:4791fa520995 149 wait_ms(1000);
sleepyhead 0:4791fa520995 150
sleepyhead 0:4791fa520995 151 TRACE("GSMCAN startet...\r\n");
sleepyhead 0:4791fa520995 152
sleepyhead 0:4791fa520995 153 // Schaltet das Modem und GPS ein
sleepyhead 0:4791fa520995 154 c027.mdmPower(true);
sleepyhead 0:4791fa520995 155 c027.gpsPower(true);
sleepyhead 0:4791fa520995 156
sleepyhead 0:4791fa520995 157 wait(2);
sleepyhead 0:4791fa520995 158
sleepyhead 0:4791fa520995 159 // Erstellt das GPS Objekt
sleepyhead 0:4791fa520995 160 #if GPSADR // GPSI2C class
sleepyhead 0:4791fa520995 161 GPSI2C gps(GPSSDA,GPSSCL,GPSADR);
sleepyhead 0:4791fa520995 162 #elif GPSBAUD // GPSSerial class
sleepyhead 0:4791fa520995 163 GPSSerial gps(GPSTXD,GPSRXD,GPSBAUD);
sleepyhead 0:4791fa520995 164 #else
sleepyhead 0:4791fa520995 165 #warning "Bitte GPS Pins definieren"
sleepyhead 0:4791fa520995 166 #endif
sleepyhead 0:4791fa520995 167
sleepyhead 0:4791fa520995 168 // Erstellt das Modem Objekt
sleepyhead 0:4791fa520995 169 MDMSerial mdm(MDMTXD,MDMRXD,MDMBAUD
sleepyhead 0:4791fa520995 170 #if DEVICE_SERIAL_FC
sleepyhead 0:4791fa520995 171 ,MDMRTS,MDMCTS
sleepyhead 0:4791fa520995 172 #endif
sleepyhead 0:4791fa520995 173 );
sleepyhead 0:4791fa520995 174
sleepyhead 0:4791fa520995 175 // Initialisert das Modem
sleepyhead 0:4791fa520995 176 TRACE("Modem wird initialisiert...\r\n");
sleepyhead 0:4791fa520995 177 MDMParser::DevStatus devStatus;
sleepyhead 0:4791fa520995 178 MDMParser::NetStatus netStatus;
sleepyhead 0:4791fa520995 179 bool mdmOk = mdm.init(SIMPIN, &devStatus);
sleepyhead 0:4791fa520995 180 if (mdmOk)
sleepyhead 0:4791fa520995 181 {
sleepyhead 0:4791fa520995 182 if (DOTRACE) mdm.dumpDevStatus(&devStatus);
sleepyhead 0:4791fa520995 183
sleepyhead 0:4791fa520995 184 // Wartet bis das Netz verbunden ist
sleepyhead 0:4791fa520995 185 TRACE("Warte auf GSM Netz...\r\n");
sleepyhead 0:4791fa520995 186 while (!mdm.checkNetStatus(&netStatus))
sleepyhead 0:4791fa520995 187 wait_ms(1000);
sleepyhead 0:4791fa520995 188
sleepyhead 0:4791fa520995 189 if (DOTRACE) mdm.dumpNetStatus(&netStatus);
sleepyhead 0:4791fa520995 190 }
sleepyhead 0:4791fa520995 191 else {
sleepyhead 0:4791fa520995 192 // Wenn das Modem nicht gestartet werden kann, versuchen wir eine Neustart
sleepyhead 0:4791fa520995 193 TRACE("Modem Initialisierung fehlgeschlagen, Neustartversuch...\r\n");
sleepyhead 0:4791fa520995 194 c027.mdmReset();
sleepyhead 0:4791fa520995 195 wait(5);
sleepyhead 0:4791fa520995 196 mdmOk = mdm.init(SIMPIN, &devStatus);
sleepyhead 0:4791fa520995 197 if (DOTRACE) mdm.dumpDevStatus(&devStatus);
sleepyhead 0:4791fa520995 198 if (mdmOk) {
sleepyhead 0:4791fa520995 199 while (!mdm.checkNetStatus(&netStatus))
sleepyhead 0:4791fa520995 200 wait_ms(1000);
sleepyhead 0:4791fa520995 201 if (DOTRACE) mdm.dumpNetStatus(&netStatus);
sleepyhead 0:4791fa520995 202 }
sleepyhead 0:4791fa520995 203 }
sleepyhead 0:4791fa520995 204 TRACE("GSM Modem bereit, starte CAN\r\n");
sleepyhead 0:4791fa520995 205 DigitalOut can_standby(CANS);
sleepyhead 0:4791fa520995 206 can1.frequency(500000);
sleepyhead 0:4791fa520995 207 can1.mode(CAN::Normal);
sleepyhead 0:4791fa520995 208 can1.attach(&recieve1);
sleepyhead 0:4791fa520995 209 can_standby = 0;
sleepyhead 0:4791fa520995 210
sleepyhead 0:4791fa520995 211 char link[128] = "";
sleepyhead 0:4791fa520995 212 unsigned int i = 0xFFFFFFFF;
sleepyhead 0:4791fa520995 213 const int wait = 100;
sleepyhead 0:4791fa520995 214 bool abort = false;
sleepyhead 0:4791fa520995 215 while (!abort) {
sleepyhead 0:4791fa520995 216 if (i == 10000/wait) {
sleepyhead 0:4791fa520995 217 while ((intRet = gps.getMessage(buf, sizeof(buf))) > 0)
sleepyhead 0:4791fa520995 218 {
sleepyhead 0:4791fa520995 219 int len = LENGTH(intRet);
sleepyhead 0:4791fa520995 220 if ((PROTOCOL(intRet) == GPSParser::NMEA) && (len > 6) && !strncmp("$GPGLL", buf, 6))
sleepyhead 0:4791fa520995 221 {
sleepyhead 0:4791fa520995 222 double la = 0, lo = 0;
sleepyhead 0:4791fa520995 223 char ch;
sleepyhead 0:4791fa520995 224 if (gps.getNmeaAngle(1,buf,len,la) &&
sleepyhead 0:4791fa520995 225 gps.getNmeaAngle(3,buf,len,lo) &&
sleepyhead 0:4791fa520995 226 gps.getNmeaItem(6,buf,len,ch) && ch == 'A')
sleepyhead 0:4791fa520995 227 {
sleepyhead 0:4791fa520995 228 TRACE("GPS Location: %.5f %.5f\r\n", la, lo);
sleepyhead 0:4791fa520995 229 sprintf(link, "https://maps.google.com/?q=%.5f,%.5f", la, lo);
sleepyhead 0:4791fa520995 230 }
sleepyhead 0:4791fa520995 231 }
sleepyhead 0:4791fa520995 232 }
sleepyhead 0:4791fa520995 233 }
sleepyhead 0:4791fa520995 234 // Status bestimmen
sleepyhead 0:4791fa520995 235 if (fltSOC != 999 && idxAc != 4 && idxEoc != 4 && (i++ > 10000/wait)) {
sleepyhead 0:4791fa520995 236 i = 0;
sleepyhead 0:4791fa520995 237 if (idxAc == 1 && idxEoc == 0 && intCarStatus != 1) {
sleepyhead 0:4791fa520995 238 intCarStatus = 1;
sleepyhead 0:4791fa520995 239 fltStartlevel = fltSOC;
sleepyhead 0:4791fa520995 240 set_time(1);
sleepyhead 0:4791fa520995 241 TRACE("Ladend; Anfangsstand: %.1f%%\r\n", fltStartlevel);
sleepyhead 0:4791fa520995 242 }
sleepyhead 0:4791fa520995 243 else if (idxEoc == 1 && intCarStatus <= 1) {
sleepyhead 0:4791fa520995 244 intCarStatus = 2;
sleepyhead 0:4791fa520995 245 timeStop = time(NULL)/60;
sleepyhead 0:4791fa520995 246 TRACE("Laden beendet; Anfangsstand: %.1f%%; Zeit: %d Minuten\r\n", fltStartlevel, timeStop);
sleepyhead 0:4791fa520995 247 if (fltStartlevel < 90) {
sleepyhead 0:4791fa520995 248 idxSendSmsNow = 1;
sleepyhead 0:4791fa520995 249 }
sleepyhead 0:4791fa520995 250 }
sleepyhead 0:4791fa520995 251 else if (idxAc == 0 && intCarStatus == 1) {
sleepyhead 0:4791fa520995 252 intCarStatus = 3;
sleepyhead 0:4791fa520995 253 timeStop = time(NULL)/60;
sleepyhead 0:4791fa520995 254 TRACE("Laden abgebrochen; Anfangsstand: %.1f%%; Zeit: %d Minuten\r\n", fltStartlevel, timeStop);
sleepyhead 0:4791fa520995 255 if (timeStop > 1) {
sleepyhead 0:4791fa520995 256 idxSendSmsNow = 1;
sleepyhead 0:4791fa520995 257 }
sleepyhead 0:4791fa520995 258 }
sleepyhead 0:4791fa520995 259 else if (idxAc == 0 && intCarStatus == 2) {
sleepyhead 0:4791fa520995 260 intCarStatus = 0;
sleepyhead 0:4791fa520995 261 fltStartlevel = fltSOC;
sleepyhead 0:4791fa520995 262 TRACE("Entladend; Anfangsstand: %.1f%%\r\n", fltStartlevel);
sleepyhead 0:4791fa520995 263 }
sleepyhead 0:4791fa520995 264 if (intCarStatus == 4 && idxAc == 0) {
sleepyhead 0:4791fa520995 265 intCarStatus = 0;
sleepyhead 0:4791fa520995 266 fltStartlevel = fltSOC;
sleepyhead 0:4791fa520995 267 TRACE("Entladend; Anfangsstand: %.1f%%\r\n", fltStartlevel);
sleepyhead 0:4791fa520995 268 }
sleepyhead 0:4791fa520995 269 else if (intCarStatus == 4 && idxEoc == 1) {
sleepyhead 0:4791fa520995 270 intCarStatus = 2;
sleepyhead 0:4791fa520995 271 fltStartlevel = fltSOC;
sleepyhead 0:4791fa520995 272 TRACE("Laden beendet; Anfangsstand: %.1f%%\r\n", fltStartlevel);
sleepyhead 0:4791fa520995 273 }
sleepyhead 0:4791fa520995 274 else if (intCarStatus == 4 && idxAc == 1 && idxEoc == 0) {
sleepyhead 0:4791fa520995 275 intCarStatus = 1;
sleepyhead 0:4791fa520995 276 fltStartlevel = fltSOC;
sleepyhead 0:4791fa520995 277 set_time(1);
sleepyhead 0:4791fa520995 278 TRACE("Ladend; Anfangsstand: %.1f%%\r\n", fltStartlevel);
sleepyhead 0:4791fa520995 279 }
sleepyhead 0:4791fa520995 280 switch (intCarStatus) {
sleepyhead 0:4791fa520995 281 case 0:
sleepyhead 0:4791fa520995 282 TRACE("Entladend; Anfangsstand: %.1f%%; Stand: %.1f%%; PCU: %.1fV\r\n", fltStartlevel, fltSOC, fltPcuV);
sleepyhead 0:4791fa520995 283 break;
sleepyhead 0:4791fa520995 284 case 1:
sleepyhead 0:4791fa520995 285 TRACE("Ladend; Anfangsstand: %.1f%%; Stand: %.1f%%; PCU: %.1fV\r\n", fltStartlevel, fltSOC, fltPcuV);
sleepyhead 0:4791fa520995 286 break;
sleepyhead 0:4791fa520995 287 case 2:
sleepyhead 0:4791fa520995 288 TRACE("Laden beendet; Anfangsstand: %.1f%%; Zeit: %d Minuten; PCU: %.1fV\r\n", fltStartlevel, timeStop, fltPcuV);
sleepyhead 0:4791fa520995 289 break;
sleepyhead 0:4791fa520995 290 case 3:
sleepyhead 0:4791fa520995 291 TRACE("Laden abgebrochen; Anfangsstand: %.1f%%; Schlussstand: %.1f%%; Zeit: %d Minuten; PCU: %.1fV\r\n", fltStartlevel, fltSOC, timeStop, fltPcuV);
sleepyhead 0:4791fa520995 292 break;
sleepyhead 0:4791fa520995 293 case 4:
sleepyhead 0:4791fa520995 294 TRACE("undefiniert;\r\n");
sleepyhead 0:4791fa520995 295 break;
sleepyhead 0:4791fa520995 296 }
sleepyhead 0:4791fa520995 297 if (mdmOk) {
sleepyhead 0:4791fa520995 298 // Status des GSM Modems ausgeben
sleepyhead 0:4791fa520995 299 if (mdm.checkNetStatus(&netStatus)) {
sleepyhead 0:4791fa520995 300 if (DOTRACE) mdm.dumpNetStatus(&netStatus);
sleepyhead 0:4791fa520995 301 }
sleepyhead 0:4791fa520995 302
sleepyhead 0:4791fa520995 303 // Ungelesene SMS prüfen
sleepyhead 0:4791fa520995 304 int ix[8];
sleepyhead 0:4791fa520995 305 int n = mdm.smsList("REC UNREAD", ix, 8);
sleepyhead 0:4791fa520995 306 if (8 < n) n = 8;
sleepyhead 0:4791fa520995 307 while (0 < n--)
sleepyhead 0:4791fa520995 308 {
sleepyhead 0:4791fa520995 309 char num[32];
sleepyhead 0:4791fa520995 310 if (mdm.smsRead(ix[n], num, buf, sizeof(buf))) {
sleepyhead 0:4791fa520995 311 TRACE("SMS von \"%s\" mit dem Text \"%s\"\r\n", num, buf);
sleepyhead 0:4791fa520995 312 TRACE("Loesche SMS %d\r\n", ix[n]);
sleepyhead 0:4791fa520995 313 mdm.smsDelete(ix[n]);
sleepyhead 0:4791fa520995 314 // Sende den aktuellen Status, wenn die SMS von der strMobilenumber gekommen ist
sleepyhead 0:4791fa520995 315 if (strcmp(num, strMobilenumber)==0) {
sleepyhead 0:4791fa520995 316 idxSendSmsNow = 1;
sleepyhead 0:4791fa520995 317 }
sleepyhead 0:4791fa520995 318 }
sleepyhead 0:4791fa520995 319 }
sleepyhead 0:4791fa520995 320 }
sleepyhead 0:4791fa520995 321 if (mdmOk && idxSendSmsNow == 1 && intCarStatus != 4) {
sleepyhead 0:4791fa520995 322 idxSendSmsNow = 0;
sleepyhead 0:4791fa520995 323 char strReply[160];
sleepyhead 0:4791fa520995 324 switch (intCarStatus) {
sleepyhead 0:4791fa520995 325 case 0:
sleepyhead 0:4791fa520995 326 snprintf(strReply, MAX_SMS_LEN, "Entladend; Anfangsstand: %.1f%%; Stand: %.1f%%; PCU: %.1fV; %s", fltStartlevel, fltSOC, fltPcuV, link);
sleepyhead 0:4791fa520995 327 mdm.smsSend(strMobilenumber, strReply);
sleepyhead 0:4791fa520995 328 break;
sleepyhead 0:4791fa520995 329 case 1:
sleepyhead 0:4791fa520995 330 snprintf(strReply, MAX_SMS_LEN, "Ladend; Anfangsstand: %.1f%%; Stand: %.1f%%; PCU: %.1fV; %s", fltStartlevel, fltSOC, fltPcuV, link);
sleepyhead 0:4791fa520995 331 mdm.smsSend(strMobilenumber, strReply);
sleepyhead 0:4791fa520995 332 break;
sleepyhead 0:4791fa520995 333 case 2:
sleepyhead 0:4791fa520995 334 snprintf(strReply, MAX_SMS_LEN, "Laden beendet; Anfangsstand: %.1f%%; Zeit: %d Minuten; PCU: %.1fV; %s", fltStartlevel, timeStop, fltPcuV, link);
sleepyhead 0:4791fa520995 335 mdm.smsSend(strMobilenumber, strReply);
sleepyhead 0:4791fa520995 336 break;
sleepyhead 0:4791fa520995 337 case 3:
sleepyhead 0:4791fa520995 338 snprintf(strReply, MAX_SMS_LEN, "Laden abgebrochen; Anfangsstand: %.1f%%; Schlussstand: %.1f%%; Zeit: %d Minuten; PCU: %.1fV; %s", fltStartlevel, fltSOC, timeStop, fltPcuV, link);
sleepyhead 0:4791fa520995 339 mdm.smsSend(strMobilenumber, strReply);
sleepyhead 0:4791fa520995 340 intCarStatus = 0;
sleepyhead 0:4791fa520995 341 fltStartlevel = fltSOC;
sleepyhead 0:4791fa520995 342 }
sleepyhead 0:4791fa520995 343 TRACE("Sende SMS-Antwort \"%s\" an \"%s\"\r\n", strReply, strMobilenumber);
sleepyhead 0:4791fa520995 344 delete[] strReply;
sleepyhead 0:4791fa520995 345 }
sleepyhead 0:4791fa520995 346 // Gebe den aktuellen Status aller CAN Bus Nachrichten aus
sleepyhead 0:4791fa520995 347 //TRACE("0x301: str301=%s\r\n", str301);
sleepyhead 0:4791fa520995 348 TRACE("0x301: fltBatteryA=%.1f, fltBatteryV=%.1f, fltSOC=%.1f, fltBatteryTemp=%.1f\r\n", fltBatteryA, fltBatteryV, fltSOC, fltBatteryTemp);
sleepyhead 0:4791fa520995 349 //TRACE("0x302: str302=%s\r\n", str302);
sleepyhead 0:4791fa520995 350 TRACE("0x302: idxGeneralError=%d, idxIsoError=%d, fltMinDischargeV=%.1f, fltMaxDischargeA=%.1f\r\n", idxGeneralError, idxIsoError, fltMinDischargeV, fltMaxDischargeA);
sleepyhead 0:4791fa520995 351 //TRACE("0x303: str303=%s\r\n", str303);
sleepyhead 0:4791fa520995 352 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);
sleepyhead 0:4791fa520995 353 //TRACE("0x304: str304=%s\r\n", str304);
sleepyhead 0:4791fa520995 354 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);
sleepyhead 0:4791fa520995 355 //TRACE("0x305: str305=%s\r\n", str305);
sleepyhead 0:4791fa520995 356 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);
sleepyhead 0:4791fa520995 357 //TRACE("0x311: str311=%s\r\n", str311);
sleepyhead 0:4791fa520995 358 TRACE("0x311: intChargeLimitA=%d\r\n", intChargeLimitA);
sleepyhead 0:4791fa520995 359 //TRACE("0x263: str263=%s\r\n", str263);
sleepyhead 0:4791fa520995 360 TRACE("0x263: fltPcuV=%.1f, fltSpeed=%.1f, fltPcuTemp=%.1f, intMainsV=%d, fltMainsA=%.1f\r\n", fltPcuV, fltSpeed, fltPcuTemp, intMainsV, fltMainsA);
sleepyhead 0:4791fa520995 361 TRACE("0x264: strShifter=%s\r\n", strShifter);
sleepyhead 0:4791fa520995 362 }
sleepyhead 0:4791fa520995 363 wait_ms(wait);
sleepyhead 0:4791fa520995 364 }
sleepyhead 0:4791fa520995 365 mdm.powerOff();
sleepyhead 0:4791fa520995 366 gps.powerOff();
sleepyhead 0:4791fa520995 367 TRACE("Schalte Modem und GPS aus...\r\n");
sleepyhead 0:4791fa520995 368 #ifdef C027_USEONBOARD
sleepyhead 0:4791fa520995 369 c027.mdmPower(false);
sleepyhead 0:4791fa520995 370 c027.gpsPower(false);
sleepyhead 0:4791fa520995 371 #endif
sleepyhead 0:4791fa520995 372 return 0;
sleepyhead 0:4791fa520995 373 }
sleepyhead 0:4791fa520995 374
sleepyhead 0:4791fa520995 375 // Hier werden die CAN Nachrichten verarbeitet und in die Variablen gespeichert
sleepyhead 0:4791fa520995 376 void recieve1() {
sleepyhead 0:4791fa520995 377 CANMessage canMsg;
sleepyhead 0:4791fa520995 378 if (can1.read(canMsg)) {
sleepyhead 0:4791fa520995 379 switch (canMsg.id) {
sleepyhead 0:4791fa520995 380 case 0x301:
sleepyhead 0:4791fa520995 381 fltBatteryA = ((float)(((int) canMsg.data[0] << 8) + canMsg.data[1]) / 10);
sleepyhead 0:4791fa520995 382 fltBatteryV = ((float)(((int) canMsg.data[2] << 8) + canMsg.data[3]) / 10);
sleepyhead 0:4791fa520995 383 fltSOC = 100.0f - ((float)(((int) canMsg.data[4] << 8) + canMsg.data[5]) / 10);
sleepyhead 0:4791fa520995 384 fltBatteryTemp = ((float)(((int) canMsg.data[6] << 8) + canMsg.data[7]) / 10);
sleepyhead 0:4791fa520995 385 //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]);
sleepyhead 0:4791fa520995 386 break;
sleepyhead 0:4791fa520995 387 case 0x302:
sleepyhead 0:4791fa520995 388 idxGeneralError = readBit(canMsg.data[0], 0);
sleepyhead 0:4791fa520995 389 idxIsoError = readBit(canMsg.data[2], 0);
sleepyhead 0:4791fa520995 390 fltMinDischargeV = ((float)(((int) canMsg.data[4] << 8) + canMsg.data[5]) / 10);
sleepyhead 0:4791fa520995 391 fltMaxDischargeA = ((float)(((int) canMsg.data[6] << 8) + canMsg.data[7]) / 10);
sleepyhead 0:4791fa520995 392 //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]);
sleepyhead 0:4791fa520995 393 break;
sleepyhead 0:4791fa520995 394 case 0x303:
sleepyhead 0:4791fa520995 395 fltBatteryMaxChargeA = ((float)(((int) canMsg.data[0] << 8) + canMsg.data[1]) / 10);
sleepyhead 0:4791fa520995 396 fltMaxChargeV = ((float)(((int) canMsg.data[2] << 8) + canMsg.data[3]) / 10);
sleepyhead 0:4791fa520995 397 idxChargeEnabled = readBit(canMsg.data[4], 0);
sleepyhead 0:4791fa520995 398 idxRegenBrakeEnabled = readBit(canMsg.data[4], 1);
sleepyhead 0:4791fa520995 399 idxDischargeEnabled = readBit(canMsg.data[4], 2);
sleepyhead 0:4791fa520995 400 idxFastChargeEnabled = readBit(canMsg.data[4], 3);
sleepyhead 0:4791fa520995 401 idxDcDcEnabled = readBit(canMsg.data[4], 4);
sleepyhead 0:4791fa520995 402 idxAc = readBit(canMsg.data[4], 5);
sleepyhead 0:4791fa520995 403 intReleasedBatteries = canMsg.data[5];
sleepyhead 0:4791fa520995 404 idxReducedNumberOfBatteries = readBit(canMsg.data[6], 0);
sleepyhead 0:4791fa520995 405 idxEpoEmerg = readBit(canMsg.data[6], 3);
sleepyhead 0:4791fa520995 406 idxCrash = readBit(canMsg.data[6], 4);
sleepyhead 0:4791fa520995 407 idxFanActive = readBit(canMsg.data[6], 5);
sleepyhead 0:4791fa520995 408 idxSocGreater102 = readBit(canMsg.data[6], 6);
sleepyhead 0:4791fa520995 409 idxIsoTest = readBit(canMsg.data[6], 7);
sleepyhead 0:4791fa520995 410 idxChargeWaitTempPCU = readBit(canMsg.data[7], 0);
sleepyhead 0:4791fa520995 411 //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]);
sleepyhead 0:4791fa520995 412 break;
sleepyhead 0:4791fa520995 413 case 0x304:
sleepyhead 0:4791fa520995 414 fltMaxGeneratorV = ((float)(((int) canMsg.data[0] << 8) + canMsg.data[1]) / 10);
sleepyhead 0:4791fa520995 415 intHighEstErrCat = ((unsigned char) canMsg.data[2]);
sleepyhead 0:4791fa520995 416 idxEoc = readBit(canMsg.data[3], 0);
sleepyhead 0:4791fa520995 417 idxReachEocPlease = readBit(canMsg.data[3], 1);
sleepyhead 0:4791fa520995 418 idxChargeWaitTempBattery = readBit(canMsg.data[3], 2);
sleepyhead 0:4791fa520995 419 idxTooManyFailedCells = readBit(canMsg.data[3], 3);
sleepyhead 0:4791fa520995 420 idxAcHeaterRelay = readBit(canMsg.data[3], 4);
sleepyhead 0:4791fa520995 421 idxAcHeaterSwitch = readBit(canMsg.data[3], 5);
sleepyhead 0:4791fa520995 422 fltBatteryTemp1 = ((float)(((int) canMsg.data[4] << 8) + canMsg.data[5]) / 10);
sleepyhead 0:4791fa520995 423 fltBatteryTemp2 = ((float)(((int) canMsg.data[6] << 8) + canMsg.data[7]) / 10);
sleepyhead 0:4791fa520995 424 //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]);
sleepyhead 0:4791fa520995 425 break;
sleepyhead 0:4791fa520995 426 case 0x305:
sleepyhead 0:4791fa520995 427 fltChargerPwm = ((float)(((int) canMsg.data[0] << 8) + canMsg.data[1]) / 10);
sleepyhead 0:4791fa520995 428 intBmiState = canMsg.data[2] & 15;
sleepyhead 0:4791fa520995 429 idxIntIsoError = readBit(canMsg.data[2], 4);
sleepyhead 0:4791fa520995 430 idxExtIsoError = readBit(canMsg.data[2], 5);
sleepyhead 0:4791fa520995 431 idxChargeEn = readBit(canMsg.data[3], 0);
sleepyhead 0:4791fa520995 432 idxOcvMeasurement = readBit(canMsg.data[3], 1);
sleepyhead 0:4791fa520995 433 idxNoChargeCurrent = readBit(canMsg.data[3], 2);
sleepyhead 0:4791fa520995 434 idxChargeOvervoltage = readBit(canMsg.data[3], 3);
sleepyhead 0:4791fa520995 435 idxChargeOvercurrent = readBit(canMsg.data[3], 4);
sleepyhead 0:4791fa520995 436 intFailedCells = ((int) canMsg.data[4]<<8) + canMsg.data[5];
sleepyhead 0:4791fa520995 437 idxWaitTempDischarge = readBit(canMsg.data[6], 6);
sleepyhead 0:4791fa520995 438 idxThermalIsoError = readBit(canMsg.data[6], 5);
sleepyhead 0:4791fa520995 439 intBatteryType = (canMsg.data[3] & 224) * 0.03125;
sleepyhead 0:4791fa520995 440 fltBmiTempError = (canMsg.data[6] & 6) / 2;
sleepyhead 0:4791fa520995 441 fltZebraTempError = (canMsg.data[6] & 24) * 0.125;
sleepyhead 0:4791fa520995 442 //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]);
sleepyhead 0:4791fa520995 443 break;
sleepyhead 0:4791fa520995 444 case 0x311:
sleepyhead 0:4791fa520995 445 intChargeLimitA = ((unsigned char) canMsg.data[1]) * 0.2 ;
sleepyhead 0:4791fa520995 446 //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]);
sleepyhead 0:4791fa520995 447 break;
sleepyhead 0:4791fa520995 448 case 0x263:
sleepyhead 0:4791fa520995 449 fltPcuV = ((float)((int) canMsg.data[3]) / 10);
sleepyhead 0:4791fa520995 450 fltSpeed = ((float)((int) canMsg.data[5]) / 2);
sleepyhead 0:4791fa520995 451 fltPcuTemp = ((float)((int) canMsg.data[2]) / 2);
sleepyhead 0:4791fa520995 452 intMainsV = ((unsigned char) canMsg.data[1]);
sleepyhead 0:4791fa520995 453 fltMainsA = ((float)((int) canMsg.data[0]) * 2 / 10);
sleepyhead 0:4791fa520995 454 //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]);
sleepyhead 0:4791fa520995 455 break;
sleepyhead 0:4791fa520995 456 case 0x264:
sleepyhead 0:4791fa520995 457 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]);
sleepyhead 0:4791fa520995 458 // Mit folgendem Block können alle unbekannten Nachrichten ausgegeben werden, bremst allerdings das Programm merklich ab
sleepyhead 0:4791fa520995 459 /* default:
sleepyhead 0:4791fa520995 460 TRACE("ID: 0x%x", canMsg.id);
sleepyhead 0:4791fa520995 461 TRACE(" Len: %d", canMsg.len);
sleepyhead 0:4791fa520995 462 TRACE(" Type: %d", canMsg.type);
sleepyhead 0:4791fa520995 463 TRACE(" Format: %d", canMsg.format);
sleepyhead 0:4791fa520995 464 TRACE(" Data:");
sleepyhead 0:4791fa520995 465 for (int count = 0; count < canMsg.len; count++) {
sleepyhead 0:4791fa520995 466 TRACE(" %x", canMsg.data[count]);
sleepyhead 0:4791fa520995 467 }
sleepyhead 0:4791fa520995 468 TRACE("\r\n"); */
sleepyhead 0:4791fa520995 469 }
sleepyhead 0:4791fa520995 470 }
sleepyhead 0:4791fa520995 471 }