Skip to content

Commit

Permalink
Better ELM327 compat
Browse files Browse the repository at this point in the history
  • Loading branch information
GAsplund committed Oct 23, 2023
1 parent 980ef1e commit 682d900
Showing 1 changed file with 73 additions and 66 deletions.
139 changes: 73 additions & 66 deletions src/fuel_economy_meter/elm327.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
#include "trip.h"
#include "Stream.h"

/**
/**
* @brief Makes sure that the hex value is always `digits` long
*
*
* Torque needs leading zeroes in its values. This function takes care of this.
*
*
* @param a The value to convert to hex
* @param digits The number of digits to use
*/
Expand Down Expand Up @@ -46,7 +46,7 @@ String ELM327::converttohex(int a, int digits)

/**
* @brief Initializes the ELM327 class
*
*
* @param inputStream a pointer to the data stream to read/write to, e.g. BluetoothSerial or Serial
* @param inputTrip a pointer to a Trip class
*/
Expand All @@ -58,93 +58,100 @@ void ELM327::begin(Stream *inputStream, Trip *inputTrip)

/**
* @brief Polls for commands from the BT serial port
*
*
* Reads the BT serial port for commands from the Torque app.
* Interprets any known commands and sends back data from the Trip class.
*
*
*/
void ELM327::poll(void)
{
String mode, OBDRequest, OBDReturn = "";
while (stream->available())
{ // Get data from BT serial port
{ // Get data from stream
delay(3); // wait for buffer to fill up
if (stream->available() > 0)
{
char c = stream->read(); // write character to c
OBDRequest += c; // write c to OBDRequest variable
OBDRequest += c; // write c to OBDRequest variable
}
OBDRequest.trim(); // get rid of line feeds
OBDRequest.trim(); // Remove line feeds
}
if (OBDRequest.length() == 0) return; // Got no data

if (OBDRequest.length() == 0)
return;

mode = OBDRequest.substring(0, 2);

if (mode == "AT")
{ // Is it an AT request? used to setup connection between Torque and Arduino
String ATCommand = OBDRequest.substring(2); // Get AT request from String
Serial.println(ATCommand); // used for debugging to see what the Torque app is asking
{ // AT request - used to setup connection between Torque and Arduino
String ATCommand = OBDRequest.substring(2);
if (ATCommand == "@1")
{ // Torque asks for device description
stream->println("OBDII Arduino Simulator"); // Give it a suitable name
{ // Device description
stream->println("OBDII Arduino Simulator");
}
if (ATCommand == "I")
{ // Torque asks for version ID
stream->println("VPEE v1.0"); //
else if (ATCommand == "I")
{ // Torque asks for version ID
stream->println("VPEE v1.0");
}
if (ATCommand == "SP0")
{ // Torque says to go to auto protocol
stream->println("OK"); // Ok
else if (ATCommand == "SP0")
{ // Torque says to go to auto protocol
stream->println("OK");
}
if (ATCommand == "DPN")
{ // Torque asks for device protocol by number
else if (ATCommand == "DPN")
{ // Torque asks for device protocol by number
stream->println("1"); // just say it is number 1.
}
if (ATCommand == "RV")
{ // Torque askes for adapter voltage
else if (ATCommand == "RV")
{ // Torque asks for adapter voltage
stream->println("12.5");
}
} else if (mode == "21")
{ // Mode 21 is used for custom values.
String OBDCommand = OBDRequest.substring(2); // Get PID request from Mode 21
if (OBDCommand == "10")
{ // This can be any value. Make your own table with PID's, names, length and formulas
OBDReturn = "61" + OBDCommand + converttohex(trip->getRpm(), 4); // 61 means return Mode 21 value + 40hex. Make sure length return conforms with formula in Torque
}
if (OBDCommand == "11")
{ // This can be any value. Make your own table with PID's, names, length and formulas
OBDReturn = "61" + OBDCommand + converttohex(trip->getLiters(), 4); // 61 means return Mode 21 value + 40hex. Make sure length return conforms with formula in Torque
}
if (OBDCommand == "12")
{ // This can be any value. Make your own table with PID's, names, length and formulas
OBDReturn = "61" + OBDCommand + converttohex(trip->getKm(), 4); // 61 means return Mode 21 value + 40hex. Make sure length return conforms with formula in Torque
}
if (OBDCommand == "13")
{ // This can be any value. Make your own table with PID's, names, length and formulas
OBDReturn = "61" + OBDCommand + converttohex(trip->getKmh(), 4); // 61 means return Mode 21 value + 40hex. Make sure length return conforms with formula in Torque
}
if (OBDCommand == "14")
{ // This can be any value. Make your own table with PID's, names, length and formulas
OBDReturn = "61" + OBDCommand + converttohex(trip->latestInjectionTime, 4); // 61 means return Mode 21 value + 40hex. Make sure length return conforms with formula in Torque
}
if (OBDCommand == "15")
{ // This can be any value. Make your own table with PID's, names, length and formulas
OBDReturn = "61" + OBDCommand + converttohex(0, 4); // 61 means return Mode 21 value + 40hex. Make sure length return conforms with formula in Torque
}
stream->println(OBDReturn); // Return value to Torque
} else if (mode == "01") // This if statement is only used to prevent Torque mentioning no PID's are available at startup.
{ // Mode 1 request
String OBDCommand = OBDRequest.substring(2); // Get PID request from Mode 1
if (OBDCommand == "00")
{ // Torque requests available PID's from Arduino
OBDReturn = "41" + OBDCommand + "08000000"; // 41 means return Mode 1 value + 40hex. 08000000hex = only coolant temp available (just to avoid error in Torque)
}
if (OBDCommand == "05")
{ // Torque requests available PID's from Arduino
OBDReturn = "41" + OBDCommand + "3C"; // 41 means return Mode 1 value + 40hex. 08000000hex = only coolant temp available (just to avoid error in Torque)
}
stream->println(OBDReturn); // Return value to Torque
}
else if (mode == "21")
{ // Mode 21 - Custom values
String pid = OBDRequest.substring(2);
if (pid == "11")
{
OBDReturn = "61" + pid + converttohex(trip->getLiters(), 4);
}
else if (pid == "12")
{
OBDReturn = "61" + pid + converttohex(trip->getKm(), 4);
}
else if (pid == "13")
{
OBDReturn = "61" + pid + converttohex(trip->getKmh(), 4);
}
else if (pid == "14")
{
OBDReturn = "61" + pid + converttohex(trip->latestInjectionTime, 4);
}
stream->println(OBDReturn);
}
else if (mode == "01")
{ // Mode 1 request - Current Data
String pid = OBDRequest.substring(2, 4);
if (pid == "00")
{ // PIDs supported (bit-encoded, big endian)
OBDReturn = "41" + pid + "08180004";
}
else if (pid == "05")
{ // Engine coolant temperature
OBDReturn = "41" + pid + "3C";
}
else if (pid == "0C")
{ // Engine speed
OBDReturn = "41" + pid + converttohex(trip->getRpm() * 4, 4);
}
else if (pid == "0D")
{ // Vehicle speed
OBDReturn = "41" + pid + converttohex(trip->getKmh(), 2);
}
else if (pid == "5E")
{ // Engine fuel rate
OBDReturn = "41" + pid + converttohex(trip->getLph() * 20, 4);
}
stream->println(OBDReturn);
}

stream->println(">"); // Let Torque know Arduino is ready.
stream->println(">"); // Ready for another command
}

0 comments on commit 682d900

Please sign in to comment.