CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Read temperature maximum minimum ds1624

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
MANEL
Guest







Read temperature maximum minimum ds1624
PostPosted: Thu Dec 08, 2005 2:31 pm     Reply with quote

Hi. I've had a circuit with PIC16f877 <--> Ds1624 connected by means I2C. The temperature is OK but the problem is that spent a certain time the temperature is sleep, is always the same one and it does not change although it changes the temperature of the surroundings. also I have a problem with the temperature minimum, the algorithm that I have created not shows minimum but 0ºC always. Somebody finds the problem ? Laughing

The program:

#include <16f877.h>
#use delay (clock=4000000)
#use I2C(MASTER, SDA=PIN_C4, SCL=PIN_C3, fast)
#use fast_io(A)
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD

#include <lcd_lolo.c>

#define simbolo_grados 0b11011111
#define simbolo_coma 0b00101100
#define I2CWRITE 0b10010000
#define I2CREAD 0b10010001
#define I2CREAD2 0b10010011

#define DS1624_CMD_ACCESSCONFIG 0xAC
#define DS1624_CMD_INITIATECONVERT 0xEE
#define DS1624_CMD_ACCESSTEMPERATURE 0xAA
#define DS1624_CMD_ACCESSMEMORY 0x17

# byte port_a=6
int datah, datal;

void i2c_conversion()
{

i2c_start();
i2c_write(I2CWRITE);
i2c_write(DS1624_CMD_INITIATECONVERT);
i2c_stop();
}

void i2c_ds1624_inicia()
{
i2c_start();
i2c_write(I2CWRITE);
i2c_write(DS1624_CMD_ACCESSCONFIG);
i2c_write(0b01001011);
i2c_stop();
delay_ms(20);
i2c_conversion();
}

void i2c_ds1624_leer_temp_c()
{
i2c_start();
i2c_write(I2CWRITE);
i2c_write(DS1624_CMD_ACCESSTEMPERATURE);
i2c_start();
i2c_write(I2CREAD);
datah=i2c_read();
datal=i2c_read(0);
i2c_stop();
i2c_ds1624_inicia();
}


int read_ext_eeprom(int address)
{
int data;
i2c_start();
i2c_write(0x90);
i2c_write(0x17);
i2c_write(address);
i2c_start();
i2c_write(0x91);
data=i2c_read();
i2c_stop();
return data;


}


void write_ext_eeprom(int address, int data)
{
i2c_start();
i2c_write(0x90);
i2c_write(0x17);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(50);
}
void main (void)
{
int temperatura;
int dec,decimal,max, maxd, auxi,auxi2,mini,mind,contador,conta,minimo;
lcd_inicia();
i2c_ds1624_inicia();
set_tris_a(0b111110);
lcd_ponc("\f");
port_a=0;
max=0;
maxd=0;
auxi=0;
mini=5;
mind=99;
auxi2=50;
contador=0;
conta=0;
while(1)
{
contador=contador+1;
if (conta<50) conta=conta+1;
i2c_ds1624_leer_temp_c();
lcd_ponc("\f");
switch(datal)
{
case 248: dec=98; break;
case 240: dec=94; break;
case 232: dec=90; break;
case 224: dec=87; break;
case 216: dec=83; break;
case 208: dec=80; break;
case 200: dec=77; break;
case 192: dec=75; break;
case 184: dec=72; break;
case 176: dec=70; break;
case 168: dec=68; break;
case 160: dec=66; break;
case 152: dec=62; break;
case 144: dec=60; break;
case 136: dec=58; break;
case 128: dec=55; break;
case 120: dec=53; break;
case 112: dec=50; break;
case 104: dec=48; break;
case 96: dec=44; break;
case 88: dec=40; break;
case 80: dec=37; break;
case 72: dec=34; break;
case 64: dec=30; break;
case 56: dec=28; break;
case 48: dec=23; break;
case 40: dec=20; break;
case 32: dec=17; break;
case 24: dec=13; break;
case 16: dec=10; break;
case 8: dec=05; break;
case 0: dec=0; break;
}
lcd_vaixy(1,1);

if (datah>max) max= datah;
if ((dec> maxd) && (auxi<=max))
{
maxd=dec;
auxi=max;
}
if ((dec<= maxd) && (auxi<max))
{
maxd=dec;
auxi=max;
}


if ((dec< mind) && (auxi2>=mini))
{
mind=dec;
auxi2=mini;
mini=datah;
}
if ((dec>= mind) && (auxi2>mini))
{
mind=dec;
auxi2=mini;
}
printf(lcd_ponc,"T= %d%2d%cC",datah,simbolo_coma,dec,simbolo_grados);
lcd_vaixy(1,2);
if (contador<100)
printf(lcd_ponc,"TMax=%d%c%2d%cC",max,simbolo_coma,maxd,simbolo_grados);
if (contador>=100)
printf(lcd_ponc,"TMin=%d%c%2d%cC",mini,simbolo_coma,mind,simbolo_grados);
if (contador>200) contador=0;
if (datah>20) output_high (PIN_A0);
if (datah<=20) output_low (PIN_A0);
}
}
jds-pic



Joined: 17 Sep 2003
Posts: 205

View user's profile Send private message

PostPosted: Fri Dec 09, 2005 2:20 pm     Reply with quote

(double posted; content in next post)

Last edited by jds-pic on Fri Dec 09, 2005 2:22 pm; edited 1 time in total
Guest








PostPosted: Fri Dec 09, 2005 2:21 pm     Reply with quote

MANEL,

(note use of "Code" button below; makes reading much easier)

you are doing a lot of work outside of i2c_ds1624_leer_temp_c(), with the high and low bytes of the result carried back to main() as globals.

in my library code you cut-n-pasted from:
Code:
int i2c_ds1624_read_temp_c(int device_addr) {
   int datah, datal;
   int addr_mask;
   addr_mask=i2c_addr_mask(device_addr);
   i2c_start();
   i2c_write(DS1624_ID | addr_mask | I2CWRITE); /* mode is write */
   i2c_write(DS1624_CMD_ACCESSTEMPERATURE); /* send access temperature command */
   i2c_start();
   i2c_write(DS1624_ID | addr_mask | I2CREAD);  /* mode is read */
   datah=i2c_read();                  /* msb */
   datal=i2c_read(0);                 /* lsb (=0.5 deg C) & No Ack */
   i2c_stop();
   if (BIT_TEST(datah,7)) /* defeat the two's complement data output; */
      return(0);          /* this means NO negative temps are returned */
   else                   /* if datal is > 0.5C, round up the value */
      return( ((datal & 0b10000000) ? datah+1 : datah) ); /* returns 0->125 deg C */
}

so here's an idea...
note that the return value is an unsigned int. the last few lines of the function make it so. for your application, just change the tail end of this function (and it's declaration of course) to return a signed int. then you won't have to screw around with datah and datal in your main.

jds-pic
padron70



Joined: 08 Dec 2005
Posts: 7

View user's profile Send private message

PostPosted: Sun Dec 11, 2005 4:44 pm     Reply with quote

Thanks jds-pic, I have changed the function i2c_ds1624_leer_temp_c() since you have recommended and the results have been correct with the maximum and minimum temperatures perfectly shown.
The final code:
Laughing
Code:

#include <16f877.h>
#use delay (clock=4000000)
#use I2C(MASTER, SDA=PIN_C4, SCL=PIN_C3, fast)
#use fast_io(A)
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD

#include <lcd_lolo.c>

#define simbolo_grados 0b11011111
#define simbolo_coma 0b00101100
#define I2CWRITE 0b10010000
#define I2CREAD 0b10010001
#define I2CREAD2 0b10010011

#define DS1624_CMD_ACCESSCONFIG  0xAC
#define DS1624_CMD_INITIATECONVERT  0xEE
#define DS1624_CMD_ACCESSTEMPERATURE 0xAA
#define DS1624_CMD_ACCESSMEMORY  0x17

# byte port_a=6

void i2c_conversion()
{

   i2c_start();
   i2c_write(I2CWRITE);
   i2c_write(DS1624_CMD_INITIATECONVERT);
   i2c_stop();
}

void i2c_ds1624_inicia()
{
   i2c_start();
   i2c_write(I2CWRITE);
   i2c_write(DS1624_CMD_ACCESSCONFIG);
   i2c_write(0b01001011);
   i2c_stop();
   delay_ms(20);
   i2c_conversion();
}

float i2c_ds1624_leer_temp_c()
{
   float dec;
   int datah, datal;
   i2c_start();
   i2c_write(I2CWRITE);
   i2c_write(DS1624_CMD_ACCESSTEMPERATURE);
   i2c_start();
   i2c_write(I2CREAD);
   datah=i2c_read();
   datal=i2c_read(0);
   switch(datal)
      {
         case 248: dec=0.98; break;
         case 240: dec=0.94; break;
         case 232: dec=0.90; break;
         case 224: dec=0.87; break;
         case 216: dec=0.83; break;
         case 208: dec=0.80; break;
         case 200: dec=0.77; break;
         case 192: dec=0.75; break;
         case 184: dec=0.72; break;
         case 176: dec=0.70; break;
         case 168: dec=0.68; break;
         case 160: dec=0.66; break;
         case 152: dec=0.62; break;
         case 144: dec=0.60; break;
         case 136: dec=0.58; break;
         case 128: dec=0.55; break;
         case 120: dec=0.53; break;
         case 112: dec=0.50; break;
         case 104: dec=0.48; break;
         case  96: dec=0.44; break;
         case  88: dec=0.40; break;
         case  80: dec=0.37; break;
         case  72: dec=0.34; break;
         case  64: dec=0.30; break;
         case  56: dec=0.28; break;
         case  48: dec=0.23; break;
         case  40: dec=0.20; break;
         case  32: dec=0.17; break;
         case  24: dec=0.13; break;
         case  16: dec=0.10; break;
         case   8: dec=0.05; break;
         case   0: dec=0.00; break;
      }

   i2c_stop();
   i2c_ds1624_inicia();
   return (datah + dec);
}


int read_ext_eeprom(int address)
{
   int data;
   i2c_start();
   i2c_write(0x90);
   i2c_write(0x17);
   i2c_write(address);
   i2c_start();
   i2c_write(0x91);
   data=i2c_read();
   i2c_stop();
   return data;


}


void write_ext_eeprom(int address, int data)
{
   i2c_start();
   i2c_write(0x90);
   i2c_write(0x17);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   delay_ms(50);
}
void main (void)
{
   float tempe,maximo,minimo;
   int contador;
   lcd_inicia();
   i2c_ds1624_inicia();
   set_tris_a(0b111110);
   lcd_ponc("\f");
   port_a=0;
   maximo=0;
   minimo=100;
   contador=0;
   while(1)
   {
      tempe=i2c_ds1624_leer_temp_c();
      i2c_ds1624_inicia();
      if (tempe>maximo) maximo= tempe;
      if ((tempe<minimo)&& (tempe!=0.0000)) minimo= tempe;
      lcd_ponc("\f");
      lcd_vaixy(1,1);
      printf(lcd_ponc,"T= %4.2f%cC",tempe,simbolo_grados);
      lcd_vaixy(1,2);
      if (contador<50)
      printf(lcd_ponc,"Maxi= %4.2f%cC",maximo,simbolo_grados);
      if (contador>=50)
      printf(lcd_ponc,"Mini= %4.2f%cC",minimo,simbolo_grados);
      if (contador>100) contador=0;
      if (tempe>20.00) output_high (PIN_A0);
      if (tempe<=20.00) output_low (PIN_A0);
      contador=contador+1;
   }
}
jds-pic



Joined: 17 Sep 2003
Posts: 205

View user's profile Send private message

PostPosted: Thu Dec 15, 2005 8:27 am     Reply with quote

padron70 wrote:


"The final code:"

Code:

<...>

void i2c_conversion()
{
   i2c_start();
   i2c_write(I2CWRITE);
   i2c_write(DS1624_CMD_INITIATECONVERT);
   i2c_stop();
}

void i2c_ds1624_inicia()
{
   i2c_start();
   i2c_write(I2CWRITE);
   i2c_write(DS1624_CMD_ACCESSCONFIG);
   i2c_write(0b01001011);
   i2c_stop();
   delay_ms(20);
   i2c_conversion();
}

float i2c_ds1624_leer_temp_c()
{
<...snip...>
   i2c_stop();
   i2c_ds1624_inicia();      <<<<<<  ------   WHY?
   return (datah + dec);
}


void main (void)
{
<...snip...>
   while(1)
   {
      tempe=i2c_ds1624_leer_temp_c();
      i2c_ds1624_inicia();
<...snip...>
   }
}


you still have a few structural problems and one logic problem...

(1) there is no reason for you to call i2c_ds1624_inicia() from within i2c_ds1624_leer_temp_c(). this is unnecessary and is likely causing you other problems related to...

(2) in i2c_ds1624_inicia() you set up for "one-shot" conversions (using i2c_write(0b01001011);) but you didn't read enough of the DS1624 datasheet to understand that it takes at minimum 400ms (max 1000ms) to complete a conversion. (refer to top of page 14 for the Ttc parameter). the while loop you have in main() makes no provision for enforcing the necessary delay. therefore, you are likely reading imcomplete conversion results, and then restarting the conversion process immediately thereafter. by your current method, i don't think you are getting accurate, repeatable measurements.

to fix (2), you can do one of three things.
a) use "continuous conversion mode" and read from the device whenever you want. it will give you the last valid result even if a new conversion is in process.
b) use a fixed 1000ms delay in your while loop after initiating a one shot conversion.
c) implement a delay_ms(50) loop which periodically checks the "done" bit in the DS1624 status register after you initiate a one shot conversion. only read when the done bit gets set.

the simplest, surest method is (a).

jds-pic

note for our english-speaking readers:
inicia ~= init
leer ~= read
Guest
Guest







PostPosted: Wed Jan 04, 2006 5:30 am     Reply with quote

What would you suggest if i say that i need water temperature sensor that must be all the time, in the water ?

You stick it in the water and that's it. He should be all time in the water...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group