Help setting up interface for 7 car signals

Dear all,

I am stopped with this problem. I don´t know how to make my voltage dividers to get optimal signals for Arduino from my car 12V sensors (ratiometric).

I started with 2k and 1k resistors to get 1/3 of the 12 volts, but am having trouble getting good signals.

Any help or suggestions?

Thanks,

OldBeaver

Perhaps you could tell us what kind of sensors you are trying to interface with, how they are connected, and what kind of problems you are having.

Dear All, and PaulS,

Ok, tks…

I have a scheme that represents my project. Don´t know how to attach it. It is in word.

But in brief it is has 5 parts:

The 7 car sensors. Output: 12V signals.
The voltage divider interface board. Output 5V signals
The Bares Bones Arduino board with the microprocessor
The 20x4 LCD display as visible output
The processing code

The signals are:

Analog:

engine temperature sensor
fuel tank level sensor
throttle position sensor (pot)

Digital:

engine rpm sensor
car speed sensor
fuel flow meter 1 sensor
fuel flow meter 2 sensor

The problem I am having is how to setup the 7 voltage dividers as to provide Arduino with a 5V or less signal, and, at the same time, not to fade (loose) the signals.

The ANALOG signals code I have at present is here:

// ============ ANALOG SIGNALS PROCESSING ==============
// ----------- Tank level reader, analog 3 --------

#include <LiquidCrystal.h>

// -------- reset pins, define pins, variables -----
float tank, x; // fuel tank level, aux
int throttle, y; // throttle position, pot
int temp, z ; // temp, aux

/* ------- create object to control an LCD GMD1602K -------*/
LiquidCrystal lcd(12, 14, 11, 7, 8, 9, 10);

void setup(){
digitalWrite(5,HIGH); // enables pull-up
digitalWrite(1,HIGH); // enables pull-up
digitalWrite(3,HIGH); // enables pull-up
lcd.begin(20,4);
lcd.clear(); // clear screen

}

// ======= Execute program over and over ===========
void loop(){
tank = analogRead(3)/3.3; // read & correct sensor value
lcd.setCursor(0,1); lcd.print(“Tank:”); lcd.print(tank); // display sensor value
x = -0.0001846tanktanktank + 0.0043404tanktank -0.258316tank + 56.194; //corrects to fuel tank shape (lt)
lcd.setCursor(9,1); lcd.print(x); // display shape corrected sensor value
map(x,66.2,0,1,60); lcd.setCursor(17,1); lcdPrintFloat(x,1); // mapped & corrected fuel tank level value

// ======= Process trottle position analog 5 =======

throttle = analogRead(5); // reads throttle position pot
y = map(throttle, 0,12,5,100); // remaps signal value

// ----------- print throttle position ---------
lcd.setCursor(0,2); lcd.print(“Tht:”), (throttle); // prints signal value
lcd.setCursor(10,2); lcd.print,(y); // prints mapped throttle position

// =========== Temperature sensor Analog 3 =======

temp = analogRead(3); // reads temp of fuel return pipe
int temp;

// ----------- print temp of return fuel pipe ----------
lcd.setCursor(0,3); lcd.print(“Temp:”); lcd.print(temp);
z = map(temp,0,100,0,100); // remaps temp values
lcd.setCursor(10,3); lcd.print(z);
delay(100);
}
// ============== END of Program ============

/* -------------- Function LcdPrintFloat ---------------- */
void lcdPrintFloat( float x, byte precision){
// precision is from 0 to 6 indicating decimal places

if(x < 0.0){
lcd.print(’-’);
x = -x;
}

lcd.print ((long)x); //prints the integer part
if( precision > 0) {
lcd.print("."); //prints decimal point
unsigned long frac;
unsigned long mult = 1;
byte padding = precision -1;
while(precision–)
mult *=10; //“amplifies” decimal values

if(x >= 0)
frac = (x - int(x)) * mult;
else
frac = (int(x)- x) * mult;
unsigned long frac1 = frac;
while( frac1 /= 10 )
padding–;
while( padding–)
lcd.print(“0”);
lcd.print(frac,DEC) ;
}
}

The DIGITAL signals processing code is here:

// ============ DIGITAL SIGNALS PROCESSING ===============

// --------- Millis between pulses for Speed ---------
// -------------- Input on Digital 5 ----------

#include <DateTime.h>
#include <LiquidCrystal.h>

/* -------reset pins, define pins, variables ------------- */
int resetPin = 1; // pin 1 resets the time
int y, zz; // aux
int xx,yy; // aux var for pulse printing
volatile byte InCount1 = 0; // declare this as a byte if the count is always less than 255
volatile byte InCount2 = 0; // declare this as a byte if the count is always less than 255
// so don’t have to disable interrupts when using in loop
float ml1, ml2; // milli litres of fuel volume in each fuel flow sensor

/* -------- create object to control LCD -------*/
LiquidCrystal lcd(12, 14, 11, 7, 8, 9, 10);

void setup(){
// ---------------- Configure pin modes ------------------
pinMode(1, INPUT); // a button on this pin resets the time
digitalWrite(5, HIGH); // enables pull-up
digitalWrite(4, HIGH); // enables pull-up
pinMode(2, INPUT); // define input pin
digitalWrite(2, HIGH); // Turn on pullup resistor
attachInterrupt(0, count1, HIGH); // call count1 when pin goes high

pinMode(3, INPUT);
digitalWrite(3, HIGH); // Turn on pullup resistor
attachInterrupt(1, count2, HIGH); // call count2 when pin goes high

DateTime.sync( 0 ); // set time to zero
lcd.begin(20,4);
lcd.clear(); // cleans display
}

void loop(){
// -------------- Process Speed sensor signal ----------------
lcd.setCursor(0,1); lcd.print("Pulse "),(pulseIn); // print pulseIn signal for tracing
zz=1800/pulseIn(5,LOW,1000); // convert to speed
lcd.setCursor(7,1); lcd.print("Speed " ), (zz); // print speed
constrain (zz, 0, 160); // constrain to min & max values
lcd.setCursor(14,1); lcd.print(zz); // print constrained speed

// --------------- input fuel flow pulses ---------------------

if(digitalRead(2) == LOW)
{DateTime.sync( 0 ); // reset time to zero if button pressed
}
if(digitalRead(3) == LOW)
{DateTime.sync( 0 ); // reset time to zero if button pressed
}
// --------------- print pulses count1 on LCD ---------------
lcd.setCursor(0,3); lcd.print(“Sig1:”); lcd.print(InCount1); // print pulse signal 1
lcd.setCursor(7,3); lcd.print(“Hz1:”); xx = constrain(InCount1,1,1000); lcd.print(xx); // print constrained pulse count 1
lcd.setCursor(14,3); lcd.print(“ml1:”); lcdPrintFloat(0.166667*xx,1); // print pulses volume1 in mili liters
delay (100);

// --------------- print pulses count2 on LCD ---------------
lcd.setCursor(0,4); lcd.print(“Sig2:”); lcd.print(InCount2); // print pulse signal 2
lcd.setCursor(7,4); lcd.print(“Hz2:”); yy = constrain(InCount2,1,1000); lcd.print(yy); // print constrained pulse count 1
lcd.setCursor(14,4); lcd.print(“ml2:”); lcdPrintFloat(0.166667*yy,1); // print pulses volume1 in mili liters
delay (100);

/* -------- Process of RPM sensor ----------------*/

lcd.setCursor(0,1); lcd.print("Signal: "); y = 60000/pulseIn(5,LOW,1000); lcd.print(y); // print signal pulses
y= constrain(y,500,4000); lcd.print(“Rpm:”),(y); // print constrained signal pulses
delay(100);

}

// --------------- Function count1 ---------------
void count1(){
InCount1++;
}
// --------------- Function count2 --------------
void count2(){
InCount2++;
}

// -------------- Function LcdPrintFloat ---------
void lcdPrintFloat( float x, byte precision){
// prints val on a ver 0012 text lcd with number of decimal places determine by precision
// precision is a number from 0 to 6 indicating the desired decimal places

if(x < 0.0){
lcd.print(’-’);
x = -x;
}

lcd.print ((long)x); //prints the integer part
if( precision > 0) {
lcd.print("."); //prints decimal point
unsigned long frac;
unsigned long mult = 1;
byte padding = precision -1;
while(precision–)
mult *=10; //“amplifies” decimal values

if(x >= 0)
frac = (x - int(x)) * mult;
else
frac = (int(x)- x) * mult;
unsigned long frac1 = frac;
while( frac1 /= 10 )
padding–;
while( padding–)
lcd.print(“0”);
lcd.print(frac,DEC) ;
}
}

Both processing codes parts are compiling OK.

THE PROBLEMS I AM HAVING:

The main problem at this time is to define the resistors for the voltage dividers, as at present I get some bad signals or no signals and I don´t know for sure if it is a voltage divider problem or a wrong code problem.

At present what I have is a 2200 ohm resistor: (A 2200k B). In side A of this resistor I connect the input 12V signal. In side B I connect a 1000 ohm to ground. The output 5V signal is taken from the junction of both.

But one can get a 5V signal with several values of resistors. Which are the optimal ones? That is my problem. At least, this is one of them.

Please, help.

Thank you much in advance.

Some code issues:
lcd.setCursor(0,1); lcd.print("Pulse "),(pulseIn);     // print pulseIn signal for tracing:

(pulseIn); is doing nothing. Why is it there?

lcd.setCursor(7,1); lcd.print("Speed " ), (zz);    // print speed

Same question about (zz);

The 2200 Ohm resistor and 1000 Ohm resistor form a voltage divider. The total resistance is 3200 Ohms. The voltage drop is linear. So the voltage at the junction will be 1000/3200 times the initial voltage (12). According to my calculator, that works out to 3.75 volts. The input signal varies from 0 to 12V, so the voltage divider is dropping that to 0 to 3.75V. You may want a smaller resistor in front (in place of the 2200 Ohm one) or a larger one in back (in place of the 1000 Ohm one).

The actual size of either of the resistors is not all that critical. The ratio is.

What is important is that the current through the resistors be less than what the resistor can handle. Mr Ohm melted a lot of resistors to come up with his law.

Use the correct wattage resistors, regardless of the size. Larger resistors will allow less current to flow, so less wattage.

Another thing: at 146 posts, maybe you could use the "Code" (#) button?

You'll also need to make sure that the resistor values don't limit the supply current too much such that the devices powered downstream begin to brown-out.

It would be better advised to use a voltage regulator rather than resistors.

You can not use a voltage regulator on the actual signal lines but you may find that the sensors will work just as well if fed with a regulated 5volts (not from the Arduino tho).

Most sensors are just variable resistors and these will probably work fine at 5v supply but if the outputs are pulses then voltage divider circuits are the only way to go on the output side. A previous poster has given good advice on these, just use the lowest value resistors that the units can handle. Resistors in series add together the simple formula is 12v divided by the TOTAL resistance will give the current flowing. So 2200 + 1000 equals 3200 at 12 volts equals 3.75 milliamps which is very low and may be OK. As previously said RATIO's is the important thing. Dont reduce the total current flowing too low because your signal will pick up too much interferance from the engine. It is also better to put the divider right next to the Arduino not the sensor, for the same reason. I hope this helps a bit. John 8-) 8-)

A further idea maybe to get equal resistors in your divider say 2 X 2200 that will give you a max 6volts but the max sensor output will probably never reach max anyway. Because that will be at the limit of the sensor.

Now a warning.....

Another thing you need to think of is where is the 12v coming from? If it is the car, then this could be as high as 14.5 and when this is the case all your calculations will be wildly out. To be really accurate (and safe) you may want to consider a 12v regulator to feed the sensors anyway (unless the sensors will work at 5V) Regards John 8-) 8-) 8-)

Yet another thought.
In the case of the digital signals just limit them to 5 volts with a resistor and a 5v zenner diode. It is the number of pules here not their size that counts.
You shouldnt get any interferance here.

The zenner should connect to ground on one side (neg side) the positive side should go to the Arduino pin also to a 2200 resistor. The other side of the resistor will go to your speed sensors which appear to be digital pulses.
If your pulses dont make it to 5 volts you may need to reduce the resistor but unless you have an oscilloscope to see the pulses dont reduce it below 1000 ohm.
The Arduino will still register a digital voltge as high even if it is only about 3v3.

You will only need the smallest rated zenner diodes you can get cuz the current is minimal they cost pence from maplins or tandy (depending where you live)

John

:sunglasses: :sunglasses: :sunglasses:

Thanks a lot for the several responses.

I am going to answer any of them, in order.

To John Sidle,

Tks for the idea, use a zener diode to cut the voltage, however it will not cut the pulses. Right. I will need one zener for each signal. The problem here is the impedance, which is something I don´t know how to calculate when you connect two circuits.

Yes, the car voltage is over 12V, in fact, it is 13.8 volts when the engine is running. That is why I was using 2200 ohm and 1000 for the volt divider.

I work alone. I have to test speed with the car in motion, for example. not easy. The task of putting one resistor, take a raid, measure in motion, then put another and so on, is time consuming and difficult. Even dangerous. That is why I want to start, at least, with the "correct" value instead of making so much experiments for each signal.

The same is for rpm and fuel flow, but at least in this case I can do the tests stand still.

The analog signals should be easier.

For easing the problem, I constructed a signal generator and used the notebook as osciloscope. With the osciloscope I can see the pulses in the sreen. But audio osciloscopes (PC computers oscilloscopes are audio based) receive too much interference even from the computer itself.

That is the reason I have asking for correct values for this. As Arduino pins are well known, their input impedance should be well known too by someone in the Forum.

I am a little confused because in other post you said I cannot use a zener and only a voltage divider with digital signals. Can you clarify this please?

Regard the position of the divider, I am aware of it, it is close to Arduino and not to the sensors.

Thank you much.

Mitch: I am trying to learn if zeners or voltage dividers. Anyway, using regulated 5 volts to energize the sensors is a hard task: the speed sensor, the fuel tank, the temp sensor, the rpm sensor. Only the two fuel flow sensors I installed would be easy.

Awol: Yes, you are right, I should use the special features for including code. And for including pictures too. However, for reasons unknown, the majority of ocasions they both do not work for me. I have lost so much time trying to do that! Something else I would like to show are circuits, diagrams, but I cannot. Sorry for that.

Maybe if you tell me exactly how to use these, step by step, I may learn once for all. Thank you for your comments.

PaulS: I will check the code. I made some editing for shorten the program. Anyway, lcd.print("title"), (variable) works fine with Arduino Ver. 17. I tried and voila!, it worked. Try it.

About voltage divider: in fact, car voltage is always over 12V, mine goes to 13.8 V with the engine running.

Ratio is the important thing, I am aware of that. And one can get the ratio with several resistors combinations, taking care of the current to avoid too high currents. I manage myself on that (Ohm´s Law). What is not in my electronics knowledge is "impedance". The only thing I know is that output impedance of circuits and devices are kept low and input impedances are kept high. The reason is to avoid that the input current is too high affecting the quality and values of the input signal coming from the previous circuit, they said.

However, I don´t know output impedances of sensors, nor input impedances of Arduino input pins, nor how to calculate them. Maybe someone can teach us a little about it.

Thank you for your thoughts and time.

Thank you all.

OldBeaver

Ok to clarify my points To limit the Digital pulses I would use a zenner and resistor. One on each signal line. The zeners will not stop (unless you have connected it the wrong way round) the pulses it will clamp them at the zener voltage which should be 5v or maybe even 4.8volt as long as it is over 3v3 the Arduino will like them. That means they will rise but be held at the zener voltage. You are limiting the pulse heights NOT the power to the DIGITAL (speed sensors etc) and certainly not the number of pulses.. The supply voltage to these sensors is immaterial.

The input impedance of the Arduino is tri-stated which is very high so you can ignor it. It is voltage fed not current fed. 2200ohm should be fine, it will not load your sensors since it will only come into play once the zener starts to limit.

Now my first post.... I can not find the words you quoted.

I am a little confused because in other post you said I cannot use a zener and only a voltage divider with digital signals. Can you clarify this please?

I think I started my post off by stating that you could not use a regulator on the signal lines..... I was responding to a previous post that ended by saying that perhaps you should use a voltage regulator.... This seemed to imply that you should use one on the signal lines. I was saying that this is not valid. maybe I read it wrong.

With regard to the analog lines (resistive sensors) if you are supplying them with voltages ranging from 12volts to 13.8volts (normal for a car) your readings are going to be all over the shop and mean not much. It will depend on engine speed and whether the lights are on etc and state of the battery. Again input impedence to the Arduino is high so you can ignor it.

Better to supply them with a regulated source 5v if possible using a 7805 regulator chip since you need a 0-5v voltage swing. But if they are not resistive and will not work at 5v then use a 7812 regulator but if you use this you will need to use a divider network on the signal lines to reduce the voltage swing to 0 to 5 or 6volts. One network for each signal line Again input impedence to the Arduino is high so you can ignor it. 2200ohm resistors should be fine.

We all work on our own that is why we have the forums to help us, but forums can not do all the work. We can not calculate impedances if we do not know the impedance of the source. If your sensor data tells you it has a 1000 ohm impedance then the maximum power will be transmitted if the destination impedance is also 1000ohms. But you are not transmitting power but almost open circuit voltages. You are getting too deep when you dont need to. Obviously some experimentation may be needed on your part under guidance from the forum.

One final point... Make sure that the Arduino internal pullup resistors are not enabled otherwise you will have a problem cuz you will be supplying 5v (sourced from the Arduino) to all your readings.

I hope this helps John 8-) 8-) 8-)

It helps indeed.

Ok to all John,

Thanks a lot for the help.

I had a previous Arduino board clone, to which I had almost all signals working. However, the structure of the project was awful and had other problems. Besides, I burned several pins cause of higher than 5V signals. Finally, I decided to start over with a better construction.

Then several things that were working are not any more.

Ok to the impedance issue, tks for the advice.

Be sure no to activate the pullup resistors? Ok.

Well, for better understanding of your advice, I will study a little bit those concepts.

Thank you again, I will keep the Forum informed with my progress.

OldBeaver

You are welcome. John :D :D :D