Last active
August 29, 2015 14:00
-
-
Save smittytone/11397681 to your computer and use it in GitHub Desktop.
Electric Imp example code to drive a Nokia 3310/5110 84 x 48 mono LCD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Nokia 5110 control code for the imp | |
// Adapted by Tony Smith from a variety of sources: | |
// http://playground.arduino.cc/Code/PCD8544 | |
// http://www.microsyl.com/index.php/2010/03/24/nokia-lcd-library/ | |
// Assign the control pins to global variables | |
PIN_RST <- hardware.pin9; | |
PIN_CE <- hardware.pin8; | |
PIN_DC <- hardware.pin7; | |
PIN_DIN <- hardware.pin5; | |
PIN_CLK <- hardware.pin2; | |
PIN_BL <- hardware.pin1; | |
// Constants | |
const LCD_COMMAND = 0; | |
const LCD_DATA = 1; | |
const LCD_X = 84; // Screen's pixel width | |
const LCD_Y = 48; // Screen's pixel height | |
// ASCII is an array of Ascii characters, each defined by an | |
// array of five 8-bit values specifying a 5 x 8 pixel matrix | |
// Note: we pad characters in the code | |
ASCII <- [ | |
[0x00, 0x00, 0x00, 0x00, 0x00], // 20 | |
[0x00, 0x00, 0x5f, 0x00, 0x00], // 21 ! | |
[0x00, 0x07, 0x00, 0x07, 0x00], // 22 " | |
[0x14, 0x7f, 0x14, 0x7f, 0x14], // 23 # | |
[0x24, 0x2a, 0x7f, 0x2a, 0x12], // 24 $ | |
[0x23, 0x13, 0x08, 0x64, 0x62], // 25 % | |
[0x36, 0x49, 0x55, 0x22, 0x50], // 26 & | |
[0x00, 0x05, 0x03, 0x00, 0x00], // 27 ' | |
[0x00, 0x1c, 0x22, 0x41, 0x00], // 28 ( | |
[0x00, 0x41, 0x22, 0x1c, 0x00], // 29 ) | |
[0x14, 0x08, 0x3e, 0x08, 0x14], // 2a * | |
[0x08, 0x08, 0x3e, 0x08, 0x08], // 2b + | |
[0x00, 0x50, 0x30, 0x00, 0x00], // 2c , | |
[0x08, 0x08, 0x08, 0x08, 0x08], // 2d - | |
[0x00, 0x60, 0x60, 0x00, 0x00], // 2e . | |
[0x20, 0x10, 0x08, 0x04, 0x02], // 2f / | |
[0x3e, 0x51, 0x49, 0x45, 0x3e], // 30 0 | |
[0x00, 0x42, 0x7f, 0x40, 0x00], // 31 1 | |
[0x42, 0x61, 0x51, 0x49, 0x46], // 32 2 | |
[0x21, 0x41, 0x45, 0x4b, 0x31], // 33 3 | |
[0x18, 0x14, 0x12, 0x7f, 0x10], // 34 4 | |
[0x27, 0x45, 0x45, 0x45, 0x39], // 35 5 | |
[0x3c, 0x4a, 0x49, 0x49, 0x30], // 36 6 | |
[0x01, 0x71, 0x09, 0x05, 0x03], // 37 7 | |
[0x36, 0x49, 0x49, 0x49, 0x36], // 38 8 | |
[0x06, 0x49, 0x49, 0x29, 0x1e], // 39 9 | |
[0x00, 0x36, 0x36, 0x00, 0x00], // 3a : | |
[0x00, 0x56, 0x36, 0x00, 0x00], // 3b ; | |
[0x08, 0x14, 0x22, 0x41, 0x00], // 3c < | |
[0x14, 0x14, 0x14, 0x14, 0x14], // 3d = | |
[0x00, 0x41, 0x22, 0x14, 0x08], // 3e > | |
[0x02, 0x01, 0x51, 0x09, 0x06], // 3f ? | |
[0x32, 0x49, 0x79, 0x41, 0x3e], // 40 @ | |
[0x7e, 0x11, 0x11, 0x11, 0x7e], // 41 A | |
[0x7f, 0x49, 0x49, 0x49, 0x36], // 42 B | |
[0x3e, 0x41, 0x41, 0x41, 0x22], // 43 C | |
[0x7f, 0x41, 0x41, 0x22, 0x1c], // 44 D | |
[0x7f, 0x49, 0x49, 0x49, 0x41], // 45 E | |
[0x7f, 0x09, 0x09, 0x09, 0x01], // 46 F | |
[0x3e, 0x41, 0x49, 0x49, 0x7a], // 47 G | |
[0x7f, 0x08, 0x08, 0x08, 0x7f], // 48 H | |
[0x00, 0x41, 0x7f, 0x41, 0x00], // 49 I | |
[0x20, 0x40, 0x41, 0x3f, 0x01], // 4a J | |
[0x7f, 0x08, 0x14, 0x22, 0x41], // 4b K | |
[0x7f, 0x40, 0x40, 0x40, 0x40], // 4c L | |
[0x7f, 0x02, 0x0c, 0x02, 0x7f], // 4d M | |
[0x7f, 0x04, 0x08, 0x10, 0x7f], // 4e N | |
[0x3e, 0x41, 0x41, 0x41, 0x3e], // 4f O | |
[0x7f, 0x09, 0x09, 0x09, 0x06], // 50 P | |
[0x3e, 0x41, 0x51, 0x21, 0x5e], // 51 Q | |
[0x7f, 0x09, 0x19, 0x29, 0x46], // 52 R | |
[0x46, 0x49, 0x49, 0x49, 0x31], // 53 S | |
[0x01, 0x01, 0x7f, 0x01, 0x01], // 54 T | |
[0x3f, 0x40, 0x40, 0x40, 0x3f], // 55 U | |
[0x1f, 0x20, 0x40, 0x20, 0x1f], // 56 V | |
[0x3f, 0x40, 0x38, 0x40, 0x3f], // 57 W | |
[0x63, 0x14, 0x08, 0x14, 0x63], // 58 X | |
[0x07, 0x08, 0x70, 0x08, 0x07], // 59 Y | |
[0x61, 0x51, 0x49, 0x45, 0x43], // 5a Z | |
[0x00, 0x7f, 0x41, 0x41, 0x00], // 5b [ | |
[0x02, 0x04, 0x08, 0x10, 0x20], // 5c \ | |
[0x00, 0x41, 0x41, 0x7f, 0x00], // 5d ], | |
[0x04, 0x02, 0x01, 0x02, 0x04], // 5e ^ | |
[0x40, 0x40, 0x40, 0x40, 0x40], // 5f _ | |
[0x00, 0x01, 0x02, 0x04, 0x00], // 60 ` | |
[0x20, 0x54, 0x54, 0x54, 0x78], // 61 a | |
[0x7f, 0x48, 0x44, 0x44, 0x38], // 62 b | |
[0x38, 0x44, 0x44, 0x44, 0x20], // 63 c | |
[0x38, 0x44, 0x44, 0x48, 0x7f], // 64 d | |
[0x38, 0x54, 0x54, 0x54, 0x18], // 65 e | |
[0x08, 0x7e, 0x09, 0x01, 0x02], // 66 f | |
[0x0c, 0x52, 0x52, 0x52, 0x3e], // 67 g | |
[0x7f, 0x08, 0x04, 0x04, 0x78], // 68 h | |
[0x00, 0x44, 0x7d, 0x40, 0x00], // 69 i | |
[0x20, 0x40, 0x44, 0x3d, 0x00], // 6a j | |
[0x7f, 0x10, 0x28, 0x44, 0x00], // 6b k | |
[0x00, 0x41, 0x7f, 0x40, 0x00], // 6c l | |
[0x7c, 0x04, 0x18, 0x04, 0x78], // 6d m | |
[0x7c, 0x08, 0x04, 0x04, 0x78], // 6e n | |
[0x38, 0x44, 0x44, 0x44, 0x38], // 6f o | |
[0x7c, 0x14, 0x14, 0x14, 0x08], // 70 p | |
[0x08, 0x14, 0x14, 0x18, 0x7c], // 71 q | |
[0x7c, 0x08, 0x04, 0x04, 0x08], // 72 r | |
[0x48, 0x54, 0x54, 0x54, 0x20], // 73 s | |
[0x04, 0x3f, 0x44, 0x40, 0x20], // 74 t | |
[0x3c, 0x40, 0x40, 0x20, 0x7c], // 75 u | |
[0x1c, 0x20, 0x40, 0x20, 0x1c], // 76 v | |
[0x3c, 0x40, 0x30, 0x40, 0x3c], // 77 w | |
[0x44, 0x28, 0x10, 0x28, 0x44], // 78 x | |
[0x0c, 0x50, 0x50, 0x50, 0x3c], // 79 y | |
[0x44, 0x64, 0x54, 0x4c, 0x44], // 7a z | |
[0x00, 0x08, 0x36, 0x41, 0x00], // 7b [ | |
[0x00, 0x00, 0x7f, 0x00, 0x00], // 7c | | |
[0x00, 0x41, 0x36, 0x08, 0x00], // 7d ] | |
[0x10, 0x08, 0x08, 0x10, 0x08], // 7e ~ | |
[0x78, 0x46, 0x41, 0x46, 0x78], // 7f DEL | |
]; | |
// IMP_GFX is an array of 84 x 5 8-bit values that are | |
// used to define an 84 x 48 pixel bitmap Electric Imp logo | |
IMP_GFX <- [ | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0xF8, | |
0xF8, 0x10, 0xC0, 0xF0, 0xF0, 0x30, 0x80, 0xC0, | |
0xC0, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0xFC, 0xFE, | |
0xFC, 0xF0, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, | |
0xF8, 0xFC, 0xFC, 0xFE, 0x7E, 0x7F, 0x3F, 0x3F, | |
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x3F, | |
0x3F, 0x7F, 0x7E, 0xFE, 0xFC, 0xFC, 0xF8, 0xFC, | |
0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0xE0, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, | |
0xF8, 0xFE, 0xFF, 0xFF, 0xE1, 0xFC, 0xFF, 0xFF, | |
0x07, 0x00, 0x00, 0x00, | |
0x00, 0x18, 0x1E, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, | |
0xFF, 0xEF, 0x0F, 0x0F, 0x1E, 0x18, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0xC0, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0x3F, | |
0x0F, 0x73, 0xF1, 0xF0, 0xE0, 0xE0, 0xE0, 0xC0, | |
0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, | |
0xF0, 0xF0, 0xF8, 0xF8, 0xF1, 0x63, 0x0F, 0x3F, | |
0xFF, 0xFF, 0xFF, 0xFE, 0xF0, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x07, 0x0F, 0xDF, 0xFF, 0xFF, 0xFF, | |
0x7F, 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x07, 0x01, | |
0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0F, | |
0x3F, 0x7F, 0xFE, 0xF8, 0xE0, 0xC0, 0x00, 0x00, | |
0x00, 0xC0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0xF8, | |
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, | |
0x80, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, | |
0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x83, | |
0x83, 0xC3, 0x43, 0x01, 0x00, 0x00, 0x00, 0xC0, | |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xF8, | |
0xF8, 0xF8, 0xF0, 0xFE, 0xFF, 0xFF, 0x07, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3E, | |
0x3C, 0x7C, 0x7B, 0xF3, 0xF3, 0xE3, 0xE3, 0xE1, | |
0xE1, 0xC1, 0xC0, 0xC3, 0xCF, 0xDF, 0xFF, 0xFF, | |
0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xF0, 0xE0, 0xE0, | |
0xE0, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE3, | |
0xE1, 0xE0, 0xF0, 0xF0, 0xF8, 0xFC, 0xFE, 0x7F, | |
0x3F, 0x1F, 0x07, 0x03, 0x00, 0x01, 0x81, 0xF1, | |
0xFF, 0xFF, 0x3F, 0x07, 0x03, 0x01, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, | |
0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, | |
0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, | |
0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, | |
0x07, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, | |
0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
0x00, 0x00, 0x00, 0x00 | |
]; | |
// MISC FUNCTIONS | |
function delay(value) | |
{ | |
// Delay for ‘value’ milliseconds | |
local a = hardware.millis() + value; | |
while (hardware.millis() < a) | |
{ | |
// NOP | |
} | |
} | |
// 5110 LCD FUNCTIONS | |
function LCDClear() | |
{ | |
// Clear the LCD by writing zeros to the entire screen | |
for (local index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++) | |
{ | |
LCDWrite(LCD_DATA, 0x00); | |
} | |
// Position the cursor at the origin | |
LCDXY(0, 0); | |
} | |
function LCDXY(x, y) | |
{ | |
// Position the cursor at column x, row y | |
// Origin is top left. x = 0-83. y = 0-5 | |
LCDWrite(LCD_COMMAND, 0x80 | x); | |
LCDWrite(LCD_COMMAND, 0x40 | y); | |
} | |
function LCDBitmap(bitarray) | |
{ | |
// Writes an array of 8-bit values to the LCD at | |
// the current cursor position | |
for (local index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++) | |
{ | |
LCDWrite(LCD_DATA, bitarray[index]); | |
} | |
} | |
function LCDCharacter(character) | |
{ | |
// Writes a 5 x 8 character graphic from the ASCII array to the screen | |
// at the current cursor position. The integer parameter is the Ascii | |
// code of the character you want to print. The character is padded with | |
// one blank line to its left and another to its right. | |
LCDWrite(LCD_DATA, 0x00); | |
for (local index = 0 ; index < 5 ; index++) | |
{ | |
LCDWrite(LCD_DATA, ASCII[character - 0x20][index]); | |
} | |
LCDWrite(LCD_DATA, 0x00); | |
} | |
function LCDString(string) | |
{ | |
// Write a string of chracters to the LCD by taking each individual | |
// character and writing it with LCDCharacter(). The PCD8544 chip will | |
// move the cursor for you, wrapping the line and scrolling if necessary | |
foreach (character in string) | |
{ | |
LCDCharacter(character); | |
} | |
} | |
function LCDWrite(data_or_command, data) | |
{ | |
// There are two memory banks in the LCD: one for data, another for | |
// commands. Select the one you want by setting pin DC high (data) or | |
// low (command). Then signal the data/command transmission by setting | |
// pin CE low, writing the data/command, them setting CE high. | |
PIN_DC.write(data_or_command); | |
// Send the data | |
PIN_CE.write(0); | |
LCDWriteByte(data); | |
PIN_CE.write(1); | |
} | |
function LCDWriteByte(byteValue) | |
{ | |
// Takes a byte of data and writes it out to the 5110 bit by bit, | |
// most significant bit first, least significant bit last. | |
// Each bit is signalled by setting pin CLK low and setting CLK | |
// high after the bit has been sent. The bit is sent on pin DIN. | |
for (local i = 8 ; i > 0 ; i--) | |
{ | |
PIN_CLK.write(0); | |
PIN_DIN.write(byteValue & 0x80); | |
byteValue = byteValue << 1; | |
PIN_CLK.write(1); | |
} | |
} | |
function LCDLight(on_or_off) | |
{ | |
// Turn the backlight on or off by passing a bool value | |
// The backlight takes 3.3V and can be either on or off | |
if (on_or_off) | |
{ | |
PIN_BL.write(1); | |
} | |
else | |
{ | |
PIN_BL.write(0); | |
} | |
} | |
function LCDInit() | |
{ | |
// Configure the imp's pins | |
PIN_CE.configure(DIGITAL_OUT); | |
PIN_RESET.configure(DIGITAL_OUT); | |
PIN_DC.configure(DIGITAL_OUT); | |
PIN_DIN.configure(DIGITAL_OUT); | |
PIN_CLK.configure(DIGITAL_OUT); | |
PIN_BL.configure(DIGITAL_OUT); | |
// Reset the PCD8544 by setting RESET low then, after 10ms, back to high | |
PIN_RST.write(0); | |
imp.sleep(0.01); | |
PIN_RST.write(1); | |
// Switch off the backlight | |
LCDLight(false); | |
// Initialize the PCD8544 for use | |
// Send Function command (0x20) to select either | |
// basic command set (+0), or extended command set (+1) | |
LCDWrite(LCD_COMMAND, 0x21); | |
// Set LCD contrast command (0x80) using Vop | |
// Try 0xB1 (good @ 3.3V) or 0xBF if your display is too dark | |
LCDWrite(LCD_COMMAND, 0xB0); | |
// Set LCD temperature coefficient (0x04 + 0-3) | |
LCDWrite(LCD_COMMAND, 0x04); | |
// Set LCD bias voltage (0x10 + 0-7) | |
LCDWrite(LCD_COMMAND, 0x14); | |
// Send Function command (0x20) to select either | |
// horizontal screen addressing (+0) or vertical addressing (+2) | |
LCDWrite(LCD_COMMAND, 0x20); | |
// Set LCD display mode (0x08) plus | |
// 0 - All pixels clear (0x08) | |
// 1 - All pixels set (0x09) | |
// 4 - Normal video (0x0C) | |
// 5 - Inverse video (0x0D) | |
LCDWrite(LCD_COMMAND, 0x0C); | |
} | |
// PROGRAM FUNCTIONS | |
function show_stuff() | |
{ | |
LCDClear(); | |
// Flash the backlight | |
LCDLight(true); | |
delay (100); | |
LCDLight(false); | |
delay (100); | |
LCDLight(true); | |
delay (100); | |
LCDLight(false); | |
delay (100); | |
LCDLight(true); | |
delay (100); | |
LCDLight(false); | |
// Display Electric Imp logo | |
LCDBitmap(IMP_GFX); | |
// Position cursor at the start of the bottom row | |
LCDXY(0,5); | |
// Write a text string | |
LCDString("Electric Imp"); | |
// Do it all again in 5 seconds | |
imp.wakeup(5.0, show_stuff); | |
} | |
// PROGRAM START | |
LCDInit(); | |
show_stuff(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment