In this post I want to share about my experience working on a simple yet exciting project. We want to implement simple digital thermometer like this:
See? It simple right? It simply consist of 3 main parts just like the above block diagram shown: LM335 temperature sensor, ATMEGA8A microcontroller (running ADC module), and LMB162 LCD for displaying the temperature.
Power Supply:
- Uses 4 Battery AAA 1,5V ( 4 x 1.5V = 6V ), or an adaptor with output > 5V connected to wall outlet.
- Uses L7805 ( 5V voltage regulator ), Micro and the rest of the circuit are powered by 5V output from the output of regulator.
- Uses L7805 ( 5V voltage regulator ), Micro and the rest of the circuit are powered by 5V output from the output of regulator.
Datasheet: L7805 Voltage Regulator (ST Microelectronics).pdf
LM335 Temperature Sensor:
Datasheet: LM335 (Texas Instruments).pdf, LM335 (ST Microelectronics).pdf
Pin diagram (package TO-92):
LM335 Temperature Sensor:
Datasheet: LM335 (Texas Instruments).pdf, LM335 (ST Microelectronics).pdf
Pin diagram (package TO-92):
Required bias current: 450uA < IR < 5mA
LM335 has VOUT = 10 mV/K x T, where T = current absolute temperature, so at room temperature 25°C = 298K, VOUT = 2.98V ( theoretically )
In the datasheet it is specified that at condition T = 25°C, IR = 1mA, VMIN = 2.92 V, VTYPICAL = 2.98 V, VMAX = 3.04 V.
If more precision is needed, then the sensor need calibration ( require a reference temperature, potentiometer and a voltmeter ). The circuit diagram below shows how to perform the calibration:
But, this is just a simple project so I don’t calibrate it, and just left ADJ pin left unconnected.
Now let’s pick R1 = 1 kOhm, then we’re gonna check whether the bias current is still inside the allowable limit, over the range of temperature.
If IR = 450uA then VOUT = 4.8V - 450uA x 1 kOhm = 4.35V ( 4.35V / 10mV/K = 435 K = 162°C )
At 0 K, VOUT = 0V, then IR = (4.8V - 0V) / 1 kOhm = 4.8mA < 5mA ( still met bias current range, acceptable! )
So with this set up, theoretically we can measure temperature from 0K to 435K while the current ranges from 450uA to 4.8mA.
At the first hooke in a supposed to be room temperature, I measured with voltmeter and got VOUT = 3.00V with IR = ~1.8mA ( and it’s theoretically acceptable because 4.8V - 3.00V = 1.8V / 1 kOhm = 1.8mA )
LMB162ABC 2X16 LCD
Datasheet: LMB162ABC (Topway Shenzen).pdf
( the datasheet has put all the details and it’s quite easy to grasp, so I’m not going to repeat all the information again, just some important things )
LMB162 has a working voltage of 5V. It has 3 pin for control operation (RS, RW, EN) and 8 pin for data/command (DB7-DB0). Pin RS: if 1 = transfer data, if 0 = transfer command to LCD. Pin RW: if 1 = read data, if 0 = write data to LCD. Pin EN is for enable, each time we do something either send command, read data, or write data to the LCD, we need to pulse EN pin ( typically 1 ms wide ) then the LCD will take the operation.
Communication with LCD can be done with either 8 bit ( DB7-DB0 ) or 4 bit ( DB7-DB4 ) interface. To reduce the number of micro pin being used for LCD, 4 bit interface is preferred. Each time LCD is powered on or reset, LCD will always set to the default 8 bit interface mode ( page 7 in the datasheet ), therefore we need to change the setting first before performing any subsequent communication. The pin connection from micro to LCD is just like these: PD7-PD4 to DB7 to DB4, PD2 to EN, PD1 to RW, PD0 to RS. We will use command number 6 “Function Set” ( see datasheet ). Set RS = 0, RW = 0, DB7-DB4 = 0010, DB3-DB0 = xxxx ( don’t care, unconnected ). This is accomplished simply by setting PORTD = 0x28 ( PD3 is not used, so whatever value is okay ) then pulse the EN pin by 1 ms. After that command is sent, now the LCD is set to 4 bit interface, then we could set all the other required setting for our application.
My setting can be seen in this piece of code:
LMB162 has 2x16 size of display. The first line is used to display “TEMPERATURE IS:” string. The second line is used to display 2 digit of Celcius, 2 digit of Reamur, and 3 digit of Fahrenheit temperature, e.g: 50°C 40°R 122°F ( all used up 16 character including space at the end )
ATMEGA8A + ADC Module
This project was built using ATMEGA8A microcontroller, but other AVR microcontroller such as ATMEGA8535, ATMEGA328, or ATMEGA16u are pretty similar, hence can be used also, as long as it has ADC module.
This project just need one ADC channel. The conversion result from the ADC is given by:
We have 3 voltage reference options to choose for the ADC: a voltage applied at AREF pin, AVCC with external capacitor at AREF pin, and internal 2.56V voltage reference with external capacitor at AREF pin. Before making a choice, I want to note that it happen to me that sometimes the output of the L7805 voltage regulator isn’t stable enough. Sometimes the output is 4.7V when a battery is used as the source for regulator input, but sometimes its outputting 4.8V when an adaptor is used as a source. This changing level of voltage, even if it's just 0.1V will affect ADC conversion result. To avoid this, I pick internal 2.56V as a voltage reference, because its value is fixed. But choosing this option makes the maximum voltage that can be read from LM335 would only be 2.56V, if a voltage above that value appear on LM335 output, that will make the ADC conversion result which is just 10 bit overflow ( see the conversion result formula ). Let’s say if T = 25°C = 298K, VOUT = 2.98V, then the conversion result from the formula = 2.98V . 1024 / 2.56V = 1192 ( more than 10 bit needed to store this value, therefore overflow! ). To fix this problem, a voltage divider which consist of 2 res 10 kOhm is added to the ouput pin of LM335, so the output got divided by 2 before being sampled by the ADC.
For example, if T = 27°C = 300K, VOUT = 3.00V, then 3.00V / 2 = 1.5V will be sampled by the ADC, the conversion result will be = 1.5V x 1024 / 2.56V = 600.
In the datasheet of ATMEGA8A section 23.4, the ADC successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get a maximum resolution. In this project my ATMEGA uses the default internal RC oscillator 1 MHz as a clock source. To get the required frequency for ADC, a prescaler of 8 is selected (ADPS2:0 = 011), therefore we obtain 1 MHz / 8 = 125 kHz.
Firmware:
The firmware was written in C and compiled with avr-gcc compiler. The program flow diagram below explain how it’s working.
Source code: Firmware_Temperature_Sensor.zip
Schematic and PCB Layout:
Schematic designed with Eagle version 6.3.0 Light version
Temperature_Sensor.sch
PCB manufactured by local manufacturer at Bandung, Indonesia Selc:
I have conducted a test to find out how long this digital thermometer will last. I used 4 brand new AAA 1,5V alkaline battery as a power source, then turned the system on. I left it just like that, and after 1 day 15 hours the LCD display got dimmed and start showing wrong temperature, then I turned it off. We can do an improvement to make the battery last longer, one obvious thing is the LCD backlight can be turned off during operation ( but it just that blue colour from the LCD display is so elegant that I don’t want to turn it off ). Second, just decrease the rate of the ADC taking the sample. In the firmware, the ADC do the sampling every 60 second, this number can be changed to conserve more power, ( e.g. took sampling every 2-3 minutes is okay and acceptable, environment temperature shouldn’t change that fast ).
Firmware:
The firmware was written in C and compiled with avr-gcc compiler. The program flow diagram below explain how it’s working.
Source code: Firmware_Temperature_Sensor.zip
Schematic and PCB Layout:
Schematic designed with Eagle version 6.3.0 Light version
Temperature_Sensor.sch
PCB manufactured by local manufacturer at Bandung, Indonesia Selc: