Detector de mala postura python/Arduino

Introducción

Este proyecto utiliza un Arduino para crear un sencillo detector de mala postura. Usaremos un sensor ultrasónico para medir la distancia entre el usuario y el dispositivo. Si la distancia disminuye por debajo de un umbral (indicando que la persona se ha encorvado), se activará una alerta sonora mediante un zumbador y una alerta visual con un LED. Es una excelente manera de aprender a usar sensores de distancia y controlar salidas basadas en condiciones.

Materiales Necesarios

  • Placa Arduino UNO (o compatible)

  • Sensor Ultrasónico HC-SR04

  • Zumbador (Buzzer) piezoeléctrico

  • 1 LED (cualquier color)

  • 1 Resistencia de 220 ohmios (para proteger el LED)

  • Protoboard

  • Cables Jumper (macho-macho y macho-hembra)

Esquema de Montaje

El montaje se centra en conectar el sensor ultrasónico y los componentes de alerta (LED y zumbador) al Arduino.

Conexiones:

  • Sensor HC-SR04:
        • VCC → Pin 5V del Arduino.

        • Trig → Pin digital 10 del Arduino.

        • Echo → Pin digital 11 del Arduino.

        • GND → Pin GND del Arduino.

      • Zumbador:

        • Pata positiva (+) → Pin digital 9 del Arduino.

        • Pata negativa (-) → Pin GND del Arduino.

      • LED:

        • Pata larga (ánodo, +) → Un extremo de la resistencia de 220Ω. El otro extremo de la resistencia → Pin digital 8 del Arduino.

        • Pata corta (cátodo, -) → Pin GND del Arduino.

Código de Arduino

// Definimos los pines para el sensor ultrasónico y las alertas
const int trigPin = 10;
const int echoPin = 11;
const int buzzerPin = 9;
const int ledPin = 8;

// Variables para la distancia y duración del pulso
long duration;
int distance;

// Umbral de distancia (en cm) para detectar mala postura
// Ajusta este valor según tu configuración y la distancia deseada
int postureThreshold = 30; // Por ejemplo, alerta si está a menos de 30 cm

void setup() {
  pinMode(trigPin, OUTPUT); // Trig Pin será una salida
  pinMode(echoPin, INPUT); // Echo Pin será una entrada
  pinMode(buzzerPin, OUTPUT); // Buzzer Pin será una salida
  pinMode(ledPin, OUTPUT); // LED Pin será una salida
  Serial.begin(9600); // Iniciamos comunicación serial para depuración (opcional)
}

void loop() {
  // Generamos un pulso corto en el pin Trig para iniciar la medición
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Leemos la duración del pulso de retorno en el pin Echo
  duration = pulseIn(echoPin, HIGH);

  // Calculamos la distancia en centímetros
  // Velocidad del sonido = 343 m/s = 0.0343 cm/µs
  // Distancia = (Tiempo * Velocidad) / 2 (porque el sonido va y vuelve)
  distance = duration * 0.0343 / 2;

  // Mostramos la distancia en el Monitor Serie (opcional)
  Serial.print("Distancia: ");
  Serial.print
				

Código de Python

  1. Necesitas tener Python instalado en tu ordenador.

  2. Necesitas instalar la biblioteca pyserial. Puedes hacerlo abriendo una terminal o símbolo del sistema y ejecutando: pip install pyserial

import serial
import time

# --- Configuración ---
# Reemplaza 'COM3' con el puerto serie correcto de tu Arduino.
# En Linux/Mac puede ser algo como '/dev/ttyACM0' o '/dev/tty.usbmodemXXXX'
# Puedes encontrar el puerto en el IDE de Arduino (Herramientas -> Puerto).
SERIAL_PORT = 'COM3'
BAUD_RATE = 9600

# El mismo umbral que usaste en el código de Arduino (en cm)
POSTURE_THRESHOLD = 30
# --- Fin Configuración ---

print(f"Intentando conectar al puerto {SERIAL_PORT} a {BAUD_RATE} baudios...")

try:
    # Inicializa la conexión serie
    arduino = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1)
    # Espera un momento para que se establezca la conexión
    time.sleep(2)
    print("Conexión establecida. Esperando datos...")

    while True:
        try:
            # Lee una línea de datos desde el Arduino
            line = arduino.readline().decode('utf-8').strip()

            # Comprueba si la línea contiene la palabra "Distancia"
            if "Distancia:" in line:
                print(f"Recibido: {line}")  # Muestra la línea completa recibida

                try:
                    # Divide la cadena por ':' y luego por ' ' para aislar el número
                    parts = line.split(':')
                    if len(parts) > 1:
                        # Corrección de sintaxis en el original (falta un punto)
                        distance_str = parts[1].strip().split(' ')[0]
                        distance = int(distance_str)

                        # Comprueba si la distancia es menor que el umbral
                        if 0 < distance < POSTURE_THRESHOLD:
                            print("---------------------------------")
                            print("¡ALERTA! Mala postura detectada.")
                            print("---------------------------------")

                except ValueError:
                    # Si no se puede convertir a número, ignora la línea
                    pass
                except Exception as e:
                    print(f"Error procesando la línea: {e}")

            # Pequeña pausa para no sobrecargar la CPU
            time.sleep(0.05)

        except serial.SerialException as e:
            print(f"Error de lectura del puerto serie: {e}")
            break
        except KeyboardInterrupt:
            print("\nDeteniendo el script.")
            break
        except Exception as e:
            print(f"Ocurrió un error inesperado: {e}")
            # Intenta seguir leyendo si es posible
            time.sleep(1)

except serial.SerialException as e:
    print(f"No se pudo conectar al puerto {SERIAL_PORT}. Error: {e}")
    print("Verifica que el puerto sea correcto y que no esté siendo usado por otro programa (como el Monitor Serie del IDE de Arduino).")
finally:
    # Asegúrate de cerrar el puerto al salir
    if 'arduino' in locals() and arduino.is_open:
        arduino.close()
        print("Puerto serie cerrado.")

Explicación del Código

 

  • Medición Ultrasónica:

    • El sensor HC-SR04 funciona enviando un pulso de sonido (Trig) y midiendo el tiempo que tarda en regresar el eco (Echo).

    • Enviamos un pulso corto (HIGH por 10 microsegundos) en trigPin.

    • Usamos pulseIn(echoPin, HIGH) para medir cuánto tiempo el pin Echo permanece en HIGH. Este es el tiempo que tardó el sonido en ir y volver.

    • La distancia se calcula usando la fórmula: distancia = (duración * velocidad_del_sonido) / 2. Usamos 0.0343 cm/µs como velocidad del sonido. Dividimos por 2 porque la duración medida es del viaje de ida y vuelta.

  • Detección de Postura:

    • Establecemos una variable postureThreshold que define la distancia mínima (en cm) a la que debe estar el usuario.

    • En el loop(), después de calcular la distance, usamos una sentencia if para comprobar si distance es menor que postureThreshold (y mayor que 0 para evitar errores de lectura).

  • Activación de Alertas:

    • Si la condición del if es verdadera (mala postura), activamos el zumbador con tone(buzzerPin, 1000), que genera un sonido de 1000 Hz.

    • También encendemos el LED con digitalWrite(ledPin, HIGH).

  • Desactivación de Alertas:

    • Si la condición del if es falsa (buena postura o sensor no detecta nada cercano), usamos noTone(buzzerPin) para silenciar el zumbador y digitalWrite(ledPin, LOW) para apagar el LED.

  • delay(100): Añadimos una pequeña pausa al final del loop para estabilizar las lecturas y evitar que el zumbador suene de forma demasiado continua si se está cerca del umbral.