Here's that code with the rxData now hard limited to 20 characters max.
Code: Select all#include <LiquidCrystal.h>
#define LCD_RS 4
#define LCD_ENABLE 5
#define LCD_DATA1 7
#define LCD_DATA2 8
#define LCD_DATA3 12
#define LCD_DATA4 13
LiquidCrystal lcd(LCD_RS, LCD_ENABLE, LCD_DATA1, LCD_DATA2, LCD_DATA3, LCD_DATA4);
#define ContrastPin 6
#define BrightnessPin 9
//This is a character buffer that will store the data from the serial port
char rxData[20];
byte rxIndex=0;
//Variables to hold the speed and RPM data.
int vehicleSpeed=0;
int vehicleRPM=0;
void setup(){
//Both the Serial LCD and the OBD-II-UART use 9600 bps.
Serial.begin(9600);
//Delete any data that may be in the serial port before we begin.
delay (100);
Serial.flush();
//Init and clear the old data from the LCD.
lcd.begin(16, 2);
lcd.clear();
// Put a Hello World message on the LCD.
lcd.print(" Initializing ");
delay (1000);
lcd.setCursor(0, 1);
lcd.print(" Reseting OBDII ");
delay (2000); // allow user time to look towards OBDII LEDs
//Reset the OBD-II-UART
Serial.println("ATZ");
// Show both responses - if any
getResponse(); // get first response
// Show what came back.
lcd.clear();
// Now show what are we doing.
lcd.print("Reset response");
lcd.setCursor(0, 1);
if(rxIndex)
{
lcd.print("rxIndex1 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
lcd.print(rxData); // should be cmd echo ??
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #1");
}
delay (2000); // wait just long enough for user to see 1st response
// Now get 2nd response, a blank line ??
getResponse();
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
if(rxIndex)
{
lcd.print("rxIndex2 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
lcd.print(rxData); // should be ???
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #2");
}
// Now get 3rd response, a blank line ??
getResponse();
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
if(rxIndex)
{
lcd.print("rxIndex3 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
lcd.print(rxData); // should be ???
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #3");
}
// Now get 4th response, ELM ... ??
getResponse();
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
if(rxIndex)
{
lcd.print("rxIndex4 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
lcd.print(rxData); // should be ELM ...
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #4");
}
delay (5000); // wait long enough for user to see responses
//Delete any data that may be in the serial port before we do next step
Serial.flush();
//Now command the OBDII to auto-detect the proper protocol as done in example 1.
Serial.println("ATSP0");
// Again show both responses - if any
getResponse();
// Show what came back.
lcd.clear();
lcd.print("Auto protocol");
lcd.setCursor(0, 1);
if(rxIndex)
{
lcd.print("rxIndex5 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
lcd.print(rxData); // should be cmd echo ?
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #5");
}
delay (2000); // wait just long enough for user to see 1st response
// Now get 2nd real response ??
getResponse();
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
if(rxIndex)
{
lcd.print("rxIndex6 = ");
lcd.print(rxIndex);
delay (2000);
lcd.setCursor(0, 1);
lcd.print(" "); // erase prior response
delay(100); // allow LCD time to refresh
lcd.print(rxData); // should say OK
// lcd.print(" Got a message");
}
else
{
lcd.print("no response #6");
}
delay (5000); // wait long enough for user to see responses
//Hoping the above worked, now put the speed header on the first row.
lcd.clear();
lcd.print("Speed: ");
//Put the RPM header on the second row.
lcd.setCursor(0, 1);
lcd.print("RPM: ");
//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.
Serial.flush();
//Set the cursor in the position where we want the speed data.
lcd.setCursor(7, 0);
//Write over the old speed data, and then reset the cursor position.
lcd.print(" "); // need 8 spaces for speed data per old code
lcd.setCursor(7, 0);
//Query the OBD-II-UART for the Vehicle Speed
Serial.println("010D");
//Get the response from the OBD-II-UART board. We get two responses
//because the OBD-II-UART echoes the command that is sent.
//We want the data in the second response.
getResponse();
getResponse();
//Convert the string data to an integer
if(rxIndex) // test to see if anything was received from OBDII
{
vehicleSpeed = strtol(&rxData[6],0,16);
//Print the speed data to the lcd
lcd.print(vehicleSpeed);
}
else
{
lcd.print("No data");
}
delay(100);
//Delete any data that may be left over in the serial port.
Serial.flush();
//Move the serial cursor to the position where we want the RPM data.
lcd.setCursor(5, 1);
//Clear the old RPM data, and then move the cursor position back.
lcd.print(" "); // need 10 spaces for RPM data ?
lcd.setCursor(5, 1);
//Query the OBD-II-UART for the Vehicle rpm
Serial.println("010C");
//Get the response from the OBD-II-UART board
getResponse();
getResponse();
//Convert the string data to an integer
//NOTE: RPM data is two bytes long, and delivered in 1/4 RPM from the OBD-II-UART
if(rxIndex) // test to see if anything was received from OBDII
{
vehicleRPM = ((strtol(&rxData[6],0,16)*256)+strtol(&rxData[9],0,16))/4;
//Print the rpm data to the lcd
lcd.print(vehicleRPM);
}
else
{
lcd.print("No data");
}
//Give the OBD bus a rest
delay(300);
}
//The getResponse function collects incoming data from the UART into the rxData buffer
// and only exits when a carriage return character is seen. Once the carriage return
// string is detected, the rxData buffer is null terminated (so we can treat it as a string)
// and the rxData index is reset to 0 so that the next string can be copied.
void getResponse(void){
char inChar=0;
rxIndex=0;
unsigned long TimeIn = millis();
//Keep reading characters until we get a carriage return or time out
while(inChar != '\r'){
//If a character comes in on the serial port, we need to act on it.
if(Serial.available() > 0){
//Start by checking if we've received the end of message character ('\r').
if(Serial.peek() == '\r'){
//Clear the Serial buffer
inChar=Serial.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 = Serial.read();
//Add the new character to the string, and increment the index variable.
rxData[rxIndex++]=inChar;
if(rxIndex > 18)
{
rxData[rxIndex]='\0'; // add the null string terminator in last place
inChar = '\r'; // set incoming character to CR to cause an exit
}
}
}
if (millis() - TimeIn > 1000) // wait 1 sec for some kind of response
{
break;
}
}
}
I'm still unsure how any condition could ever make rxIndex show as a || or ||| ???? But I do think I have a handle on why the LCD went blank after sending it the 1'st rxData response.