[SOLVED] How to read serial number of DS18S20 or DS18B20 in MikroC for PIC

Status
Not open for further replies.

polona1010

Member level 1
Joined
Apr 17, 2013
Messages
40
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Visit site
Activity points
1,524
Hello

I need example in MikroC for PIC how to read serial number of DS18S20 or DS18B20 using MikroC OneWire library.

Result should be on 2x16 LCD.

PIC18F45K22 is microcontroller.


Thanks Polona
 

Hello

I need example in MikroC for PIC how to read serial number of DS18S20 or DS18B20 using MikroC OneWire library.

Result should be on 2x16 LCD.

PIC18F45K22 is microcontroller.


Thanks Polona


Hi Polona,

1-Wire needs little time investment to learn how to access and set 1-Wire devices. All relevant informations for particular part can be found in part datasheet which is supplied by manufacturer Maxim-Integrated.

Command for reading address number of 1-wire device is $33.

Family code for DS1820 (DS18S20) is 10h.
Family code for DS18B20 is 28h.


Short example code :

Code:
Ow_Reset(&PORTE, 2);                         // Onewire reset signal
    Ow_Write(&PORTE, 2, 0x33);                   // Read ROM
    Delay_us(120);

       colona = 17;
       for(i = 0; i <= 7; i++)
          {
            colona = colona - 2;
            sernum = Ow_Read(&PORTE, 2);
            bytetohex(sernum, sernum_hex);
            Lcd_Out(1, colona, sernum_hex);
          }





This is default MikroE example for 1-Wire, I just modify to show serial number in first row instead text "Temperature:".

Complete code in MikroC for PIC :

Code:
// LCD module connections
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections

//  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
//  18S20: 9  (default setting; can be 9,10,11,or 12)
//  18B20: 12
const unsigned short TEMP_RESOLUTION = 9;

char *text = "000.0000";
unsigned temp;
char sernum;
int i;
int colona;
char *sernum_hex[8];


void Display_Temperature(unsigned int temp2write) {
  const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
  char temp_whole;
  unsigned int temp_fraction;

  // Check if temperature is negative
  if (temp2write & 0x8000) {
    text[0] = '-';
    temp2write = ~temp2write + 1;
  }

  // Extract temp_whole
  temp_whole = temp2write >> RES_SHIFT ;

  // Convert temp_whole to characters
  if (temp_whole/100)
    text[0] = temp_whole/100  + 48;
  else
    text[0] = '0';

  text[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  text[2] =  temp_whole%10     + 48;             // Extract ones digit

  // Extract temp_fraction and convert it to unsigned int
  temp_fraction  = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;

  // Convert temp_fraction to characters
  text[4] =  temp_fraction/1000    + 48;         // Extract thousands digit
  text[5] = (temp_fraction/100)%10 + 48;         // Extract hundreds digit
  text[6] = (temp_fraction/10)%10  + 48;         // Extract tens digit
  text[7] =  temp_fraction%10      + 48;         // Extract ones digit

  // Print temperature on LCD
  Lcd_Out(2, 7, text);
}

void main() {
  ANSELE = 0;                                    // Configure PORTE pins as digital
  TRISE.B2 = 1;                                  // Configure RE2 pin as input

  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  Lcd_Out(2, 1, "Temp:");
  // Print degree character, 'C' for Centigrades
  Lcd_Chr(2,15,176);                             // Different LCD displays have different char code for degree
                                                 // If you see greek alpha letter try typing 178 instead of 223
  Lcd_Chr(2,16,'C');

  // Main loop
  do {
    // Perform temperature reading
    Ow_Reset(&PORTE, 2);                         // Onewire reset signal
    Ow_Write(&PORTE, 2, 0xCC);                   // Issue command SKIP_ROM
    Ow_Write(&PORTE, 2, 0x44);                   // Issue command CONVERT_T
    Delay_us(120);

    Ow_Reset(&PORTE, 2);
    Ow_Write(&PORTE, 2, 0xCC);                   // Issue command SKIP_ROM
    Ow_Write(&PORTE, 2, 0xBE);                   // Issue command READ_SCRATCHPAD

    temp =  Ow_Read(&PORTE, 2);
    temp = (Ow_Read(&PORTE, 2) << 8) + temp;

    // Format and display result on Lcd
    Display_Temperature(temp);


    Ow_Reset(&PORTE, 2);                         // Onewire reset signal
    Ow_Write(&PORTE, 2, 0x33);                   // Read ROM
    Delay_us(120);

       colona = 17;
       for(i = 0; i <= 7; i++)
          {
            colona = colona - 2;
            sernum = Ow_Read(&PORTE, 2);
            bytetohex(sernum, sernum_hex);
            Lcd_Out(1, colona, sernum_hex);
          }

    Delay_ms(500);
  } while (1);
}

Just to mention temp reading calc for DS18B20 must be made with different calc. Just to know in this example you will get correct temp only for DS18S20. Based on this expirience you can try to make correct reading for DS18B20. Point is to learn something.

This example is for one slave on single microlan, if you want to use more slaves then you should use Search ROM command first, or you can use different port pins.


I hope this help You.


Additional to this, you can make PCB identification using some 1-Wire part, such as DS2401 (serial number) and uC check pre-programmed serial with serial on PCB and if data match then device work, in other case nothing.



:wink:
 
Thank you mr. tpetar.

- - - Updated - - -

Can this be used for door entry or other security such as ibutton?
 

Thank you mr. tpetar.

Can this be used for door entry or other security such as ibutton?

I'm glad to help You.

Of course you can use this or similar designs for door entry security. iButton have DS1990 and other for this purpose.

Check 1-wire group, you have simple project with 89C2051 and iButton keys (up to 15 different keys). Check also in the same group and project for iButton clonning.

Also you can use and make various projects on similar idea.


;-)
 
For DS18B20 change

Code:
const unsigned short TEMP_RESOLUTION = 9;

to

Code:
const unsigned short TEMP_RESOLUTION = 12;


Try to make that code to work with both DS18S20 and DS18B20. Use "if" and family code detection "10h" and "28h".

;-)
 
Thank you again.

Codes works, THANKS, THANKS.

This is best site for learning electronics.
 

Polona here is code which support both DS18S20 and DS18B20.

Resolution between 12-bit and 9-bit is automatically adjusts by code, based on device family code (0x28 for DS18B20 and 0x10 for DS18S20).

2x16 LCD screen shots :






Code:
// LCD module connections
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections

//  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
//  18S20: 9  (default setting; can be 9,10,11,or 12)
//  18B20: 12
const unsigned short TEMP_RES_B = 12;
const unsigned short TEMP_RES_S = 9;
unsigned short TEMP_RESOLUTION;

char family_code;
char family_code_hex[2];

char *text = "000.0000";
unsigned temp;
char sernum;
char sernum_hex[8];
int i;
int colona;

void Resolution()
     {
      Ow_Reset(&PORTE, 2);                         // Onewire reset signal
      Ow_Write(&PORTE, 2, 0x33);                   // Issue command Read_ROM
      Delay_us(120);

      family_code = Ow_Read(&PORTE, 2);
      bytetohex(family_code, family_code_hex[2]);
      if (family_code_hex[2] == 0x28) 
         {
         Lcd_Out(2, 1, "     ");
         Lcd_Out(2, 1, "18B20");
         TEMP_RESOLUTION = Temp_Res_B;
         }
      if (family_code_hex[2] == 0x10) 
         {
         Lcd_Out(2, 1, "     ");
         Lcd_Out(2, 1, "18S20");
         TEMP_RESOLUTION = Temp_Res_S;
         }

     }



void Display_Temperature(unsigned int temp2write)
     {
     unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
     char temp_whole;
     unsigned int temp_fraction;

     // Check if temperature is negative
     if (temp2write & 0x8000) 
        {
        text[0] = '-';
        temp2write = ~temp2write + 1;
        }

     // Extract temp_whole
     temp_whole = temp2write >> RES_SHIFT ;

     // Convert temp_whole to characters
     if (temp_whole/100)
        text[0] = temp_whole/100  + 48;
     else
        text[0] = '0';

     text[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
     text[2] =  temp_whole%10     + 48;             // Extract ones digit

     // Extract temp_fraction and convert it to unsigned int
     temp_fraction  = temp2write << (4-RES_SHIFT);
     temp_fraction &= 0x000F;
     temp_fraction *= 625;

     // Convert temp_fraction to characters
     text[4] =  temp_fraction/1000    + 48;         // Extract thousands digit
     text[5] = (temp_fraction/100)%10 + 48;         // Extract hundreds digit
     text[6] = (temp_fraction/10)%10  + 48;         // Extract tens digit
     text[7] =  temp_fraction%10      + 48;         // Extract ones digit

     // Print temperature on LCD
     Lcd_Out(2, 7, text);
     }

void main() {
  ANSELE = 0;                                    // Configure PORTE pins as digital
  TRISE.B2 = 1;                                  // Configure RE2 pin as input

  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  
  // Print degree character, 'C' for Centigrades
  Lcd_Chr(2,15,178);                             // 176 ASCII for degree symbol
  Lcd_Chr(2,16,'C');


  // Main loop
  do {

     Resolution();
  
    //Unique Part Serial Number
    Ow_Reset(&PORTE, 2);                         // Onewire reset signal
    Ow_Write(&PORTE, 2, 0x33);                   // Issue command Read_ROM
    Delay_us(120);

       colona = 17;
       for(i = 0; i <= 7; i++)
          {
            colona = colona - 2;
            sernum = Ow_Read(&PORTE, 2);
            bytetohex(sernum, sernum_hex);
            Lcd_Out(1, colona, sernum_hex);
          }

    // Perform temperature reading
    Ow_Reset(&PORTE, 2);                         // Onewire reset signal
    Ow_Write(&PORTE, 2, 0xCC);                   // Issue command SKIP_ROM
    Ow_Write(&PORTE, 2, 0x44);                   // Issue command CONVERT_T
    Delay_us(120);

    Ow_Reset(&PORTE, 2);
    Ow_Write(&PORTE, 2, 0xCC);                   // Issue command SKIP_ROM
    Ow_Write(&PORTE, 2, 0xBE);                   // Issue command READ_SCRATCHPAD

    temp =  Ow_Read(&PORTE, 2);
    temp = (Ow_Read(&PORTE, 2) << 8) + temp;

    // Format and display result on Lcd
    Display_Temperature(temp);

    Delay_ms(500);
  } while (1);
}



:wink:
 
Last edited:
Thank you very much, you helped me a lots.

- - - Updated - - -

Now I have new project how to use internal eeprom of 18f45k22 to store some data. Can you help me in new thread for this?
 

guys can u help me how to read rtc from ds1994

- - - Updated - - -

guys can u help me how to read rtc from ds1994
 

Hi
Im trying to simulate the second code of both ds18b20 and ds18s20 with ISIS PROTEUS,
but the lcd display always 00,000 C. Im compiling the code with MIKROC PRO and compilation is succeed
any help thanks,
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…