Reading 12v analogue & digital signals in an automotive environment

Hi all!

I'm building a device for my car and need to read a number of input signals from the car - some analogue and some digital, all 12-15v. I guess the best thing to do is use a voltage divider and reading up on this forum it seems that a big divide around 1:14 might be a good idea using 3k3 from analogue to ground and 47k from pin to source.

Since I have a number of them, I want to keep the circuit nice and simple so I can replicate it. Is the above a sensible approach?

I guess the best thing to do is use a voltage divider and reading up on this forum it seems that a big divide around 1:14 might be a good idea using 3k3 from analogue to ground and 47k from pin to source.

Why do you think a ratio of 1:14 would be helpful? If you connect 12V to the divider, what voltage will that give at the Arduino input? What voltage do you need?

Is the above a sensible approach?

In principal, yes.

Since you say this is an automotive environment, are you capable of reading the values of these sensors from OBD-II? These days implementing OBD-II on Arduino isn't so bad, and opens up a lot of possibilities for future projects.

For the digital inputs I'd use an [u]over-voltage protection circuit[/u] instead of a voltage divider, because the "12V" does vary and the protection circuit will hard-clamp the voltage to just-over 5V. (I'd use a higher-value resistor than the example, maybe 10K.)

For the analog inputs a 3:1 voltage divider should work and I'd add a "protection diode" in case there are unexpected voltage spikes.

Katemonster33:
Since you say this is an automotive environment, are you capable of reading the values of these sensors from OBD-II? These days implementing OBD-II on Arduino isn't so bad, and opens up a lot of possibilities for future projects.

Actually the first version of my code used OBD, but then I found out that my new engine runs GM Lan - a General Motors variant of CAN Bus and uses two single wire CAN channels (CAN H and CAN L). I had a little Google and really couldn't find much on this manufacturer specific CAN Protocol so gave up on this route and decided just to interpret the vehicle harness instead. Having said that, overnight I realised that most of these sensors are likely to be 0-5v, though I guess I'll need to be sure that they can't exceed 5v. For these reads (fuel level, temps and pressures), can I just wire in the raw signal or will I need to put a zener on there just in case?

DVDdoug:
For the digital inputs I'd use an [u]over-voltage protection circuit[/u] instead of a voltage divider, because the "12V" does vary and the protection circuit will hard-clamp the voltage to just-over 5V. (I'd use a higher-value resistor than the example, maybe 10K.)

For the analog inputs a 3:1 voltage divider should work and I'd add a "protection diode" in case there are unexpected voltage spikes.

For reading analogue, I found this thread which seems to have a neat prefab solution:

https://forum.arduino.cc/index.php?topic=416888.0

For digital my thought is to use a PC817 opto-coupler with a 10k resistor in line with the supply, and the Arduino internal pullup for the reading side.

450nick:
Actually the first version of my code used OBD, but then I found out that my new engine runs GM Lan - a General Motors variant of CAN Bus and uses two single wire CAN channels (CAN H and CAN L). I had a little Google and really couldn't find much on this manufacturer specific CAN Protocol so gave up on this route and decided just to interpret the vehicle harness instead. Having said that, overnight I realised that most of these sensors are likely to be 0-5v, though I guess I'll need to be sure that they can't exceed 5v. For these reads (fuel level, temps and pressures), can I just wire in the raw signal or will I need to put a zener on there just in case?

I actually work in automotive diagnostics, so I can shed some light here.

GMLAN refers to the proprietary portion of your cars electronics software. It's really just an addendum to OBD-II. If you're just trying to read emissions related data like standard sensors (O2 sensors, engine RPM, etc) you can use OBD-II over the two CAN wires you spoke of. An ELM-327 should accomplish this easily.

Now if you need to read more specific data, especially body-related stuff like your HVAC system, or if you want to run special tests (like activating the EVAP solenoid on or off), that's where GMLAN comes in. I hope that clears it up.

Anyway, if you're more comfortable reading the raw sensor values, yeah I'd say a resistor divider with maybe a diode to prevent the arduino from back feeding current into the ECU, that should get you what you need.

Well this is extremely interesting - I had totally written the idea off... Thank you so much for responding in this case! The problem I have is that the engine is still in a box and the car isn't built yet so I can't test the instrument cluster I'm building other than with an Arduino CAN simulator that I picked up from Skpang.co.uk. I have however designed into the PCB the ability to read both CAN H and Can L using the Arduino RX & TX inputs respectively in case I fancy adding the functionality later.

It's a crate LT4 motor so it won't have anything in there other than engine diagnostic data so hopefully everything I would need would be on the conventional protocol which sounds nice... To read this then would I simply wire CAN H to Arduino RX and CAN L to TX and then run my CAN bus code?

GM ECM Manual

Page 9 shows the outputs I can tap into from the ECM Harness. I would rather use the CAN Bus if feasible...

450nick:
To read this then would I simply wire CAN H to Arduino RX and CAN L to TX and then run my CAN bus code?

No, that won't work.

CAN is a bi-directional bus where the two wires (H for High and L for Low) carries the same signal, just being out of phase (look into 'differential signalling', it's a way to cut down on noise)

To talk with the CAN-bus you need a special chip that's called a CAN Transceiver or CAN PHY. This will convert the electrical levels to something that your Arduino can work with.

// Per.

Zapro:
No, that won't work.

CAN is a bi-directional bus where the two wires (H for High and L for Low) carries the same signal, just being out of phase (look into 'differential signalling', it's a way to cut down on noise)

To talk with the CAN-bus you need a special chip that's called a CAN Transceiver or CAN PHY. This will convert the electrical levels to something that your Arduino can work with.

// Per.

Thanks Per - like this one? http://www.ti.com/lit/ds/symlink/sn65hvd233-ht.pdf

Any idea how you wire it up in my case to plug into the arduino?

[EDIT] This looks feasible - is it correct for my application? Also, what is JP1 doing...? Can I get rid of it?

I was about to suggest the IC in your edit - that looks better. Use a 5V one over a 3.3V one, it'll be easier to interface with an Arduino.

JP1 performs something called bus termination - in your car, one of the ECU's has that 120 ohm resistor between CANH and CANL. I believe most engine ECUs do. For your application, it might be safe to exclude that jumper, but if you have trouble in the future I'd just add the resistor between CANH and CANL without the jumper.

Once you get to the point where you're able to see bus traffic on the RX pin we can start talking about message structure.

Great, thank you very much for your help! I would love some help with the code once I've got the board design complete.

Do you know if it's possible to get a list of available data from the ECU I'm planning to use? I'm not sure what it will be able to provide...

Also, the vehicle speed sensor in this setup comes from a 17 tooth sensor on the T56 Magnum gearbox. I guess the ECM doesn't care about the speed, just whether the car is moving or not? In which case, the speed reading will need to be scaled in the code if I'm pulling it from CAN Bus - is that correct?

Assuming you can get the ECU wired up to an OBD-II port, there's a set of messages using mode $01 (the "read data" service in OBD-II) that will tell you what sensors are available to read. You can do that using the Arduino.

The ECU has a latch for "vehicle moving / not moving" in its code I'm sure, but you should be able to get the actual vehicle speed value in mph / kph from OBD-II. From the bus you'd request ID $0D using OBD mode $01, and the value you get is the speed in kph as a single byte (thus, 0 -255 kph) and you'd need to run the conversion to convert it to mph if you need those units.

Katemonster33:
Assuming you can get the ECU wired up to an OBD-II port, there's a set of messages using mode $01 (the "read data" service in OBD-II) that will tell you what sensors are available to read. You can do that using the Arduino.

Great, I'll drop you a message when I'm a little further along if you don't mind to find out a little more about how to do this properly (I had a working CAN reader to pull specific PIDs but nothing more than that yet).

Katemonster33:
The ECU has a latch for "vehicle moving / not moving" in its code I'm sure, but you should be able to get the actual vehicle speed value in mph / kph from OBD-II. From the bus you'd request ID $0D using OBD mode $01, and the value you get is the speed in kph as a single byte (thus, 0 -255 kph) and you'd need to run the conversion to convert it to mph if you need those units.

Cool, I think the LS ECU is expecting to see a 40 tooth wheel on the final drive, so probably this gearbox with a 17 tooth wheel in the gearbox (before the final drive ratio) is going to have the ECU thinking it's going a very different speed than usual. In this case I guess I can just work out the scaling and do this in the Arduino code (so long as the ECU isn't looking for the real speed and only whether it's moving or not).

Oh are you wanting to have the Atduino massage that 17 tooth into a 40 tooth for your ECU? Its possible , but IMO you might be better off just getting a 40 tooth gear custom machined for your application. Up to you though.

No not exactly, I need to check, but I hear that the standard LS/LT V8 ECU usually runs off a 40 tooth wheel in its natural habitat with an auto gearbox, but in this case it's being offered as an aftermarket crate motor, T56 Magnum manual gearbox, which comes as a package from GM. Usually for this kind of setup you would put a 40 tooth wheel on the differential output and run the signal back to the ECU and would then need to correct it for any difference in tyre circumference but here the gearbox has it's own speed sensor built in. This is a neater solution but it it is pre-differential so will be affected by any difference in both tyre circumference and final drive ratio. Part of me thinks that as the motor and gearbox comes as a package, the ECU should be pre-tuned to use this speed sensor, but even if they did it could still be wrong unless I get lucky with my final drive ratio choice and tyre circumference. So either way the ECU is probably going to see the wrong speed unless I make some sort of scaling board and put it between the ECU and the speed sensor, but then that's another thing to go wrong so if the ECU doesn't care what the speed actually is, rather that there just is motion or not, then I can just do the scaling in the arduino code when converting from kph to mph for use in my display...

Quite a long explanation but hopefully it makes sense! In short, to your point the answer is yes :slight_smile:

[EDIT] As the 17 tooth wheel is inside the gearbox, it would be very difficult to change so it's a case of use it or not...