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.
 
 
 
 
guillermoponce 85a6d9c144 File up of read for sensors 5 days ago
7-sensors Adding the folder with the drivers for the sensors HTU21D and BD1750. 5 days ago
8-react-ui-sensors Upload the folders of the code for get data from the sensors and the frontend and backend of the web page 7 days ago
ReadMe.md File up of read for sensors 5 days ago

ReadMe.md

Librerías Sensores HTU21D-BH1750 y Código de ejecución main.c

Se desarrollan las librerías referentes al sensor de húmedad y temperatura HTU21D y sensor de luminocidad BH1750. Los presentes sensores utilizan el protocolo de comunicación I2c, por lo que la conexión se realizará en paralelo. Lo primero a realizar es la creación de los headers file, en este caso se crean dos archivos por separado esto con el objetivo de volverlo portable. Dentro de estos archivos declaramos la dirección de cada sensor, así como los comandos que se utilizarán para el desarrollo del proyecto. Tambien se declaran las funciones a utilizar dentro de los archivos ".c".

El contenido del header file referente al sensor HTU21D es el siguiente:

#ifndef HTU21D_H     //Definicion del archivo para header
#define HTU21D_H

#define HTU21D_ADDR 0x40	//Definition of sensor address direction 

//Commands for reading of temperature or humidity 
#define HTU21D_TEMP	    0xE3
#define HTU21D_HUM	    0xE5
#define HTU21D_RESET	0xFE

//Function declarations
// Temperature:
int get_temp(int fd, double *temp);
// Humidity:
int get_hum(int fd, double *hum);
// Reset:
int reset_sensor(int fd);

#endif

Las funciones declaradas en este archivo es para captura de temperatura y húmedad, además se agrega un función extra para el reseteo del sensor.

El contenido del header fil referente al sensor BH1750 es el siguiente:

#ifndef BH1750_h     //Definicion del archivo para header
#define BH1750_h

#define BH1750_ADDR 0x23	//Definition of sensor address direction 

//Commands for reading of temperature or humidity 
#define BH1750_PON	    0x01 //Command for power on 
#define BH1750_OTHR	    0x20 //Command for One Time H-Resolution
#define BH1750_RESET	0xFE //Command for Reset the sensor

//Function declarations
// Get the brightness:
int get_lux(int fd, double *lux);
// Reset:
int reset_BH1750(int fd);

#endif

En este caso el sensor BH1750 solo mide una variable que es la luminocidad, por lo que se declarán solo dos funciones, una te entrega el valor de luminocidad y la función adicional sirve para el reseteo del sensor.

Archivo HTU21D.c

Dentro de este archivo se desarrolla el contenido de las funciones declaradas dentro del header file. Lo primero que se realiza en este codigo es la declaración de las funciones necesarias para el correcto funcionamiento del archivo. Las librerías son las siguientes:

#include <stdlib.h>
#include <stdio.h> //to print error 

#include <unistd.h> //header file for standard I2c send and receive commands
#include <sys/ioctl.h> //setup I2c devices
#include <linux/i2c-dev.h> //definitions and structures 
#include <i2c/smbus.h> //smbus commands

#include "HTU21D_H.h"

La siguiente funcion es referente a la obtención del valor de temperatura, esta función te pide como primer argumento el descriptor del archivo del bus I2c y lo siguiente es el puntero a función donde se almacenará el valor de la temperatura. En este caso la forma en que trabaja el sensor es necesario realizar un reset del mismo para que realice la lectura de manera correcta, por lo que se manda a llamar la función reset_sensor.

Una vez reseteado de manera correcta el sensor extrae el dato del bus de I2c y se asigna en un arreglo donde posteriormente se analiza el valor y con este se sabe si se logro establecer la comunicación y que la lectura del dato se realizó de manera correcta. Posteriormente se realiza el calculo del dato y se despliega.

El codigo es el siguiente:

// Temperature:
int get_temp(int fd, double *temp){
	reset_sensor(fd);
	char buffer[3];
	__s32 res = i2c_smbus_read_i2c_block_data(fd, HTU21D_TEMP, sizeof(buffer), buffer);
	if (res < 0){
		perror("Error -1: Failed to read from the device");
		return -1;
	}
	*temp = -46.85+175.72*(buffer[0]*256+buffer[1])/65536.0;
	return 0;
}

La siguiente función sirver para obtener el valor de la húmedad, en este caso como argumento pide los mismos valores que la función para obener la temperatura, sin embargo, estos cambian ya que el comando que se envía es diferente al de la temperatura, además de que el calculo es diferente del valor es diferente. El siguiente codigo es referentea esta funcion:

int get_hum(int fd, double *hum){
	reset_sensor(fd);
	char buffer[3];
	__s32 res = i2c_smbus_read_i2c_block_data(fd, HTU21D_HUM, sizeof(buffer), buffer);
	if ( res < 0 ){
		perror("Error -3: Failed to read humidity ");
		return -1;
	}
	*hum = -6+125*(buffer[0]*256+buffer[1])/65536.0;
	return 0;
}

En la siguiente fución se realiza el reset del sensor en el cual solo pide como argumento la dirección del archivo bus para el I2c. Una vez obtenido se envía el comando para el reseteo del sensor. El codigo es el siguiente:

// Reset Sensor 
int reset_sensor(int fd){
	if(0 > ioctl(fd, I2C_SLAVE, HTU21D_ADDR)){
		perror("Error -2: Failed to reset");
		return -2;
	}
	i2c_smbus_write_byte(fd, HTU21D_RESET);
	return 0;
}

Archivo BH1750

Se agregan las mismas librerías que se utilizaron en el sensor HTU21D sin embargo solo se agrega el "header file" correspondiente a este sensor ya que de no ser asi no se podría hacer uso de las funciones escritas en ese archivo.

#include <stdlib.h>
#include <stdio.h> //to print error
#include <fcntl.h> 

#include <unistd.h> //header file for standard I2c send and receive commands
#include <sys/ioctl.h> //setup I2c devices
#include <linux/i2c-dev.h> //definitions and structures 
#include <i2c/smbus.h> //smbus commands

#include "BH1750_H.h"

En este caso el funcionamiento del sensor es diferente al del HTU21D ya que este no necesita un reseteo previo para la lectura del sensor. En este caso solo se hará uso de una función "get_lux" los argumentos que pide esta función es la direccion del bus del I2c y el puntero a la variable en la cual se regresara el valor estimado. Lo primero que se realiza dentro de esta función es establecer la comunicación con la dirección correspondiente del sensor e indicamos que el sensor será el esclavo.

Lo siguiente es enviar el comando para configurar el tipo de lectura que se desea, en este caso se opto por una sola lectura de alta resolución, posterior a esto hay que esperar un cierto tiempo en el que el sensor se configura. Una vez ya configurado podemos realizar la lectura y de esta manera calcular el valor correspondiente a la luminocidad. El codigo es el siguiente:

int get_lux(int fd, double *lux){
    
    // Establish the direction of the slave
    if (ioctl(fd, I2C_SLAVE, BH1750_ADDR) < 0){
        perror("Error to stablish the direction of I2C");
        //close(fd);
        return 1;
    }

    // Send the command for the mesaurment 
    if(i2c_smbus_write_byte(fd, BH1750_OTHR) < 0){
        perror("Failed to send the command for mesaurment ");
        //close(fd);
        return 1;
    }

    usleep(180000);

	char buffer[2];
	__s32 res = i2c_smbus_read_i2c_block_data(fd, 0x00, sizeof(buffer), buffer);
	if (res != 2){
		perror("Error -1: Failed to read from the device");
        return 1;
	}
	*lux    = ((buffer[0] << 8) | buffer[1]) / 1.2;
	return 0;
}

"main.c"

Lo primero que declaramos dentro de este archivo son las librerías correspondiente para la escritura del codigo, tambien agregamos los header files de los sensores, es importante recordar que van dentro de comillas dobles ya que esto indica que los archivos se encuentran dentro de la misma carpeta donde esta el main.c. Tambien definimos los puertos donde se encuentra el bus de I2c y tambien declaramos la dirección del archivo del bus de I2c. Además de estas declaraciones se agregan dos mas correspondientes a los archivos .json correspondientes a cada sensor, ya que estos serán modificados cada que se haga una lectura del sensor.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//additional libraries:
#include <fcntl.h>

#include "HTU21D_H.h"
#include "BH1750_H.h"
#include <errno.h>

#define I2C_PATH "/dev/i2c-%d"
#define I2C_PORT_2 2
#define I2C_PORT_1 1

#define HTU21D_json_path "/home/debian/CODIGOS/8-react-ui-sensors/ui/HTU21D.json"
#define BH1750_json_path "/home/debian/CODIGOS/8-react-ui-sensors/ui/BH1750.json"
int sensor;

Una vez hecho esto, la primera acción a realizar dentro del bucle infinito es la concatenación del path de la direccion del bus de I2c en el cual se va a establecer la comunicación, una vez hecho esto utilizamos este path para abrirlo en modo lectura y escritura. Una vez que lo habramos verificamos si se abrio de manera correcta en caso que se habra de manera erronea retornará un error.

while (1) {
		//if (sensor == 1){
		char filePath[99];
		snprintf(filePath, sizeof(filePath), I2C_PATH, I2C_PORT_2);
    	   	int fd = open(filePath, O_RDWR);
		//to do.... complete the structure for the cases when we cant open the file
		if(fd < 0){
			fprintf(stderr, "Error: Unable to access HTU21D sensor: %s \n ", strerror(errno));
			exit(-1);
		}

La primera lectura que se realizará es la del sensor HTU21D referente a la temperatura y húmedad. Para esto hacemos uso de las funciones get_temp() y get_hum() y se hace una validación en la cual si el valor de retorno es menor a 0 entonces existe un error extrayendo la información y rompe el ciclo.

double Temperature = 10;
		double Humidity    =  0;
		if((get_temp(fd, &Temperature)<0) || (get_hum(fd, &Humidity)<0)){
				fprintf(stderr, "Error -404: Cant do the messaurment \n ");
				exit(-1);
		}

Una vez que se haya capturado los valores de los sensores se procede a realizar la escritura en los archivos .json correspondientes en este caso el del sensor HTU21D. Una vez que se haya escrito los valores se cierra el archivo y se imprimen los valores en la consola.

FILE *archivo = fopen(HTU21D_json_path, "w");
		if (archivo == NULL){
			perror("The file can not open ");
			return -1;
		} else{
			fprintf(archivo, "{\"Temperature\" : %5.2f , \"Humidity\" : %5.2f}", Temperature, Humidity);
		}
		fclose(archivo);
		printf ("{\"Temperature\" : %5.2f , \"Humidity\" : %5.2f}", Temperature, Humidity);

Una vez terminado la lectura del sensor HTU21D se procede a realizar la lectura del sensor BH1750, el proceso es el mismo. Como se cerro el bus de comunicación lo volvemos a abrir y verificamos que se haya completado la acción.

fd = open(filePath, O_RDWR);
		//to do.... complete the structure for the cases when we cant open the file
		if(fd < 0){
			fprintf(stderr, "Error: Unable to access HTU21D sensor: %s \n ", strerror(errno));
			exit(-1);
		}

		double Bright = 0;
		if((get_lux(fd, &Bright) < 0)){
				fprintf(stderr, "Error -404: Cant do the messaurment \n ");
				exit(-1);
		}

Posteriormente a esto realizamos a lectura del sensor y se verfica que el valor no retorne un error. En caso de no existir algun error con el valor se almacena y se escribe en el archivo ".json" y al final se imprime el valor en la consola.

FILE *archivo_1 = fopen(BH1750_json_path, "w");
		if (archivo_1 == NULL){
			perror("The file can not open ");
			return -1;
		} else{
			fprintf(archivo_1, "{\"Brightness\" : %5.2f }", Bright);
		}
		fclose(archivo_1);
		printf ("{\"Brightness\" : %5.2f }\n", Bright);
		//}
		usleep(2000000);

Compilación

Una vez que el archivo main.c se haya completado lo siguiente es realizar la compilación para realizar la prueba correspondiente de funcionamiento. Para la compilación se ejecuta el siguiente comando.

gcc main.c HTU21D.c BH1750_c.c -o executable -li2c 

Donde main.c es el documento a compilar, HTU21D.c, BH1750 se agregan estos archivo ya que son necesarios para la poder realizar la compilación y el nombre del archivo que sera la aplicacion y tambien agregamos la libreria li2c para que jale los archivos correspondientes a todo el