You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.8 KiB
C
93 lines
2.8 KiB
C
#include <unistd.h> // Para enviar comandos y recibir datos desde dispositivos I2C
|
|
#include <sys/ioctl.h> // setting up and controlling the I2C device settings
|
|
#include <linux/i2c-dev.h> // Definiciones para el sistema de llamadas y estructuras especificaspara I2C
|
|
#include <stdio.h> // perror
|
|
|
|
#include "sen0466_co.h" // Archivo header
|
|
|
|
int changeQA_CO(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, SEN0466_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;
|
|
} /*else {
|
|
printf("Comando enviado exitosamente. Sensor en modo Q&A.\n");
|
|
}*/
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// --- 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
|
|
}
|
|
|
|
int getCO(int fd, int *co_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, SEN0466_I2C_ADDR) < 0) {
|
|
perror("No se pudo conectar al sensor de CO");
|
|
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 = SEN0466_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
|
|
*co_valor = (buf[2] * 256) + buf[3];
|
|
|
|
return 0;
|
|
}
|