I was continuing testing with the Arduino to get communication happening with the car – there is a requirement to test data against known values to confirm findings.
I was aiming to use the hardware driven serial on the Arduino’s ATMega328 chip – the reference docs claim it can support custom baud rates, so I figured it should just work.
The code base over at OBDuino suggests that Serial.begin(10400) should also work. I was blaming the circuit used for the lack of communication, which would make sense, but it does work with NewSoftSerial. I tested this last night by using 9600 baud with an ELM327 cable. The test fails using the baud rate of 10400 in the Hardware serial.
With NewSoftSerial working at 9600 baud, the missing link then becomes how to use 10400 baud with NewSoftSerial.
The answer was simple enough thankfully:
#if F_CPU == 16000000
static const DELAY_TABLE PROGMEM table[] =
{
// baud rxcenter rxintra rxstop tx
{ 115200, 1, 17, 17, 12, },
{ 57600, 10, 37, 37, 33, },
{ 38400, 25, 57, 57, 54, },
{ 31250, 31, 70, 70, 68, },
{ 28800, 34, 77, 77, 74, },
{ 19200, 54, 117, 117, 114, },
{ 14400, 74, 156, 156, 153, },
{ 10400, 106, 218, 218, 215, },
{ 9600, 114, 236, 236, 233, },
{ 4800, 233, 474, 474, 471, },
{ 2400, 471, 950, 950, 947, },
{ 1200, 947, 1902, 1902, 1899, },
{ 300, 3804, 7617, 7617, 7614, },
};
The baud rate 10400 is simply 10400 / 9600 = 1.0833333. Then for each of the 9600 rx and tx values, divide by 1.0833333.
Testing this with the OBD wake up that gets sent every second or so (ox01, 0x3E, 0x3F) gets the correct data as it would be at 9600 baud (and matches what I tested with the ECU in the car).
It’s not ideal though, software serial is using CPU clock cycles to fake an actual serial port, there needs to be a reason as to why the Arduino didn’t like 10400 baud, this is against the knowledge that it works with the OBDuino – a project that’s been used numerous times in the USA, and would therefore be successful.
It really should come down to whether the circuit is correct (I’ve tried the variation here; http://blog.perquin.com/prj/obdii/, and here elmelectronics.com/DSheets/ELM323DS.pdf, and the very simple zener and resistor circuit here, http://sterntech.com/obdii_protocols_iso.php) – not to mention variations to those to see if it was a TX related issue (- I was leaving TX empty for receiving only).
Being the holiday period it’ll take too long to track down one of the IC chips used in the OBDuino, and the MC33290 IC used there is End of life.
I’ve looked over this circuit by someone else who tried the same trick as the first link above, but that’s really only adding protection, and looking through his blog, I doubt he found a result – he claims he got the initial init – but that’s it)..
Logically thinking, the serial would be processed as one might expect, the data bits are logic high and low – 5V high, 0V low, the standard used in the car is that the circuit idles high and goes low when bits are being sent – so 0, 1, 0, 1 is simply 0V, 5V, 0V, 5V. That should be received, but perhaps the arduino’s software is discarding it – though that makes less sense compared to the circuit not producing enough current to trigger a logic high / logic low as need be. I don’t think the pulses are long enough for the DMM to pick up either.
I’ll have to toss up on how to solve this issue another time, I’ve got something to work
3 Responses to NewSoftSerial – Adding a baud rate