A friend of mine has asked me to help create a digital dashboard for his racing car (Renault 5 GT Turbo MKII from 1989). For this project I have thought to use an arduino Mega and a 7 "nextion screen. I like to do things with arduino but I don't have all the necessary knowledge. This is going to be a long project I think.
This car does not have any ecu or obd from which to obtain the data, so I used its current analog gauges to know the values of the sensors that I need (Oil pressure, Oil temperature, Water temperature, Turbo pressure and battery voltage.
To measure the values I have fed each gauge with a 12v and 1.5 Amp power supply. plus a 10K potentiometer. By varying the potentiometer and checking the indicator, I was able to obtain the values in volts for each scale part.
For example. in water temperature at 40ºC they are 4.5v and at 100ºC they are 3v.
I have reviewed code samples to measure sensors and display the value on the screen, but they all use ohms measurements.
How can I use the voltage to correctly indicate the values on the screen?
Any ideas or suggestion?
Have you used analogRead() before? It takes a continuous voltage between 0 and 5 volts as input and converts it to a 10 bit digital number (i.e. 0 to 1023). Is this what you need, or have I misunderstood?
A friend of mine has asked me to help create a screen for his racing car (Renault 5 GT Turbo MKII from 1989). For this project I have thought to use an arduino Mega and a 7 "nextion screen. I like to do things with arduino but I don't have all the necessary knowledge. This is going to be a long project I think
This car does not have any ecu or obd from which to obtain the data, so I used its current analog gauges to know the values of the sensors I need (Oil pressure, Oil temperature, Water temperature, Turbo pressure and battery voltage.
To measure the values I have fed each gauge with a 12v and 1.5 Amp power supply. plus a 10K potentiometer. By varying the potentiometer and checking the indicator, I was able to obtain the values in volts for each scale part.
For example. in water temperature at 40ºC they are 4.5v and at 100ºC they are 3v.
I have reviewed code samples to measure sensors and display the value on the screen, but they all use ohm measurements.
How can I use the voltage to correctly indicate the values on the screen?
Any ideas or suggestions?
Thank you for your answers.
If I have used the analog read before. So ..... Can I use it to indicate the voltage value to display on the screen?
Something like;
int analogPin = A3; // signal from water temp sensor connected to analog pin 3
// outside leads to ground and +5V
int val = 0; // variable to store the value read
void setup() {
Serial.begin(9600);
}
void loop() {
val = analogRead(analogPin); // read the input pin
Serial.println(val); // debug value
}
Great! All that remains is to map that to a real temperature using your reference points, i.e. 4.5 V = 40 degrees and 3 V = 100 degrees. You can do that manually in your code or you can use the map() function tehboris mentions.
One general note though: you should make sure you never exceed the maximum rated input voltage to the pins, which is usually 5 V. If your sensor will exceed that then you can use a simple voltage divider to bring it within range. Of course, then you would need to adjust your mapping in the code to accommodate the change.
Let us know how you get on - sounds like a cool project!
It’s occurred to me that maybe it’s the mathematical part that might be helpful to explain.
Since you’ve only taken readings at two points then the best you can do is assume the voltage changes linearly with the temperature (which may well be a good enough approximation in the operating temperature range).
You could try implementing this conversion in your code:
temp = 220 - 0.1953 * val
That’s just the equation of a straight line which passes through your two measured points, with the 0 to 5 V range changed to 0 to 1023 to deal with the val from analogRead().
You could always take one or more further measurements with your sensor to validate the assumption of linearity or, in doing so, you may decide you wish to use a nonlinear function. All totally doable.
Hello. Thank you for taking your time to reply to me.
Tom; analog inputs never exceed 4.87v. checked
R11K; I have checked the values at different points on the gauge and I doubt their linearity .... these are the values obtained for example on the water temperature gauge.
40ºC - 4.50v
80ºC - 3.80v
90ºC - 3.50 V
100ºC - 3.00v
110ºC - 2.70v
120ºC - 2.20v
more than 120ºC - 0.20v
possible margin of error in 0.10v measurements
Thank you very much for your help. I promise to share the progress of the entire project.
This is a second order polynomial (a quadratic) which attempts to approximate the response, which is clearly not linear.
Have a look at the plot to see if the approximation makes sense to you (it can always be tweaked and I could easily have made a mistake with your datapoints).
If you’re interested in how I did that I used MATLAB’s polyfit() function to fit a polynomial of order two to your measurements. I think the quadratic approximation seems better as, like you said, it’s not linear.
You’ll probably just have to think about how to implement the conversion in your code.
Like I said, that function can be tweaked. I think you just need to make sure you’re happy that whatever function you use is suitable for the whole range of expected values. For example, do you need to know what happens much above 120 degrees? Maybe not if that’s outside the possible range.
But it’s worth acknowledging that the quadratic will reach a maximum predicted temperature as voltage decreases, them start to fall again. This is completely fine as long as the part of the curve in your operating range fits your needs.
I’ve just included another plot that extends the input right down to zero so you can see what I mean.
EDIT 2: Actually, something just popped into my head based on what you said about the output being less than 0.2 V above 120 degrees, so I took the liberty of adding another datapoint at (0.2, 125), then fitted a third order polynomial in the same way. You might think this results in a better approximation.
It's unusual for an automotive temperature sensor to have an operating range that doesn't extend down well below zero. -40oC is a common lower limit. You should try to gather some data points with the sensor in ice-water and in a freezer to understand what it does when cold.
Thanks for your help, I don't really understand how you get those lines (I already have to study at night). I will try to implement that code to check if it works correctly.
Hello Blackfin. Well, I really don't know what would happen at those temperatures, but according to the driver of the car, he doesn't care if it indicates the correct temperature below 40ºC and not above 120ºC, since from 117ºC the engine could literally explode ( engine very very tight). I have thought about placing zener diodes in the signals to protect it from possible voltage surges above 5v. Do you see it correct?
Thanks for your answers and help. I promise to tell news.
Most cars use ntc thermistors for the temperature sensors and 0-5v transducers for pressure sensors.
The temp sensors will probably require some extra circuitry but can be read accurately using the Steinhart-Hart equation. This page has a decent explanation, MicroSquirt® Introduction.
The pressure sensors should be pretty straight forward given the linear output.
Maybe check out the speeduino project speeduino.com, it's an open source ecu based on the arduino mega and other mcus. You could run one for monitoring sensors if you didn't want it to run the engine.
I elaborated this code to test with a potentiometer, but something is wrong because it throws me an error.
int analogPin=A0; // signal from water temp sensor connected to analog pin 0
// outside leads to ground and +5V
int val = 0; // variable to store the value read
int temp;
void setup() {
Serial.begin(9600);
pinMode (analogPin, INPUT);
}
void loop() {
val = analogRead(analogPin); // read the input pin
temp = -0.000000001512515 * val^3 + 0.000000476177465 * val^2 - 0.000070031485393 * val + 1.253424469424954;
Serial.print ("Reading");
Serial.println(val); // debug value
Serial.print ("Temp");
Serial.print (temp);
}
Where I have the mistake?. My mind is already blocked. Sure I have an absurd error but I can no longer see it
Holy cow Batman! What kind of reading is this temp sensor giving you? You have a data-sheet for that?
Oh wait, I see your graph. Do you have those data points listed somewhere?
Oh, never mind I found 'em.
Ok! Try it like this..
#include <mapper.h>
#include <multimap.h>
mapper aToVMapper(0,1023,0,5); // Analog to volts.
multiMap vToTempMapper; // This will be volts to temp.
int analogPin=A0; // signal from water temp sensor connected to analog pin 0
void setup(void) {
Serial.begin(9600);
vToTempMapper.addPoint(4.5,40); // Set your datapoints into the mapper.
vToTempMapper.addPoint(3.8,80);
vToTempMapper.addPoint(3.5,90);
vToTempMapper.addPoint(3,100);
vToTempMapper.addPoint(2.7,110);
vToTempMapper.addPoint(2.2,120);
}
// This takes the reading from analogInput() and gives back... temp.
float getTemp(int aVal) {
float volts;
float temp;
volts = aToVMapper.map(aVal);
temp = vToTempMapper.map(volts);
return temp;
}
void loop(void) {
int val;
float temp;
val = analogRead(analogPin); // read the input pin
temp = getTemp(val);
Serial.print ("Temp");
Serial.print (temp);
}
You'll need to grab LC_baseTools from the IDE's library manager to compile this.
It Works!!. I did not know this mapper. You have saved me thousands of hours trying to make it work. Just one more question, I have two more sensors to add to my code that follow the same non-linear pattern (oil temperature and oil pressure).
How could I add them to my code using their different voltage and temperature values? (they are totally different between the three sensors)
Thank you very much for your help.
My project has been named "Jlee system" in your honor.