Menu

all about electronic and microcontrollers

Tuesday, November 30, 2010

Lesson nr.18-DS18X20 using 1-Wire Protocol & LCD

Hardware setup:
In this experiment we will work with temperature sensor DS18B20, but this time results will be displayed on 2x16 LCD.
Communication with LCD will be performed through 4-bits and connections is made as follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3, RS with RB4 and EN with RB5.
Data pin of DS18B20 is connected to PORT RA1 and we also use pull-up resistors (4k7 ohm), for the communication with temperature sensor to be performed.
The range value wich can be measured, is between -55 and +128 Celsius degree.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.18:
'          DS18X20 using 1-Wire Protocol & LCD.
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with temperature sensor DS18B20 and LCD.
'          Communication with LCD will be performed through 4-bits and connections
'          is made as follows: D4 with RB0, D5 with RB1, D6 with RB2, D7 with RB3;
'                              RS with RB4 and EN with RB5.
'          Data pin of DS18B20 is connected to PORT RA1 and we also use pull-up 
'          resistors (4k7 ohm).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_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 = 12;

char *text = "000.0";
unsigned temp;

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

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

  // Extract temp_whole
  temp_whole = temp2write >> RES_SHIFT ;

  // Convert temp_whole to characters
  if (!isNegative){
  if (temp_whole/100)
  text[0] = temp_whole/100  + 48;
  else
  text[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
  
  // Print temperature on LCD
  Lcd_Out(2, 5, text);
}
  // Custom character for simbol " * " (degrees).
const char character[] = {4,10,4,0,0,0,0,0};
void CustomChar(char pos_row, char pos_char) 
{
 char i;
 Lcd_Cmd(64);
 for (i = 0; i<=7; i++) Lcd_Chr_CP(character[i]);
 Lcd_Cmd(_LCD_RETURN_HOME);
 Lcd_Chr(pos_row, pos_char, 0);
 }

void main()                                      // Main;
{
 CMCON |=7;                                      // Disable Comparators;
 Lcd_Init();                                     // Initialize LCD;
 Lcd_Cmd(_LCD_CLEAR);                            // Clear LCD;
 Lcd_Cmd(_LCD_CURSOR_OFF);                       // Turn cursor off;
 Lcd_Out(1, 3, "Temperature:");                  // Show message to LCD on line 1 from
                                                 // column 3;
 // Print degree character, 'C' for Centigrades
 CustomChar(2,10);                               // Display custom character (degree)
                                                 // on line 2 and column 10.

 Lcd_Chr(2,11,'C');                              // Show message to LCD on line 2 from
                                                 // column 11;

 //--- Main loop
 do 
 {
  //--- Perform temperature reading
  Ow_Reset(&PORTA, 1);                           // Onewire reset signal;
  Ow_Write(&PORTA, 1, 0xCC);                     // Issue command SKIP_ROM;
  Ow_Write(&PORTA, 1, 0x44);                     // Issue command CONVERT_T;
  Delay_us(700);                                 // delay 0,7s (required for signal
                                                 // processing);

  Ow_Reset(&PORTA, 1);                           // Onewire reset signal;
  Ow_Write(&PORTA, 1, 0xCC);                     // Issue command SKIP_ROM;
  Ow_Write(&PORTA, 1, 0xBE);                     // Issue command READ_SCRATCHPAD;

  temp = Ow_Read(&PORTA, 1);                     // Next Read Temperature, read Byte
                                                 // 0 from Scratchpad;
  temp = (Ow_Read(&PORTA, 1) << 8) + temp;       // Then read Byte 1 from Scratchpad
                                                 // and shift 8 bit left and add the Byte 0;

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

  Delay_ms(400);                                 // 0,4s delay required to finish the process;
  } while (1);                                   // infinite loop;
}                                                // End.

7 comments:

  1. te rog sa imi trimiti si mie hexul pentru acesta schema! Multumesc mult !
    mirceacra@gmail.com

    ReplyDelete
  2. same with 7 segment still displays -000c on LCD using ISIS pro

    ReplyDelete
    Replies
    1. Proteus ISIS makes these kind of error in simulation mode. In reality it works very well.

      Delete
  3. hi.
    How to put two or three temperatures simultaneously.

    ReplyDelete
    Replies
    1. You mean the same line of data?
      We must modify the 1-wire library on mikroc. It's more complicated but not impossible. The easiest way is to use different input ports for each 1-wire sensor

      Delete
  4. Am realizat acest termometru si functioneaza foarte bine. Sunt novice in domeniu, dar imi puteti explica cum pot conecta doi senzori, la doua porturi diferite? Am vreo doua saptamani de cand ma straduiesc si nu reusesc sa-i citesc pe amandoi. Multumesc!

    ReplyDelete

If you do not understand something, or if you make some aplication helped by this blog, let me know.