PubInv / moonrat

Moonrat: A second-generation portable incubator
GNU Affero General Public License v3.0
3 stars 3 forks source link

Input Voltage for the TMP sensor, affects the measure scale #273

Open kurama79 opened 3 months ago

kurama79 commented 3 months ago

Arduino UNO R3 and Arduino UNO R4 WiFi default 5 volts pin issue

Here we test just the sensor to verify that the lectures of the temperature were right, the problem surges when we measure with a voltmeter the voltage input that it receives. For the calibration, it is necessary to consider the input voltage to set the correct scale and get good sensing. Then we proceed to make the next proofs.

USB case

The Arduino board is connected to the USB port in the computer and these are the lectures:

R3 ------------------------------------------------------------------

r3_usb

R4 ------------------------------------------------------------------

r4_usb

As we can see the first one which is the Arduino R3 has a better and stable input voltage for the sensor and the Arduino R4 doesn't.

12 Volts Power Supply

The Arduino board is connected to 12 volts, and the voltmeter measures are:

R3 ------------------------------------------------------------------

r3_12_power

R4 ------------------------------------------------------------------

r4_12_power

In this case, the Arduino which is more confident is the R4.

Solution

We propose adding the next function to the code to detect the Arduino board's real voltage in the 5-volt pin.

long readVcc() 
{
    // Configure the ADC to use the intern reference channel 
    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    delay(2);  // Wait for a stable reference

    // Initialize the ADC conversion
    ADCSRA |= _BV(ADSC);  
    while (bit_is_set(ADCSRA, ADSC)); 

    // Read the ADC
    uint8_t low = ADCL;
    uint8_t high = ADCH;
    long result = (high << 8) | low;

    // Vcc in millivolts
    long vcc = 1126400L / ADC;  // Utiliza 1.1 * 1024 * 1000
    //long vcc = (1.1 * 1024 * 1000) / result;  // Utiliza 1.1 * 1024 * 1000

  return vcc;
}

The above code "solves" the problem because we can use that real voltage to calibrate the sensor with the current voltage in the 5-volt pin.

But... :(

This code doesn't work in Arduino R4, but the R4 has a more stable voltage when connected to a power supply over 6 volts, its 5-volt pin always has 4.98 volts.

So we propose an #ifdef conditional in the code where if the variables and default functions that measure the voltage in the Arduino board (R3 case) then we can run the above function, if not then we can consider the 4.98 volt to the calibration.

ForrestErickson commented 3 months ago

Regarding the voltage on R3 and R4 and how the voltage changes from USB input to external Vcc input.

Lets review a bit to get a common understanding.

Ratiometric

The A2D (Analog to Digital) conversion process is of a type called "ratiometric " This means that any change to the reference voltage of the A2D will cause a change in the converted digital value. If this is new to you, here is some well written explanations https://learn.sparkfun.com/tutorials/analog-to-digital-conversion/all

So if changes to the supply to the MoonRat and therefor the UNO make changes to the Vcc errors will occur in the converted temperature.

Programable Reference

The Atmega328 has in internal reference from which the A2D can also be referenced. See: https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/ This reference is 1.1 Volt.
Refer to the Atmega328 data sheet for any specification on tolerance and on temperature coefficient for this reference which may need to be taken into account. This reference may help us a lot. Data sheet URL: https://www.analog.com/media/en/technical-documentation/data-sheets/tmp35_36_37.pdf

Voltage of TMP36 at <= 50C

The TMP36 data sheet shows a typical output voltage versus temperature image For temperatures of interest to our incubation this voltage looks to be comfortably below the 1.1Volt refence so that that reference could be used.

Conclusion Factory Calibration Is Probably A Requirement

While I have not tried to make an error budget and unless someone undertakes the task to do so and can demonstrate that we do not need to do so, I think it is a requirement that we build a factory calibration methodology into our device.

Calibration One or Two Points

We would place the TMP36 sensor into a calibrated temperature environment and then adjust (a multiplicative offset I think) the returned value to report the correct value of the calibrated environment. It would be even better to calibrate at two temperatures. 0C is probably a good temperature for a low end as ice water is easy to make. Harder is the higher temperature. We could simply heat an environment to some thing like 45C and measure with an accurate external device the real temperature and then calibrate the MoonRatII to that temperature.

Calibration and Storing Calibration

While I have not tried to work out code details, the Arduino MAP function is probably a very handy way to do this. The firmware would need to store four calibration numbers into EEPROM. And probably another location to indicate that the numbers are valid calibration numbers.

ForrestErickson commented 3 months ago

See more about the MAP function here: https://www.arduino.cc/reference/en/language/functions/math/map/

Note that the function uses integers and truncates and so the numbers fed into it should probably be multiplied by ten before the MAP function and then a floating point divide by ten of the returned value from the MAP would preserve some accuracy.

However I am only speculating.