Problems with Microcontroller Projects? You may face many Problems, but do not worry we are ready to solve your Problems. All you need to do is just leave your Comments. We will assure you that you will find a solution to your project along with future tips. On Request we will Mail you the Codes for Registered Members of this site only, at free service...Follow Me.

PIC16F628A + DS1820 + 4-Digit Seven Segment C/F Thermometer

Introduction
This project describes how to read temperature from a DS1820 sensor with a PIC16F628A microcontroller and display the temperature value in a multiplexed 4-digit seven segment display. The temperature will be displayed in both Centigrade and Fahrenheit units switching back and forth. The temperature resolution is 1 degree in both the units. Out of 4-digits, the most significant three digits will display numeric temperature values from 00 to 125. The most significant digit will show '-' for negative temperatures, and the least significant digit will display C or F.

On my PIC16F628A board, connect D1 to RA2, D2 to RA1, D3 to RA0, and D4 to RA3. DS1820 data will be read at RA4 port. The seven segments a-g will be driven by RB0-RB6.

Software

/* Project name:
     Seven-segment display digital thermometer
 * Copyright:
     (c) Rajendra Bhatt, 2010.
      MCU:             PIC16F628A
     Oscillator:      XT, 4.0 MHz
*/

// Temperature digits
unsigned short i, DD0=0x3f, DD1=0x3f,DD2=0x3f, CF_Flag=0xff, CF=0x3f, N_Flag;
// CF_Flag = 0: F, 1: C
// Variable to store temperature register value
unsigned temp_value=0, temp_whole;
unsigned int temp_fraction=0;
float temp_F;

//-------------- Function to Return mask for common cathode 7-seg. display
unsigned short mask(unsigned short num) {
  switch (num) {
    case 0 : return 0x3F;
    case 1 : return 0x06;
    case 2 : return 0x5B;
    case 3 : return 0x4F;
    case 4 : return 0x66;
    case 5 : return 0x6D;
    case 6 : return 0x7D;
    case 7 : return 0x07;
    case 8 : return 0x7F;
    case 9 : return 0x6F;
    case 10 : return 0x40;  // Symbol '-'
    case 11 : return 0x39;   // Symbol C
    case 12 : return 0x71;   // Symbol F
    case 13 : return 0x00;  // Blank
  } //case end
}

void display_temp(short DD0, short DD1, short DD2, short CF)    {
    for (i = 0; i<=200; i++) {
      PORTB = DD0;
      RA0_bit = 1;          // Select Ones Digit
      RA1_bit = 0;
      RA2_bit = 0;
      RA3_bit = 0;
      delay_ms(5);
      PORTB = DD1;
      RA0_bit = 0;
      RA1_bit = 1;        // Select Tens Digit
      RA2_bit = 0;
      RA3_bit = 0;
      delay_ms(5);
      PORTB = DD2;
      RA0_bit = 0;
      RA1_bit = 0;
      RA2_bit = 1;        // Select +/- Digit
      RA3_bit = 0;
      delay_ms(5);
      PORTB = CF;
      RA0_bit = 0;
      RA1_bit = 0;
      RA2_bit = 0 ;
      RA3_bit = 1;        // Select CF Digit
      delay_ms(5);
        }
     return;
}


void main() {
  CMCON  |= 7;      // Disable Comparators
  TRISB = 0x00;    // Set PORTB direction to be output
  PORTB = 0x00;    // Turn OFF LEDs on PORTB
  TRISA0_bit = 0;  // RA.0 to RA3 Output
  TRISA1_bit = 0;
  TRISA2_bit = 0;
  TRISA3_bit = 0;


    //--- main loop
  do {

    N_Flag = 0;  // Reset Temp Flag
    //--- perform temperature reading
    Ow_Reset(&PORTA, 4);      // Onewire reset signal
    Ow_Write(&PORTA, 4, 0xCC);   // Issue command SKIP_ROM
    Ow_Write(&PORTA, 4, 0x44);   // Issue command CONVERT_T
    display_temp(DD0, DD1, DD2,CF)   ;
    Ow_Reset(&PORTA, 4);
    Ow_Write(&PORTA, 4, 0xCC);    // Issue command SKIP_ROM
    Ow_Write(&PORTA, 4, 0xBE);    // Issue command READ_SCRATCHPAD

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

    if (temp_value & 0x8000) {
     temp_value = ~temp_value + 1;
     N_Flag = 1;   // Temp is -ive
     }
    if (temp_value & 0x0001) temp_value += 1;   // 0.5 round to 1
    temp_value = temp_value >> 1 ;
    if (CF_Flag == 0) {
     if (N_Flag ==1) {
      temp_F = (32.0-9.0*temp_value/5.0)*10 + 6;
      if (temp_F < 0){
         N_Flag=1;
         temp_value = abs(temp_value);
         }
         else N_Flag = 0;
      }
    else temp_F = (9.0*temp_value/5.0+32.0)*10 + 6; //If decimal is greater or equal
                                             // to 0.5, add 0.5
    temp_value = temp_F/10;
    CF = 12;
    }

    if (CF_Flag == 0xff) CF = 11;

    DD0 = temp_value%10;  // Extract Ones Digit
    DD0 = mask(DD0);
    DD1 = (temp_value/10)%10; // Extract Tens Digit
    DD1 = mask(DD1);
    DD2 =  temp_value/100; // Extract Hundred digit
    CF = mask(CF);
    if (N_Flag == 1) DD2=10;
    else if (DD2 == 0) DD2 = 13 ;
    DD2 = mask(DD2) ;

      PORTB=0x00;
      CF_Flag =~CF_Flag;

    } while (1);
}



Output Pictures




Over 99F temperature reading (touched the sensor with a hot soldering iron )

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...

Recent Comments

Popular Projects

Give Support

Give Support
Encourage Me through Comments

Microcontroller Projects

Total Pageviews