Sensor Mapping Error

Hello to everyone,
I am using a sensor connected to adc1 channel of ads1115. Data of ads11115 is received at ESP32. Output of sensor is 0.4 Volt to 2.0 Volts for 0 to 250 ppm. I am using the following code

#include <Adafruit_ADS1X15.h>
Adafruit_ADS1115 ads;

float SensorValue;

void setup() {
    Serial.begin(115200);
  
  delay(100);  

  Serial.println("Getting single-ended readings from AIN0..3");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
  if (!ads.begin())
  {
    Serial.println("Failed to initialize ADS.");
    while (1); 
  }

}

void loop() {
  int16_t adc0, adc1, adc2, adc3;
  float volts0, volts1, volts2, volts3;
 
  adc0 = ads.readADC_SingleEnded(0);
  adc1 = ads.readADC_SingleEnded(1);
  adc2 = ads.readADC_SingleEnded(2);
  adc3 = ads.readADC_SingleEnded(3);
 
  volts0 = ads.computeVolts(adc0);
  volts1 = ads.computeVolts(adc1);
  volts2 = ads.computeVolts(adc2);
  volts3 = ads.computeVolts(adc3);

Serial.println("-----------------------------------------------------------");
Serial.print("AIN1: "); Serial.print(adc1); Serial.print("  "); Serial.print(volts1); Serial.println("V");

SensorValue = map(volts1, .40, 2.00, 0, 250);
  
  Serial.print("Gas Value: ");
  Serial.println(SensorValue);
  delay(500);
}

I am expecting values according to the value of input volts.
But in serial monitor values are as -
0 for 0.4 Volt to 0.99 Volt
125 for 1 Volt to 1.99 Volts
250 for 2 Volts
I would be very thankful for any help.

This says... SensorValue is assigned the input reading volts1, which ranges from 40 to 2 and will output 0 to 250.

I thought that ".40" was "40" sorry.

Try: ``` SensorValue = map (volts1, 0.4, 2.0, 0, 250); // input, in_min, in_max, out_min, out_max ```

I think your input device producing "volts1" is not working. reading correctly.

Thanks for reply.
Sensor output signal is changing gradually but gas value is not.
Please see data copied from serial monitor-

AIN1: 10712 2.01V
Gas Value: 250.00

AIN1: 10681 2.00V
Gas Value: 250.00

AIN1: 10669 2.00V
Gas Value: 250.00

AIN1: 10686 2.00V
Gas Value: 250.00

AIN1: 10700 2.01V
Gas Value: 250.00

AIN1: 10683 2.00V
Gas Value: 250.00

AIN1: 10649 2.00V
Gas Value: 125.00

AIN1: 10630 1.99V
Gas Value: 125.00

AIN1: 10586 1.98V
Gas Value: 125.00

AIN1: 10561 1.98V
Gas Value: 125.00

.
.
.
.
.
AIN1: 5451 1.02V
Gas Value: 125.00

AIN1: 5427 1.02V
Gas Value: 125.00

AIN1: 5401 1.01V
Gas Value: 125.00

AIN1: 5370 1.01V
Gas Value: 125.00

AIN1: 5345 1.00V
Gas Value: 125.00

AIN1: 5308 1.00V
Gas Value: 0.00

AIN1: 5311 1.00V
Gas Value: 0.00

AIN1: 5308 1.00V
Gas Value: 0.00

AIN1: 5278 0.99V
Gas Value: 0.00

What is the raw value of volts1?

Serial.println(volts1); without mapping.

I think that you can not map floats; there was recently a topic where that was mentioned.

The Arduino map() function takes integer arguments. Use mapf() instead, or write your own code, as it is only one line.

2 Likes

Thanks for reply.
Serial.println(volts1); is giving print as 0.40

During the program. Not just once.

Value of AIN1 as shown above

If your Gas Sensor has a range of 0.4vdc to 2.0vdc...

Use:

SensorValue = mapf(volts1, .4, 2, 0, 250);
1 Like

Thanks for reply. Using mapf function following error occurred while compilation -78:14: error: 'mapf' was not declared in this scope.

Try adding this line at the top of the sketch...

 #include <Mapf.h>
1 Like

Now my program is printing desired values in serial monitor.
I would like to discuss one more point.
In the meanwhile, I have derived a relation to calculate sensor value as- Sensor Value = ( Vf-V0) X 156.25, Where V0 is initial voltage i.e. 0.4V and Vf is voltage at considered point. Putting this relation in logic is also giving accurate readings. Please tell what should be used function mapf or this relation ? I am very thankful for your kind support.

I am uncertain of your question. Use formula that gives your program more control: Vf - V0 (difference) or map(sensor, minIN, maxIN, minOUT, maxOUT); Post your new code here for better understanding.

You have a voltage span of 2.0 - 0.4 = 1.6V with a zero offset of 0.4V, subtract the offset and you have a voltage span of 0 to1.6V = 0 to 250 PPM. so:

SensorValue = mapf(volts1 -0.4,1.6, 0, 250);

Thanks for your suggestion. But SensorValue = mapf(volts1, .4, 2, 0, 250); is working fine.

Sorry, perhaps I was unable to explain.
I have two options for achieving sensor readings as-

  1. Using SensorValue = mapf(volts1, .4, 2, 0, 250);
  2. Using SensorValue = ( Vf-V0) * 156.25 ; Where V0 is initial voltage i.e. 0.4V and Vf is voltage at considered point.
    Both are giving accurate readings.
    My question is that which option is better.

The one where you can see what the code is doing, instead of calling some function that you must trust or look into at all.

Both ways have the same results, both have the same problems, both express a linear relationship.

Which TBH I did not verify on the back of an envelope (156.25, e.g.). I trust your maths.

My preference would be to write the expression in the form

   y = mx +b

which is the standard way to write the equation for a line. I'll let you do or not do that. :expressionless:

OK, now I think maybe the mapf is better as it makes the endpoints clear…

Otherwise, you'd write

   sensorValue = (Vf - 0.4)/(2.0 - 0.4) * 155.25;

or

  sensorValue = 146.25 * Vf - 62.5;

I tire of arguing with myself. You decide. :expressionless:

a7

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.