44. Ejemplo 2: Envió de datos de Arduino(Potenciómetro) hacia Python - Teoría

📡 Captura de Datos Serial: Potenciómetro Arduino → Python

¡Hola comunidad! 👋 Hoy vamos a explorar cómo capturar datos a través del puerto serial usando Arduino y Python. Vamos a conectar un potenciómetro y visualizar sus datos en tiempo real desde Python. ¡Vamos al código! 🚀

🔌 Hardware Básico

Para este proyecto necesitamos:

  • Arduino (cualquier modelo con puerto serial)

  • Potenciometro de 10kΩ

  • Conexiones básicas al pin analógico

💾 Código Arduino

cpp
// Arduino: Lectura del potenciómetro
const int potPin = A0;  // Pin analógico
int valor = 0;

void setup() {
  Serial.begin(9600);   // Inicia comunicación serial
}

void loop() {
  valor = analogRead(potPin);  // Lee valor (0-1023)
  Serial.println(valor);       // Envía con salto de línea
  delay(100);                  // Cada 100ms
}

Explicación clave:

  • Serial.println(valor) envía el dato con salto de línea

  • El delay de 100ms evita saturar el puerto serial

  • La lectura analógica devuelve valores entre 0-1023

🐍 Código Python para Recepción

python
import serial
import time

# Configuración del puerto
puerto = 'COM5'      # ¡Ajusta según tu sistema!
baudios = 9600
timeout = 1          # Timeout de 1 segundo

try:
    # Conexión con Arduino
    arduino = serial.Serial(puerto, baudios, timeout=timeout)
    time.sleep(2)    # Espera para conexión estable
    
    print(f"Conexión establecida con Arduino en {puerto}")
    
    # Bucle infinito para recepción continua
    while True:
        if arduino.in_waiting > 0:  # Si hay datos disponibles
            # Decodificación del dato recibido
            dato = arduino.readline().decode('latin-1').rstrip()
            
            try:
                # Conversión a entero (casteo)
                valor_entero = int(dato)
                print(f"Dato recibido: {valor_entero}")
                
            except ValueError:
                print(f"Error: Dato recibido no es un número entero válido: {dato}")
                # break  # Opcional: romper el bucle en caso de error
                
except serial.SerialException as e:
    print(f"Error de conexión: {e}")
except KeyboardInterrupt:
    print("\nPrograma interrumpido por usuario")
finally:
    if 'arduino' in locals() and arduino.is_open:
        arduino.close()
        print("Conexión serial cerrada")

🔍 Análisis Detallado del Código Python

1. Configuración Inicial

python
puerto = 'COM5'  # Windows
# Para Linux: '/dev/ttyUSB0'
# Para Mac: '/dev/cu.usbmodem14101'

¡IMPORTANTE! Debes verificar tu puerto correcto en el Administrador de Dispositivos.

2. Establecimiento de Conexión

python
arduino = serial.Serial(puerto, baudios, timeout=timeout)
time.sleep(2)  # Tiempo crítico para estabilización

El time.sleep(2) es esencial para que el puerto serial se inicialice correctamente.

3. Bucle de Recepción Infinita

python
while True:

Necesitamos un bucle infinito porque en aplicaciones reales los datos llegan continuamente.

4. Decodificación del Dato

python
dato = arduino.readline().decode('latin-1').rstrip()
  • readline(): Lee hasta encontrar salto de línea

  • decode('latin-1'): Convierte bytes a string (también puede ser 'utf-8')

  • rstrip(): Elimina espacios y saltos de línea extra

5. Manejo de Errores con try-except

python
try:
    valor_entero = int(dato)  # Casteo a entero
except ValueError:
    print(f"Error: Dato recibido no es un número entero válido: {dato}")

El bloque try-except previene que el programa se detenga por datos corruptos.

⚠️ Puntos Críticos a Considerar

Formato de Decodificación

python
# Alternativas comunes:
.decode('latin-1')
.decode('utf-8')
.decode('ascii')

El formato depende de tu versión de Python y sistema. ¡Prueba cuál funciona!

Control del Bucle While

python
while True:
    # ... código de recepción ...
    # break  # ¡Comentado! ¿Qué pasa si lo activamos?

Pregunta clave: ¿Qué sucede cuando aparece un error?

  • Sin break: El programa sigue recibiendo indefinidamente

  • Con break: Sale del bucle y cierra la conexión

Cierre Elegante de Conexión

El bloque finally asegura que el puerto se cierre correctamente incluso si hay errores.

🔄 Adaptación para ESP32

Si usas ESP32 en lugar de Arduino:

cpp
// Para ESP32
const int potPin = 35;  // GPIO35 (pin analógico)
// ¡El resto del código es idéntico!

🎯 Buenas Prácticas

  1. Verifica siempre el puerto COM correcto

  2. Usa timeout para evitar bloqueos eternos

  3. Implementa manejo de errores robusto

  4. Considera agregar un mecanismo de salida controlada

  5. Prueba diferentes formatos de decodificación

📊 Posibles Mejoras

python
# Ejemplo: Agregar timestamp
from datetime import datetime
timestamp = datetime.now().strftime("%H:%M:%S.%f")[:-3]
print(f"[{timestamp}] Dato: {valor_entero}")

# Ejemplo: Guardar en archivo
with open('datos.csv', 'a') as f:
    f.write(f"{timestamp},{valor_entero}\n")

🤔 Reflexión Final

¿Se cierra el puerto automáticamente al error?

  • Respuesta: NO, sin un break explícito, el bucle continúa infinitamente

  • Solución recomendada: Implementar lógica de salida condicional

🚀 Próximos Pasos

  1. Agregar visualización gráfica en tiempo real

  2. Implementar control bidireccional (Python → Arduino)

  3. Crear interfaz gráfica de usuario

  4. Conectar múltiples sensores simultáneamente

¡Listo para la práctica! ¿Alguna pregunta antes de proceder con la demostración en vivo? 💻

#Arduino #Python #SerialCommunication #DataAcquisition #IoT #Programming #Electronics

¿Has implementado comunicación serial antes? ¡Comparte tus experiencias en los comentarios! 👇



Comentarios

Entradas populares de este blog

¿Qué es el Modelo OSI?

bit -El codigo ASCII

38. Tema 1: Protocolos de comunicación.