Automatically convert voltage-to-value for analog sending units?

Hi everyone! So a little project I'm working on that has me stumped is taking analog sending units, and having the program automatically calculate to value (in PSI, temperature, etc.) so I don't have to do the math manually.

For example, let's say Sensor A is a pressure sensor, that operates at .5 to 4.5 volts. The .5 volts represents 0 PSI, and 4.5 volts represents 100 PSI.

Let's say Sensor B is a temperature sensor, that operates at 0 to 5.0 volts. The 0 volts represents 60 degrees Fahrenheit, and the 5.0 volts represents 300 degrees Fahrenheit.

I'd like to be able to enter the minimum voltage of each sensor/sending unit as a variable, as well as the maximum voltage. I'd like to also have a variable for what the value of the sensor is at the lowest voltage, as well as at the highest voltage. Then, I'll have a "lower" threshold that I'd like to enter as a variable, as well as an upper threshold... I already have the program written to do something if the the minimum threshold or maximum threshold is reached, but I'm currently using voltage instead of the sensor value (PSI, Temperature, etc.) that I'd like things to happen. I'm trying to re-write the variables to handle this the way I want it to, and here is all I have so far:

#define SensorA_Type                         PSI

#define SensorA_MinVoltage                0.5
#define SensorA_MaxVoltage               4.5

#define SensorA_ValueAtMinVoltage     0
#define SensorA_ValueAtMaxVotlage    100

#define SensorA_MinThreshold            11
#define SensorA_MaxThreshold            80



#define SensorB_Type                         Degrees

#define SensorB_MinVoltage                0.0
#define SensorB_MaxVoltage               5.0

#define SensorB_ValueAtMinVoltage     60
#define SensorB_ValueAtMaxVotlage    300

#define SensorB_MinThreshold            150
#define SensorB_MaxThreshold           250

I can't wrap my head around the math that needs to take place for each sensor, using the values I'm placing for the variables. If I also want the serial monitor to tell me the current value of the sensor (ie: for Sensor A, I'd like to see "Manifold Pressure: 18 PSI", assuming the current calculated value of the sensor is at 18 PSI, based on the voltage), how would I display the calculated PSI?

This is likely something very simply, but I'm still very much a newbie when it comes to coding things. Any help would be hugely appreciated!! Thanks so much!!!!

1 Like

AGrayson84:
For example, let's say Sensor A is a pressure sensor, that operates at .5 to 4.5 volts.

Very unusual for a pressure sensor.
Most output a ratio of 10% to 90% of their supply. Could be a big difference.

Let's forget about 'volts'. You're not building a voltmeter.
10% of a 10-bit A/D (1024 values) is about 102., and 90% is about 922.
See this sketch.

const byte pressurePin = A0;
float sensorType = 100.0; // 100 psi full scale
const int offset = 102; // zero pressure adjust
const int fullScale = 922; // max pressure adjust
float pressure; // final pressure

void setup() {
  Serial.begin(9600);
}

void loop() {
  pressure = (analogRead(pressurePin) - offset) * sensorType / (fullScale - offset);
  
  Serial.print("Pressure: ");
  Serial.print(pressure, 1); // one decimal place is all you get with a 10-bit A/D
  Serial.println(" psi");
  delay(500); // remove in final code
}

Not sure which temp sensor would output 0-5volt.
For a thermistor, you would use a Steinhart-Hart equation.
Maybe use map() to convert 0-1023 to 60-300.
Leo..

You can map the range of one onto the range of the other. For that you have take care of the offset.

I like to deal with voltages :wink: That makes it possible to measure the input pin with a multimeter and verify if the sketch can read the same voltage. I think it is also easier to use float for the voltage when the average of many samples is used: averageRead.ino.

For sensor A, the range of the voltage is 4 V (4.5 - 0.5) and the range for the pressure is 100 psi (100-0).
When you divide by the voltage range and multiply by the pressure range, then you have moved from voltage to pressure.
There is an other way to look at it: to go from voltage to psi, you have to remove the voltage by dividing by the voltage and introduce the pressure by multiplying with the pressure.

A "0.5" is a floating point for the compiler and a "60" is a integer for the compiler. With these calculations it is better to use 'float' for everything.

// Sensor A
float voltage = 2.0;   // (0.5 to 4.5)
float t1 = voltage - 0.5;   // remove the offset
float t2 = t1 / (4.5-0.5);  // divide by the voltage range, "voltage" is removed
float t3 = t2 * (100.0-0.0);  // multiply with pressure range, "pressure" is introduced
float pressure = t3 + 0.0;   // add pressure offset

// Sensor B
#define SensorB_MinVoltage                0.0
#define SensorB_MaxVoltage               5.0

#define SensorB_ValueAtMinVoltage     60.0
#define SensorB_ValueAtMaxVotlage    300.0
float v = 3.5;  // 0.0 to 5.0
float temperature = ((v - SensorB_MinVoltage) / (SensorB_MaxVoltage - SensorB_MinVoltage) * (SensorB_ValueAtMaxVotlage - SensorB_ValueAtMinVoltage)) + SensorB_ValueAtMinVoltage;

The next step is to learn about the difference between 'ratiometric' sensors and sensors that output a certain voltage.

Koepel:
I like to deal with voltages :wink: That makes it possible to measure the input pin with a multimeter

which you then have to permanently leave connected to the Arduino.
Because voltages change all the time with supply and load variations.

The final pressure outcome might be the same, but I think it's best to code with true data.

Most "0.5 to 4.5volt" sensors are ratiometric,
and are advertised that way because they assume a 5.000volt supply (which it rarely is).
Leo..

Wawa, when a ratiometric sensor is used, then it is okay to calculate the voltage first using 5.0000 as a theoretical reference. The voltage will drop out of the calculation and the result will be exactly the same as with your calculation, regardless variations in the power supply or load.

When measuring the voltage at the analog input pin with a multimeter, then the reference voltage should be taken into account especially for a ratiometric sensor.

Yes, that's what I said. The final result is still the same.
But I still think it's dumb to use some random/fictional number to get there when you don't have to.

I think you mean that reference voltage is not important for ratiometric sensors.
As long as you power the sensor from the same reference voltage.
Leo..

Ha ha, I still think it's smarter to use float and calculate the voltage 8)
The datasheet of a pressure sensor could say that if it is powered with exactly 5.0V then the output is from 0.5 to 4.5V. In my calculation I can use those exact numbers and I don't have to choose between integers from 0 to 1023.

When calculating the average of many samples or a simple low-pass filter, I also prefer to do that with the voltage. It even makes me feel better because it is a real unit. I have already problems when someone says that something is 2' long, because the ' thingy is not a real thing :wink:

AGrayson84, with two opinions you can choose what seems best to you.