Log in to your Altimeter Cloud account
Don't have an account? Create one
We'll send a confirmation link to verify your email. Check your spam/junk folder if you don't see it.
Already have an account? Log in
The altimeter can be put in to deep sleep and consume almost no power while maintaining the 3.3V supply to the device and systems.
The Status LED's and sensors can be powered down in deep sleep as well.
Due to power leak on the I2C line on hardware revisions 1 - 3 these should leave the sensors on but be told to go to sleep to obtain the most efficient deep sleep of around 24uA.
Hardware revision 4+ can have the sensors powered off and achieve around 20uA in sleep.
All unused pins should be reset using the command gpio_reset_pin(GPIO_NUM_21); and then all GPIO pins held before going in to deep sleep to obtain the absolute lowest power consumption.
At 24uA sleep power the internal 50mAh will last around 3 months in deep sleep.
This code also demonstarates how to use the POWER button which is actually a reset button as a on/off power button. This is achieved by saving a toggle of 0 or 1 to the NVS preferences. This means on each reset cycle the code will either go ON or OFF.
/* * Mercury Deep Sleep Toggle Example * Each reset toggles between ON (green strobe) and OFF (deep sleep). * Sensors are put to sleep via I2C before entering deep sleep. * VACC stays HIGH to avoid current leaking through I2C pullup ESD diodes. */ #include "Wire.h" #include "Preferences.h" #include "Adafruit_NeoPixel.h" #include "esp_sleep.h" #include "driver/gpio.h" #include "WiFi.h" #include "Mercury_Pins.h" Adafruit_NeoPixel pixels(4, LED, NEO_GRB + NEO_KHZ800); Preferences preferences; unsigned int onoroff = 0; void led_clear() { pixels.setPixelColor(0, 0); pixels.setPixelColor(1, 0); pixels.setPixelColor(2, 0); pixels.setPixelColor(3, 0); pixels.show(); } void i2cWrite(uint8_t addr, uint8_t reg, uint8_t val) { Wire.beginTransmission(addr); Wire.write(reg); Wire.write(val); Wire.endTransmission(); } bool i2cPresent(uint8_t addr) { Wire.beginTransmission(addr); return (Wire.endTransmission() == 0); } void setup() { // Turn on sensor power pinMode(VACC, OUTPUT); digitalWrite(VACC, HIGH); // NeoPixel on, red flash to confirm reset pinMode(LEDPOWER, OUTPUT); digitalWrite(LEDPOWER, HIGH); delay(20); pixels.begin(); pixels.setPixelColor(0, pixels.Color(80, 0, 0)); pixels.setPixelColor(1, pixels.Color(80, 0, 0)); pixels.setPixelColor(2, pixels.Color(80, 0, 0)); pixels.setPixelColor(3, pixels.Color(80, 0, 0)); pixels.show(); delay(100); led_clear(); // ── Early on/off decision before Serial or USB init ── preferences.begin("example", false); delay(2); onoroff = preferences.getUInt("onoroff", 0); if (onoroff == 0) { onoroff = 1; } else { onoroff = 0; } preferences.putUInt("onoroff", onoroff); delay(10); preferences.end(); // ════════════════════════════════════════════════════════ // SLEEP PATH — onoroff is 0, put sensors to sleep and enter deep sleep // ════════════════════════════════════════════════════════ if (onoroff == 0) { pixels.setPixelColor(0, pixels.Color(80, 0, 0)); pixels.setPixelColor(1, pixels.Color(80, 0, 0)); pixels.setPixelColor(2, pixels.Color(80, 0, 0)); pixels.setPixelColor(3, pixels.Color(80, 0, 0)); pixels.show(); delay(1200); led_clear(); delay(5); // ── Put sensors to sleep via I2C ── // VACC stays HIGH — if we cut sensor power the I2C pullups // (connected to 3V3) would leak current through the sensor // ESD protection diodes. Instead we send sleep commands. Wire.begin(SDA, SCL); delay(10); // BMP581 (rev 3+ at 0x47): write 0x00 to ODR register = standby ~1.3uA if (i2cPresent(0x47)) i2cWrite(0x47, 0x37, 0x00); // BMP390 (rev 0-2 at 0x77): write 0x00 to PWR_CTRL = sleep ~3.4uA if (i2cPresent(0x77)) i2cWrite(0x77, 0x1B, 0x00); // LSM6DSO32 (all revisions at 0x6B): power down accel + gyro ~3uA if (i2cPresent(0x6B)) { i2cWrite(0x6B, 0x10, 0x00); // CTRL1_XL = accel off i2cWrite(0x6B, 0x11, 0x00); // CTRL2_G = gyro off } Wire.end(); // ── Turn off NeoPixel ── digitalWrite(LEDPOWER, LOW); pinMode(LED, OUTPUT); digitalWrite(LED, LOW); // ── Turn off output ── pinMode(OUT1, OUTPUT); digitalWrite(OUT1, LOW); // ── Hold pins during deep sleep ── // gpio_hold_en tells the RTC to maintain each pin's current // level while the main GPIO controller is powered down. // Without this, pins float and sensors could draw extra current. gpio_hold_en((gpio_num_t)VACC); // Held HIGH — sensors powered in sleep gpio_hold_en((gpio_num_t)LEDPOWER); // Held LOW gpio_hold_en((gpio_num_t)LED); // Held LOW gpio_hold_en((gpio_num_t)OUT1); // Held LOW esp_deep_sleep_start(); } // ════════════════════════════════════════════════════════ // ON PATH — release holds and run // ════════════════════════════════════════════════════════ gpio_hold_dis((gpio_num_t)VACC); gpio_hold_dis((gpio_num_t)LEDPOWER); gpio_hold_dis((gpio_num_t)LED); gpio_hold_dis((gpio_num_t)OUT1); // Restore power (may have been held from sleep) digitalWrite(VACC, HIGH); digitalWrite(LEDPOWER, HIGH); } void loop() { // Flash green/blue when in on state for (int i = 0; i < 4; i++) { pixels.setPixelColor(i, pixels.Color(0, 80, 0)); } pixels.show(); delay(200); for (int i = 0; i < 4; i++) { pixels.setPixelColor(i, pixels.Color(0, 0, 80)); } pixels.show(); delay(200); }#pragma once /* * Mercury (ESP32-C6) Pin Definitions * Board-specific GPIO assignments */ // ── Status LED (NeoPixel) ── #define LEDPOWER 3 // NeoPixel power (drive HIGH to enable) #define LED 2 // NeoPixel data signal // ── I2C Bus ── #define SDA 21 // I2C data #define SCL 22 // I2C clock // ── Sensor Power ── #define VACC 20 // Sensor power rail (drive HIGH to enable) // ── General Purpose Ports ── #define GP06 6 // GP06 port #define GP07 7 // GP07 port // ── High Current Output ── #define OUT1 5 // High current output (e.g. pyro / relay) // ── Battery Bar LEDs ── #define BL1 4 // Battery LED 1 (lowest) #define BL2 14 // Battery LED 2 #define BL3 15 // Battery LED 3 #define BL4 18 // Battery LED 4 #define BL5 19 // Battery LED 5 (highest) // ── Indicators ── #define DISK 8 // Disk activity LED // ── Analogue / Detection ── #define BATIN 0 // Battery voltage (1:1 divider) #define USBDETECT 1 // USB power detect (HIGH = USB present) #define BUTTON 9 // BUTTON on the board, boot button but can be used