Se trata de una librería C, SHTxx_RyP.c, para el control del sensor SHT11 con un PIC. Un ejemplo de su aplicación se puede ver en el artículo: "Sensor de temperatura y humedad SHT11 con PIC". Es válida para toda la gama de sensores SHT10, SHT11, SHT15, SHT71 y SHT75.
Cuando se emplee la versión v3 o v4 del sensor SHT71 o SHT75, la librería alternativa es SHT7xv3_RyP.c que contiene los coeficientes de cálculo adecuados correspondientes a dichas versiones.
Cuando se emplee la versión v3 o v4 del sensor SHT71 o SHT75, la librería alternativa es SHT7xv3_RyP.c que contiene los coeficientes de cálculo adecuados correspondientes a dichas versiones.
Dentro de la librería C encontraremos el código estructurado en diferentes secuencias y funciones.
La SECUENCIA DE INICIO DE TRANSMISIÓN consistente en:
La SECUENCIA DE INICIO DE TRANSMISIÓN consistente en:
-
Poner a “0”
la línea DATA mientras SCK está a “1” .
-
Poner a “0”
SCK mientras DATA continua a “0” .
-
Volver a poner a “1” SCK sin cambiar el estado de
DATA
-
Finalmente pasar DATA a “1” mientras SCK está a “1”
/**
secuencia de inicio de transmisión **/
void
SHTxx_InicioTrans (void) {
//DATA a "0" con SCK a
"1"
output_float(sht_data_pin);
//línea DATA a "1"
output_low(sht_sck_pin);
//línea SCK a "0"
delay_us(1);
output_high(sht_sck_pin);
//línea SCK a "1"
delay_us(1);
output_low(sht_data_pin);
//línea DATA a "0"
delay_us(1);
//SCK a "0" sin cambiar DATA "0"
output_low(sht_sck_pin);
//línea SCK a "0"
delay_us(2);
//SCK a "1" sin cambiar DATA "0"
output_high(sht_sck_pin);
//línea SCK a "1"
delay_us(1);
//DATA a "1" con SCK a "1"
output_float(sht_data_pin);
//línea DATA a "1"
delay_us(1);
output_low(sht_sck_pin);
//línea SCK a "0"
}
La SECUENCIA DE RESET resetea solo la
interface, los registros de estado mantienen sus valores. Consiste en:
-
Con la línea DATA puesta a “1” ,
c onmutar 9 o más veces la línea SCK entre “0” y “1” .
-
Debe seguirle una
secuencia de Inicio.
/** secuencia de reset **/
void SHTxx_Reset (void) {
int i;
//inicio
de secuencia con SCK a “0”
y DATA a “1”
output_float(sht_data_pin); //línea DATA a
“1”
output_low(sht_sck_pin); //línea SCK a
“0”
delay_us(2);
//conmuta
SCK 9 veces con DATA a “1”
for(i=0; i<9;
i++) {
output_high(sht_sck_pin);
delay_us(2);
output_low(sht_sck_pin);
delay_us(2);
}
/** secuencia de inicio de transmisión **/
SHTxx_InicioTrans ();
}
Con la SECUENCIA DE ENVIO DE COMANDO se
le indica al sensor la actuación que debe realizar. Son comandos de 5 bits pero
se debe enviar un byte completo (8 bits), 3 bits de dirección A0 a A2 y los 5
bits del comando C0 a C4. Los bits de dirección solo permiten valor “0” .
COMANDO
|
Código
en binario
|
Código
hex.
|
Reservado
|
0000x
|
--
|
Medida de Temperatura
|
00011
|
0x03
|
Medida de Humedad Relativa
|
00101
|
0x05
|
Lectura del Registro de Estado
|
00111
|
0x07
|
Escritura en registro de Estado
|
00110
|
0x06
|
Reservado
|
0101x-1110x
|
--
|
Reset del Sofá, resetea la interface, limpia el
registro a los valores por defecto. SE debe esperar un mínimo de 11msg antes
del siguiente comando.
|
11110
|
0x1D
|
Consiste en:
-
Tras una secuencia completa de Inicio de
transmisión.
-
Envío del comando bit a bit
-
Lectura del ack
Línea
fina indica su control por el PIC, línea gruesa control por el sensor.
/** secuencia de envío de comando **/
int1 SHTxx_Comando (int8 sht_comando) {
int8 bit;
int8 mascara = 0x80;
int1 ack;
delay_us(4);
//Salida del
comando bit a bit
for(bit=8; bit>=1; bit--) {
output_low(sht_sck_pin);
//línea SCK a "0"
//Línea DATA a "1" si MSB es
"1"
if((sht_comando & mascara) > 0)
output_float(sht_data_pin);
//Línea DATA a "0" si MSB es
"0"
else output_low(sht_data_pin);
delay_us(1);
output_high(sht_sck_pin); //línea SCK a
"1"
delay_us(1);
mascara = mascara >> 1; //siguiente
bit pasa a ser MSB
}
/** lectura del
ack **/
output_low(sht_sck_pin);
//línea SCK a "0"
delay_us(1);
ack = input(sht_data_pin);
//lectura del
ack
output_high(sht_sck_pin);
//línea SCK a "1"
delay_us(1);
output_low(sht_sck_pin);
//línea SCK a "0"
return(ack);
}
La SECUENCIA DE ESPERA DE MEDICIÓN TERMINADA espera, una vez enviado el comando de medida
de la temperatura o humedad, a que el sensor avise de la finalización del
proceso de medida pasando la línea DATA de “1” a “0” . Puede durar un máximo de 20/80/320msg. para una medida de
8/12/14 bits.
Línea
fina indica su control por el PIC, línea gruesa control por el sensor.
/**
Secuencia de espera de medida terminada **/
void SHTxx_Espera (void) {
int16 sht_delay;
output_float(sht_data_pin); //línea DATA a
"1"
output_low(sht_sck_pin); //línea SCK a
"0"
delay_us(1);
//Espera a que linea DATA pase a
"0" máximo 300msg.
for(sht_delay=0; sht_delay<30000;
sht_delay++) {
//si linea
DATA pasa a "0" => fin de la medición
if (!input(sht_data_pin)) break;
delay_us(10);
}
}
Con la SECUENCIA DE LECTURA DEL DATO DE UNA
MEDIDA, y tras que el SHTxx haya indicado el fin de una medición, el
microcontrolador reinicia el bus SCK para obtener el dato de la medida. El dato de la medida es almacenado
por lo que el procesador puede hacer otras tareas hasta su lectura.
La secuencia consiste en:
-
Lectura del byte alto del dato de la medida. Si es
un dato de 8 bits este byte se ignora.
-
El microcontrolador pone la linea DATA a “0” como reconocimiento ack.
-
Lectura del byte bajo del dato de la medida.
-
El microcontrolador pone la linea DATA a “0” como reconocimiento ack si va
a leer el byte CRC checksum o a “1”
para terminar sin lectura de CRC checksum.
-
Lectura del byte del CRC checksum (opcional).
-
El microcontrolador pone la línea DATA a “0” como reconocimiento ack.
Línea
fina indica su control por el PIC, línea gruesa control por el sensor.
/**
Secuencia de lectura del dato de la medida **/
int16 SHTxx_Lectura (void) {
int8 bit;
int16 sht_dato = 0;
const int16 mascara0 = 0x0000;
const int16 mascara1 = 0x0001;
//guarda byte alto del dato leído en byte
alto de sht_dato bit a bit
for(bit=8;
bit>=1; bit--) {
sht_dato =
sht_dato << 1; //siguiente bit pasa a ser MSB
output_high(sht_sck_pin); //línea SCK a "1"
delay_us(1);
//si línea DATA es "1"
pone bit correspondiente en
sht_dato a "1"
if (input(sht_data_pin)) sht_dato |= mascara1;
//si línea
DATA es "0" pone bit correspondiente en sht_dato a "0"
else sht_dato |= mascara0;
output_low(sht_sck_pin);
//línea SCK a "0"
delay_us(1);
}
//Envío ack poniendo linea DATA a "0"
output_low(sht_data_pin);
//línea DATA a "0"
delay_us(1);
output_high(sht_sck_pin);
//línea SCK a "1"
delay_us(2);
output_low(sht_sck_pin);
//línea SCK a "0"
delay_us(1);
output_float(sht_data_pin);
//línea DATA a "1"
//guarda byte bajo del dato leído en byte
bajo de sht_dato bit a bit
for(bit=8;
bit>=1; bit--) {
sht_dato =
sht_dato << 1; //siguiente
bit pasa a ser MSB
output_high(sht_sck_pin); //línea SCK a "1"
delay_us(1);
//si línea DATA es "1" pone bit
correspondiente en sht_dato a "1"
if (input(sht_data_pin)) sht_dato |= mascara1; //shift in data bit
//si línea
DATA es "0" pone bit correspondiente en sht_dato a "0"
else sht_dato |= mascara0;
output_low(sht_sck_pin);
//línea SCK a "0"
delay_us(1);
}
//Envío ack poniendo linea DATA a "1" => no lectura CRC
checksum
output_float(sht_data_pin); //línea DATA a "1"
delay_us(1);
output_high(sht_sck_pin);
//línea SCK a "1"
delay_us(2);
output_low(sht_sck_pin);
//línea SCK a "0"
return(sht_dato);
}
La FUNCIÓN DE MEDIDA DE LA VARIABLE
ejecuta todas las secuencias necesarias y en el orden correcto para obtener el
valor digital de la humedad o temperatura leídas por el sensor. El proceso
será:
-
Secuencia de inicio de transmisión
-
Secuencia de envío de comando
-
Secuencia de espera hasta medición completada
-
Secuencia de lectura del dato de la medición
//** Función
de medida de variable **/
int16 SHTxx_Medida (sht_comando) {
int1 ack;
int16 sht_dato;
/** secuencia de inicio de transmission **/
SHTxx_InicioTrans ();
//envío del commando y lectura del ack
ack = SHTxx_Comando (sht_comando);
if(ack == 1) return; //si hay error sale de la medida
//espera a que sht termine el cálculo de la
medida
SHTxx_Espera ();
//finalizada la medida, obtiene el valor
digital
sht_dato = SHTxx_Lectura ();
return(sht_dato);
}
La FUNCIÓN DEL CÁLCULO DE LAS VARIABLES obtiene
los valores reales analógicos partiendo de los datos digitales leídos por el
sensor. Para el cálculo se emplean unos coeficientes proporcionados por el
fabricante y que dependen de la resolución (nº de bits) de las medidas
obtenidas.
SHTxx_calculo (int16 sht_DatoTemperatura,
float &sht_temperatura, int16 sht_DatoHumedad, float &sht_humedad) {
float sht_HumedadLineal;
//Cálculo de temperatura en función de la
medida digital del sensor
sht_temperatura = ((float)
sht_DatoTemperatura * d2) + d1;
//Cálculo valor lineal humedad
sht_HumedadLineal = (sht_DatoHumedad * c2) +
(sht_DatoHumedad * sht_DatoHumedad * c3) + c1;
//Cálculo de la humedad compensada por
temperatura
sht_humedad = ((sht_temperatura - 25.0) *
(t1 + (t2 * sht_DatoHumedad))) + sht_HumedadLineal;
}
La FUNCIÓN DE
LECTURA DEL REGISTRO DE ESTADO obtiene el valor de configuración de dicho
registro. Consistirá en:
-
Secuencia de inicio de transmisión
-
Secuencia de envío de comando
-
Secuencia de lectura del registro de estado y
cheksum
SHTxx_LECTURA_REGISTRO_ESTADO () {
int16 sht_dato; //Byte alto = registro estado, byte bajo = ckecksum
int8 sht_checksum; //Guardará el
valor del checksum
/** secuencia de inicio de transmission **/
SHTxx_InicioTrans ();
/** Secuencia de envío de comando **/
SHTxx_Comando
(SHTxx_REG_ESTADO_R); //Comando de lectura registro de estado
/** Lectura del registro de estado y checksum **/
sht_dato = SHTxx_Lectura ();
sht_registro = make8(sht_dato,1);
//Byte alto = valor registro de estado
sht_checksum = make8(sht_dato,0); //Byte
bajo = valor del
checksum
return
(sht_registro); //Devuelve
valor del registro de estado
}
Con la FUNCIÓN
DE ESCRITURA DEL REGISTRO DE ESTADO se carga el valor de configuración del
sensor. Consistirá en:
-
Secuencia de inicio de transmisión
-
Secuencia de envío de comando
-
Secuencia de escritura del valor del registro de
estado
SHTxx_ESCRITURA_REGISTRO_ESTADO
(sht_registro) {
/** secuencia de inicio de transmisión **/
SHTxx_InicioTrans ();
/** Secuencia de envío de comando **/
SHTxx_Comando (SHTxx_REG_ESTADO_W); //Comando de esritura registro de estado
SHTxx_Comando (sht_registro); //Argumento
a cargar en el registro de estado
}
Con la FUNCIÓN DE RESET DE SOFT se envía el comando que inicializa el
valor del registro a sus valores por defecto (0x00).
void SHTxx_Reset_Soft (void) {
SHTxx_Reset(); //Reset comunicación
SHTxx_Comando(SHTxx_SOFT_RESET); //Comando reset=>Reg.Estado ,valores defecto
delay_ms(15); //Espera 15 mseg.
}
Artículo relacionado>> Sensor SHT11 con PIC
3 comentarios:
Estoy usando un 16f886 en 8mhz con un sht35 pero la simulación la hago con un sht11.
El compilador ccs c compiler me da los siguientes warnings:
>>>> warning Function not void and does not return a value SHTxx_Medida
>>>> warning Function not void and does not return a value SHTxx_calculo
>>>> warning Function not void and does not return a value SHTxx_ESCRITURA_REGISTRO_ESTADO
Y Proteus me marca 1 segundo la T y H mas o menos normal y después
-40 en Temperatura y o en humedad.
He encontrado otros errores, cuando accedo correctamente modificando un poco el tema puertos en ccs C desde proteus los valores en el lcd no coinciden con los del sensor. y en la protoboard aparecen un par de valores 2 segundos y despues -40, quizas tenga que ver con los bits de resolución?. Alguien me puede dar una mano?
esta es mi configuración:
#include
#include
#include
#define INTRAC PIN_C6
#define LUZ PIN_C7
#define CALOR PIN_C5
#define FRIO PIN_C1
#define HUMEDAD PIN_C0
#define BLIGHT PIN_A1 //PORTA RA1
#define SET PIN_A2 //PORTA RA2
#define MAS PIN_A3 //PORTA RA3
#define MENOS PIN_A4 //PORTA RA4
#define BLLCD PIN_C2 //luz backlight
#use i2c(master, sda=PIN_C4, scl=PIN_C3, slow)
#use STANDARD_IO(C)
#use STANDARD_IO(A)
#use FIXED_IO( A_outputs=PIN_A7,PIN_A6,PIN_A5,PIN_A0 )
#use FIXED_IO( B_outputs=PIN_B3 )
#use FIXED_IO( C_outputs=PIN_C7,PIN_C6,PIN_C5,PIN_C2,PIN_C1,PIN_C0 )
#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA4 PIN_B4
#define LCD_DATA5 PIN_B5
#define LCD_DATA6 PIN_B6
#define LCD_DATA7 PIN_B7
Publicar un comentario