#include // Para enviar comandos y recibir datos desde dispositivos I2C #include // setting up and controlling the I2C device settings #include // Definiciones para el sistema de llamadas y estructuras especificaspara I2C #include // perror #include "sen0472_o3.h" // Archivo header // --- MÉTODO PARA CAMBIAR A MODO Q&A AL SENSOR --- int changeQA_O3(int fd) { // El comando necesita 9 bytes // 0xFF: Byte de inicio // 0x01: Dirección // 0x78: Comando para cambiar tipo // 0x04: El tipo Q&A // 0x00...: Rellenos // 0x83: El checksum (suma de control) unsigned char cmd[9] = {0xFF, 0x01, 0x78, 0x04, 0x00, 0x00, 0x00, 0x00, 0x83}; // Conecta el driver al sensor en el bus fd a traves de su dirección y estableciendolo como dispositivo esclavo if (ioctl(fd, I2C_SLAVE, SEN0472_I2C_ADDR) < 0) { perror("No se pudo conectar al sensor"); return -1; } // Envia los 9 bytes if (write(fd, cmd, 9) != 9) { perror("Error al escribir el comando de cambio de modo"); return -1; // Falló } return 0; // Éxito } // --- MÉTODO PARA VERIFICAR EL CHECKSUM (Si el paquete recibido está libre de errores) --- static int verificar_checksum(unsigned char *buf) { unsigned char tempq = 0; int i; // Suma los bytes del 1 al 7 for (i = 1; i < 8; i++) { tempq += buf[i]; } // Calcula el complemento a 2 (negación + 1) tempq = (~tempq) + 1; // Compara el resultado con el octavo byte (el checksum recibido) if (tempq == buf[8]) { return 1; // El paquete es válido } return 0; // El paquete está corrompido } // --- MÉTODO PARA OBTENER EL O3 (OZONO) --- double getO3(int fd, double *o3_valor){ // Conecta el driver al sensor en el bus fd a traves de su dirección y estableciendolo como dispositivo esclavo if (ioctl(fd, I2C_SLAVE, SEN0472_I2C_ADDR) < 0) { perror("No se pudo conectar al sensor de O3"); return -1; } // Enviar el comando de lectura para que el sensor prepare el dato y lo deje listo en el buffer de salida unsigned char cmd = SEN0472_READ; // 0x86 if (write(fd, &cmd, 1) != 1) { perror("Error al enviar comando de lectura"); return -1; } // Espera a que el sensor prepare el dato usleep(100000); // 100ms // Leer el bloque de datos y lo almacena en el arreglo buf unsigned char buf[9]; int res = read(fd, buf, 9); if (res < 0) { perror("Error de lectura I2C"); return -1; } // Verifica el checksum if (!verificar_checksum(buf)) { printf("Error: Checksum inválido. Datos corruptos descartados.\n"); return -1; } // Convierte el valor a valor decimal int valor_crudo = (buf[2] * 256) + buf[3]; *o3_valor = valor_crudo * 0.1; return 0; }