I am working on a program that uses an Esp32 board to read a BBME/BMP sensor board and count the number of times a rain gauge toggles for each 0.01″ of rain received.
This board, the Sensor board, uses the ESP-NOW protocol to send its data to a Receiver/Display Esp32 board in my house (well that’s the plan). I’ve discovered that with one of my Esp32 boards (Adafruit HUZZAH32-ESP32 Feather Board) when programmed and attached to power thru the USB cable the program works like I expected, but when attached to only battery power, the same board setup acts differently.
The main difference is that the board when attached to only the battery power does not either save or recover(?) the variables that were supposed to be saved to the RTC memory. In your article in the Random Nerd Tutorials – ESP Deep Sleep, you use a variable “bootcounter” which I also do. If I power this same board with a USB cable attached to my computer all works as expected.
It got real interesting when I programmed another “identical” Adafruit ESP32 Feather board with this same program and I did the same experiment of powering the board with only a battery vs the USB cable/computer. With the second board, it worked “correctly” or the same with both power sources.This is all fine and good, but how will a different Esp32 board act?
I then did the same experiment with an ESP32 Dev. Board. When attached to the USB power both the ESP32 Feather board and the ESP32 Dev. Board acted nearly the same. Both boards recovered the bootcount number from memory when they came out of deep sleep and correctly communicated with the Esp32 Receiver board. But when the ESP32 Dev. board was powered with only a battery, the board didn’t seem to recover from deep sleep.
The ESP32 Feather board when powered with a battery would communicate with the ESP32 receiver board and display the values of Temperature, Humidity, Pressure and Rain amount (though the values for the rain amount were incorrect), but the ESP32 Dev. board when powered with only a battery would not communicate anything to the ESP32 receiver board. I have attached my code below. My question is why do I see different activities with the two different boards with different sources of power? Are these boards so new that the basic internal machine code/wiring of each of these boards is different? Help! Thanks for any help you can give me, Bob.
/* Rui Santos Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. */ #include <esp_now.h> #include <esp_sleep.h> #include <WiFi.h> #include <Wire.h> #include <BME280I2C.h> #define SERIAL_BAUD 115200 #define SEALEVELPRESSURE_HPA (1013.25) #define BUTTON_PIN_BITMASK 0x8000 // GPIO 15 #define uS_TO_S_FACTOR 1000000 //Conversion factor for microseconds to seconds #define TIME_TO_SLEEP 20 //Time ESP32 will go to sleep (in seconds) RTC_DATA_ATTR bool Rain = false; //No rain on startup RTC_DATA_ATTR int bootCount = 0; RTC_DATA_ATTR float dayRainCounter; // amount of rain received in a day in hundredths of an inch RTC_DATA_ATTR float yearRainCounter; // amount of rain received in a year in hundredths of an inch /* Method to print the reason by which ESP32 has been awaken from sleep */ void print_wakeup_reason(){ esp_sleep_wakeup_cause_t wakeup_reason; wakeup_reason = esp_sleep_get_wakeup_cause(); switch(wakeup_reason) { case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break; case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break; case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break; case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break; case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break; default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break; } } const int interval = 60000; const int rainInputPin = 15; const int tempSensorPower = 21; unsigned long previousMillis = millis(); // time at the start of this program unsigned long currentMillis = millis(); unsigned long dayMillis = millis(); // start time for this day unsigned long yearMillis = millis(); // start time for this year unsigned long dayInterval = 86400000; // a day of milliseconds unsigned long yearInterval = 31536000000; // a year of milliseconds // REPLACE WITH YOUR RECEIVER MAC Address for SparkFun Thing Board uint8_t broadcastAddress[] = {0xB4, 0xE6, 0x2D, 0xE8, 0xBF, 0xAD}; // Structure example to send data // Must match the receiver structure typedef struct struct_message { float a; float b; float c; float d; float e; bool f; } struct_message; // Create a struct_message called myData struct_message myData; // callback when data is sent void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { Serial.print("\r\nLast Packet Send Status:\t"); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); } BME280I2C::Settings settings( BME280::OSR_X1, BME280::OSR_X1, BME280::OSR_X1, BME280::Mode_Forced, BME280::StandbyTime_1000ms, BME280::Filter_Off, BME280::SpiEnable_False, 0x76 // I2C address. I2C specific. ); BME280I2C bme(settings); void setup() { // Init Serial Monitor bool status; pinMode(rainInputPin, INPUT); pinMode(tempSensorPower, OUTPUT); Serial.begin(SERIAL_BAUD); delay(300); //Take some time to open up the Serial Monitor if (bootCount == 0){ dayRainCounter = 0; yearRainCounter = 0; } if (bootCount >= 250){ bootCount = 1; } Rain = digitalRead(rainInputPin); digitalWrite(tempSensorPower, HIGH); //Time set to wake up ESP32 esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); //Use ext1 to wakeup also, GPIO 15 esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_HIGH); //Increment boot number and print it every reboot ++bootCount; Serial.println("Boot number: " + String(bootCount)); //Print the wakeup reason for ESP32 print_wakeup_reason(); while(!Serial) {} // Wait Wire.begin(); while(!bme.begin()) { Serial.println("Could not find BME280I2C sensor!"); delay(1000); } // bme.chipID(); // Deprecated. See chipModel(). switch(bme.chipModel()) { case BME280::ChipModel_BME280: Serial.println("Found BME280 sensor! Success."); break; case BME280::ChipModel_BMP280: Serial.println("Found BMP280 sensor! No Humidity available."); break; default: Serial.println("Found UNKNOWN sensor! Error!"); } // Change some settings before using. settings.tempOSR = BME280::OSR_X4; bme.setSettings(settings); // Set device as a Wi-Fi Station WiFi.mode(WIFI_STA); // Init ESP-NOW if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; } // Once ESPNow is successfully Init, we will register for Send CB to // get the status of Trasnmitted packet esp_now_register_send_cb(OnDataSent); // Register peer esp_now_peer_info_t peerInfo; memcpy(peerInfo.peer_addr, broadcastAddress, 6); peerInfo.channel = 0; peerInfo.encrypt = false; // Add peer if (esp_now_add_peer(&peerInfo) != ESP_OK){ Serial.println("Failed to add peer"); return; } BME280::TempUnit tempUnit(BME280::TempUnit_Celsius); BME280::PresUnit presUnit(BME280::PresUnit_Pa); float temp(NAN), hum(NAN), pres(NAN); //Increment boot number and print it every reboot // ++bootCount; // Serial.println("Boot number: " + String(bootCount)); bme.read(pres, temp, hum, tempUnit, presUnit); if (Rain){ // if the input from the rain bucket is HIGH a hundredth of an inch of rain has been received dayRainCounter += 1; // increment the daily rain counter Rain = false; //Reset for no rain condition to catch next increment of rain gauge pres = 0; //Temporarily set press to zero to see if the code comes thru this section of the code if (currentMillis - dayMillis >= dayInterval){ // check to see if a day has gone by dayMillis = millis(); // reset the day time yearRainCounter = yearRainCounter + dayRainCounter; dayRainCounter = 0; // reset the daily rain counter } if (currentMillis - yearMillis >= yearInterval){ yearMillis = millis(); // reset the yearly time yearRainCounter = 0; // reset the yearly rain counter } } // Set values to send myData.a = hum; myData.b = 1.8 * temp + 32; myData.c = pres / 100.0F; myData.d = dayRainCounter; myData.e = bootCount; myData.f = false; delay(300); // Send message via ESP-NOW esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData)); if (result == ESP_OK) { Serial.println("Sent with success, NOW"); } else { Serial.println("Error sending the data"); } // Disable BT // esp_bluedroid_disable(); //Disable BT Controller // esp_bt_controller_disable(); //Disable WIFI // esp_err_t esp_wifi_stop(); //Turn off power to temp sensor digitalWrite(tempSensorPower, LOW); //Go to sleep now Serial.println("Going to sleep now"); delay(1000); esp_deep_sleep_start(); } void loop() { }
Hi.
That’s very weird.
So, you are saying that with some ESP32 boards, it saves the bootCount on the RTC memory while working on battery, and with other boards it doesn’t?
Can you tell me exactly which boards are you using and how are you powering them with batteries?
Regards,
Sara
Hi Sara,
Electronics can be sooo weird sometimes. I found my problem. I realized upon getting your response, that I must have missed something. So, I reviewed my setup and made sure that when I was powering each of the 4 different Esp32 boards on batteries that I was actually furnishing power to the Esp32 boards. Well that all checked out fine, but all of a sudden everything started to work like it should have. It turns out that each time I was on the battery power I was running the power thru an electronic amp meter to measure the current when the boards were active vs. being in deep sleep. But this time when I was measuring the power to the boards, the VOM was out of the circuit and being used as a volt meter. It seems the VOM when in the circuit as an amp meter was introducing noise on the power line and causing Esp32 boards to oscillate. During these checks this time, I could hear a very high pitched frequency when the amp meter was in the circuit and I noticed that the power to the Esp32 board was fluctuating very erratically 20 ma. or 30 ma. and wouldn’t go into deep sleep. Mystery solved, but who would have guessed an amp meter? Keep safe and thanks for responding so quickly. Bob