I am using a Ebay ELM327 obdii device that is locked at 38400 Baud. I wrote a simple program to read and log data. The program works fine on my Arduino Mega using Serial to communicate with the Serial Monitor on the PC and Serial1 to communicate with the device.
However, my intent was to use a Nano so I could fit the arduino inside the ELM327 enclosure. I modified the program to use softwareserial to communicate with the ELM327 device leaving the RX and TX pins open for programming and communication with the Serial Monitor on the PC.
The Nano seems to receive a couple of packets of invaild data from the device and then all communication stops. I monitored the byte by byte output and I was getting strange characters mixed with vaild characters.
I thought this may be due to using software serial so I modified the program to use TX and RX and write to an SD card and then problem was the same.
It seems to work fine on Mega and Uno but not the Nano.
I had to increase the delays during to loop from 25 to 200 to even get it to display any data.
My theory is the Nano cannot communicate at 38400 baud and therefore is receiving incomplete or garbled data streams from the ELM327 device.
Any help would be appreciated
#include <SoftwareSerial.h>
SoftwareSerial obd(2,3);
//This is a character buffer that will store the data from the serial port
char rxData[20];
char rxIndex=0;
//Variables to hold the Vehicle data from OBDii Device
int vehicleVSS=0; //in KPH
int vehicleRPM=0; //RPM
void setup(){
obd.begin(38400);
Serial.begin(38400);
Serial.println("Program Start");
//Wait for a little while before sending the reset command to the OBD-II-UART
delay(3000);
//Reset the OBD-II-UART
obd.println("ATZ");
//Make sure TX has completed
obd.flush();
//Wait for a bit before starting to send commands after the reset.
delay(2000);
}
void loop(){
//Delete any data that may be in the serial port before we begin.
while(obd.available() > 0)
{
obd.read();
}
//Query the OBD-II-UART for the Vehicle RPM
obd.print("010C\r");
//Wait for TX to finish
obd.flush();
getResponse();
getResponse(); //this should contain the data we want
vehicleRPM = ((strtol(&rxData[6],0,16)*256)+strtol(&rxData[9],0,16))/4;
getResponse();
Serial.println(vehicleRPM);
delay(200);
// Clear Rx buffer
while(obd.available() > 0)
{
obd.read();
}
//Query the OBD-II-UART for the Vehicle Speed in Km/H
obd.print("010D\r");
// Wait for TX to finish
obd.flush();
getResponse();
getResponse();
vehicleVSS = strtol(&rxData[6],0,16); //this is KPH for MPH multiply by 0.621371;
getResponse();
Serial.println(vehicleVSS);
delay(200);
}
void getResponse(void){
char inChar=0;
//Keep reading characters until we get a carriage return
while(inChar != '\r'){
//If a character comes in on the serial port, we need to act on it.
if(obd.available() > 0){
//Start by checking if we've received the end of message character ('\r').
if(obd.peek() == '\r'){
//Clear the Serial buffer
inChar=obd.read();
//Put the end of string character on our data string
rxData[rxIndex]='\0';
//Reset the buffer index so that the next character goes back at the beginning of the string.
rxIndex=0;
}
//If we didn't get the end of message character, just add the new character to the string.
else{
//Get the new character from the Serial port.
inChar = obd.read();
//Add the new character to the string, and increment the index variable.
rxData[rxIndex++]=inChar;
}
}
}
}