Weather station with was: ESP32 C3 Mini now: XIAO ESP32 C3

I'm thinking of finally dipping a toe in the ESP32 water and would like some constructive criticism of my idea.

Currently my weather station has a Wemos D1 mini pro (ESP8266), plus an ATtiny85. I've never been entirely happy with this arrangement. How many times have I lectured beginners on this forum about not using 2 "Arduino" (ie. 2 MCU) in the same circuit? Yet I did it myself.

My reason was that the wind speed anemometer, wind vane and rain guage need constant monitoring. All 3 sensors are based on magnets and reed switches. Something needs to detect their signal edges or resistance continuously.

Because the weather station runs on battery power (li-ion cell), I need to minimise power usage, so the Wemos D1 mini needs to spend most of its time in deep sleep. The ATtiny monitors the wind & rain sensors continuously.

The D1 mini wakes every 15 mins, gets the readings from the ATtiny via software UART, it also reads SHT31 temp/humidity and BH1750 light level sensor over i2c, connects to WiFi and POSTs the data off to a local server on my LAN.

The D1 mini has a UFL connector to connect to an external higher gain antenna to ensure a reliable connection to the WiFi despite poor signal strength where it is located.

I'm thinking I could replace the D1 mini pro and ATtiny with an ESP32 C3 Super Mini "plus". The "plus" just means it has a UFL connector for that important external antenna.

I'm reading up about the specs and capabilities of the C3 to try to figure out if it's a good fit to replace the D1 + ATtiny.

I'm thinking that, similar to the D1 mini, the C3 will spend most of its time in deep sleep. But unlike the D1 mini, the C3 can wake from deep sleep when there are signal edges from the anemometer or rain gauge. This involves using a feature called "wake stub" which is a user-defined function that runs from its RTC memory, which is retained during deep sleep, unlike most of the RAM memory. Variables can also be stored in this RTC memory.

The wake stub function could, I think, count the signal edges from the anemometer/rain gauge, read the resistance of the wind vane and go immediately back to deep sleep.

On a timed 6 second interval, it would wake and check for a new highest wind gust speed and go back to deep sleep.

Every 150 timed wakes (15 mins), it would finally properly wake the ESP32 up to connect to WiFi and POST off the results.

So I would ideally like advice from someone with experience using the ESP32 C3 about my plan/idea. Can I use it like this? Will it wake from deep sleep fast enough for this idea too work?

Some further details: the anemometer could generate up to about 50 interrupts per second during extremely high winds. Most of the time it will be far fewer interrupts per second. The rain guage will only generate a few interrupts per minute at most even in heavy rain.

Note that the Seeed XIAO version of the ESP32C3 has a better build quality and it has a builtin charger and LiPo battery connection. Well worth a few dollars more.
It also comes with a stick-on aerial.
Leo..

2 Likes

Thanks, I'll definitely consider the XIAO.

The built-in charger isn't needed in this particular case. I currently replace the empty battery with a fully charged replacement so the sensor is back up and running.

I didn't know about the 'Wake Stub', I need to find the docs now. I assume the wind gauge will trigger the wake, but I am curious to hear how well that works at 50 interrupts per second.

Just found the docs, very cool.

Sorry, I should have posted the link

Deep Sleep Wake Stubs - ESP32-C3 - — ESP-IDF Programming Guide v5.0 documentation.

On the link above it says

The wake stub code can only call functions implemented in ROM or loaded into RTC Fast Memory (see below.)

I wonder if that would include digitalRead() and analogRead()? Those may be the only two functions I would need in the wake stub.

There's also a way to increase speed of wake up from deep sleep described here

I was surprised to find a ROM implementation of printf. Now I need to investigate everything in ROM.
I recently discovered the tiny size of the XIAO including the model with a camera. Literally the size of my thumbnail. Now this super low power functionality will keep me busy for the coming winter months.

1 Like

My ESP32 Supermini C3 arrived today. So far, so good!

I tested its wifi sensitivity, using its built-in antenna.

15:23:40.574 -> Scan start
15:23:43.356 -> Scan done
15:23:43.356 -> 4 networks found
15:23:43.356 -> Nr | SSID                             | RSSI | CH | Encryption
15:23:43.356 ->  1 | granary                          |  -47 | 13 | WPA2
15:23:43.356 ->  2 | DIRECT-59-HP M283 LaserJet       |  -53 |  6 | WPA2
15:23:43.356 ->  3 | granary2                         |  -91 |  1 | WPA+WPA2
15:23:43.389 ->  4 | (redacted)                       |  -92 | 11 | WPA2

For comparison, here are the results for my Wemos D1 mini pro using its built-in antenna, in the same position:

15:15:06.649 -> Scan start
15:15:08.870 -> Scan done
15:15:08.870 -> 3 networks found
15:15:08.870 -> Nr | SSID                             | RSSI | CH | Encryption
15:15:08.870 ->  1 | DIRECT-59-HP M283 LaserJet       |  -50 |  6 | WPA+WPA2
15:15:08.870 ->  2 | (redacted)                       |  -84 | 11 | WPA+WPA2
15:15:08.870 ->  3 | granary                          |  -45 | 13 | WPA+WPA2

and the Wemos D1 mini pro using an external antenna (maybe 3dBi, I can't remember):

15:20:42.997 -> Scan start
15:20:45.215 -> Scan done
15:20:45.215 -> 5 networks found
15:20:45.215 -> Nr | SSID                             | RSSI | CH | Encryption
15:20:45.215 ->  1 | (redacted)                       |  -94 |  1 | WPA+WPA2
15:20:45.215 ->  2 | DIRECT-59-HP M283 LaserJet       |  -42 |  6 | WPA+WPA2
15:20:45.215 ->  3 | (redacted)                       |  -97 | 10 | WPA+WPA2
15:20:45.215 ->  4 | (redacted)                       |  -75 | 11 | WPA+WPA2
15:20:45.249 ->  5 | granary                          |  -40 | 13 | WPA+WPA2

I need to figure out how to configure the C3 super mini to use an external antenna. Any idea, anyone?

This post gives a clue. I can't see your board in details. Some of them already have a zero ohm resistor connecting the 2 antennas. Never tried it myself.

Thanks for the link, but it looks wrong to me.


If you did what they are suggesting, the external antenna and the built-in antenna would both be connected at the same time. That would result in having the wrong impedance connected to the chip, which would give a poor result and possibly damage the chip, I think.

Perhaps it's also important to remove the built-in antenna when you make that link.

just solder/swipe off the red aerial first.
It's just a piece of double-sided circuit board with a 3-4 turn coil etched on it.
It's only electrically connected on one side, the hot side. The other side is just for support.
Too bad you didn't get the Seed XIAO ESP32C3. It's smaller, shielded has external aerial included and more.
Have fun with your new toys.
Leo..

Yeah, thought so, thanks @Wawa :slight_smile:

If things don't go well, I might still do that! The C3 supermini was very inexpensive and I was already putting an order in to the supplier, and I was curious.

Hard to imagine the XIAO is smaller than this thing! The C3 supermini also came with a stick-on antenna, I'll test it later and compare it to some others I have.

What's the "more"?

See the link in post#2.

Not sure about the wake-up capabilities of the C3.
That link says the C3 can only do GPIO wakeup. not timer wake-up from deepsleep.
Never had to use it myself, but I seem to remember that your weather station did GPIO wake-up from a second processor.
Leo..

Oh... I hope that's not the case. That would be a deal-breaker for my weather station. The ESP8266 has that feature, so I hope the C3 also has it also

I will update the topic when I find out!

According to the ESP32C3 datasheet:

Deep-sleep mode: CPU and most peripherals are powered down. Only the RTC memory is powered on.
Wi-Fi connection data are stored in the RTC memory. The RTC timer or the RTC GPIOs can wake up the
chip from the Deep-sleep mode.

That's a relief! Will confirm this works in practice... when I get around to it.

Testing the on-board Neopixel LED:

/*
  BlinkRGB

  Demonstrates usage of onboard RGB LED on some ESP dev boards.

  Calling digitalWrite(RGB_BUILTIN, HIGH) will use hidden RGB driver.

  RGBLedWrite demonstrates control of each channel:
  void rgbLedWrite(uint8_t pin, uint8_t red_val, uint8_t green_val, uint8_t blue_val)

  WARNING: After using digitalWrite to drive RGB LED it will be impossible to drive the same pin
    with normal HIGH/LOW level
*/
#define RGB_BRIGHTNESS 255 // Change white brightness (max 255)

// the setup function runs once when you press reset or power the board

void setup() {
  // No need to initialize the RGB LED
}

// the loop function runs over and over again forever
void loop() {
#ifdef RGB_BUILTIN
  digitalWrite(RGB_BUILTIN, HIGH);  // Turn the RGB LED white == 20.9mA
  delay(5000);
  digitalWrite(RGB_BUILTIN, LOW);  // Turn the RGB LED off == 18.5mA
  delay(5000);

  rgbLedWrite(RGB_BUILTIN, RGB_BRIGHTNESS, RGB_BRIGHTNESS, RGB_BRIGHTNESS);  // White == 27.5mA
  delay(5000);
  rgbLedWrite(RGB_BUILTIN, RGB_BRIGHTNESS, 0, 0);  // Red == 21.9mA
  delay(5000);
  rgbLedWrite(RGB_BUILTIN, 0, RGB_BRIGHTNESS, 0);  // Green == 21.7mA
  delay(5000);
  rgbLedWrite(RGB_BUILTIN, 0, 0, RGB_BRIGHTNESS);  // Blue == 21.4mA
  delay(5000);
  rgbLedWrite(RGB_BUILTIN, 0, 0, 0);  // Off / black == 18.5mA
  delay(5000);
#endif
}

It seems that using digitalWrite(RGB_BUILTIN, HIGH) does not set it to maximum brightness.

I have a concern about this LED: I know many ws2812 leds have a quiescent current of <1mA. But even this might significantly increase consumption when the board is in deep sleep.

Testing Deep Sleep mode:

/*
Simple Deep Sleep with Timer Wake Up
=====================================
ESP32 offers a deep sleep mode for effective power
saving as power is an important factor for IoT
applications. In this mode CPUs, most of the RAM,
and all the digital peripherals which are clocked
from APB_CLK are powered off. The only parts of
the chip which can still be powered on are:
RTC controller, RTC peripherals ,and RTC memories

This code displays the most basic deep sleep with
a timer to wake it up and how to store data in
RTC memory to use it over reboots

This code is under Public Domain License.

Author:
Pranav Cherukupalli <cherukupallip@gmail.com>
*/

#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  5          /* Time ESP32 will go to sleep (in seconds) */

RTC_DATA_ATTR int bootCount = 0;

/*
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;
  }
}

void setup() {
  Serial.begin(115200);
  delay(1000);  //Take some time to open up the Serial Monitor

  //Increment boot number and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  //Print the wakeup reason for ESP32
  print_wakeup_reason();

  /*
  First we configure the wake up source
  We set our ESP32 to wake up every 5 seconds
  */
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");

  /*
  Next we decide what all peripherals to shut down/keep on
  By default, ESP32 will automatically power down the peripherals
  not needed by the wakeup source, but if you want to be a poweruser
  this is for you. Read in detail at the API docs
  http://esp-idf.readthedocs.io/en/latest/api-reference/system/deep_sleep.html
  Left the line commented as an example of how to configure peripherals.
  The line below turns off all RTC peripherals in deep sleep.
  */
  //esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
  //Serial.println("Configured all RTC Peripherals to be powered down in sleep");

  /*
  Now that we have setup a wake cause and if needed setup the
  peripherals state in deep sleep, we can now start going to
  deep sleep.
  In the case that no wake up sources were provided but deep
  sleep was started, it will sleep forever unless hardware
  reset occurs.
  */
  Serial.println("Going to sleep now");
  Serial.flush();
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop() {
  //This is not going to be called
}

I'm seeing consumption of about 1.1~1.2mA during Deep Sleep. I can think of at least 2 reasons for this:

  • The small red power LED. This, according to the schematics I can find, has a 10K series resistor and is connected to Vsys, which is in turn connected to Vbus (pin marked "5V") via a BAT60J schottky diode which will drop about 0.3V. So I estimate this LED will draw around 0.3mA when connected to USB/5V and maybe 0.15mA when the 5V pin is connected to a Li-po pack.
  • The quiescent current of the Neopixel LED. Assuming the C3 chip is drawing the advertised ~50uA in Deep Sleep, the remaining ~1mA could be the quiescent current of this LED.

Conclusions so far about the ESP32 C3 Supermini plus:

  1. ESP32C3 will indeed wake from internal RTC timer :slight_smile:
  2. Current consumption in Deep Sleep will not be an improvement on my current solution of Wemos D1 mini pro + ATtiny85 :frowning:

After today's testing, I agree! Considering purchase of the XIAO now. On Temu, where I purchased the C3 Supermini Plus, the XIAO is about 3x more expensive. But maybe worth it for my purposes.

It seems Temu is quite expensive place to buy XIAO ESP32C3 (£7.70). That would be a good price for x3, but you only get 1 for your money!

I will shop around. Suspect I can get lower price than that from UK supplier, and lower still from China.

Just purchased from AliExpress for £1.63, free postage... Crazy