Arduino + L9637 K-Line reader - 10400 baud on SoftwareSerial? I know this question has been asked many times before in different flavours, but all of the previous questions I have found seem to pre-date the current SoftwareSerial library, which afaik now (unlike when the previous questions were asked) allows any baud rate to be set as it calculates the values for the timings.

So I currently have the L9637 monolithic bus driver connected to pins D0 and D1 of my Arduino Uno. I am trying to create an ECU reader to communicate with my car over the KW1281 protocol, and from testing I have discovered I need to do the 5 baud init and then communicate at 10,400 baud.

First off I want to say I have successfully managed to run the 5 baud init. Now, I realise the pins (D0 &amp; D1) are capable of hardware serial, however when trying to use the hardware serial I couldn't get any connection to the car. I think it's because the hardware serial doesn't like the pin modes to be changed after setup - however this is required to perform the 5 baud init. So I have decided to use the SoftwareSerial library for the following 10,400 baud communication. 

With this library I successfully receive three (incorrect) response bytes from the ECU when setting a baud rate of 9600, however the response bytes - despite being correct in the number of them (3) - are wrong in terms of their value and seem to just be zero values. 

Now as my car requires 10,400 baud communication, I instead setup the serial port to 10,400 baud. I know from experience that using 9600 baud will give incorrect response bytes and 10400 baud solves this. So I expected this would work and solve my problem, however it didn't. I still get 3 bytes containing 0. Just to be clear the three correct values should be: 55 01 8A

So I was wondering:


Am I right in assuming the SoftwareSerial library will work for any baud rate, even 10,400?
If yes to point 1, can anyone suggest why I might be getting data bytes containing 0 instead of the correct values?


As the full code is too long to post, the code for setting up the UART at 10,400, and then receiving the bytes is as follows:

#include &lt;Wire.h&gt; 
#include &lt;SoftwareSerial.h&gt;

SoftwareSerial obd(pinKLineRX, pinKLineTX, false); // RX, TX, inverse logic
obd.begin(baudrate);   

uint8_t data = 0;
int recvcount = 0;
char s[3];

while (obd.available())
{
   uint8_t data = obd.read();
   s[recvcount] = data;    
   recvcount++; 
}


And then to print the data I do the following:

#include &lt;Adafruit_GFX.h&gt;    
#include &lt;UTFTGLUE.h&gt;

UTFTGLUE lcd(0x9488,A2,A1,A3,A4,A0);

char textout[30];
int xVal = 50;
cursorY = 10;
for (int i=0; i &lt; size; i++)
{
  uint8_t data = s[i];

  sprintf(textout, "%i ", data);
  lcd.print(textout, xVal, cursorY);
  xVal += 10;
}

cursorY += 10;


The output on the LCD is 


  0 0 0


When it should be 


  55 01 8A
I've found 9600 baud to be the receive limit among standard baud rates (transmission can go faster). You're proposing an 8% increase over 9600 which sounds like it has a good chance of working but you'll need to experiment to find out.

You also asked why might your data (on the LCD) be wrong.

You'll do your sanity a big favor and do two separate experiments:


First, get known data (literal strings or terminal input) to display correctly on your LCD, before you try to use the LCD to confirm or debug your communications.
Second, get SoftwareSerial running (or find out that it doesn't...) at 10400 baud. In fact try to get up to, say, 12000 baud, or at least push the rate to find out where it starts to fail so you know how much head-room you'll have at 10,400. The simplest way would be to use two Arduinos if you have access to another one. Again, use your terminal or some literal strings on MCU 'A' to send to MCU 'B', MCU 'B' should receive a line and echo it back to 'A', who prints it on its terminal. Printing it on 'B's terminal wouldn't be a bad idea either.


You'll be in a lot better position to combine the two techniques once you have confidence that each one works; especially if you copy-and-paste known-working code segments.