Nissan Consult and Arduino

Hello everyone, like many people I’m relatively new to arduino - done several tutorials a couple of my own projects (fan controller for my car, an alarm clock, servo control stuff - just random stuff like that ) but I’m having some issues with my current project and hoping maybe someone can offer some insight to why things aren’t working like I think they should. I’m not sure if my problem is software library stuff (which I admit I don’t totally understand).

Basically, there’s a consult library out there provided by a user named Crim - he claims it works with his arduino and an LCD screen (at least it did at one point). He’s been off here for a couple of years and I’m working on something similar and trying to use his (slightly modified) library. There’s also some info on the Nissan Consult interface provided by PLMS Development about address requests that return certain values.

The link to his library is: https://github.com/Crim/Arduino-Nissan-Consult-Library

The link(s) to the PLMS info is: http://www.plmsdevelopments.com/diy_consult.htm <<-- there they have listed the protocol, a generic ECU data register lookup table, and an interface schematic for the cable.

On the library files, I did go through and modify all of the WProgram.h references in the files to Arduino.h to support the new 1.0+ IDE. I have been trying to simply get a modified version of his program to run (modified to use a serial LCD in place of the liquid crystal library). My code is below. My serial LCD will display the stuff correctly, and it will say “ECU iniitallized” (the first booleen returning true) but after that will not read any further info from the ECU. The code is currently set up to display just the coolant temp and RPM.

My hardware setup is a nano running the serial LCD on pin 11, and the hardware serial is used to connect to an RS232-TTL adapter from NKC Electronics ( this one - http://www.nkcelectronics.com/RS232-to-TTL-converter-board-DTE-with-Male-DB9-33V-to-5V_p_369.html ). This is connected to a consult to serial cable that I purchased from amazon a while ago.

The consult cable works when used with a Serial-USB adapter and a computer to access the information. I have tried numerous programs with the consult cable + serial-usb adapter and it works fine when connected this way. My issue seems to be when the arduino tries to connect to the ecu via the consult cable. The program will work fine up to the point it tries to get the part num, and it fails. It also fails on the coolant temp and RPM.

Here is my code (really just modified code from crim’s example) - note that it calls the library files listed above:

#include <Consult.h>
#include <ConsultConversionFunctions.h>
#include <ConsultErrorCode.h>
#include <ConsultRegister.h>
#include <SoftwareSerial.h>

//sets up the LCD using softwareSerial and connected to pin 11.
SoftwareSerial lcd=SoftwareSerial(10, 11); // RX, TX for LCD
Consult myConsult = Consult(); //sets up myConsult var.
char ESC = 0xFE; //lcd hex command for entering other screen commands
char line = 0x45; //lcd hex command for cursor position - used to select where to print.
char clr=0x51;  //lcd hex command for clear screenclear

void setup() {
  // Tell Consult which Serial object to use to talk to the ECU
  myConsult.setSerial(&Serial);
  // We want MPH and Farenheit, so pass in false
  // If you want KPH or Celcius, pass in true
  myConsult.setMetric(false);

  //start LCD
  lcd.begin(9600);
  
  // Set LCD Contrast
  lcd.write(ESC);
  lcd.write(0x52);  //LCD hex command for contrast
  lcd.write(40);    // writing the value for contrast (0-40)

  // Set Backlight
  lcd.write(ESC);
  lcd.write(0x53); //LCD hex command for brightness
  lcd.write(7);    // writing value for backlight brightness (0-8)
 
  //clear Screen
  lcd.write(ESC);
  lcd.write(clr); //LCD command to clear screen and return to position 0

  // Some output on the LCD
  lcd.print("Consult");
 
  lcd.write(ESC);
  lcd.write(line);
  lcd.write(0x14); //hex location for line 3
  lcd.print("Starting...");
 
}

void loop() {
  // Attempt to initialize consult <---> ecu conversation
  // Keep re-trying until it initializes
  while (myConsult.initEcu() == false) {
    // Failed to connect
    delay(1000);
    
    // Output to LCD
    lcd.write(ESC); //clear screen
    lcd.write(clr);
    lcd.write(ESC);
    lcd.write(line);
    lcd.write(0x28); //line2
    lcd.print("Failed to connect!!!");  //print on line 2
  }
  
  // Output to LCD once connected (initEcu returns true)
  lcd.write(ESC);//clear screen
  lcd.write(clr);
  lcd.print("Connected to ECU!");
  
  // Try to pull ECU Part Number, 11 chars + 1 null terminator
  char partNumber[12];
  if (myConsult.getEcuPartNumber(partNumber)) {
    // Pulled ECU PartNumber, it is now stored 
    // in partNumber variable!
    // Output to LCD
    lcd.print(partNumber);
  }
  else {
    // Failed to retrieve ECU Part Number
    // Output to LCD
    lcd.print("Failed to get partnum");
  }
  
  // Small Pause
  delay(2000);
  
  // Clear our LCD
  lcd.write(ESC);
  lcd.write(clr);
    
  // Attempt to read Coolant Temp,
  // Coolant temp only spans a single register, pass in ECU_REGISTER_NULL for the LSB register address
  int coolantTemp;
  if (myConsult.getRegisterValue(ECU_REGISTER_COOLANT_TEMP, ECU_REGISTER_NULL, &coolantTemp)) {
    // coolantTemp now contains the temp, but we need to convert it to something human readable
    coolantTemp = ConsultConversionFunctions::convertCoolantTemp(coolantTemp);
    
    // Output to lcd - line 1
    lcd.print("Coolant:");
    lcd.print(coolantTemp);
  }
  else {
    // Failed to read coolant temp
    // output to LCD
    lcd.print("Failed read coolant");
  }
    
  // Attempt to read Tachometer,
  // This register spans two registers, first pass in MSB, then LSB
  int tach;
  if (myConsult.getRegisterValue(ECU_REGISTER_TACH_MSB, ECU_REGISTER_TACH_LSB, &tach)) {
    // tach now contains the tach value, but we need to convert it to something human readable
    tach = ConsultConversionFunctions::convertTachometer(tach);
    
    // Output to LCD - line 2
    lcd.write(ESC);
    lcd.write(0x45);
    lcd.write(0x40);
    lcd.print("Tach:");
    lcd.print(tach);
    
  }
  else {
    // Failed to read tach
    // Output to LCD - line 2
    lcd.write(ESC);
    lcd.write(0x45);
    lcd.write(0x40);  
    lcd.print("Failed read tach");
  }
  
  // Small pause
  delay(2000);
  
  //clear screen
  lcd.write(ESC); 
  lcd.write(clr);

I think you will have a problem unless you make contact with someone who is familiar with the same stuff. For anyone else there would be a huge amount to study before they could offer useful advice. They would also need to have the same hardware (including a suitable Nissan). (I haven't had a car for 4 years now).

You say

The consult cable works when used with a Serial-USB adapter and a computer to access the information.

. Is this using some off-the-shelf software or some PC code that you have written?

If you have off-the-shelf PC software I suggest that your first step should be to develop your own PC code before trying to get it to work with the Arduino. Programming on the PC is much easier. When it works it should be reasonably easy to transfer your learning to the Arduino.

Maybe there is a web Forum about doing this stuff on a PC?

...R

It is using off the shelf software (ECUTalk, Conzult, a couple others). If one of these programs were open source maybe I could decipher how to read/write from the ECU, but I can't find any that are.

As for programming on the PC - i have zero experience with most PC programming, especially when it comes to hardware input/output. The arduino is actually a little easier for me, since I did have a C+ class back in college. I'm not good by any means, but at least part of the time I can understand the code.

There have been a few other posts on here about this exact topic, and the ones I have found have kind of died without a resolution ever coming about (or if the problem/program was resolved, they never posted back)- so there is a chance people out there are trying the same thing or have done the same thing. I have seen videos on youtube of people using an arduino to communicate with their nissan Consult interfaced ECU, but unfortunately non of those videos post a link to source code, or the link is dead, and archive.org can't bring it back...

Someone out there has done this successfully, I just need to find who.

Any help anyone can give would be awesome. I'm even willing to donate some $$ for some help. Time isn't cheap, and for someone who isn't interested to look through libraries, code, and protocol to figure out why it's not working and how I can make it work is a lot to ask.

Ha a challenge! (but not willing to dive into the libs …)

Can you make a short list of

  • what works as expected
  • what works but not as expected
  • what does not work at all

Q1: can you read any register from the car over the interface?

Can you add a counter in this loop? or a print of millis() to see how long it takes to initialize?

  while (myConsult.initEcu() == false) {
    // Failed to connect
    delay(1000);
    
    // Output to LCD
    lcd.write(ESC); //clear screen
    lcd.write(clr);
    lcd.write(ESC);
    lcd.write(line);
    lcd.write(0x28); //line2
    lcd.print("Failed to connect!!!");  //print on line 2
  }

dived a bit in the lib.

  • The library uses the Serial port at 9600 baud.
  • You could connect to it using a terminal program and a sniffer (logic ananlyzer)

What I do not trust is the only call that seems to work from your post.

// code deliberately not in code blocks to allow highlight


boolean Consult::initEcu()
{
// Byte we will read from ecu
int ecuByte;

// Verify we have set the Serial
if (_consultSerial == NULL) {
return false;
}

// First stop any streams
stopEcuStream();

// Make 2 attempts to init
for (int x=0; x<2; x++) {
// Send init sequence
writeEcu(0xFF);
writeEcu(0xFF);
writeEcu(0xEF);

// Read from ecu
if (readEcuWithTimeout(&ecuByte, 2)) {
if (ecuByte == 0x10) {
// We initialized it!
}
else {
// Already initialized
}
// Send stop command
stopEcuStream();
return true; <<<<<<<<<<<<<<<<<<< there is no condition preventing reaching this statement
}
delay(250);
}

return false;
}


This states I do two attempts and if (it thinks) it can read a byte ( due to static noise?) no matter what I will always return true.

So in short, the lib probably did not make any connection at all but saw some signal on the serial line and interpreted that as a byte.

Way to proceed is to get a logic analyzer and see what is on the line.

Did you connect the TX and RX crossed or not? The TX of the Nissan should probably on the RX of the Arduino and vv.

Hope this helps a bit.

robtillaart - I'm pretty sure you are correct about it not actually initializing. After fiddling with it some last night, I don't think it actually looks for the correct response - it just looks for anything on the RX line. I started by plugging/unplugging the jumper wires that connected the RS232-TTL adapter to the arduino TX/RX lines and found that if I unplugged the RX line it and reset it would give the "failed to connect" message in the code. However - immediately upon connection it would say it was connected, without the TX/RX lights on either the adapter or the arduino flashing(or maybe they just flashed so fast I couldn't see it). It would then continue to say "Connected to ECU" and try to read the two programed values, but always return "could not read value" - even if I disconnected the lines. This morning I did some more fiddling and noticed that If I connected a female RS232-TTL adapter (not connected to anything else) to the male RS232-TTL adapter that is connected to the arduino, it would say it was connected to the ECU, even though it clearly isn't. Then I connected another arduino to the 2nd rs232-ttl adapter and used a software serial/hardware serial echo to send/receive the code from the consult arduino. (see pic) Using this method I confirmed that I can send junk to the consult unit (using the echo unit) and it will say that it's initialized. The info I guess I need to learn more about how this serial communication stuff works.

To answer your requests: What works as expected -All the LCD stuff works as expected. What works but not as expected - the initialize ecu line command/return. (as described above). What does not work at all - everything else. Any time I try to send a command to the ECU using the above code have it send something back - i get nothing.

A1: I've not been able to read any register from the car using arduino- but I'm new to serial communication in hex. I can send to my LCD and the like, but it's reading the serial communications I'm not entirely clear on.

I have attempted switching TX/RX lines, nothing changed. I believe that the arduino TX should go to the adapter TX and the RX should go to the RX. This is based on the fact that if I change them i can't get it to say its connected.

Like I mentioned previously, the consult cable will work with a USB-Serial adapter and my laptop. I have not been able to find any open source software for the Consult Interface. Maybe I can use a serial sniffer program on the virtual serial port to see what the PC is sending/receiving over the serial port?

I'll do some research on what is needed for the sniffer program and logic analyzer for the arduino.

Thanks for your elaborate explanation...

possible actions I can think of - Can you check with a voltmeter if the GROUNDS are connected, so the electronics share a common reference?

  • Does the RS232 connect really need the TTL level convertor? is the RS232 12V if the voltages get too low, communications fail.

  • Connect the laptop and use an Arduino as sniffer?

So, after working on this a little more, I believe the issue is the RS232-TTL adapter not communicating correctly with the consult adapter. The way i tested this is using two adapters, one male & one female, and hooked them up to eachtother- rx to tx and tx to rx. Gave them both 5V and tried to see if it would just pass the signal from the USB adapter through - it wouldn't.

SO.....my next idea is to use a USB host shield along with the USB cable (based on the profilic 2303 chip) I have and see if that will work. I did get some serial data sniffed using a software serial sniffer so I can try and emulate those commands via the shield. Only problem - I doubt anyone has any libraries for this and I'm not good enough at programming to write my own since I doubt it's as simple as just sending the commands and listening for reply. I'll do some more research on the usb shield and see if that helps or not...

so a bit of an update to this, I found a person in europe who did this a while back with a serial interfaced arduino (the freeduino max serial). They don't make the boards anymore, but NKC had had some PCBs for them, so I ordered a couple PCB and the components to build my own. Hopefully I can get it to work without needing a USB interface - I was reading up on it and i'm not sure it would work at all.

In the meantime I'm trying to learn to write my own library for this instead of using the existing. The existing one may work, but it's good to learn. Where i am at now is trying to figure out how to translate any data that the ECU sends back to something usable - particularly in the case of the data that is more than one byte.

Another update.

Using the other program I found I was able to get the consult adapter to work and display data correctly. Seems the previous library didn’t do a good job of connecting with the ecu. the good news is that with the new program I was able to get it to interface using a RS232-TTL converter, so I will be able to use my Mega and maybe do some data logging as well as add some other features that I was wanting.

I’m using the interface and initialization logic from the other program I found an implementing it into a new program along with a couple other features (wideband o2, boost pressure, etc) as well as eventually doing some data logging.

Robtillart - thank you for the assistance in helping figure the library was wierd. Now that I found something that works I can go down a road that I know will lead to success.

Welcom, if you need help to build the library you know where to find me :)

basicmods: Another update.

Using the other program I found I was able to get the consult adapter to work and display data correctly. Seems the previous library didn't do a good job of connecting with the ecu. the good news is that with the new program I was able to get it to interface using a RS232-TTL converter, so I will be able to use my Mega and maybe do some data logging as well as add some other features that I was wanting.

I'm using the interface and initialization logic from the other program I found an implementing it into a new program along with a couple other features (wideband o2, boost pressure, etc) as well as eventually doing some data logging.

Robtillart - thank you for the assistance in helping figure the library was wierd. Now that I found something that works I can go down a road that I know will lead to success.

Do you have a link to the other code? I am also trying to do this.

basicmods: So, after working on this a little more, I believe the issue is the RS232-TTL adapter not communicating correctly with the consult adapter. The way i tested this is using two adapters, one male & one female, and hooked them up to eachtother- rx to tx and tx to rx.

Did you try swapping this so you connected RX to RX an TX to TX. This is needed sometimes because of the way equipment is classified as eithe DTE or CTE. This main a TX can be an input or an output. Check that you were connecting an input to an output and not two outputs together.

basicmods:
the good news is that with the new program I was able to get it to interface using a RS232-TTL converter, so I will be able to use my Mega and maybe do some data logging as well as add some other features that I was wanting.

Hi!
I want to create device like you.
Can you plz explain for what purpose did you use RS232-TTL converter ? Why do not connect uart (tx-rx) to rs232 on consult adapter ? Seems Crim didn’t use any converter at all.

RS232 uses much higher voltages than TTL level Arduino. A direct connection WILL damage the Arduino

basicmods: Another update.

Using the other program I found I was able to get the consult adapter to work and display data correctly. Seems the previous library didn't do a good job of connecting with the ecu. the good news is that with the new program I was able to get it to interface using a RS232-TTL converter, so I will be able to use my Mega and maybe do some data logging as well as add some other features that I was wanting.

I'm using the interface and initialization logic from the other program I found an implementing it into a new program along with a couple other features (wideband o2, boost pressure, etc) as well as eventually doing some data logging.

Hi! I have the same problem with initializing ecu. Basicmods, can you share your scetch, plz? At least initialiazing part ? I'm having Mega 2560 and ttl-rs232 converter.

robtillaart: RS232 uses much higher voltages than TTL level Arduino. A direct connection WILL damage the Arduino

Thnx! Now i use rs232 ttl converter. But still don't know how to initialize ecu.

I apoligize for the delay, for some reason I haven't been getting emails that there were updates to the thread.

As far as the code that I got to work - it was some code that I borrowed from a nice member named vojta78 of nissanclub.cz; his youtube video has a link to his code. It does work with a serial arduino.

here is a link to his youtube video showing what his code does. The link to his working code is included in his description.:

https://www.youtube.com/watch?v=ARcLRkK-4Mc

I've kind of stopped working on this project as I have a new ECU for my car (NismotronicSA) that does not support consult output (it uses the consult connection to log the data internally). There is an interface for the Nismotronic to use an external screen, however the developers do not want to release the interface protocol.

Hello,

Google users working on Nissan Consult and arduino, please drop a note of what you’re doing and your results so far.

Hi, sorry for bringing up an old topic, but I started to work on exactly same project. I need some help and I believe I’ll be able to contribute later with my results.

First things first - I’m building the cable myself. I will also want to try it with a PC via USB before working further with Arduino.

So as far as I understand - I can skip all the MAX232 part, since I don’t need to convert ECU serial signal to RS232 and then back from it to USB, right? I just need to cross-over the Tx/Rx lines, correct?