AT&T IoT hackster.io contest entry: Carpal2
Dependencies: FXOS8700CQ Pubnub_mbed2_sync WNCInterface mbed-rtos mbed
main.cpp@0:d2425a595807, 2016-12-20 (annotated)
- Committer:
- cswiger
- Date:
- Tue Dec 20 16:44:32 2016 +0000
- Revision:
- 0:d2425a595807
- Child:
- 1:610520d32d22
AT&T IoT hackster.io contest entry Carpal2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cswiger | 0:d2425a595807 | 1 | /* ===================================================================== |
cswiger | 0:d2425a595807 | 2 | Copyright © 2016, Avnet (R) |
cswiger | 0:d2425a595807 | 3 | |
cswiger | 0:d2425a595807 | 4 | Contributors: |
cswiger | 0:d2425a595807 | 5 | * James M Flynn, www.em.avnet.com |
cswiger | 0:d2425a595807 | 6 | * Chuck Swiger |
cswiger | 0:d2425a595807 | 7 | |
cswiger | 0:d2425a595807 | 8 | Licensed under the Apache License, Version 2.0 (the "License"); |
cswiger | 0:d2425a595807 | 9 | you may not use this file except in compliance with the License. |
cswiger | 0:d2425a595807 | 10 | You may obtain a copy of the License at |
cswiger | 0:d2425a595807 | 11 | |
cswiger | 0:d2425a595807 | 12 | http://www.apache.org/licenses/LICENSE-2.0 |
cswiger | 0:d2425a595807 | 13 | |
cswiger | 0:d2425a595807 | 14 | Unless required by applicable law or agreed to in writing, |
cswiger | 0:d2425a595807 | 15 | software distributed under the License is distributed on an |
cswiger | 0:d2425a595807 | 16 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
cswiger | 0:d2425a595807 | 17 | either express or implied. See the License for the specific |
cswiger | 0:d2425a595807 | 18 | language governing permissions and limitations under the License. |
cswiger | 0:d2425a595807 | 19 | |
cswiger | 0:d2425a595807 | 20 | @file WNC_Pubnub_obd2b |
cswiger | 0:d2425a595807 | 21 | @version 1.0b |
cswiger | 0:d2425a595807 | 22 | @date Dec 2016 |
cswiger | 0:d2425a595807 | 23 | |
cswiger | 0:d2425a595807 | 24 | - This version has the AccelX,Y,Z sensor and code for GPS |
cswiger | 0:d2425a595807 | 25 | ======================================================================== */ |
cswiger | 0:d2425a595807 | 26 | |
cswiger | 0:d2425a595807 | 27 | #include "mbed.h" |
cswiger | 0:d2425a595807 | 28 | #include "WNCInterface.h" |
cswiger | 0:d2425a595807 | 29 | #include "main.h" // obd2 includes |
cswiger | 0:d2425a595807 | 30 | //#include "MODSERIAL.h" // already exists in WNCInterface |
cswiger | 0:d2425a595807 | 31 | #include "pubnub_sync.h" |
cswiger | 0:d2425a595807 | 32 | #include "sensors.h" |
cswiger | 0:d2425a595807 | 33 | #include "hardware.h" |
cswiger | 0:d2425a595807 | 34 | |
cswiger | 0:d2425a595807 | 35 | #define DEBUG |
cswiger | 0:d2425a595807 | 36 | #define MBED_PLATFORM |
cswiger | 0:d2425a595807 | 37 | |
cswiger | 0:d2425a595807 | 38 | #define CRLF "\n\r" |
cswiger | 0:d2425a595807 | 39 | |
cswiger | 0:d2425a595807 | 40 | I2C i2c(PTC11, PTC10); //SDA, SCL -- define the I2C pins being used |
cswiger | 0:d2425a595807 | 41 | |
cswiger | 0:d2425a595807 | 42 | WNCInterface wnc; |
cswiger | 0:d2425a595807 | 43 | MODSERIAL pc(USBTX,USBRX,256,256); |
cswiger | 0:d2425a595807 | 44 | MODSERIAL obd2(PTC15,PTC14,256,256); // (TX,RX,txbuffer,rxbuffer) |
cswiger | 0:d2425a595807 | 45 | // This is the Bluetooth J199 connector - pin3 DCT14 RX, pin4 DTC15 TX |
cswiger | 0:d2425a595807 | 46 | pubnub_t *pbp = pubnub_alloc(); |
cswiger | 0:d2425a595807 | 47 | |
cswiger | 0:d2425a595807 | 48 | |
cswiger | 0:d2425a595807 | 49 | DigitalOut rled(PTB19); // RED panel lamp |
cswiger | 0:d2425a595807 | 50 | DigitalOut gled(PTB18); // GREEN |
cswiger | 0:d2425a595807 | 51 | |
cswiger | 0:d2425a595807 | 52 | |
cswiger | 0:d2425a595807 | 53 | long OBDBAUD = 9600; |
cswiger | 0:d2425a595807 | 54 | long PCBAUD = 115200; |
cswiger | 0:d2425a595807 | 55 | |
cswiger | 0:d2425a595807 | 56 | K64F_Sensors_t SENSOR_DATA = |
cswiger | 0:d2425a595807 | 57 | { |
cswiger | 0:d2425a595807 | 58 | .Temperature = "0", |
cswiger | 0:d2425a595807 | 59 | .Humidity = "0", |
cswiger | 0:d2425a595807 | 60 | .AccelX = "0", |
cswiger | 0:d2425a595807 | 61 | .AccelY = "0", |
cswiger | 0:d2425a595807 | 62 | .AccelZ = "0", |
cswiger | 0:d2425a595807 | 63 | .GPS_Satellites = "0", |
cswiger | 0:d2425a595807 | 64 | .GPS_Latitude = "0", |
cswiger | 0:d2425a595807 | 65 | .GPS_Longitude = "0", |
cswiger | 0:d2425a595807 | 66 | .GPS_Altitude = "0", |
cswiger | 0:d2425a595807 | 67 | .GPS_Speed = "0", |
cswiger | 0:d2425a595807 | 68 | .GPS_Course = "0" |
cswiger | 0:d2425a595807 | 69 | }; |
cswiger | 0:d2425a595807 | 70 | |
cswiger | 0:d2425a595807 | 71 | char* itoa(int val, int base){ |
cswiger | 0:d2425a595807 | 72 | static char buf[32] = {0}; |
cswiger | 0:d2425a595807 | 73 | int i = 30; |
cswiger | 0:d2425a595807 | 74 | for(; val && i ; --i, val /= base) |
cswiger | 0:d2425a595807 | 75 | buf[i] = "0123456789abcdef"[val % base]; |
cswiger | 0:d2425a595807 | 76 | return &buf[i+1]; |
cswiger | 0:d2425a595807 | 77 | } |
cswiger | 0:d2425a595807 | 78 | |
cswiger | 0:d2425a595807 | 79 | |
cswiger | 0:d2425a595807 | 80 | //Periodic timer |
cswiger | 0:d2425a595807 | 81 | Ticker OneMsTicker; |
cswiger | 0:d2425a595807 | 82 | volatile bool bTimerExpiredFlag = false; |
cswiger | 0:d2425a595807 | 83 | int OneMsTicks = 0; |
cswiger | 0:d2425a595807 | 84 | int iTimer1Interval_ms = 1000; |
cswiger | 0:d2425a595807 | 85 | |
cswiger | 0:d2425a595807 | 86 | void OneMsFunction() |
cswiger | 0:d2425a595807 | 87 | { |
cswiger | 0:d2425a595807 | 88 | OneMsTicks++; |
cswiger | 0:d2425a595807 | 89 | if ((OneMsTicks % iTimer1Interval_ms) == 0) |
cswiger | 0:d2425a595807 | 90 | { |
cswiger | 0:d2425a595807 | 91 | bTimerExpiredFlag = true; |
cswiger | 0:d2425a595807 | 92 | } |
cswiger | 0:d2425a595807 | 93 | } //OneMsFunction() |
cswiger | 0:d2425a595807 | 94 | |
cswiger | 0:d2425a595807 | 95 | |
cswiger | 0:d2425a595807 | 96 | void GetDTC(void) |
cswiger | 0:d2425a595807 | 97 | { |
cswiger | 0:d2425a595807 | 98 | char jsonreply[140] = {'\0'}; |
cswiger | 0:d2425a595807 | 99 | dtc_read(); // populate the DTC struct if any |
cswiger | 0:d2425a595807 | 100 | if(has_dtc) { |
cswiger | 0:d2425a595807 | 101 | strcpy(jsonreply,"{\""); |
cswiger | 0:d2425a595807 | 102 | for (int i=0; i<MAX_DTC_READ; i++) { |
cswiger | 0:d2425a595807 | 103 | strcat(jsonreply,itoa((i+1),10)); |
cswiger | 0:d2425a595807 | 104 | strcat(jsonreply,"\":\""); |
cswiger | 0:d2425a595807 | 105 | if(i!=MAX_DTC_READ-1) { // last one? |
cswiger | 0:d2425a595807 | 106 | strcat(jsonreply,DTC[i].code); |
cswiger | 0:d2425a595807 | 107 | strcat(jsonreply,"\",\""); |
cswiger | 0:d2425a595807 | 108 | } else { |
cswiger | 0:d2425a595807 | 109 | strcat(jsonreply,DTC[i].code); |
cswiger | 0:d2425a595807 | 110 | strcat(jsonreply,"\"}"); |
cswiger | 0:d2425a595807 | 111 | } |
cswiger | 0:d2425a595807 | 112 | } |
cswiger | 0:d2425a595807 | 113 | } else { |
cswiger | 0:d2425a595807 | 114 | strcpy(jsonreply,"{\"1\":\"none\"}"); |
cswiger | 0:d2425a595807 | 115 | } |
cswiger | 0:d2425a595807 | 116 | pubnub_res rslt = pubnub_publish(pbp, "carpal2", jsonreply); |
cswiger | 0:d2425a595807 | 117 | if (rslt != PNR_STARTED) |
cswiger | 0:d2425a595807 | 118 | pc.printf("Failed to start publishing, rslt=%d"CRLF, rslt); |
cswiger | 0:d2425a595807 | 119 | else { |
cswiger | 0:d2425a595807 | 120 | rslt = pubnub_await(pbp); |
cswiger | 0:d2425a595807 | 121 | if (rslt != PNR_OK) |
cswiger | 0:d2425a595807 | 122 | pc.printf("Failed to finished publishing, rslt=%d"CRLF, rslt); |
cswiger | 0:d2425a595807 | 123 | else { |
cswiger | 0:d2425a595807 | 124 | pc.printf("Published! Response from Pubnub: %s"CRLF, pubnub_last_publish_result(pbp)); |
cswiger | 0:d2425a595807 | 125 | } |
cswiger | 0:d2425a595807 | 126 | } |
cswiger | 0:d2425a595807 | 127 | |
cswiger | 0:d2425a595807 | 128 | } // GetDTC |
cswiger | 0:d2425a595807 | 129 | |
cswiger | 0:d2425a595807 | 130 | bool parse_JSON(char const* json_string) |
cswiger | 0:d2425a595807 | 131 | { |
cswiger | 0:d2425a595807 | 132 | char const* beginquote; |
cswiger | 0:d2425a595807 | 133 | char token[] = "get:"; |
cswiger | 0:d2425a595807 | 134 | beginquote = strstr(json_string, token ); |
cswiger | 0:d2425a595807 | 135 | if ((beginquote != 0)) |
cswiger | 0:d2425a595807 | 136 | { |
cswiger | 0:d2425a595807 | 137 | char getreq = beginquote[strlen(token)]; // this only gets a single letter at the position after 'get:' |
cswiger | 0:d2425a595807 | 138 | PRINTF(GRN "get Found : %c" DEF "\r\n", getreq); |
cswiger | 0:d2425a595807 | 139 | switch(getreq) |
cswiger | 0:d2425a595807 | 140 | { |
cswiger | 0:d2425a595807 | 141 | case 'd': |
cswiger | 0:d2425a595807 | 142 | { // dtc |
cswiger | 0:d2425a595807 | 143 | GetDTC(); |
cswiger | 0:d2425a595807 | 144 | break; |
cswiger | 0:d2425a595807 | 145 | } |
cswiger | 0:d2425a595807 | 146 | default: |
cswiger | 0:d2425a595807 | 147 | { |
cswiger | 0:d2425a595807 | 148 | break; |
cswiger | 0:d2425a595807 | 149 | } |
cswiger | 0:d2425a595807 | 150 | } //switch(getreq) |
cswiger | 0:d2425a595807 | 151 | return true; |
cswiger | 0:d2425a595807 | 152 | } |
cswiger | 0:d2425a595807 | 153 | else |
cswiger | 0:d2425a595807 | 154 | { |
cswiger | 0:d2425a595807 | 155 | return false; |
cswiger | 0:d2425a595807 | 156 | } |
cswiger | 0:d2425a595807 | 157 | } //parse_JSON |
cswiger | 0:d2425a595807 | 158 | |
cswiger | 0:d2425a595807 | 159 | |
cswiger | 0:d2425a595807 | 160 | int main() |
cswiger | 0:d2425a595807 | 161 | { |
cswiger | 0:d2425a595807 | 162 | char data[256]; |
cswiger | 0:d2425a595807 | 163 | int ret; |
cswiger | 0:d2425a595807 | 164 | |
cswiger | 0:d2425a595807 | 165 | long vehicle_speed = 0; |
cswiger | 0:d2425a595807 | 166 | long engine_rpm = 0; |
cswiger | 0:d2425a595807 | 167 | long fuel_status = 0; |
cswiger | 0:d2425a595807 | 168 | long engine_load = 0; |
cswiger | 0:d2425a595807 | 169 | long coolant_temp = 0; |
cswiger | 0:d2425a595807 | 170 | long stft_b1 = 0; |
cswiger | 0:d2425a595807 | 171 | long ltft_b1 = 0; |
cswiger | 0:d2425a595807 | 172 | long stft_b2 = 0; |
cswiger | 0:d2425a595807 | 173 | long ltft_b2 = 0; |
cswiger | 0:d2425a595807 | 174 | long timing_adv = 0; |
cswiger | 0:d2425a595807 | 175 | long int_air_temp = 0; |
cswiger | 0:d2425a595807 | 176 | long maf_air_flow = 0; |
cswiger | 0:d2425a595807 | 177 | long throttle_pos = 0; |
cswiger | 0:d2425a595807 | 178 | long b1s2_o2_v = 0; |
cswiger | 0:d2425a595807 | 179 | |
cswiger | 0:d2425a595807 | 180 | |
cswiger | 0:d2425a595807 | 181 | rled = 1; // red panel lamp while initializing |
cswiger | 0:d2425a595807 | 182 | gled = 0; |
cswiger | 0:d2425a595807 | 183 | |
cswiger | 0:d2425a595807 | 184 | // Configure PC BAUD |
cswiger | 0:d2425a595807 | 185 | pc.baud(PCBAUD); |
cswiger | 0:d2425a595807 | 186 | |
cswiger | 0:d2425a595807 | 187 | //debug |
cswiger | 0:d2425a595807 | 188 | wait(10); // wait for terminal connected |
cswiger | 0:d2425a595807 | 189 | pc.printf(WHT "STARTING WNCInterface PubNub Test" CRLF); |
cswiger | 0:d2425a595807 | 190 | |
cswiger | 0:d2425a595807 | 191 | //Create a 1ms timer tick function: |
cswiger | 0:d2425a595807 | 192 | iTimer1Interval_ms = SENSOR_UPDATE_INTERVAL_MS; |
cswiger | 0:d2425a595807 | 193 | OneMsTicker.attach(OneMsFunction, 0.001f) ; |
cswiger | 0:d2425a595807 | 194 | |
cswiger | 0:d2425a595807 | 195 | //Initialize the I2C sensors that are present |
cswiger | 0:d2425a595807 | 196 | sensors_init(); |
cswiger | 0:d2425a595807 | 197 | read_sensors(); |
cswiger | 0:d2425a595807 | 198 | |
cswiger | 0:d2425a595807 | 199 | // init and connect the WNCInterface cell modem |
cswiger | 0:d2425a595807 | 200 | pc.printf(DEF "init() returned 0x%04X" CRLF, wnc.init(NULL,&pc)); |
cswiger | 0:d2425a595807 | 201 | ret = wnc.connect(); |
cswiger | 0:d2425a595807 | 202 | wnc.doDebug(0); // if you want a LOT of AT commands logged (1) |
cswiger | 0:d2425a595807 | 203 | |
cswiger | 0:d2425a595807 | 204 | pc.printf("IP Address: %s " CRLF, wnc.getIPAddress()); |
cswiger | 0:d2425a595807 | 205 | pc.printf("-------------------------------------" CRLF); |
cswiger | 0:d2425a595807 | 206 | pc.printf("starting PubNub sync..." CRLF); |
cswiger | 0:d2425a595807 | 207 | |
cswiger | 0:d2425a595807 | 208 | // create the Pubnub interface |
cswiger | 0:d2425a595807 | 209 | pubnub_init(pbp, "pub-c-xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb", "sub-c-xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb"); |
cswiger | 0:d2425a595807 | 210 | |
cswiger | 0:d2425a595807 | 211 | // Setup STN1110 UART |
cswiger | 0:d2425a595807 | 212 | pc.printf("Configuring OBD UART\r\n"); |
cswiger | 0:d2425a595807 | 213 | Init(); |
cswiger | 0:d2425a595807 | 214 | pc.printf("Configure done..\r\n"); |
cswiger | 0:d2425a595807 | 215 | while(1) { |
cswiger | 0:d2425a595807 | 216 | if (bTimerExpiredFlag) |
cswiger | 0:d2425a595807 | 217 | { |
cswiger | 0:d2425a595807 | 218 | bTimerExpiredFlag = false; |
cswiger | 0:d2425a595807 | 219 | rled = 1; |
cswiger | 0:d2425a595807 | 220 | pc.printf("Refresh...\n\r"); |
cswiger | 0:d2425a595807 | 221 | Refresh(); |
cswiger | 0:d2425a595807 | 222 | pc.printf("Get coolant temp...\n\r"); |
cswiger | 0:d2425a595807 | 223 | get_pid(COOLANT_TEMP,&coolant_temp); |
cswiger | 0:d2425a595807 | 224 | pc.printf("Get rpm...\n\r"); |
cswiger | 0:d2425a595807 | 225 | get_pid(ENGINE_RPM,&engine_rpm); |
cswiger | 0:d2425a595807 | 226 | get_pid(LOAD_VALUE,&engine_load); |
cswiger | 0:d2425a595807 | 227 | get_pid(VEHICLE_SPEED,&vehicle_speed); |
cswiger | 0:d2425a595807 | 228 | pc.printf("Coolant: %d\n\rRPM: %d\n\r",coolant_temp,engine_rpm); |
cswiger | 0:d2425a595807 | 229 | // short keys to keep air co$t$ down |
cswiger | 0:d2425a595807 | 230 | // oc or os ol - obd2 coolant temp, rpm, speed, load |
cswiger | 0:d2425a595807 | 231 | // la lo - gps latitude, longitude |
cswiger | 0:d2425a595807 | 232 | // ax ay - accelarometer X,Y |
cswiger | 0:d2425a595807 | 233 | pc.printf("Read sensors\n\r"); |
cswiger | 0:d2425a595807 | 234 | read_sensors(); |
cswiger | 0:d2425a595807 | 235 | snprintf(data,256,"{\"la\":%s,\"lo\":%s,\"ax\":%s,\"ay\":%s,\"oc\":%d,\"or\":%d,\"ol\":%d,\"os\":%d}",SENSOR_DATA.GPS_Latitude,SENSOR_DATA.GPS_Longitude,SENSOR_DATA.AccelX,SENSOR_DATA.AccelY,coolant_temp,engine_rpm,engine_load,vehicle_speed); |
cswiger | 0:d2425a595807 | 236 | // publish json and wait for result |
cswiger | 0:d2425a595807 | 237 | pubnub_res rslt = pubnub_publish(pbp, "carpal2", data); |
cswiger | 0:d2425a595807 | 238 | if (rslt != PNR_STARTED) { |
cswiger | 0:d2425a595807 | 239 | pc.printf("Failed to start publishing, rslt=%d"CRLF, rslt); |
cswiger | 0:d2425a595807 | 240 | rled = 1; |
cswiger | 0:d2425a595807 | 241 | gled = 0; |
cswiger | 0:d2425a595807 | 242 | } else { |
cswiger | 0:d2425a595807 | 243 | rslt = pubnub_await(pbp); |
cswiger | 0:d2425a595807 | 244 | if (rslt != PNR_OK) { |
cswiger | 0:d2425a595807 | 245 | pc.printf("Failed to finished publishing, rslt=%d"CRLF, rslt); |
cswiger | 0:d2425a595807 | 246 | rled = 1; |
cswiger | 0:d2425a595807 | 247 | gled = 0; |
cswiger | 0:d2425a595807 | 248 | } else { |
cswiger | 0:d2425a595807 | 249 | pc.printf("Published! Response from Pubnub: %s"CRLF, pubnub_last_publish_result(pbp)); |
cswiger | 0:d2425a595807 | 250 | rled = 0; |
cswiger | 0:d2425a595807 | 251 | gled = 1; |
cswiger | 0:d2425a595807 | 252 | } |
cswiger | 0:d2425a595807 | 253 | } |
cswiger | 0:d2425a595807 | 254 | |
cswiger | 0:d2425a595807 | 255 | rslt = pubnub_subscribe(pbp, "carpal2", 0); |
cswiger | 0:d2425a595807 | 256 | if (rslt != PNR_STARTED) { |
cswiger | 0:d2425a595807 | 257 | pc.printf("Failed to start subscribing, rslt=%d"CRLF, rslt); |
cswiger | 0:d2425a595807 | 258 | rled = 1; |
cswiger | 0:d2425a595807 | 259 | gled = 0; |
cswiger | 0:d2425a595807 | 260 | } else { |
cswiger | 0:d2425a595807 | 261 | rslt = pubnub_await(pbp); |
cswiger | 0:d2425a595807 | 262 | if (rslt != PNR_OK) { |
cswiger | 0:d2425a595807 | 263 | pc.printf("Failed to finished subscribing, rslt=%d"CRLF, rslt);\ |
cswiger | 0:d2425a595807 | 264 | rled = 1; |
cswiger | 0:d2425a595807 | 265 | gled = 0; |
cswiger | 0:d2425a595807 | 266 | } else { |
cswiger | 0:d2425a595807 | 267 | pc.printf("Subscribed! Received messages follow:"CRLF); |
cswiger | 0:d2425a595807 | 268 | while (char const *msg = pubnub_get(pbp)) { |
cswiger | 0:d2425a595807 | 269 | pc.printf("subscribe got: %s"CRLF, msg); |
cswiger | 0:d2425a595807 | 270 | parse_JSON(msg); |
cswiger | 0:d2425a595807 | 271 | } |
cswiger | 0:d2425a595807 | 272 | } |
cswiger | 0:d2425a595807 | 273 | rled = 0; |
cswiger | 0:d2425a595807 | 274 | gled = 1; |
cswiger | 0:d2425a595807 | 275 | } // subscribe result |
cswiger | 0:d2425a595807 | 276 | } // end timer expired |
cswiger | 0:d2425a595807 | 277 | } // end infinite loop |
cswiger | 0:d2425a595807 | 278 | } |
cswiger | 0:d2425a595807 | 279 | |
cswiger | 0:d2425a595807 | 280 | char pid_reslen[] = |
cswiger | 0:d2425a595807 | 281 | { |
cswiger | 0:d2425a595807 | 282 | // pid 0x00 to 0x1F |
cswiger | 0:d2425a595807 | 283 | 4,4,2,2,1,1,1,1,1,1,1,1,2,1,1,1, |
cswiger | 0:d2425a595807 | 284 | 2,1,1,1,2,2,2,2,2,2,2,2,1,1,1,4, |
cswiger | 0:d2425a595807 | 285 | |
cswiger | 0:d2425a595807 | 286 | // pid 0x20 to 0x3F |
cswiger | 0:d2425a595807 | 287 | 4,2,2,2,4,4,4,4,4,4,4,4,1,1,1,1, |
cswiger | 0:d2425a595807 | 288 | 1,2,2,1,4,4,4,4,4,4,4,4,2,2,2,2, |
cswiger | 0:d2425a595807 | 289 | |
cswiger | 0:d2425a595807 | 290 | // pid 0x40 to 0x4E |
cswiger | 0:d2425a595807 | 291 | 4,8,2,2,2,1,1,1,1,1,1,1,1,2,2 |
cswiger | 0:d2425a595807 | 292 | }; |
cswiger | 0:d2425a595807 | 293 | |
cswiger | 0:d2425a595807 | 294 | |
cswiger | 0:d2425a595807 | 295 | |
cswiger | 0:d2425a595807 | 296 | /*********************** |
cswiger | 0:d2425a595807 | 297 | Init |
cswiger | 0:d2425a595807 | 298 | ***********************/ |
cswiger | 0:d2425a595807 | 299 | char Init() |
cswiger | 0:d2425a595807 | 300 | { |
cswiger | 0:d2425a595807 | 301 | obd2.baud(OBDBAUD); |
cswiger | 0:d2425a595807 | 302 | char str[STRLEN]; |
cswiger | 0:d2425a595807 | 303 | // reset |
cswiger | 0:d2425a595807 | 304 | stn1110_command(str, "ATWS\r"); |
cswiger | 0:d2425a595807 | 305 | // turn echo off |
cswiger | 0:d2425a595807 | 306 | stn1110_command(str, "ATE0\r"); |
cswiger | 0:d2425a595807 | 307 | |
cswiger | 0:d2425a595807 | 308 | // send 01 00 until we are connected |
cswiger | 0:d2425a595807 | 309 | do |
cswiger | 0:d2425a595807 | 310 | { |
cswiger | 0:d2425a595807 | 311 | stn1110_command(str, "0100\r"); |
cswiger | 0:d2425a595807 | 312 | wait(1); // might want to change this to return non-zero for engine off or something, otherwise it's stuck here |
cswiger | 0:d2425a595807 | 313 | } |
cswiger | 0:d2425a595807 | 314 | while(stn1110_check_response("0100", str)!=0); |
cswiger | 0:d2425a595807 | 315 | |
cswiger | 0:d2425a595807 | 316 | // ask protocol |
cswiger | 0:d2425a595807 | 317 | stn1110_command(str, "ATDPN\r"); |
cswiger | 0:d2425a595807 | 318 | |
cswiger | 0:d2425a595807 | 319 | check_supported_pids(); |
cswiger | 0:d2425a595807 | 320 | |
cswiger | 0:d2425a595807 | 321 | return 0; |
cswiger | 0:d2425a595807 | 322 | } |
cswiger | 0:d2425a595807 | 323 | |
cswiger | 0:d2425a595807 | 324 | char stn1110_read(char *str, char size) |
cswiger | 0:d2425a595807 | 325 | { |
cswiger | 0:d2425a595807 | 326 | int b; |
cswiger | 0:d2425a595807 | 327 | char i=0; |
cswiger | 0:d2425a595807 | 328 | |
cswiger | 0:d2425a595807 | 329 | // wait for something on com port |
cswiger | 0:d2425a595807 | 330 | while((b=obd2.getc())!=PROMPT && i<size) // this blocks! Arduino Serial.read would return -1 |
cswiger | 0:d2425a595807 | 331 | { |
cswiger | 0:d2425a595807 | 332 | if(b>=' ') |
cswiger | 0:d2425a595807 | 333 | str[i++]=b; |
cswiger | 0:d2425a595807 | 334 | } |
cswiger | 0:d2425a595807 | 335 | |
cswiger | 0:d2425a595807 | 336 | if(i!=size) // we got a prompt |
cswiger | 0:d2425a595807 | 337 | { |
cswiger | 0:d2425a595807 | 338 | str[i]=NUL; // replace CR by NUL |
cswiger | 0:d2425a595807 | 339 | return PROMPT; |
cswiger | 0:d2425a595807 | 340 | } |
cswiger | 0:d2425a595807 | 341 | else |
cswiger | 0:d2425a595807 | 342 | return DATA; |
cswiger | 0:d2425a595807 | 343 | } |
cswiger | 0:d2425a595807 | 344 | |
cswiger | 0:d2425a595807 | 345 | void stn1110_write(char *str) |
cswiger | 0:d2425a595807 | 346 | { |
cswiger | 0:d2425a595807 | 347 | while(*str!=NUL) |
cswiger | 0:d2425a595807 | 348 | obd2.putc(*str++); |
cswiger | 0:d2425a595807 | 349 | } |
cswiger | 0:d2425a595807 | 350 | |
cswiger | 0:d2425a595807 | 351 | char stn1110_check_response(const char *cmd, char *str) |
cswiger | 0:d2425a595807 | 352 | { |
cswiger | 0:d2425a595807 | 353 | // cmd is something like "010D" |
cswiger | 0:d2425a595807 | 354 | // str should be "41 0D blabla" |
cswiger | 0:d2425a595807 | 355 | if(cmd[0]+4 != str[0] |
cswiger | 0:d2425a595807 | 356 | || cmd[1]!=str[1] |
cswiger | 0:d2425a595807 | 357 | || cmd[2]!=str[3] |
cswiger | 0:d2425a595807 | 358 | || cmd[3]!=str[4]) |
cswiger | 0:d2425a595807 | 359 | return 1; |
cswiger | 0:d2425a595807 | 360 | |
cswiger | 0:d2425a595807 | 361 | return 0; // no error |
cswiger | 0:d2425a595807 | 362 | } |
cswiger | 0:d2425a595807 | 363 | |
cswiger | 0:d2425a595807 | 364 | char stn1110_compact_response(char *buf, char *str) |
cswiger | 0:d2425a595807 | 365 | { |
cswiger | 0:d2425a595807 | 366 | char i=0; |
cswiger | 0:d2425a595807 | 367 | |
cswiger | 0:d2425a595807 | 368 | str+=6; |
cswiger | 0:d2425a595807 | 369 | while(*str!=NUL) |
cswiger | 0:d2425a595807 | 370 | buf[i++]=strtoul(str, &str, 16); // 16 = hex |
cswiger | 0:d2425a595807 | 371 | |
cswiger | 0:d2425a595807 | 372 | return i; |
cswiger | 0:d2425a595807 | 373 | } |
cswiger | 0:d2425a595807 | 374 | |
cswiger | 0:d2425a595807 | 375 | char stn1110_command(char *str, char *cmd) |
cswiger | 0:d2425a595807 | 376 | { |
cswiger | 0:d2425a595807 | 377 | strcpy(str, cmd); |
cswiger | 0:d2425a595807 | 378 | stn1110_write(str); |
cswiger | 0:d2425a595807 | 379 | return stn1110_read(str, STRLEN); |
cswiger | 0:d2425a595807 | 380 | } |
cswiger | 0:d2425a595807 | 381 | |
cswiger | 0:d2425a595807 | 382 | void check_supported_pids(void) |
cswiger | 0:d2425a595807 | 383 | { |
cswiger | 0:d2425a595807 | 384 | |
cswiger | 0:d2425a595807 | 385 | // on some ECU first PID read attemts some time fails, changed to 3 attempts |
cswiger | 0:d2425a595807 | 386 | for (char i=0; i<3; i++) |
cswiger | 0:d2425a595807 | 387 | { |
cswiger | 0:d2425a595807 | 388 | pid01to20_support = (get_pid(PID_SUPPORT00, &tempLong)) ? tempLong : 0; |
cswiger | 0:d2425a595807 | 389 | if (pid01to20_support) |
cswiger | 0:d2425a595807 | 390 | break; |
cswiger | 0:d2425a595807 | 391 | } |
cswiger | 0:d2425a595807 | 392 | |
cswiger | 0:d2425a595807 | 393 | if(is_pid_supported(PID_SUPPORT20)) |
cswiger | 0:d2425a595807 | 394 | if (get_pid(PID_SUPPORT20, &tempLong)) |
cswiger | 0:d2425a595807 | 395 | pid21to40_support = tempLong; |
cswiger | 0:d2425a595807 | 396 | |
cswiger | 0:d2425a595807 | 397 | if(is_pid_supported(PID_SUPPORT40)) |
cswiger | 0:d2425a595807 | 398 | if (get_pid(PID_SUPPORT40, &tempLong)) |
cswiger | 0:d2425a595807 | 399 | pid41to60_support = tempLong; |
cswiger | 0:d2425a595807 | 400 | } |
cswiger | 0:d2425a595807 | 401 | |
cswiger | 0:d2425a595807 | 402 | char is_pid_supported(char pid) |
cswiger | 0:d2425a595807 | 403 | { |
cswiger | 0:d2425a595807 | 404 | if(pid==0) |
cswiger | 0:d2425a595807 | 405 | return 1; |
cswiger | 0:d2425a595807 | 406 | else |
cswiger | 0:d2425a595807 | 407 | if(pid<=0x20) |
cswiger | 0:d2425a595807 | 408 | { |
cswiger | 0:d2425a595807 | 409 | if(1L<<(char)(0x20-pid) & pid01to20_support) |
cswiger | 0:d2425a595807 | 410 | return 1; |
cswiger | 0:d2425a595807 | 411 | } |
cswiger | 0:d2425a595807 | 412 | else |
cswiger | 0:d2425a595807 | 413 | if(pid<=0x40) |
cswiger | 0:d2425a595807 | 414 | { |
cswiger | 0:d2425a595807 | 415 | if(1L<<(char)(0x40-pid) & pid21to40_support) |
cswiger | 0:d2425a595807 | 416 | return 1; |
cswiger | 0:d2425a595807 | 417 | } |
cswiger | 0:d2425a595807 | 418 | else |
cswiger | 0:d2425a595807 | 419 | if(pid<=0x60) |
cswiger | 0:d2425a595807 | 420 | { |
cswiger | 0:d2425a595807 | 421 | if(1L<<(char)(0x60-pid) & pid41to60_support) |
cswiger | 0:d2425a595807 | 422 | return 1; |
cswiger | 0:d2425a595807 | 423 | } |
cswiger | 0:d2425a595807 | 424 | |
cswiger | 0:d2425a595807 | 425 | return 0; |
cswiger | 0:d2425a595807 | 426 | } |
cswiger | 0:d2425a595807 | 427 | |
cswiger | 0:d2425a595807 | 428 | |
cswiger | 0:d2425a595807 | 429 | char get_pid(char pid, long *ret) |
cswiger | 0:d2425a595807 | 430 | { |
cswiger | 0:d2425a595807 | 431 | char cmd_str[6]; // to send to STN1110 |
cswiger | 0:d2425a595807 | 432 | char str[STRLEN]; // to receive from STN1110 |
cswiger | 0:d2425a595807 | 433 | char i; |
cswiger | 0:d2425a595807 | 434 | char buf[10]; // to receive the result |
cswiger | 0:d2425a595807 | 435 | char reslen; |
cswiger | 0:d2425a595807 | 436 | |
cswiger | 0:d2425a595807 | 437 | // check if PID is supported |
cswiger | 0:d2425a595807 | 438 | if(!is_pid_supported(pid)) |
cswiger | 0:d2425a595807 | 439 | { |
cswiger | 0:d2425a595807 | 440 | // Not Supported |
cswiger | 0:d2425a595807 | 441 | return 0; |
cswiger | 0:d2425a595807 | 442 | } |
cswiger | 0:d2425a595807 | 443 | |
cswiger | 0:d2425a595807 | 444 | // receive length depends on pid |
cswiger | 0:d2425a595807 | 445 | reslen=pid_reslen[pid]; |
cswiger | 0:d2425a595807 | 446 | |
cswiger | 0:d2425a595807 | 447 | sprintf(cmd_str, "01%02X\r", pid); |
cswiger | 0:d2425a595807 | 448 | stn1110_write(cmd_str); |
cswiger | 0:d2425a595807 | 449 | stn1110_read(str, STRLEN); |
cswiger | 0:d2425a595807 | 450 | |
cswiger | 0:d2425a595807 | 451 | if(stn1110_check_response(cmd_str, str)!=0) |
cswiger | 0:d2425a595807 | 452 | { |
cswiger | 0:d2425a595807 | 453 | return 0; |
cswiger | 0:d2425a595807 | 454 | } |
cswiger | 0:d2425a595807 | 455 | stn1110_compact_response(buf, str); |
cswiger | 0:d2425a595807 | 456 | |
cswiger | 0:d2425a595807 | 457 | *ret=buf[0]*256U+buf[1]; |
cswiger | 0:d2425a595807 | 458 | |
cswiger | 0:d2425a595807 | 459 | // Calculate different for each PID |
cswiger | 0:d2425a595807 | 460 | switch(pid) |
cswiger | 0:d2425a595807 | 461 | { |
cswiger | 0:d2425a595807 | 462 | case ENGINE_RPM: |
cswiger | 0:d2425a595807 | 463 | *ret=*ret/4U; |
cswiger | 0:d2425a595807 | 464 | break; |
cswiger | 0:d2425a595807 | 465 | case MAF_AIR_FLOW: |
cswiger | 0:d2425a595807 | 466 | break; |
cswiger | 0:d2425a595807 | 467 | case VEHICLE_SPEED: |
cswiger | 0:d2425a595807 | 468 | *ret=buf[0]; |
cswiger | 0:d2425a595807 | 469 | break; |
cswiger | 0:d2425a595807 | 470 | case FUEL_STATUS: |
cswiger | 0:d2425a595807 | 471 | case LOAD_VALUE: |
cswiger | 0:d2425a595807 | 472 | case THROTTLE_POS: |
cswiger | 0:d2425a595807 | 473 | case REL_THR_POS: |
cswiger | 0:d2425a595807 | 474 | case EGR: |
cswiger | 0:d2425a595807 | 475 | case EGR_ERROR: |
cswiger | 0:d2425a595807 | 476 | case FUEL_LEVEL: |
cswiger | 0:d2425a595807 | 477 | case ABS_THR_POS_B: |
cswiger | 0:d2425a595807 | 478 | case ABS_THR_POS_C: |
cswiger | 0:d2425a595807 | 479 | case ACCEL_PEDAL_D: |
cswiger | 0:d2425a595807 | 480 | case ACCEL_PEDAL_E: |
cswiger | 0:d2425a595807 | 481 | case ACCEL_PEDAL_F: |
cswiger | 0:d2425a595807 | 482 | case CMD_THR_ACTU: |
cswiger | 0:d2425a595807 | 483 | *ret=(buf[0]*100U)/255U; |
cswiger | 0:d2425a595807 | 484 | break; |
cswiger | 0:d2425a595807 | 485 | case ABS_LOAD_VAL: |
cswiger | 0:d2425a595807 | 486 | *ret=(*ret*100)/255; |
cswiger | 0:d2425a595807 | 487 | break; |
cswiger | 0:d2425a595807 | 488 | case B1S1_O2_V: |
cswiger | 0:d2425a595807 | 489 | case B1S2_O2_V: |
cswiger | 0:d2425a595807 | 490 | case B1S3_O2_V: |
cswiger | 0:d2425a595807 | 491 | case B1S4_O2_V: |
cswiger | 0:d2425a595807 | 492 | case B2S1_O2_V: |
cswiger | 0:d2425a595807 | 493 | case B2S2_O2_V: |
cswiger | 0:d2425a595807 | 494 | case B2S3_O2_V: |
cswiger | 0:d2425a595807 | 495 | case B2S4_O2_V: |
cswiger | 0:d2425a595807 | 496 | case O2S1_WR_V: |
cswiger | 0:d2425a595807 | 497 | case O2S2_WR_V: |
cswiger | 0:d2425a595807 | 498 | case O2S3_WR_V: |
cswiger | 0:d2425a595807 | 499 | case O2S4_WR_V: |
cswiger | 0:d2425a595807 | 500 | case O2S5_WR_V: |
cswiger | 0:d2425a595807 | 501 | case O2S6_WR_V: |
cswiger | 0:d2425a595807 | 502 | case O2S7_WR_V: |
cswiger | 0:d2425a595807 | 503 | case O2S8_WR_V: |
cswiger | 0:d2425a595807 | 504 | case O2S1_WR_C: |
cswiger | 0:d2425a595807 | 505 | case O2S2_WR_C: |
cswiger | 0:d2425a595807 | 506 | case O2S3_WR_C: |
cswiger | 0:d2425a595807 | 507 | case O2S4_WR_C: |
cswiger | 0:d2425a595807 | 508 | case O2S5_WR_C: |
cswiger | 0:d2425a595807 | 509 | case O2S6_WR_C: |
cswiger | 0:d2425a595807 | 510 | case O2S7_WR_C: |
cswiger | 0:d2425a595807 | 511 | case O2S8_WR_C: |
cswiger | 0:d2425a595807 | 512 | case CMD_EQUIV_R: |
cswiger | 0:d2425a595807 | 513 | case DIST_MIL_ON: |
cswiger | 0:d2425a595807 | 514 | case DIST_MIL_CLR: |
cswiger | 0:d2425a595807 | 515 | case TIME_MIL_ON: |
cswiger | 0:d2425a595807 | 516 | case TIME_MIL_CLR: |
cswiger | 0:d2425a595807 | 517 | case INT_AIR_TEMP: |
cswiger | 0:d2425a595807 | 518 | case AMBIENT_TEMP: |
cswiger | 0:d2425a595807 | 519 | case CAT_TEMP_B1S1: |
cswiger | 0:d2425a595807 | 520 | case CAT_TEMP_B2S1: |
cswiger | 0:d2425a595807 | 521 | case CAT_TEMP_B1S2: |
cswiger | 0:d2425a595807 | 522 | case CAT_TEMP_B2S2: |
cswiger | 0:d2425a595807 | 523 | case STFT_BANK1: |
cswiger | 0:d2425a595807 | 524 | case LTFT_BANK1: |
cswiger | 0:d2425a595807 | 525 | case STFT_BANK2: |
cswiger | 0:d2425a595807 | 526 | case LTFT_BANK2: |
cswiger | 0:d2425a595807 | 527 | case FUEL_PRESSURE: |
cswiger | 0:d2425a595807 | 528 | case MAN_PRESSURE: |
cswiger | 0:d2425a595807 | 529 | case BARO_PRESSURE: |
cswiger | 0:d2425a595807 | 530 | *ret=buf[0]; |
cswiger | 0:d2425a595807 | 531 | if(pid==FUEL_PRESSURE) |
cswiger | 0:d2425a595807 | 532 | *ret*=3U; |
cswiger | 0:d2425a595807 | 533 | break; |
cswiger | 0:d2425a595807 | 534 | case COOLANT_TEMP: |
cswiger | 0:d2425a595807 | 535 | *ret=buf[0]-40U; |
cswiger | 0:d2425a595807 | 536 | break; |
cswiger | 0:d2425a595807 | 537 | case EVAP_PRESSURE: |
cswiger | 0:d2425a595807 | 538 | *ret=((int)buf[0]*256+buf[1])/4; |
cswiger | 0:d2425a595807 | 539 | break; |
cswiger | 0:d2425a595807 | 540 | case TIMING_ADV: |
cswiger | 0:d2425a595807 | 541 | *ret=(buf[0]/2)-64; |
cswiger | 0:d2425a595807 | 542 | break; |
cswiger | 0:d2425a595807 | 543 | case CTRL_MOD_V: |
cswiger | 0:d2425a595807 | 544 | break; |
cswiger | 0:d2425a595807 | 545 | case RUNTIME_START: |
cswiger | 0:d2425a595807 | 546 | break; |
cswiger | 0:d2425a595807 | 547 | case OBD_STD: |
cswiger | 0:d2425a595807 | 548 | *ret=buf[0]; |
cswiger | 0:d2425a595807 | 549 | break; |
cswiger | 0:d2425a595807 | 550 | default: |
cswiger | 0:d2425a595807 | 551 | *ret=0; |
cswiger | 0:d2425a595807 | 552 | for(i=0; i<reslen; i++) |
cswiger | 0:d2425a595807 | 553 | { |
cswiger | 0:d2425a595807 | 554 | *ret*=256L; |
cswiger | 0:d2425a595807 | 555 | *ret+=buf[i]; |
cswiger | 0:d2425a595807 | 556 | } |
cswiger | 0:d2425a595807 | 557 | break; |
cswiger | 0:d2425a595807 | 558 | } |
cswiger | 0:d2425a595807 | 559 | |
cswiger | 0:d2425a595807 | 560 | return 1; |
cswiger | 0:d2425a595807 | 561 | } |
cswiger | 0:d2425a595807 | 562 | |
cswiger | 0:d2425a595807 | 563 | |
cswiger | 0:d2425a595807 | 564 | char verifyECUAlive() |
cswiger | 0:d2425a595807 | 565 | { |
cswiger | 0:d2425a595807 | 566 | char cmd_str[6]; |
cswiger | 0:d2425a595807 | 567 | char str[STRLEN]; |
cswiger | 0:d2425a595807 | 568 | sprintf(cmd_str, "01%02X\r", ENGINE_RPM); |
cswiger | 0:d2425a595807 | 569 | stn1110_write(cmd_str); |
cswiger | 0:d2425a595807 | 570 | stn1110_read(str, STRLEN); |
cswiger | 0:d2425a595807 | 571 | |
cswiger | 0:d2425a595807 | 572 | if(stn1110_check_response(cmd_str, str) == 0) |
cswiger | 0:d2425a595807 | 573 | { |
cswiger | 0:d2425a595807 | 574 | return 1; |
cswiger | 0:d2425a595807 | 575 | } |
cswiger | 0:d2425a595807 | 576 | else |
cswiger | 0:d2425a595807 | 577 | { |
cswiger | 0:d2425a595807 | 578 | return 0; |
cswiger | 0:d2425a595807 | 579 | } |
cswiger | 0:d2425a595807 | 580 | } |
cswiger | 0:d2425a595807 | 581 | |
cswiger | 0:d2425a595807 | 582 | |
cswiger | 0:d2425a595807 | 583 | char Refresh() |
cswiger | 0:d2425a595807 | 584 | { |
cswiger | 0:d2425a595807 | 585 | //debug |
cswiger | 0:d2425a595807 | 586 | isIgnitionOn = verifyECUAlive(); |
cswiger | 0:d2425a595807 | 587 | |
cswiger | 0:d2425a595807 | 588 | //If ignition is on, check for engine |
cswiger | 0:d2425a595807 | 589 | if (isIgnitionOn) { |
cswiger | 0:d2425a595807 | 590 | isEngineOn = (get_pid(ENGINE_RPM, &engineRPM) && engineRPM > 0) ? 1 : 0; |
cswiger | 0:d2425a595807 | 591 | } else { // else engine must be off |
cswiger | 0:d2425a595807 | 592 | isEngineOn = 0; |
cswiger | 0:d2425a595807 | 593 | } |
cswiger | 0:d2425a595807 | 594 | return 0; |
cswiger | 0:d2425a595807 | 595 | } |
cswiger | 0:d2425a595807 | 596 | |
cswiger | 0:d2425a595807 | 597 | |
cswiger | 0:d2425a595807 | 598 | |
cswiger | 0:d2425a595807 | 599 | bool dtc_clear(void) |
cswiger | 0:d2425a595807 | 600 | { |
cswiger | 0:d2425a595807 | 601 | char cmd_answer[DTC_BUFFER]=""; |
cswiger | 0:d2425a595807 | 602 | |
cswiger | 0:d2425a595807 | 603 | stn1110_write("04\r"); |
cswiger | 0:d2425a595807 | 604 | stn1110_read(cmd_answer,DTC_BUFFER); |
cswiger | 0:d2425a595807 | 605 | strip_answer(cmd_answer); |
cswiger | 0:d2425a595807 | 606 | |
cswiger | 0:d2425a595807 | 607 | if (strcmp(cmd_answer, "44")!=0) |
cswiger | 0:d2425a595807 | 608 | { |
cswiger | 0:d2425a595807 | 609 | return false; |
cswiger | 0:d2425a595807 | 610 | } else |
cswiger | 0:d2425a595807 | 611 | { |
cswiger | 0:d2425a595807 | 612 | has_dtc=false; |
cswiger | 0:d2425a595807 | 613 | return true; |
cswiger | 0:d2425a595807 | 614 | } |
cswiger | 0:d2425a595807 | 615 | } |
cswiger | 0:d2425a595807 | 616 | |
cswiger | 0:d2425a595807 | 617 | |
cswiger | 0:d2425a595807 | 618 | bool dtc_read(void) |
cswiger | 0:d2425a595807 | 619 | { |
cswiger | 0:d2425a595807 | 620 | char cmd_answer[DTC_BUFFER]=""; |
cswiger | 0:d2425a595807 | 621 | has_dtc=false; |
cswiger | 0:d2425a595807 | 622 | |
cswiger | 0:d2425a595807 | 623 | stn1110_write("03\r"); |
cswiger | 0:d2425a595807 | 624 | stn1110_read(cmd_answer,DTC_BUFFER); |
cswiger | 0:d2425a595807 | 625 | |
cswiger | 0:d2425a595807 | 626 | for (char i=0;i<MAX_DTC_READ;i++) |
cswiger | 0:d2425a595807 | 627 | { |
cswiger | 0:d2425a595807 | 628 | strcpy(DTC[i].code,""); |
cswiger | 0:d2425a595807 | 629 | } |
cswiger | 0:d2425a595807 | 630 | |
cswiger | 0:d2425a595807 | 631 | strip_answer(cmd_answer); |
cswiger | 0:d2425a595807 | 632 | |
cswiger | 0:d2425a595807 | 633 | if (strstr(cmd_answer, "NODATA")) |
cswiger | 0:d2425a595807 | 634 | { |
cswiger | 0:d2425a595807 | 635 | //No errors |
cswiger | 0:d2425a595807 | 636 | return true; |
cswiger | 0:d2425a595807 | 637 | } |
cswiger | 0:d2425a595807 | 638 | |
cswiger | 0:d2425a595807 | 639 | if (strncmp(cmd_answer, "43", 2)!=0) |
cswiger | 0:d2425a595807 | 640 | { |
cswiger | 0:d2425a595807 | 641 | //ERROR: Incorrect answer |
cswiger | 0:d2425a595807 | 642 | return false; |
cswiger | 0:d2425a595807 | 643 | } |
cswiger | 0:d2425a595807 | 644 | |
cswiger | 0:d2425a595807 | 645 | char *ss=cmd_answer+2; |
cswiger | 0:d2425a595807 | 646 | char dtclen=0; |
cswiger | 0:d2425a595807 | 647 | |
cswiger | 0:d2425a595807 | 648 | while (strlen(ss) >= 4) |
cswiger | 0:d2425a595807 | 649 | { |
cswiger | 0:d2425a595807 | 650 | const char *prefix[16]= |
cswiger | 0:d2425a595807 | 651 | { |
cswiger | 0:d2425a595807 | 652 | "P0", "P1", "P2", "P3", |
cswiger | 0:d2425a595807 | 653 | "C0", "C1", "C2", "C3", |
cswiger | 0:d2425a595807 | 654 | "B0", "B1", "B2", "B3", |
cswiger | 0:d2425a595807 | 655 | "U0", "U1", "U2", "U3", |
cswiger | 0:d2425a595807 | 656 | }; |
cswiger | 0:d2425a595807 | 657 | uint8_t p=0; |
cswiger | 0:d2425a595807 | 658 | if ( ((*ss)>='0') && ((*ss)<='9') ) p=(*ss)-'0'; else |
cswiger | 0:d2425a595807 | 659 | if ( ((*ss)>='A') && ((*ss)<='F') ) p=(*ss)-'A'+10; else |
cswiger | 0:d2425a595807 | 660 | if ( ((*ss)>='a') && ((*ss)<='f') ) p=(*ss)-'a'+10; |
cswiger | 0:d2425a595807 | 661 | char code[6]; |
cswiger | 0:d2425a595807 | 662 | strcpy(code, prefix[p]); |
cswiger | 0:d2425a595807 | 663 | code[2]=ss[1]; |
cswiger | 0:d2425a595807 | 664 | code[3]=ss[2]; |
cswiger | 0:d2425a595807 | 665 | code[4]=ss[3]; |
cswiger | 0:d2425a595807 | 666 | code[5]=0; |
cswiger | 0:d2425a595807 | 667 | |
cswiger | 0:d2425a595807 | 668 | if (strcmp(code, "P0000")!=0) |
cswiger | 0:d2425a595807 | 669 | { |
cswiger | 0:d2425a595807 | 670 | strcpy(DTC[dtclen].code,code); |
cswiger | 0:d2425a595807 | 671 | has_dtc=true; |
cswiger | 0:d2425a595807 | 672 | dtclen++; |
cswiger | 0:d2425a595807 | 673 | } |
cswiger | 0:d2425a595807 | 674 | ss+=4; |
cswiger | 0:d2425a595807 | 675 | } |
cswiger | 0:d2425a595807 | 676 | |
cswiger | 0:d2425a595807 | 677 | return true; |
cswiger | 0:d2425a595807 | 678 | } |
cswiger | 0:d2425a595807 | 679 | |
cswiger | 0:d2425a595807 | 680 | char *strip_answer(char *s) |
cswiger | 0:d2425a595807 | 681 | { |
cswiger | 0:d2425a595807 | 682 | char *ss; |
cswiger | 0:d2425a595807 | 683 | for (ss=s; *s; s++) |
cswiger | 0:d2425a595807 | 684 | { |
cswiger | 0:d2425a595807 | 685 | if ( ((*s)!=' ') && ((*s)!='\t') && ((*s)!='\n') && ((*s)!='\r') ) |
cswiger | 0:d2425a595807 | 686 | (*ss++)=(*s); |
cswiger | 0:d2425a595807 | 687 | } |
cswiger | 0:d2425a595807 | 688 | (*ss)=0; |
cswiger | 0:d2425a595807 | 689 | |
cswiger | 0:d2425a595807 | 690 | return s; |
cswiger | 0:d2425a595807 | 691 | } |
cswiger | 0:d2425a595807 | 692 |