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.
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.
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.
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.
Shows how each pixel is organized in DRAM. Image taken from the Nokia 5110 Datasheet |
Shows how each byte in RAM relates to each pixels on the display. Image taken from the Nokia 5110 Datasheet |
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!
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!
Is the compiler smart enough to figure out the redundant puts/writeStringToLCD functions? Does it case more memory usage?
ReplyDeleteThat 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.
DeleteSome of the links to 43oh are broken. Getting 404.
ReplyDeleteThank you for pointing that out. I fixed the main 3 links.
Delete