Incorrect measurements with ENV III HAT on M5StickC+



  • Hello,

    I have the impression that ENV III HAT is not working properly and is providing incorrect measurements:

    M5StickC+ with ENV III HAT

    First, the measured temperature is about 3°C above the actual temperature (which I also checked with a DS18B20 sensor). I understand that the sensor measurement can be disturbed by the heating of the electronic components, but still... 3°C is a huge difference !

    I made sure to put the microcontroller in deep sleep to give it time to cool down (see my code below)!

    Then, the measured pressure is always equal to zero... 🤔

    Here is my code:

    #include <M5Unified.h>
    #include <UNIT_ENV.h>
    
    constexpr uint32_t SLEEP_DURATION_US = 60 * 1000 * 1000; // 1 min
    
    SHT3X   sht30;
    QMP6988 qmp6988;
    
    void setup() {
    
        M5.begin();
        M5.Display.setRotation(3);
        M5.Display.setFont(&fonts::Font2);
    
        Wire.begin(0, 26);
        qmp6988.init();
        
    }
    
    void loop() {
    
        static float_t temperature, humidity, pressure;
    
        uint8_t fail = sht30.get();
    
        temperature = fail ? 0 : sht30.cTemp;
        humidity    = fail ? 0 : sht30.humidity;
        pressure    = qmp6988.calcPressure();
    
        qmp6988.setpPowermode(QMP6988_SLEEP_MODE);
    
        M5.Display.drawString("T:", 10, 10); M5.Display.drawFloat(temperature, 2, 30, 10);
        M5.Display.drawString("H:", 10, 30); M5.Display.drawFloat(humidity,    2, 30, 30);
        M5.Display.drawString("P:", 10, 50); M5.Display.drawFloat(pressure,    2, 30, 50);
    
        delay(2000);
    
        M5.Power.Axp192.setLDO2(0);
        esp_sleep_enable_timer_wakeup(SLEEP_DURATION_US);
        esp_deep_sleep_start();
    
    }
    

    Did I make a mistake somewhere?

    Maybe you have experienced this sensor yourself and have some elements to share with me?

    Thank you very much in advance.
    Steph



  • I apparently get a small improvement in the temperature measurement by shutting down the microcontroller like this:

        // M5.Power.Axp192.setLDO2(0);
        // esp_sleep_enable_timer_wakeup(SLEEP_DURATION_US);
        // esp_deep_sleep_start();
        M5.Power.deepSleep(SLEEP_DURATION_US);
    

    But I still have a 2.5°C difference...

    On the other hand, I don't have a solution for the pressure measurement. 😕



  • Well... I'm soooooo sorry... I thought I had an ENV III, but it's actually an ENV II... 😬

    ENV II even has two temperature sensors, since instead of the QMP6988, it has a BMP280, which is a pressure and temperature sensor. It is, therefore, possible to perform 2 simultaneous temperature measurements!

    So, this time things work better:

    ENV II with M55StickC+

    We still notice a difference in the temperature measurements. The SHT30 seems to get better results (which is probably why they added it).

    Here, it's still 1°C above the real temperature. In the meantime, I turned on the air-conditioning, so maybe the deviation is reduced because of the ventilation? On the other hand, we can see that the temperature measured by the BMP280 is 1°C higher than the one measured by the SHT30.

    But this time, I get a non-zero pressure measurement. 🙂

    Here is the new version of my code for those who are interested:

    #include <M5Unified.h>
    #include <UNIT_ENV.h>
    #include <Adafruit_BMP280.h>
    
    constexpr uint32_t SLEEP_DURATION_US = 30 * 1000 * 1000; // 30 sec
    
    SHT3X sht30;
    Adafruit_BMP280 bmp;
    // QMP6988 qmp6988; // only for ENV III
    
    void setup() {
    
        M5.begin();
        M5.Display.setRotation(3);
        M5.Display.setFont(&fonts::Font2);
    
        Wire.begin(0, 26);
        bmp.begin(0x76);
        bmp.setSampling(
            Adafruit_BMP280::MODE_NORMAL,
            Adafruit_BMP280::SAMPLING_X16,
            Adafruit_BMP280::SAMPLING_X16,
            Adafruit_BMP280::FILTER_X16,
            Adafruit_BMP280::STANDBY_MS_500
        );
    
        // qmp6988.init(); // only for ENV III
        
    }
    
    void displayMeasurement(
        const uint8_t x1,
        const uint8_t x2,
        const uint8_t x3,
        const uint8_t y,
        const char*   sensor,
        const char*   data,
        const float_t value
    ) {
    
        M5.Display.drawString(sensor,  x1, y);
        M5.Display.drawString(data,    x2, y);
        M5.Display.drawFloat(value, 2, x3, y);
    
    }
    
    void loop() {
    
        static float_t temperature_1, temperature_2, humidity, pressure;
    
        uint8_t fail = sht30.get();
    
        temperature_1 = bmp.readTemperature();
        temperature_2 = fail ? 0 : sht30.cTemp;
        humidity      = fail ? 0 : sht30.humidity;
        pressure      = bmp.readPressure();
        
        // only for ENV III
        // pressure = qmp6988.calcPressure();
        // qmp6988.setpPowermode(QMP6988_SLEEP_MODE);
    
        displayMeasurement(10, 70, 100, 10, "BMP280", "T1", temperature_1);
        displayMeasurement(10, 70, 100, 30, "SHT30",  "T2", temperature_2);
        displayMeasurement(10, 70, 100, 50, "SHT30",  "H",  humidity);
        displayMeasurement(10, 70, 100, 70, "BMP280", "P",  pressure);
    
        delay(2000);
        
        M5.Power.deepSleep(SLEEP_DURATION_US);
    
    }
    

    Sorry for my confusion between ENV II and ENV III. But maybe finally the questions raised here will be useful to some readers...



  • Glad you worked it out.



  • Hello
    Witch tolerances does your AZ device have? Must been shown in the manual.
    Lee



  • Hello @northwest, you're right, I have to check.

    Unfortunately I misplaced the manual, but I did find this summary doc online. It states the following features:

    • Accuracy : -20-100°C +/- 1°C
    • Resolution : 0.1°C

    Nevertheless, I have a couple of DS18B20 sensors, which are known to be pretty accurate, all of which indicate a temperature very close to that measured by my kitchen thermometer.

    An error close to 1°C is acceptable in my use case, but ENV II or ENV III HATs get worse measurements than my DS18B20. I also compared these measurements with other sensors like the Adafruit BME280 (which always gives measurements with a 2°C increase because of the voltage regulator on the sensor board), but which is still accurate when taken into account.

    Thank you,
    Steph



  • At the moment, I try to control the radiators in the house with this ENVIII. I have diffrent meassuring instruments here, I will check next week how they are to compare with the ENVIII



  • @northwest Ok Lee, thank you very much, that's very kind of you 🙂



  • I know Im posting on an old thread, but the information for these things are hard to come by.

    Im a newb, but sort of know what Im looking at with this code.

    But Im unable to get this running on my M5stickCplus with ENVIII
    even with the help for ENVIII in the code the // comments I cant get this working. I get the screen blink every 30 seconds, which I dialed down to ten seconds, and it blinks no readings, all at 0.00

    What am I missing here? I also couldnt find M5_env.h and used m5stack_ENV.h from the install libraries, assuming they are the same ?

    Thanks for any help. Especially thanks to the OP for his code here, looks promising, helping me learn a lot.



  • ENVIII and ENVIIIHat are NOT the same thing and as such use different pins

    ENVIII uses the port on the bottom of the stick whereas the HAT use the pins on the top of the stick.



  • @ajb2k3 this is great info!

    I did start to understand the 0x56 addresse and 0x44 I think it is.. it seems like the addresses were the same in the technical manuals, but maybe that has no bearing on what you are saying ?
    Im guessing the wire. commands Im seeing would be for the non hat version ?

    Ill start looking for the difference in the pins and maybe be able to learn something again!

    Again, Im a super newb and I appreciate the help.

    I originally found this thread because my envIII hat temperature reading just cant be true. it seems a bit high and sort of climbs at time and peaks around 29 degrees. I suspect its the working temperature of the M5stick. screen heat I guess?



  • When I mean different pins, I mean that they use different IO pins when connected to the sticks.
    Units use GPIO32/33 on the StickCplus where as the hats use G26/G36/G25/G0 on the Hat connector.

    The sensors have been proved not to be fully realible and need calibrating, tuning in code in order to work in the environment you intend them to work in.

    As to the I2C address issue. If you have more than 1 device on the bus with the same i2c address, the data received by the sticks could be corrupted, the bus may stop working or data recorded will be very inaccurate.



  • @ajb2k3 Thank you so much! this is very helpful.

    Could I also ask you to point me in a direction for the calibration formula or a small description of the theory behind calibrating it ? in my head I just feel like chopping 3 degrees off the reading would almost suffice, but Im sure there is a more eloquent method. Ultimately if I can figure it out, sleeping code will be needed for longer run times in terms of battery longevity. This seemingly also would help a bit with accurate temps.

    Thanks!



  • You will need to find the data sheet for the temperature sensor used in the unit as I have no idea how to make the numbers for calibration.



  • @teflon121 If you are measuring temperature in an environment where the temperature is stable such as at my desk(!) you can, for sure, just add an "offset". Just measure the ambient with a known and trusted thermometer and add or subtract this to the raw measurement.
    If the device is going to be subjected to a wide range of temps, then you need to see if offset is satisfactory over that range.
    If not...the second half of calibration is "span" which is accomplished by multiply or dividing the raw measurement. This gets fiddly and can be enjoyable like tuning a carburetor!
    display = raw * span + offset, or depending on characteristics of the sensor, display = (raw + offset) * span
    Span is usually a very low number like 1.2 or 0.98
    -Terry