PIC Projects

Driving LCD directly from PIC

This project is one another thermometer application that uses the TCN75A digital sensor from Microchip. The sensor provides digital temp conversion in the range -40°C - 125°C (-40°F - 257°F) and has maximum resolution 0.0625°C. However, the LCD that I used (2.5 digits model LCD-S2X1C50TR manufactured by Lumex) only works reliably in the temperature range 0 - 50°C, so the code is adjusted for this range only. The temperature is displayed in degrees of Fahrenheit.

This note describes the approach and software. Check here for practical implementation of these ideas.

Also check here for a really low-power thermometer.

Hardware

The schematic can be easily obtained from the image below. The LCD is a passive device and has no built-in controller. The used microcontroller PIC16F913 has a built-in LCD module that is able to generate all necessary waveforms for driving LCDs with up to 16 segments (plus up to four backplanes). The above mentioned LCD assumes a simple static mode that requires only one BIAS voltage of 5V and, hence, has just one backplane. The LCD has 16 pins, out of which 2·7 = 14 are used for two 7-segment digits, one is for the leftmost 1/2-digit (can only be 1, its both segments are connected together internally) and one is for the backplane (the remaining pin RC5/SEG10 is not used for LCD in my design). This way 16 out of 25 I/O pins are reserved for driving LCD and two more pins are used for communicating with the temp sensor that implements the I2C interface. The PIC has this interface also implemented in hardware. However, unfortunately this block cannot be used along with the LCD driver, since they share the same I/O pins. Driving the LCD is a more important function for me, while a small subset of the I2C interface needed to communicate with the sensor can be easily implemented in software. The unused for the thermometer I/O pins RA2, RA6, RA7, BR5, and RC5 are configured for output to minimize the power consumption. The input only pin RE3 is used here for programming. Hence, there is a good number of free pins available for other applications of this PIC which involve LCD.

Prototype Layout

The sensor is connected to the PIC via pins RC0/VLCD1 and RC1/VLCD2. Normally, these pins are used for the LCD BIAS voltages in a non-static mode. However, it turns out that they are just normal I/O pins in the LCD static mode, which is not clear from the documentation and discovered experimentally. The 5-pin connector in the left bottom corner of the image is intended for PIC programming by using the ICSP (In-Circuit Serial Programming) mode and goes to my Brenner8 USB programmer during programming only. The components on the right part of the image around MAX756 chip belong to the DC-DC converter that delivers 5V voltage from a single 1.5V battery. The TCN75A sensor is put on a small PCB for a convenience. The two pulling-up resistors of the I2C bus are 5.6K each.

Software

The code starts with four subroutines used for LCD 7-segment codes. The pin assignment between the LCD and PIC is based on a convenient PCB layout (this part of the project is not completed yet). This lead to the situation that both LCD digits are driven from different parts of the PIC LCD Data registers, so four 7-segment codes are needed to update the LCD digit-by-digit. All variables used in the code are placed in the shared area of all banks, thus minimizing the switching between them. This way the banks are only switched to access the SFRs when it is inavoidable. A major part of the initialization is for setting up the LCD module. To save power and extend battery life the PIC is put into a sleep mode. The PIC's watchdog timer awakes the PIC every 8 seconds (approx.) to start a new temp measurement. The PIC is driven from the internal 31kHz oscillator, which is also used for the LCD module and watchdog timer. The main loop of the code works at each PIC awake from sleep and the performed tasks alternate between sending to the sensor a request for a new temp conversion (which typically takes 250 msec) and reading the temp digital data from sensor. The thermometer is intended for an indoor usage where the temperature normally does not fluctuate very fast. The display is updated every 16 seconds which is quite appropriate.

After reading a new temp from sensor, it is compared with the old one saved after the previous reading. If those values match (which happens most of the time in a leaving room) the PIC is put back on sleep till the next watchdog event. Otherwise, the new temp is converted into Fahrenheit scale (the sensor reading are in degrees Celsius) and the LCD registers are updated accordingly. This is done to minimize the computations and this way keep the PIC in sleep as much as possible. The sensor is requested to perform a temperature conversion with 4 binary bits for the fraction (resolution 0.0625°C) which is beneficial for the accuracy, but only two most significant fraction bits are used for display (we have only 2.5 decimal digits there). This way the temperature in the working range 0 - 63.75°C with 0.25°C resolution takes just one byte to encode, providing 256 different values for the input. To convert the input temperature (stored internally in variable tempC) into Fahrenheit and further into a BCD representation I use the PIC EEPROM module. The EEPROM capacity is 256 bytes, which perfectly matches the number of different digitized temperature values. The EEPROM returns a BCD of two least significant decimal digits (the tens and units of the temp reading). To display the hundreds of temp (actually, just one hundred) one more checking is required to turn on the rightmost LCD 1/2-digit. If the measured temperature exceeds 63.75°C, it is reset to its maximum value in the working range (63.75°C which corresponds to the byte entirely consisting of ones). Similarly, if the measured temperature is negative (in Celsius scale), just 0 will be displayed. The temperatures below 0 (which is the freezing point in °C) and above 63.75°C (147°F) are unlikely in a leaving room and this does not affect much the device functionality. The new temp BCD codes obtained from the EEPROM are then encoded into two bytes 7-segment codes and copied to the LCD registers. This way the DC component of the LCD driving waveform is minimized. The I2C interface routines are borrowed from the other thermometer experiments on this Web site.

Download the complete source code here.

Performance

The device draws approx. 600 μA of current while in sleep mode. This is quite a bit larger than I expected, since the PIC itself should only consume about 15 μA according to the specifications and so much is the sensor in its shutdown mode and the DC-DC converter. However, it is unclear how much the LCD would draw. This depends on its capacitance, refresh frequency, displayed digits, etc. The LCD refresh rate in the current setup is approx. 65 Hz, which eliminates flickering completely. Furthermore, the prototyping solderess board also contributes a lot to the parasitic capacitance. Hopefully, this cituation will be better on a PCB. Once after every 8 seconds the I2C bus is used shortly for a communication with sensor. This time the drained peak current goes up to 2.5 mA for several milliseconds. I wonder for how long a single battery cell would last.

I have already mentioned some disadvantages of the TCN75A sensor compared to other models (see here for details). However, this concerns a higher resolution temp measurement with one decimal digit. If only integer (and rounded off) part of the temp is displayed I noticed no difference between the sensor models I have tested. At least, both TCN75A and MCP9803 show the same temp vales with practically unnoticeable difference in consistency and stability.


Last modified:Mon, Jan 23, 2023.

18605