├── LM15SGFNZ07.cpp ├── LM15SGFNZ07.h ├── README.md ├── digitalWriteFast.h ├── examples ├── LM15SGFNZ07_demo │ ├── LM15SGFNZ07_demo.ino │ └── icon.h └── PaddleWar │ └── PaddleWar.ino ├── font.h └── paddlewar_diagram.png /LM15SGFNZ07.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Siemens M55 LCD (LM15SGFNZ07) library 3 | * 4 | * This library enables you to control an LM15SGFNZ07 LCD module with your Arduino. This updated version of the library 5 | * supports more of the capabilities of the LCD and runs quicker than the original one thanks to using the SPI port for 6 | * communication with the LCD. To import this library into your Arduino IDE use the import library function and select 7 | * the library folder or ZIP file. After importing you can run the included demo found under LM15SGFNZ07 of the examples 8 | * menu to get an understanding of this library's awesome capabilities. 9 | * 10 | * Original code by Mindogas 2011. markauskas.mindaugas@gmail.com 11 | * Adapted by Maarten Janssen in 2015. 12 | * 13 | * Latest version of the libaray can be downloaded from my GitHub page: http://github.com/DhrBaksteen 14 | * Contact me at maarten@cheerful.nl 15 | * 16 | * The LM15SGFNZ07 is an LCD with a 101x80 pixels resolution, capable of displaying 4096 colors. It is found in Siemens 17 | * mobile phones (models A65, M55, C60, MC60, S55, A60). Connect the LCD to your Arduino as follows: 18 | * LCD pin --> Arduino pin 19 | * 1 (/CS) 6 20 | * 2 (/RST) 5 21 | * 3 (RS) 4 22 | * 4 (Sclk) 13 (or SPI SCK) 23 | * 5 (Sdata) 11 (or SPI MOSI) 24 | * 6 (+3.3v) 3.3v 25 | * 7 (GND) GND 26 | * 8 (LED1) 3.3v 27 | * 9 (GND) GND 28 | * 10 (LED2) 3.3v 29 | * 30 | * Note 1: You are free to use any of the Arduino's digital pins for LCD communication. This is configure in the 31 | * library's constructor function. 32 | * Note 2: Pin 1 of the LCD is the right most pin, closest to the edge. 33 | */ 34 | 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include "LM15SGFNZ07.h" 42 | 43 | 44 | #define LCD_RS_ON digitalWriteFast(LCD_RS,HIGH); // Put LCD in command mode 45 | #define LCD_RS_OFF digitalWriteFast(LCD_RS,LOW); // Put LCD in data mode 46 | #define LCD_CS_OFF digitalWriteFast(LCD_CS,HIGH); // Disable LCD 47 | #define LCD_CS_ON digitalWriteFast(LCD_CS,LOW); // Enable LCD 48 | #define LCD_RESET_ON digitalWriteFast(LCD_RESET,LOW); // Put LCD in reset mode 49 | #define LCD_RESET_OFF digitalWriteFast(LCD_RESET,HIGH); // Put LCD in normal mode 50 | 51 | 52 | const unsigned char initData[139] PROGMEM = { 53 | 0xF4, 0x90, 0xB3, 0xA0, 0xD0, 0xF0, 0xE2, 0xD4, 0x70, 0x66, 54 | 0xB2, 0xBA, 0xA1, 0xA3, 0xAB, 0x94, 0x95, 0x95, 0x95, 0xF5, 55 | 0x90, 0xF1, 0x00, 0x10, 0x22, 0x30, 0x45, 0x50, 0x68, 0x70, 56 | 0x8A, 0x90, 0xAC, 0xB0, 0xCE, 0xD0, 0xF2, 0x0F, 0x10, 0x20, 57 | 0x30, 0x43, 0x50, 0x66, 0x70, 0x89, 0x90, 0xAB, 0xB0, 0xCD, 58 | 0xD0, 0xF3, 0x0E, 0x10, 0x2F, 0x30, 0x40, 0x50, 0x64, 0x70, 59 | 0x87, 0x90, 0xAA, 0xB0, 0xCB, 0xD0, 0xF4, 0x0D, 0x10, 0x2E, 60 | 0x30, 0x4F, 0x50, 0xF5, 0x91, 0xF1, 0x01, 0x11, 0x22, 0x31, 61 | 0x43, 0x51, 0x64, 0x71, 0x86, 0x91, 0xA8, 0xB1, 0xCB, 0xD1, 62 | 0xF2, 0x0F, 0x11, 0x21, 0x31, 0x42, 0x51, 0x63, 0x71, 0x85, 63 | 0x91, 0xA6, 0xB1, 0xC8, 0xD1, 0xF3, 0x0B, 0x11, 0x2F, 0x31, 64 | 0x41, 0x51, 0x62, 0x71, 0x83, 0x91, 0xA4, 0xB1, 0xC6, 0xD1, 65 | 0xF4, 0x08, 0x11, 0x2B, 0x31, 0x4F, 0x51, 0x80, 0x94, 0xF5, 66 | 0xA2, 0xF4, 0x60, 0xF0, 0x40, 0x50, 0xC0, 0xF4, 0x70 67 | }; 68 | 69 | const unsigned char setupData[19] PROGMEM = { 70 | 0xF0, 0x81, 0xF4, 0xB3, 0xA0, 0xF0, 0x06, 0x10, 0x20, 0x30, 71 | 0xF5, 0x0F, 0x1C, 0x2F, 0x34, 0xF0, 0x91, 0xF5, 0x80 72 | }; 73 | 74 | 75 | /** 76 | * Constructor for the LM15SGFNZ07 library. 77 | * 78 | * pinCs - Arduino pin number connected to LCD's chip select pin (LCD pin 1) 79 | * pinReset - Arduino pin number connected to LCD's reset pin (LCD pin 2) 80 | * pinRs - Arduino pin number connected to LCD's register select pin (LCD pin 3) 81 | */ 82 | LM15SGFNZ07::LM15SGFNZ07(byte pinCs, byte pinReset, byte pinRs) { 83 | this->LCD_CS = pinCs; 84 | this->LCD_RESET = pinReset; 85 | this->LCD_RS = pinRs; 86 | } 87 | 88 | 89 | /** 90 | * Initialize the LCD. 91 | */ 92 | void LM15SGFNZ07::init(void) { 93 | SPI.begin(); 94 | pinMode(LCD_CS, OUTPUT); 95 | pinMode(LCD_RESET, OUTPUT); 96 | pinMode(LCD_RS, OUTPUT); 97 | 98 | LCD_CS_OFF; 99 | LCD_RESET_OFF; 100 | LCD_RS_OFF; 101 | LCD_RESET_ON; 102 | delay(10); 103 | LCD_RESET_OFF; 104 | delay(10); 105 | LCD_RS_ON; 106 | LCD_CS_ON; 107 | 108 | for (int i = 0; i < 139; i ++) { 109 | SPI.transfer(pgm_read_byte_near(initData + i)); 110 | } 111 | 112 | delay(1); 113 | LCD_CS_OFF; 114 | delay(1); 115 | LCD_CS_ON; 116 | 117 | for (int i = 0; i < 19; i ++) { 118 | SPI.transfer(pgm_read_byte_near(setupData + i)); 119 | } 120 | 121 | LCD_RS_OFF; 122 | 123 | setContrast(0x1A); 124 | delay(100); 125 | } 126 | 127 | 128 | /** 129 | * Clear the screen with the given color. 130 | * 131 | * color - 12-bit color value 132 | */ 133 | void LM15SGFNZ07::clear(unsigned int color) { 134 | LCD_CS_ON; 135 | setWindow(0, 0, 101, 80); 136 | for (int i = 0; i < 8080; i++) { 137 | SPI.transfer(color >> 8); 138 | SPI.transfer(color & 0xFF); 139 | } 140 | LCD_CS_OFF; 141 | } 142 | 143 | 144 | /** 145 | * Draw a bitmap onto the screen at the given position. 146 | * 147 | * x - Left coordinate 148 | * y - Top coordinate 149 | * width - Width of the bitmap 150 | * height - Height of the bitmap 151 | * bitmap - Pointer to the bitmap image 152 | */ 153 | void LM15SGFNZ07::drawBitmap(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned short *bitmap) { 154 | LCD_CS_ON; 155 | setWindow(x, y, width, height); 156 | for (int i = 0; i < width * height; i ++) { 157 | SPI.transfer(bitmap[i] >> 8); 158 | SPI.transfer(bitmap[i] & 0xFF); 159 | } 160 | LCD_CS_OFF; 161 | } 162 | 163 | 164 | /** 165 | * Draw a bitmap stored in progam memory onto the screen at the given position. 166 | * 167 | * x - Left coordinate 168 | * y - Top coordinate 169 | * width - Width of the bitmap 170 | * height - Height of the bitmap 171 | * bitmap - Pointer to the bitmap image 172 | */ 173 | void LM15SGFNZ07::drawBitmap(unsigned char x,unsigned char y, unsigned char width, unsigned char height, const PROGMEM unsigned short *bitmap) { 174 | LCD_CS_ON; 175 | setWindow(x, y, width, height); 176 | for (int i = 0; i < width * height; i ++) { 177 | unsigned int data = pgm_read_word_near(bitmap ++); 178 | SPI.transfer(data >> 8); 179 | SPI.transfer(data & 0xFF); 180 | } 181 | LCD_CS_OFF; 182 | } 183 | 184 | 185 | /** 186 | * Draw a line between two points in the given color. 187 | * 188 | * x1 - X coordinate of the first point 189 | * y1 - Y coordinate of the first point 190 | * x2 - X coordinate of the second point 191 | * y2 - Y coordinate of the second point 192 | * color - 12-bit color value 193 | */ 194 | void LM15SGFNZ07::drawLine(unsigned char x1, unsigned char y1, unsigned x2, unsigned char y2, unsigned int color) { 195 | LCD_CS_ON; 196 | if (y1 == y2) { 197 | // Simple solution for horizontal lines. 198 | setWindow(x1, y1, abs(x2 - x1) + 1, 1); 199 | for (int i = 0; i <= abs(x2 - x1); i ++) { 200 | SPI.transfer(color >> 8 ); 201 | SPI.transfer(color & 0xFF); 202 | } 203 | 204 | } else if (x1 == x2) { 205 | // Simple solution for vertical lines. 206 | setWindow(x1, y1, 1, abs(y2 - y1) + 1); 207 | for (int i = 0; i <= abs(y2 - y1); i ++) { 208 | SPI.transfer(color >> 8 ); 209 | SPI.transfer(color & 0xFF); 210 | } 211 | 212 | } else { 213 | // Draw diagonal line using Bresenham's algorithm. 214 | if (x2 < x1) { 215 | unsigned char t = x1; 216 | x1 = x2; 217 | x2 = t; 218 | } 219 | 220 | int dx = abs(x2 - x1); 221 | int sx = x1 < x2 ? 1 : -1; 222 | int dy = abs(y2 - y1); 223 | int sy = y1 < y2 ? 1 : -1; 224 | float err = (dx > dy ? dx : -dy) / 2; 225 | float e2; 226 | 227 | for (;;) { 228 | drawPixel(x1, y1, color); 229 | if (x1 == x2 && y1 == y2) break; 230 | e2 = err; 231 | if (e2 > -dx) { 232 | err -= dy; 233 | x1 += sx; 234 | } 235 | if (e2 < dy) { 236 | err += dx; 237 | y1 += sy; 238 | } 239 | } 240 | } 241 | LCD_CS_OFF; 242 | } 243 | 244 | 245 | /** 246 | * Draw a pixel on screen in the given color. Note that drawing individual pixels is slow due to having to set the 247 | * active window for each pixel. 248 | * 249 | * x - X coordinate of pixel 250 | * y - Y coordinate of pixel 251 | * color - 12-bit color value 252 | */ 253 | void LM15SGFNZ07::drawPixel(unsigned char x, unsigned char y, unsigned int color) { 254 | LCD_CS_ON; 255 | setWindow(x, y, 1, 1); 256 | SPI.transfer(color >> 8 ); 257 | SPI.transfer(color & 0xFF); 258 | LCD_CS_OFF; 259 | } 260 | 261 | 262 | /** 263 | * Draw a rectangular area on the screen with a given color. 264 | * 265 | * x - Left coordinate 266 | * y - Top coordinate 267 | * width - Rectangle width 268 | * height - Rectangle height 269 | * color - 12-bit color value 270 | */ 271 | void LM15SGFNZ07::drawRect(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned int color) { 272 | LCD_CS_ON; 273 | // Top 274 | setWindow(x, y, width, 1); 275 | for (int i = 0; i < width; i ++) { 276 | SPI.transfer(color >> 8); 277 | SPI.transfer(color & 0xFF); 278 | } 279 | 280 | // Bottom 281 | setWindow(x, y + height - 1, width, 1); 282 | for (int i = 0; i < width; i ++) { 283 | SPI.transfer(color >> 8); 284 | SPI.transfer(color & 0xFF); 285 | } 286 | 287 | // Left 288 | setWindow(x, y, 1, height); 289 | for (int i = 0; i < height; i ++) { 290 | SPI.transfer(color >> 8); 291 | SPI.transfer(color & 0xFF); 292 | } 293 | 294 | // Right 295 | setWindow(x + width - 1, y, 1, height); 296 | for (int i = 0; i < height; i ++) { 297 | SPI.transfer(color >> 8); 298 | SPI.transfer(color & 0xFF); 299 | } 300 | LCD_CS_OFF; 301 | } 302 | 303 | 304 | /** 305 | * Draw a string on screen. 306 | * 307 | * str - Pointer to the string to display. 308 | * x - X position of the text 309 | * y - Y position of the text 310 | * color - 12-bit text color 311 | * background - 12-bit background color 312 | */ 313 | void LM15SGFNZ07::drawString(char *str, unsigned char x, unsigned char y, unsigned int color, unsigned int background) { 314 | LCD_CS_ON; 315 | int strPos = 0; 316 | 317 | while (str[strPos] != 0) { 318 | unsigned int glyphPtr = (str[strPos] - 32) * 6; 319 | unsigned int glyphWidth = pgm_read_byte_near(font + (glyphPtr ++)); 320 | 321 | for (int i = 0; i < glyphWidth; i ++) { 322 | setWindow(x ++, y, 1, 8); 323 | unsigned char glyphData = pgm_read_byte_near(font + (glyphPtr ++)); 324 | 325 | for (unsigned char mask = 0x80; mask; mask >>= 1) { 326 | SPI.transfer(glyphData & mask ? color >> 8 : background >> 8); 327 | SPI.transfer(glyphData & mask ? color & 0xFF : background & 0xFF); 328 | } 329 | } 330 | 331 | setWindow(x ++, y, 1, 8); 332 | for (unsigned char j = 0; j < 8; j ++) { 333 | SPI.transfer(background >> 8); 334 | SPI.transfer(background & 0xFF); 335 | } 336 | strPos ++; 337 | } 338 | LCD_CS_OFF; 339 | } 340 | 341 | 342 | /** 343 | * Fill a rectangular area of the screen with a given color. 344 | * 345 | * x - Left coordinate 346 | * y - Top coordinate 347 | * width - Rectangle width 348 | * height - Rectangle height 349 | * color - 12-bit color value 350 | */ 351 | void LM15SGFNZ07::fillRect(unsigned char x, unsigned char y, unsigned char width, unsigned char height, unsigned int color) { 352 | LCD_CS_ON; 353 | setWindow(x, y, width, height); 354 | for (int i = 0; i < width * height; i ++) { 355 | SPI.transfer(color >> 8); 356 | SPI.transfer(color & 0xFF); 357 | } 358 | LCD_CS_OFF; 359 | } 360 | 361 | 362 | /** 363 | * Toggle inverse display. 364 | * 365 | * inverse - Turns inverse display on when true. 366 | */ 367 | void LM15SGFNZ07::inverseScreen(bool inverse) { 368 | LCD_RS_ON; 369 | LCD_CS_ON; 370 | SPI.transfer(0xF0); 371 | SPI.transfer(0x90 | (inverse ? 0x09 : 0x01)); 372 | LCD_CS_OFF; 373 | LCD_RS_OFF; 374 | } 375 | 376 | 377 | /** 378 | * Set a number of rows on the display to be inversed using the given inverting mode. 379 | * 380 | * y - The row to start inverting 381 | * height - The number of rows to invert 382 | * inverseMode - The inverting function to be used this can be one of the following: 383 | * LCD_INVERSE_OFF: Turns off line inversions 384 | * LCD_INVERSE_ON: Inversed lines are shown in negative 385 | * LCD_INVERSE_BLINK: Inversed lines alternate between positive and negative 386 | */ 387 | void LM15SGFNZ07::setInverseLines(unsigned char y, unsigned char height, unsigned char inverseMode) { 388 | LCD_RS_ON; 389 | LCD_CS_ON; 390 | SPI.transfer(0xF5); 391 | SPI.transfer(0x40 | (y & 0x0F)); 392 | SPI.transfer(0x50 | (y >> 4)); 393 | SPI.transfer(0xF5); 394 | SPI.transfer(0x60 | ((y + height - 1) & 0x0F)); 395 | SPI.transfer(0x70 | ((y + height - 1) >> 4)); 396 | SPI.transfer(0xF5); 397 | SPI.transfer(0x80 | (inverseMode & 0x03)); 398 | LCD_CS_OFF; 399 | LCD_RS_OFF; 400 | } 401 | 402 | 403 | /** 404 | * Set LCD contrast. 405 | * 406 | * contrast - Contrast value to set in a range from 0 to 127. A good value for this seems to be 0x1A. 407 | */ 408 | void LM15SGFNZ07::setContrast(unsigned char contrast) { 409 | LCD_RS_ON; 410 | LCD_CS_ON; 411 | SPI.transfer(0xF4); 412 | SPI.transfer(0xB0 | (contrast >> 4)); 413 | SPI.transfer(0xA0 | (contrast & 0x0F)); 414 | LCD_CS_OFF; 415 | LCD_RS_OFF; 416 | } 417 | 418 | 419 | /** 420 | * Turn the LCD on or off. When turned off display content is preserved. 421 | * 422 | * on - Turns the LCD on when true and off when false 423 | */ 424 | void LM15SGFNZ07::setLcdOn(bool on) { 425 | LCD_RS_ON; 426 | LCD_CS_ON; 427 | SPI.transfer(0xF0); 428 | SPI.transfer(0x80 | (on ? 0x01 : 0x00)); 429 | LCD_CS_OFF; 430 | LCD_RS_OFF; 431 | } 432 | 433 | 434 | /** 435 | * Set which is the top line of the LCD and wrap around display contents. 436 | * 437 | * y - Line number to be drawn first in a range from 0 to 79 438 | */ 439 | void LM15SGFNZ07::setStartLine(unsigned char y) { 440 | LCD_RS_ON; 441 | LCD_CS_ON; 442 | SPI.transfer(0xF0); 443 | SPI.transfer(0x40 | (y & 0x0F)); 444 | SPI.transfer(0x50 | (y >> 4)); 445 | LCD_CS_OFF; 446 | LCD_RS_OFF; 447 | } 448 | 449 | 450 | /** 451 | * Set the active drawing area of the LCD. The cursor will be set to the given (x, y) position. 452 | * 453 | * x - Left coordinate 454 | * y - Top coodrinate 455 | * width - Width of the active drawing area 456 | * height - Height of the active drawing area 457 | */ 458 | void LM15SGFNZ07::setWindow(unsigned char x, unsigned char y, unsigned char width, unsigned char height) { 459 | unsigned char xStart = (x << 1) + 6; 460 | unsigned char xEnd = ((x + width - 1) << 1) + 7; 461 | unsigned char yStart = y; 462 | unsigned char yEnd = y + height - 1; 463 | 464 | LCD_RS_ON; 465 | SPI.transfer(0xF0); 466 | SPI.transfer(0x00 | (xStart & 0x0F)); 467 | SPI.transfer(0x10 | (xStart >> 4)); 468 | SPI.transfer(0x20 | (yStart & 0x0F)); 469 | SPI.transfer(0x30 | (yStart >> 4)); 470 | SPI.transfer(0xF5); 471 | SPI.transfer(0x00 | (xEnd & 0x0F)); 472 | SPI.transfer(0x10 | (xEnd >> 4)); 473 | SPI.transfer(0x20 | (yEnd & 0x0F)); 474 | SPI.transfer(0x30 | (yEnd >> 4)); 475 | LCD_RS_OFF; 476 | } 477 | -------------------------------------------------------------------------------- /LM15SGFNZ07.h: -------------------------------------------------------------------------------- 1 | /** 2 | * LM15SGFNZ07.h 3 | * Siemens M55 LCD (LM15SGFNZ07) library 4 | * 5 | * Original code by Mindogas 2011. markauskas.mindaugas at gmail.com 6 | * Adapted by Maarten Janssen in 2015. maarten@cheerful.nl 7 | */ 8 | 9 | #ifndef LM15SGFNZ07 _h 10 | #define LM15SGFNZ07 _h 11 | 12 | #include 13 | 14 | 15 | // Basic colors definitions 16 | #define BLACK 0x000 17 | #define BLUE 0x00F 18 | #define GREEN 0x0F0 19 | #define CYAN 0x0FF 20 | #define RED 0xF00 21 | #define PINK 0xF0F 22 | #define YELLOW 0xFF0 23 | #define WHITE 0xFFF 24 | 25 | // Line inverse options 26 | #define LCD_INVERSE_OFF 0x00 27 | #define LCD_INVERSE_ON 0x01 28 | #define LCD_INVERSE_BLINK 0x03 29 | 30 | 31 | class LM15SGFNZ07 { 32 | public: 33 | LM15SGFNZ07(byte pinCs, byte pinReset, byte pinRs); 34 | void init(void); 35 | void clear(unsigned int color); 36 | void drawBitmap(unsigned char x,unsigned char y, unsigned char width, unsigned char height, unsigned short *bitmap); 37 | void drawBitmap(unsigned char x,unsigned char y, unsigned char width, unsigned char height, const PROGMEM unsigned short *bitmap); 38 | void drawLine(unsigned char x1, unsigned char y1, unsigned x2, unsigned char y2, unsigned int color); 39 | void drawPixel(unsigned char x, unsigned char y,unsigned int color); 40 | void drawRect(unsigned char x,unsigned char y, unsigned char width, unsigned char height, unsigned int color); 41 | void drawString(char *str, unsigned char x, unsigned char y, unsigned int color, unsigned int background); 42 | void fillRect(unsigned char x,unsigned char y, unsigned char width, unsigned char height, unsigned int color); 43 | void inverseScreen(bool inverse); 44 | void setContrast(unsigned char contrast); 45 | void setInverseLines(unsigned char y, unsigned char height, unsigned char inverseMode); 46 | void setLcdOn(bool on); 47 | void setStartLine(unsigned char y); 48 | void setWindow(unsigned char x, unsigned char y, unsigned char width, unsigned char height); 49 | 50 | private: 51 | byte LCD_CS; 52 | byte LCD_RESET; 53 | byte LCD_RS; 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LM15SGFNZ07 LCD Library for Arduino 2 | 3 | This library enables you to control an LM15SGFNZ07 LCD module with your Arduino. The LM15SGFNZ07 is an LCD with a 101x80 pixels resolution, capable of displaying 4096 colors. It is found in Siemens mobile phones (models A65, M55, C60, MC60, S55, A60). 4 | 5 | This library is an updated version of the original by Mindogas (https://bitbucket.org/mindogas/lm15sgfnz07) that supports more of the capabilities of the LCD and runs quicker than the original thanks to the use of the Arduino's SPI port for communication. 6 | 7 | To import this library into your Arduino IDE use the import library function and select the library folder or ZIP file. After importing you can run the included demo and PaddleWar! game found under LM15SGFNZ07 of the examples menu to get an understanding of this library's awesome capabilities. 8 | 9 | --- 10 | 11 | ### Connecting the LCD to the Arduino 12 | 13 | Connect the LCD using the following wiring configuration: 14 | 15 | | LCD pin | Arduino pin | 16 | |-----------|--------------------------| 17 | | 1 (/cs)1 | 62 | 18 | | 2 (/rst) | 52 | 19 | | 3 (rs) | 42 | 20 | | 4 (sclk) | 13 (or SPI SCK) | 21 | | 5 (sdata) | 11 (or SPI MOSI) | 22 | | 6 (+3.3v) | 3.3v | 23 | | 7 (gnd) | gnd | 24 | | 8 (led1) | 3.3v | 25 | | 9 (led gnd) | gnd | 26 | | 10 (led2) | 3.3v | 27 | 28 | 1 *Pin 1 of the LCD is the right most pin, closest to the edge.* 29 | 2 *The Arduino pin numbers shown here are the default ones. You are free to use any of the Arduino's digital pins for LCD communication. This is configured when creating a library instance.* 30 | 31 | --- 32 | 33 | ### Included examples 34 | 35 | The library comes with two examples: 36 | * A showcase of the library functions. 37 | * The game PaddleWar. This is the same PaddleWar game as included in the Commander Keen games. You play a game of ping pong against the Arduino and try to be the first to score 21 points. To play the game connect a potentiometer between pins A0, +5v and GND and a small speaker between pins 7 and GND. The game will start automatically when you power up the Arduino. Use the potentiometer to move wour paddle and beat the other player. The first player to reach 21 points wins and the game ends. Reset your Arduino to play again. 38 | 39 | 40 | 41 | --- 42 | 43 | ### Geting started with the library 44 | 45 | To get started be sure to first import the LM15SGFNZ07 library into your Arduino project. 46 | You then need to create an instance of the LCD driver and setup the pin configuration. 47 | Before sending any commands to the LCD you must always initialize it first by calling the init() function. 48 | This puts the LCD in a ready state (you will probably see some garbage on screen). 49 | See below for a boilerplate example or try the demo by selecting it from the Arduino IDE's examples menu. 50 | 51 | ```C 52 | #include 53 | #include 54 | 55 | LM15SGFNZ07 lcd(6, 5, 4); // Create lcd instance and set pin configuration. 56 | 57 | void setup() { 58 | lcd.init(); // Initialize lcd. 59 | lcd.clear(0x000); 60 | lcd.drawString("Hello World!", 5, 5, 0xFFF); 61 | } 62 | 63 | void loop() { 64 | // Do something awesome! 65 | } 66 | ``` 67 | 68 | --- 69 | 70 | ### Functions reference 71 | Below are the functions available in this library. 72 | 73 | 74 | ----- 75 | #### Constructor 76 | ```C 77 | LM15SGFNZ07(byte pinCs, byte pinReset, byte pinRs); 78 | ``` 79 | Create an instance of the LCD driver and set pin configuration 80 | 81 | 82 | 83 | 84 |
pinCsArduino pin number connected to LCD's chip select pin (LCD pin 1)
pinResetArduino pin number connected to LCD's reset pin (LCD pin 2)
pinRsArduino pin number connected to LCD's register select pin (LCD pin 3)
85 | 86 | 87 | ----- 88 | #### init 89 | ```C 90 | void init(void); 91 | ``` 92 | Configures the pinMode of the Arduino pins associated with the LCD and initializes the display controller. 93 | This function must always be called before sending any subsequent commands. 94 | 95 | 96 | ----- 97 | #### clear 98 | ```C 99 | void clear(unsigned int color); 100 | ``` 101 | Clears the screen with the given color value. 102 | 103 | 104 |
colorA 12-bit color value
105 | 106 | 107 | ----- 108 | #### drawBitmap 109 | ```C 110 | void drawBitmap(unsigned char x,unsigned char y, unsigned char width, unsigned char height, unsigned short *bitmap); 111 | void drawBitmap(unsigned char x,unsigned char y, unsigned char width, unsigned char height, const PROGMEM unsigned short *bitmap); 112 | ``` 113 | Draw a bitmap onto the screen. 114 | The bitmap can either be stored locally in SRAM or in program memory. 115 | Bitmap data must be stored as a one-dimensional array of 16-bit integers where each integer represents a 12-bit color value. 116 | 117 | 118 | 119 | 120 | 121 | 122 |
xX position on screen
yY position on screen
widthWidth of the bitmap image
heightHeight of the bitmap image
bitmapPointer to bitmap data in SRAM or program memory
123 | 124 | 125 | ----- 126 | #### drawLine 127 | ```C 128 | void drawLine(unsigned char x1, unsigned char y1, unsigned x2, unsigned char y2, unsigned int color); 129 | ``` 130 | Draw a line between two points in the given color. 131 | 132 | 133 | 134 | 135 | 136 | 137 |
x1X coordinate of start point
y1Y coordinate of start point
x2X coordinate of end point
y2Y coordinate of end point
color12-bit color value
138 | 139 | 140 | ----- 141 | #### drawPixel 142 | ```C 143 | void drawPixel(unsigned char x, unsigned char y,unsigned int color); 144 | ``` 145 | Place a single pixel on screen. 146 | 147 | 148 | 149 | 150 |
xX coordinate
yY coordinate
color12-bit color value
151 | 152 | 153 | ----- 154 | #### drawRect 155 | ```C 156 | void drawRect(unsigned char x,unsigned char y, unsigned char width, unsigned char height, unsigned int color); 157 | ``` 158 | Draw a rectangle on screen in the given color. 159 | 160 | 161 | 162 | 163 | 164 | 165 |
xX coordinate of left edge
yY coordinate of top edge
widthWidth of the rectangle
heightHeight of the rectangle
color12-bit color value
166 | 167 | 168 | ----- 169 | #### drawString 170 | ```C 171 | void drawString(char *str, unsigned char x, unsigned char y, unsigned int color, unsigned int background); 172 | ``` 173 | Print a text on screen. 174 | Text can have any color and always has a solid background color. 175 | In order to put as many characters on a small screen a proportional font is used. 176 | Spacing between characters is 1 pixel. 177 | 178 | To replace the font alter the font.h file that comes with the library. 179 | For each glyph in the font we define the number of columns in the glyph bitmap between 1 and 5. 180 | This is followed by the bit pattern of each column. 181 | Glyphs that are less than 5 columns wide must be padded so that each glyph takes 6 bytes of data. 182 | 183 | 184 | 185 | 186 | 187 | 188 |
strThe text string to print
xX coordinate of the text
yY coordinate of the text
color12-bit color of the text
background12-bit color of the text background
189 | 190 | 191 | ----- 192 | #### fillRect 193 | ```C 194 | void fillRect(unsigned char x,unsigned char y, unsigned char width, unsigned char height, unsigned int color); 195 | ``` 196 | Draws a filled rectangle. 197 | 198 | 199 | 200 | 201 | 202 | 203 |
xX coordinate of left edge
yY coordinate of top edge
widthWidth of the rectangle
heightHeight of the rectangle
color12-bit color value
204 | 205 | 206 | ----- 207 | #### inverseScreen 208 | ```C 209 | void inverseScreen(bool inverse); 210 | ``` 211 | Switches inverse colors on or off. 212 | This can be useful to briefly flash the screen to get a users attention. 213 | 214 | 215 |
inverseSwitches inverse color mode on when true
216 | 217 | 218 | ----- 219 | #### setContrast 220 | ```C 221 | void setContrast(unsigned char contrast); 222 | ``` 223 | Sets the contrast of the sreen. 224 | A good contrast value seems to be 0x1A, which is also set as default by the init function. 225 | 226 | 227 |
contrastA contrast value ranging from 0 to 127
228 | 229 | 230 | ----- 231 | #### setInverseLines 232 | ```C 233 | void setInverseLines(unsigned char y, unsigned char height, unsigned char inverseMode); 234 | ``` 235 | Sets inverse or blink mode for a certain number of lines on the screen. 236 | The controller of this LCD is able to blink a certain number of lines on the screen every 32 frames. 237 | This can be a useful function to highlight certain areas on the screen. 238 | For example a selected menu option. 239 | If the screen is already in inverse mode then setting lines to inverse will reverse the effect. 240 | 241 | Three inverting modes are available: 242 | * LCD_INVERSE_OFF - Disables line inversion mode 243 | * LCD_INVERSE_ON - Inverses the given area on screen 244 | * LCD_INVERSE_BLINK - Inverses and blinks the given area 245 | 246 | 247 | 248 | 249 |
yStart line
heightNumber of lines to inverse
inverseModeDefines how the lines are inverted
250 | 251 | 252 | ----- 253 | #### setLcdOn 254 | ```C 255 | void setLcdOn(bool on); 256 | ``` 257 | Switches the LCD screen on or off. 258 | The init method switches the screen on, so this function is not required prior to sending any commands. 259 | When the screen is switched off the content is preserved. 260 | 261 | 262 |
onSwitches the screen on when true and off when false
263 | 264 | 265 | ----- 266 | #### setStartLine 267 | ```C 268 | void setStartLine(unsigned char y); 269 | ``` 270 | Sets the line that is to be displayed as the first line in screen. 271 | After line 79 the display wraps around to line 0. 272 | 273 | 274 |
yLine number to be displayed on top ranging from 0 to 79
275 | 276 | 277 | ----- 278 | #### setWindow 279 | ```C 280 | void setWindow(unsigned char x, unsigned char y, unsigned char width, unsigned char height); 281 | ``` 282 | Defines the active drawing area. 283 | When color data is sent to the display it is placed in this area. 284 | Both width and height wrap around when more data is sent than fit into the area. 285 | 286 | 287 | 288 | 289 | 290 |
xX coordinate of the left edge of the active area
yY coordinate of the top edge of the active area
widthWidth of the area
heightHeight of the area
291 | 292 | 293 | ----- 294 | #### Colors 295 | The following predefined colors are available. 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 |
BLACK0x000
BLUE0x00F
GREEN0x0F0
CYAN0x0FF
RED0xF00
PINK0xF0F
YELLOW0xFF0
WHITE0xFFF
306 | 307 | 308 | ----- 309 | #### Pin toggle functions 310 | The following functions toggle the control pins of the LCD. 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 |
LCD_RS_ONPut the LCD in command mode
LCD_RS_OFFPut the LCD in data mode
LCD_CS_OFFDisables the LCD (current state is preserved)
LCD_CS_ONEnables the LCD
LCD_RESET_ONPuts the LCD in reset mode
LCD_RESET_OFFPuts the LCD in normal mode
319 | -------------------------------------------------------------------------------- /digitalWriteFast.h: -------------------------------------------------------------------------------- 1 | #if !defined(digitalPinToPortReg) 2 | #if !(defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) ) 3 | 4 | 5 | // Standard Arduino Pins 6 | #define digitalPinToPortReg(P) \ 7 | (((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC)) 8 | #define digitalPinToDDRReg(P) \ 9 | (((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC)) 10 | #define digitalPinToPINReg(P) \ 11 | (((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC)) 12 | #define digitalPinToBit(P) \ 13 | (((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14)) 14 | 15 | #if defined(__AVR_ATmega8__) 16 | 17 | // 3 PWM 18 | #define digitalPinToTimer(P) \ 19 | (((P) == 9 || (P) == 10) ? &TCCR1A : (((P) == 11) ? &TCCR2 : 0)) 20 | #define digitalPinToTimerBit(P) \ 21 | (((P) == 9) ? COM1A1 : (((P) == 10) ? COM1B1 : COM21)) 22 | #else 23 | 24 | // 6 PWM 25 | #define digitalPinToTimer(P) \ 26 | (((P) == 6 || (P) == 5) ? &TCCR0A : \ 27 | (((P) == 9 || (P) == 10) ? &TCCR1A : \ 28 | (((P) == 11 || (P) == 3) ? &TCCR2A : 0))) 29 | #define digitalPinToTimerBit(P) \ 30 | (((P) == 6) ? COM0A1 : (((P) == 5) ? COM0B1 : \ 31 | (((P) == 9) ? COM1A1 : (((P) == 10) ? COM1B1 : \ 32 | (((P) == 11) ? COM2A1 : COM2B1))))) 33 | #endif 34 | 35 | #else 36 | // Arduino Mega Pins 37 | #define digitalPinToPortReg(P) \ 38 | (((P) >= 22 && (P) <= 29) ? &PORTA : \ 39 | ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \ 40 | (((P) >= 30 && (P) <= 37) ? &PORTC : \ 41 | ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : \ 42 | ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PORTE : \ 43 | (((P) >= 54 && (P) <= 61) ? &PORTF : \ 44 | ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : \ 45 | ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : \ 46 | (((P) == 14 || (P) == 15) ? &PORTJ : \ 47 | (((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL)))))))))) 48 | 49 | #define digitalPinToDDRReg(P) \ 50 | (((P) >= 22 && (P) <= 29) ? &DDRA : \ 51 | ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \ 52 | (((P) >= 30 && (P) <= 37) ? &DDRC : \ 53 | ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : \ 54 | ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &DDRE : \ 55 | (((P) >= 54 && (P) <= 61) ? &DDRF : \ 56 | ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : \ 57 | ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : \ 58 | (((P) == 14 || (P) == 15) ? &DDRJ : \ 59 | (((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL)))))))))) 60 | 61 | #define digitalPinToPINReg(P) \ 62 | (((P) >= 22 && (P) <= 29) ? &PINA : \ 63 | ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \ 64 | (((P) >= 30 && (P) <= 37) ? &PINC : \ 65 | ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : \ 66 | ((((P) >= 0 && (P) <= 3) || (P) == 5) ? &PINE : \ 67 | (((P) >= 54 && (P) <= 61) ? &PINF : \ 68 | ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : \ 69 | ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : \ 70 | (((P) == 14 || (P) == 15) ? &PINJ : \ 71 | (((P) >= 62 && (P) <= 69) ? &PINK : &PINL)))))))))) 72 | 73 | #define digitalPinToBit(P) \ 74 | (((P) >= 7 && (P) <= 9) ? (P) - 3 : \ 75 | (((P) >= 10 && (P) <= 13) ? (P) - 6 : \ 76 | (((P) >= 22 && (P) <= 29) ? (P) - 22 : \ 77 | (((P) >= 30 && (P) <= 37) ? 37 - (P) : \ 78 | (((P) >= 39 && (P) <= 41) ? 41 - (P) : \ 79 | (((P) >= 42 && (P) <= 49) ? 49 - (P) : \ 80 | (((P) >= 50 && (P) <= 53) ? 53 - (P) : \ 81 | (((P) >= 54 && (P) <= 61) ? (P) - 54 : \ 82 | (((P) >= 62 && (P) <= 69) ? (P) - 62 : \ 83 | (((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \ 84 | (((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \ 85 | (((P) == 19) ? 2 : \ 86 | (((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \ 87 | (((P) == 2) ? 4 : \ 88 | (((P) == 3 || (P) == 4) ? 5 : 7))))))))))))))) 89 | 90 | // 15 PWM 91 | #define digitalPinToTimer(P) \ 92 | (((P) == 13 || (P) == 4) ? &TCCR0A : \ 93 | (((P) == 11 || (P) == 12) ? &TCCR1A : \ 94 | (((P) == 10 || (P) == 9) ? &TCCR2A : \ 95 | (((P) == 5 || (P) == 2 || (P) == 3) ? &TCCR3A : \ 96 | (((P) == 6 || (P) == 7 || (P) == 8) ? &TCCR4A : \ 97 | (((P) == 46 || (P) == 45 || (P) == 44) ? &TCCR5A : 0)))))) 98 | #define digitalPinToTimerBit(P) \ 99 | (((P) == 13) ? COM0A1 : (((P) == 4) ? COM0B1 : \ 100 | (((P) == 11) ? COM1A1 : (((P) == 12) ? COM1B1 : \ 101 | (((P) == 10) ? COM2A1 : (((P) == 9) ? COM2B1 : \ 102 | (((P) == 5) ? COM3A1 : (((P) == 2) ? COM3B1 : (((P) == 3) ? COM3C1 : \ 103 | (((P) == 6) ? COM4A1 : (((P) == 7) ? COM4B1 : (((P) == 8) ? COM4C1 : \ 104 | (((P) == 46) ? COM5A1 : (((P) == 45) ? COM5B1 : COM5C1)))))))))))))) 105 | 106 | #endif 107 | #endif 108 | 109 | #if !defined(digitalWriteFast) 110 | #define digitalWriteFast(P, V) \ 111 | if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ 112 | if (digitalPinToTimer(P)) \ 113 | bitClear(*digitalPinToTimer(P), digitalPinToTimerBit(P)); \ 114 | bitWrite(*digitalPinToPortReg(P), digitalPinToBit(P), (V)); \ 115 | } else { \ 116 | digitalWrite((P), (V)); \ 117 | } 118 | #endif 119 | 120 | #if !defined(pinModeFast) 121 | #define pinModeFast(P, V) \ 122 | if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ 123 | bitWrite(*digitalPinToDDRReg(P), digitalPinToBit(P), (V)); \ 124 | } else { \ 125 | pinMode((P), (V)); \ 126 | } 127 | #endif 128 | 129 | #if !defined(digitalReadFast) 130 | #define digitalReadFast(P) ( (int) __digitalReadFast__((P)) ) 131 | #define __digitalReadFast__(P ) \ 132 | (__builtin_constant_p(P) ) ? ( \ 133 | digitalPinToTimer(P) ? ( \ 134 | bitClear(*digitalPinToTimer(P), digitalPinToTimerBit(P)) , \ 135 | bitRead(*digitalPinToPINReg(P), digitalPinToBit(P))) : \ 136 | bitRead(*digitalPinToPINReg(P), digitalPinToBit(P))) : \ 137 | digitalRead((P)) 138 | #endif 139 | 140 | #if !defined(digitalWriteFast2) 141 | #define digitalWriteFast2(P, V) \ 142 | if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ 143 | bitWrite(*digitalPinToPortReg(P), digitalPinToBit(P), (V)); \ 144 | } else { \ 145 | digitalWrite((P), (V)); \ 146 | } 147 | #endif 148 | 149 | #if !defined(pinModeFast2) 150 | #define pinModeFast2(P, V) \ 151 | if (__builtin_constant_p(P) && __builtin_constant_p(V)) { \ 152 | if (digitalPinToTimer(P)) \ 153 | bitClear(*digitalPinToTimer(P), digitalPinToTimerBit(P)); \ 154 | bitWrite(*digitalPinToDDRReg(P), digitalPinToBit(P), (V)); \ 155 | } else { \ 156 | pinMode((P), (V)); \ 157 | } 158 | #endif 159 | 160 | #if !defined(digitalReadFast2) 161 | #define digitalReadFast2(P) ( (int) __digitalReadFast2__((P)) ) 162 | #define __digitalReadFast2__(P ) \ 163 | (__builtin_constant_p(P) ) ? ( \ 164 | ( bitRead(*digitalPinToPINReg(P), digitalPinToBit(P))) ) : \ 165 | digitalRead((P)) 166 | #endif 167 | -------------------------------------------------------------------------------- /examples/LM15SGFNZ07_demo/LM15SGFNZ07_demo.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Demo sketch for the LM15SGFNZ07 LCD display library. This demo consists of 3 parts to show most of the capabilities 3 | * of the LM15SGFNZ07 library. 4 | * Coded by Maarten Janssen in 2015. 5 | * 6 | * Latest version of the libaray can be downloaded from my GitHub page: http://github.com/DhrBaksteen 7 | * Contact me at maarten@cheerful.nl 8 | * 9 | * The LM15SGFNZ07 is an LCD with a 101x80 pixels resolution, capable of displaying 4096 colors. It is found in Siemens 10 | * mobile phones (models A65, M55, C60, MC60, S55, A60). Connect the LCD to your Arduino as follows: 11 | * LCD pin --> Arduino pin 12 | * 1 (/CS) 6 13 | * 2 (/RST) 5 14 | * 3 (RS) 4 15 | * 4 (Sclk) 13 (or SPI SCK) 16 | * 5 (Sdata) 11 (or SPI MOSI) 17 | * 6 (+3.3v) 3.3v 18 | * 7 (GND) GND 19 | * 8 (LED1) 3.3v 20 | * 9 (GND) GND 21 | * 10 (LED2) 3.3v 22 | */ 23 | 24 | #include 25 | #include 26 | #include "icon.h" 27 | 28 | LM15SGFNZ07 lcd(6, 5, 4); 29 | 30 | void setup() 31 | { 32 | lcd.init(); 33 | } 34 | 35 | void loop() { 36 | demo1(); 37 | demo2(); 38 | demo3(); 39 | } 40 | 41 | void demo1() { 42 | lcd.clear(0x000); 43 | lcd.fillRect(1, 0, 14, 45, 0xFFF); 44 | lcd.fillRect(15, 0, 14, 45, 0xFF0); 45 | lcd.fillRect(29, 0, 14, 45, 0x0FF); 46 | lcd.fillRect(43, 0, 14, 45, 0x0F0); 47 | lcd.fillRect(57, 0, 14, 45, 0xF0F); 48 | lcd.fillRect(71, 0, 14, 45, 0xF00); 49 | lcd.fillRect(85, 0, 14, 45, 0x00F); 50 | 51 | lcd.fillRect(1, 45, 98, 15, 0xF00); 52 | lcd.drawString("LM15SGFNZ07", 18, 49, 0xFFF, 0xF00); 53 | 54 | for (int i = 0; i < 16; i ++) { 55 | lcd.fillRect(i * 6 + 1, 60, 8, 5, (i << 8) + (i << 4) + i); 56 | lcd.fillRect(i * 6 + 1, 65, 8, 5, i << 8); 57 | lcd.fillRect(i * 6 + 1, 70, 8, 5, i << 4); 58 | lcd.fillRect(i * 6 + 1, 75, 8, 5, i); 59 | } 60 | 61 | delay(10000); 62 | } 63 | 64 | 65 | void demo2() { 66 | lcd.clear(0xFFF); 67 | 68 | for (int i = 2; i < 80; i += 5) { 69 | lcd.drawLine(0, i, 100, i, 0x888); 70 | } 71 | 72 | for (int i = 2; i < 101; i += 5) { 73 | lcd.drawLine(i, 0, i, 79, 0x888); 74 | } 75 | 76 | lcd.fillRect(0, 0, 10, 10, 0x00F); 77 | lcd.fillRect(91, 0, 10, 10, 0x0F0); 78 | lcd.fillRect(91, 70, 10, 10, 0xFF0); 79 | lcd.fillRect(0, 70, 10, 10, 0xF00); 80 | 81 | lcd.fillRect(10, 0, 81, 5, 0x0FF); 82 | lcd.fillRect(96, 10, 5, 60, 0x8F0); 83 | lcd.fillRect(10, 75, 81, 5, 0xF80); 84 | lcd.fillRect(0, 10, 5, 60, 0xF0F); 85 | 86 | lcd.drawBitmap(34, 24, 32, 32, icon); 87 | delay(10000); 88 | } 89 | 90 | 91 | void demo3() { 92 | lcd.clear(0x22F); 93 | lcd.drawRect(0, 0, 101, 80, 0xFFF); 94 | 95 | for (unsigned char x = 0; x <= 80; x += 10) { 96 | lcd.drawLine(0, x, x, 80, 0xFFF); 97 | lcd.drawLine(20 + x, 0, 100, x, 0xFFF); 98 | } 99 | 100 | lcd.drawString("Arduino", 28, 35, 0xFFF, 0x22F); 101 | lcd.drawBitmap(63, 34, 11, 9, heart); 102 | delay(10000); 103 | } 104 | 105 | -------------------------------------------------------------------------------- /examples/LM15SGFNZ07_demo/icon.h: -------------------------------------------------------------------------------- 1 | const unsigned short icon[1024] PROGMEM = { 2 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 3 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 4 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 5 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 6 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x00F, 0x000, 0xFFF, 0xFFF, 7 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 8 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x00F, 0x00F, 0x000, 0xFFF, 9 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 10 | 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0x000, 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x00F, 0x00F, 0x000, 0xFFF, 11 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 12 | 0xFFF, 0xFFF, 0x000, 0x000, 0xFF0, 0x000, 0x880, 0x000, 0x000, 0xFFF, 0xFFF, 0x000, 0x00F, 0xFFF, 0x00F, 0x000, 13 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xAAA, 0x888, 0x888, 0xAAA, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 14 | 0xFFF, 0x000, 0xFF0, 0x000, 0x000, 0x000, 0x880, 0x000, 0x000, 0xFFF, 0xFFF, 0x000, 0x888, 0x888, 0xAAA, 0x000, 15 | 0xFFF, 0xFFF, 0xFFF, 0x000, 0xAAA, 0x888, 0x000, 0x000, 0x888, 0xAAA, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 16 | 0xFFF, 0x000, 0x000, 0xFF0, 0x880, 0x880, 0x000, 0x880, 0x000, 0xFFF, 0xFFF, 0x000, 0x888, 0xAAA, 0xAAA, 0x000, 17 | 0xFFF, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 18 | 0xFFF, 0x000, 0x880, 0x000, 0x000, 0x000, 0x880, 0x880, 0x000, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0x000, 0xFFF, 19 | 0xFFF, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 20 | 0xFFF, 0xFFF, 0x000, 0xFF0, 0xFF0, 0x888, 0x880, 0x880, 0x000, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xAAA, 0x000, 0xFFF, 21 | 0xFFF, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 0xFFF, 0x000, 0x888, 0x000, 0xFFF, 0x000, 0x000, 0x000, 0xFFF, 0xFFF, 22 | 0xFFF, 0xFFF, 0x000, 0x880, 0xFF0, 0x888, 0x888, 0x880, 0x000, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 0xFFF, 23 | 0xFFF, 0xFFF, 0xFFF, 0x000, 0xAAA, 0x000, 0x000, 0x888, 0x000, 0xFFF, 0x000, 0x888, 0x888, 0xAAA, 0x000, 0xFFF, 24 | 0xFFF, 0xFFF, 0xFFF, 0x000, 0xFF0, 0xFF0, 0x888, 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xFFF, 0x000, 0xFFF, 25 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x888, 0x888, 0x000, 0xFFF, 0x000, 0x888, 0x000, 0x000, 0x888, 0xAAA, 0x000, 26 | 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0x000, 0x000, 0x880, 0x880, 0x000, 0xFFF, 0xFFF, 0x000, 0x000, 0x000, 0xFFF, 27 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 0xFFF, 0x000, 0x888, 0x000, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 28 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xFF0, 0x888, 0x880, 0x880, 0x000, 0xFFF, 0xFFF, 0x000, 0xF00, 0x000, 0xFFF, 29 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 0x000, 0x888, 0x000, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x888, 0x000, 30 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xFF0, 0x888, 0x888, 0x880, 0x000, 0xFFF, 0xFFF, 0x000, 0xF00, 0x000, 0xFFF, 31 | 0xFFF, 0xFFF, 0xFFF, 0x000, 0x888, 0x888, 0x888, 0x888, 0x888, 0x000, 0x000, 0x000, 0x000, 0x888, 0xAAA, 0x000, 32 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x880, 0xFF0, 0x888, 0x880, 0x880, 0x000, 0x000, 0x000, 0xF00, 0x000, 0x000, 33 | 0x000, 0x000, 0x000, 0x888, 0x000, 0x888, 0x000, 0x000, 0x000, 0xAAA, 0x888, 0x888, 0x888, 0xAAA, 0x000, 0xFFF, 34 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xFF0, 0x888, 0x880, 0x880, 0x000, 0x0FF, 0x000, 0xF00, 0x000, 0x0FF, 35 | 0x088, 0x000, 0x888, 0x888, 0x888, 0x000, 0x000, 0xFFF, 0xFFF, 0x000, 0x000, 0x000, 0x000, 0x000, 0xFFF, 0xFFF, 36 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0xFF0, 0x888, 0x888, 0x880, 0x000, 0x088, 0x000, 0xF00, 0x000, 0x088, 37 | 0x000, 0x888, 0x888, 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 38 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0x880, 0xFF0, 0x888, 0x880, 0x880, 0x000, 0x000, 0xF00, 0x000, 0x000, 39 | 0x888, 0x888, 0x000, 0xAAA, 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 40 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x088, 0x000, 0x000, 0x880, 0x880, 0x880, 0x000, 0x000, 0xF00, 0x000, 0x888, 41 | 0x888, 0x000, 0x000, 0x000, 0x088, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 42 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0xFFF, 0x0FF, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 43 | 0x000, 0x000, 0x0FF, 0x088, 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 44 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0x000, 0x0FF, 0xFFF, 0x0FF, 0xFFF, 0x0FF, 0xFFF, 0x0FF, 0xFFF, 45 | 0x0FF, 0xFFF, 0x000, 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 46 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x088, 0x088, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 47 | 0x000, 0x000, 0x088, 0x088, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 48 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x088, 0x088, 0x088, 0x088, 0x088, 0x088, 0x088, 0x088, 0x088, 0x088, 49 | 0x088, 0x088, 0x088, 0x088, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 50 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x088, 0x888, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 51 | 0x088, 0x088, 0x088, 0x088, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 52 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x088, 0x888, 0x0FF, 0xFFF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 53 | 0x0FF, 0x888, 0x088, 0x088, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 54 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x088, 0x888, 0x0FF, 0xFFF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 55 | 0x0FF, 0x888, 0x088, 0x088, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 56 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x088, 0x888, 0x0FF, 0xFFF, 0xFFF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 57 | 0x0FF, 0x888, 0x088, 0x088, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 58 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x088, 0x888, 0x0FF, 0x888, 0xFFF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 59 | 0x0FF, 0x888, 0x088, 0x088, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 60 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x088, 0x888, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 0x0FF, 61 | 0x0FF, 0x888, 0x088, 0x088, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 62 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0x888, 0x888, 0x888, 0x888, 0x888, 0x888, 0x888, 0x888, 63 | 0x888, 0x088, 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 64 | 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 65 | 0x000, 0x000, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF 66 | }; 67 | 68 | 69 | const unsigned short heart[99] PROGMEM = { 70 | 0x22F, 0xA00, 0xA00, 0xA00, 0x22F, 0x22F, 0x22F, 0xA00, 0xA00, 0xA00, 0x22F, 71 | 0xA00, 0xFAA, 0xFAA, 0xFAA, 0xA00, 0x22F, 0xA00, 0xFAA, 0xFAA, 0xFAA, 0xA00, 72 | 0xA00, 0xF88, 0xF88, 0xF88, 0xF88, 0xA00, 0xF88, 0xF88, 0xF88, 0xF88, 0xA00, 73 | 0xA00, 0xF66, 0xF66, 0xF66, 0xF66, 0xF66, 0xF66, 0xF66, 0xF66, 0xF66, 0xA00, 74 | 0x22F, 0xA00, 0xF44, 0xF44, 0xF44, 0xF44, 0xF44, 0xF44, 0xF44, 0xA00, 0x22F, 75 | 0x22F, 0x22F, 0xA00, 0xF22, 0xF22, 0xF22, 0xF22, 0xF22, 0xA00, 0x22F, 0x22F, 76 | 0x22F, 0x22F, 0x22F, 0xA00, 0xF00, 0xF00, 0xF00, 0xA00, 0x22F, 0x22F, 0x22F, 77 | 0x22F, 0x22F, 0x22F, 0x22F, 0xA00, 0xF00, 0xA00, 0x22F, 0x22F, 0x22F, 0x22F, 78 | 0x22F, 0x22F, 0x22F, 0x22F, 0x22F, 0xA00, 0x22F, 0x22F, 0x22F, 0x22F, 0x22F 79 | }; 80 | -------------------------------------------------------------------------------- /examples/PaddleWar/PaddleWar.ino: -------------------------------------------------------------------------------- 1 | /** 2 | * Demo sketch for the LM15SGFNZ07 LCD display library. This demo lets you play the PaddleWar! game from the Commander 3 | * Keen series. Connect a potentionmeter to A0, +5v and GND to control your paddle. Simple sounds are provided if you 4 | * connect a small speaker between pins 7 and GND. The game will start automatically and end when either you or the 5 | * Arduino reach 21 points. Reset your Arduino for another game. 6 | * Coded by Maarten Janssen in 2015. 7 | * 8 | * Latest version of the libaray can be downloaded from my GitHub page: http://github.com/DhrBaksteen 9 | * Contact me at maarten@cheerful.nl 10 | * 11 | * The LM15SGFNZ07 is an LCD with a 101x80 pixels resolution, capable of displaying 4096 colors. It is found in Siemens 12 | * mobile phones (models A65, M55, C60, MC60, S55, A60). Connect the LCD to your Arduino as follows: 13 | * LCD pin --> Arduino pin 14 | * 1 (/CS) 6 15 | * 2 (/RST) 5 16 | * 3 (RS) 4 17 | * 4 (Sclk) 13 (or SPI SCK) 18 | * 5 (Sdata) 11 (or SPI MOSI) 19 | * 6 (+3.3v) 3.3v 20 | * 7 (GND) GND 21 | * 8 (LED1) 3.3v 22 | * 9 (GND) GND 23 | * 10 (LED2) 3.3v 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | 32 | const unsigned short bmpPaddleWar[296] PROGMEM = { 33 | 0x555, 0x5F5, 0x5F5, 0x5F5, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x5F5, 34 | 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x5F5, 35 | 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x555, 0x5F5, 36 | 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x555, 0x5F5, 0x555, 0x555, 0x5F5, 0x5F5, 0x555, 0x555, 0x5F5, 0x5F5, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x5F5, 0x5F5, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x5F5, 0x5F5, 0x555, 0x555, 0x5F5, 37 | 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 38 | 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x5F5, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x555, 0x5F5, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x5F5, 0x5F5, 0x555, 0x5F5, 0x5F5, 0x555, 0x555, 0x5F5, 39 | 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x555, 0x5F5, 0x555, 0x555, 0x5F5, 0x5F5, 0x555, 0x5F5, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x555, 40 | 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x5F5, 0x555, 0x555, 0x5F5, 0x5F5, 0x555, 0x555, 0x5F5, 0x5F5, 0x555, 0x5F5, 0x5F5, 0x555, 0x5F5, 0x555, 0x555, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5, 0x555, 0x5F5 41 | }; 42 | 43 | const unsigned short bmpPaddle[36] PROGMEM = { 44 | 0x555, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x555, 45 | 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 46 | 0x555, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x5F5, 0x555 47 | }; 48 | 49 | const unsigned short bmpBall[16] PROGMEM = { 50 | 0x555, 0x5F5, 0x5F5, 0x555, 51 | 0x5F5, 0x5F5, 0x5F5, 0x5F5, 52 | 0x5F5, 0x5F5, 0x5F5, 0x5F5, 53 | 0x555, 0x5F5, 0x5F5, 0x555 54 | }; 55 | 56 | 57 | LM15SGFNZ07 lcd(6,5,4); 58 | 59 | int paddleBottom = 0; 60 | float paddleTop = 43; 61 | int p1Score = 0; 62 | int p2Score = 0; 63 | int hold = 0; 64 | float ballX = 48; 65 | float ballY = 42; 66 | float ballDx = 0.5; 67 | float ballDy = -0.5; 68 | 69 | 70 | /** 71 | * Initialize LCD and PaddleWar game. 72 | */ 73 | void setup() { 74 | lcd.init(); 75 | lcd.clear(0x555); 76 | lcd.drawLine(0, 10, 101, 10, 0x5F5); 77 | lcd.drawLine(0, 75, 101, 75, 0x5F5); 78 | lcd.drawString("0", 2, 2, 0x5F5, 0x555); 79 | lcd.drawString("0", 88, 2, 0x5F5, 0x555); 80 | lcd.drawBitmap(32, 1, 37, 8, bmpPaddleWar); 81 | 82 | ballDx = (random(2) - 0.5) / 2; 83 | ballDy = random(2) - 0.5; 84 | hold = 100; 85 | } 86 | 87 | 88 | /** 89 | * Main game loop. 90 | */ 91 | void loop() { 92 | // Update player paddle position and remove old sprites. 93 | int newpaddleBottom = analogRead(0) / 12 + 2; 94 | if (paddleBottom != newpaddleBottom) { 95 | lcd.fillRect(paddleBottom, 71, 14, 3, 0x555); 96 | paddleBottom = newpaddleBottom; 97 | } 98 | lcd.fillRect((int)paddleTop, 12, 14, 3, 0x555); 99 | lcd.fillRect((int)ballX, (int)ballY, 4, 4, 0x555); 100 | 101 | if (hold == 0) { 102 | // Move Arduino's paddle. 103 | if (ballX < paddleTop + 5 && paddleTop > 0) { 104 | paddleTop -= 0.25; 105 | } else if (ballX > paddleTop + 5 && paddleTop < 89) { 106 | paddleTop += 0.25; 107 | } 108 | 109 | // Horizontal ball movement and bounce. 110 | ballX += ballDx; 111 | if (ballX >= 97) { 112 | ballX = 97; 113 | ballDx = -ballDx; 114 | tone(7, 1000, 100); 115 | } else if (ballX <= 0) { 116 | ballX = 0; 117 | ballDx = -ballDx; 118 | tone(7, 1000, 100); 119 | } 120 | 121 | // Vertical ball movement. 122 | ballY += ballDy; 123 | if (ballY > 68 && ballY < 71 && ballDy > 0) { 124 | // Bounce off player's paddle. 125 | bouncePaddle(paddleBottom); 126 | } else if (ballY < 15 && ballY > 11 && ballDy < 0) { 127 | // Bounce off Arduino's paddle. 128 | bouncePaddle(paddleTop); 129 | } else if (ballY >= 71 || ballY <= 11) { 130 | // Player or Arduino missed the ball. 131 | miss(); 132 | } 133 | } else { 134 | hold --; 135 | } 136 | 137 | // Paint ball and paddles. 138 | if (hold == 0) { 139 | lcd.drawBitmap((int)ballX, (int)ballY, 4, 4, bmpBall); 140 | } 141 | lcd.drawBitmap((int)paddleTop, 12, 12, 3, bmpPaddle); 142 | lcd.drawBitmap(paddleBottom, 71, 12, 3, bmpPaddle); 143 | 144 | delay(10); 145 | } 146 | 147 | 148 | /** 149 | * Check whether the baddle hits the ball and make it bounce off. 150 | */ 151 | void bouncePaddle(int paddleX) { 152 | int collision = ballX - paddleX + 4; 153 | if (collision > 0 && collision < 16) { 154 | // If the ball is hit reverse Y direction and determine 155 | // X direction from where the ball hit the paddle 156 | ballDy = -ballDy; 157 | tone(7, 1200, 100); 158 | if (collision < 4) { 159 | ballDx = -0.5; 160 | } else if (collision < 8) { 161 | ballDx = -0.25; 162 | } else if (collision < 12) { 163 | ballDx = 0.25; 164 | } else { 165 | ballDx = 0.5; 166 | } 167 | } 168 | } 169 | 170 | 171 | /** 172 | * Either the player or the Arduino missed the ball. 173 | */ 174 | void miss() { 175 | char score[3]; 176 | if (ballY <= 11) { 177 | // Update player score. End game if 21. 178 | p1Score ++; 179 | tone(7, 600, 100); 180 | String(p1Score).toCharArray(score, 3); 181 | lcd.fillRect(1, 2, 12, 8, 0x555); 182 | lcd.drawString(score, 1, 1, 0x5F5, 0x555); 183 | if (p1Score == 21) endGame(true); 184 | } else { 185 | // Update Arduino's score. End game if 21. 186 | p2Score ++; 187 | tone(7, 100, 500); 188 | String(p2Score).toCharArray(score, 3); 189 | lcd.fillRect(88, 2, 12, 8, 0x555); 190 | lcd.drawString(score, 88, 1, 0x5F5, 0x555); 191 | if (p2Score == 21) endGame(false); 192 | } 193 | 194 | // Set up next ball. 195 | ballY = 42; 196 | ballX = 48; 197 | ballDx = (random(2) - 0.5) / 2; 198 | hold = 100; 199 | } 200 | 201 | 202 | /** 203 | * Show win or lose message when game ends and stop. 204 | */ 205 | void endGame(bool hasWon) { 206 | for (int i = 1; i < 180; i += 2) { 207 | lcd.drawLine(0, i, i, 0, 0x555); 208 | } 209 | lcd.fillRect(20, 22, 60, 36, 0x555); 210 | lcd.drawRect(20, 22, 60, 36, 0x5F5); 211 | lcd.drawBitmap(32, 25, 37, 8, bmpPaddleWar); 212 | lcd.drawLine(20, 35, 79, 35, 0x5F5); 213 | if (hasWon) { 214 | lcd.drawString("You win!", 34, 43, 0x5F5, 0x555); 215 | } else { 216 | lcd.drawString("You lost!", 32, 43, 0x5F5, 0x555); 217 | } 218 | while(true); 219 | } 220 | -------------------------------------------------------------------------------- /font.h: -------------------------------------------------------------------------------- 1 | const unsigned char font[576] PROGMEM = { 2 | 2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, // Sp 3 | 1, 0b11111010, 0b00000000, 0b00000000, 0b00000000, 0b00000000, // ! 4 | 3, 0b11100000, 0b00000000, 0b11100000, 0b00000000, 0b00000000, // " 5 | 5, 0b00101000, 0b11111110, 0b00101000, 0b11111110, 0b00101000, // # 6 | 5, 0b00100100, 0b01010100, 0b11111110, 0b01010100, 0b01001000, // $ 7 | 5, 0b11000110, 0b11001000, 0b00010000, 0b00100110, 0b11000110, // % 8 | 5, 0b01101100, 0b10010010, 0b01101010, 0b00000100, 0b00001010, // & 9 | 1, 0b11100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, // ' 10 | 2, 0b01111100, 0b10000010, 0b00000000, 0b00000000, 0b00000000, // ( 11 | 2, 0b10000010, 0b01111100, 0b00000000, 0b00000000, 0b00000000, // ) 12 | 5, 0b00101000, 0b00010000, 0b01111100, 0b00010000, 0b00101000, // * 13 | 5, 0b00010000, 0b00010000, 0b01111100, 0b00010000, 0b00010000, // + 14 | 2, 0b00000010, 0b00000100, 0b00000000, 0b00000000, 0b00000000, // , 15 | 5, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, // - 16 | 1, 0b00000010, 0b00000000, 0b00000000, 0b00000000, 0b00000000, // . 17 | 5, 0b00000110, 0b00001000, 0b00010000, 0b00100000, 0b11000000, // / 18 | 5, 0b01111100, 0b10001010, 0b10010010, 0b10100010, 0b01111100, // 0 19 | 3, 0b01000010, 0b11111110, 0b00000010, 0b00000000, 0b00000000, // 1 20 | 5, 0b01000010, 0b10000110, 0b10001010, 0b10010010, 0b01100010, // 2 21 | 5, 0b10000100, 0b10000010, 0b10100010, 0b11010010, 0b10001100, // 3 22 | 5, 0b00011000, 0b00101000, 0b01001000, 0b11111110, 0b00001000, // 4 23 | 5, 0b11100100, 0b10100010, 0b10100010, 0b10100010, 0b10011100, // 5 24 | 5, 0b00111100, 0b01010010, 0b10010010, 0b10010010, 0b00001100, // 6 25 | 5, 0b10000000, 0b10001110, 0b10010000, 0b10100000, 0b11000000, // 7 26 | 5, 0b01101100, 0b10010010, 0b10010010, 0b10010010, 0b01101100, // 8 27 | 5, 0b01100000, 0b10010010, 0b10010010, 0b10010100, 0b01111000, // 9 28 | 1, 0b00101000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, // : 29 | 2, 0b00000010, 0b00100100, 0b00000000, 0b00000000, 0b00000000, // ; 30 | 4, 0b00010000, 0b00101000, 0b01000100, 0b10000010, 0b00000000, // < 31 | 5, 0b00101000, 0b00101000, 0b00101000, 0b00101000, 0b00101000, // = 32 | 4, 0b10000010, 0b01000100, 0b00101000, 0b00010000, 0b00000000, // > 33 | 5, 0b01000000, 0b10000000, 0b10001010, 0b10010000, 0b01100000, // ? 34 | 5, 0b01111100, 0b10000010, 0b10111010, 0b10101010, 0b01111000, // @ 35 | 5, 0b01111110, 0b10010000, 0b10010000, 0b10010000, 0b01111110, // A 36 | 5, 0b11111110, 0b10010010, 0b10010010, 0b10010010, 0b01101100, // B 37 | 5, 0b01111100, 0b10000010, 0b10000010, 0b10000010, 0b01000100, // C 38 | 5, 0b11111110, 0b10000010, 0b10000010, 0b10000010, 0b01111100, // D 39 | 5, 0b11111110, 0b10010010, 0b10010010, 0b10010010, 0b10000010, // E 40 | 5, 0b11111110, 0b10010000, 0b10010000, 0b10010000, 0b10000000, // F 41 | 5, 0b01111100, 0b10000010, 0b10010010, 0b10010010, 0b01011110, // G 42 | 5, 0b11111110, 0b00010000, 0b00010000, 0b00010000, 0b11111110, // H 43 | 3, 0b10000010, 0b11111110, 0b10000010, 0b00000000, 0b00000000, // I 44 | 5, 0b00000100, 0b00000010, 0b10000010, 0b11111100, 0b10000000, // J 45 | 5, 0b11111110, 0b00010000, 0b00101000, 0b01000100, 0b10000010, // K 46 | 4, 0b11111110, 0b00000010, 0b00000010, 0b00000010, 0b00000000, // L 47 | 5, 0b11111110, 0b01000000, 0b00110000, 0b01000000, 0b11111110, // M 48 | 5, 0b11111110, 0b00100000, 0b00010000, 0b00001000, 0b11111110, // N 49 | 5, 0b01111100, 0b10000010, 0b10000010, 0b10000010, 0b01111100, // O 50 | 5, 0b11111110, 0b10010000, 0b10010000, 0b10010000, 0b01100000, // P 51 | 5, 0b01111100, 0b10000010, 0b10001010, 0b10000100, 0b01111010, // Q 52 | 5, 0b11111110, 0b10010000, 0b10011000, 0b10010100, 0b01100010, // R 53 | 5, 0b01100010, 0b10010010, 0b10010010, 0b10010010, 0b10001100, // S 54 | 5, 0b10000000, 0b10000000, 0b11111110, 0b10000000, 0b10000000, // T 55 | 5, 0b11111100, 0b00000010, 0b00000010, 0b00000010, 0b11111100, // U 56 | 5, 0b11111000, 0b00000100, 0b00000010, 0b00000100, 0b11111000, // V 57 | 5, 0b11111100, 0b00000010, 0b00001100, 0b00000010, 0b11111100, // W 58 | 5, 0b11000110, 0b00101000, 0b00010000, 0b00101000, 0b11000110, // X 59 | 5, 0b11100000, 0b00010000, 0b00001110, 0b00010000, 0b11100000, // Y 60 | 5, 0b10000110, 0b10001010, 0b10010010, 0b10100010, 0b11000010, // Z 61 | 2, 0b11111110, 0b10000010, 0b00000000, 0b00000000, 0b00000000, // [ 62 | 5, 0b11000000, 0b00100000, 0b00010000, 0b00001000, 0b00000110, // '\' 63 | 2, 0b10000010, 0b11111110, 0b00000000, 0b00000000, 0b00000000, // ] 64 | 3, 0b01000000, 0b10000000, 0b01000000, 0b00000000, 0b00000000, // ^ 65 | 5, 0b00000010, 0b00000010, 0b00000010, 0b00000010, 0b00000010, // _ 66 | 2, 0b10000000, 0b01000000, 0b00000000, 0b00000000, 0b00000000, // ` 67 | 4, 0b00011100, 0b00100010, 0b00100100, 0b00111110, 0b00000000, // a 68 | 4, 0b11111110, 0b00100100, 0b00100010, 0b00011100, 0b00000000, // b 69 | 4, 0b00011100, 0b00100010, 0b00100010, 0b00010100, 0b00000000, // c 70 | 4, 0b00011100, 0b00100010, 0b00100100, 0b11111110, 0b00000000, // d 71 | 4, 0b00011100, 0b00101010, 0b00101010, 0b00010000, 0b00000000, // e 72 | 4, 0b01111110, 0b10010000, 0b10000000, 0b01000000, 0b00000000, // f 73 | 4, 0b01100100, 0b10010010, 0b01010010, 0b11111100, 0b00000000, // g 74 | 4, 0b11111110, 0b00010000, 0b00100000, 0b00011110, 0b00000000, // h 75 | 1, 0b10111110, 0b00000000, 0b00000000, 0b00000000, 0b00000000, // i 76 | 3, 0b00000010, 0b00000010, 0b10111100, 0b00000000, 0b00000000, // j 77 | 4, 0b11111110, 0b00001000, 0b00010100, 0b00100010, 0b00000000, // k 78 | 2, 0b11111100, 0b00000010, 0b00000000, 0b00000000, 0b00000000, // l 79 | 5, 0b00111110, 0b00100000, 0b00011000, 0b00100000, 0b00011110, // m 80 | 4, 0b00111110, 0b00100000, 0b00100000, 0b00011110, 0b00000000, // n 81 | 4, 0b00011100, 0b00100010, 0b00100010, 0b00011100, 0b00000000, // o 82 | 4, 0b11111110, 0b01010000, 0b10010000, 0b01100000, 0b00000000, // p 83 | 4, 0b01100000, 0b10010000, 0b01010000, 0b11111110, 0b00000000, // q 84 | 4, 0b00111110, 0b00010000, 0b00100000, 0b00010000, 0b00000000, // r 85 | 4, 0b00010010, 0b00101010, 0b00101010, 0b00100100, 0b00000000, // s 86 | 4, 0b11111100, 0b00100010, 0b00100010, 0b00000100, 0b00000000, // t 87 | 4, 0b00111100, 0b00000010, 0b00000010, 0b00111100, 0b00000000, // u 88 | 5, 0b00111000, 0b00000100, 0b00000010, 0b00000100, 0b00111000, // v 89 | 5, 0b00111100, 0b00000010, 0b00001100, 0b00000010, 0b00111100, // w 90 | 5, 0b00100010, 0b00010100, 0b00001000, 0b00010100, 0b00100010, // x 91 | 4, 0b11100100, 0b00010010, 0b00100010, 0b11111100, 0b00000000, // y 92 | 4, 0b00100110, 0b00101010, 0b00101010, 0b00110010, 0b00000000, // z 93 | 3, 0b00010000, 0b01101100, 0b10000010, 0b00000000, 0b00000000, // { 94 | 1, 0b11111110, 0b00000000, 0b00000000, 0b00000000, 0b00000000, // | 95 | 3, 0b10000010, 0b01101100, 0b00010000, 0b00000000, 0b00000000, // } 96 | 4, 0b01000000, 0b10000000, 0b01000000, 0b10000000, 0b00000000, // ~ 97 | 5, 0b10101010, 0b01010100, 0b10101010, 0b01010100, 0b10101010 // Block 98 | }; 99 | -------------------------------------------------------------------------------- /paddlewar_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DhrBaksteen/Arduino-SPI-LM15SGFNZ07-LCD-Library/10d0666d96215af47fddf671152b34b37c10543d/paddlewar_diagram.png --------------------------------------------------------------------------------