Tuesday, August 7, 2012

Using a Nokia LCD Library

SparkFun sells a great, low-cost, yet easy to use LCD display breakout board for the Nokia 5110 display. This LCD is perfect for any which requires a user interface. When I made the decision to build a reflow toaster oven, I also decided that I wanted to be able to view the oven's progress on a small display. This post supports the series I am writing about on HardwareBreakout.com which discusses building your own toaster oven "reflow oven".

This specific display has been used in many projects on many different microcontrollers, such as the Arduino. This means that there is already ample information out there on this LCD including libraries written for many different microcontrollers. Since reinventing the wheel is usually a bad idea, this post will discuss using an existing library for the MSP430 to meet our toaster oven needs.

Requirements

My goal for this project is to display real-time information on the reflow process. This includes the current temperature in the toaster oven, the temperature the toaster oven should be at, the current zone the oven is in (e.g. cooldown, reflow, preheat), and how long the process has been going on for. Given that all of the information I would like to display is text based, implementation is fairly straight forward.

There are many libraries written specifically for the MSP430 that interface with this display.
These are just three of the many libraries which can be found for the MSP430. For this post, I have decided to use RobG's Nokia 5110 as it uses the hardware SPI rather than a software SPI. Please take a second to look at his forum post, it is very well done.

It is VERY important to give credit where credit is due. If you use someone else's code, always include comments in your code linking to the original author. It is great that we have such an awesome community, where code is shared freely.

The Nokia LCD

While it is not necessary to understand how the LCD works when using a fully functioning library, it can still be beneficial if you need to modify the library or if you run into problems with your project. The first step in figuring out how the Nokia 5110 works is to take a look at the datasheet.

Shows how each pixel is organized in DRAM. Image taken from the Nokia 5110 Datasheet
The above image shows how each pixel on the screen is organized. There are a total of 84x48 pixels, these pixels are organized into 6 horizontal banks (zero through five), and 84 columns. Each bank contains 8 pixels, which sum up to a total of 48 rows.

Shows how each byte in RAM relates to each pixels on the display. Image taken from the Nokia 5110 Datasheet
The above image shows how the RAM will map to a given pixel in the display. This image shows the whole display, with each row representing one bank. One byte in memory stores the data for each column in a given bank; this makes sense considering there are 8 rows of pixels in each bank.

Given that we are strictly displaying text on the screen using RobG's code, we do not really need to know any of this. That being said, understanding how the memory is mapped to the display is very important if you will be creating your own graphics or characters.

Creating an LCD Project in CCS

Since I prefer Code Composer Studio (CCS) over the other methods for programming the MSP430, I will quickly discuss how to use someone else's code in your projects.

The first step is to create a new project for your specific device, for this example I am using the MSP430G2553. While you can import any file to your project, I prefer to just copy and paste the code when using code posted online. For RobG's code you need to create one new file, "PCD8544.h" and copy his code directly into it. The simplest way to start with his library is to also copy his "main.c" and modify it for your project.

While it is possible to change some of the pin assignments around, be careful. Some of the pins need to stay where they are because they are special SPI pins built into the USCIB interface (in the MSP430G2553). To use this library in its most basic form, three functions are needed.
  • clearBank(bank) - Clears an entire line on the LCD display and sets the current location to the beginning of the line.
  • writeStringToLCD(string) - Write a string to the LCD in the current location.
  • writeCharToLCD(char) - Write a character to the LCD in the current location.
In addition to RobB's code I will be using the printf code which I discussed in my previous post. This allows us to display the content of our variables on the LCD display, for example the current temperature of the toaster oven. To use printf, you have to copy the printf.c file into your project and then create the following two functions in your main.c file. By using these functions, the output of printf is displayed on the LCD.

 /**  
  * puts() is used by printf() to display or send a string.. This function  
  *   determines where printf prints to. For this case it outputs a string  
  *   to a LCD, another option could be to send the string out via UART.  
  **/  
 void puts(char *s) {  
   writeStringToLCD(s);  
 }  
 /**  
  * puts() is used by printf() to display or send a character. This function  
  *   determines where printf prints to. For this case it outputs a  
  *   character to a LCD.  
  **/  
 void putc(unsigned b) {  
   writeCharToLCD(b);  
 }  

Code Snippet

The code below is a snippet from my project. This is just a quick example of using RobG's code with my project. I call this function whenever I want to display the current status of the toaster oven on the display. The variables it uses are global variables which will be updated as the program runs. I only call this function when a value is changed, so that the display is not updated unnecessarily. 

 void updateStatus() {  
   
      clearBank(0);               // Line 0 shows current temperature  
      printf("Current: ");  
      printf("%u", currentTemp);  
      writeCharToLCD(0x7f);     // Degree symbol  
      writeStringToLCD("C");  
      clearBank(1);               // Line 1 is empty  
   
      clearBank(2);               // Line 2 shows the desired temperature  
      writeStringToLCD("Desired: ");  
      printf("%u", desiredTemp);  
      writeCharToLCD(0x7f);     // Degree symbol  
      writeStringToLCD("C");  
      clearBank(3);               // Line 3 is empty  
   
      clearBank(4);               // Line 4 shows which zone the oven is in  
      printf("Zone: ");  
      writeStringToLCD(zoneString[zoneIndex]);  
      if (heatOn)                    // Line 4 includes an asterisk when the  
           printf("*");          // heating elements are on  
   
      clearBank(5);               // Line 5 shows the time the toaster oven   
      printf("Time: ");          // has been running  
      if (minutes < 10)          // Make sure there are always two digits  
           printf("0");  
      printf("%u:", minutes);  
   
      if (seconds < 10)          // Make sure there are always two digits  
           printf("0");  
      printf("%u", seconds);  
 }  
   

Conclusion

Overall, integrating RobG's library into my project was very simple. It went without a hitch. Modifying his code for custom characters is also fairly straight forward. I hope this post helped shed some light on how the Nokia 5110 display works. It has never been easier to use such a cool display in your projects. This post supports my series on Hardware Breakout which discusses building a toaster oven "reflow oven".

Leave a comment and post links of your projects using the Nokia 5110!

2 comments:

  1. Is the compiler smart enough to figure out the redundant puts/writeStringToLCD functions? Does it case more memory usage?

    ReplyDelete
    Replies
    1. That is a very good question. To be honest, I am not 100% sure. My best guess is that it will not cause more memory usage because we are using a pointer. If anyone else has an idea or thinks that I am wrong, please reply to this.

      Delete