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

pic16f84 thermometer using DS18B20

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



Joined: 17 Oct 2009
Posts: 6

View user's profile Send private message

pic16f84 thermometer using DS18B20
PostPosted: Sat Oct 17, 2009 4:35 am     Reply with quote

Hello. I've built a digital thermometer with pic16f84 and DS18B20 from this site: http://www.coolcircuit.com/project/digitemp/ and it's not working very well. The sensor is showing about 72 degrees C in a room. In the original project the sensor is DS1820 but I only have DS18B20. Could someone help me modify the source codes thus showing the right temperature? I have no programming experience, that is why I am asking for your help.

The source codes:

main.c
Code:

#include <16F84A.h>
#use delay(clock=4000000)
#fuses NOWDT,XT, NOPUT, NOPROTECT
#include <mylcd.c>
#include <ds1820.c>
//=====================================
// main program start here
//=====================================
void main(void)
{
   int buff[9], sensor, n,temp,temp_dec;

   delay_ms(50);
   lcd_init();

   while(true)
   {
      sensor=0;
      init_ds1820(sensor);
      write_ds1820_one_byte(0xcc, sensor);  // skip ROM
      write_ds1820_one_byte(0x44, sensor);  // perform temperature conversion
      while (read_ds1820_one_byte(sensor)==0xff); // wait for conversion complete
      init_ds1820(sensor);
      write_ds1820_one_byte(0xcc, sensor);  // skip ROM
      write_ds1820_one_byte(0xbe, sensor);  // read the result

      for (n=0; n<9; n++)     // read 9 bytes but, use only one byte
      {
         buff[n]=read_ds1820_one_byte(sensor);  // read DS1820
      }
      temp=buff[0]>>1;

      if ((buff[0] & 0x1)==1)
         temp_dec=5;
      else
         temp_dec=0;

      lcd_putc("\f");
      printf(lcd_putc,"Temp   :");
      printf(lcd_putc," %u.%u'C",temp,temp_dec);
      delay_ms(1000);
   }
} //enf of main program


ds1820:
Code:

#BYTE TRISA=0x85
#BYTE PORTA=0x5
#BYTE STATUS=0x3
#define RP0  5
#define C 0

// The following are standard 1-Wire routines.
void make_ds1820_high_pin(int sensor)
{
   TRISA = 0xff;
}

void make_ds1820_low_pin(int sensor)
{
   PORTA = 0x00;
   TRISA = 0xff & (~(0x01 << sensor));
}


// delay routines
void delay_10us(int t)
{
#asm
            BCF STATUS, RP0
 DELAY_10US_X:
            CLRWDT
            NOP
            NOP
            NOP
            NOP
            NOP
            NOP
            DECFSZ t, F
            GOTO DELAY_10US_X
#endasm
}

void delay_ms(long t)   // delays t millisecs
{
   do
   {
     delay_10us(100);
   } while(--t);
}

void init_ds1820(int sensor)
{
   make_ds1820_high_pin(sensor);
   make_ds1820_low_pin(sensor);
   delay_10us(50);

   make_ds1820_high_pin(sensor);
   delay_10us(50);
}

int read_ds1820_one_byte(int sensor)
{
   int n, i_byte, temp, mask;
   mask = 0xff & (~(0x01<<sensor));
   for (n=0; n<8; n++)
   {
      PORTA=0x00;
      TRISA=mask;
      TRISA=0xff;
#asm
      CLRWDT
      NOP
      NOP
#endasm
      temp=PORTA;
      if (temp & ~mask)
      {
        i_byte=(i_byte>>1) | 0x80;   // least sig bit first
      }
      else
      {
        i_byte=i_byte >> 1;
      }
      delay_10us(6);
   }
   return(i_byte);
}

void write_ds1820_one_byte(int d, int sensor)
{
   int n, mask;
   mask = 0xff & (~(0x01<<sensor));
   for(n=0; n<8; n++)
   {
      if (d&0x01)
      {
         PORTA=0;
         TRISA=mask;      // momentary low
         TRISA=0xff;
         delay_10us(6);
      }

      else
      {
          PORTA=0;
          TRISA=mask;
     delay_10us(6);
          TRISA=0xff;
      }
      d=d>>1;
   }
}


I don't know if this is necessary but I'll post it anyway.
lcd.c
Code:

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 = 6                  // on to port B (at address 6)
#define set_tris_lcd(x) set_tris_b(x)
#define lcd_type 1           // 1 lines
#define lcd_line_two 0x40    // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 3),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 lcd_read_byte()
{
      BYTE low,high;
      set_tris_lcd(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_lcd(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_lcd(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[i]);
}

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

   if(y!=1)
     address=lcd_line_two;
   else
     address=0;
   address+=x-1;
   lcd_send_byte(0,0x80|address);
}

void lcd_putc( char c)
{
   switch (c) {
     case '\f'   : lcd_send_byte(0,1);
                   delay_ms(2);
                                           break;
     case '\n'   : lcd_gotoxy(1,2);        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);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}
gr1ph0n



Joined: 17 Oct 2009
Posts: 6

View user's profile Send private message

PostPosted: Sun Oct 18, 2009 4:37 am     Reply with quote

Nobody can help me?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 18, 2009 3:05 pm     Reply with quote

Quote:
The sensor is showing about 72 degrees C in a room.

What was the real temperature in your room during this test ?
(Measured by a thermometer, or by your estimate).
gr1ph0n



Joined: 17 Oct 2009
Posts: 6

View user's profile Send private message

PostPosted: Tue Oct 20, 2009 10:09 am     Reply with quote

Sorry for not responding, for 2 days i had trouble with my internet connection. The real temperature was 24 degrees C. The sensor is responding, when I put it near a heat source the temperature start to grow.
Although I have no programming experience, by logic (I guess) and with examples from this site, I made a program, please don't laugh because I was desperate to made my thermometer work for my baby.
When I compile it I receive this error: "Out of ROM, A segment or the program is too large @PRINTF_L32D_74FPFPF.

And this is the program:
Code:

#include <16f84.h>
#use delay(clock=4000000)
#fuses NOWDT,XT, NOPUT, NOPROTECT
#include "1wire.c"
#include "mylcd.c"


float ds1820_read()
{
int8 busy=0, temp1, temp2;
signed int16 temp3;
float result;

onewire_reset();
onewire_write(0xCC);
onewire_write(0x44);
delay_ms(200);
while (busy == 0)
  busy = onewire_read();
onewire_reset();
onewire_write(0xCC);
onewire_write(0xBE);
temp1 = onewire_read();
temp2 = onewire_read();

temp3 = make16(temp2, temp1);
result = (float) temp3 / 16.0;  //0.1 deg C resolution
delay_ms(200);
return(result);
}
void main()
{
float temperature;
 delay_ms(50);
   lcd_init();

//for  10 bit resolution mod
onewire_write(0xCC);
onewire_write(0x4E);

onewire_write(125);
  onewire_write(-55); //this should be done for proper working of DS18B20
   onewire_write(127);

onewire_reset();
   onewire_write(0xCC);
    onewire_write(0x48);
    delay_ms(15);

while (1)
{
  temperature = ds1820_read();

lcd_putc("\f");
printf(lcd_putc,"Temp:");
printf (lcd_putc," %3.1f\n\r",temperature);

Help me if you can, please!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 20, 2009 10:46 am     Reply with quote

Use the ds18B20 driver from the CCS code library forum:
http://www.ccsinfo.com/forum/viewtopic.php?t=28425
gr1ph0n



Joined: 17 Oct 2009
Posts: 6

View user's profile Send private message

PostPosted: Tue Oct 20, 2009 10:51 am     Reply with quote

That is what I have used. One question. I saw that, when I used "%3.1f" the error apears, can you tell me why %3.1f was put there, please. Thank you.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 20, 2009 10:59 am     Reply with quote

The 16F84A only has 1K rom. Floating point code uses a large amount
of ROM space. There isn't enough ROM space to do your floating point
printf statement.
gr1ph0n



Joined: 17 Oct 2009
Posts: 6

View user's profile Send private message

PostPosted: Tue Oct 20, 2009 11:02 am     Reply with quote

PCM programmer wrote:
The 16F84A only has 1K rom. Floating point code uses a large amount
of ROM space. There isn't enough ROM space to do your floating point
printf statement.


Can I do something? I don't want something fancy, just to show the temperature.
Sorry for my noob questions and for my ignorance.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 20, 2009 11:14 am     Reply with quote

Try displaying the result as a signed integer instead of a float.
Make the changes shown in bold below:
Quote:
printf (lcd_putc," %d\n\r", (signed int)temperature);
gr1ph0n



Joined: 17 Oct 2009
Posts: 6

View user's profile Send private message

PostPosted: Wed Oct 21, 2009 3:48 am     Reply with quote

It worked. Thank you very much!
This is the code that worked for me with PIC16F84:
Code:

#include <16f84.h>
#use delay(clock=4000000)
#fuses NOWDT,XT, NOPUT, NOPROTECT
#include "1wire.c"
#include "mylcd.c"


float ds1820_read()
{
int8 busy=0, temp1, temp2;
signed int16 temp3;
float result;

onewire_reset();
onewire_write(0xCC);
onewire_write(0x44);
delay_ms(200);
while (busy == 0)
  busy = onewire_read();
onewire_reset();
onewire_write(0xCC);
onewire_write(0xBE);
temp1 = onewire_read();
temp2 = onewire_read();

temp3 = make16(temp2, temp1);
result = (float) temp3 / 16.0;  //0.1 deg C resolution
delay_ms(200);
return(result);
}
void main()
{
float temperature;
 delay_ms(50);
   lcd_init();

//for  10 bit resolution mod
onewire_write(0xCC);
onewire_write(0x4E);

onewire_write(125);
  onewire_write(-55); //this should be done for proper working of DS18B20
   onewire_write(127);

onewire_reset();
   onewire_write(0xCC);
    onewire_write(0x48);
    delay_ms(15);

while (1)
{
  temperature = ds1820_read();

lcd_putc("\f");
printf(lcd_putc,"Temp:");
printf (lcd_putc," %d", (signed int) temperature);
delay_ms(100);
}

}


I want to make a statement: This is not my code!
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