In this Lesson, we will make a digital temperature meter using DS18B20. The connection between temperature sensor and microcontroller will be done through a single wire. This is advantage of the temperature sensor model. The temperature value will be displayed on 4 digits-with 7 segment, in multiplexed mod of course.
PORTB will be used for character (RB0=a, RB1=b...RB6=g, RB7=dp) and for digits RA0 = digit1...RA3 = digit4. Data wire from DS18B20 is conected to RA4.
Pull-up resistor (with a value of 4.7 k), is required to perform communication between the sensor and microcontroller.
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.14:
' Digital thermometer with DS18B20 and 7- Segments.
' Done by:
' Aureliu Raducu Macovei, 2010.
' Description:
' In this experiment we will work with one-wire communication.
' The thermal sensor used is "DS18B20" and measured value is displayed
' on the 7-segment digits. PORTB will be used for character
' (RB0=a,RB1=b...RB6=g,RB7=dp)and for digits RA0=digit1...RA3=digit4.
' Data wire from DS18B20 is conected to RA4.
' 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
'*******************************************************************************
*/
unsigned short i, DD0=0x40, DD1=0x40,DD2=0x40, DD3 =0x61, N_Flag;
unsigned temp_value=0; // Variable to store temperature register value
unsigned short mask(unsigned short num) // Mask for 7 segment common cathode;
{
switch (num)
{
case 0 : return 0x3F; // 0;
case 1 : return 0x06; // 1;
case 2 : return 0x5B; // 2;
case 3 : return 0x4F; // 3;
case 4 : return 0x66; // 4;
case 5 : return 0x6D; // 5;
case 6 : return 0x7D; // 6;
case 7 : return 0x07; // 7;
case 8 : return 0x7F; // 8;
case 9 : return 0x6F; // 9;
case 10 : return 0x40; // Symbol '-'
case 11 : return 0x61; // Symbol C
case 12 : return 0x00; // Blank
} //case end
}
void display_temp(short DD0, short DD1, short DD2, short DD3)
{
for (i = 0; i<=4; i++)
{
PORTB = DD3;
RA0_bit = 1; // Select C Digit;
RA1_bit = 0;
RA2_bit = 0;
RA3_bit = 0;
delay_ms(2);
PORTB = DD0;
RA0_bit = 0;
RA1_bit = 1; // Select Ones Digit;
RA2_bit = 0;
RA3_bit = 0;
delay_ms(2);
PORTB = DD1;
RA0_bit = 0;
RA1_bit = 0;
RA2_bit = 1; // Select Tens Digit;
RA3_bit = 0;
delay_ms(2);
PORTB = DD2;
RA0_bit = 0;
RA1_bit = 0;
RA2_bit = 0 ;
RA3_bit = 1; // Select +/- Digit;
delay_ms(2);
}return;
}
void DS18B20() //Perform temperature reading
{
Display_temp(DD0, DD1, DD2, DD3);
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, DD3);
Ow_Reset(&PORTA, 4);
Ow_Write(&PORTA, 4, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTA, 4, 0xBE); // Issue command READ_SCRATCHPAD
Display_temp(DD0, DD1, DD2, DD3);
// Next Read Temperature
temp_value = Ow_Read(&PORTA, 4); // Read Byte 0 from Scratchpad
temp_value = (Ow_Read(&PORTA, 4) << 8) + temp_value; // Then read Byte 1 from
// Scratchpad and shift
// 8 bit left and add the Byte 0
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 >> 4 ; //<<< // 1 for DS1820 and
// 4 for DS18B20;
}
void main()
{
CMCON |= 7; // Disable Comparators
TRISB = 0; // Set PORTB direction to be output
PORTB = 0; // Turn OFF LEDs on PORTB
PORTA = 0;
TRISA0_bit = 0; // RA.0 to RA3 Output
TRISA1_bit = 0;
TRISA2_bit = 0;
TRISA3_bit = 0;
do { //--- main loop
N_Flag = 0; // Reset Temp Flag
DS18B20();
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
if (N_Flag == 1) DD2=0x0A; // DD2 10 ??
else if (DD2 == 0) DD2 = 0x0D; // DD2 13 ??
DD2 = mask(DD2);
display_temp(DD0, DD1, DD2, DD3); // Infinite loop;
} while (1);
}
it show -000c using ISIS pro
ReplyDeleteMay i add a few comments on your code?
ReplyDelete- Why not set your DS18X20 to 9 bit mode since you dont use the high resolution ?
- When you do a convertT command you need to wait 750ms(in 12bit mode)
before reading the scratchpad otherwise you are reading the previous
measurement.
- I cant tell from the video but do you notice any flicker on the 7 segment because
of stopping multiplex when you read 18x20 and calculate?
Hope this helps and keep up the good work,dd
work at negative temperatures??
ReplyDeleteLove tthis
ReplyDelete