Manual Mercury V1
Descubre cómo volar rápidamente con facilidad, conecta tu altimeter para subir datos al sitio web de Altimeter Cloud y todas las características avanzadas también. Si estás atascado o apenas comenzando, este es el lugar indicado.

Poniendo el Mercury en sueño profundo < 24uA

PDF

El altímetro puede entrar en modo de reposo profundo y consumir casi ninguna potencia mientras mantiene el suministro de 3.3V al dispositivo y los sistemas.
Los LED de estado y los sensores también pueden desactivarse en modo de reposo profundo.
Debido a la fuga de potencia en la línea I2C en las revisiones de hardware 1-3, estos deben dejar los sensores encendidos pero recibir instrucciones de entrar en reposo para obtener el modo de reposo profundo más eficiente de alrededor de 24uA.
La revisión de hardware 4+ puede apagar los sensores y lograr alrededor de 20uA en reposo.

Todos los pines no utilizados deben restablecerse usando el comando gpio_reset_pin(GPIO_NUM_21); y luego mantener todos los pines GPIO antes de entrar en reposo profundo para obtener el consumo de potencia absoluto más bajo.
Con una potencia de reposo de 24uA, la batería interna de 50mAh durará alrededor de 3 meses en reposo profundo. 

Este código también demuestra cómo usar el botón POWER, que en realidad es un botón de reinicio, como un botón de encendido/apagado. Esto se logra guardando un alternador de 0 o 1 en las preferencias NVS. Esto significa que en cada ciclo de reinicio, el código irá a ON u OFF. 

¿Utilizando Arduino IDE? Nuestro programador en línea incluye Mercury_Pins.h de forma predeterminada, por lo que los nombres de pin funcionan sin problemas. Si está utilizando Arduino IDE u otro programador, copie el contenido de la pestaña Mercury_Pins.h y péguelo en la parte superior de su programa.
/*
 * Ejemplo de alternancia de reposo profundo de Mercury
 * Cada reinicio alterna entre ON (destello verde) y OFF (reposo profundo).
 * Los sensores se ponen en reposo a través de I2C antes de entrar en reposo profundo.
 * VACC permanece HIGH para evitar fugas de corriente a través de los diodos ESD de las resistencias pull-up de I2C.
 */
#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() {
    // Encender la alimentación del sensor
    pinMode(VACC, OUTPUT);
    digitalWrite(VACC, HIGH);

    // NeoPixel encendido, destello rojo para confirmar reinicio
    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();

    // — Decisión temprana de encendido/apagado antes de inicializar Serial o USB —
    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();

    // ——————————————————————————————————————————————————————————————
    // RUTA DE REPOSO — onoroff es 0, poner sensores en reposo e entrar en reposo profundo
    // ——————————————————————————————————————————————————————————————
    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);

        // — Poner sensores en reposo a través de I2C —
        // VACC permanece HIGH — si cortamos la alimentación del sensor, las resistencias
        // pull-up de I2C (conectadas a 3V3) filtrarían corriente a través de los diodos
        // de protección ESD del sensor. En su lugar, enviamos comandos de reposo.
        Wire.begin(SDA, SCL);
        delay(10);

        // BMP581 (rev 3+ en 0x47): escribir 0x00 en el registro ODR = en espera ~1.3uA
        if (i2cPresent(0x47)) i2cWrite(0x47, 0x37, 0x00);

        // BMP390 (rev 0-2 en 0x77): escribir 0x00 en PWR_CTRL = reposo ~3.4uA
        if (i2cPresent(0x77)) i2cWrite(0x77, 0x1B, 0x00);

        // LSM6DSO32 (todas las revisiones en 0x6B): apagar acelerómetro + giroscopio ~3uA
        if (i2cPresent(0x6B)) {
            i2cWrite(0x6B, 0x10, 0x00);  // CTRL1_XL = acelerómetro apagado
            i2cWrite(0x6B, 0x11, 0x00);  // CTRL2_G  = giroscopio apagado
        }

        Wire.end();

        // — Apagar NeoPixel —
        digitalWrite(LEDPOWER, LOW);
        pinMode(LED, OUTPUT);
        digitalWrite(LED, LOW);

        // — Apagar salida —
        pinMode(OUT1, OUTPUT);
        digitalWrite(OUT1, LOW);

        // — Mantener pines durante reposo profundo —
        // gpio_hold_en le dice al RTC que mantenga el nivel actual de cada pin
        // mientras el controlador GPIO principal está apagado.
        // Sin esto, los pines flotarían y los sensores podrían consumir corriente adicional.
        gpio_hold_en((gpio_num_t)VACC);       // Mantenido HIGH — sensores alimentados en reposo
        gpio_hold_en((gpio_num_t)LEDPOWER);   // Mantenido LOW
        gpio_hold_en((gpio_num_t)LED);        // Mantenido LOW
        gpio_hold_en((gpio_num_t)OUT1);       // Mantenido LOW

        esp_deep_sleep_start();
    }

    // ——————————————————————————————————————————————————————————————
    // RUTA ON — liberar retenciones y ejecutar
    // ——————————————————————————————————————————————————————————————
    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);

    // Restaurar alimentación (puede haber sido mantenida desde el reposo)
    digitalWrite(VACC, HIGH);
    digitalWrite(LEDPOWER, HIGH);
}

void loop() {
    // Destello verde/azul cuando está en estado encendido
    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
/*
 * Definiciones de pines de Mercury (ESP32-C6)
 * Asignaciones de GPIO específicas de la placa
 */

// — LED de estado (NeoPixel) —
#define LEDPOWER      3    // Alimentación de NeoPixel (llevar HIGH para habilitar)
#define LED           2    // Señal de datos de NeoPixel

// — Bus I2C —
#define SDA           21   // Datos I2C
#define SCL           22   // Reloj I2C

// — Alimentación del sensor —
#define VACC          20   // Carril de alimentación del sensor (llevar HIGH para habilitar)

// — Puertos de propósito general —
#define GP06          6    // Puerto GP06
#define GP07          7    // Puerto GP07

// — Salida de alto amperaje —
#define OUT1          5    // Salida de alto amperaje (p. ej. pirotécnico / relé)

// — LED de batería —
#define BL1           4    // LED de batería 1 (más bajo)
#define BL2           14   // LED de batería 2
#define BL3           15   // LED de batería 3
#define BL4           18   // LED de batería 4
#define BL5           19   // LED de batería 5 (más alto)

// — Indicadores —
#define DISK          8    // LED de actividad de disco

// — Analógico / Detección —
#define BATIN         0    // Voltaje de batería (divisor 1:1)
#define USBDETECT     1    // Detección de alimentación USB (HIGH = USB presente)
#define BUTTON        9    // BUTTON en la placa, botón de arranque pero se puede usar