Skip to content

Instantly share code, notes, and snippets.

@hggh
Created June 4, 2022 09:31
Show Gist options
  • Save hggh/6c33a130d9df5d71e38edde374a77777 to your computer and use it in GitHub Desktop.
Save hggh/6c33a130d9df5d71e38edde374a77777 to your computer and use it in GitHub Desktop.
ESP32-S2 deep sleep with bme280
#include <Arduino.h>
#include <Wire.h>
#include <WiFi.h>
#include <MQTT.h>
#include <SparkFunBME280.h>
#include <esp_wifi.h>
#include "esp_sleep.h"
#include <driver/adc_common.h>
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "esp_wifi.h"
#include <driver/adc_common.h>
#include "driver/gpio.h"
#include "driver/rtc_io.h"
BME280 bme;
WiFiClient wifi;
MQTTClient mqtt;
RTC_DATA_ATTR unsigned int status_boot_count = 0;
RTC_DATA_ATTR unsigned int status_wifi_errors = 0;
//#define DEBUG 1
#define uS_TO_S_FACTOR 1000000
#define DEFAULT_VREF 3300
#define NO_OF_SAMPLES 10
#define ADC_LIC_PIN GPIO_NUM_6
#define ADC_SOLAR_PIN GPIO_NUM_4
adc_channel_t adc_lic_pin_channel = ADC_CHANNEL_5;
adc_channel_t adc_solar_pin_channel = ADC_CHANNEL_3;
#define MQTT_SERVER "xx.xx.xx.xx"
#define MQTT_USERNAME "xx"
#define MQTT_PASSWORD "x"
const char* ssid = "xx-xx";
const char* password = "xx";
IPAddress ip_ip(x, xx, xx, xx);
IPAddress ip_gateway(x, x, x, 1);
IPAddress ip_dns(x, x, x, 1);
IPAddress ip_subnet(255, 255, 255, 0);
int get_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
#ifdef DEBUG
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;
}
#endif
return wakeup_reason;
}
float get_voltage(adc_channel_t channel, gpio_num_t pin) {
static float volt_r1 = 1000000.0;
static float volt_r2 = 1000000.0;
static esp_adc_cal_characteristics_t adc_chars;
static const adc_bits_width_t width = ADC_WIDTH_BIT_13;
static const adc_atten_t atten = ADC_ATTEN_DB_11;
adc_power_acquire();
gpio_reset_pin(pin);
gpio_set_direction(pin, GPIO_MODE_INPUT);
adc1_config_width(width);
adc1_config_channel_atten((adc1_channel_t)channel, atten);
esp_adc_cal_characterize(ADC_UNIT_1, atten, width, DEFAULT_VREF, &adc_chars);
uint32_t adc_reading = 0;
for (int i = 0; i < NO_OF_SAMPLES; i++) {
adc_reading += adc1_get_raw((adc1_channel_t)channel);
}
adc_reading /= NO_OF_SAMPLES;
// get mV
uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, &adc_chars);
float real_voltage = (voltage / 1000.0) / (volt_r2 / ( volt_r1 + volt_r2));
adc_power_release();
rtc_gpio_isolate(pin);
return real_voltage;
}
void goto_sleep() {
bme.setMode(MODE_SLEEP);
mqtt.disconnect();
delay(1);
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
esp_wifi_stop();
adc_power_off();
esp_sleep_enable_timer_wakeup((uint64_t)15 * (uint64_t)60 * (uint64_t)uS_TO_S_FACTOR);
esp_deep_sleep_start();
}
void setup() {
adc_power_on();
++status_boot_count;
setCpuFrequencyMhz(80);
#ifdef DEBUG
Serial.begin(115200);
#endif
get_wakeup_reason();
Wire.begin();
bme.setI2CAddress(0x76);
bme.beginI2C();
bme.setMode(MODE_SLEEP);
bme.setMode(MODE_FORCED);
WiFi.mode(WIFI_STA);
WiFi.persistent(false);
WiFi.setHostname("weatherstation");
WiFi.config(ip_ip, ip_gateway, ip_subnet, ip_dns, ip_dns);
WiFi.begin(ssid, password);
bool wifi_ok = false;
for(int i=0; i < 2000; i++) {
if (WiFi.status() == WL_CONNECTED) {
wifi_ok = true;
break;
}
delay(1);
#ifdef DEBUG
Serial.print(".");
#endif
}
if (wifi_ok == false) {
status_wifi_errors++;
goto_sleep();
}
float volt_solar = get_voltage(adc_solar_pin_channel, ADC_SOLAR_PIN);
float volt_lic = get_voltage(adc_lic_pin_channel, ADC_LIC_PIN);
mqtt.begin(MQTT_SERVER, wifi);
mqtt.setTimeout(5);
mqtt.connect("weatherstation", MQTT_USERNAME, MQTT_PASSWORD);
mqtt.loop();
mqtt.publish("/weatherstation/bootcount/state", String(status_boot_count).c_str(), false, 1);
mqtt.publish("/weatherstation/wifierrors/state", String(status_wifi_errors).c_str()), false, 1;
mqtt.publish("/weatherstation/humidity/state", String(bme.readFloatHumidity()).c_str(), false, 1);
mqtt.publish("/weatherstation/temperature/state", String(bme.readTempC()).c_str(), false, 1);
mqtt.publish("/weatherstation/pressure/state", String(bme.readFloatPressure() / 100.0).c_str(), false, 1);
mqtt.publish("/weatherstation/volt_solar/state", String(volt_solar).c_str(), false, 1);
mqtt.publish("/weatherstation/volt_lic/state", String(volt_lic).c_str(), false, 1);
wifi.flush();
mqtt.loop();
#ifdef DEBUG
Serial.print("BootCount: ");
Serial.println(status_boot_count);
Serial.print("volt_solar: ");
Serial.println(volt_solar);
Serial.print("volt_lic: ");
Serial.println(volt_lic);
#endif
goto_sleep();
}
void loop() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment