AHT21 Sensor data doesn't show up in IOT Cloud please help

Hi,
I made a simple project and connected a temperature and humidity sensor (AHT21) to ESP32 Dev board. The serial monitor shows that the ESP32 Dev board is connected to my router and to IoT cloud and it shows both values updated every 2 seconds. So far so good.
But after configuration of the thing and properties nothing happened on the IoT cloud. It shows always 0 as a value for both. I am a bit desperate and don't know what to do now.

Can someone please help me?

Here is my link

Hey!

I was going to review your sketch but it is no longer available.

Did you manage to solve your issue?
If not, can you reshare your code so that I can take a look at it?

Hi dbeamonte,

I did find a way to make it work, it's not as clean as I would like and I wasn't able to get the code to compile in IOT Cloud. The reason I couldn't get it to compile is that the library I needed isn't available in IOT Cloud and when I tried to add it by uploading my libraries it still didn't show up. I pulled it from a GIT and it appears to work. I just downloaded the prebuilt code from IOT Cloud, opened it in Arduino IDE and compiled it there.

The adafruit and other AHT libraries in the library didn't work. I can't be 100% sure, but with my limitied knowledge the only difference I could see from a working DHT11 code and not working AHT code is the difference between read and get in the print.serial command.

When I found the GIT with read commands I was able to get it to work, however still not how I expected it too.

example:

  Serial.println();

ahtValue = aht20.readTemperature(); //read 6-bytes via I2C, takes 80 milliseconds

  Serial.print(F("Temperature: "));
   
    // Get temp in Fahrenheit (F)
  if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    **temperature = (((ahtValue/5)*9)+32);** //this line sends is what IOT Cloud receives and prints to a dashboard.
    Serial.print(((ahtValue/5)*9)+32);  //this line is what sends the readings to Serial Monitor
    Serial.println(F("°F"));
  }

Here is the Humidity code as well:

 ahtValue = aht20.readHumidity(); //read another 6-bytes via I2C, takes 80 milliseconds

  Serial.print(F("Humidity: "));
  
  if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    **humidity = (ahtValue);** //again this line sends to IOT Cloud
    Serial.print(ahtValue);  //this line to Serial Montior
    Serial.println(F("%"));
  }

Below is the code I tried at first:

/* 
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/edb59396-ea45-4459-bb50-01017dd0c74e 

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  float humidity;
  float temperature;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include "Wire.h"
#include "AHT20.h"
#include "thingProperties.h"
AHT20 aht21;

void setup(){
  Serial.begin(115200);
  Serial.println("Humidity AHT20 examples");
  //Join I2C bus
  Wire.begin();
  //Check if the AHT20 will acknowledge
  if (aht21.begin() == false)
  {
    Serial.println("AHT21 not detected. Please check wiring. Freezing.");
    while (1);
  }
  Serial.println("AHT21 acknowledged.");


  // Defined in thingProperties.h
 initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}

void loop() {
  ArduinoCloud.update();
  // Your code here 
    //If a new measurement is available
  if (aht21.available() == true)

  {
    //Get the new temperature and humidity value
    float h = aht21.getHumidity();
    float f = aht21.getTemperature();
    float temperature = aht21.getTemperature();
    float humidity = aht21.getHumidity();


  if(isnan(humidity) || isnan(temperature)){
    Serial.println("Failed to read from AHT Sensor!");
  }else{
    //Print the results
     Serial.print("Temperature: ");
    temperature = (((temperature/5)*9)+32); 
    // Get temp in Fahrenheit (F)
    Serial.print(temperature, 0);
    Serial.println("°F");
    Serial.print(" | ");
    Serial.print("Humidity: ");
    Serial.print(humidity, 0);
    Serial.println("%");
    Serial.println();
  }
  }

  //The AHT20 can respond with a reading every ~50ms. However, increased read time can cause the IC to heat around 1.0C above ambient.
  //The datasheet recommends reading every 2 seconds.
  delay(2000);
}

Below is the complete code I am running now with addition of deep sleep added, so I would be happy to have your take on this:

#include "arduino_secrets.h"
/***************************************************************************************************/
/*
   This is an Arduino example for Aosong ASAIR AHT10/AHT15/AHT20/AHT21/AHT25/AM2301B/AM2311B
   Digital Humidity & Temperature Sensor

   written by : enjoyneering
   sourse code: https://github.com/enjoyneering/

   Aosong ASAIR AHT1x/AHT2x features:
   - AHT1x +1.8v..+3.6v, AHT2x +2.2v..+5.5v
   - AHT1x 0.25uA..320uA, AHT2x 0.25uA..980uA
   - temperature range -40C..+85C
   - humidity range 0%..100%
   - typical accuracy T +-0.3C, RH +-2%
   - typical resolution T 0.01C, RH 0.024%
   - normal operating range T -20C..+60C, RH 10%..80%
   - maximum operating rage T -40C..+80C, RH 0%..100%
   - response time 8..30sec*
   - I2C bus speed 100KHz..400KHz, 10KHz recommended minimum
     *measurement with high frequency leads to heating of the
      sensor, interval must be > 1 second to keep self-heating below 0.1C

   This device uses I2C bus to communicate, specials pins are required to interface
   Board                                     SDA              SCL              Level
   Uno, Mini, Pro, ATmega168, ATmega328..... A4               A5               5v
   Mega2560................................. 20               21               5v
   Due, SAM3X8E............................. 20               21               3.3v
   MKR Zero, XIAO SAMD21, SAMD21xx.......... PA08             PA09             3.3v
   Leonardo, Micro, ATmega32U4.............. 2                3                5v
   Digistump, Trinket, Gemma, ATtiny85...... PB0/D0           PB2/D2           3.3v/5v
   Blue Pill*, STM32F103xxxx boards*........ PB7/PB9          PB6/PB8          3.3v/5v
   ESP8266 ESP-01**......................... GPIO0            GPIO2            3.3v/5v
   NodeMCU 1.0**, WeMos D1 Mini**........... GPIO4/D2         GPIO5/D1         3.3v/5v
   ESP32***................................. GPIO21/D21       GPIO22/D22       3.3v
                                             GPIO16/D16       GPIO17/D17       3.3v
                                            *hardware I2C Wire mapped to Wire1 in stm32duino
                                             see https://github.com/stm32duino/wiki/wiki/API#I2C
                                           **most boards has 10K..12K pullup-up resistor
                                             on GPIO0/D3, GPIO2/D4/LED & pullup-down on
                                             GPIO15/D8 for flash & boot
                                          ***hardware I2C Wire mapped to TwoWire(0) aka GPIO21/GPIO22 in Arduino ESP32

   Supported frameworks:
   Arduino Core - https://github.com/arduino/Arduino/tree/master/hardware
   ATtiny  Core - https://github.com/SpenceKonde/ATTinyCore
   ESP8266 Core - https://github.com/esp8266/Arduino
   ESP32   Core - https://github.com/espressif/arduino-esp32
   STM32   Core - https://github.com/stm32duino/Arduino_Core_STM32
   SAMD    Core - https://github.com/arduino/ArduinoCore-samd


   GNU GPL license, all text above must be included in any redistribution,
   see link for details - https://www.gnu.org/licenses/licenses.html
*/
/***************************************************************************************************/
/* 
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/edb59396-ea45-4459-bb50-01017dd0c74e 

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  float humidity;
  float temperature;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include "thingProperties.h"
#include <Wire.h>
#include <AHTxx.h>


#define uS_TO_S_FACTOR 100000000ULL  /* Conversion factor for micro seconds to seconds */
long TIME_TO_SLEEP = 9; /* Time ESP32 will go to sleep (in # x uS_TO_SFACTOR \ 60000000 = minutes) */
RTC_DATA_ATTR int bootCount = 0;


float ahtValue;                               //to store T/RH result

AHTxx aht20(AHTXX_ADDRESS_X38, AHT2x_SENSOR); //sensor address, sensor type

  
/**************************************************************************/
/*
    setup()

    Main setup
*/
/**************************************************************************/


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

  
  while (aht20.begin() != true)
  {
    Serial.println(F("AHT2x not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free

    delay(5000);
  }

  Serial.println(F("AHT20 OK"));

 
/**************************************************************************/
/*
    loop()

     Main loop
*/
/**************************************************************************/

  // Defined in thingProperties.h
 initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
 
    // Attach the IoT Cloud properties to the variables
  //ArduinoCloud.attach(temperature);
  //ArduinoCloud.attach(humidity);

  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();


}

void loop() {

for (int j=1; j<=20; j=j+1) {
  ArduinoCloud.update();
  // Your code here 
  /* DEMO - 2, temperature call will read 6-bytes via I2C, humidity will use same 6-bytes */
  Serial.println();

ahtValue = aht20.readTemperature(); //read 6-bytes via I2C, takes 80 milliseconds

  Serial.print(F("Temperature: "));
   
    // Get temp in Fahrenheit (F)
  if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    temperature = (((ahtValue/5)*9)+32);
    Serial.print(((ahtValue/5)*9)+32);
    Serial.println(F("°F"));
  }
  else
  {
    printStatus(); //print temperature command status

    if   (aht20.softReset() == true) Serial.println(F("reset success")); //as the last chance to make it alive
    else                             Serial.println(F("reset failed"));
  }

  delay(2000); //measurement with high frequency leads to heating of the sensor, see NOTE

  ahtValue = aht20.readHumidity(); //read another 6-bytes via I2C, takes 80 milliseconds

  Serial.print(F("Humidity: "));
  
  if (ahtValue != AHTXX_ERROR) //AHTXX_ERROR = 255, library returns 255 if error occurs
  {
    humidity = (ahtValue);
    Serial.print(ahtValue);
    Serial.println(F("%"));
  }
  else
  {
    printStatus(); //print humidity command status
  }
  
  
    delay(250);
    

  }
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); //go to sleep
  Serial.println("ESP32 will sleep for " + String(TIME_TO_SLEEP * uS_TO_S_FACTOR / 60000000) + " Minutes");
  Serial.println("Going to deep sleep now.");
  esp_deep_sleep_start();     //deep sleep turns off wifi, bluetooth and CPU to save battery
}


/**************************************************************************/
/*
    printStatus()

    Print last command status
*/
/**************************************************************************/
void printStatus()
{
  switch (aht20.getStatus())
  {
    case AHTXX_NO_ERROR:
      Serial.println(F("no error"));
      break;

    case AHTXX_BUSY_ERROR:
      Serial.println(F("sensor busy, increase polling time"));
      break;

    case AHTXX_ACK_ERROR:
      Serial.println(F("sensor didn't return ACK, not connected, broken, long wires (reduce speed), bus locked by slave (increase stretch limit)"));
      break;

    case AHTXX_DATA_ERROR:
      Serial.println(F("received data smaller than expected, not connected, broken, long wires (reduce speed), bus locked by slave (increase stretch limit)"));
      break;

    case AHTXX_CRC8_ERROR:
      Serial.println(F("computed CRC8 not match received CRC8, this feature supported only by AHT2x sensors"));
      break;

    default:
      Serial.println(F("unknown status"));    
      break;
  }
  // Check if connected to the IoT Cloud and update values
  ArduinoCloud.update();



  delay(100);
}

Hey!
Thanks for sharing the sketch.
A couple of general notes on your code before jumping into the details.

  • It's recommended to remove delays in the loop so that ArduinoCloud.update() is called as often as possible. You can define an implementation based on millis() instead. Something like this:
unsigned long last_ts = 0;
void loop() {
  ArduinoCloud.update();
  if (millis() > last_ts + 2000) {
    last_ts = millis();
    // Your code that has to be executed once every 2s here
  }
}
  • You can then just call ArduinoCloud.update() once at the beginning of the loop() instead of in all the iterations of your for clause.
  • The IoT Cloud enables the watchdog (WDT) by default unless you specify otherwise. This could interfere with your setup. I would suggest disabling it

Some code good practices here: https://docs.arduino.cc/arduino-cloud/getting-started/technical-reference#recommended-code-practices.

Using deep sleep with Arduino Cloud can be a bit tricky, as when the device does not send data to the Cloud for some period of time it gets disconnected and so, every time it wakes up, it has to reconnect again before syncing the variables and that takes some time. So, after waking up, you should make sure that the device has effectively connected to the Cloud and synced the variables before going to sleep again (you can play with the following callbacks https://github.com/arduino-libraries/ArduinoIoTCloud/blob/master/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino).

If you want to compile your code in the IoT Cloud with an external library, you need to use the full Web Editor (which is the online alternative to the traditional local Arduino IDE). From the IoT Cloud editor, you can just click on Open Full Editor. There, you have a Library Manager where you can import your library. I would suggest doing that instead of using the Arduino IDE and compiling offline.

Eager to know if any of this helps ::blush:

I will have a look when I get time, I am headed out on PTO and will not be able to work on this for a couple of weeks. BTW, I did try using the full Arduino editor (I only used this honestly) and it wouldn't show the imported library I tried to add.

Thanks for the advice.

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