En este ejemplo se muestra como leer un sensor I2C conectado a ZYBO (de Digilent) desde Linux. El sensor es en este caso el sensor de luminosidad TSL2561de Adrafruit.
Sensor de luminosidad I2C TSL2561 |
Los detalles de uso de este sensor se pueden leer en el datasheet, aunque resumiendo se han de seguir los siguientes pasos:
- Mandar comando de encender 0x80, 0x03
- Configurar el tiempo de integración a 13.7ms 0x81, 0x00
- Mandar los comandos de lectura para ambos canales. ch0 (0x8c,0x8d) y ch1(0x8d,0x8f)
- Convertir a Lux usando la función dada en el datasheet.
Una vez conectada la ZYBO por el terminal (ver tutorial (III)) únicamente tendremos que cambiar el software. Para esto abrimos un nuevo archivo de texto e introducimos el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | #include <linux/i2c-dev.h> #include <linux/i2c.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include "lux-calculation.c" /* TODO addapt the i2c slave address to your sensor */ #define I2C_ADDRESS 0x39 /* TODO driver path to the i2c */ static char *i2c = "/dev/i2c-0"; static int i2c_handler; int i2c_write(int file, char *buf, size_t len) { if (write(file, buf, len) < 0) { /* ERROR HANDLING: i2c transaction failed */ printf("Failed to write from the i2c bus: %s\n", strerror(errno)); return errno; } else { return 0; } } int i2c_read(int file, char *buf, size_t len) { if (read(file,buf,len) < 0) { /* ERROR HANDLING: i2c transaction failed */ printf("Failed to read from the i2c bus: %s\n", strerror(errno)); return errno; } else { return 0; } } double ReadTCusingADC(void) { unsigned char NullCmd = 0x00; double ADCoutput = 0; char buffer[7] = ""; char read_channel[] = {0x8c, 0x8d}; i2c_write(i2c_handler, read_channel, 2); memset(buffer, sizeof(buffer), '\0'); usleep(2000); if (i2c_read(i2c_handler, buffer, 3) < 0) { /* ERROR HANDLING: you can check errno to see what went wrong */ perror("Failed to read"); exit(1); } int Ch0 = buffer[0] + 0xFF*buffer[1]; //printf ("channel0 %d ", Ch0); //For debugging i2c_write(i2c_handler, power_sequence, 2); char read_channel2[] = {0x8e, 0x8f}; i2c_write(i2c_handler, read_channel2, 2); memset(buffer, sizeof(buffer), '\0'); usleep(2000); if (i2c_read(i2c_handler, buffer, 3) < 0) { /* ERROR HANDLING: you can check errno to see what went wrong */ perror("Failed to read"); exit(1); } int Ch1 = buffer[0] + 0xFF*buffer[1]; //printf("channel0 %d \n",Ch1); //For debugging ADCoutput = CalculateLux(0, 0,Ch0, Ch1, 0 ); return ADCoutput; } int sensor_powerOn(){ char power_sequence[] = {0x80, 0x03}; i2c_write(i2c_handler, power_sequence, 2); char time_sequence[] = {0x81, 0x00}; i2c_write(i2c_handler, time_sequence, 2); return 0; } int main (void) { /* open device on /dev/i2c-x */ i2c_handler = open(i2c, O_RDWR); if ((i2c_handler = open(i2c, O_RDWR)) < 0) { /* ERROR HANDLING: you can check errno to see what went wrong */ perror("Failed to open the i2c bus"); exit(1); } if (ioctl(i2c_handler, I2C_SLAVE, I2C_ADDRESS) < 0) { printf("Failed to acquire bus access and/or talk to slave.\n"); /* ERROR HANDLING; you can check errno to see what went wrong */ exit(1); } sensor_powerOn(); printf("sensor_init\n"); /* TODO: addapt the ReadTCusingADC function to the Lux sensor */ int i; double result; for (i = 0; i < 150; i++) { result = ReadTCusingADC(); printf("%f\n", result); sleep(1); } /* close connection and return */ close(i2c_handler); return 0; } |
No hay comentarios:
Publicar un comentario