Příručka Mercury V1
Zjistěte, jak létat rychle a snadno, připojte svůj výškoměr pro nahrávání na webové stránky Altimeter Cloud a využijte všechny pokročilé funkce. Pokud jste v nouzi nebo teprve začínáte, jste tu správně.

Uvedení Mercury do hlubokého režimu spánku < 24µA

PDF

Altimetr lze uvést do hlubokého spánku a spotřebovávat téměř žádný výkon při zachování 3,3V napájení zařízení a systémů.
Stavové LED a senzory mohou být v hlubokém spánku také vypnuty.
Vzhledem k úniku energie na I2C lince u revizí hardwaru 1 - 3 by měly být senzory zapnuty, ale instruovány, aby přešly do spánku, aby se dosáhlo nejvíce efektivního hlubokého spánku kolem 24uA.
Hardware revize 4+ může mít senzory vypnuty a dosáhnout kolem 20uA v režimu spánku.

Všechny nepoužívané piny by měly být resetovány pomocí příkazu gpio_reset_pin(GPIO_NUM_21); a poté by všechny GPIO piny měly být uzavřeny před vstupem do hlubokého spánku, aby se dosáhlo absolutně nejnižší spotřeby energie.
Při 24uA spotřebě spánku interní 50mAh bude trvat kolem 3 měsíců v hlubokém spánku. 

Tento kód také demonstruje, jak používat tlačítko POWER, které je ve skutečnosti resetovacím tlačítkem jako na/vypínací tlačítko. To se dosahuje uložením přepínače 0 nebo 1 do preferencí NVS. To znamená, že při každém cyklu resetování bude kód buď ZAPNUTý nebo VYPNUTý. 

Používáte Arduino IDE? Náš online programátor zahrnuje Mercury_Pins.h ve výchozím nastavení, takže názvy pinů fungují bez problémů. Pokud používáte Arduino IDE nebo jiný programátor, zkopírujte obsah karty Mercury_Pins.h a vložte jej na začátek vašeho programu.
/*
 * 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