├── .gitattributes ├── .gitignore ├── Firmware └── Nokia-5100-LCD-Example │ ├── LCD_Functions.h │ └── Nokia-5100-LCD-Example.ino ├── LICENSE.md └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## SparkFun Useful stuff 3 | ################# 4 | 5 | ## AVR Development 6 | *.eep 7 | *.elf 8 | *.lst 9 | *.lss 10 | *.sym 11 | *.d 12 | *.o 13 | *.srec 14 | *.map 15 | 16 | ## Notepad++ backup files 17 | *.bak 18 | 19 | ## BOM files 20 | *bom* 21 | 22 | ################# 23 | ## Eclipse 24 | ################# 25 | 26 | *.pydevproject 27 | .project 28 | .metadata 29 | bin/ 30 | tmp/ 31 | *.tmp 32 | *.bak 33 | *.swp 34 | *~.nib 35 | local.properties 36 | .classpath 37 | .settings/ 38 | .loadpath 39 | 40 | # External tool builders 41 | .externalToolBuilders/ 42 | 43 | # Locally stored "Eclipse launch configurations" 44 | *.launch 45 | 46 | # CDT-specific 47 | .cproject 48 | 49 | # PDT-specific 50 | .buildpath 51 | 52 | 53 | ############# 54 | ## Eagle 55 | ############# 56 | 57 | # Ignore the board and schematic backup files 58 | *.b#? 59 | *.s#? 60 | *.l#? 61 | 62 | 63 | ################# 64 | ## Visual Studio 65 | ################# 66 | 67 | ## Ignore Visual Studio temporary files, build results, and 68 | ## files generated by popular Visual Studio add-ons. 69 | 70 | # User-specific files 71 | *.suo 72 | *.user 73 | *.sln.docstates 74 | 75 | # Build results 76 | [Dd]ebug/ 77 | [Rr]elease/ 78 | *_i.c 79 | *_p.c 80 | *.ilk 81 | *.meta 82 | *.obj 83 | *.pch 84 | *.pdb 85 | *.pgc 86 | *.pgd 87 | *.rsp 88 | *.sbr 89 | *.tlb 90 | *.tli 91 | *.tlh 92 | *.tmp 93 | *.vspscc 94 | .builds 95 | *.dotCover 96 | 97 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 98 | #packages/ 99 | 100 | # Visual C++ cache files 101 | ipch/ 102 | *.aps 103 | *.ncb 104 | *.opensdf 105 | *.sdf 106 | 107 | # Visual Studio profiler 108 | *.psess 109 | *.vsp 110 | 111 | # ReSharper is a .NET coding add-in 112 | _ReSharper* 113 | 114 | # Installshield output folder 115 | [Ee]xpress 116 | 117 | # DocProject is a documentation generator add-in 118 | DocProject/buildhelp/ 119 | DocProject/Help/*.HxT 120 | DocProject/Help/*.HxC 121 | DocProject/Help/*.hhc 122 | DocProject/Help/*.hhk 123 | DocProject/Help/*.hhp 124 | DocProject/Help/Html2 125 | DocProject/Help/html 126 | 127 | # Click-Once directory 128 | publish 129 | 130 | # Others 131 | [Bb]in 132 | [Oo]bj 133 | sql 134 | TestResults 135 | *.Cache 136 | ClientBin 137 | stylecop.* 138 | ~$* 139 | *.dbmdl 140 | Generated_Code #added for RIA/Silverlight projects 141 | 142 | # Backup & report files from converting an old project file to a newer 143 | # Visual Studio version. Backup files are not needed, because we have git ;-) 144 | _UpgradeReport_Files/ 145 | Backup*/ 146 | UpgradeLog*.XML 147 | 148 | 149 | ############ 150 | ## Windows 151 | ############ 152 | 153 | # Windows image file caches 154 | Thumbs.db 155 | 156 | # Folder config file 157 | Desktop.ini 158 | 159 | 160 | ############# 161 | ## Mac OS 162 | ############# 163 | 164 | .DS_Store 165 | 166 | 167 | ############# 168 | ## Linux 169 | ############# 170 | 171 | # backup files (*.bak on Win) 172 | *~ 173 | 174 | 175 | ############# 176 | ## Python 177 | ############# 178 | 179 | *.py[co] 180 | 181 | # Packages 182 | *.egg 183 | *.egg-info 184 | dist 185 | build 186 | eggs 187 | parts 188 | bin 189 | var 190 | sdist 191 | develop-eggs 192 | .installed.cfg 193 | 194 | # Installer logs 195 | pip-log.txt 196 | 197 | # Unit test / coverage reports 198 | .coverage 199 | .tox 200 | 201 | #Translations 202 | *.mo 203 | 204 | #Mr Developer 205 | .mr.developer.cfg 206 | -------------------------------------------------------------------------------- /Firmware/Nokia-5100-LCD-Example/LCD_Functions.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Pin definitions: 4 | Most of these pins can be moved to any digital or analog pin. 5 | DN(MOSI)and SCLK should be left where they are (SPI pins). The 6 | LED (backlight) pin should remain on a PWM-capable pin. */ 7 | const int scePin = 7; // SCE - Chip select, pin 3 on LCD. 8 | const int rstPin = 6; // RST - Reset, pin 4 on LCD. 9 | const int dcPin = 5; // DC - Data/Command, pin 5 on LCD. 10 | const int sdinPin = 11; // DN(MOSI) - Serial data, pin 6 on LCD. 11 | const int sclkPin = 13; // SCLK - Serial clock, pin 7 on LCD. 12 | const int blPin = 9; // LED - Backlight LED, pin 8 on LCD. 13 | 14 | /* PCD8544-specific defines: */ 15 | #define LCD_COMMAND 0 16 | #define LCD_DATA 1 17 | 18 | /* 84x48 LCD Defines: */ 19 | #define LCD_WIDTH 84 // Note: x-coordinates go wide 20 | #define LCD_HEIGHT 48 // Note: y-coordinates go high 21 | #define WHITE 0 // For drawing pixels. A 0 draws white. 22 | #define BLACK 1 // A 1 draws black. 23 | 24 | /* Font table: 25 | This table contains the hex values that represent pixels for a 26 | font that is 5 pixels wide and 8 pixels high. Each byte in a row 27 | represents one, 8-pixel, vertical column of a character. 5 bytes 28 | per character. */ 29 | static const byte ASCII[][5] PROGMEM = { 30 | // First 32 characters (0x00-0x19) are ignored. These are 31 | // non-displayable, control characters. 32 | {0x00, 0x00, 0x00, 0x00, 0x00} // 0x20 33 | ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 0x21 ! 34 | ,{0x00, 0x07, 0x00, 0x07, 0x00} // 0x22 " 35 | ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 0x23 # 36 | ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 0x24 $ 37 | ,{0x23, 0x13, 0x08, 0x64, 0x62} // 0x25 % 38 | ,{0x36, 0x49, 0x55, 0x22, 0x50} // 0x26 & 39 | ,{0x00, 0x05, 0x03, 0x00, 0x00} // 0x27 ' 40 | ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 0x28 ( 41 | ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 0x29 ) 42 | ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 0x2a * 43 | ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 0x2b + 44 | ,{0x00, 0x50, 0x30, 0x00, 0x00} // 0x2c , 45 | ,{0x08, 0x08, 0x08, 0x08, 0x08} // 0x2d - 46 | ,{0x00, 0x60, 0x60, 0x00, 0x00} // 0x2e . 47 | ,{0x20, 0x10, 0x08, 0x04, 0x02} // 0x2f / 48 | ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 0x30 0 49 | ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 0x31 1 50 | ,{0x42, 0x61, 0x51, 0x49, 0x46} // 0x32 2 51 | ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 0x33 3 52 | ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 0x34 4 53 | ,{0x27, 0x45, 0x45, 0x45, 0x39} // 0x35 5 54 | ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 0x36 6 55 | ,{0x01, 0x71, 0x09, 0x05, 0x03} // 0x37 7 56 | ,{0x36, 0x49, 0x49, 0x49, 0x36} // 0x38 8 57 | ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 0x39 9 58 | ,{0x00, 0x36, 0x36, 0x00, 0x00} // 0x3a : 59 | ,{0x00, 0x56, 0x36, 0x00, 0x00} // 0x3b ; 60 | ,{0x08, 0x14, 0x22, 0x41, 0x00} // 0x3c < 61 | ,{0x14, 0x14, 0x14, 0x14, 0x14} // 0x3d = 62 | ,{0x00, 0x41, 0x22, 0x14, 0x08} // 0x3e > 63 | ,{0x02, 0x01, 0x51, 0x09, 0x06} // 0x3f ? 64 | ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 0x40 @ 65 | ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 0x41 A 66 | ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 0x42 B 67 | ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 0x43 C 68 | ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 0x44 D 69 | ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 0x45 E 70 | ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 0x46 F 71 | ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 0x47 G 72 | ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 0x48 H 73 | ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 0x49 I 74 | ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 0x4a J 75 | ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 0x4b K 76 | ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 0x4c L 77 | ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 0x4d M 78 | ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 0x4e N 79 | ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 0x4f O 80 | ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 0x50 P 81 | ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 0x51 Q 82 | ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 0x52 R 83 | ,{0x46, 0x49, 0x49, 0x49, 0x31} // 0x53 S 84 | ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 0x54 T 85 | ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 0x55 U 86 | ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 0x56 V 87 | ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 0x57 W 88 | ,{0x63, 0x14, 0x08, 0x14, 0x63} // 0x58 X 89 | ,{0x07, 0x08, 0x70, 0x08, 0x07} // 0x59 Y 90 | ,{0x61, 0x51, 0x49, 0x45, 0x43} // 0x5a Z 91 | ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 0x5b [ 92 | ,{0x02, 0x04, 0x08, 0x10, 0x20} // 0x5c \ (keep this to escape the backslash) 93 | ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 0x5d ] 94 | ,{0x04, 0x02, 0x01, 0x02, 0x04} // 0x5e ^ 95 | ,{0x40, 0x40, 0x40, 0x40, 0x40} // 0x5f _ 96 | ,{0x00, 0x01, 0x02, 0x04, 0x00} // 0x60 ` 97 | ,{0x20, 0x54, 0x54, 0x54, 0x78} // 0x61 a 98 | ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 0x62 b 99 | ,{0x38, 0x44, 0x44, 0x44, 0x20} // 0x63 c 100 | ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 0x64 d 101 | ,{0x38, 0x54, 0x54, 0x54, 0x18} // 0x65 e 102 | ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 0x66 f 103 | ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 0x67 g 104 | ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 0x68 h 105 | ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 0x69 i 106 | ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 0x6a j 107 | ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 0x6b k 108 | ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 0x6c l 109 | ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 0x6d m 110 | ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 0x6e n 111 | ,{0x38, 0x44, 0x44, 0x44, 0x38} // 0x6f o 112 | ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 0x70 p 113 | ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 0x71 q 114 | ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 0x72 r 115 | ,{0x48, 0x54, 0x54, 0x54, 0x20} // 0x73 s 116 | ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 0x74 t 117 | ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 0x75 u 118 | ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 0x76 v 119 | ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 0x77 w 120 | ,{0x44, 0x28, 0x10, 0x28, 0x44} // 0x78 x 121 | ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 0x79 y 122 | ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 0x7a z 123 | ,{0x00, 0x08, 0x36, 0x41, 0x00} // 0x7b { 124 | ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 0x7c | 125 | ,{0x00, 0x41, 0x36, 0x08, 0x00} // 0x7d } 126 | ,{0x10, 0x08, 0x08, 0x10, 0x08} // 0x7e ~ 127 | ,{0x78, 0x46, 0x41, 0x46, 0x78} // 0x7f DEL 128 | }; 129 | 130 | /* The displayMap variable stores a buffer representation of the 131 | pixels on our display. There are 504 total bits in this array, 132 | same as how many pixels there are on a 84 x 48 display. 133 | 134 | Each byte in this array covers a 8-pixel vertical block on the 135 | display. Each successive byte covers the next 8-pixel column over 136 | until you reach the right-edge of the display and step down 8 rows. 137 | 138 | To update the display, we first have to write to this array, then 139 | call the updateDisplay() function, which sends this whole array 140 | to the PCD8544. 141 | 142 | Because the PCD8544 won't let us write individual pixels at a 143 | time, this is how we can make targeted changes to the display. */ 144 | byte displayMap[LCD_WIDTH * LCD_HEIGHT / 8] = { 145 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,0)->(11,7) ~ These 12 bytes cover an 8x12 block in the left corner of the display 146 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,0)->(23,7) 147 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, // (24,0)->(35,7) 148 | 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0xFE, 0x1E, 0x0E, 0x02, 0x00, // (36,0)->(47,7) 149 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (48,0)->(59,7) 150 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,0)->(71,7) 151 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,0)->(83,7) 152 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,8)->(11,15) 153 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,8)->(23,15) 154 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // (24,8)->(35,15) 155 | 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF8, // (36,8)->(47,15) 156 | 0xF8, 0xF0, 0xF8, 0xFE, 0xFE, 0xFC, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00, // (48,8)->(59,15) 157 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,8)->(71,15) 158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,8)->(83,15) 159 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,16)->(11,23) 160 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,16)->(23,23) 161 | 0x00, 0x00, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xF3, 0xE0, 0xE0, 0xC0, // (24,16)->(35,23) 162 | 0xC0, 0xC0, 0xE0, 0xE0, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // (36,16)->(47,23) 163 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x00, 0x00, 0x00, // (48,16)->(59,23) 164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,16)->(71,23) 165 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,16)->(83,23) 166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,24)->(11,31) 167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,24)->(23,31) 168 | 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // (24,24)->(35,31) 169 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // (36,24)->(47,31) 170 | 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, // (48,24)->(59,31) 171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,24)->(71,31) 172 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,24)->(83,31) 173 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,32)->(11,39) 174 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,32)->(23,39) 175 | 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, // (24,32)->(35,39) 176 | 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, // (36,32)->(47,39) 177 | 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (48,32)->(59,39) 178 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,32)->(71,39) 179 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,32)->(83,39) 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (0,40)->(11,47) 181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (12,40)->(23,47) 182 | 0x00, 0x00, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, // (24,40)->(35,47) 183 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (36,40)->(47,47) 184 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (48,40)->(59,47) 185 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (60,40)->(71,47) 186 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (72,40)->(83,47) !!! The bottom right pixel! 187 | }; 188 | 189 | // There are two memory banks in the LCD, data/RAM and commands. 190 | // This function sets the DC pin high or low depending, and then 191 | // sends the data byte 192 | void LCDWrite(byte data_or_command, byte data) 193 | { 194 | //Tell the LCD that we are writing either to data or a command 195 | digitalWrite(dcPin, data_or_command); 196 | 197 | //Send the data 198 | digitalWrite(scePin, LOW); 199 | SPI.transfer(data); //shiftOut(sdinPin, sclkPin, MSBFIRST, data); 200 | digitalWrite(scePin, HIGH); 201 | } 202 | 203 | 204 | // This function sets a pixel on displayMap to your preferred 205 | // color. 1=Black, 0= white. 206 | void setPixel(int x, int y, boolean bw) 207 | { 208 | // First, double check that the coordinate is in range. 209 | if ((x >= 0) && (x < LCD_WIDTH) && (y >= 0) && (y < LCD_HEIGHT)) 210 | { 211 | byte shift = y % 8; 212 | 213 | if (bw) // If black, set the bit. 214 | displayMap[x + (y/8)*LCD_WIDTH] |= 1< dy) 261 | { 262 | int fraction = dy - (dx >> 1); 263 | while (x0 != x1) 264 | { 265 | if (fraction >= 0) 266 | { 267 | y0 += stepy; 268 | fraction -= dx; 269 | } 270 | x0 += stepx; 271 | fraction += dy; 272 | setPixel(x0, y0, bw); 273 | } 274 | } 275 | else 276 | { 277 | int fraction = dx - (dy >> 1); 278 | while (y0 != y1) 279 | { 280 | if (fraction >= 0) 281 | { 282 | x0 += stepx; 283 | fraction -= dy; 284 | } 285 | y0 += stepy; 286 | fraction += dx; 287 | setPixel(x0, y0, bw); 288 | } 289 | } 290 | } 291 | 292 | // setRect will draw a rectangle from x0,y0 top-left corner to 293 | // a x1,y1 bottom-right corner. Can be filled with the fill 294 | // parameter, and colored with bw. 295 | // This function was grabbed from the SparkFun ColorLCDShield 296 | // library. 297 | void setRect(int x0, int y0, int x1, int y1, boolean fill, boolean bw) 298 | { 299 | // check if the rectangle is to be filled 300 | if (fill == 1) 301 | { 302 | int xDiff; 303 | 304 | if(x0 > x1) 305 | xDiff = x0 - x1; //Find the difference between the x vars 306 | else 307 | xDiff = x1 - x0; 308 | 309 | while(xDiff > 0) 310 | { 311 | setLine(x0, y0, x0, y1, bw); 312 | 313 | if(x0 > x1) 314 | x0--; 315 | else 316 | x0++; 317 | 318 | xDiff--; 319 | } 320 | } 321 | else 322 | { 323 | // best way to draw an unfilled rectangle is to draw four lines 324 | setLine(x0, y0, x1, y0, bw); 325 | setLine(x0, y1, x1, y1, bw); 326 | setLine(x0, y0, x0, y1, bw); 327 | setLine(x1, y0, x1, y1, bw); 328 | } 329 | } 330 | 331 | // setCircle draws a circle centered around x0,y0 with a defined 332 | // radius. The circle can be black or white. And have a line 333 | // thickness ranging from 1 to the radius of the circle. 334 | // This function was grabbed from the SparkFun ColorLCDShield 335 | // library. 336 | void setCircle (int x0, int y0, int radius, boolean bw, int lineThickness) 337 | { 338 | for(int r = 0; r < lineThickness; r++) 339 | { 340 | int f = 1 - radius; 341 | int ddF_x = 0; 342 | int ddF_y = -2 * radius; 343 | int x = 0; 344 | int y = radius; 345 | 346 | setPixel(x0, y0 + radius, bw); 347 | setPixel(x0, y0 - radius, bw); 348 | setPixel(x0 + radius, y0, bw); 349 | setPixel(x0 - radius, y0, bw); 350 | 351 | while(x < y) 352 | { 353 | if(f >= 0) 354 | { 355 | y--; 356 | ddF_y += 2; 357 | f += ddF_y; 358 | } 359 | x++; 360 | ddF_x += 2; 361 | f += ddF_x + 1; 362 | 363 | setPixel(x0 + x, y0 + y, bw); 364 | setPixel(x0 - x, y0 + y, bw); 365 | setPixel(x0 + x, y0 - y, bw); 366 | setPixel(x0 - x, y0 - y, bw); 367 | setPixel(x0 + y, y0 + x, bw); 368 | setPixel(x0 - y, y0 + x, bw); 369 | setPixel(x0 + y, y0 - x, bw); 370 | setPixel(x0 - y, y0 - x, bw); 371 | } 372 | radius--; 373 | } 374 | } 375 | 376 | // This function will draw a char (defined in the ASCII table 377 | // near the beginning of this sketch) at a defined x and y). 378 | // The color can be either black (1) or white (0). 379 | void setChar(char character, int x, int y, boolean bw) 380 | { 381 | byte column; // temp byte to store character's column bitmap 382 | for (int i=0; i<5; i++) // 5 columns (x) per character 383 | { 384 | column = pgm_read_byte(&ASCII[character - 0x20][i]); 385 | for (int j=0; j<8; j++) // 8 rows (y) per character 386 | { 387 | if (column & (0x01 << j)) // test bits to set pixels 388 | setPixel(x+i, y+j, bw); 389 | else 390 | setPixel(x+i, y+j, !bw); 391 | } 392 | } 393 | } 394 | 395 | // setStr draws a string of characters, calling setChar with 396 | // progressive coordinates until it's done. 397 | // This function was grabbed from the SparkFun ColorLCDShield 398 | // library. 399 | void setStr(char * dString, int x, int y, boolean bw) 400 | { 401 | while (*dString != 0x00) // loop until null terminator 402 | { 403 | setChar(*dString++, x, y, bw); 404 | x+=5; 405 | for (int i=y; i (LCD_WIDTH - 5)) // Enables wrap around 411 | { 412 | x = 0; 413 | y += 8; 414 | } 415 | } 416 | } 417 | 418 | // This function will draw an array over the screen. (For now) the 419 | // array must be the same size as the screen, covering the entirety 420 | // of the display. 421 | // Also, the array must reside in FLASH and declared with PROGMEM. 422 | void setBitmap(const char * bitArray) 423 | { 424 | for (int i=0; i<(LCD_WIDTH * LCD_HEIGHT / 8); i++) 425 | { 426 | char c = pgm_read_byte(&bitArray[i]); 427 | displayMap[i] = c; 428 | } 429 | } 430 | 431 | // This function clears the entire display either white (0) or 432 | // black (1). 433 | // The screen won't actually clear until you call updateDisplay()! 434 | void clearDisplay(boolean bw) 435 | { 436 | for (int i=0; i<(LCD_WIDTH * LCD_HEIGHT / 8); i++) 437 | { 438 | if (bw) 439 | displayMap[i] = 0xFF; 440 | else 441 | displayMap[i] = 0; 442 | } 443 | } 444 | 445 | // Helpful function to directly command the LCD to go to a 446 | // specific x,y coordinate. 447 | void gotoXY(int x, int y) 448 | { 449 | LCDWrite(0, 0x80 | x); // Column. 450 | LCDWrite(0, 0x40 | y); // Row. ? 451 | } 452 | 453 | // This will actually draw on the display, whatever is currently 454 | // in the displayMap array. 455 | void updateDisplay() 456 | { 457 | gotoXY(0, 0); 458 | for (int i=0; i < (LCD_WIDTH * LCD_HEIGHT / 8); i++) 459 | { 460 | LCDWrite(LCD_DATA, displayMap[i]); 461 | } 462 | } 463 | 464 | // Set contrast can set the LCD Vop to a value between 0 and 127. 465 | // 40-60 is usually a pretty good range. 466 | void setContrast(byte contrast) 467 | { 468 | LCDWrite(LCD_COMMAND, 0x21); //Tell LCD that extended commands follow 469 | LCDWrite(LCD_COMMAND, 0x80 | contrast); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark 470 | LCDWrite(LCD_COMMAND, 0x20); //Set display mode 471 | } 472 | 473 | /* There are two ways to do this. Either through direct commands 474 | to the display, or by swapping each bit in the displayMap array. 475 | We'll leave both methods here, comment one or the other out if 476 | you please. */ 477 | void invertDisplay() 478 | { 479 | /* Direct LCD Command option 480 | LCDWrite(LCD_COMMAND, 0x20); //Tell LCD that extended commands follow 481 | LCDWrite(LCD_COMMAND, 0x08 | 0x05); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark 482 | LCDWrite(LCD_COMMAND, 0x20); //Set display mode */ 483 | 484 | /* Indirect, swap bits in displayMap option: */ 485 | for (int i=0; i < (LCD_WIDTH * LCD_HEIGHT / 8); i++) 486 | { 487 | displayMap[i] = ~displayMap[i] & 0xFF; 488 | } 489 | updateDisplay(); 490 | } 491 | 492 | //This sends the magical commands to the PCD8544 493 | void lcdBegin(void) 494 | { 495 | //Configure control pins 496 | pinMode(scePin, OUTPUT); 497 | pinMode(rstPin, OUTPUT); 498 | pinMode(dcPin, OUTPUT); 499 | pinMode(sdinPin, OUTPUT); 500 | pinMode(sclkPin, OUTPUT); 501 | pinMode(blPin, OUTPUT); 502 | analogWrite(blPin, 255); 503 | 504 | SPI.begin(); 505 | SPI.setDataMode(SPI_MODE0); 506 | SPI.setBitOrder(MSBFIRST); 507 | 508 | //Reset the LCD to a known state 509 | digitalWrite(rstPin, LOW); 510 | digitalWrite(rstPin, HIGH); 511 | 512 | LCDWrite(LCD_COMMAND, 0x21); //Tell LCD extended commands follow 513 | LCDWrite(LCD_COMMAND, 0xB0); //Set LCD Vop (Contrast) 514 | LCDWrite(LCD_COMMAND, 0x04); //Set Temp coefficent 515 | LCDWrite(LCD_COMMAND, 0x14); //LCD bias mode 1:48 (try 0x13) 516 | //We must send 0x20 before modifying the display control mode 517 | LCDWrite(LCD_COMMAND, 0x20); 518 | LCDWrite(LCD_COMMAND, 0x0C); //Set display control, normal mode. 519 | } 520 | 521 | 522 | -------------------------------------------------------------------------------- /Firmware/Nokia-5100-LCD-Example/Nokia-5100-LCD-Example.ino: -------------------------------------------------------------------------------- 1 | /* Nokia 5100 LCD Example Code 2 | Graphics driver and PCD8544 interface code for SparkFun's 3 | 84x48 Graphic LCD. 4 | https://www.sparkfun.com/products/10168 5 | 6 | by: Jim Lindblom 7 | adapted from code by Nathan Seidle and mish-mashed with 8 | code from the ColorLCDShield. 9 | date: October 10, 2013 10 | license: Officially, the MIT License. Review the included License.md file 11 | Unofficially, Beerware. Feel free to use, reuse, and modify this 12 | code as you see fit. If you find it useful, and we meet someday, 13 | you can buy me a beer. 14 | 15 | This all-inclusive sketch will show off a series of graphics 16 | functions, like drawing lines, circles, squares, and text. Then 17 | it'll go into serial monitor echo mode, where you can type 18 | text into the serial monitor, and it'll be displayed on the 19 | LCD. 20 | 21 | This stuff could all be put into a library, but we wanted to 22 | leave it all in one sketch to keep it as transparent as possible. 23 | 24 | Hardware: (Note most of these pins can be swapped) 25 | Graphic LCD Pin ---------- Arduino Pin 26 | 1-VCC ---------------- 5V 27 | 2-GND ---------------- GND 28 | 3-SCE ---------------- 7 29 | 4-RST ---------------- 6 30 | 5-D/C ---------------- 5 31 | 6-DN(MOSI) ---------------- 11 32 | 7-SCLK ---------------- 13 33 | 8-LED - 330 Ohm res -- 9 34 | The SCLK, DN(MOSI), must remain where they are, but the other 35 | pins can be swapped. The LED pin should remain a PWM-capable 36 | pin. Don't forget to stick a current-limiting resistor in line 37 | between the LCD's LED pin and Arduino pin 9! 38 | */ 39 | #include 40 | #include "LCD_Functions.h" 41 | 42 | /* This array is the same size as the displayMap. We'll use it 43 | as an example of how to draw a bitmap. xkcd comic transposing 44 | makes for an excellent display application. 45 | For reference, see: http://xkcd.com/149/ */ 46 | static const char xkcdSandwich[504] PROGMEM = { 47 | 0xFF, 0x8D, 0x9F, 0x13, 0x13, 0xF3, 0x01, 0x01, 0xF9, 0xF9, 0x01, 0x81, 0xF9, 0xF9, 0x01, 0xF1, 48 | 0xF9, 0x09, 0x09, 0xFF, 0xFF, 0xF1, 0xF9, 0x09, 0x09, 0xF9, 0xF1, 0x01, 0x01, 0x01, 0x01, 0x01, 49 | 0xF9, 0xF9, 0x09, 0xF9, 0x09, 0xF9, 0xF1, 0x01, 0xC1, 0xE9, 0x29, 0x29, 0xF9, 0xF1, 0x01, 0xFF, 50 | 0xFF, 0x71, 0xD9, 0x01, 0x01, 0xF1, 0xF9, 0x29, 0x29, 0xB9, 0xB1, 0x01, 0x01, 0x01, 0xF1, 0xF1, 51 | 0x11, 0xF1, 0xF1, 0xF1, 0xE1, 0x01, 0xE1, 0xF1, 0x51, 0x51, 0x71, 0x61, 0x01, 0x01, 0xC1, 0xF1, 52 | 0x31, 0x31, 0xF1, 0xFF, 0xFF, 0x00, 0x01, 0x01, 0x01, 0x01, 0x60, 0xE0, 0xA0, 0x01, 0x01, 0x81, 53 | 0xE1, 0x61, 0x60, 0xC0, 0x01, 0xE1, 0xE1, 0x21, 0x21, 0xE0, 0xC1, 0x01, 0xC1, 0xE1, 0x20, 0x20, 54 | 0xFC, 0xFC, 0xE0, 0xE0, 0xC1, 0xE1, 0xE0, 0xC1, 0xE0, 0xE1, 0x01, 0xFC, 0xFC, 0x21, 0x21, 0xE1, 55 | 0xC1, 0xE5, 0xE4, 0x01, 0xC1, 0xE0, 0x20, 0x21, 0x20, 0x00, 0x01, 0xFD, 0xFD, 0x21, 0x20, 0xE0, 56 | 0x00, 0x00, 0x01, 0x01, 0xC0, 0x61, 0x31, 0x31, 0x21, 0x20, 0xC0, 0x81, 0x01, 0x01, 0x01, 0x00, 57 | 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02, 58 | 0x03, 0x01, 0x00, 0x01, 0x03, 0xF2, 0x1A, 0x0B, 0x08, 0x0B, 0x1B, 0x10, 0x60, 0xE3, 0x03, 0x00, 59 | 0x01, 0x03, 0x02, 0x02, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03, 60 | 0x03, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01, 0x03, 0x02, 0x02, 0x03, 0x01, 0x00, 0x03, 61 | 0x03, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3E, 0x63, 0x80, 0x80, 0x80, 0x80, 0x60, 0x3F, 0x07, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x01, 0x01, 0x02, 0x03, 0x3E, 0xE8, 0xF8, 0xF0, 0xD0, 0x90, 64 | 0x18, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x38, 0xFF, 67 | 0x0C, 0x38, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 68 | 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 69 | 0x5F, 0x8F, 0x84, 0x05, 0x07, 0x06, 0x0C, 0x0E, 0x0E, 0x0C, 0x14, 0x34, 0x68, 0x88, 0xD8, 0x70, 70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0xE0, 0x00, 0xF0, 0xF0, 0x00, 0x80, 71 | 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x20, 0x38, 72 | 0x0E, 0x01, 0xC0, 0x3F, 0xE0, 0x00, 0x00, 0x03, 0x0E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xB6, 0xED, 0xC0, 0xC0, 74 | 0xC0, 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xE1, 0xE1, 0xC1, 75 | 0xEF, 0xBB, 0x83, 0x86, 0x88, 0xB0, 0x80, 0x80, 0x80, 0x8F, 0x90, 0x90, 0x90, 0x9F, 0x8F, 0x80, 76 | 0x9F, 0x9F, 0x87, 0x8D, 0x98, 0x80, 0x8C, 0x9E, 0x92, 0x92, 0x9F, 0xC0, 0xC7, 0xFF, 0xB8, 0x8F, 77 | 0x80, 0x90, 0x90, 0xC0, 0xF0, 0x8E, 0x81, 0x80, 0x81, 0x8F, 0xB8, 0xE0, 0x80, 0x80, 0x80, 0x80, 78 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF, 79 | }; 80 | 81 | void setup() 82 | { 83 | Serial.begin(9600); 84 | 85 | lcdBegin(); // This will setup our pins, and initialize the LCD 86 | updateDisplay(); // with displayMap untouched, SFE logo 87 | setContrast(40); // Good values range from 40-60 88 | delay(2000); 89 | 90 | lcdFunTime(); // Runs a 30-second demo of graphics functions 91 | 92 | // Wait for serial to come in, then clear display and go to echo 93 | while (!Serial.available()) 94 | ; 95 | clearDisplay(WHITE); 96 | updateDisplay(); 97 | } 98 | 99 | // Loop turns the display into a local serial monitor echo. 100 | // Type to the Arduino from the serial monitor, and it'll echo 101 | // what you type on the display. Type ~ to clear the display. 102 | void loop() 103 | { 104 | static int cursorX = 0; 105 | static int cursorY = 0; 106 | 107 | if (Serial.available()) 108 | { 109 | char c = Serial.read(); 110 | 111 | switch (c) 112 | { 113 | case '\n': // New line 114 | cursorY += 8; 115 | break; 116 | case '\r': // Return feed 117 | cursorX = 0; 118 | break; 119 | case '~': // Use ~ to clear the screen. 120 | clearDisplay(WHITE); 121 | updateDisplay(); 122 | cursorX = 0; // reset the cursor 123 | cursorY = 0; 124 | break; 125 | default: 126 | setChar(c, cursorX, cursorY, BLACK); 127 | updateDisplay(); 128 | cursorX += 6; // Increment cursor 129 | break; 130 | } 131 | // Manage cursor 132 | if (cursorX >= (LCD_WIDTH - 4)) 133 | { // If the next char will be off screen... 134 | cursorX = 0; // ... reset x to 0... 135 | cursorY += 8; // ...and increment to next line. 136 | if (cursorY >= (LCD_HEIGHT - 7)) 137 | { // If the next line takes us off screen... 138 | cursorY = 0; // ...go back to the top. 139 | } 140 | } 141 | } 142 | } 143 | 144 | /* This function serves as a fun demo of the graphics driver 145 | functions below. */ 146 | void lcdFunTime() 147 | { 148 | clearDisplay(WHITE); // Begin by clearing the display 149 | randomSeed(analogRead(A0)); 150 | 151 | /* setPixel Example */ 152 | const int pixelCount = 100; 153 | for (int i=0; i=0; i-=5) 203 | { 204 | analogWrite(blPin, i); // blPin is ocnnected to BL LED 205 | delay(20); 206 | } 207 | for (int i=0; i<256; i+=5) 208 | { 209 | analogWrite(blPin, i); 210 | delay(20); 211 | } 212 | } 213 | 214 | /* setRect Example */ 215 | clearDisplay(WHITE); // Start fresh 216 | 217 | // setRect takes six parameters (x0, y0, x1, y0, fill, bw) 218 | // x0, y0, x1, and y0 are the two diagonal corner coordinates 219 | // fill is a boolean, which determines if the rectangle is 220 | // filled in. bw determines the color 0=white, 1=black. 221 | for (int x=0; x