int8_t ELM327::get_vin_blocking(char *vin) Description: ------------ * Read Vehicle Identification Number (VIN). This is a blocking function. Inputs: ------- * char vin[] - pointer to c-string in which to store VIN Note: (allocate memory for 18 character c-string in calling function) Return: ------- * int8_t - the ELM_XXX status of getting the VIN */
| 2938 | * int8_t - the ELM_XXX status of getting the VIN |
| 2939 | */ |
| 2940 | int8_t ELM327::get_vin_blocking(char vin[]) |
| 2941 | { |
| 2942 | char temp[3] = {0}; |
| 2943 | char *idx; |
| 2944 | uint8_t vin_counter = 0; |
| 2945 | uint8_t ascii_val; |
| 2946 | |
| 2947 | if (debugMode) |
| 2948 | Serial.println(F("Getting VIN...")); |
| 2949 | |
| 2950 | sendCommand("0902"); // VIN is command 0902 |
| 2951 | while (get_response() == ELM_GETTING_MSG) |
| 2952 | ; |
| 2953 | |
| 2954 | // strcpy(payload, "0140:4902013144341:475030305235352:42313233343536"); |
| 2955 | if (nb_rx_state == ELM_SUCCESS) |
| 2956 | { |
| 2957 | memset(vin, 0, 18); |
| 2958 | // **** Decoding **** |
| 2959 | if (strstr(payload, "490201")) |
| 2960 | { |
| 2961 | // OBD scanner provides this multiline response: |
| 2962 | // 014 ==> 0x14 = 20 bytes following |
| 2963 | // 0: 49 02 01 31 44 34 ==> 49 02 = Header. 01 = 1 VIN number in message. 31, 44, 34 = First 3 VIN digits |
| 2964 | // 1: 47 50 30 30 52 35 35 ==> 47->35 next 7 VIN digits |
| 2965 | // 2: 42 31 32 33 34 35 36 ==> 42->36 next 7 VIN digits |
| 2966 | // |
| 2967 | // The resulitng payload buffer is: |
| 2968 | // "0140:4902013144341:475030305235352:42313233343536" ==> VIN="1D4GP00R55B123456" (17-digits) |
| 2969 | idx = strstr(payload, "490201") + 6; // Pointer to first ASCII code digit of first VIN digit |
| 2970 | // Loop over each pair of ASCII code digits. 17 VIN digits + 2 skipped line numbers = 19 loops |
| 2971 | for (int i = 0; i < (19 * 2); i += 2) |
| 2972 | { |
| 2973 | temp[0] = *(idx + i); // Get first digit of ASCII code |
| 2974 | temp[1] = *(idx + i + 1); // Get second digit of ASCII code |
| 2975 | // No need to add string termination, temp[3] always == 0 |
| 2976 | |
| 2977 | if (strstr(temp, ":")) |
| 2978 | continue; // Skip the second "1:" and third "2:" line numbers |
| 2979 | |
| 2980 | ascii_val = strtol(temp, 0, 16); // Convert ASCII code to integer |
| 2981 | snprintf(vin + vin_counter++, sizeof(uint8_t), "%c", ascii_val); // Convert ASCII code integer back to character |
| 2982 | // Serial.printf("Chars %s, ascii_val=%d[dec] 0x%02hhx[hex] ==> VIN=%s\n", temp, ascii_val, ascii_val, vin); |
| 2983 | } |
| 2984 | } |
| 2985 | if (debugMode) |
| 2986 | { |
| 2987 | Serial.print(F("VIN: ")); |
| 2988 | Serial.println(vin); |
| 2989 | } |
| 2990 | } |
| 2991 | else |
| 2992 | { |
| 2993 | if (debugMode) |
| 2994 | { |
| 2995 | Serial.println(F("No VIN response")); |
| 2996 | printError(); |
| 2997 | } |
nothing calls this directly
no outgoing calls
no test coverage detected