Autor Tema: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"  (Leído 11016 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado sherckuith

  • PIC10
  • *
  • Mensajes: 6
Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
« Respuesta #30 en: 10 de Marzo de 2011, 19:57:26 »
Hola compañeros, una pregunta crusial por una apuesta, el SHT11 es I2C o que tipo de comunicación usa????... gracias...
« Última modificación: 10 de Marzo de 2011, 19:59:56 por sherckuith »

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
« Respuesta #31 en: 10 de Marzo de 2011, 20:15:37 »
Hola, según la hoja de datos, la comunicación es serial por 2 hilos.

Saludos!

Desconectado sherckuith

  • PIC10
  • *
  • Mensajes: 6
Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
« Respuesta #32 en: 11 de Marzo de 2011, 03:12:08 »
Exactamente ese es mi dilema, tengo una libreria que funciona perfectamente pero al conectarla al pic y probar la misma secuencia pero usando la comunicacion I2C teniendo en cuenta que es SCK y SDA los pines a usar no funciona... entonces es algo que cambia en el protocolo de I2C o es otro protocolo similar al I2C pero propio del SHT11???, muchisimas gracias por responder tan pronto....

Desconectado bmb

  • PIC18
  • ****
  • Mensajes: 423
Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
« Respuesta #33 en: 11 de Marzo de 2011, 09:10:07 »
Hola sherckuith, según leí,  el integrado no utiliza el protocolo I2C.  De la hoja de datos:

Citar
The sensor cannot be addressed by I2C protocol; however, the sensor can be connected to an I2C bus without interference with other devices connected to the bus. The controller must switch between the protocols.

Según entiendo, esto significa que se puede conectar a un bus I2C sin causar interferencia a este, pero debe manejar su propio protocolo.

Por aquí encuentras una librería en c para ese integrado.

Saludos!

Desconectado sherckuith

  • PIC10
  • *
  • Mensajes: 6
Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
« Respuesta #34 en: 11 de Marzo de 2011, 17:14:46 »
Aaaa.. ya! chevere!!!! muchisimas gracias por sacarnos de esa duda, aposte una pizza a que era I2C y por lo que veo perdi! =( no importa, al menos sali de la ignorancia..., esta es la libreria que yo tengo, es la de J1M, esta sumamente bien explicada, si puedes pruebala y a ver que diferencias encontramos ok...

// set DATA and SCK
#define DATOS  PIN_A4
#define CLOCK  PIN_A5

#define SHT11_noACK 0
#define SHT11_ACK   1

// SHT11 commands                 //adr  command  r/w
#define SHT11_STATUS_REG_W 0x06   //000   0011    0
#define SHT11_STATUS_REG_R 0x07   //000   0011    1
#define SHT11_MEASURE_TEMP 0x03   //000   0001    1
#define SHT11_MEASURE_HUMI 0x05   //000   0010    1
#define SHT11_RESET        0x1E   //000   1111    0

enum {TEMP,HUMI};


byte sht11_escribir_byte(byte value)
// writes a byte on the Sensibus and checks the acknowledge
{
   byte i,error=0;

   for (i=128;i>0;i/=2)                 //shift bit for masking
   {
      if (i & value)   output_high(DATOS);   //masking value with i , write to SENSI-BUS
      else output_low(DATOS);
      output_high(CLOCK);               //clk for SENSI-BUS
      delay_us(5);                      //pulswith approx. 5 us
      output_low(CLOCK);
   }
   output_high(DATOS);                   //release DATA-line
   output_high(CLOCK);                   //clk #9 for ack
   error=input(DATOS);                   //check ack (DATA will be pulled down by SHT11)
   output_low(CLOCK);
   return error;                         //error=1 in case of no acknowledge
}


byte sht11_leer_byte(byte ack)
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
   byte i,val=0;

   output_high(DATOS);             //release DATA-line
   for (i=128;i>0;i/=2)           //shift bit for masking 0x80
   {
      output_high(CLOCK);               //clk for SENSI-BUS
      if (input(DATOS))   val=(val | i);  //read bit
      output_low(CLOCK);
   }
   if (ack) output_low(DATOS);      //in case of "ack==1" pull down DATA-Line
   else output_float(DATOS);
   output_high(CLOCK);             //clk #9 for ack
   delay_us(5);                    //pulswith approx. 5 us
   output_low(CLOCK);
   output_high(DATOS);             //release DATA-line
   return val;
}


void sht11_init(void)
// generates a transmission start
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
{
   output_high(DATOS);
   output_low(CLOCK);             //Initial state
   delay_us(2);
   output_high(CLOCK);
   delay_us(2);
   output_low(DATOS);
   delay_us(2);
   output_low(CLOCK);
   delay_us(5);
   output_high(CLOCK);
   delay_us(2);
   output_float(DATOS);
   delay_us(2);
   output_low(CLOCK);
}


void sht11_hard_reset(void)
//para hacer un reset completo del sensor se realiza la secuencia...
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
{
   byte i;

   output_high(DATOS);
   output_low(CLOCK);           //Initial state
   for(i=0;i<9;i++)             //9 SCK cycles
   {
      output_high(CLOCK);
      delay_us(2);
      output_low(CLOCK);
      delay_us(2);
   }
   sht11_init();            //transmission start
}

byte sht11_soft_reset(void)
// resets the sensor by a softreset
{
   byte error=0;

   sht11_hard_reset();                                    //reset communication
   error+=sht11_escribir_byte(SHT11_RESET);          //send RESET-command to sensor
   return error;                               //error=1 in case of no response form the sensor
}


byte sht11_leer_registro_estado(byte *p_valor, byte *p_checksum)
// reads the status register with checksum (8-bit)
{
   byte error=0;

   sht11_init();                           //transmission start
   error = sht11_escribir_byte(SHT11_STATUS_REG_R);  //send command to sensor
   *p_valor = sht11_leer_byte(SHT11_ACK);            //read status register (8-bit)
   *p_checksum = sht11_leer_byte(SHT11_NOACK);       //read checksum (8-bit)
   return error;                               //error=1 in case of no response form the sensor
}


byte sht11_escribir_registro_estado(byte *p_valor)
// writes the status register with checksum (8-bit)
{
   byte error=0;

   sht11_init();                           //transmission start
   error += sht11_escribir_byte(SHT11_STATUS_REG_W); //send command to sensor
   error += sht11_escribir_byte(*p_valor);           //send value of status register
   return error;                               //error>=1 in case of no response form the sensor
}


byte sht11_medicion(byte *p_valor, byte *p_checksum, byte modo)
// makes a measurement (humidity/temperature) with checksum
{
   byte error=0;
   int16 i;

   sht11_init();
   switch(modo)                             //send command to sensor
   {
      case TEMP   : error+=sht11_escribir_byte(SHT11_MEASURE_TEMP); break;
      case HUMI   : error+=sht11_escribir_byte(SHT11_MEASURE_HUMI); break;
      default     : break;
   }
   for (i=0;i<65535;i++) if(input(DATOS)==0) break;  //wait until sensor has finished the measurement
   if(input(DATOS)) error+=1;               // or timeout (~2 sec.) is reached
   *(p_valor+1)  =sht11_leer_byte(SHT11_ACK);     //read the first byte (MSB)
   *(p_valor)    =sht11_leer_byte(SHT11_ACK);     //read the second byte (LSB)
   *(p_checksum) =sht11_leer_byte(SHT11_NOACK);   //read checksum

   return error;
}


void sht11_calculos(float *p_humedad, float *p_temperatura)
{
// calculates temperature [°C] and humidity [%RH]
// input :  humi [Ticks] (12 bit)
//          temp [Ticks] (14 bit)
// output:  humi [%RH]
//          temp [°C]

   const float C1=-4.0;               // for 12 Bit
   const float C2=+0.0405;            // for 12 Bit
   const float C3=-0.0000028;         // for 12 Bit
   const float T1=+0.01;            // for 14 Bit @ 5V
   const float T2=+0.00008;         // for 14 Bit @ 5V

   float rh;
   float t;
   float rh_lin;                     // rh_lin:  Humidity linear
   float rh_true;                     // rh_true: Temperature compensated humidity
   float t_C;                        // t_C   :  Temperature [°C]
   rh = *p_humedad;                  // rh:      Humidity [Ticks] 12 Bit
   t = *p_temperatura;               // t:       Temperature [Ticks] 14 Bit

   t_C = t*0.01 - 40;               //calc. temperature from ticks to [°C]
   rh_lin=C3*rh*rh + C2*rh + C1;      //calc. humidity from ticks to [%RH]
   rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH]
   if(rh_true>100)rh_true=100;      //cut if the value is outside of
   if(rh_true<0.1)rh_true=0.1;      //the physical possible range

   *p_temperatura=t_C;               //return temperature [°C]
   *p_humedad=rh_true;               //return humidity[%RH]
}



bye... y gracias nuevamente...

Desconectado sherckuith

  • PIC10
  • *
  • Mensajes: 6
Re: Librería SHT11 de J1M. Problema con declaración de cadenas. "Esquivado ;)"
« Respuesta #35 en: 11 de Marzo de 2011, 17:17:09 »
Sorry, olvide el archivo C,


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/////               LECTURA SENSOR HUMEDAD/TEMPERATURA SHT11               /////
/////                                                                      /////
///// En este programa se muestra como leer el sensor SHT11 de la casa     /////
///// sensirion (www.sensirion.com), para no forzar el sensor se ha puesto /////
///// un delay de 1sg, segun su datasheet el tiempo de lectura y lectura   /////
///// puede ser inferior. Se adjunta un esquema de conexión en Proteus.    /////
///// Aunque puede ser modificado puesto que el protocolo de lectura del   /////
///// sensor está implementado en la libreria.                             /////
/////                                                                      /////
/////                                                                      /////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#include <18F2520.h>

#fuses NOWDT, WDT128, XT, NOPROTECT, BROWNOUT, BORV45, NOPUT, NOCPD
#fuses NOSTVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOIESO, NOFCMEN, NOPBADEN
#fuses NOWRTC, NOWRTB, NOEBTR, NOEBTRB, NOCPB, NOLPT1OSC, MCLR, NOXINST

#use delay(clock=4000000)

#include <lcd420.h>
#include <sht11.h>

void lectura_sht11(void);
void mostrar_temp_hum(void);

unsigned int8 temp_actual, humedad_actual;

typedef union
{
   int16 i;
   float f;
} valor;
valor humedad, temperatura;
byte errorsht11,checksum;


void main()
{
   lcd_init();
   sht11_hard_reset();

   while(true)
   {
      lectura_sht11();
      mostrar_temp_hum();
      delay_ms(1000);
   }
}


void lectura_sht11(void)
{
   errorsht11=0;
   errorsht11+=sht11_medicion((byte*) &humedad.i, &checksum, HUMI);     //measure humidity
   errorsht11+=sht11_medicion((byte*) &temperatura.i, &checksum, TEMP); //measure temperature
   if(errorsht11!=0)                                                    //in case of an error: connection reset
   {
      printf(lcd_putc,"\n\rerror:%U", errorsht11);
      sht11_hard_reset();
     }
   else
   {
      humedad.f=(float)humedad.i;                              //converts integer to float
      temperatura.f=(float)temperatura.i;                      //converts integer to float
      sht11_calculos(&humedad.f, &temperatura.f);              //calculate humidity, temperature
      temp_actual = temperatura.f;
      humedad_actual = humedad.f;
   }
}


void mostrar_temp_hum(void)
{
   lcd_gotoxy(1,1);
   printf(lcd_putc," %2.2f",temperatura.f);
   lcd_send_byte(1,0b11011111);                 //caracter de grados " º "
   printf(lcd_putc,"C  %2.2f%%HR",humedad.f);
}


usa la libreria del display de 4x20:

////////////////////////////////////////////////////////////////////////////
////                             LCD420.C                               ////
////            Driver for common 4x20 LCD modules                      ////
////                                                                    ////
////  lcd_init()   Must be called before any other function.            ////
////                                                                    ////
////  lcd_putc(c)  Will display c on the next position of the LCD.      ////
////                     The following have special meaning:            ////
////                      \f  Clear display                             ////
////                      \n  Go to start of second line                ////
////                      \b  Move back one position                    ////
////                                                                    ////
////  lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)     ////
////                                                                    ////
////  lcd_getc(x,y)   Returns character at position x,y on LCD          ////
////                                                                    ////
////////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,1997 Custom Computer Services            ////
//// This source code may only be used by licensed users of the CCS C   ////
//// compiler.  This source code may only be distributed to other       ////
//// licensed users of the CCS C compiler.  No other use, reproduction  ////
//// or distribution is permitted without written permission.           ////
//// Derivative programs created using this software in object code     ////
//// form are not restricted in any way.                                ////
////////////////////////////////////////////////////////////////////////////

// As defined in the following structure the pin connection is as follows:
//     C0  enable
//     C1  rs
//     C2  rw
//     C4  D4
//     C5  D5
//     C6  D6
//     C7  D7
//
//   LCD pins D0-D3 are not used and PIC C3 is not used.

struct lcd_pin_map {                 // This structure is overlayed
           BOOLEAN enable;           // on to an I/O port to gain
           BOOLEAN rs;               // access to the LCD pins.
           BOOLEAN rw;               // The bits are allocated from
           BOOLEAN unused;           // low order up.  ENABLE will
           int     data : 4;         // be pin B0.
        } lcd;

#byte lcd = 0xF82                        // This puts the entire structure
                                     // on to port C (at address 0xF82)

#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 lines


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                             // These bytes need to be sent to the LCD
                             // to start it up.


                             // The following are used for setting
                             // the I/O port direction register.

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in

BYTE lcdline;

BYTE lcd_read_byte() {
      BYTE low,high;

      set_tris_c(LCD_READ);
      lcd.rw = 1;
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_c(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      lcd.rw = 0;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}


void lcd_init() {
    BYTE i;

    set_tris_c(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(15);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(5);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0, LCD_INIT_STRING);
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE address;

   switch(y) {
     case 1 : address=0x80;break;
     case 2 : address=0xc0;break;
     case 3 : address=0x94;break;
     case 4 : address=0xd4;break;
   }
   address+=x-1;
   lcd_send_byte(0,address);
}

void lcd_putc( char c) {
   switch (c) {
     case '\f'   : lcd_send_byte(0,1);
                   lcdline=1;
                   delay_ms(2);
                                           break;
     case '\n'   : lcd_gotoxy(1,++lcdline);        break;
     case '\b'   : lcd_send_byte(0,0x10);  break;
     default     : lcd_send_byte(1,c);     break;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}


ahora si... GXS!!!!