Wearables e IoTTécnico

Recordatorio de postura con ESP32 que vibra cuando te encorvas

Un dispositivo pequeño que se engancha a la ropa aprende tu posición derecha y vibra suave después de 30 segundos encorvado.

NivelTécnico
Tiempo1.5 h
Costo est.~$75
Pasos5

Una IMU mide hacia dónde jala la gravedad, así que sabe la inclinación de lo que tenga enganchado. Puesta en la parte alta de la espalda o el cuello de la camisa, una XIAO ESP32-C3 compara tu inclinación actual con tu postura derecha calibrada.

⚠ SEGURIDAD
Es un recordatorio de hábitos, no un aparato médico ni de terapia. Las baterías LiPo pueden incendiarse si se perforan, se sobrecargan o hacen cortocircuito. Cárgalas en una bolsa LiPo, nunca sin supervisión, y quita siempre las hélices mientras trabajas en la mesa.

Pasos de la misión

  1. Conecta la IMU

    SDA del MPU6050 a D4 (GPIO6), SCL a D5 (GPIO7), VCC a 3V3 y GND a GND.

  2. Controla el motor

    Activa el motor de vibración con un transistor NPN desde D0 (GPIO2) a través de una resistencia de 1 kΩ, con un diodo en paralelo con el motor.

  3. Graba MicroPython

    Instala MicroPython para el ESP32-C3 y guarda el script como main.py con Thonny.

  4. Calibra

    Siéntate derecho cuando encienda; promedia 20 lecturas como tu buena postura.

  5. Úsalo y ajusta

    Cambia el umbral de 15° y la espera de 30 segundos hasta que los recordatorios ayuden sin molestar.

Código

# main.py (MicroPython, XIAO ESP32-C3 + MPU6050)
from machine import I2C, Pin
import math, struct, time

i2c = I2C(0, sda=Pin(6), scl=Pin(7), freq=400000)
MPU = 0x68
i2c.writeto_mem(MPU, 0x6B, b'\x00')          # wake the sensor
motor = Pin(2, Pin.OUT, value=0)

def pitch():
    ax, ay, az = struct.unpack('>hhh', i2c.readfrom_mem(MPU, 0x3B, 6))
    return math.degrees(math.atan2(ax, math.sqrt(ay * ay + az * az)))

def buzz(n=3):
    for _ in range(n):
        motor.on(); time.sleep(0.3); motor.off(); time.sleep(0.3)

time.sleep(3)                                  # sit up straight now
ref = sum(pitch() for _ in range(20)) / 20
buzz(1)
slouch_since = None

while True:
    if abs(pitch() - ref) > 15:
        slouch_since = slouch_since or time.time()
        if time.time() - slouch_since > 30:
            buzz(); slouch_since = time.time()
    else:
        slouch_since = None
    time.sleep(0.5)

Code comments are in English, like most libraries and docs — a good habit for makers.

Preguntas

¿Qué eje debo usar?

Depende de cómo quede la placa en tu cuerpo. Imprime ax, ay y az mientras te inclinas hacia adelante y usa el eje que más cambie.