RobotyPic son proyectos básicos de electrónica con microcontroladores PIC, de aplicación en el mundo de la robótica didáctica, con archivos fuente creados mediante el compilador CCS PIC C COMPILER en lenguajeC.

Librería C para sensor SHT11 con PIC

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.
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:

-         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”, conmutar 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. 
}


[+/-] Ver / Ocultar librería C completa


Artículo relacionado>> Sensor SHT11 con PIC


3 comentarios:

CGR dijo...
Este comentario ha sido eliminado por el autor.
CGR dijo...

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?

CGR dijo...

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

Related Posts Plugin for WordPress, Blogger...

CONTACTA - (Haz referencia del artículo sobre el que trata la consulta o comentario)