#include #include #include #include #include #include // --- FUNCIÓN DE INICIALIZACIÓN --- // Devuelve el descriptor de archivo (fd) o -1 si falla. int init_uart(const char *puerto, speed_t baudrate) { // Abrir el puerto: Lectura/Escritura, no ser la terminal controladora, no bloquear. int fd = open(puerto, O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror("Error al abrir el puerto UART"); return -1; } struct termios tty; if (tcgetattr(fd, &tty) != 0) { perror("Error al obtener los atributos del puerto"); close(fd); return -1; } // Configurar Baudios cfsetispeed(&tty, baudrate); cfsetospeed(&tty, baudrate); // MODO CRUDO: 8N1 (8 bits, Sin paridad, 1 bit de parada) tty.c_cflag &= ~PARENB; // Sin paridad tty.c_cflag &= ~CSTOPB; // 1 bit de parada tty.c_cflag &= ~CSIZE; // Limpiar máscara de tamaño tty.c_cflag |= CS8; // 8 bits de datos // Desactivar control de flujo por hardware y señales de módem tty.c_cflag &= ~CRTSCTS; tty.c_cflag |= CREAD | CLOCAL; // Desactivar procesamiento de software (Modo crudo absoluto) tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); tty.c_oflag &= ~OPOST; tty.c_iflag &= ~(IXON | IXOFF | IXANY); tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // Configuración de tiempos de espera (Timeout) tty.c_cc[VMIN] = 0; // No exigir un mínimo de bytes tty.c_cc[VTIME] = 20; // Esperar máximo 2 segundos (20 decimas) // Limpiar basura del búfer y aplicar la configuración tcflush(fd, TCIFLUSH); if (tcsetattr(fd, TCSANOW, &tty) != 0) { perror("Error al aplicar la configuración UART"); close(fd); return -1; } // Quitar el modo "No Bloqueante" para que VTIME y VMIN funcionen correctamente fcntl(fd, F_SETFL, 0); return fd; } // --- FUNCIÓN PARA ENVIAR --- void send_uart(int fd, unsigned char *trama, int longitud) { tcflush(fd, TCIOFLUSH); // Limpiar tubería antes de hablar int escritos = write(fd, trama, longitud); if (escritos < 0) { perror("Error al escribir en el puerto"); } } // --- FUNCIÓN PARA RECIBIR --- int receive_uart(int fd, unsigned char *buffer, int longitud_esperada) { int bytes_leidos = read(fd, buffer, longitud_esperada); return bytes_leidos; } // --- FUNCION PRINCIPAL --- int main() { int uart_fd = init_uart("/dev/serial0", B9600); if (uart_fd == -1) return 1; unsigned char comando[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; unsigned char respuesta[9]; while(1) { send_uart(uart_fd, comando, sizeof(comando)); usleep(100000); // 100ms para que el sensor responda int bytes = receive_uart(uart_fd, respuesta, 9); if (bytes == 9) { // 1. Calcular el valor real int co2_ppm = (respuesta[2] * 256) + respuesta[3]; // 2. Imprimir en consola (para tu propio monitoreo) printf("Respuesta OK: CO2 = %d ppm\n", co2_ppm); } else { printf("Error: Bytes recibidos = %d\n", bytes); } sleep(10); } close(uart_fd); return 0; }