Thermometer, thermostat with Temperature - 0.1°C, range of supported temperatures of - 55 to +125 °C by Peter
This
thermometer-thermostat allows you to measure and maintain a temperature of -55
° C to +125 ° C, with an accuracy of 0.1 ° C. It is built on a microcontroller
ATmega8, digital temperature sensor DS18B20 and character display, on the basis
of the controller HD44780, containing 2 lines of 16 characters each. Originally
it was designed to manage the incubator, but after some changes in the program
the microcontroller, the range of supported temperatures was significantly
expanded.
In
standard mode, the screen displays the current temperature, which is updated
every second. Pressing the button SB1, supported by a temperature controller displays
the temperature on the bottom line display. Long-term, continuous press of the
button SB2 (the data of seconds specified in the constant
"Button_mode_time", by default - 4 seconds) will transfer the unit to
service mode, you can set a new value of the temperature. In this mode, the
button SB1 increases the value of the temperature, and the SB2 - decreases. Long
press (time in seconds, depending on the number of constant Button_force_time)
on one of these buttons lead to a rapid change in temperature. Writing a new
value of the temperature will automatically after a certain period of time specified
in the constant "Thermo_mode_save_time" (by default - 8 seconds) if
no button is pressed.
The
thermostat can operate on heating (eg, in an incubator) and cooling (eg, in the
refrigerator). The mode is selected by using the constant "Thermostat_type".
As originally developed the device to maintain the temperature in the incubator
and the reliability was very important, then it has been added sound
notification or absence of fault (or broken wire) sensor. If you repeatedly
fail to read data from the sensor DS18B20, then from the speaker you hear an
alarm. If necessary, disable this option easily, by writing to the constant
"Error_sound_state" number not equal to one. The same speaker is used
for scoring buttons. If that does not require a constant
"Button_beep_state" need not record the number of 1.
Source code:
'*****************************************************************************
'** Thermometer, thermostat with Temperature - 0.1°C **
'** The range of supported temperatures of - 55 to +125 °C **
'** Compiler - BASCOM v 2.0.1.0; Ńontroller - ATmega8; Sensor - DS18B20 **
'** Author - Peter 24.11.2010ă. **
'*****************************************************************************
$regfile = "m8def.dat" ' ATmega8
$crystal = 4000000 ' 4 ĚĂö
$hwstack = 80
$swstack = 80
$framesize = 80
Declare Sub Mk_init()
Declare Sub Selectmode()
Declare Sub Thermo_lcd(thermo As Integer)
Declare Sub Thermocontrol(thermo As Integer , Thermosetting As Integer)
Declare Sub Modify_setting_button()
Declare Sub Modify_setting_lcd(thermo As Integer)
Declare Function Read_thermo(thermo As Byte) As Byte
1wire_pin Alias Portd.0 ' The output for the sensor DS18B20.
Button_plus Alias Pind.1 ' Button "+ / current temperature".
Button_minus Alias Pind.2 ' Button "- / settings".
Led_read_1wire Alias Portc.0 ' The output for the LED blinks when data is read from the sensor DS18B20.
Out_thermostat Alias Portc.1 ' Output the thermostat. It connects the load.
Sreaker Alias Portc.2 ' Output to the speaker.
Const Button_delay = 24
Const Button_force_delay = 200 ' The delay in milliseconds. change in long-term retention of digits in service mode buttons.
Const Thermostat_type = 0 ' 0 - thermostat operates in heating, 1 - Cooling.
Const Error_sound_state = 1 ' 1 - beep if an error occurs reading data from the sensor DS18B20.
Const Button_force_time = 2 ' Time in seconds after which to begin a rapid change in the current setting temperature.
Const Thermo_mode_save_time = 8 ' Âđĺě˙ â ńĺęóíäŕő, ďî ďđîřĺńňâčţ ęîňîđîăî, áóäóň çŕďčńŕíű äŕííűĺ î ňĺęóůĺé ňĺěďĺđŕňóđĺ, ĺńëč íĺ íŕćčěŕëŕńü íč îäíŕ ęíîďęŕ.
Const Button_beep_state = 1 ' 1 - îçâó÷čâŕňü ęëŕâčŕňóđó
Const Button_mode_time = 4 ' Time in seconds, after which will be recorded in the EEPROM data on the current temperature, if not clicked no button.
Dim Flaginputtermo As Byte ' 1 - the need to poll the sensor DS18B20.
Dim Thermo_mode_state As Byte ' The auxiliary variable used in the translation unit in setting mode.
Dim Button_plus_state As Byte ' The auxiliary variable used in determining when press / release the "+ / current temperature" in service mode.
Dim Button_minus_state As Byte ' The auxiliary variable used in determining when press / release button "- / settings" in the mode.
Dim Button_force_counter As Byte ' Time counter (seconds), after which begins a rapid change in temperature in the installed mode.
Dim Temp_1wirearray(9) As Byte ' In this array of data from the sensor is placed DS18B20
Dim 1wire_array(9) As Byte ' and if no errors, then the data is copied into the array.
Dim Error_thermo_counter As Byte ' Error counter reading from the sensor DS18B20.
Dim Thermo_mode As Byte ' Working hours: 0 - normal operation, 1 - preparing for the transition to a service mode 2 - mode settings.
Dim Thermo_mode_counter As Byte ' Counter counting down the time (in seconds) required to switch to the settings.
Dim Thermo_mode_save_counter As Byte ' Counter, after which the settings will be saved in EEPROM.
Dim Currenttermo As Integer At 1wire_array Overlay ' Current temperature.
Dim Thermo_setting As Integer ' Supported by the thermostat temperature.
Dim Modify_thermo_setting As Integer ' Time value maintained by the thermostat temperature to be used in service mode.
Dim Ee_thermosetting As Eram Integer ' Memory location in EEPROM, which stores the current temperature is maintained.
Config Lcd = 16 * 2 ' Display 2 lines of 16 characters.
Config Lcdbus = 4
Config Lcdmode = Port
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , Rs = Portb.4 , E = Portb.5
Config 1wire = 1wire_pin ' The configuration pin of the temperature sensor DS18B20.
Config Led_read_1wire = Output ' The configuration pin output for the LED blinks when data is read from the sensor.
Config Out_thermostat = Output ' The configuration pin for the thermostat output.
Config Sreaker = Output ' The configuration pin for output to speaker, the sender of an emergency.
Config Button_plus = Input ' The configuration pin for the "+ / current temperature".
Config Button_minus = Input ' Configuration pin for a button "- / settings".
Config Timer1 = Timer , Prescale = 64 ' The configuration of the timer Timer1.
On Timer1 Timer1_interrupts
Stop Timer1
Config Watchdog = 2048 ' The configuration of the watchdog response time of about 2 seconds.
Call Mk_init()
Enable Interrupts ' Enable all interrupts.
'************************** Main ***********************************************
Do
Reset Watchdog ' Reset watchdog.
If Flaginputtermo = 1 Then ' Needs to read data from the sensor DS18B20.
Flaginputtermo = 0
If Read_thermo(1wire_array(1)) = 1 Then ' Successful reading of data from the sensor DS18B20.
If Thermo_mode = 0 Then
Call Thermo_lcd(currenttermo) ' The output of the current temperature display.
End If
Call Thermocontrol(currenttermo , Thermo_setting) ' Comparison of current and set temperature and load management.
Error_thermo_counter = 0 ' Reset error counter is read from the sensor DS18B20.
Else ' An error occurred while reading data from the sensor.
If Error_thermo_counter >= 2 Then
#if Error_sound_state = 1
Sound Sreaker , 2000 , 80 ' Alarm.
Sreaker = 0
#endif
Sreaker = 0
Error_thermo_counter = 0
Cls : Lcd "Sensor error!"
Thermo_mode = 0
Else
Incr Error_thermo_counter ' If an error occurred reading from DS18B20, but do not exceed the allowable threshold of errors - errors increase the value of the counter.
End If
End If
End If
Call Selectmode() ' Poll button and switch modes.
If Thermo_mode = 2 Then ' Settings mode.
Call Modify_setting_button()
End If
Loop
End
' ***************************** Interrupts *************************************
' Interrupt Timer1 (interrupt occurs approximately once per second).
Timer1_interrupts:
Flaginputtermo = 1 ' Necessary to interrogate the sensor DS18B20.
If Thermo_mode = 0 And Thermo_mode_state = 1 Then ' Button is pressed and held the entrance to the settings.
If Thermo_mode_counter < 200 Then Incr Thermo_mode_counter ' Counting the time interval required to enter settings.
Elseif Thermo_mode = 2 Then ' Active mode settings.
If Thermo_mode_save_counter < 200 Then Incr Thermo_mode_save_counter ' Counter time before saving settings.
If Button_force_counter < 200 Then Incr Button_force_counter ' Counter times out quickly change the desired temperature for prolonged holding down the button.
End If
Return
' **************************** Subroutine **************************************
' Initialization program.
Sub Mk_init()
Out_thermostat = 0
Sreaker = 0
Error_thermo_counter = 0
Thermo_mode = 0
Thermo_mode_state = 0
Thermo_mode_counter = 0
Thermo_mode_save_counter = 0
Thermo_setting = Ee_thermosetting ' Reading a given temperature from EEPROM memory.
Cursor Off
Deflcdchar 1 , 228 , 234 , 228 , 224 , 224 , 224 , 224 , 224 ' Symbol "°"
Cls
Lcd "Thermostat v 1.2"
Lowerline
'Lcd "BASCOM v 2.0.1.0"
Lcd "Lev-hik@yandex.ru"
If Thermo_setting < -880 Or Thermo_setting > 2000 Then ' These temperatures are not supported.
#if Error_sound_state = 1
Sound Sreaker , 2000 , 80 ' Alarm.
Sreaker = 0
#endif
Cls
Lcd "Error EEPROM"
Thermo_setting = 0 ' Set of the temperature of 0 ° C.
Ee_thermosetting = Thermo_setting ' Save the data in the EEPROM.
End If
1wreset ' Reset sensor.
1wwrite &HCC ' Command "Skip ROM".
1wwrite &H44 ' Command "Convert T"
Wait 2
Shiftlcd Left
Wait 1
Timer1 = 0
Flaginputtermo = 0
Enable Timer1
Start Timer1
Start Watchdog
End Sub
' Subroutine mode selection.
Sub Selectmode()
If Thermo_mode = 0 Then ' Standard mode.
If Button_minus = 0 Then
#if Button_beep_state = 1
If Button_minus_state = 0 Then
Waitms Button_delay
If Button_minus = 0 Then
Button_minus_state = 1
Sound Sreaker , 80 , 400
Sreaker = 0
Else
Button_minus_state = 0
End If
End If
#endif
If Thermo_mode_state = 0 Then
Thermo_mode_counter = 0
Thermo_mode_state = 1
Else
If Thermo_mode_counter >= Button_mode_time Then Thermo_mode = 1 ' Long-term (defined in a constant Button_mode_time) holding down button "- / settings" - preparing to move into the service mode.
End If
Else
Thermo_mode_counter = 0
Thermo_mode_state = 0
Button_minus_state = 0
End If
Else ' Mode settings.
If Thermo_mode_state = 1 Then
Thermo_mode_counter = 0
Thermo_mode_state = 0
Cls
Lcd Spc(4) ; "Setting"
End If
If Thermo_mode = 1 Then ' Preparing to move into the service mode (standby button is released "- / settings").
If Button_minus = 1 Then
Waitms Button_delay
If Button_minus = 1 Then
Thermo_mode = 2 ' Button "- / settings" is released - go to service mode.
Modify_thermo_setting = Thermo_setting
Thermo_mode_save_counter = 0
Button_plus_state = 0
Button_minus_state = 0
Call Modify_setting_lcd(modify_thermo_setting)
End If
End If
Elseif Thermo_mode > 2 Then ' BUG!
Thermo_mode = 0
Thermo_mode_counter = 0
Thermo_mode_state = 0
Button_plus_state = 0
Button_minus_state = 0
End If
End If
End Sub
' Subroutine service keys in selection of the temperature.
Sub Modify_setting_button()
Local Temp_shift As Byte
Local Temp_1 As Byte
If Button_plus = 0 And Button_minus = 1 Then ' Press "+ / current temperature".
Waitms Button_delay
If Button_plus = 0 Then
Thermo_mode_save_counter = 0
If Button_force_counter >= Button_force_time Then
If Modify_thermo_setting < 1980 Then
Modify_thermo_setting = Modify_thermo_setting + 16
Call Modify_setting_lcd(modify_thermo_setting)
Waitms Button_force_delay
End If
Else
If Button_plus_state = 0 Then
Button_plus_state = 1
#if Button_beep_state = 1
Sound Sreaker , 80 , 400
Sreaker = 0
#endif
If Modify_thermo_setting < 2000 Then ' + 125°C
Temp_shift = Modify_thermo_setting And 15
Temp_1 = Lookup(temp_shift , Button_modify_label)
Modify_thermo_setting = Modify_thermo_setting + Temp_1
Call Modify_setting_lcd(modify_thermo_setting)
End If
End If
End If
Else
Button_plus_state = 0
End If
Elseif Button_minus = 0 And Button_plus = 1 Then ' Button is pressed "- / settings".
Waitms Button_delay
If Button_minus = 0 Then
Thermo_mode_save_counter = 0
If Button_force_counter >= Button_force_time Then
If Modify_thermo_setting > -860 Then
Modify_thermo_setting = Modify_thermo_setting - 16
Call Modify_setting_lcd(modify_thermo_setting)
Waitms Button_force_delay
End If
Else
If Button_minus_state = 0 Then
Button_minus_state = 1
#if Button_beep_state = 1
Sound Sreaker , 80 , 400
Sreaker = 0
#endif
If Modify_thermo_setting > -880 Then ' - 55°C
Temp_shift = Modify_thermo_setting And 15
Temp_1 = Lookup(temp_shift , Button_modify_label)
Modify_thermo_setting = Modify_thermo_setting - Temp_1
Call Modify_setting_lcd(modify_thermo_setting)
End If
End If
End If
Else
Button_minus_state = 0
End If
Else ' The buttons are not pressed or pressed just two.
Button_plus_state = 0
Button_minus_state = 0
Button_force_counter = 0
End If
If Thermo_mode_save_counter >= Thermo_mode_save_time Then ' If the button is never pressed for a preset constant Thermo_mode_save_Time number of seconds, save the settings and exit to standart mode.
If Modify_thermo_setting <> Thermo_setting Then ' If supported by the temperature change
Ee_thermosetting = Modify_thermo_setting ' save the settings in the EEPROM.
Thermo_setting = Modify_thermo_setting
End If
Thermo_mode_save_counter = 0
Thermo_mode = 0
Thermo_mode_counter = 0
Thermo_mode_state = 0
Button_plus_state = 0
Button_minus_state = 0
End If
End Sub
' Subroutine LCD display data on the selection mode of the temperature.
Sub Modify_setting_lcd(thermo As Integer)
Local Lcd_out As Single
Lcd_out = Thermo / 16
Cls
Lcd Spc(4) ; "Setting"
Lowerline
Lcd "set t" ; Chr(1) ; ": " ; Fusing(lcd_out , "#.#") ; Chr(1) ; "C"
End Sub
' Data output on the display.
Sub Thermo_lcd(thermo As Integer)
Local Lcd_out As Single
Cls
Lcd_out = Thermo / 16
Lcd "Thermo: " ; Fusing(lcd_out , "#.#") ; Chr(1) ; "C"
If Button_plus = 0 Then
Waitms Button_delay
If Button_plus = 0 Then
Lcd_out = Thermo_setting / 16
Lowerline
Lcd "set t" ; Chr(1) ; ": " ; Fusing(lcd_out , "#.#") ; Chr(1) ; "C"
#if Button_beep_state = 1
If Button_plus_state = 0 Then
Button_plus_state = 1
Sound Sreaker , 80 , 400
Sreaker = 0
End If
#endif
Else
Button_plus_state = 0
End If
Else
Button_plus_state = 0
End If
End Sub
' Temperature control for load management.
Sub Thermocontrol(thermo As Integer , Thermosetting As Integer)
If Thermo <= Thermosetting Then
#if Thermostat_type = 0
Out_thermostat = 1
#else
Out_thermostat = 0
#endif
Else
#if Thermostat_type = 0
Out_thermostat = 0
#else
Out_thermostat = 1
#endif
End If
End Sub
' ***************************** Function ***************************************
' Reading data from a temperature sensor.
Function Read_thermo(thermo As Byte) As Byte
Local Temp As Byte
Temp = 0 ' Set tag read errors.
Disable Interrupts
Led_read_1wire = 1
1wreset ' Reset sensor.
If Err = 0 Then
1wwrite &HCC ' Command "Skip ROM"
1wwrite &HBE ' Command "Read Scratchpad".
Temp_1wirearray(1) = 1wread(9) ' ×ňĺíčĺ äŕííűő ń äŕň÷čęŕ.
1wreset ' Reset sensor.
1wwrite &HCC ' Command "Skip ROM".
1wwrite &H44 ' Command "Convert T"
If Temp_1wirearray(9) = Crc8(temp_1wirearray(1) , 8) Then ' Checksum.
For Temp = 1 To 8
Thermo(temp) = Temp_1wirearray(temp)
Next Temp
Temp = 1 ' Reset tag read errors.
Led_read_1wire = 0
End If
End If
Enable Interrupts
Read_thermo = Temp
End Function
' ******************************* Data ***************************************
Button_modify_label:
Data 2 , 1 , 1 , 2 , 1 , 2 , 1 , 1 , 2 , 1 , 1 , 2 , 1 , 2 , 1 , 1
|