1

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 & 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:

  1. Am I right in assuming the SoftwareSerial library will work for any baud rate, even 10,400?
  2. 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 <Wire.h> 
#include <SoftwareSerial.h>

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 <Adafruit_GFX.h>    
#include <UTFTGLUE.h>

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

char textout[30];
int xVal = 50;
cursorY = 10;
for (int i=0; i < 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 don't have experience with your specific case... I tried to use MIDI over SoftwareSerial (31250 baud). And I missed some messages, especially when there are more messages sent in a shorter period. There are other SoftwareSerial libraries, but had similar problems. So I try to stay away from SoftwareSerial. – Michel Keijzers May 22 '17 at 14:29
  • Thanks for your reply. Well I believe I cannot use hardware serial so I have no choice really... Although I did see that when using a lower baud and also receiving less messages then there should be less missed messages in the serial connection. Can you by any chance tell me if you had to edit the software serial library to calculate the correct timings for the custom baud rate? Or did you use the latest libraries where the library calculates the timings? – James Elder May 22 '17 at 17:39
  • I used the midi library which I passed the baudrate to that library (MIDI library from 47effects). So I did not had to change the library. I will add some more in an answer (gives me some possibility to add bullets). – Michel Keijzers May 22 '17 at 18:46
1

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.

  • Thanks for your answer, I think I may have not explained the situation very clearly in my original post though. I know for sure my LCD is displaying the correct data so there is no issue there. As for the SoftwareSerial running at 10,400 baud, I know that others have had it running on an Arduino Uno before but that was with the old library which used hardcoded timings. So I guess the take home for now is to as you say try and communicate with a PC running at 10,400 baud in order to reduce the unknowns and very that serial instance.begin(10400) works out of the box (or not if thats the case). – James Elder May 22 '17 at 17:38
  • Also the Arduino library specifies the Uno can handle up to 57600 baud, so there shouldn't be a technical issue running 10,400. – James Elder May 22 '17 at 17:39
  • Great! When I last tested it, I didn't find it to receive reliably at above 9600 baud. I guess it's time I check my library version & test again. I could sure use that 5x speedup! – JRobert May 22 '17 at 20:48
0

I tried using MIDI data with the software library. However, I also got problems with missing and/or corrupted messages. MIDI has a fixed baudrate of 31,250 baud. As long as I did not sent too much, everything was ok, but sending continuous messages (within the 31,250 baud rate spec) I got into problems. It seems that the input buffer was too full and/or no time to process them.

The default buffer for the serial (software serial) buffer was 64 bytes. I increased it to 128, but saw no difference. Making the buffer higher probably just would delay the time until messages are corrupted.

What you can do is:

  • Use a non Arduino device with multiple UARTs (no experience with that)
  • There seems to exists a 328PB version of the Uno which has two UARTs (but it maybe a kind of niche device, possibly with support problems)
  • What I did was using a Mega, it has 4 UARTs.
  • Using multiple Uno's and/or Mega's connected to eachother, giving 1 resp. 4 UARTs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.