Descripción general

Este script en Python está diseñado para establecer una comunicación serial con un dispositivo (llamado Burro IPA) a través de un puerto serial especificado. El objetivo principal del script es enviar un mensaje de handshake (@HLWD*) al dispositivo y esperar una respuesta de reconocimiento (#ACK*). Si se recibe el reconocimiento, indica que el dispositivo está listo para comunicarse. El script incluye mecanismos de manejo de errores para gestionar problemas con la conexión serial y permite una terminación controlada mediante una interrupción de teclado.

Funciones

  • La función principal establece la comunicación serial sobre una conexión USB o TTL especificada usando el puerto y baud rate proporcionados.
  • Entra en un bucle continuo para enviar un mensaje de solicitud (@HLWD_) al robot Burro IPA, iniciando un handshake para establecer la comunicación.
  • Al recibir una respuesta del robot, procesa los datos entrantes para confirmar si se recibió un reconocimiento (#ACK_).
  • Si el reconocimiento es exitoso, la función se prepara para enviar una solicitud de verificación de estado (?STTN_) al robot, consultando su estado actual de estación.
  • Lee la respuesta del robot, interpreta los datos y verifica si el robot está detenido en una estación.
  • Si se confirma que el robot está detenido, la función envía un mensaje específico al robot y activa un LED para indicar el estado visualmente.

Ejemplo

example_client_handshake.py
import serial
import logging
import argparse
import sys
import time


def setup_logging():
    """ Configura el formato de logging. """
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')


def parse_arguments():
    """ Analiza los argumentos de la línea de comandos. """
    parser = argparse.ArgumentParser(description="Envía una solicitud de comunicación por serial al Burro IPA.",
                                     epilog="Ejemplo: python3 example_client_handshake.py --port /dev/ttyUSB1")
    parser.add_argument("--port", default="/dev/ttyUSB0", help="Puerto serial al que conectarse.")
    parser.add_argument("--baud", type=int, default=115200, help="Baud rate para la conexión serial.")
    parser.add_argument("--timeout", type=float, default=0.5, help="Timeout de lectura para la conexión serial.")
    return parser.parse_args()


def main():
    # Configuración de utilidades para el script
    setup_logging()
    args = parse_arguments()
    logging.info(f"Dispositivo serial abierto: port={args.port}, baud={args.baud}, timeout={args.timeout}")

    while True:
        try:
            # Inicializa la conexión serial
            device = serial.Serial(args.port, args.baud, timeout=args.timeout)
        except serial.SerialException as e:
            logging.error(f"No se pudo abrir el puerto serial: {e}")

        try:
            # Envía el saludo `@HLWD_` para que el robot sepa que estás listo para comunicarte. Espera recibir un
            # `ACK_` si la comunicación se ha establecido correctamente.
            handshake = "@HLWD_"
            ack = "#ACK_"

            # Envía el saludo
            device.write((handshake + '\r').encode())
            tic = time.time()

            # Lee la respuesta
            incoming_data = device.read_until(b'\r').decode().strip()
            toc = time.time()

            logging.info(f"Recibido: {incoming_data} ({1000*(toc-tic):.3f}ms)")

            # Si la respuesta es un ACK entonces has hecho contacto. Puedes salir de este ejemplo si es un archivo separado
            # o continuar si quieres que sea el programa principal.
            if incoming_data == ack:
                logging.info("ACK recibido.")
                sys.exit(0)

            # Espera un poco antes de volver a intentar para evitar saturar la conexión.
            time.sleep(0.5)
        except KeyboardInterrupt:
            # Salir si se recibe `CTRL^C`.
            logging.info("Saliendo...")
            sys.exit(0)
        except Exception as e:
            # Registra cualquier error pero no detiene el script.
            logging.error(f"Error: {e}")


if __name__ == '__main__':
    main()