I am currently trying to figure out how to read 2 or more pieces of data from the SparkFun OBD-II UART.
I am able to read 1 item perfectly fine such as manifold pressure or rpms, however I get inconsistent and faulty readings when I try to read rpms and manifold pressure at the same time, the serial monitor displays something like this while idling (atmospheric and 1200rpm):
kpa: 101 rpm: 0
kpa: 101 rpm: 0
kpa: 101 rpm: 0
kpa: 0 rpm: 0
kpa: 101 rpm: 0
kpa: 0 rpm: 0
…
it correctly reads pressure half the time and does not seem to read rpm at all.
thank you for your help!
#include <SoftwareSerial.h>
#include "ELMduino.h"
#define ELM_RX 2
#define ELM_TX 3
SoftwareSerial elmSerial(ELM_RX, ELM_TX); // RX, TX for ELM327 module
ELM327 myELM327;
void setup() {
Serial.begin(9600); // Start serial communication for debugging
elmSerial.begin(9600); // Start software serial for ELM327
Serial.println("Initializing ELM327...");
if (!myELM327.begin(elmSerial)) {
Serial.println("Failed to connect to ELM327");
while (1); // Stop here if ELM327 connection fails
}
Serial.println("ELM327 connected");
}
void loop() {
int press = myELM327.manifoldPressure();
if (myELM327.nb_rx_state == ELM_SUCCESS) {
Serial.print ("kpa: ");
Serial.print (press);
}
else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
myELM327.printError();
}
int rpm = myELM327.rpm();
if (myELM327.nb_rx_state == ELM_SUCCESS) {
Serial.print (" rpm: ");
Serial.println(rpm);
}
else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
myELM327.printError();
}
}
The main issue is that you’re making two separate requests to the ELM327 in quick succession. OBD-II communication has a certain latency, and the ELM327 needs time to process each request and receive a response from the car’s ECU. When you request data too quickly, you may get incomplete or invalid responses.
Here’s an improved version of your code that should solve this issue:
#include <SoftwareSerial.h>
#include "ELMduino.h"
#define ELM_RX 2
#define ELM_TX 3
SoftwareSerial elmSerial(ELM_RX, ELM_TX); // RX, TX for ELM327 module
ELM327 myELM327;
unsigned long lastRequestTime = 0;
const unsigned long requestInterval = 100; // Time between requests in milliseconds
void setup() {
Serial.begin(9600); // Start serial communication for debugging
elmSerial.begin(9600); // Start software serial for ELM327
Serial.println("Initializing ELM327...");
if (!myELM327.begin(elmSerial)) {
Serial.println("Failed to connect to ELM327");
while (1); // Stop here if ELM327 connection fails
}
Serial.println("ELM327 connected");
}
void loop() {
if (millis() - lastRequestTime >= requestInterval) {
lastRequestTime = millis();
int press = myELM327.manifoldPressure();
if (myELM327.nb_rx_state == ELM_SUCCESS) {
Serial.print("kpa: ");
Serial.print(press);
} else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
Serial.print("MAP Error: ");
myELM327.printError();
}
delay(50); // Small delay between requests
int rpm = myELM327.rpm();
if (myELM327.nb_rx_state == ELM_SUCCESS) {
Serial.print(" rpm: ");
Serial.println(rpm);
} else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
Serial.print("RPM Error: ");
myELM327.printError();
}
}
}
Here’s what’s changed and why:
I’ve added a timing mechanism to control how often we request data. This helps prevent overwhelming the ELM327 with too many requests.
There’s a small delay (50ms) between the manifold pressure and RPM requests. This gives the ELM327 and the car’s ECU some time to process each request.
I’ve separated the error messages for MAP (Manifold Absolute Pressure) and RPM to help you identify which request is failing if there’s an issue.
The requestInterval is set to 100ms, which means you’ll get updates about 10 times per second. You can adjust this value based on your needs and the capabilities of your specific OBD-II system.
thank you for the help! unfortunately, I’m still running into errors, the serial output just reads
rpm: 0
rpm: 0
rpm: 0
rpm: 0
rpm: 0
…
I tried adjusting the delay time and request interval, however it does not appear to make a difference in the data.
I tried a different car and had the same issue, 9600 seems to be the only baud rate it can connect on. the code you provided still works if I comment out the second request