IAN LANG ELECTRONICS

Which as you'll gather from the title above is a practical consideration and application for the LCD screen which whilst not as spectacular as the last demo does provide us with a useful task to set it to and moreover we are going to run it with the library this time.

 

What this device does is to make a portable thermometer that you can use to measure the temperature wherever you happen to be. I haven't shown it here, but if you want the thermometer to come on only when you close a switch put it in the power line feed to the Arduino.

As it stands, this device will tell you the temperature in Centigrade (Celsius) or Fahrenheit using one button to switch between. It features a small graphic and some text.

 

If you haven't got the library already, get it from here:

 

 

 

 

 

 

Download it to a folder so that you know where it is, and you'll find it comes as a Windows-ready folder. Now just copy the lot into your Arduino libraries folder. In your IDE (you must restart it first) go to the examples and you'll find under PCD8544 a sketch called "Hello World". Run it, and you'll get some text that says hello world followed by a count and a smiley. If you see all that, congrats, your LCD module is working.

 

 

On with our little project then. Here's how you wire up:

 

 

Go Back

Using a Nokia 5110 Graphic LCD to Make an Ambient Temperature Thermometer.

http://code.google.com/p/pcd8544/ thermowire

We are using a TMP 36 here. This device puts out 10 mV for every degree of centigrade it measures, and there's an offset of 500 mV to account for negative values. The practical upshot is that it has a range of -50 to 450 degrees. If you are at the extremes of those temperatures, the last thing you're going to be worrying about is looking at the thermometer as you'll be too busy failing to stay alive, but we still have to account for them.

 

Here's the sketch for you to copy and paste or alternatively clicking on the link on the left will let you download and open it as a text file. Click, and in a second or two you'll be invited to save or open. Open it and a text file will pop up in Notepad, so you can select all and copy it straight to your IDE.

 

 

#include <PCD8544.h>

#define LCD_WIDTH = 84;

#define LCD_HEIGHT = 48;

const unsigned char tempnow [] = {

0xFF, 0xF7, 0xF7, 0x07, 0xF7, 0xF7, 0x3F, 0xDF, 0xDF, 0x3F, 0xFF, 0x1F, 0xDF, 0xDF, 0x3F, 0xDF,

0xDF, 0x7F, 0xBF, 0x1F, 0xDF, 0xDF, 0x3F, 0xFF, 0x3F, 0xDF, 0xDF, 0x3F, 0xFF, 0x1F, 0xDF, 0xFF,

0xBF, 0xDF, 0xDF, 0x1F, 0xFF, 0x1F, 0xDF, 0xFF, 0x1F, 0xFF, 0xFF, 0x1F, 0xFF, 0x1F, 0xDF, 0xFF,

0x3F, 0xDF, 0xDF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x17, 0xFF, 0x1F, 0x5F, 0xDF, 0xFF, 0xFF, 0xFF,

0xFF, 0x1F, 0xDF, 0xDF, 0x3F, 0xFF, 0x3F, 0xDF, 0xDF, 0x1F, 0x7F, 0x1F, 0xFF, 0x3F, 0x1F, 0xFF,

0x1F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFB, 0xFB, 0xFE, 0xFF, 0xF8,

0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF9, 0xFF, 0xF1, 0xFB, 0xFB, 0xFC, 0xFE, 0xF8, 0xFB, 0xFB, 0xF9,

0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFA, 0xFB, 0xF8, 0xFF, 0xFA, 0xFB, 0xFF, 0xF8, 0xFB, 0xFB, 0xF8,

0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFB, 0xFB, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFB, 0xFE,

0xFA, 0xFD, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xF8, 0xFB, 0xFB, 0xF8, 0xFE, 0xFF,

0xF8, 0xFC, 0xFE, 0xF8, 0xFE, 0xFF, 0xFB, 0xFF,

};

boolean centigrade=true;boolean lockout=false;

 void lcdcommands(byte commandbyte){

 digitalWrite(5,0);

  digitalWrite(7, LOW);

  shiftOut(4, 3, MSBFIRST, commandbyte);

  digitalWrite(7, HIGH);}

 static PCD8544 lcd;

void setup() {

  lcd.begin(84,48);

  lcdcommands(0x21); //Tell LCD that extended commands follow- if you don't it wont recognise commands following

  lcdcommands(0xB9); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark- careful not to get it too pasty white!

  lcdcommands(0x20); //Send 0x20 or the screen won't respond to data commands following

   lcd.setCursor(0,0);//column , row

 

  lcd.drawBitmap(tempnow,84,2);

 }

 

void loop() {

// *************The following section gets the input

int output = (analogRead(A0));//get the voltage reading from the TMP 36

output=map(output,0,1023,-50,450);// map it to a centigrade reading

 

//*******The following section selects the measurement system*****

if (digitalRead(8)==HIGH && lockout == false&&centigrade==true){

  lockout=true;centigrade=false;}

  if (digitalRead(8)==HIGH && lockout == false&&centigrade==false){

  lockout=true;centigrade=true;}

  if (centigrade==false){

    float nineoverfive= 1.8;

    output=output*nineoverfive;

    output=output+32;}

 

    if (digitalRead(8)==LOW){lockout=false;}

 

 

//**************The following section controls the output***********

  String metric="";

if (centigrade==true){metric = "Centigrade";}

else{metric="Fahrenheit";}

lcd.setCursor(40,3);

lcd.print("    ");

lcd.setCursor(40,3);

lcd.print(output);

lcd.setCursor(15,5);

lcd.print(metric);

lcd.setCursor(25,4);

lcd.print("degrees");

//********************************************************************

 

 

delay(250);

 

}

 

If you've got this up and running what your LCD should be showing you is a black band on top of the screen with white text saying "Temperature is now" and then underneath whatever the temperature is followed by "degrees" on the next line and "Centigrade" on the bottom. If that's the case, we're going great. Now press the button. The display will change to Fahrenheit. Do it again and it will go back to Centigrade.

 

There are two things you may notice about this sketch in comparison to the Space Invaders one last chapter. Firstly it's much, much shorter. Secondly it uses about two thirds of the RAM that the Space Invaders thing did. How come? It's because of the library I'm afraid. Libraries always bulk your sketches out to big proportions. Sometimes we have to use them but it's generally better to find a way to commune directly with the peripheral attached to your Arduino. The advantage is that the coding is made much simpler and so for a small and simple project like this it makes much more sense to use the library and spend 30 minutes knocking up a sketch round it than it does to sit for three or four hours creating a complex beast to do the same job.

 

Let's delve in to that code then and find out what all the bits are doing. It begins:

 

#include <PCD8544.h>

 

This is the call to use the library. It does absolutely nothing at run time, but at compile time it tells the compiler to meld all the used bits of the library into your sketch. This is why it bloats your sketches up.

Next comes:

 

#define LCD_WIDTH = 84;

#define LCD_HEIGHT = 48;

 

If you've been reading the other chapters prior to this one you'll know that define is a way to cheat with variables as it creates a global without using RAM. The disadvantage is that if you are not careful it's easy to change the definitions accidentally. Here we are defining the number of columns and the number of rows. There are 48 rows, but as the pixel banks are treated as eight deep, in practice there's only six (48/8=6) and don't fall into the trap I regularly do and think that the top row is 1 and the bottom 6 because they go from 0-5. I've been doing programming since 1982 and I still forget about zero-indexing. Doh!

 

Here's an interesting bit:

 

const unsigned char tempnow [] = {

0xFF, 0xF7, 0xF7, 0x07, 0xF7, 0xF7, 0x3F, 0xDF, 0xDF, 0x3F, 0xFF, 0x1F, 0xDF, 0xDF, 0x3F, 0xDF,

0xDF, 0x7F, 0xBF, 0x1F, 0xDF, 0xDF, 0x3F, 0xFF, 0x3F, 0xDF, 0xDF, 0x3F, 0xFF, 0x1F, 0xDF, 0xFF,

0xBF, 0xDF, 0xDF, 0x1F, 0xFF, 0x1F, 0xDF, 0xFF, 0x1F, 0xFF, 0xFF, 0x1F, 0xFF, 0x1F, 0xDF, 0xFF,

0x3F, 0xDF, 0xDF, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x17, 0xFF, 0x1F, 0x5F, 0xDF, 0xFF, 0xFF, 0xFF,

0xFF, 0x1F, 0xDF, 0xDF, 0x3F, 0xFF, 0x3F, 0xDF, 0xDF, 0x1F, 0x7F, 0x1F, 0xFF, 0x3F, 0x1F, 0xFF,

0x1F, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFB, 0xFB, 0xFE, 0xFF, 0xF8,

0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF9, 0xFF, 0xF1, 0xFB, 0xFB, 0xFC, 0xFE, 0xF8, 0xFB, 0xFB, 0xF9,

0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFA, 0xFB, 0xF8, 0xFF, 0xFA, 0xFB, 0xFF, 0xF8, 0xFB, 0xFB, 0xF8,

0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFB, 0xFB, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFB, 0xFE,

0xFA, 0xFD, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xF8, 0xFB, 0xFB, 0xF8, 0xFE, 0xFF,

0xF8, 0xFC, 0xFE, 0xF8, 0xFE, 0xFF, 0xFB, 0xFF,

};

 

It's the graphic at the top of the screen reduced to a lot of numbers. They relate to the pixel value of the columns in rows of eight. This is just the data for them; the drawing bit comes in the setup.

 

Now we need to set up two boolean variables to make the change switch work. These are going to be used to lock down the button once it's been pressed and to change the system of measurement from the one it is to the one it's not.

 

boolean centigrade=true;boolean lockout=false;

 

The next part is a tricky one. Over the page we go to look at it. Get your cuppa now.

 

5110 Thermo

5V

GND

Input Pin

Wire up your switch in the manner on the right

to pull the pin reliably low. A 10k resistor will work here.

All the resistors on the LCD module are 10k except the one on SCE which is 1k.

breaktime More>