2
« en: Miércoles 8 de Julio de 2009, 05:50 »
Hola a todos, tengo un problema con el sensor SHT15, lo que sucede es que solo logro apreciar en la pantalla LCD una Temp de -37.8º y una humedad de .1%, este sensor es de la SENSIRION, en la página de la sensirion aparece un código para controlarlo, dicho código lo varié levemente, agradecería si alguien pudiera ayudarme a solucionar este problema o si ya han pasado por esto y han dado con la solución, que me comentaran que fue lo que hicieron.
Leí el datasheet del sensor y revise en varias ocasiones las funciones del programa original, pienso que el error podria estar en una función llamada "Leer_byte" la original(codigo de la sensirion)"s_read_byte"
Este es mi codigo:
/********LIBRERIAS*******************/
#include <Sensor2.h>
#include <LCD.C>
#include <math.h>
#include <stdio.h>
#use fast_io(d)
/*******TIPOS DEFINIDOS**************/
typedef union
{
unsigned int i;
float f;
} valor;
enum {TEMP, HUME};
/******DEFINICIONES LOCALES**********/
#define Status_REG_ESC 0x06 //00000110
#define Status_REG_LEC 0x07 //00000111
#define MED_TEMP 0x03 //00000011
#define MED_HUME 0x05 //00000101
#define RESET 0x1E //00011110
#define NOACK 0
#define ACK 1
#define DATA PIN_D7
#define SCK PIN_D6
/******************FUNSIONES***************************/
/** FUNCION DEL FABRICANTE ----> ESCRIBIR UN BYTE***********/
char escribir_byte(unsigned char valor)
{
unsigned int i;
unsigned char error=0;
set_tris_d(0x00);
for(i=128;i>0;i/=2)
{
if(i & valor)
{
output_high(DATA);
}
else
{
output_low(DATA);
delay_us(2);
output_high(SCK);
delay_us(2);
output_low(SCK);
delay_us(2);
}
}
set_tris_d(0x80);
delay_us(2);
output_high(SCK);
delay_us(2);
error=input(DATA);
output_low(SCK);
return error;
}
/** FUNCION DEL FABRICANTE ----> LEER UN BYTE***********/
char leer_byte(unsigned char ack)
{
unsigned char valor=0, i;
set_tris_d(0x80);
//output_low(SCK);
for(i=128;i>0;i/=2)
{
output_high(SCK);
//delay_us(2);
if(input(DATA))
valor=(valor | i);
output_low(SCK);
delay_us(2);
}
/*if(input(DATA)=!ack) //En caso de que ack==ACK, se pone a nivel bajo la linea de datos
{
set_tris_d(0x00);
output_high(DATA);
}*/
output_bit(DATA, !ack);
output_high(SCK);
delay_us(5);
output_low(SCK);
set_tris_d(0x80);
return valor;
}
////////////////////////////////////
void inicio_transmision()
{
output_high(DATA); //Data 1
output_low(SCK); //SCK 0
delay_us(2);
output_high(SCK); //SCK 1
delay_us(2);
output_low(DATA); //Data 0
delay_us(2);
output_low(SCK); //SCK 0
delay_us(6);
output_high(SCK); //SCK 1
delay_us(2);
output_high(DATA); //DATA 1
delay_us(2);
output_low(SCK); //SCK 0
}
////////////////////////////////////////
void coneccion_reset()
{
int i;
output_high(DATA);
set_tris_d(0x00);
//output_low(SCK);
for(i=0;i<=9;i++)
{
output_high(SCK);
delay_us(2);
output_low(SCK);
delay_us(2);
}
inicio_transmision();
}
/****FUNSION DEL FABRICANTE ---> RESTABLECIMIENTO***********/
char restablecimiento()
{
unsigned char error=0;
coneccion_reset();
error+=escribir_byte(RESET); //error=error + escribir byte
return error;
}
/****FUNSION DEL FABRICANTE ---> MEDIDA DE TEMP Y HUMEDAD*********************/
char medida(unsigned char *p_valor, unsigned char *p_checksum, unsigned char modo)
{
unsigned error=0;
unsigned int i;
inicio_transmision();
switch(modo)
{
case TEMP:
error+=escribir_byte(MED_TEMP);
break;
case HUME:
error+=escribir_byte(MED_HUME);
break;
default:
break;
}
(modo==HUME) ? delay_ms(55) : delay_ms(210);
for(i=0; i<65535; i++)
{
if(input(DATA)==0)
break;
if(input(DATA))
error+=1;
*(p_valor+1) = leer_byte(ACK);
*(p_valor) = leer_byte(ACK);
*p_checksum = leer_byte(NOACK);
return error;
}
}
//////////////CALCULOS DE LA TEMPERATURA Y LA HUMEDAD////////////////////////
void calculos(float *p_humedad, float *p_temperatura)
{
const float C1 = -4.0; // Para 12 bit
const float C2 = 0.0405; // Para 12 bit
const float C3 = -0.0000028; // Para 12 bit
const float T1 = 0.01;
const float T2 = 0.00008;
float RH,TEMP,RH_LIN,RH_TRUE,TC;
RH = *p_humedad;
TEMP = *p_temperatura;
/////Calculos//////////////////
TC = TEMP*0.01-40;
RH_LIN = C3*RH*RH + C2*RH + C1;
RH_TRUE = (TC-25) * (T1+T2*RH) + RH_LIN;
if(RH_TRUE>100)
RH_TRUE=100;
if(RH_TRUE<0.1)
RH_TRUE=0.1;
*p_temperatura = TC;
*p_humedad = RH_TRUE;
}
/////////////////////LECTURA DEL STATUSREG////////////////////////////
/*char Leer_statusreg(unsigned char *p_valor, unsigned char *p_checksum)
{
unsigned char error=0;
inicio_transmision();
error=escribir_byte(Status_REG_LEC);
*p_valor=leer_byte(ACK);
*p_checksum=leer_byte(NOACK);
return error;
}
///////////////////ESCRITURA DEL STATUSREG////////////////////////////
char Escribir_statusreg(unsigned char *p_valor)
{
unsigned char error=0;
inicio_transmision();
error+=escribir_byte(Status_REG_ESC);
error+=escribir_byte(*p_valor);
return error;
}*/
/************MAIN********************/
void main()
{
unsigned int i;
unsigned char error, checksum;
valor hume_val, temp_val;
/////////////////////////////////////
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
/////////////////////////////////////
coneccion_reset();
while(1)
{
error=0;
error+=medida((unsigned char*) &hume_val.i, &checksum, HUME);
error+=medida((unsigned char*) &temp_val.i, &checksum, TEMP);
if (error!=0)
{
coneccion_reset();
}
else
{
hume_val.f=(float)hume_val.i;
temp_val.f=(float)temp_val.i;
calculos(&hume_val.f, &temp_val.f);
lcd_gotoxy(4,1);
printf(lcd_putc, "TEMP: %5.1fC", temp_val.f);
lcd_gotoxy(-2,3);
printf(lcd_putc, "HUME: %5.1f%%", hume_val.f);
}
delay_ms(800);
}
}