ARDUINO > My second Arduino Project - LCD Temperature monitor with history graph chart
My second Arduino Project - LCD Temperature monitor with history graph chart PDF Print E-mail
(10 votes, average: 4.60 out of 5)

arduino_logoThis is an update to my first Arduino project in which basically I had used an Arduino Duamilanove connected with an LM35 (temperature sensor) and an HC44780 16x2 text LCD display, to read the current ambient temperature and calculate an average, minimum and maximum and display all these to the LCD display. At this second project I wanted to display a history graph chart of temperature over time on this simple text LCD.


This can be relatively easy at graphics displays (there is a ready arduino library for this) but not so easy at an LCD text display. To make the graph I used the 6 bottom right LCD elements where each element should be created by a dynamically updated custom LCD character. The future and final purpose of this graph chart is to display logged data.

Bellow is a photo of the LCD in action with explanation of the readings on it.

lcd_graph_screenYou can find the circuit and details on how to do the connections and code of the temperature monitor see my first project.




In this document I will explain the way I thought of and coded the graph creation.
First of all what is important to understand is the each element at a 16x2 HC44780 text LCD is a matrix of 8 rows x 5columns. To make something like a graph plot we must put in there a custom LCD character that is dynamically updated at each sample taken. The HC44780 has 8 custom character empty slots (memory positions 0-7). I am using the 1st (0) for the degrees symbol creation. Now the LCD as you may know is constantly and very fast refreshing the screen, reading the characters from its character map memory. That is the reason that for a graph chart consisting of 6 lcd elements I should use 6 custom chars (lcd memory 1-6) , one for each element.


So here is the sequence of coding I did to make the graph chart alive:

1. Firstly custom chars 1 to 6 must be cleared writing all zero bits to them.
To do this grafChar array is set to all zeros.Then grafChar is written to all custom chars memory 1-6 to six.
Then custom chars 1 to 6 are written to LCD positions 10 to 15 at the second display row.
2. Then temperature samples are taken at predefined times. Every time 10 samples are gathered an average of them is calculated.
Sampling period is calculated with accuracy using the Arduino milis() function. (see full code for more details).
Min and max temperature is updated and then a new point at the graph must be created.
I remind you that a char elements has only 8 points height. So the point height must have a value somewhere between from 0 to 7 at a range between the min and max temperatures.
Here is the way to make the analogy work:
(current temp - min Temp)*8/(max Temp - min Temp)
and here is the function for it.

// function to get graph point height
int getheight ( float tempnow , float minT , float maxT ) { // takes measurements , minimum and maximum temperature and reurns a value from 0 to 7
if (tempnow <= minT) return 0;  // lowest graph point
if (tempnow >= maxT) return 7; // highest graph point
if (tempnow > minT & tempnow < maxT) {
return (tempnow - minT)*8/(maxtemp - minT); // here is the way values from 1 to 6 are calculated 

Then this height will be passed to my createpoint function. To this function I give coordinates(column and height) and the custom character memory position I currenty want to update.

// function to make graph point in hc 77480 special characters
int createpoint (int row, int col, int hcchar) { // takes as input the row(height) , the column of custom char that it must be set, and custom character memory position at LCD.
lcd.setCursor(9, 1); // just to verify height . remove it afterwards
lcd.print(row); // just to verify height. remove it afterwards
row = 7 - row; // lcd character 0 is top left so invert coordinates
col = 4 -col; // lcd character 0 is top left so invert coordinates
while (row < 8 ){
bitSet(grafChar[row], col ) ; // this loop sets 1 the bit of the needed pixel and all below that at graphChar bitarray so as to display a bar!
lcd.createChar(hcchar, grafChar); // write to custom character the contents of grafChar array.
return 1; // not used

The function sets the bits I want at the grafChar array with the beautiful bitset arduino function and then reload the array to custom LCD map position I have chosen.
3. Every time a new point is created a counter , taking values 0-4 is increased so that the next point is plotted at the next elements column. As soon as the fifth column (4) of an element is completed. Another counter is updated. This is the custom LCD memory position to be used. The column element column counter is set back to first column (0).
4. When all 6 LCD elements are filled I have chosen to clear all elements , by clearing the custom LCD characters, and setting custom character memory position back to 1 starting the graph plot from the start.

Below is the video showing all the above working in reallity.

I am sure many of you will find better ways to do this graph or optimize my code.
Maybe someone of you could take my functions and makes some nice graph library adding pointers for the arrays for the HC44780 LCDs. If you do improve my idea please let me know!

Note: Please note that sampling period is just for demo reasons. This sampling period will be greater in a real datalogging application.

Feel free to comment and ask for more info or help.

Here you can download the full code.



Add your comment

Your name:

Anti-spam: complete the taskJoomla CAPTCHA
Comments (5)
5Tuesday, 11 August 2015 22:03
Hey this really inspired me to do my project much betterr!! thx a lot :-)

hey and this captcha was really hardcore.. can You do it easier to comment? :-D
error programming
4Sunday, 30 June 2013 00:49
hi, (i'm a noob, so forgive me if i'll ask for abvious)

trying your sketch got an error :

sketch_mar20d_16x2lcd_temperaturewithgraph_v2.pde: In function 'void loop()':
sketch_mar20d_16x2lcd_temperaturewithgraph_v2:201: error: call of overloaded 'write(int)' is ambiguous
C:\Program Files (x86)\Arduino\libraries\LiquidCrystal/LiquidCrystal.h:82: note: candidates are: virtual size_t LiquidCrystal::write(uint8_t)
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino/Print.h:49: note: size_t Print::write(const char*)

can you explain it to me?
many thanks
3Thursday, 07 March 2013 09:20
Awesome project! I will try to make this work on my 4x27 lcd!
2Wednesday, 19 December 2012 03:55
Good job dude
Arduino + LCD
1Monday, 01 August 2011 04:31
Khoa Nguyen
Awesome project man :D
What do you want from my site?