1

I'm using an Arduino Mega with a Bluetooth ELM327 adapter to read live data from my car’s OBD-II port — specifically RPM (PID 010C). The goal is to log data to an SD card or display it in real time.

To verify that my car and hardware were set up correctly, I took help from this article: The Ultimate Guide to Using a Car Diagnostic Scanner

I identified the correct OBD-II port and confirmed power and ground pins before connecting my hardware.

I initialized the communication with commands like ATZ, ATE0, and ATSP0.

I connected the ELM327 via Bluetooth (HC-05) to Arduino Mega's Serial1.

Sent the following AT commands:

Serial1.print("ATZ\r"); // Reset
Serial1.print("ATE0\r"); // Echo off
Serial1.print("ATSP0\r"); // Auto-select protocol
Serial1.print("010C\r"); // Request engine RPM
Occasionally received a valid response like:
41 0C 1A F8 → ((0x1A * 256) + 0xF8) / 4 = 1720 RPM.

But responses are inconsistent: sometimes I get NO DATA, partial bytes, or just nothing. I'm suspecting either timing issues or that I’m not reading the buffer correctly.

Should I wait for the > prompt from ELM327 before sending another command? If so, what’s the best way to do that using Arduino code?

My Arduino code:

#include <SoftwareSerial.h>
SoftwareSerial elmSerial(10, 11); // RX, TX for HC-05 (adjust as needed)
void setup() {
 Serial.begin(9600); // Monitor
 elmSerial.begin(9600); // ELM327 default
 delay(1000);
 sendCommand("ATZ\r");
 sendCommand("ATE0\r");
 sendCommand("ATSP0\r");
}
void loop() {
 sendCommand("010C"); // Request RPM
 delay(2000); // Wait between requests
}
void sendCommand(String cmd) {
 elmSerial.print(cmd + "\r");
 delay(100);
 while (elmSerial.available()) {
 char c = elmSerial.read();
 Serial.print(c); // Echo to Serial Monitor
 }
}
asked Jun 16 at 10:44
2
  • Question edited, included my Arduino code. Thanks. Commented Jun 16 at 18:21
  • Please add also (a text(!) copy of) the output in the Serial Monitor. Are you aware that SoftwareSerial cannot receive and send at the same time? Another hint: please extend the print to Serial.print(c, HEX); to make NUL bytes visible, as messages are binary. Commented Jun 18 at 8:05

1 Answer 1

1

You're very close! You're correctly setting up the ELM327 and sending the right commands, but the inconsistent responses and "NO DATA" likely come from timing issues and not reading the ELM327 response fully before sending the next command.

Here's the solution:

  1. Wait for the > Prompt

The ELM327 always ends its response with a > character. You should read until you see that.

  1. Avoid Fixed Delays — Wait Until Response is Done

Use a timeout to avoid being stuck forever if something goes wrong, but otherwise read until > appears.

Updated Code:

void sendCommand(String cmd) {
 elmSerial.print(cmd + "\r");
 unsigned long startTime = millis();
 String response = "";
 while (millis() - startTime < 2000) { // 2 second timeout
 while (elmSerial.available()) {
 char c = elmSerial.read();
 response += c;
 if (c == '>') {
 Serial.print(response); // Only print when full response received
 return;
 }
 }
 }
 Serial.println("Timeout or incomplete response:");
 Serial.println(response);
}
answered Jun 18 at 22:54

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.