├── .gitignore ├── Driver.md ├── library.properties ├── library.json ├── .github ├── stale.yml └── workflows │ └── main.yml ├── examples ├── CSN_A2 │ └── CSN_A2_DEMO │ │ ├── CSN_A2_DEMO.ino │ │ ├── CSN_A2_ThermalPrinter.h │ │ └── CSN_A2_ThermalPrinter.cpp ├── EPaper │ ├── EPD_WaveShare_43 │ │ └── EPD_WaveShare_43.ino │ ├── EPD_WaveShare_75 │ │ └── EPD_WaveShare_75.ino │ ├── EPD_WaveShare_42 │ │ └── EPD_WaveShare_42.ino │ ├── EPaperDemo2_54Pervasive │ │ └── EPaperDemo2_54Pervasive.ino │ ├── EPD_WaveShare_1_54D67 │ │ └── EPD_WaveShare_1_54D67.ino │ ├── EPD_WaveShare_29 │ │ └── EPD_WaveShare_29.ino │ ├── EPD_WaveShare_29T5 │ │ └── EPD_WaveShare_29T5.ino │ └── EPD_WaveShare_1_54 │ │ └── EPD_WaveShare_1_54.ino ├── ILI9341 │ ├── Carousel │ │ └── Carousel.ino │ ├── DrawPaletteImage_1Bit │ │ ├── DrawPaletteImage_1Bit.ino │ │ └── image.h │ ├── BasicDrawing │ │ └── BasicDrawing.ino │ ├── DrawPaletteImage_4Bit │ │ ├── DrawPaletteImage_4Bit.ino │ │ └── image.h │ ├── DrawBMP │ │ └── DrawBMP.ino │ ├── DrawXBM │ │ └── DrawXBM.ino │ ├── TouchPaint │ │ └── TouchPaint.ino │ └── RotatingCube │ │ └── RotatingCube.ino └── SSD1331 │ └── SSD1331_SPI │ └── SSD1331_SPI.ino ├── lib └── readme.txt ├── platformio.ini ├── LICENSE ├── README.md ├── src ├── DisplayDriver.cpp ├── DisplayDriver.h ├── SSD1331_SPI.h ├── EPD_WaveShare_154D67.h ├── EPD_WaveShare_29.h ├── EPD_WaveShare_154.h ├── EPD_WaveShare_29T5.h ├── ILI9341_SPI.h ├── EPD_WaveShare_75.h ├── EPaperPervasive.h ├── EPD_WaveShare_43.cpp ├── EPD_WaveShare.h ├── MiniGrafx.h ├── EPD_WaveShare_43.h ├── EPD_WaveShare_42.h └── Carousel.h ├── API.md ├── tests └── TestSuite.ino └── Introduction.md /.gitignore: -------------------------------------------------------------------------------- 1 | .pioenvs 2 | .piolibdeps 3 | .clang_complete 4 | .gcc-flags.json 5 | .vscode 6 | .vscode/* 7 | .pio 8 | .pio/* 9 | -------------------------------------------------------------------------------- /Driver.md: -------------------------------------------------------------------------------- 1 | # How to implement a new display driver 2 | 3 | It is probably best if you first have a look at an existing driver. 4 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Mini Grafx 2 | version=1.2.6 3 | author=Daniel Eichhorn 4 | maintainer=Daniel Eichhorn 5 | sentence=Graphics Library for embedded devices with a framebuffer 6 | paragraph=Graphics Library for embedded devices with a framebuffer 7 | category=Display 8 | url=https://github.com/ThingPulse/minigrafx 9 | architectures=esp8266,esp32 10 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Mini Grafx", 3 | "version": "1.2.6", 4 | "keywords": "embedded, graphics, tft, oled, e-paper", 5 | "description": "A generic graphics library containing several drivers for TFT, OLED and e-paper displays", 6 | "repository": 7 | { 8 | "type": "git", 9 | "url": "https://github.com/ThingPulse/minigrafx " 10 | }, 11 | "authors": 12 | [ 13 | { 14 | "name": "Daniel Eichhorn", 15 | "email": "dani@thingpulse.com", 16 | "url": "https://www.thingpulse.com" 17 | } 18 | ], 19 | "frameworks": "arduino", 20 | "platforms": [ 21 | "espressif8266", 22 | "espressif32" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 180 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 14 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: stale 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /examples/CSN_A2/CSN_A2_DEMO/CSN_A2_DEMO.ino: -------------------------------------------------------------------------------- 1 | 2 | #include "MiniGrafx.h" // General graphic library 3 | #include "CSN_A2_ThermalPrinter.h" // Hardware-specific library 4 | 5 | #define CSN_A2_RX D3 6 | #define CSN_A2_TX D4 7 | 8 | #define BITS_PER_PIXEL 1 9 | 10 | uint16_t palette[] = {0, 1}; 11 | 12 | CSN_A2 driver = CSN_A2(CSN_A2_RX, CSN_A2_TX); 13 | MiniGrafx gfx = MiniGrafx(&driver, BITS_PER_PIXEL, palette); 14 | 15 | void setup() { 16 | Serial.begin(115200); 17 | gfx.init(); 18 | gfx.fillBuffer(0); 19 | gfx.setColor(1); 20 | gfx.setFont(ArialMT_Plain_10); 21 | gfx.drawLine(0, 0, gfx.getWidth(), gfx.getHeight()); 22 | gfx.drawString(10, 10, "Hello World"); 23 | gfx.setFont(ArialMT_Plain_16); 24 | gfx.drawString(10, 30, "Everything works!"); 25 | gfx.setFont(ArialMT_Plain_24); 26 | gfx.drawString(10, 55, "Yes! Millis: " + String(millis())); 27 | gfx.commit(); 28 | } 29 | 30 | void loop() { 31 | 32 | } 33 | -------------------------------------------------------------------------------- /lib/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for the project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link to executable file. 4 | 5 | The source code of each library should be placed in separate directory, like 6 | "lib/private_lib/[here are source files]". 7 | 8 | For example, see how can be organized `Foo` and `Bar` libraries: 9 | 10 | |--lib 11 | | |--Bar 12 | | | |--docs 13 | | | |--examples 14 | | | |--src 15 | | | |- Bar.c 16 | | | |- Bar.h 17 | | |--Foo 18 | | | |- Foo.c 19 | | | |- Foo.h 20 | | |- readme.txt --> THIS FILE 21 | |- platformio.ini 22 | |--src 23 | |- main.c 24 | 25 | Then in `src/main.c` you should use: 26 | 27 | #include 28 | #include 29 | 30 | // rest H/C/CPP code 31 | 32 | PlatformIO will find your libraries automatically, configure preprocessor's 33 | include paths and build them. 34 | 35 | More information about PlatformIO Library Dependency Finder 36 | - http://docs.platformio.org/page/librarymanager/ldf.html 37 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; http://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | env_default = esp_wroom_02 13 | 14 | [env:d1_mini] 15 | platform = espressif8266 16 | board = d1_mini 17 | framework = arduino 18 | upload_speed = 921600 19 | monitor_speed = 115200 20 | ;board_f_cpu = 160000000L 21 | ;upload_resetmethod = ck 22 | ;lib_deps = XPT2046_Touchscreen 23 | 24 | [env:esp_wroom_02] 25 | platform = espressif8266 26 | board = esp_wroom_02 27 | framework = arduino 28 | upload_speed = 921600 29 | monitor_speed = 115200 30 | ;board_f_cpu = 160000000L 31 | ;upload_resetmethod = ck 32 | ;lib_deps = XPT2046_Touchscreen 33 | 34 | [env:esp32] 35 | platform = espressif32 36 | board = lolin32 37 | framework = arduino 38 | board_build.f_cpu = 40000000L 39 | upload_speed = 921600 40 | monitor_speed = 115200 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 by ThingPulse Ltd., https://thingpulse.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![PlatformIO CI](https://github.com/ThingPulse/minigrafx/actions/workflows/main.yml/badge.svg)](https://github.com/ThingPulse/minigrafx/actions/workflows/main.yml) 2 | 3 | # ThingPulse MiniGrafx Library 4 | 5 | This is a graphics library for embedded devices containing a framebuffer to avoid flickering. Instead of writing directly to the display all drawing operations are made on the buffer stored in memory. Once you are finished with one drawing cycle the whole content of the framebuffer is written to the display. 6 | 7 | ## Service level promise 8 | 9 |
10 | This is a ThingPulse prime project. See our open-source commitment declaration for what this means.
11 | 12 | ## Inspiration 13 | 14 | This library is heavily based on [https://github.com/ThingPulse/esp8266-oled-ssd1306](https://github.com/ThingPulse/esp8266-oled-ssd1306) 15 | developed by Fabrice Weinberg and myself mostly for tiny OLED displays. This new library targets also color displays and e-paper displays with higher resolution 16 | 17 | ## Philosophy 18 | 19 | Often in technology you have to choose between several options and make a trade-off. While some graphic libraries 20 | are optimized for minimal memory consumption they have to accept ugly visual side effects such as flickering or tearing. 21 | 22 | ## Getting started 23 | 24 | [Getting Started](Introduction.md) by reading the intro. 25 | 26 | ## API 27 | 28 | [API Documentation](API.md) of the library. 29 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # documentation at https://docs.platformio.org/en/latest/integration/ci/github-actions.html 2 | 3 | name: PlatformIO CI 4 | 5 | on: [push, pull_request] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | example: 13 | - examples/ILI9341/RotatingCube 14 | - examples/ILI9341/DrawXBM 15 | - examples/ILI9341/DrawPaletteImage_4Bit 16 | - examples/ILI9341/DrawPaletteImage_1Bit 17 | - examples/ILI9341/Carousel 18 | - examples/ILI9341/BasicDrawing 19 | - examples/EPaper/EPaperDemo2_54Pervasive 20 | - examples/EPaper/EPD_WaveShare_29 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Cache pip 24 | uses: actions/cache@v2 25 | with: 26 | path: ~/.cache/pip 27 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} 28 | restore-keys: ${{ runner.os }}-pip- 29 | - name: Cache PlatformIO 30 | uses: actions/cache@v2 31 | with: 32 | path: ~/.platformio 33 | key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} 34 | - name: Set up Python 35 | uses: actions/setup-python@v2 36 | - name: Install PlatformIO 37 | run: | 38 | python -m pip install --upgrade pip 39 | pip install --upgrade platformio 40 | - name: Install library dependencies 41 | run: pio lib -g install "https://github.com/PaulStoffregen/XPT2046_Touchscreen/#v1.4" "EspSoftwareSerial @ ^6.15.2" 42 | - name: Run PlatformIO 43 | run: pio ci --lib="." --board=d1_mini --board=esp_wroom_02 --board=lolin32 44 | env: 45 | PLATFORMIO_CI_SRC: ${{ matrix.example }} 46 | -------------------------------------------------------------------------------- /src/DisplayDriver.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #include "DisplayDriver.h" 29 | 30 | 31 | DisplayDriver::DisplayDriver(int16_t w, int16_t h): 32 | WIDTH(w), HEIGHT(h) 33 | { 34 | _width = WIDTH; 35 | _height = HEIGHT; 36 | rotation = 0; 37 | 38 | } 39 | 40 | uint8_t DisplayDriver::getRotation(void) const { 41 | return rotation; 42 | } 43 | 44 | void DisplayDriver::setRotation(uint8_t x) { 45 | rotation = (x & 3); 46 | switch(rotation) { 47 | case 0: 48 | case 2: 49 | _width = WIDTH; 50 | _height = HEIGHT; 51 | break; 52 | case 1: 53 | case 3: 54 | _width = HEIGHT; 55 | _height = WIDTH; 56 | break; 57 | } 58 | } 59 | 60 | 61 | 62 | // Return the size of the display (per current rotation) 63 | int16_t DisplayDriver::width(void) const { 64 | return _width; 65 | } 66 | 67 | int16_t DisplayDriver::height(void) const { 68 | return _height; 69 | } 70 | -------------------------------------------------------------------------------- /examples/CSN_A2/CSN_A2_DEMO/CSN_A2_ThermalPrinter.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef _MINIGRAFX_CSN_A2_ 29 | #define _MINIGRAFX_CSN_A2_ 30 | 31 | #include 32 | #include 33 | #include "DisplayDriver.h" 34 | 35 | 36 | 37 | #define CSN_A2_WIDTH 384 38 | #define CSN_A2_HEIGHT 384 39 | 40 | #define LF 0x0A; 41 | // Horizontal TAB 42 | #define HT 0x09 43 | #define ESC 0x1B 44 | // group seperator 45 | #define GS 0x1D 46 | // space 47 | #define SP 0x20 48 | // NP form feed; new page 49 | #define FF 0x0C 50 | 51 | #define ASCII_DC2 18 52 | 53 | class CSN_A2 : public DisplayDriver { 54 | 55 | public: 56 | CSN_A2(int8_t _RX, int8_t _TX); 57 | 58 | void init(void); 59 | void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); 60 | void setRotation(uint8_t r); 61 | 62 | void wake(); 63 | 64 | void writeBuffer(BufferInfo *bufferInfo); 65 | 66 | void setFastRefresh(boolean isFastRefreshEnabled); 67 | 68 | void spiwrite(uint8_t); 69 | void writeCommand(uint8_t c); 70 | void writedata(uint8_t d); 71 | void timeoutWait(); 72 | uint8_t reverse(uint8_t in); 73 | private: 74 | boolean hwSPI; 75 | int32_t _rx, _tx; 76 | SoftwareSerial *serial; 77 | 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /examples/EPaper/EPD_WaveShare_43/EPD_WaveShare_43.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | 32 | #include "EPD_WaveShare_43.h" 33 | #include "MiniGrafx.h" 34 | #include "DisplayDriver.h" 35 | 36 | 37 | 38 | #define SCREEN_WIDTH 800 39 | #define SCREEN_HEIGHT 600 40 | #define BITS_PER_PIXEL 1 41 | 42 | const int wake_up = 18; 43 | const int reset = 19; 44 | 45 | uint16_t palette[] = {0, 1}; 46 | 47 | HardwareSerial mySerial(2); 48 | EPD_WaveShare_43 epd(&mySerial); 49 | MiniGrafx gfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette); 50 | 51 | void setup() { 52 | pinMode(wake_up, HIGH); 53 | pinMode(reset, HIGH); 54 | gfx.init(); 55 | 56 | } 57 | 58 | uint8_t rotation = 0; 59 | 60 | void loop() { 61 | //epd.Dis_Clear_full(); 62 | //delay(1500); 63 | //epd.EPD_init_Part(); 64 | //delay(1000); 65 | 66 | //gfx.init(); 67 | gfx.setRotation(rotation); 68 | gfx.fillBuffer(1); 69 | gfx.setColor(0); 70 | gfx.setFont(ArialMT_Plain_10); 71 | gfx.drawLine(0, 0, gfx.getWidth(), gfx.getHeight()); 72 | gfx.drawString(10, 10, "Hello World"); 73 | gfx.setFont(ArialMT_Plain_16); 74 | gfx.drawString(10, 30, "Everything works!"); 75 | gfx.setFont(ArialMT_Plain_24); 76 | gfx.drawString(10, 55, "Yes! Millis: " + String(millis())); 77 | gfx.commit(); 78 | delay(5000); 79 | rotation = (rotation + 1) % 4; 80 | } 81 | -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | # MiniGrafx API 2 | 3 | This chapter explains the available methods of the graphics library. 4 | 5 | ## Constructor 6 | 7 | The constructor creates the graphic library and allocates the frame buffer memory. 8 | Parameters: 9 | * DisplayDriver: the hardware driver for your library. See [How to implement a new driver](Driver.md) 10 | * bitsPerPixel: bit depth, currently supported are 1, 2, 4 and 8 11 | * palette: array with length 2^bitsPerPixel containing the mapping from palette color to display color 12 | 13 | ```C++ 14 | MiniGrafx(DisplayDriver *driver, uint8_t bitsPerPixel, uint16_t *palette); 15 | ``` 16 | 17 | Example: 18 | ```C++ 19 | #define BITS_PER_PIXEL 1 20 | uint16_t palette[] = {ILI9341_BLACK, // 0 21 | ILI9341_WHITE}; 22 | 23 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 24 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 25 | ``` 26 | 27 | ## changeBitDepth 28 | 29 | With changeBitDepth you can change the bit depth even after creating the MiniGrafx object. Please bear in mind that this operation deallocates the reserved frame buffer memory and allocates new memory according to the new 30 | bit depth. Or in other words the content of the frame buffer before calling this method will be lost if it has 31 | not yet been written to the display. 32 | 33 | ```C++ 34 | void changeBitDepth(uint8_t bitsPerPixel, uint16_t *palette); 35 | ``` 36 | 37 | ## init 38 | 39 | With the init function you initialize the driver as well as the graphics library. Usually you only do this 40 | once in the setup method: 41 | 42 | ```C++ 43 | gfx.init(); 44 | ``` 45 | 46 | 47 | ## commit 48 | 49 | The commit() method calls the driver to write the content of the frame buffer to the display. Without calling 50 | commit() the content of the frame buffer will not become visible. You usually do this at the end of all the drawing in one loop iteration: 51 | 52 | ```C++ 53 | gfx.commit(); 54 | ``` 55 | 56 | ## fillBuffer and clear 57 | 58 | With clear() and fillBuffer() you fill the frame buffer with one value; you erase it. The only difference between 59 | the two is that clear() fills the frame buffer with the palette index 0, whereas with fillBuffer(uint8_t) you 60 | can define which color should be used to fill the buffer. 61 | 62 | ```C++ 63 | void clear(); 64 | void fillBuffer(uint8_t pal); 65 | ``` 66 | 67 | ## setColor 68 | 69 | With setColor you define the currently active color for many drawing operations. The parameter is the palette 70 | index of the color you want to set. The range of color is thus between 0 and 2^bitDepth - 1. For a bith depth 71 | of 4 it can be 0 and 15. 72 | 73 | ```C++ 74 | void setColor(uint16_t color); 75 | ``` 76 | 77 | ## setPixel and getPixel 78 | 79 | Many higher level drawing operations use setPixel to draw into the frame buffer. Using this atomic function might 80 | not be as fast as possible but increases flexibility and portability. getPixel reads out the palette index at 81 | the given index. 82 | 83 | ```C++ 84 | void setPixel(uint16_t x, uint16_t y); 85 | uint16_t getPixel(uint16_t x, uint16_t y); 86 | ``` 87 | -------------------------------------------------------------------------------- /examples/ILI9341/Carousel/Carousel.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "MiniGrafx.h" // General graphic library 4 | #include "ILI9341_SPI.h" // Hardware-specific library 5 | #include "Carousel.h" 6 | 7 | #define TFT_DC 4 // D2 8 | #define TFT_CS 5 // D1 9 | #define TFT_LED 15 // D8 10 | 11 | // defines the colors usable in the paletted 16 color frame buffer 12 | uint16_t palette[] = {ILI9341_BLACK, // 0 13 | ILI9341_WHITE, // 1 14 | ILI9341_NAVY, // 2 15 | ILI9341_DARKCYAN, // 3 16 | ILI9341_DARKGREEN, // 4 17 | ILI9341_MAROON, // 5 18 | ILI9341_PURPLE, // 6 19 | ILI9341_OLIVE, // 7 20 | ILI9341_LIGHTGREY, // 8 21 | ILI9341_DARKGREY, // 9 22 | ILI9341_BLUE, // 10 23 | ILI9341_GREEN, // 11 24 | ILI9341_CYAN, // 12 25 | ILI9341_RED, // 13 26 | ILI9341_MAGENTA, // 14 27 | ILI9341_YELLOW}; // 15 28 | 29 | int SCREEN_WIDTH = 240; 30 | int SCREEN_HEIGHT = 320; 31 | int BITS_PER_PIXEL = 4; // 2^4 = 16 colors 32 | 33 | // Initialize the driver 34 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 35 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 36 | Carousel carousel(&gfx, 0, 0, 240, 100); 37 | 38 | void drawFrame1(MiniGrafx *display, CarouselState* state, int16_t x, int16_t y) { 39 | display->setColor(1); 40 | display->setFont(ArialMT_Plain_16); 41 | display->drawString(x + 10, y + 10, "The Carousel is Back!"); 42 | } 43 | 44 | void drawFrame2(MiniGrafx *display, CarouselState* state, int16_t x, int16_t y) { 45 | // Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file 46 | // Besides the default fonts there will be a program to convert TrueType fonts into this format 47 | display->setColor(13); 48 | display->setTextAlignment(TEXT_ALIGN_LEFT); 49 | display->setFont(ArialMT_Plain_10); 50 | display->drawString(10 + x, 10 + y, "Arial 10"); 51 | 52 | display->setColor(11); 53 | display->setFont(ArialMT_Plain_16); 54 | display->drawString(10 + x, 20 + y, "Arial 16"); 55 | 56 | display->setColor(12); 57 | display->setFont(ArialMT_Plain_24); 58 | display->drawString(10 + x, 34 + y, "Arial 24"); 59 | } 60 | 61 | FrameCallback frames[] = { drawFrame1, drawFrame2 }; 62 | 63 | // how many frames are there? 64 | int frameCount = 2; 65 | 66 | 67 | void setup() { 68 | 69 | Serial.begin(115200); 70 | 71 | // Turn on the background LED 72 | pinMode(TFT_LED, OUTPUT); 73 | digitalWrite(TFT_LED, HIGH); 74 | 75 | carousel.setFrames(frames, frameCount); 76 | 77 | gfx.init(); 78 | gfx.fillBuffer(0); 79 | gfx.commit(); 80 | 81 | } 82 | 83 | void loop() { 84 | int remainingTimeBudget = carousel.update(); 85 | 86 | if (remainingTimeBudget > 0) { 87 | // You can do some work here 88 | // Don't do stuff if you are below your 89 | // time budget. 90 | delay(remainingTimeBudget); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/DisplayDriver.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef _MINIGRAFX_DRIVER_H 29 | #define _MINIGRAFX_DRIVER_H 30 | 31 | #include "Arduino.h" 32 | 33 | struct BufferInfo { 34 | // the frame buffer 35 | uint8_t *buffer; 36 | // number of bits used for one pixel 37 | uint8_t bitsPerPixel; 38 | // the palette in case the framebuffer uses a different bit depth than the display 39 | uint16_t *palette; 40 | // x origin of the area to copy 41 | uint16_t windowX; 42 | // y origin of the area to copy 43 | uint16_t windowY; 44 | // width of the area to be copied 45 | uint16_t windowWidth; 46 | // height of the area to be copied 47 | uint16_t windowHeight; 48 | // x where to copy the window to 49 | uint16_t targetX; 50 | // y where to copy the window to 51 | uint16_t targetY; 52 | // width of the source buffer 53 | uint16_t bufferWidth; 54 | // height of the source buffer 55 | uint16_t bufferHeight; 56 | // is this a partial update? 57 | bool isPartialUpdate = false; 58 | }; 59 | 60 | class DisplayDriver { 61 | 62 | public: 63 | 64 | DisplayDriver(int16_t w, int16_t h); // Constructor 65 | 66 | virtual void setRotation(uint8_t r); 67 | virtual void init() = 0; 68 | virtual void writeBuffer(BufferInfo *bufferInfo) = 0; 69 | virtual void setFastRefresh(boolean isEnabled) = 0; 70 | 71 | int16_t height(void) const; 72 | int16_t width(void) const; 73 | 74 | uint8_t getRotation(void) const; 75 | 76 | 77 | protected: 78 | const int16_t 79 | WIDTH, HEIGHT; // This is the 'raw' display w/h - never changes 80 | int16_t _width, _height; 81 | uint8_t rotation; 82 | boolean isFastRefreshEnabled = false; 83 | 84 | }; 85 | 86 | 87 | #endif // _MINIGRAFX_DRIVER_H 88 | -------------------------------------------------------------------------------- /examples/SSD1331/SSD1331_SPI/SSD1331_SPI.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "MiniGrafx.h" // General graphic library 33 | #include "SSD1331_SPI.h" // Hardware-specific library 34 | #include "image.h" 35 | 36 | #define TFT_DC 4 37 | #define TFT_CS 17 38 | 39 | 40 | // defines the colors usable in the paletted 16 color frame buffer 41 | uint16_t palette[256]; 42 | 43 | 44 | 45 | int SCREEN_WIDTH = 96; 46 | int SCREEN_HEIGHT = 64; 47 | int BITS_PER_PIXEL = 16; 48 | 49 | // Initialize the driver 50 | SSD1331_SPI tft = SSD1331_SPI(TFT_CS, TFT_DC); 51 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette, SCREEN_WIDTH, SCREEN_HEIGHT); 52 | 53 | uint64_t lastRefresh = 0; 54 | uint16_t counter = 0; 55 | void setup() { 56 | Serial.begin(115200); 57 | 58 | // Initialize the driver only once 59 | gfx.init(); 60 | // fill the buffer with black 61 | gfx.fillBuffer(0); 62 | // write the buffer to the display 63 | //gfx.commit(); 64 | 65 | gfx.drawBmpFromPgm(image, 0, 0); 66 | gfx.setColor(0xFFFF); 67 | gfx.drawString(0, 0, String(1000.0 / (millis() - lastRefresh), 1) + "fps"); 68 | lastRefresh = millis(); 69 | gfx.commit(); 70 | 71 | delay(10000); 72 | } 73 | 74 | //uint8_t counter = 0; 75 | void loop() { 76 | gfx.fillBuffer(0); 77 | gfx.setColor(1); 78 | gfx.setFont(ArialMT_Plain_16); 79 | gfx.setColor(ILI9341_WHITE); 80 | gfx.drawString(0, 0, String(1000.0 / (millis() - lastRefresh), 1) + "fps"); 81 | lastRefresh = millis(); 82 | gfx.commit(); 83 | 84 | 85 | 86 | 87 | counter++; 88 | 89 | } 90 | -------------------------------------------------------------------------------- /tests/TestSuite.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "MiniGrafx.h" // General graphic library 5 | #include "ILI9341_SPI.h" // Hardware-specific library 6 | 7 | 8 | 9 | 10 | #define TFT_DC D2 11 | #define TFT_CS D1 12 | #define TFT_LED D8 13 | 14 | // defines the colors usable in the paletted 16 color frame buffer 15 | uint16_t palette[] = {ILI9341_BLACK, // 0 16 | ILI9341_WHITE, // 1 17 | ILI9341_NAVY, // 2 18 | ILI9341_DARKCYAN, // 3 19 | ILI9341_DARKGREEN, // 4 20 | ILI9341_MAROON, // 5 21 | ILI9341_PURPLE, // 6 22 | ILI9341_OLIVE, // 7 23 | ILI9341_LIGHTGREY, // 8 24 | 0x39E7, //ILI9341_DARKGREY, // 9 25 | ILI9341_BLUE, // 10 26 | ILI9341_GREEN, // 11 27 | ILI9341_CYAN, // 12 28 | ILI9341_RED, // 13 29 | ILI9341_MAGENTA, // 14 30 | 0xFD80}; // 15 31 | 32 | 33 | 34 | int SCREEN_WIDTH = 240; 35 | int SCREEN_HEIGHT = 320; 36 | int BITS_PER_PIXEL = 1 ; // 2^4 = 16 colors 37 | 38 | // Initialize the driver 39 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 40 | MiniGrafx gfx = MiniGrafx(&tft, SCREEN_WIDTH, SCREEN_HEIGHT, BITS_PER_PIXEL, palette); 41 | 42 | 43 | void ASSERT_TRUE(String testName, bool condition) { 44 | if (condition) { 45 | Serial.println(testName + " PASS"); 46 | } else { 47 | Serial.println(testName + " FAIL"); 48 | } 49 | } 50 | void testSetPixel() { 51 | Serial.println("== Test Set Pixel=="); 52 | gfx.fillBuffer(0); 53 | ASSERT_TRUE("Getting Black Pixel", gfx.getPixel(0, 0) == 0); 54 | gfx.setColor(1); 55 | gfx.setPixel(0, 0); 56 | ASSERT_TRUE("Getting White Pixel", gfx.getPixel(0, 0) == 1); 57 | } 58 | 59 | void testDrawLine() { 60 | Serial.println(); 61 | Serial.println("== Test drawLine =="); 62 | gfx.fillBuffer(0); 63 | gfx.setColor(1); 64 | gfx.drawLine(1, 0, 10, 0); 65 | ASSERT_TRUE("DrawLine Pixel not set", gfx.getPixel(0, 0) == 0); 66 | for (int i = 1; i < 10; i++) { 67 | ASSERT_TRUE("DrawLine Pixel set by line", gfx.getPixel(i, 0) == 1); 68 | } 69 | ASSERT_TRUE("DrawLine Pixel not set", gfx.getPixel(11, 0) == 0); 70 | } 71 | 72 | void testDrawHorizontalLine() { 73 | Serial.println(); 74 | Serial.println("== Test drawHorizontalLine =="); 75 | gfx.fillBuffer(0); 76 | gfx.setColor(1); 77 | //0000000000111111 78 | //0123456789012345 79 | //----XXXXXXXXX--- 80 | gfx.drawHorizontalLine(4, 5, 9); 81 | ASSERT_TRUE("DrawLine Pixel not set", gfx.getPixel(3, 4) == 0); 82 | for (int i = 0; i < 9; i++) { 83 | ASSERT_TRUE("DrawLine Pixel set by line", gfx.getPixel(4 + i, 5) == 1); 84 | } 85 | ASSERT_TRUE("DrawLine Pixel not set", gfx.getPixel(13, 5) == 0); 86 | } 87 | 88 | void setup() { 89 | // NOTE!!! Wait for >2 secs 90 | // if board doesn't support software reset via Serial.DTR/RTS 91 | Serial.begin(115200); 92 | delay(5000); 93 | Serial.println(); 94 | Serial.println("Test Begin"); 95 | 96 | gfx.init(); 97 | testSetPixel(); 98 | testDrawLine(); 99 | testDrawHorizontalLine(); 100 | } 101 | 102 | 103 | 104 | void loop() { 105 | 106 | } 107 | -------------------------------------------------------------------------------- /examples/ILI9341/DrawPaletteImage_1Bit/DrawPaletteImage_1Bit.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "MiniGrafx.h" // General graphic library 33 | #include "ILI9341_SPI.h" // Hardware-specific library 34 | #include "image.h" 35 | 36 | #define TFT_DC 4 // D2 37 | #define TFT_CS 5 // D1 38 | #define TFT_LED 15 // D8 39 | 40 | // defines the colors usable in the paletted 16 color frame buffer 41 | uint16_t palette[] = {ILI9341_BLACK, // 0 42 | ILI9341_WHITE}; // 15 43 | 44 | 45 | 46 | int SCREEN_WIDTH = 240; 47 | int SCREEN_HEIGHT = 320; 48 | int BITS_PER_PIXEL = 1 ; // 2^4 = 16 colors 49 | 50 | // Initialize the driver 51 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 52 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 53 | 54 | 55 | // Used for fps measuring 56 | uint16_t counter = 0; 57 | long startMillis = millis(); 58 | uint16_t interval = 20; 59 | int color = 1; 60 | String fps = "0fps"; 61 | 62 | void setup() { 63 | Serial.begin(115200); 64 | 65 | // Turn on the background LED 66 | pinMode(TFT_LED, OUTPUT); 67 | digitalWrite(TFT_LED, HIGH); 68 | 69 | gfx.init(); 70 | gfx.fillBuffer(0); 71 | gfx.commit(); 72 | 73 | 74 | startMillis = millis(); 75 | } 76 | 77 | 78 | void loop() { 79 | 80 | gfx.fillBuffer(0); 81 | 82 | gfx.setColor(15); 83 | gfx.drawString(2, 2, fps); 84 | gfx.setTransparentColor(0); 85 | gfx.drawPalettedBitmapFromPgm(0, -100 + counter % 420, img); 86 | gfx.commit(); 87 | 88 | counter++; 89 | // only calculate the fps every iterations. 90 | if (counter % interval == 0) { 91 | color = (color + 1) % 15 + 1; 92 | long millisSinceUpdate = millis() - startMillis; 93 | fps = String(interval * 1000.0 / (millisSinceUpdate)) + "fps"; 94 | startMillis = millis(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /examples/ILI9341/BasicDrawing/BasicDrawing.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "MiniGrafx.h" // General graphic library 33 | #include "ILI9341_SPI.h" // Hardware-specific library 34 | #include "image.h" 35 | 36 | #define TFT_DC 4 // D2 37 | #define TFT_CS 5 // D1 38 | #define TFT_LED 15 // D8 39 | 40 | // defines the colors usable in the paletted 16 color frame buffer 41 | uint16_t palette[256]; 42 | 43 | 44 | 45 | int SCREEN_WIDTH = 240; 46 | int SCREEN_HEIGHT = 320; 47 | int BITS_PER_PIXEL = 16; 48 | 49 | // Initialize the driver 50 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 51 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette, 240, 40); 52 | 53 | uint64_t lastRefresh = 0; 54 | uint16_t counter = 0; 55 | void setup() { 56 | Serial.begin(115200); 57 | 58 | // Turn on the background LED 59 | pinMode(TFT_LED, OUTPUT); 60 | digitalWrite(TFT_LED, HIGH); 61 | for (uint16_t i = 0; i < 255; i++) { 62 | palette[i] = ((i / 8) << 11) | ((i / 4) << 5) | (i / 8); 63 | } 64 | // Initialize the driver only once 65 | gfx.init(); 66 | // fill the buffer with black 67 | gfx.fillBuffer(0); 68 | // write the buffer to the display 69 | //gfx.commit(); 70 | 71 | gfx.drawBmpFromPgm(image, 0, 0); 72 | gfx.setColor(ILI9341_WHITE); 73 | gfx.drawString(0, 0, String(1000.0 / (millis() - lastRefresh), 1) + "fps"); 74 | lastRefresh = millis(); 75 | gfx.commit(0, 0); 76 | gfx.fillBuffer(0); 77 | gfx.drawBmpFromPgm(image, 0, -40); 78 | gfx.commit(0, 40); 79 | } 80 | 81 | //uint8_t counter = 0; 82 | void loop() { 83 | gfx.fillBuffer(0); 84 | gfx.setColor(1); 85 | gfx.setFont(ArialMT_Plain_16); 86 | gfx.setColor(ILI9341_WHITE); 87 | gfx.drawString(0, 0, String(1000.0 / (millis() - lastRefresh), 1) + "fps"); 88 | lastRefresh = millis(); 89 | gfx.commit(0, 80); 90 | 91 | 92 | 93 | 94 | counter++; 95 | 96 | } 97 | -------------------------------------------------------------------------------- /examples/EPaper/EPD_WaveShare_75/EPD_WaveShare_75.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "EPD_WaveShare_75.h" 33 | #include "MiniGrafx.h" 34 | #include "DisplayDriver.h" 35 | 36 | /* 37 | Connect the following pins: 38 | Display NodeMCU 39 | BUSY D1 40 | RST D2 41 | DC D8 42 | CS D3 43 | CLK D5 44 | DIN D7 45 | GND GND 46 | 3.3V 3V3 47 | */ 48 | /*#define CS D3 49 | #define RST D2 50 | #define DC D8 51 | #define BUSY D1*/ 52 | #if defined(ESP8266) 53 | #define CS 15 // D8 54 | #define RST 2 // D4 55 | #define DC 5 // D1 56 | #define BUSY 4 // D2 57 | #else if defined(ESP32) 58 | #define CS 2 59 | #define RST 15 60 | #define DC 5 61 | #define BUSY 4 62 | #define USR_BTN 12 63 | #endif 64 | 65 | #define SCREEN_WIDTH 640 66 | #define SCREEN_HEIGHT 384 67 | #define BITS_PER_PIXEL 1 68 | 69 | 70 | uint16_t palette[] = {0, 1}; 71 | 72 | EPD_WaveShare75 epd(CS, RST, DC, BUSY); 73 | MiniGrafx gfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette); 74 | 75 | void setup() { 76 | Serial.begin(115200); 77 | gfx.init(); 78 | gfx.setRotation(1); 79 | Serial.println("Finished Setup"); 80 | } 81 | 82 | uint8_t rotation = 0; 83 | 84 | void loop() { 85 | 86 | 87 | gfx.setRotation(rotation); 88 | gfx.fillBuffer(1); 89 | gfx.setColor(0); 90 | gfx.setFont(ArialMT_Plain_10); 91 | gfx.drawLine(0, 0, gfx.getWidth(), gfx.getHeight()); 92 | gfx.drawString(10, 10, "Hello World"); 93 | gfx.setFont(ArialMT_Plain_16); 94 | gfx.drawString(10, 30, "Everything works!"); 95 | gfx.setFont(ArialMT_Plain_24); 96 | gfx.drawString(10, 55, "Yes! Millis: " + String(millis())); 97 | 98 | gfx.commit(); 99 | Serial.println("Commited buffer"); 100 | rotation = (rotation + 1) % 4; 101 | delay(5000); 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/SSD1331_SPI.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef _MINIGRAFX_SSD1331_ 29 | #define _MINIGRAFX_SSD1331_ 30 | 31 | #include 32 | #include 33 | #include "DisplayDriver.h" 34 | 35 | #define SSD1331_WIDTH 96 36 | #define SSD1331_HEIGHT 64 37 | 38 | // Timing Delays 39 | #define SSD1331_DELAYS_HWFILL (3) 40 | #define SSD1331_DELAYS_HWLINE (1) 41 | 42 | // SSD1331 Commands 43 | #define SSD1331_CMD_DRAWLINE 0x21 44 | #define SSD1331_CMD_DRAWRECT 0x22 45 | #define SSD1331_CMD_FILL 0x26 46 | #define SSD1331_CMD_SETCOLUMN 0x15 47 | #define SSD1331_CMD_SETROW 0x75 48 | #define SSD1331_CMD_CONTRASTA 0x81 49 | #define SSD1331_CMD_CONTRASTB 0x82 50 | #define SSD1331_CMD_CONTRASTC 0x83 51 | #define SSD1331_CMD_MASTERCURRENT 0x87 52 | #define SSD1331_CMD_SETREMAP 0xA0 53 | #define SSD1331_CMD_STARTLINE 0xA1 54 | #define SSD1331_CMD_DISPLAYOFFSET 0xA2 55 | #define SSD1331_CMD_NORMALDISPLAY 0xA4 56 | #define SSD1331_CMD_DISPLAYALLON 0xA5 57 | #define SSD1331_CMD_DISPLAYALLOFF 0xA6 58 | #define SSD1331_CMD_INVERTDISPLAY 0xA7 59 | #define SSD1331_CMD_SETMULTIPLEX 0xA8 60 | #define SSD1331_CMD_SETMASTER 0xAD 61 | #define SSD1331_CMD_DISPLAYOFF 0xAE 62 | #define SSD1331_CMD_DISPLAYON 0xAF 63 | #define SSD1331_CMD_POWERMODE 0xB0 64 | #define SSD1331_CMD_PRECHARGE 0xB1 65 | #define SSD1331_CMD_CLOCKDIV 0xB3 66 | #define SSD1331_CMD_PRECHARGEA 0x8A 67 | #define SSD1331_CMD_PRECHARGEB 0x8B 68 | #define SSD1331_CMD_PRECHARGEC 0x8C 69 | #define SSD1331_CMD_PRECHARGELEVEL 0xBB 70 | #define SSD1331_CMD_VCOMH 0xBE 71 | 72 | 73 | class SSD1331_SPI : public DisplayDriver { 74 | 75 | public: 76 | SSD1331_SPI(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK, int8_t _RST, int8_t _MISO); 77 | SSD1331_SPI(int8_t _CS, int8_t _DC, int8_t _RST = -1); 78 | 79 | void init(void); 80 | void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); 81 | void setRotation(uint8_t r); 82 | 83 | void writeBuffer(BufferInfo *bufferInfo); 84 | 85 | void setFastRefresh(boolean isFastRefreshEnabled); 86 | 87 | void spiwrite(uint8_t); 88 | void writeCommand(uint8_t c); 89 | void writedata(uint8_t d); 90 | private: 91 | boolean hwSPI; 92 | int32_t _cs, _dc, _rst, _mosi, _miso, _sclk; 93 | 94 | }; 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /examples/EPaper/EPD_WaveShare_42/EPD_WaveShare_42.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "EPD_WaveShare_42.h" 33 | #include "MiniGrafx.h" 34 | #include "DisplayDriver.h" 35 | 36 | /* 37 | Connect the following pins: 38 | Display NodeMCU 39 | BUSY D1 40 | RST D2 41 | DC D8 42 | CS D3 43 | CLK D5 44 | DIN D7 45 | GND GND 46 | 3.3V 3V3 47 | */ 48 | /*#define CS D3 49 | #define RST D2 50 | #define DC D8 51 | #define BUSY D1*/ 52 | 53 | #if defined(ESP8266) 54 | #define CS 15 // D8 55 | #define RST 2 // D4 56 | #define DC 5 // D1 57 | #define BUSY 4 // D2 58 | #else if defined(ESP32) 59 | #define CS 2 60 | #define RST 15 61 | #define DC 5 62 | #define BUSY 4 63 | #define USR_BTN 12 64 | #endif 65 | 66 | #define SCREEN_WIDTH 400 67 | #define SCREEN_HEIGHT 300 68 | #define BITS_PER_PIXEL 1 69 | 70 | 71 | uint16_t palette[] = {0, 1}; 72 | 73 | EPD_WaveShare42 epd(CS, RST, DC, BUSY); 74 | MiniGrafx gfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette); 75 | uint32_t startMillis; 76 | 77 | void setup() { 78 | startMillis = millis(); 79 | Serial.begin(115200); 80 | gfx.init(); 81 | gfx.setRotation(0); 82 | gfx.setFastRefresh(false); 83 | } 84 | 85 | uint8_t rotation = 0; 86 | 87 | void loop() { 88 | 89 | 90 | gfx.setRotation(rotation); 91 | gfx.fillBuffer(1); 92 | gfx.setColor(0); 93 | gfx.setFont(ArialMT_Plain_10); 94 | gfx.drawLine(0, 0, gfx.getWidth(), gfx.getHeight()); 95 | gfx.drawString(10, 10, "Hello World"); 96 | gfx.setFont(ArialMT_Plain_16); 97 | gfx.drawString(10, 30, "Everything works!"); 98 | gfx.setFont(ArialMT_Plain_24); 99 | gfx.drawString(10, 55, "Yes! Millis: " + String(millis())); 100 | gfx.drawString(10, 80, "Rotation: " + String(rotation)); 101 | Serial.printf("Time until commit: %dms\n", (millis() - startMillis)); 102 | gfx.commit(); 103 | 104 | rotation = (rotation + 1) % 4; 105 | epd.Sleep(); 106 | Serial.printf("Time before sleep: %dms\n", (millis() - startMillis)); 107 | ESP.deepSleep(30 * 1000000, WAKE_RF_DEFAULT ); 108 | //delay(3000); 109 | 110 | } 111 | -------------------------------------------------------------------------------- /examples/EPaper/EPaperDemo2_54Pervasive/EPaperDemo2_54Pervasive.ino: -------------------------------------------------------------------------------- 1 | // -*- mode: c++ -*- 2 | // Copyright 2013 Pervasive Displays, Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at: 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, 11 | // software distributed under the License is distributed on an 12 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 | // express or implied. See the License for the specific language 14 | // governing permissions and limitations under the License. 15 | 16 | #include 17 | #include 18 | 19 | // required libraries 20 | #include 21 | #include "EPaperPervasive.h" 22 | #include "MiniGrafx.h" 23 | #include "DisplayDriver.h" 24 | 25 | // Arduino IO layout 26 | //const int Pin_TEMPERATURE = A0; // Temperature is handled by LM75 over I2C and not an analog pin 27 | const int Pin_PANEL_ON = 4; // D2 28 | const int Pin_BORDER = 2; // D4 29 | const int Pin_DISCHARGE = 5;// D1 30 | //const int Pin_PWM = 5; // Not used by COG v2 31 | const int Pin_RESET = 16; // D0 32 | const int Pin_BUSY = 5; // D1 33 | const int Pin_EPD_CS = 0; // D3 34 | const int Pin_FLASH_CS = 15;// D8 35 | const int Pin_SW2 = 15; // D8 36 | const int Pin_RED_LED = 15; // D8 37 | 38 | 39 | // defines the colors usable in the paletted 16 color frame buffer 40 | uint16_t palette[] = {0, 1}; 41 | 42 | 43 | // LED anode through resistor to I/O pin 44 | // LED cathode to Ground 45 | #define LED_ON HIGH 46 | #define LED_OFF LOW 47 | 48 | #define EPD_SIZE EPD_2_7 49 | #define SCREEN_WIDTH 264 50 | #define SCREEN_HEIGHT 176 51 | #define BITS_PER_PIXEL 1 52 | 53 | // define the E-Ink display 54 | EPD_Class epd(EPD_SIZE, SCREEN_WIDTH, SCREEN_HEIGHT, Pin_PANEL_ON, Pin_BORDER, Pin_DISCHARGE, Pin_RESET, Pin_BUSY, Pin_EPD_CS); 55 | MiniGrafx gfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette); 56 | 57 | // I/O setup 58 | void setup() { 59 | pinMode(Pin_RED_LED, OUTPUT); 60 | //pinMode(Pin_SW2, INPUT); 61 | //pinMode(Pin_TEMPERATURE, INPUT); 62 | //pinMode(Pin_PWM, OUTPUT); 63 | //pinMode(Pin_BUSY, INPUT); 64 | pinMode(Pin_RESET, OUTPUT); 65 | pinMode(Pin_PANEL_ON, OUTPUT); 66 | pinMode(Pin_DISCHARGE, OUTPUT); 67 | pinMode(Pin_BORDER, OUTPUT); 68 | pinMode(Pin_EPD_CS, OUTPUT); 69 | //pinMode(Pin_FLASH_CS, OUTPUT); 70 | 71 | digitalWrite(Pin_RED_LED, LOW); 72 | //digitalWrite(Pin_PWM, LOW); // not actually used - set low so can use current eval board unmodified 73 | digitalWrite(Pin_RESET, LOW); 74 | digitalWrite(Pin_PANEL_ON, LOW); 75 | digitalWrite(Pin_DISCHARGE, LOW); 76 | digitalWrite(Pin_BORDER, LOW); 77 | digitalWrite(Pin_EPD_CS, LOW); 78 | //digitalWrite(Pin_FLASH_CS, HIGH); 79 | 80 | Serial.begin(115200); 81 | 82 | Serial.println(); 83 | Serial.println(); 84 | //Serial.println("Demo G2 version: " DEMO_VERSION); 85 | //Serial.println("Display: " MAKE_STRING(EPD_SIZE)); 86 | Serial.println(); 87 | 88 | gfx.init(); 89 | epd.init(); // power up the EPD panel 90 | if (!epd) { 91 | Serial.print("EPD error = "); 92 | Serial.print(epd.error()); 93 | Serial.println(""); 94 | return; 95 | } else { 96 | Serial.println("Good to go"); 97 | } 98 | epd.setFactor(25); 99 | epd.clear(); 100 | } 101 | 102 | 103 | static int state = 2; 104 | 105 | 106 | // main loop 107 | void loop() { 108 | gfx.fillBuffer(0); 109 | gfx.setFont(ArialMT_Plain_24); 110 | gfx.setColor(1); 111 | gfx.setTextAlignment(TEXT_ALIGN_LEFT); 112 | gfx.drawString(0, 0, "EPaper Display Driver"); 113 | gfx.drawLine(0, 26, 264, 26); 114 | gfx.fillCircle(264/2, 176 / 2, 10); 115 | gfx.drawRect(264/2 - 12, 176 / 2 - 12, 24, 24); 116 | gfx.commit(); 117 | 118 | 119 | epd.end(); // power down the EPD panel 120 | delay(50000); 121 | } 122 | -------------------------------------------------------------------------------- /examples/ILI9341/DrawPaletteImage_4Bit/DrawPaletteImage_4Bit.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "MiniGrafx.h" // General graphic library 33 | #include "ILI9341_SPI.h" // Hardware-specific library 34 | #include "image.h" 35 | 36 | 37 | #define TFT_DC 4 // D2 38 | #define TFT_CS 5 // D1 39 | #define TFT_LED 15 // D8 40 | 41 | // defines the colors usable in the paletted 16 color frame buffer 42 | uint16_t palette[] = {ILI9341_BLACK, // 0 43 | ILI9341_WHITE, // 1 44 | ILI9341_NAVY, // 2 45 | ILI9341_DARKCYAN, // 3 46 | ILI9341_DARKGREEN, // 4 47 | ILI9341_MAROON, // 5 48 | ILI9341_PURPLE, // 6 49 | ILI9341_OLIVE, // 7 50 | ILI9341_LIGHTGREY, // 8 51 | 0x39E7, //ILI9341_DARKGREY, // 9 52 | ILI9341_BLUE, // 10 53 | ILI9341_GREEN, // 11 54 | ILI9341_CYAN, // 12 55 | ILI9341_RED, // 13 56 | ILI9341_MAGENTA, // 14 57 | 0xFD80}; // 15 58 | 59 | 60 | 61 | int SCREEN_WIDTH = 240; 62 | int SCREEN_HEIGHT = 320; 63 | int BITS_PER_PIXEL = 4 ; // 2^4 = 16 colors 64 | 65 | // Initialize the driver 66 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 67 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 68 | 69 | 70 | // Used for fps measuring 71 | uint16_t counter = 0; 72 | long startMillis = millis(); 73 | uint16_t interval = 20; 74 | int color = 1; 75 | String fps = "0fps"; 76 | 77 | void setup() { 78 | Serial.begin(115200); 79 | 80 | // Turn on the background LED 81 | pinMode(TFT_LED, OUTPUT); 82 | digitalWrite(TFT_LED, HIGH); 83 | 84 | gfx.init(); 85 | gfx.fillBuffer(0); 86 | gfx.drawPalettedBitmapFromPgm(0, -100 + counter % 420, img); 87 | gfx.commit(); 88 | 89 | 90 | startMillis = millis(); 91 | } 92 | 93 | 94 | void loop() { 95 | 96 | gfx.fillBuffer(0); 97 | 98 | gfx.setColor(15); 99 | gfx.drawString(2, 2, fps); 100 | gfx.setTransparentColor(0); 101 | gfx.drawPalettedBitmapFromPgm(100, 100, img); 102 | gfx.commit(); 103 | 104 | counter++; 105 | // only calculate the fps every iterations. 106 | if (counter % interval == 0) { 107 | color = (color + 1) % 15 + 1; 108 | long millisSinceUpdate = millis() - startMillis; 109 | fps = String(interval * 1000.0 / (millisSinceUpdate)) + "fps"; 110 | startMillis = millis(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/EPD_WaveShare_154D67.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2020 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thigpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef EPD1IN54D67_H 29 | #define EPD1IN54D67_H 30 | 31 | #include 32 | #include "DisplayDriver.h" 33 | 34 | // Display resolution 35 | #define EPD_WIDTH 200 36 | #define EPD_HEIGHT 200 37 | 38 | // EPD2IN9 commands 39 | #define DRIVER_OUTPUT_CONTROL 0x01 40 | #define BOOSTER_SOFT_START_CONTROL 0x0C 41 | #define GATE_SCAN_START_POSITION 0x0F 42 | #define DEEP_SLEEP_MODE 0x10 43 | #define DATA_ENTRY_MODE_SETTING 0x11 44 | #define SW_RESET 0x12 45 | #define TEMPERATURE_SENSOR_CONTROL 0x1A 46 | #define MASTER_ACTIVATION 0x20 47 | #define DISPLAY_UPDATE_CONTROL_1 0x21 48 | #define DISPLAY_UPDATE_CONTROL_2 0x22 49 | #define WRITE_RAM 0x24 50 | #define WRITE_VCOM_REGISTER 0x2C 51 | #define WRITE_LUT_REGISTER 0x32 52 | #define SET_DUMMY_LINE_PERIOD 0x3A 53 | #define SET_GATE_TIME 0x3B 54 | #define BORDER_WAVEFORM_CONTROL 0x3C 55 | #define SET_RAM_X_ADDRESS_START_END_POSITION 0x44 56 | #define SET_RAM_Y_ADDRESS_START_END_POSITION 0x45 57 | #define SET_RAM_X_ADDRESS_COUNTER 0x4E 58 | #define SET_RAM_Y_ADDRESS_COUNTER 0x4F 59 | #define TERMINATE_FRAME_READ_WRITE 0xFF 60 | 61 | 62 | class EPD_WaveShare154D67 : public DisplayDriver { 63 | public: 64 | unsigned long width; 65 | unsigned long height; 66 | 67 | EPD_WaveShare154D67(uint8_t csPin, uint8_t rstPin, uint8_t dcPin, uint8_t busyPin); 68 | ~EPD_WaveShare154D67(); 69 | 70 | void setRotation(uint8_t r); 71 | void init(); 72 | 73 | void writeBuffer(BufferInfo *bufferInfo); 74 | 75 | int Init(); 76 | 77 | int IfInit(void); 78 | void DigitalWrite(int pin, int value); 79 | int DigitalRead(int pin); 80 | void DelayMs(unsigned int delaytime); 81 | void SpiTransfer(unsigned char data); 82 | 83 | 84 | void SendCommand(unsigned char command); 85 | void SendData(unsigned char data); 86 | void SendBulkData(unsigned char* data, uint32_t size); 87 | void WaitUntilIdle(void); 88 | void Reset(void); 89 | 90 | void DisplayFrame(void); 91 | void Sleep(void); 92 | void setFastRefresh(boolean isFastRefreshEnabled); 93 | void setTemperature(float temperature); 94 | 95 | private: 96 | uint8_t rotation; 97 | unsigned int reset_pin; 98 | unsigned int dc_pin; 99 | unsigned int cs_pin; 100 | unsigned int busy_pin; 101 | bool isInitialRefresh = true; 102 | 103 | uint8_t reverse(uint8_t in); 104 | uint8_t getPixel(uint8_t *buffer, uint16_t x, uint16_t y, uint16_t bufferWidth, uint16_t bufferHeight); 105 | void fillRam(uint8_t command, uint8_t value); 106 | void SetMemoryArea(int x_start, int y_start, int x_end, int y_end); 107 | void SetMemoryPointer(int x, int y); 108 | void writeBufferWithCommand(uint8_t command, BufferInfo *bufferInfo); 109 | }; 110 | 111 | #endif /* EPD1IN54D67_H */ 112 | 113 | /* END OF FILE */ 114 | -------------------------------------------------------------------------------- /examples/ILI9341/DrawBMP/DrawBMP.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "MiniGrafx.h" // General graphic library 33 | #include "ILI9341_SPI.h" // Hardware-specific library 34 | #include "image.h" 35 | #include 36 | 37 | #define TFT_DC D2 38 | #define TFT_CS D1 39 | #define TFT_LED D8 40 | 41 | // defines the colors usable in the paletted 16 color frame buffer 42 | uint16_t palette[] = {ILI9341_BLACK, // 0 43 | ILI9341_WHITE, // 1 44 | ILI9341_NAVY, // 2 45 | ILI9341_DARKCYAN, // 3 46 | ILI9341_DARKGREEN, // 4 47 | ILI9341_MAROON, // 5 48 | ILI9341_PURPLE, // 6 49 | ILI9341_OLIVE, // 7 50 | ILI9341_LIGHTGREY, // 8 51 | ILI9341_DARKGREY, // 9 52 | ILI9341_BLUE, // 10 53 | ILI9341_GREEN, // 11 54 | ILI9341_CYAN, // 12 55 | ILI9341_RED, // 13 56 | ILI9341_MAGENTA, // 14 57 | ILI9341_YELLOW}; // 15 58 | 59 | 60 | 61 | int SCREEN_WIDTH = 240; 62 | int SCREEN_HEIGHT = 320; 63 | int BITS_PER_PIXEL = 4; // 2^4 = 16 colors 64 | 65 | // Initialize the driver 66 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 67 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 68 | 69 | 70 | // Used for fps measuring 71 | uint16_t counter = 0; 72 | long startMillis = millis(); 73 | uint16_t interval = 20; 74 | int color = 1; 75 | String fps = "0fps"; 76 | 77 | void setup() { 78 | Serial.begin(115200); 79 | 80 | // Turn on the background LED 81 | pinMode(TFT_LED, OUTPUT); 82 | digitalWrite(TFT_LED, HIGH); 83 | 84 | // create grey scale palette for greay image 85 | for (int i = 0; i < 16; i++) { 86 | palette[i] = ((i * 31 / 16) << 11) | ((i * 63 / 16) << 5) | ((i * 31 / 16)); 87 | } 88 | 89 | gfx.init(); 90 | gfx.fillBuffer(0); 91 | gfx.commit(); 92 | //SPIFFS.format(); 93 | SPIFFS.begin(); 94 | /*if (!SPIFFS.remove("file.bmp")) { 95 | Serial.println("Could not remove file"); 96 | } 97 | File f = SPIFFS.open("file.bmp", "w+"); 98 | for (int i = 0; i < image_len; i++) { 99 | uint8_t data = pgm_read_byte(image + i); 100 | f.write(data); 101 | } 102 | f.close();*/ 103 | 104 | //SPIFFS.end(); 105 | 106 | startMillis = millis(); 107 | } 108 | 109 | 110 | void loop() { 111 | 112 | gfx.fillBuffer(0); 113 | gfx.setColor(color); 114 | gfx.drawBmpFromFile("file.bmp", 10, 40 + counter); 115 | //gfx.drawBmpFromPgm(image, 10, 40); 116 | gfx.setColor(15); 117 | gfx.drawString(2, 2, fps); 118 | for (int i = 0; i < 16; i++) { 119 | gfx.setColor(i); 120 | gfx.drawLine(0, i + 100, 240, i + 100); 121 | } 122 | gfx.commit(); 123 | 124 | counter++; 125 | // only calculate the fps every iterations. 126 | if (counter % interval == 0) { 127 | color = (color + 1) % 15 + 1; 128 | long millisSinceUpdate = millis() - startMillis; 129 | fps = String(interval * 1000.0 / (millisSinceUpdate)) + "fps"; 130 | startMillis = millis(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/EPD_WaveShare_29.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef EPD2IN9_H 29 | #define EPD2IN9_H 30 | 31 | #include 32 | #include "DisplayDriver.h" 33 | 34 | // Display resolution 35 | #define EPD_WIDTH 128 36 | #define EPD_HEIGHT 296 37 | 38 | // EPD2IN9 commands 39 | #define DRIVER_OUTPUT_CONTROL 0x01 40 | #define BOOSTER_SOFT_START_CONTROL 0x0C 41 | #define GATE_SCAN_START_POSITION 0x0F 42 | #define DEEP_SLEEP_MODE 0x10 43 | #define DATA_ENTRY_MODE_SETTING 0x11 44 | #define SW_RESET 0x12 45 | #define TEMPERATURE_SENSOR_CONTROL 0x1A 46 | #define MASTER_ACTIVATION 0x20 47 | #define DISPLAY_UPDATE_CONTROL_1 0x21 48 | #define DISPLAY_UPDATE_CONTROL_2 0x22 49 | #define WRITE_RAM 0x24 50 | #define WRITE_VCOM_REGISTER 0x2C 51 | #define WRITE_LUT_REGISTER 0x32 52 | #define SET_DUMMY_LINE_PERIOD 0x3A 53 | #define SET_GATE_TIME 0x3B 54 | #define BORDER_WAVEFORM_CONTROL 0x3C 55 | #define SET_RAM_X_ADDRESS_START_END_POSITION 0x44 56 | #define SET_RAM_Y_ADDRESS_START_END_POSITION 0x45 57 | #define SET_RAM_X_ADDRESS_COUNTER 0x4E 58 | #define SET_RAM_Y_ADDRESS_COUNTER 0x4F 59 | #define TERMINATE_FRAME_READ_WRITE 0xFF 60 | 61 | 62 | const unsigned char lut_full_update[] = 63 | { 64 | 0x32, // command 65 | 0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 67 | }; 68 | 69 | const unsigned char lut_partial_update[] = 70 | { 71 | 0x32, // command 72 | 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 74 | }; 75 | 76 | class EPD_WaveShare29 : public DisplayDriver { 77 | public: 78 | unsigned long width; 79 | unsigned long height; 80 | 81 | EPD_WaveShare29(uint8_t csPin, uint8_t rstPin, uint8_t dcPin, uint8_t busyPin); 82 | ~EPD_WaveShare29(); 83 | 84 | void setRotation(uint8_t r); 85 | void init(); 86 | 87 | void writeBuffer(BufferInfo *bufferInfo); 88 | 89 | int Init(const unsigned char* lut); 90 | 91 | int IfInit(void); 92 | void DigitalWrite(int pin, int value); 93 | int DigitalRead(int pin); 94 | void DelayMs(unsigned int delaytime); 95 | void SpiTransfer(unsigned char data); 96 | 97 | void SendCommand(unsigned char command); 98 | void SendData(unsigned char data); 99 | void WaitUntilIdle(void); 100 | void Reset(void); 101 | 102 | void DisplayFrame(void); 103 | void Sleep(void); 104 | void setFastRefresh(boolean isFastRefreshEnabled); 105 | 106 | private: 107 | uint8_t rotation; 108 | unsigned int reset_pin; 109 | unsigned int dc_pin; 110 | unsigned int cs_pin; 111 | unsigned int busy_pin; 112 | const unsigned char* lut; 113 | 114 | uint8_t reverse(uint8_t in); 115 | uint8_t getPixel(uint8_t *buffer, uint16_t x, uint16_t y, uint16_t bufferWidth, uint16_t bufferHeight); 116 | void SetLut(const unsigned char* lut); 117 | void SetMemoryArea(int x_start, int y_start, int x_end, int y_end); 118 | void SetMemoryPointer(int x, int y); 119 | }; 120 | 121 | #endif /* EPD2IN9_H */ 122 | 123 | /* END OF FILE */ 124 | -------------------------------------------------------------------------------- /src/EPD_WaveShare_154.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thigpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef EPD1IN54_H 29 | #define EPD1IN54_H 30 | 31 | #include 32 | #include "DisplayDriver.h" 33 | 34 | // Display resolution 35 | #define EPD_WIDTH 200 36 | #define EPD_HEIGHT 200 37 | 38 | // EPD2IN9 commands 39 | #define DRIVER_OUTPUT_CONTROL 0x01 40 | #define BOOSTER_SOFT_START_CONTROL 0x0C 41 | #define GATE_SCAN_START_POSITION 0x0F 42 | #define DEEP_SLEEP_MODE 0x10 43 | #define DATA_ENTRY_MODE_SETTING 0x11 44 | #define SW_RESET 0x12 45 | #define TEMPERATURE_SENSOR_CONTROL 0x1A 46 | #define MASTER_ACTIVATION 0x20 47 | #define DISPLAY_UPDATE_CONTROL_1 0x21 48 | #define DISPLAY_UPDATE_CONTROL_2 0x22 49 | #define WRITE_RAM 0x24 50 | #define WRITE_VCOM_REGISTER 0x2C 51 | #define WRITE_LUT_REGISTER 0x32 52 | #define SET_DUMMY_LINE_PERIOD 0x3A 53 | #define SET_GATE_TIME 0x3B 54 | #define BORDER_WAVEFORM_CONTROL 0x3C 55 | #define SET_RAM_X_ADDRESS_START_END_POSITION 0x44 56 | #define SET_RAM_Y_ADDRESS_START_END_POSITION 0x45 57 | #define SET_RAM_X_ADDRESS_COUNTER 0x4E 58 | #define SET_RAM_Y_ADDRESS_COUNTER 0x4F 59 | #define TERMINATE_FRAME_READ_WRITE 0xFF 60 | 61 | 62 | const unsigned char lut_full_update[] = 63 | { 64 | 0x32, // command 65 | 0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 67 | }; 68 | 69 | const unsigned char lut_partial_update[] = 70 | { 71 | 0x32, // command 72 | 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 74 | }; 75 | 76 | class EPD_WaveShare154 : public DisplayDriver { 77 | public: 78 | unsigned long width; 79 | unsigned long height; 80 | 81 | EPD_WaveShare154(uint8_t csPin, uint8_t rstPin, uint8_t dcPin, uint8_t busyPin); 82 | ~EPD_WaveShare154(); 83 | 84 | void setRotation(uint8_t r); 85 | void init(); 86 | 87 | void writeBuffer(BufferInfo *bufferInfo); 88 | 89 | int Init(const unsigned char* lut); 90 | 91 | int IfInit(void); 92 | void DigitalWrite(int pin, int value); 93 | int DigitalRead(int pin); 94 | void DelayMs(unsigned int delaytime); 95 | void SpiTransfer(unsigned char data); 96 | 97 | void SendCommand(unsigned char command); 98 | void SendData(unsigned char data); 99 | void WaitUntilIdle(void); 100 | void Reset(void); 101 | 102 | void DisplayFrame(void); 103 | void Sleep(void); 104 | void setFastRefresh(boolean isFastRefreshEnabled); 105 | void setTemperature(float temperature); 106 | 107 | private: 108 | uint8_t rotation; 109 | unsigned int reset_pin; 110 | unsigned int dc_pin; 111 | unsigned int cs_pin; 112 | unsigned int busy_pin; 113 | const unsigned char* lut; 114 | 115 | uint8_t reverse(uint8_t in); 116 | uint8_t getPixel(uint8_t *buffer, uint16_t x, uint16_t y, uint16_t bufferWidth, uint16_t bufferHeight); 117 | void SetLut(const unsigned char* lut); 118 | void SetMemoryArea(int x_start, int y_start, int x_end, int y_end); 119 | void SetMemoryPointer(int x, int y); 120 | }; 121 | 122 | #endif /* EPD1IN54_H */ 123 | 124 | /* END OF FILE */ 125 | -------------------------------------------------------------------------------- /src/EPD_WaveShare_29T5.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef EPD2IN9T5_H 29 | #define EPD2IN9T5_H 30 | 31 | #include 32 | #include "DisplayDriver.h" 33 | 34 | // Display resolution 35 | #define EPD_WIDTH 128 36 | #define EPD_HEIGHT 296 37 | 38 | // EPD2IN9 commands 39 | #define EPD_PANEL_SETTING 0x00 40 | #define EPD_POWER_SETTING 0x01 41 | #define EPD_POWER_OFF 0x02 42 | #define EPD_POWER_ON 0x04 43 | #define EPD_BOOSTER_SOFT_START 0x06 44 | #define EPD_DEEPL_SLEEP 0x07 45 | #define EPD_DISPLAY_START_TRANSMISSION_1 0x10 46 | #define EPD_REFRESH_FRAME 0x12 47 | #define EPD_DISPLAY_START_TRANSMISSION_2 0x13 48 | #define EPD_SET_LUT_VCOM 0x20 49 | #define EPD_SET_LUT_WW 0x21 50 | #define EPD_SET_LUT_BW 0x22 51 | #define EPD_SET_LUT_WB 0x23 52 | #define EPD_SET_LUT_BB 0x24 53 | #define EPD_PLL_SETTING 0x30 54 | #define EPD_VCOM_DATA_INTERNAL_SETTING 0x50 55 | #define EPD_RESOLUTION_SETTING 0x61 56 | #define EPD_VCOM_DC_SETTING 0x82 57 | #define EPD_PARTIAL_RESOLUTION_SETTING 0x90 58 | #define EPD_PARTIAL_IN 0x91 59 | #define EPD_PARTIAL_OUT 0x92 60 | 61 | 62 | class EPD_WaveShare29T5 : public DisplayDriver { 63 | public: 64 | unsigned long width; 65 | unsigned long height; 66 | 67 | EPD_WaveShare29T5(uint8_t csPin, uint8_t rstPin, uint8_t dcPin, uint8_t busyPin); 68 | ~EPD_WaveShare29T5(); 69 | 70 | void setRotation(uint8_t r); 71 | void init(); 72 | 73 | void writeBuffer(BufferInfo *bufferInfo); 74 | 75 | int IfInit(void); 76 | void DigitalWrite(int pin, int value); 77 | int DigitalRead(int pin); 78 | void DelayMs(unsigned int delaytime); 79 | void SpiTransfer(unsigned char data); 80 | 81 | void SendCommand(unsigned char command); 82 | void SendData(unsigned char data); 83 | void WaitUntilIdle(void); 84 | void Reset(void); 85 | 86 | void DisplayFrame(void); 87 | void Sleep(void); 88 | void setFastRefresh(boolean isFastRefreshEnabled); 89 | 90 | private: 91 | uint8_t rotation; 92 | unsigned int reset_pin; 93 | unsigned int dc_pin; 94 | unsigned int cs_pin; 95 | unsigned int busy_pin; 96 | 97 | uint8_t reverse(uint8_t in); 98 | uint8_t getPixel(uint8_t *buffer, uint16_t x, uint16_t y, uint16_t bufferWidth, uint16_t bufferHeight); 99 | void SetLut(); 100 | void SetMemoryArea(int x_start, int y_start, int x_end, int y_end); 101 | 102 | static const unsigned char lut_20_vcomDC_2bit[]; 103 | static const unsigned char lut_21_ww_2bit[]; 104 | static const unsigned char lut_22_bw_2bit[]; 105 | static const unsigned char lut_23_wb_2bit[]; 106 | static const unsigned char lut_24_bb_2bit[]; 107 | static const unsigned char* lut_2bit[]; 108 | 109 | static const unsigned char lut_20_vcomDC[]; 110 | static const unsigned char lut_21_ww[]; 111 | static const unsigned char lut_22_bw[]; 112 | static const unsigned char lut_23_wb[]; 113 | static const unsigned char lut_24_bb[]; 114 | static const unsigned char* lut_full[]; 115 | 116 | static const unsigned char lut_20_vcomDC_partial[]; 117 | static const unsigned char lut_21_ww_partial[]; 118 | static const unsigned char lut_22_bw_partial[]; 119 | static const unsigned char lut_23_wb_partial[]; 120 | static const unsigned char lut_24_bb_partial[]; 121 | static const unsigned char* lut_partial[]; 122 | 123 | }; 124 | 125 | #endif /* EPD2IN9T5_H */ 126 | 127 | /* END OF FILE */ 128 | -------------------------------------------------------------------------------- /src/ILI9341_SPI.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef _MINIGRAFX_ILI9341H_ 29 | #define _MINIGRAFX_ILI9341H_ 30 | 31 | #include "Arduino.h" 32 | #include "Print.h" 33 | #include "DisplayDriver.h" 34 | #if defined (__AVR__) 35 | #include 36 | #elif defined(ESP8266) 37 | #include 38 | #endif 39 | 40 | 41 | #define ILI9341_TFTWIDTH 240 42 | #define ILI9341_TFTHEIGHT 320 43 | 44 | #define ILI9341_NOP 0x00 45 | #define ILI9341_SWRESET 0x01 46 | #define ILI9341_RDDID 0x04 47 | #define ILI9341_RDDST 0x09 48 | 49 | #define ILI9341_SLPIN 0x10 50 | #define ILI9341_SLPOUT 0x11 51 | #define ILI9341_PTLON 0x12 52 | #define ILI9341_NORON 0x13 53 | 54 | #define ILI9341_RDMODE 0x0A 55 | #define ILI9341_RDMADCTL 0x0B 56 | #define ILI9341_RDPIXFMT 0x0C 57 | #define ILI9341_RDIMGFMT 0x0D 58 | #define ILI9341_RDSELFDIAG 0x0F 59 | 60 | #define ILI9341_INVOFF 0x20 61 | #define ILI9341_INVON 0x21 62 | #define ILI9341_GAMMASET 0x26 63 | #define ILI9341_DISPOFF 0x28 64 | #define ILI9341_DISPON 0x29 65 | 66 | #define ILI9341_CASET 0x2A 67 | #define ILI9341_PASET 0x2B 68 | #define ILI9341_RAMWR 0x2C 69 | #define ILI9341_RAMRD 0x2E 70 | 71 | #define ILI9341_PTLAR 0x30 72 | #define ILI9341_MADCTL 0x36 73 | #define ILI9341_PIXFMT 0x3A 74 | 75 | #define ILI9341_FRMCTR1 0xB1 76 | #define ILI9341_FRMCTR2 0xB2 77 | #define ILI9341_FRMCTR3 0xB3 78 | #define ILI9341_INVCTR 0xB4 79 | #define ILI9341_DFUNCTR 0xB6 80 | 81 | #define ILI9341_PWCTR1 0xC0 82 | #define ILI9341_PWCTR2 0xC1 83 | #define ILI9341_PWCTR3 0xC2 84 | #define ILI9341_PWCTR4 0xC3 85 | #define ILI9341_PWCTR5 0xC4 86 | #define ILI9341_VMCTR1 0xC5 87 | #define ILI9341_VMCTR2 0xC7 88 | 89 | #define ILI9341_RDID1 0xDA 90 | #define ILI9341_RDID2 0xDB 91 | #define ILI9341_RDID3 0xDC 92 | #define ILI9341_RDID4 0xDD 93 | 94 | #define ILI9341_GMCTRP1 0xE0 95 | #define ILI9341_GMCTRN1 0xE1 96 | /* 97 | #define ILI9341_PWCTR6 0xFC 98 | 99 | */ 100 | 101 | // Color definitions 102 | #define ILI9341_BLACK 0x0000 /* 0, 0, 0 */ 103 | #define ILI9341_NAVY 0x000F /* 0, 0, 128 */ 104 | #define ILI9341_DARKGREEN 0x03E0 /* 0, 128, 0 */ 105 | #define ILI9341_DARKCYAN 0x03EF /* 0, 128, 128 */ 106 | #define ILI9341_MAROON 0x7800 /* 128, 0, 0 */ 107 | #define ILI9341_PURPLE 0x780F /* 128, 0, 128 */ 108 | #define ILI9341_OLIVE 0x7BE0 /* 128, 128, 0 */ 109 | #define ILI9341_LIGHTGREY 0xC618 /* 192, 192, 192 */ 110 | #define ILI9341_DARKGREY 0x7BEF /* 128, 128, 128 */ 111 | #define ILI9341_BLUE 0x001F /* 0, 0, 255 */ 112 | #define ILI9341_GREEN 0x07E0 /* 0, 255, 0 */ 113 | #define ILI9341_CYAN 0x07FF /* 0, 255, 255 */ 114 | #define ILI9341_RED 0xF800 /* 255, 0, 0 */ 115 | #define ILI9341_MAGENTA 0xF81F /* 255, 0, 255 */ 116 | #define ILI9341_YELLOW 0xFFE0 /* 255, 255, 0 */ 117 | #define ILI9341_WHITE 0xFFFF /* 255, 255, 255 */ 118 | #define ILI9341_ORANGE 0xFD20 /* 255, 165, 0 */ 119 | #define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ 120 | #define ILI9341_PINK 0xF81F 121 | 122 | 123 | class ILI9341_SPI : public DisplayDriver { 124 | 125 | public: 126 | 127 | ILI9341_SPI(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK, 128 | int8_t _RST, int8_t _MISO); 129 | ILI9341_SPI(int8_t _CS, int8_t _DC, int8_t _RST = -1); 130 | 131 | void init(void); 132 | void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); 133 | void setRotation(uint8_t r); 134 | 135 | void writeBuffer(BufferInfo *bufferInfo); 136 | 137 | void pushColor(uint16_t color); 138 | void setFastRefresh(boolean isFastRefreshEnabled); 139 | 140 | void spiwrite(uint8_t); 141 | void writecommand(uint8_t c); 142 | void writedata(uint8_t d); 143 | 144 | 145 | 146 | private: 147 | boolean hwSPI; 148 | int32_t _cs, _dc, _rst, _mosi, _miso, _sclk; 149 | 150 | }; 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /src/EPD_WaveShare_75.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef EPD7IN5_H 29 | #define EPD7IN5_H 30 | 31 | #include 32 | #include 33 | #include "DisplayDriver.h" 34 | 35 | // Display resolution 36 | #define EPD_WIDTH 640 37 | #define EPD_HEIGHT 384 38 | 39 | // EPD7IN5 commands 40 | #define PANEL_SETTING 0x00 41 | #define POWER_SETTING 0x01 42 | #define POWER_OFF 0x02 43 | #define POWER_OFF_SEQUENCE_SETTING 0x03 44 | #define POWER_ON 0x04 45 | #define POWER_ON_MEASURE 0x05 46 | #define BOOSTER_SOFT_START 0x06 47 | #define DEEP_SLEEP 0x07 48 | #define DATA_START_TRANSMISSION_1 0x10 49 | #define DATA_STOP 0x11 50 | #define DISPLAY_REFRESH 0x12 51 | #define IMAGE_PROCESS 0x13 52 | #define LUT_FOR_VCOM 0x20 53 | #define LUT_BLUE 0x21 54 | #define LUT_WHITE 0x22 55 | #define LUT_GRAY_1 0x23 56 | #define LUT_GRAY_2 0x24 57 | #define LUT_RED_0 0x25 58 | #define LUT_RED_1 0x26 59 | #define LUT_RED_2 0x27 60 | #define LUT_RED_3 0x28 61 | #define LUT_XON 0x29 62 | #define PLL_CONTROL 0x30 63 | #define TEMPERATURE_SENSOR_COMMAND 0x40 64 | #define TEMPERATURE_CALIBRATION 0x41 65 | #define TEMPERATURE_SENSOR_WRITE 0x42 66 | #define TEMPERATURE_SENSOR_READ 0x43 67 | #define VCOM_AND_DATA_INTERVAL_SETTING 0x50 68 | #define LOW_POWER_DETECTION 0x51 69 | #define TCON_SETTING 0x60 70 | #define TCON_RESOLUTION 0x61 71 | #define SPI_FLASH_CONTROL 0x65 72 | #define REVISION 0x70 73 | #define GET_STATUS 0x71 74 | #define AUTO_MEASUREMENT_VCOM 0x80 75 | #define READ_VCOM_VALUE 0x81 76 | #define VCM_DC_SETTING 0x82 77 | 78 | class EPD_WaveShare75 : public DisplayDriver { 79 | public: 80 | EPD_WaveShare75(uint8_t csPin, uint8_t rstPin, uint8_t dcPin, uint8_t busyPin); 81 | ~EPD_WaveShare75(); 82 | void init(void); 83 | void setRotation(uint8_t r); 84 | void writeBuffer(BufferInfo *bufferInfo); 85 | 86 | void WaitUntilIdle(void); 87 | void Reset(void); 88 | void SetLut(void); 89 | void DisplayFrame(const unsigned char* frame_buffer, uint8_t bitsPerPixel, uint16_t *palette); 90 | void SendCommand(unsigned char command); 91 | void SendData(unsigned char data); 92 | void Sleep(void); 93 | int IfInit(void); 94 | void DelayMs(unsigned int delaytime); 95 | void DigitalWrite(int pin, int value); 96 | int DigitalRead(int pin); 97 | void SpiTransfer(unsigned char data); 98 | void setFastRefresh(boolean isFastRefreshEnabled); 99 | uint8_t getPixel(const unsigned char* buffer, uint16_t x, uint16_t y, uint8_t bitsPerPixel); 100 | uint8_t getPixel(const unsigned char* buffer, uint16_t x, uint16_t y); 101 | uint8_t reverse(uint8_t in); 102 | 103 | private: 104 | uint8_t reset_pin; 105 | uint8_t dc_pin; 106 | uint8_t cs_pin; 107 | uint8_t busy_pin; 108 | uint16_t width; 109 | uint16_t height; 110 | uint16_t bufferWidth; 111 | uint16_t bufferHeight; 112 | uint8_t rotation; 113 | }; 114 | 115 | #endif /* EPD7IN5_H */ 116 | 117 | /* END OF FILE */ 118 | -------------------------------------------------------------------------------- /examples/EPaper/EPD_WaveShare_1_54D67/EPD_WaveShare_1_54D67.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "EPD_WaveShare_154D67.h" 33 | #include "MiniGrafx.h" 34 | #include "DisplayDriver.h" 35 | 36 | 37 | #define MINI_BLACK 0 38 | #define MINI_WHITE 1 39 | 40 | /* 41 | Connect the following pins: 42 | Display NodeMCU 43 | BUSY D1 44 | RST D2 45 | DC D8 46 | CS D3 47 | CLK D5 48 | DIN D7 49 | GND GND 50 | 3.3V 3V3 51 | */ 52 | /*#define CS D3 53 | #define RST D2 54 | #define DC D8 55 | #define BUSY D1*/ 56 | 57 | /*#if defined(ESP8266) 58 | #define CS 15 // D8 59 | #define RST 2 // D4 60 | #define DC 5 // D1 61 | #define BUSY 4 // D2 62 | #elif defined(ESP32)*/ 63 | #define CS 4 // D8 64 | #define RST 14 // D4 65 | #define DC 12 // D1 66 | #define BUSY 27 // D2 67 | #define EPD_CS 4 68 | 69 | //#endif 70 | 71 | #define BITS_PER_PIXEL 1 72 | 73 | 74 | uint16_t palette[] = {0, 1}; 75 | boolean isFastRefreshEnabled = false; 76 | 77 | EPD_WaveShare154D67 epd(CS, RST, DC, BUSY); 78 | MiniGrafx screenGfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette, EPD_WIDTH, EPD_HEIGHT); 79 | MiniGrafx dialogGfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette, 96, 96); 80 | 81 | uint8_t counter = 0; 82 | uint8_t rotation = 0; 83 | uint8_t mode = 0; 84 | boolean modeChanged = true; 85 | 86 | #define MODES 3 87 | 88 | void testFullScreenCommit() { 89 | 90 | screenGfx.setRotation(rotation); 91 | screenGfx.fillBuffer(MINI_WHITE); 92 | screenGfx.setColor(MINI_BLACK); 93 | screenGfx.setFont(ArialMT_Plain_10); 94 | screenGfx.drawLine(0, 0, screenGfx.getWidth(), screenGfx.getHeight()); 95 | screenGfx.drawRect(0, 0, screenGfx.getWidth() - 1, screenGfx.getHeight() - 1); 96 | screenGfx.drawString(0, 0, "Hello World.\nMillis: " + String(millis()) + "\nRotation: " + String(rotation)); 97 | screenGfx.commit(); 98 | rotation = (rotation + 1) % 4; 99 | } 100 | 101 | void testPictureInPicture() { 102 | dialogGfx.setFastRefresh(true); 103 | dialogGfx.setRotation(rotation); 104 | dialogGfx.fillBuffer(MINI_WHITE); 105 | dialogGfx.commit(16, 16); 106 | dialogGfx.setColor(MINI_BLACK); 107 | dialogGfx.setFont(ArialMT_Plain_10); 108 | dialogGfx.drawLine(0, 0, dialogGfx.getWidth(), dialogGfx.getHeight()); 109 | dialogGfx.drawString(0, 0, "Hello World. Rotation:\n" + String(rotation)); 110 | dialogGfx.commit(16, 16); 111 | rotation = (rotation + 1) % 4; 112 | } 113 | 114 | void testWindowedCommit() { 115 | screenGfx.setFastRefresh(true); 116 | //screenGfx.fillBuffer(MINI_BLACK); 117 | //screenGfx.commit(16, 16, 80, 32, 16, 16); 118 | screenGfx.setColor(MINI_WHITE); 119 | 120 | screenGfx.setRotation(0); 121 | screenGfx.setFont(ArialMT_Plain_24); 122 | screenGfx.drawString(18, 18, String(millis())); 123 | screenGfx.commit(16, 16, 80, 32, 16, 16); 124 | } 125 | 126 | void setup() { 127 | Serial.begin(115200); 128 | 129 | screenGfx.init(); 130 | screenGfx.fillBuffer(MINI_WHITE); 131 | screenGfx.setColor(MINI_BLACK); 132 | // the device thas two screen buffers. For partial update 133 | // make sure that both have the same content-> clear both. 134 | //screenGfx.commit(); 135 | //screenGfx.commit(); 136 | 137 | dialogGfx.init(); 138 | 139 | 140 | } 141 | 142 | #define REPETITIONS 10 143 | #define MODES 4 144 | 145 | void loop() { 146 | //ode = 3; 147 | uint64_t startTime = millis(); 148 | switch(mode) { 149 | case 0: 150 | Serial.println("Testing Fullscreen commit. Fast Refresh"); 151 | screenGfx.setFastRefresh(true); 152 | testFullScreenCommit(); 153 | break; 154 | case 1: 155 | Serial.println("Testing Fullscreen commit. Full Refresh"); 156 | screenGfx.setFastRefresh(false); 157 | testFullScreenCommit(); 158 | break; 159 | case 2: 160 | Serial.println("Testing Picture in Picture/ Partial update"); 161 | dialogGfx.setFastRefresh(true); 162 | testPictureInPicture(); 163 | break; 164 | case 3: 165 | Serial.println("Testing windowed commit"); 166 | testWindowedCommit(); 167 | } 168 | Serial.printf("Cycle took: %dms\n", millis() - startTime ); 169 | 170 | counter++; 171 | modeChanged = false; 172 | if (counter % REPETITIONS == 0) { 173 | modeChanged = true; 174 | mode = (mode + 1) % MODES; 175 | } 176 | //delay(4000); 177 | 178 | } 179 | -------------------------------------------------------------------------------- /examples/EPaper/EPD_WaveShare_29/EPD_WaveShare_29.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "EPD_WaveShare_29.h" 33 | #include "MiniGrafx.h" 34 | #include "DisplayDriver.h" 35 | 36 | #define MINI_BLACK 0 37 | #define MINI_WHITE 1 38 | 39 | /* 40 | Connect the following pins: 41 | Display NodeMCU 42 | BUSY D1 43 | RST D2 44 | DC D8 45 | CS D3 46 | CLK D5 47 | DIN D7 48 | GND GND 49 | 3.3V 3V3 50 | */ 51 | /*#define CS D3 52 | #define RST D2 53 | #define DC D8 54 | #define BUSY D1*/ 55 | 56 | #if defined(ESP8266) 57 | #define CS 15 // D8 58 | #define RST 2 // D4 59 | #define DC 5 // D1 60 | #define BUSY 4 // D2 61 | #elif defined(ESP32) 62 | #define CS 5 // D8 63 | #define RST 12 // D4 64 | #define DC 19 // D1 65 | #define BUSY 4 // D2 66 | #endif 67 | 68 | #define BITS_PER_PIXEL 1 69 | 70 | 71 | uint16_t palette[] = {0, 1}; 72 | boolean isFastRefreshEnabled = false; 73 | 74 | EPD_WaveShare29 epd(CS, RST, DC, BUSY); 75 | MiniGrafx screenGfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette, EPD_WIDTH, EPD_HEIGHT); 76 | MiniGrafx dialogGfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette, 96, 96); 77 | 78 | uint8_t counter = 0; 79 | uint8_t rotation = 0; 80 | uint8_t mode = 0; 81 | boolean modeChanged = true; 82 | 83 | #define MODES 3 84 | 85 | void testFullScreenCommit() { 86 | 87 | screenGfx.setRotation(rotation); 88 | screenGfx.fillBuffer(MINI_WHITE); 89 | screenGfx.setColor(MINI_BLACK); 90 | screenGfx.setFont(ArialMT_Plain_10); 91 | screenGfx.drawLine(0, 0, screenGfx.getWidth(), screenGfx.getHeight()); 92 | screenGfx.drawRect(0, 0, screenGfx.getWidth() - 1, screenGfx.getHeight() - 1); 93 | screenGfx.drawString(0, 0, "Hello World.\nMillis: " + String(millis()) + "\nRotation: " + String(rotation)); 94 | screenGfx.commit(); 95 | rotation = (rotation + 1) % 4; 96 | } 97 | 98 | void testPictureInPicture() { 99 | if (modeChanged) { 100 | screenGfx.commit(); 101 | screenGfx.commit(); 102 | } 103 | dialogGfx.setFastRefresh(true); 104 | dialogGfx.setRotation(rotation); 105 | dialogGfx.fillBuffer(MINI_BLACK); 106 | dialogGfx.setColor(MINI_WHITE); 107 | dialogGfx.setFont(ArialMT_Plain_10); 108 | dialogGfx.drawLine(0, 0, dialogGfx.getWidth(), dialogGfx.getHeight()); 109 | dialogGfx.drawString(0, 0, "Hello World. Rotation:\n" + String(rotation)); 110 | dialogGfx.commit(16, 16); 111 | rotation = (rotation + 1) % 4; 112 | } 113 | 114 | void testWindowedCommit() { 115 | if (modeChanged) { 116 | screenGfx.setFastRefresh(false); 117 | screenGfx.commit(); 118 | screenGfx.commit(); 119 | } 120 | screenGfx.fillBuffer(MINI_BLACK); 121 | screenGfx.setColor(MINI_WHITE); 122 | screenGfx.setFastRefresh(true); 123 | screenGfx.setRotation(0); 124 | screenGfx.setFont(ArialMT_Plain_24); 125 | screenGfx.drawString(18, 18, String(millis())); 126 | screenGfx.commit(16, 16, 80, 32, 16, 16); 127 | } 128 | 129 | void setup() { 130 | Serial.begin(115200); 131 | 132 | screenGfx.init(); 133 | screenGfx.fillBuffer(MINI_WHITE); 134 | screenGfx.setColor(MINI_BLACK); 135 | // the device thas two screen buffers. For partial update 136 | // make sure that both have the same content-> clear both. 137 | screenGfx.commit(); 138 | screenGfx.commit(); 139 | 140 | dialogGfx.init(); 141 | 142 | 143 | } 144 | 145 | #define REPETITIONS 10 146 | #define MODES 4 147 | 148 | void loop() { 149 | uint64_t startTime = millis(); 150 | switch(mode) { 151 | case 0: 152 | Serial.println("Testing Fullscreen commit. Fast Refresh"); 153 | screenGfx.setFastRefresh(true); 154 | testFullScreenCommit(); 155 | break; 156 | case 1: 157 | Serial.println("Testing Fullscreen commit. Full Refresh"); 158 | screenGfx.setFastRefresh(false); 159 | testFullScreenCommit(); 160 | break; 161 | case 2: 162 | Serial.println("Testing Picture in Picture/ Partial update"); 163 | dialogGfx.setFastRefresh(true); 164 | testPictureInPicture(); 165 | break; 166 | case 3: 167 | Serial.println("Testing windowed commit"); 168 | testWindowedCommit(); 169 | } 170 | Serial.printf("Cycle took: %dms\n", millis() - startTime ); 171 | 172 | counter++; 173 | modeChanged = false; 174 | if (counter % REPETITIONS == 0) { 175 | modeChanged = true; 176 | mode = (mode + 1) % MODES; 177 | } 178 | //delay(4000); 179 | 180 | } 181 | -------------------------------------------------------------------------------- /examples/CSN_A2/CSN_A2_DEMO/CSN_A2_ThermalPrinter.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #include "CSN_A2_ThermalPrinter.h" 29 | 30 | // Constructor when using hardware SPI. Faster, but must use SPI pins 31 | // specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.) 32 | CSN_A2::CSN_A2(int8_t rx, int8_t tx) : DisplayDriver(CSN_A2_WIDTH, CSN_A2_HEIGHT) { 33 | this->_rx = rx; 34 | this->_tx = tx; 35 | } 36 | 37 | void CSN_A2::init(void) { 38 | this->serial = new SoftwareSerial(this->_rx, this->_tx); 39 | this->serial->begin(9600); 40 | 41 | this->wake(); 42 | delay(500); 43 | int zero=0; 44 | int heatTime = 80; 45 | int heatInterval = 255; 46 | char printDensity = 15; 47 | char printBreakTime = 15; 48 | 49 | this->serial->write(27); 50 | this->serial->write(64); 51 | 52 | this->serial->write(27); 53 | this->serial->write(55); 54 | this->serial->write(7); //Default 64 dots = 8*('7'+1) 55 | this->serial->write(heatTime); //Default 80 or 800us 56 | this->serial->write(heatInterval); //Default 2 or 20us 57 | //Modify the print density and timeout 58 | this->serial->write(18); 59 | this->serial->write(35); 60 | int printSetting = (printDensity<<4) | printBreakTime; 61 | this->serial->write(printSetting); //Combination of printDensity and printBreakTime 62 | } 63 | 64 | void CSN_A2::setFastRefresh(boolean isFastRefreshEnabled) { 65 | // Not enabled at the moment 66 | } 67 | 68 | void CSN_A2::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { 69 | 70 | } 71 | void CSN_A2::setRotation(uint8_t r) { 72 | 73 | } 74 | 75 | void CSN_A2::wake() { 76 | // Printer may have been idle for a very long time, during which the 77 | // micros() counter has rolled over. To avoid shenanigans, reset the 78 | // timeout counter before issuing the wake command. 79 | this->serial->write(255); 80 | // Datasheet recomments a 50 mS delay before issuing further commands, 81 | // but in practice this alone isn't sufficient (e.g. text size/style 82 | // commands may still be misinterpreted on wake). A slightly longer 83 | // delay, interspersed with ESC chars (no-ops) seems to help. 84 | for(uint8_t i=0; i<10; i++) { 85 | this->serial->write(27); 86 | delay(100); 87 | } 88 | } 89 | 90 | void CSN_A2::writeBuffer(BufferInfo *bufferInfo) { 91 | int w = bufferInfo->bufferWidth; 92 | int h = bufferInfo->bufferHeight; 93 | const uint8_t *bitmap = bufferInfo->buffer; 94 | 95 | int maxChunkHeight = 255; 96 | 97 | int rowBytes, rowBytesClipped, rowStart, chunkHeight, chunkHeightLimit, 98 | x, y, i; 99 | 100 | rowBytes = (w + 7) / 8; // Round up to next byte boundary 101 | rowBytesClipped = (rowBytes >= 48) ? 48 : rowBytes; // 384 pixels max width 102 | bool dtrEnabled = false; 103 | // Est. max rows to write at once, assuming 256 byte printer buffer. 104 | if(dtrEnabled) { 105 | chunkHeightLimit = 255; // Buffer doesn't matter, handshake! 106 | } else { 107 | chunkHeightLimit = 256 / rowBytesClipped; 108 | if(chunkHeightLimit > maxChunkHeight) chunkHeightLimit = maxChunkHeight; 109 | else if(chunkHeightLimit < 1) chunkHeightLimit = 1; 110 | } 111 | 112 | for(i=rowStart=0; rowStart < h; rowStart += chunkHeightLimit) { 113 | // Issue up to chunkHeightLimit rows at a time: 114 | chunkHeight = h - rowStart; 115 | if(chunkHeight > chunkHeightLimit) chunkHeight = chunkHeightLimit; 116 | 117 | this->serial->write(ASCII_DC2); 118 | this->serial->write('*'); 119 | this->serial->write(chunkHeight); 120 | this->serial->write(rowBytesClipped); 121 | 122 | for(y=0; y < chunkHeight; y++) { 123 | for(x=0; x < rowBytesClipped; x++, i++) { 124 | //timeoutWait(); 125 | delay(1); 126 | this->serial->write(~reverse(*(bitmap+i))); 127 | } 128 | i += rowBytes - rowBytesClipped; 129 | } 130 | Serial.print("."); 131 | //timeoutSet(chunkHeight * dotPrintTime); 132 | } 133 | this->serial->print(FF); 134 | // prevByte = '\n'; 135 | 136 | } 137 | 138 | uint8_t CSN_A2::reverse(uint8_t in){ 139 | uint8_t out; 140 | out = 0; 141 | if (in & 0x01) out |= 0x80; 142 | if (in & 0x02) out |= 0x40; 143 | if (in & 0x04) out |= 0x20; 144 | if (in & 0x08) out |= 0x10; 145 | if (in & 0x10) out |= 0x08; 146 | if (in & 0x20) out |= 0x04; 147 | if (in & 0x40) out |= 0x02; 148 | if (in & 0x80) out |= 0x01; 149 | 150 | return(out); 151 | } 152 | 153 | void CSN_A2::timeoutWait() { 154 | //while((long)(micros() - resumeTime) < 0L); // (syntax is rollover-proof) 155 | //delay(resumeTime); 156 | } 157 | -------------------------------------------------------------------------------- /examples/EPaper/EPD_WaveShare_29T5/EPD_WaveShare_29T5.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #include 29 | #include "EPD_WaveShare_29T5.h" 30 | #include "MiniGrafx.h" 31 | #include "DisplayDriver.h" 32 | 33 | #define MINI_BLACK 0 34 | #define MINI_WHITE 1 35 | 36 | /* 37 | Connect the following pins: 38 | Display NodeMCU 39 | BUSY D1 40 | RST D2 41 | DC D8 42 | CS D3 43 | CLK D5 44 | DIN D7 45 | GND GND 46 | 3.3V 3V3 47 | */ 48 | /*#define CS D3 49 | #define RST D2 50 | #define DC D8 51 | #define BUSY D1*/ 52 | 53 | #if defined(ESP8266) 54 | #define CS 15 // D8 55 | #define RST 2 // D4 56 | #define DC 5 // D1 57 | #define BUSY 4 // D2 58 | #elif defined(ESP32) 59 | #define CS 5 // D8 60 | #define RST 12 // D4 61 | #define DC 19 // D1 62 | #define BUSY 4 // D2 63 | #endif 64 | 65 | #define BITS_PER_PIXEL 1 66 | 67 | 68 | uint16_t palette[] = {0, 1}; 69 | boolean isFastRefreshEnabled = false; 70 | 71 | EPD_WaveShare29T5 epd(CS, RST, DC, BUSY); 72 | MiniGrafx screenGfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette, EPD_WIDTH, EPD_HEIGHT); 73 | MiniGrafx dialogGfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette, 96, 96); 74 | 75 | uint8_t counter = 0; 76 | uint8_t rotation = 0; 77 | uint8_t mode = 0; 78 | boolean modeChanged = true; 79 | 80 | #define MODES 3 81 | 82 | void testFullScreenCommit() { 83 | 84 | 85 | screenGfx.setRotation(rotation); 86 | screenGfx.fillBuffer(MINI_WHITE); 87 | screenGfx.setColor(MINI_BLACK); 88 | screenGfx.setFont(ArialMT_Plain_10); 89 | screenGfx.drawLine(0, 0, screenGfx.getWidth(), screenGfx.getHeight()); 90 | screenGfx.drawRect(0, 0, screenGfx.getWidth() - 1, screenGfx.getHeight() - 1); 91 | screenGfx.drawString(0, 0, "Hello World.\nMillis: " + String(millis()) + "\nRotation: " + String(rotation)); 92 | screenGfx.commit(); 93 | rotation = (rotation + 1) % 4; 94 | } 95 | 96 | void testPictureInPicture() { 97 | if (modeChanged) { 98 | screenGfx.commit(); 99 | screenGfx.commit(); 100 | } 101 | dialogGfx.setFastRefresh(true); 102 | dialogGfx.setRotation(rotation); 103 | dialogGfx.fillBuffer(MINI_BLACK); 104 | dialogGfx.setColor(MINI_WHITE); 105 | dialogGfx.setFont(ArialMT_Plain_10); 106 | dialogGfx.drawLine(0, 0, dialogGfx.getWidth(), dialogGfx.getHeight()); 107 | dialogGfx.drawString(0, 0, "Hello World. Rotation:\n" + String(rotation)); 108 | dialogGfx.commit(16, 16); 109 | rotation = (rotation + 1) % 4; 110 | } 111 | 112 | void testWindowedCommit() { 113 | if (modeChanged) { 114 | screenGfx.setFastRefresh(false); 115 | screenGfx.commit(); 116 | screenGfx.commit(); 117 | } 118 | screenGfx.fillBuffer(MINI_BLACK); 119 | screenGfx.setColor(MINI_WHITE); 120 | screenGfx.setFastRefresh(true); 121 | screenGfx.setRotation(0); 122 | screenGfx.setFont(ArialMT_Plain_24); 123 | screenGfx.drawString(18, 18, String(millis())); 124 | screenGfx.commit(16, 16, 80, 32, 16, 16); 125 | } 126 | 127 | void setup() { 128 | Serial.begin(115200); 129 | 130 | screenGfx.init(); 131 | screenGfx.fillBuffer(MINI_WHITE); 132 | screenGfx.setColor(MINI_BLACK); 133 | // the device thas two screen buffers. For partial update 134 | // make sure that both have the same content-> clear both. 135 | screenGfx.commit(); 136 | 137 | dialogGfx.init(); 138 | 139 | 140 | } 141 | 142 | #define REPETITIONS 10 143 | #define MODES 5 144 | 145 | void loop() { 146 | uint64_t startTime = millis(); 147 | switch(mode) { 148 | case 0: 149 | Serial.println("Testing Fullscreen commit. Fast Refresh"); 150 | screenGfx.setFastRefresh(true); 151 | testFullScreenCommit(); 152 | break; 153 | case 1: 154 | Serial.println("Testing Fullscreen commit. Full Refresh"); 155 | screenGfx.setFastRefresh(false); 156 | testFullScreenCommit(); 157 | break; 158 | case 2: 159 | Serial.println("Testing Picture in Picture/ Partial update"); 160 | dialogGfx.setFastRefresh(true); 161 | testPictureInPicture(); 162 | break; 163 | case 3: 164 | Serial.println("Testing windowed commit"); 165 | testWindowedCommit(); 166 | break; 167 | case 4: 168 | Serial.println("Test Sleep"); 169 | epd.Sleep(); 170 | epd.init(); 171 | counter = 0; 172 | mode = 0; 173 | break; 174 | } 175 | Serial.printf("Cycle took: %dms\n", millis() - startTime ); 176 | Serial.println("----------"); 177 | counter++; 178 | modeChanged = false; 179 | if (counter % REPETITIONS == 0) { 180 | Serial.println("================="); 181 | modeChanged = true; 182 | mode = (mode + 1) % MODES; 183 | } 184 | //delay(4000); 185 | 186 | } 187 | -------------------------------------------------------------------------------- /examples/ILI9341/DrawXBM/DrawXBM.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "MiniGrafx.h" // General graphic library 33 | #include "ILI9341_SPI.h" // Hardware-specific library 34 | 35 | #define TFT_DC 4 // D2 36 | #define TFT_CS 5 // D1 37 | #define TFT_LED 15 // D8 38 | 39 | // See https://blog.squix.org/2015/05/esp8266-nodemcu-how-to-create-xbm.html 40 | // about how to create a XBM array 41 | #define WiFi_Logo_width 60 42 | #define WiFi_Logo_height 36 43 | const char WiFi_Logo_bits[] PROGMEM = { 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 46 | 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 47 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 48 | 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 49 | 0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 50 | 0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 51 | 0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00, 52 | 0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C, 53 | 0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00, 54 | 0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C, 55 | 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00, 56 | 0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 57 | 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 58 | 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C, 59 | 0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00, 60 | 0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F, 61 | 0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00, 62 | 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 63 | 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 64 | 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 65 | 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 | }; 69 | 70 | // defines the colors usable in the paletted 16 color frame buffer 71 | uint16_t palette[] = {ILI9341_BLACK, // 0 72 | ILI9341_WHITE, // 1 73 | ILI9341_NAVY, // 2 74 | ILI9341_DARKCYAN, // 3 75 | ILI9341_DARKGREEN, // 4 76 | ILI9341_MAROON, // 5 77 | ILI9341_PURPLE, // 6 78 | ILI9341_OLIVE, // 7 79 | ILI9341_LIGHTGREY, // 8 80 | ILI9341_DARKGREY, // 9 81 | ILI9341_BLUE, // 10 82 | ILI9341_GREEN, // 11 83 | ILI9341_CYAN, // 12 84 | ILI9341_RED, // 13 85 | ILI9341_MAGENTA, // 14 86 | ILI9341_YELLOW}; // 15 87 | 88 | 89 | 90 | int SCREEN_WIDTH = 240; 91 | int SCREEN_HEIGHT = 320; 92 | int BITS_PER_PIXEL = 4; // 2^4 = 16 colors 93 | 94 | // Initialize the driver 95 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 96 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 97 | 98 | 99 | // Used for fps measuring 100 | uint16_t counter = 0; 101 | long startMillis = millis(); 102 | uint16_t interval = 20; 103 | int color = 1; 104 | String fps = "0fps"; 105 | 106 | void setup() { 107 | Serial.begin(115200); 108 | 109 | // Turn on the background LED 110 | pinMode(TFT_LED, OUTPUT); 111 | digitalWrite(TFT_LED, HIGH); 112 | 113 | gfx.init(); 114 | gfx.fillBuffer(0); 115 | gfx.commit(); 116 | 117 | 118 | startMillis = millis(); 119 | } 120 | 121 | 122 | void loop() { 123 | 124 | gfx.fillBuffer(0); 125 | gfx.setColor(color); 126 | gfx.drawXbm(10, 40, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits); 127 | gfx.setColor(1); 128 | gfx.drawString(2, 2, fps); 129 | gfx.commit(); 130 | 131 | counter++; 132 | // only calculate the fps every iterations. 133 | if (counter % interval == 0) { 134 | color = (color + 1) % 15 + 1; 135 | long millisSinceUpdate = millis() - startMillis; 136 | fps = String(interval * 1000.0 / (millisSinceUpdate)) + "fps"; 137 | startMillis = millis(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /examples/EPaper/EPD_WaveShare_1_54/EPD_WaveShare_1_54.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "EPD_WaveShare_154.h" 33 | #include "MiniGrafx.h" 34 | #include "DisplayDriver.h" 35 | 36 | 37 | #define MINI_BLACK 0 38 | #define MINI_WHITE 1 39 | 40 | /* 41 | Connect the following pins: 42 | Display NodeMCU 43 | BUSY D1 44 | RST D2 45 | DC D8 46 | CS D3 47 | CLK D5 48 | DIN D7 49 | GND GND 50 | 3.3V 3V3 51 | */ 52 | /*#define CS D3 53 | #define RST D2 54 | #define DC D8 55 | #define BUSY D1*/ 56 | 57 | /*#if defined(ESP8266) 58 | #define CS 15 // D8 59 | #define RST 2 // D4 60 | #define DC 5 // D1 61 | #define BUSY 4 // D2 62 | #elif defined(ESP32)*/ 63 | #define CS 4 // D8 64 | #define RST 14 // D4 65 | #define DC 12 // D1 66 | #define BUSY 27 // D2 67 | //#endif 68 | 69 | #define BITS_PER_PIXEL 1 70 | 71 | 72 | uint16_t palette[] = {0, 1}; 73 | boolean isFastRefreshEnabled = false; 74 | 75 | EPD_WaveShare154 epd(CS, RST, DC, BUSY); 76 | MiniGrafx screenGfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette, EPD_WIDTH, EPD_HEIGHT); 77 | MiniGrafx dialogGfx = MiniGrafx(&epd, BITS_PER_PIXEL, palette, 96, 96); 78 | 79 | uint8_t counter = 0; 80 | uint8_t rotation = 0; 81 | uint8_t mode = 0; 82 | boolean modeChanged = true; 83 | 84 | #define MODES 3 85 | 86 | void testFullScreenCommit() { 87 | 88 | screenGfx.setRotation(rotation); 89 | screenGfx.fillBuffer(MINI_WHITE); 90 | screenGfx.setColor(MINI_BLACK); 91 | screenGfx.setFont(ArialMT_Plain_10); 92 | screenGfx.drawLine(0, 0, screenGfx.getWidth(), screenGfx.getHeight()); 93 | screenGfx.drawRect(0, 0, screenGfx.getWidth() - 1, screenGfx.getHeight() - 1); 94 | screenGfx.drawString(0, 0, "Hello World.\nMillis: " + String(millis()) + "\nRotation: " + String(rotation)); 95 | screenGfx.commit(); 96 | rotation = (rotation + 1) % 4; 97 | } 98 | 99 | void testPictureInPicture() { 100 | if (modeChanged) { 101 | screenGfx.commit(); 102 | screenGfx.commit(); 103 | } 104 | dialogGfx.setFastRefresh(true); 105 | dialogGfx.setRotation(rotation); 106 | dialogGfx.fillBuffer(MINI_BLACK); 107 | dialogGfx.setColor(MINI_WHITE); 108 | dialogGfx.setFont(ArialMT_Plain_10); 109 | dialogGfx.drawLine(0, 0, dialogGfx.getWidth(), dialogGfx.getHeight()); 110 | dialogGfx.drawString(0, 0, "Hello World. Rotation:\n" + String(rotation)); 111 | dialogGfx.commit(16, 16); 112 | rotation = (rotation + 1) % 4; 113 | } 114 | 115 | void testWindowedCommit() { 116 | if (modeChanged) { 117 | screenGfx.setFastRefresh(false); 118 | screenGfx.commit(); 119 | screenGfx.commit(); 120 | } 121 | screenGfx.fillBuffer(MINI_BLACK); 122 | screenGfx.setColor(MINI_WHITE); 123 | screenGfx.setFastRefresh(true); 124 | screenGfx.setRotation(0); 125 | screenGfx.setFont(ArialMT_Plain_24); 126 | screenGfx.drawString(18, 18, String(millis())); 127 | screenGfx.commit(16, 16, 80, 32, 16, 16); 128 | } 129 | 130 | void setup() { 131 | Serial.begin(115200); 132 | 133 | screenGfx.init(); 134 | screenGfx.fillBuffer(MINI_WHITE); 135 | screenGfx.setColor(MINI_BLACK); 136 | // the device thas two screen buffers. For partial update 137 | // make sure that both have the same content-> clear both. 138 | screenGfx.commit(); 139 | screenGfx.commit(); 140 | 141 | dialogGfx.init(); 142 | 143 | epd.setTemperature(0); 144 | 145 | } 146 | 147 | #define REPETITIONS 10 148 | #define MODES 4 149 | 150 | void loop() { 151 | if (Serial.available() > 0) { 152 | String temp = Serial.readString(); 153 | Serial.println("Temperature: " + temp); 154 | epd.setTemperature(temp.toFloat()); 155 | } 156 | 157 | uint64_t startTime = millis(); 158 | switch(mode) { 159 | case 0: 160 | Serial.println("Testing Fullscreen commit. Fast Refresh"); 161 | screenGfx.setFastRefresh(true); 162 | testFullScreenCommit(); 163 | break; 164 | case 1: 165 | Serial.println("Testing Fullscreen commit. Full Refresh"); 166 | screenGfx.setFastRefresh(false); 167 | testFullScreenCommit(); 168 | break; 169 | case 2: 170 | Serial.println("Testing Picture in Picture/ Partial update"); 171 | dialogGfx.setFastRefresh(true); 172 | testPictureInPicture(); 173 | break; 174 | case 3: 175 | Serial.println("Testing windowed commit"); 176 | testWindowedCommit(); 177 | } 178 | Serial.printf("Cycle took: %dms\n", millis() - startTime ); 179 | 180 | counter++; 181 | modeChanged = false; 182 | if (counter % REPETITIONS == 0) { 183 | modeChanged = true; 184 | mode = (mode + 1) % MODES; 185 | } 186 | //delay(4000); 187 | 188 | } 189 | -------------------------------------------------------------------------------- /src/EPaperPervasive.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Pervasive Displays, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at: 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, 10 | // software distributed under the License is distributed on an 11 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | // express or implied. See the License for the specific language 13 | // governing permissions and limitations under the License. 14 | 15 | #if !defined(EPD2_H) 16 | #define EPD2_H 1 17 | 18 | #include 19 | #include 20 | #include "DisplayDriver.h" 21 | 22 | //#if defined(__MSP430_CPU__) 23 | //#define PROGMEM 24 | //#else 25 | //#include 26 | //#endif 27 | 28 | // if more SRAM available (8 kBytes) 29 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 30 | #define EPD_ENABLE_EXTRA_SRAM 1 31 | #endif 32 | 33 | typedef enum { 34 | EPD_1_44, // 128 x 96 35 | EPD_2_0, // 200 x 96 36 | EPD_2_7 // 264 x 176 37 | } EPD_size; 38 | 39 | typedef enum { // Image pixel -> Display pixel 40 | EPD_inverse, // B -> W, W -> B (New Image) 41 | EPD_normal // B -> B, W -> W (New Image) 42 | } EPD_stage; 43 | 44 | typedef enum { // error codes 45 | EPD_OK, 46 | EPD_UNSUPPORTED_COG, 47 | EPD_PANEL_BROKEN, 48 | EPD_DC_FAILED 49 | } EPD_error; 50 | 51 | // values for border byte 52 | const uint8_t EPD_BORDER_BYTE_BLACK = 0xff; 53 | const uint8_t EPD_BORDER_BYTE_WHITE = 0xaa; 54 | const uint8_t EPD_BORDER_BYTE_NULL = 0x00; 55 | 56 | typedef void EPD_reader(void *buffer, uint32_t address, uint16_t length); 57 | 58 | class EPD_Class : public DisplayDriver { 59 | public: 60 | // power up and power down the EPD panel 61 | void init(); 62 | void end(); 63 | 64 | void setFactor(int temperature = 25); 65 | 66 | bool operator!() const { 67 | return EPD_OK != this->status; 68 | } 69 | 70 | EPD_error error() const { 71 | return this->status; 72 | } 73 | 74 | // clear display (anything -> white) 75 | void clear() { 76 | this->frame_fixed_13(0xff, EPD_inverse); 77 | this->frame_stage2(); 78 | this->frame_fixed_13(0xaa, EPD_normal); 79 | } 80 | 81 | // output an image (PROGMEM data) 82 | void image(const uint8_t *image_data) { 83 | this->frame_data_13(image_data, EPD_inverse); 84 | this->frame_stage2(); 85 | this->frame_data_13(image_data, EPD_normal); 86 | } 87 | 88 | // change from old image to new image (SRAM version) 89 | void image_sram(const uint8_t *image_data) { 90 | this->frame_data_13(image_data, EPD_inverse, false); 91 | this->frame_stage2(); 92 | this->frame_data_13(image_data, EPD_normal, false); 93 | } 94 | 95 | void writeBuffer(BufferInfo *bufferInfo) { 96 | this->writeBuffer(bufferInfo->buffer, 1, bufferInfo->palette, EPD_inverse); 97 | this->frame_stage2(); 98 | this->writeBuffer(bufferInfo->buffer, 1, bufferInfo->palette, EPD_normal); 99 | 100 | } 101 | 102 | void writeBuffer(uint8_t *buffer, uint8_t bitsPerPixel, uint16_t *palette, EPD_stage stage); 103 | 104 | void display(uint8_t *buffer) { 105 | //this->frame_cb_13(buffer, EPD_inverse); 106 | //this->frame_stage2(); 107 | this->frame_cb_13(buffer, EPD_normal); 108 | //this->frame_data_13(buffer, EPD_inverse, false); 109 | //this->frame_stage2(); 110 | //this->frame_data_13(buffer, EPD_normal, false); 111 | } 112 | 113 | 114 | 115 | // Low level API calls 116 | // =================== 117 | 118 | // single frame refresh 119 | void frame_fixed_timed(uint8_t fixed_value, long stage_time); 120 | 121 | // the B/W toggle stage 122 | void frame_stage2(); 123 | 124 | // stages 1/3 functions 125 | void frame_fixed_13(uint8_t fixed_value, EPD_stage stage); 126 | void frame_data_13(const uint8_t *image_data, EPD_stage stage, bool read_progmem = true); 127 | void frame_cb_13(uint32_t address, EPD_reader *reader, EPD_stage stage); 128 | void frame_cb_13(uint8_t *buffer, EPD_stage stage); 129 | void setFastRefresh(boolean isFastRefreshEnabled); 130 | 131 | // single line display - very low-level 132 | // also has to handle AVR progmem 133 | void line(uint16_t line, const uint8_t *data, uint8_t fixed_value, 134 | bool read_progmem, EPD_stage stage = EPD_normal, uint8_t border_byte = EPD_BORDER_BYTE_NULL, bool set_voltage_limit = false); 135 | 136 | // inline static void attachInterrupt(); 137 | // inline static void detachInterrupt(); 138 | 139 | EPD_Class(EPD_size size, 140 | uint16_t width, 141 | uint16_t height, 142 | int panel_on_pin, 143 | int border_pin, 144 | int discharge_pin, 145 | int reset_pin, 146 | int busy_pin, 147 | int chip_select_pin); 148 | 149 | private: 150 | /*int EPD_Pin_PANEL_ON = 0; 151 | int EPD_Pin_BORDER = 0; 152 | int EPD_Pin_DISCHARGE = 0; 153 | int EPD_Pin_RESET = 0; 154 | int EPD_Pin_BUSY = 0; 155 | int EPD_Pin_EPD_CS = 0;*/ 156 | int EPD_Pin_PANEL_ON; 157 | int EPD_Pin_BORDER; 158 | int EPD_Pin_DISCHARGE; 159 | int EPD_Pin_RESET; 160 | int EPD_Pin_BUSY; 161 | int EPD_Pin_EPD_CS; 162 | 163 | EPD_size size; 164 | uint16_t lines_per_display; 165 | uint16_t dots_per_line; 166 | uint16_t bytes_per_line; 167 | uint16_t bytes_per_scan; 168 | 169 | uint8_t voltage_level; 170 | 171 | EPD_error status; 172 | 173 | const uint8_t *channel_select; 174 | uint16_t channel_select_length; 175 | 176 | typedef struct { 177 | uint16_t stage1_repeat; 178 | uint16_t stage1_step; 179 | uint16_t stage1_block; 180 | uint16_t stage2_repeat; 181 | uint16_t stage2_t1; 182 | uint16_t stage2_t2; 183 | uint16_t stage3_repeat; 184 | uint16_t stage3_step; 185 | uint16_t stage3_block; 186 | } compensation_type; 187 | 188 | const compensation_type *compensation; 189 | uint16_t temperature_offset; 190 | 191 | EPD_Class(const EPD_Class &f); // prevent copy 192 | 193 | void power_off(); 194 | void nothing_frame(); 195 | void dummy_line(); 196 | void border_dummy_line(); 197 | 198 | 199 | }; 200 | 201 | #endif 202 | -------------------------------------------------------------------------------- /src/EPD_WaveShare_43.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #include "EPD_WaveShare_43.h" 29 | 30 | 31 | EPD_WaveShare_43::EPD_WaveShare_43(Stream *serial) : DisplayDriver(800, 600) { 32 | this->serial = serial; 33 | } 34 | 35 | void EPD_WaveShare_43::init(void) { 36 | //stream->begin(115200); 37 | //pinMode(wake_up, HIGH); 38 | //pinMode(reset, HIGH); 39 | setMemory(MEM_NAND); 40 | } 41 | 42 | void EPD_WaveShare_43::setFastRefresh(boolean isFastRefreshEnabled) { 43 | // Not enabled at the moment 44 | } 45 | 46 | void EPD_WaveShare_43::setRotation(uint8_t r) { 47 | 48 | } 49 | 50 | void EPD_WaveShare_43::writeBuffer(BufferInfo *bufferInfo) { 51 | uint8_t color = 0; 52 | Serial.println("Clearing"); 53 | clear(); 54 | Serial.println("Writing"); 55 | for (int y = 0; y < 400; y++) { 56 | for (int x = 0; x < 400; x++) { 57 | color = getPixel(bufferInfo->buffer, x, y); 58 | if (color == 0) { 59 | drawPixel(x,y); 60 | } 61 | } 62 | if (y % 10 == 0) { 63 | yield(); 64 | } 65 | } 66 | update(); 67 | } 68 | 69 | void EPD_WaveShare_43::putchars(const unsigned char * ptr, int n) 70 | { 71 | int i, x; 72 | 73 | for(i = 0; i < n; i++) 74 | { 75 | x = ptr[i]; 76 | serial->write(x); 77 | } 78 | } 79 | 80 | unsigned char EPD_WaveShare_43::verify(const void * ptr, int n) 81 | { 82 | int i; 83 | unsigned char * p = (unsigned char *)ptr; 84 | unsigned char result; 85 | 86 | for(i = 0, result = 0; i < n; i++) 87 | { 88 | result ^= p[i]; 89 | } 90 | 91 | return result; 92 | } 93 | 94 | void EPD_WaveShare_43::setColor(unsigned char color, unsigned char bkcolor) 95 | { 96 | _cmd_buff[0] = FRAME_B; 97 | 98 | _cmd_buff[1] = 0x00; 99 | _cmd_buff[2] = 0x0B; 100 | 101 | _cmd_buff[3] = CMD_SET_COLOR; 102 | 103 | _cmd_buff[4] = color; 104 | _cmd_buff[5] = bkcolor; 105 | 106 | _cmd_buff[6] = FRAME_E0; 107 | _cmd_buff[7] = FRAME_E1; 108 | _cmd_buff[8] = FRAME_E2; 109 | _cmd_buff[9] = FRAME_E3; 110 | _cmd_buff[10] = verify(_cmd_buff, 10); 111 | 112 | putchars(_cmd_buff, 11); 113 | } 114 | 115 | void EPD_WaveShare_43::drawPixel(int x0, int y0) 116 | { 117 | _cmd_buff[0] = FRAME_B; 118 | 119 | _cmd_buff[1] = 0x00; 120 | _cmd_buff[2] = 0x0D; 121 | 122 | _cmd_buff[3] = CMD_DRAW_PIXEL; 123 | 124 | _cmd_buff[4] = (x0 >> 8) & 0xFF; 125 | _cmd_buff[5] = x0 & 0xFF; 126 | _cmd_buff[6] = (y0 >> 8) & 0xFF; 127 | _cmd_buff[7] = y0 & 0xFF; 128 | 129 | _cmd_buff[8] = FRAME_E0; 130 | _cmd_buff[9] = FRAME_E1; 131 | _cmd_buff[10] = FRAME_E2; 132 | _cmd_buff[11] = FRAME_E3; 133 | _cmd_buff[12] = verify(_cmd_buff, 12); 134 | 135 | putchars(_cmd_buff, 13); 136 | } 137 | 138 | void EPD_WaveShare_43::setMemory(unsigned char mode) 139 | { 140 | _cmd_buff[0] = FRAME_B; 141 | 142 | _cmd_buff[1] = 0x00; 143 | _cmd_buff[2] = 0x0A; 144 | 145 | _cmd_buff[3] = CMD_MEMORYMODE; 146 | 147 | _cmd_buff[4] = mode; 148 | 149 | _cmd_buff[5] = FRAME_E0; 150 | _cmd_buff[6] = FRAME_E1; 151 | _cmd_buff[7] = FRAME_E2; 152 | _cmd_buff[8] = FRAME_E3; 153 | _cmd_buff[9] = verify(_cmd_buff, 9); 154 | 155 | putchars(_cmd_buff, 10); 156 | } 157 | 158 | void EPD_WaveShare_43::clear(void) 159 | { 160 | _cmd_buff[0] = FRAME_B; 161 | 162 | _cmd_buff[1] = 0x00; 163 | _cmd_buff[2] = 0x09; 164 | 165 | _cmd_buff[3] = CMD_CLEAR; 166 | 167 | _cmd_buff[4] = FRAME_E0; 168 | _cmd_buff[5] = FRAME_E1; 169 | _cmd_buff[6] = FRAME_E2; 170 | _cmd_buff[7] = FRAME_E3; 171 | _cmd_buff[8] = verify(_cmd_buff, 8); 172 | 173 | putchars(_cmd_buff, 9); 174 | } 175 | 176 | void EPD_WaveShare_43::update(void) 177 | { 178 | memcpy(_cmd_buff, _cmd_update, 8); 179 | _cmd_buff[8] = verify(_cmd_buff, 8); 180 | 181 | putchars(_cmd_buff, 9); 182 | } 183 | 184 | uint16_t EPD_WaveShare_43::getPixel(uint8_t *buffer, uint16_t x, uint16_t y) { 185 | if (x >= width() || y >= height() || x < 0 || y < 0) return 0; 186 | uint8_t bitShift = 3; 187 | uint8_t bitsPerPixel = 1; 188 | uint8_t bitMask = 1; 189 | uint8_t pixelsPerByte = 8; 190 | uint32_t bufferSize = width() * height() / pixelsPerByte; 191 | // bitsPerPixel: 8, pixPerByte: 1, 0 1 = 2^0 192 | // bitsPerPixel: 4, pixPerByte: 2, 1 2 = 2^1 193 | // bitsPerPixel 2, pixPerByte: 4, 2 4 = 2^2 194 | // bitsPerPixel 1, pixPerByte: 8, 3 8 = 2^3 195 | uint16_t pos = (y * width() + x) >> bitShift; 196 | if (pos > bufferSize) { 197 | return 0; 198 | } 199 | 200 | uint8_t shift = (x & (pixelsPerByte - 1)) * bitsPerPixel; 201 | 202 | return (buffer[pos] >> shift) & bitMask; 203 | } 204 | 205 | void EPD_WaveShare_43::setBaud(long baud) 206 | { 207 | _cmd_buff[0] = FRAME_B; 208 | 209 | _cmd_buff[1] = 0x00; 210 | _cmd_buff[2] = 0x0D; 211 | 212 | _cmd_buff[3] = CMD_SET_BAUD; 213 | 214 | _cmd_buff[4] = (baud >> 24) & 0xFF; 215 | _cmd_buff[5] = (baud >> 16) & 0xFF; 216 | _cmd_buff[6] = (baud >> 8) & 0xFF; 217 | _cmd_buff[7] = baud & 0xFF; 218 | 219 | _cmd_buff[8] = FRAME_E0; 220 | _cmd_buff[9] = FRAME_E1; 221 | _cmd_buff[10] = FRAME_E2; 222 | _cmd_buff[11] = FRAME_E3; 223 | _cmd_buff[12] = verify(_cmd_buff, 12); 224 | 225 | putchars(_cmd_buff, 13); 226 | 227 | delay(10); 228 | 229 | } 230 | -------------------------------------------------------------------------------- /src/EPD_WaveShare.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #if !defined(EPDWS154_H) 29 | #define EPDWS154_H 1 30 | 31 | #include 32 | #include 33 | #include "DisplayDriver.h" 34 | 35 | 36 | #define EPD_BUSY_LEVEL 0 37 | 38 | //#define EPD1X54 1 39 | #define EPD2X9 1 40 | /*#ifdef EPD2X9 41 | #define xDot 128 42 | #define yDot 296 43 | #define DELAYTIME 1500 44 | // static const unsigned char GDVol[] = {0x03,0xea}; // Gate voltage +15V/-15V 45 | #elif EPD02X13 46 | #define xDot 128 47 | #define yDot 250 48 | #define DELAYTIME 4000 49 | // static const unsigned char GDVol[] = {0x03,0xea}; // Gate voltage +15V/-15V 50 | #elif EPD1X54 51 | #define xDot 200 52 | #define yDot 200 53 | #define DELAYTIME 1500 54 | // static const unsigned char GDVol[] = {0x03,0x00}; // Gate voltage +15V/-15V 55 | #endif*/ 56 | 57 | //static const unsigned char GDOControl[]={0x01,(yDot-1)%256,(yDot-1)/256,0x00}; //for 1.54inch 58 | static const unsigned char softstart[]={0x0c,0xd7,0xd6,0x9d}; 59 | // static const unsigned char Rambypass[] = {0x21,0x8f}; // Display update 60 | // static const unsigned char MAsequency[] = {0x22,0xf0}; // clock 61 | // static const unsigned char SDVol[] = {0x04,0x0a}; // Source voltage +15V/-15V 62 | static const unsigned char VCOMVol[] = {0x2c,0xa8}; // VCOM 7c 63 | // static const unsigned char BOOSTERFB[] = {0xf0,0x1f}; // Source voltage +15V/-15V 64 | static const unsigned char DummyLine[] = {0x3a,0x1a}; // 4 dummy line per gate 65 | static const unsigned char Gatetime[] = {0x3b,0x08}; // 2us per line 66 | // static const unsigned char BorderWavefrom[] = {0x3c,0x33}; // Border 67 | static const unsigned char RamDataEntryMode[] = {0x11,0x01}; // Ram data entry mode 68 | 69 | #ifdef EPD02X13 70 | static const unsigned char LUTDefault_full[]={ 71 | 0x32, // command 72 | 0x22,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x01,0x00,0x00,0x00,0x00, 73 | }; 74 | static const unsigned char LUTDefault_part[]={ 75 | 0x32, // command 76 | 0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 77 | }; 78 | #else 79 | //Write LUT register 80 | static const unsigned char LUTDefault_part[31] = { 81 | 0x32, // command 82 | 0x10,0x18,0x18,0x08,0x18,0x18,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x14,0x44,0x12,0x00,0x00,0x00,0x00,0x00,0x00 83 | }; 84 | static const unsigned char LUTDefault_full[31] = { 85 | 0x32, // command 86 | 0x02,0x02,0x01,0x11,0x12,0x12,0x22,0x22,0x66,0x69,0x69,0x59,0x58,0x99,0x99,0x88,0x00,0x00,0x00,0x00,0xF8,0xB4,0x13,0x51,0x35,0x51,0x51,0x19,0x01,0x00 87 | }; 88 | #endif 89 | 90 | enum EPD_TYPE { 91 | EPD1_54, 92 | EPD02_13, 93 | EPD2_9 94 | }; 95 | 96 | class EPD_WaveShare : public DisplayDriver { 97 | 98 | public: 99 | EPD_WaveShare(EPD_TYPE epdType, uint8_t csPin, uint8_t rstPin, uint8_t dcPin, uint8_t busyPin); 100 | 101 | void setRotation(uint8_t r); 102 | void init(); 103 | 104 | void writeBuffer(BufferInfo *bufferInfo); 105 | 106 | void EPD_init_Part(void); 107 | void Dis_Clear_full(void); 108 | 109 | static int getWidth(EPD_TYPE epdType); 110 | static int getHeight(EPD_TYPE epdType); 111 | 112 | private: 113 | uint8_t csPin; 114 | uint8_t rstPin; 115 | uint8_t dcPin; 116 | uint8_t busyPin; 117 | uint8_t rotation; 118 | uint16_t delaytime; 119 | uint16_t xDot; 120 | uint16_t yDot; 121 | uint16_t bufferWidth; 122 | uint16_t bufferHeight; 123 | unsigned char GDOControl[4]; 124 | 125 | unsigned char ReadBusy(void); 126 | uint8_t Reverse_bits(uint8_t num); 127 | uint8_t getPixel(uint8_t *buffer, uint16_t x, uint16_t y); 128 | void EPD_WriteCMD(unsigned char command); 129 | void EPD_WriteCMD_p1(unsigned char command,unsigned char para); 130 | void EPD_POWERON(void); 131 | void EPD_Write(const unsigned char *value, unsigned char datalen); 132 | void EPD_WriteDispRam(unsigned char XSize,unsigned int YSize,unsigned char *Dispbuff); 133 | void EPD_WriteDispRamMono(unsigned char XSize,unsigned int YSize,unsigned char dispdata); 134 | void EPD_SetRamArea(unsigned char Xstart,unsigned char Xend,unsigned char Ystart,unsigned char Ystart1,unsigned char Yend,unsigned char Yend1); 135 | void EPD_SetRamPointer(unsigned char addrX,unsigned char addrY,unsigned char addrY1); 136 | void EPD_part_display(unsigned char RAM_XST,unsigned char RAM_XEND,unsigned char RAM_YST,unsigned char RAM_YST1,unsigned char RAM_YEND,unsigned char RAM_YEND1); 137 | void EPD_Init(void); 138 | void EPD_Update(void); 139 | void EPD_Update_Part(void); 140 | void EPD_WirteLUT(unsigned char *LUTvalue,unsigned char Size); 141 | void EPD_init_Full(void); 142 | void EPD_Dis_Full(unsigned char *DisBuffer,unsigned char Label); 143 | void EPD_Dis_Part(unsigned char xStart,unsigned char xEnd,unsigned long yStart,unsigned long yEnd,unsigned char *DisBuffer,unsigned char Label); 144 | void Dis_Char(char acsii,char size,char mode,char next,unsigned char *buffer); 145 | void setFastRefresh(boolean isFastRefreshEnabled); 146 | 147 | void driver_delay_xms(unsigned long xms); 148 | void SPI_Write(unsigned char value); 149 | 150 | 151 | }; 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /src/MiniGrafx.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #include 29 | #if defined(ESP32) 30 | #include 31 | #endif 32 | #include "ILI9341_SPI.h" 33 | #include "MiniGrafxFonts.h" 34 | 35 | 36 | 37 | #ifndef _MINI_GRAFXH_ 38 | #define _MINI_GRAFXH_ 39 | 40 | #ifndef DEBUG_MINI_GRAFX 41 | #define DEBUG_MINI_GRAFX(...) 42 | #endif 43 | 44 | #ifndef _swap_int16_t 45 | #define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } 46 | #endif 47 | 48 | // Header Values 49 | #define JUMPTABLE_BYTES 4 50 | 51 | #define JUMPTABLE_LSB 1 52 | #define JUMPTABLE_SIZE 2 53 | #define JUMPTABLE_WIDTH 3 54 | #define JUMPTABLE_START 4 55 | 56 | #define WIDTH_POS 0 57 | #define HEIGHT_POS 1 58 | #define FIRST_CHAR_POS 2 59 | #define CHAR_NUM_POS 3 60 | 61 | #define CUSTOM_BITMAP_DATA_START 6 62 | 63 | enum TEXT_ALIGNMENT { 64 | TEXT_ALIGN_LEFT = 0, 65 | TEXT_ALIGN_RIGHT = 1, 66 | TEXT_ALIGN_CENTER = 2, 67 | TEXT_ALIGN_CENTER_BOTH = 3 68 | }; 69 | 70 | enum BUFFER_COLOR_DEPTH { 71 | BIT_1 = 1, 72 | BIT_2 = 2, 73 | BIT_4 = 4, 74 | BIT_8 = 8, 75 | BIT_16 = 16 76 | }; 77 | 78 | class MiniGrafx { 79 | 80 | public: 81 | MiniGrafx(DisplayDriver *driver, uint8_t bitsPerPixel, uint16_t *palette); 82 | MiniGrafx(DisplayDriver *driver, uint8_t bitsPerPixel, uint16_t *palette, uint16_t width, uint16_t height); 83 | void init(); 84 | void changeBitDepth(uint8_t bitsPerPixel, uint16_t *palette); 85 | uint16_t getHeight(); 86 | uint16_t getWidth(); 87 | void setRotation(uint8_t r); 88 | void setMirroredHorizontally(boolean isMirroredHorizontally); 89 | void setMirroredVertically(boolean isMirroredVertically); 90 | void setPixel(uint16_t x, uint16_t y); 91 | uint16_t getPixel(uint16_t x, uint16_t y); 92 | void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1); 93 | void setColor(uint16_t color); 94 | void setTransparentColor(uint16_t transparentColor); 95 | void drawCircle(int16_t x0, int16_t y0, uint16_t radius); 96 | void drawRect(int16_t x, int16_t y, int16_t width, int16_t height); 97 | void fillRect(int16_t xMove, int16_t yMove, int16_t width, int16_t height); 98 | void fillCircle(int16_t x0, int16_t y0, int16_t radius); 99 | void drawHorizontalLine(int16_t x, int16_t y, int16_t length); 100 | void drawVerticalLine(int16_t x, int16_t y, int16_t length); 101 | uint16_t drawString(int16_t xMove, int16_t yMove, String strUser); 102 | 103 | // Draws a String with a maximum width at the given location. 104 | // If the given String is wider than the specified width 105 | // The text will be wrapped to the next line at a space or dash 106 | void drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, String text); 107 | 108 | void drawStringInternal(int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth); 109 | void fillBottomFlatTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3); 110 | void fillTopFlatTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3); 111 | void fillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3); 112 | void drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3); 113 | uint16_t getStringWidth(const char* text, uint16_t length); 114 | void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const char *xbm); 115 | void drawBmpFromFile(String filename, uint8_t x, uint16_t y); 116 | void drawBmpFromPgm(const char *xbm, uint8_t x, uint16_t y); 117 | void drawPalettedBitmapFromPgm(uint16_t x, uint16_t y, const char *palBmp); 118 | void drawPalettedBitmapFromFile(uint16_t x, uint16_t y, String fileName); 119 | 120 | uint16_t read16(File &f); 121 | uint32_t read32(File &f); 122 | void setFont(const char *fontData); 123 | void setFontFile(String fontFile); 124 | void setTextAlignment(TEXT_ALIGNMENT textAlignment); 125 | void inline drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const char *data, uint16_t offset, uint16_t bytesInData); 126 | void commit(); 127 | void commit(uint16_t xPos, uint16_t yPos); 128 | void commit(uint16_t srcXPos, uint16_t srcYPos, uint16_t srcWidth, uint16_t srcHeight, uint16_t targetXPos, uint16_t targetYPos); 129 | 130 | void clear(); 131 | void freeBuffer(); 132 | void setFastRefresh(boolean isFastRefreshEnabled); 133 | void fillBuffer(uint8_t pal); 134 | static char* utf8ascii(String s); 135 | static byte utf8ascii(byte ascii); 136 | void colorSwap(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color1, uint16_t color2); 137 | 138 | private: 139 | void initializeBuffer(); 140 | DisplayDriver *driver; 141 | File fontFile; 142 | uint16_t width, height; 143 | uint16_t initialWidth, initialHeight; 144 | uint16_t color; 145 | uint8_t rotation; 146 | int16_t transparentColor = -1; 147 | uint8_t bitsPerPixel = 4; 148 | uint8_t bitShift = 1; 149 | uint16_t bufferSize = 0; 150 | uint16_t* palette = 0; 151 | uint8_t *buffer = 0; 152 | uint16_t bitMask; 153 | uint8_t pixelsPerByte; 154 | boolean isPgmFont = true; 155 | boolean isMirroredHorizontally = false; 156 | boolean isMirroredVertically = false; 157 | const char *fontData = ArialMT_Plain_16; 158 | TEXT_ALIGNMENT textAlignment; 159 | uint8_t readFontData(const char * start, uint32_t offset); 160 | 161 | }; 162 | 163 | #endif 164 | -------------------------------------------------------------------------------- /examples/ILI9341/TouchPaint/TouchPaint.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include 33 | #include "MiniGrafx.h" // General graphic library 34 | #include "ILI9341_SPI.h" // Hardware-specific library 35 | #include 36 | 37 | #define TFT_DC D2 38 | #define TFT_CS D1 39 | #define TFT_LED D8 40 | #define TOUCH_CS D3 41 | #define TOUCH_IRQ D4 42 | 43 | // defines the colors usable in the paletted 16 color frame buffer 44 | uint16_t palette[] = {ILI9341_BLACK, // 0 45 | ILI9341_WHITE, // 1 46 | ILI9341_NAVY, // 2 47 | ILI9341_DARKCYAN, // 3 48 | ILI9341_DARKGREEN, // 4 49 | ILI9341_MAROON, // 5 50 | ILI9341_PURPLE, // 6 51 | ILI9341_OLIVE, // 7 52 | ILI9341_LIGHTGREY, // 8 53 | ILI9341_DARKGREY, // 9 54 | ILI9341_BLUE, // 10 55 | ILI9341_GREEN, // 11 56 | ILI9341_CYAN, // 12 57 | ILI9341_RED, // 13 58 | ILI9341_MAGENTA, // 14 59 | ILI9341_YELLOW}; // 15 60 | 61 | 62 | 63 | int SCREEN_WIDTH = 240; 64 | int SCREEN_HEIGHT = 320; 65 | int BITS_PER_PIXEL = 4; // 2^4 = 16 colors 66 | 67 | // Initialize the driver 68 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 69 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 70 | 71 | XPT2046_Touchscreen ts(TOUCH_CS, TOUCH_IRQ); 72 | 73 | bool loadTouchCalibration(); 74 | bool saveTouchCalibration(); 75 | 76 | TS_Point p1, p2; 77 | int state = 0; 78 | int lastStateChange = 0; 79 | 80 | float dx = 0; 81 | float dy = 0; 82 | int ax = 0; 83 | int ay = 0; 84 | int color = 1; 85 | 86 | void setup() { 87 | // Turn on the background LED 88 | pinMode(TFT_LED, OUTPUT); 89 | digitalWrite(TFT_LED, HIGH); 90 | 91 | ts.begin(); 92 | 93 | gfx.init(); 94 | gfx.fillBuffer(0); 95 | gfx.commit(); 96 | bool isCalibrationAvailable = loadTouchCalibration(); 97 | if (isCalibrationAvailable) { 98 | state = 2; 99 | } 100 | } 101 | 102 | void loop() { 103 | 104 | TS_Point p = ts.getPoint(); 105 | 106 | if (state == 0) { 107 | gfx.fillBuffer(0); 108 | gfx.setColor(1); 109 | gfx.setTextAlignment(TEXT_ALIGN_CENTER); 110 | gfx.drawString(120, 160, "Please Touch Circle"); 111 | gfx.fillCircle(5, 5, 5); 112 | if (ts.touched()) { 113 | p1 = p; 114 | state++; 115 | lastStateChange = millis(); 116 | gfx.fillBuffer(0); 117 | } 118 | 119 | } else if (state == 1) { 120 | gfx.fillBuffer(0); 121 | gfx.setColor(1); 122 | gfx.setTextAlignment(TEXT_ALIGN_CENTER); 123 | gfx.drawString(120, 160, "Please Touch Circle"); 124 | gfx.drawCircle(235, 315, 5); 125 | if (ts.touched() && (millis() - lastStateChange > 1000)) { 126 | 127 | p2 = p; 128 | state++; 129 | lastStateChange = millis(); 130 | dx = 240.0 / abs(p1.y - p2.y); 131 | dy = 320.0 / abs(p1.x - p2.x); 132 | ax = p1.y < p2.y ? p1.y : p2.y; 133 | ay = p1.x < p2.x ? p1.x : p2.x; 134 | gfx.fillBuffer(0); 135 | saveTouchCalibration(); 136 | } 137 | 138 | } else { 139 | for (int i = 0; i < 16; i++) { 140 | gfx.setColor(i); 141 | gfx.fillRect(i* 15, 0, 20, 20); 142 | } 143 | if (ts.touched() && (millis() - lastStateChange > 1000)) { 144 | 145 | int x = (p.y - ax) * dx; 146 | int y = 320 - (p.x - ay) * dy; 147 | if (y < 15) { 148 | color = x / 15; 149 | if (color == 0) { 150 | gfx.fillBuffer(0); 151 | color = 1; 152 | } 153 | } 154 | gfx.setColor(color); 155 | gfx.fillCircle(x, y, 5); 156 | 157 | } 158 | } 159 | 160 | gfx.commit(); 161 | } 162 | 163 | bool loadTouchCalibration() { 164 | 165 | // always use this to "mount" the filesystem 166 | bool result = SPIFFS.begin(); 167 | Serial.println("SPIFFS opened: " + result); 168 | 169 | // this opens the file "f.txt" in read-mode 170 | File f = SPIFFS.open("/calibration.txt", "r"); 171 | 172 | if (!f) { 173 | return false; 174 | } else { 175 | 176 | //Lets read line by line from the file 177 | String dxStr = f.readStringUntil('\n'); 178 | String dyStr = f.readStringUntil('\n'); 179 | String axStr = f.readStringUntil('\n'); 180 | String ayStr = f.readStringUntil('\n'); 181 | 182 | dx = dxStr.toFloat(); 183 | dy = dyStr.toFloat(); 184 | ax = axStr.toInt(); 185 | ay = ayStr.toInt(); 186 | 187 | } 188 | f.close(); 189 | } 190 | 191 | bool saveTouchCalibration() { 192 | 193 | 194 | // always use this to "mount" the filesystem 195 | bool result = SPIFFS.begin(); 196 | 197 | // open the file in write mode 198 | File f = SPIFFS.open("/calibration.txt", "w"); 199 | if (!f) { 200 | Serial.println("file creation failed"); 201 | } 202 | // now write two lines in key/value style with end-of-line characters 203 | f.println(dx); 204 | f.println(dy); 205 | f.println(ax); 206 | f.println(ay); 207 | 208 | f.close(); 209 | } 210 | -------------------------------------------------------------------------------- /examples/ILI9341/RotatingCube/RotatingCube.ino: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2017 by Daniel Eichhorn 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: I am spending a lot of my free time in developing Software and Hardware 21 | for these projects. Please consider supporting me by 22 | a) Buying my hardware kits from https://blog.squix.org/shop 23 | b) Send a donation: https://www.paypal.me/squix/5USD 24 | c) Or using this affiliate link while shopping: https://www.banggood.com/?p=6R31122484684201508S 25 | 26 | See more at https://blog.squix.org 27 | 28 | Demo for the buffered graphics library. Renders a 3D cube 29 | */ 30 | 31 | #include 32 | #include "MiniGrafx.h" // General graphic library 33 | #include "ILI9341_SPI.h" // Hardware-specific library 34 | 35 | #define TFT_DC 4 // D2 36 | #define TFT_CS 5 // D1 37 | #define TFT_LED 15 // D8 38 | 39 | // defines the colors usable in the paletted 16 color frame buffer 40 | uint16_t palette[] = {ILI9341_BLACK, // 0 41 | ILI9341_WHITE, // 1 42 | ILI9341_NAVY, // 2 43 | ILI9341_DARKCYAN, // 3 44 | ILI9341_DARKGREEN, // 4 45 | ILI9341_MAROON, // 5 46 | ILI9341_PURPLE, // 6 47 | ILI9341_OLIVE, // 7 48 | ILI9341_LIGHTGREY, // 8 49 | ILI9341_DARKGREY, // 9 50 | ILI9341_BLUE, // 10 51 | ILI9341_GREEN, // 11 52 | ILI9341_CYAN, // 12 53 | ILI9341_RED, // 13 54 | ILI9341_MAGENTA, // 14 55 | ILI9341_YELLOW}; // 15 56 | 57 | 58 | 59 | int SCREEN_WIDTH = 240; 60 | int SCREEN_HEIGHT = 320; 61 | int BITS_PER_PIXEL = 4; // 2^4 = 16 colors 62 | 63 | // Initialize the driver 64 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 65 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 66 | 67 | 68 | // Used for fps measuring 69 | uint16_t counter = 0; 70 | long startMillis = millis(); 71 | uint16_t interval = 20; 72 | 73 | // size / 2 of cube edge 74 | float d = 15; 75 | float px[] = { 76 | -d, d, d, -d, -d, d, d, -d }; 77 | float py[] = { 78 | -d, -d, d, d, -d, -d, d, d }; 79 | float pz[] = { 80 | -d, -d, -d, -d, d, d, d, d }; 81 | 82 | // define the triangles 83 | // The order of the vertices MUST be CCW or the 84 | // shoelace method won't work to detect visible edges 85 | int faces[12][3] = { 86 | {0,1,4}, 87 | {1,5,4}, 88 | {1,2,5}, 89 | {2,6,5}, 90 | {5,7,4}, 91 | {6,7,5}, 92 | {3,4,7}, 93 | {4,3,0}, 94 | {0,3,1}, 95 | {1,3,2}, 96 | {2,3,6}, 97 | {6,3,7} 98 | }; 99 | 100 | // mapped coordinates on screen 101 | float p2x[] = { 102 | 0,0,0,0,0,0,0,0}; 103 | float p2y[] = { 104 | 0,0,0,0,0,0,0,0}; 105 | 106 | // rotation angle in radians 107 | float r[] = { 108 | 0,0,0}; 109 | 110 | #define SHAPE_SIZE 600 111 | // Define how fast the cube rotates. Smaller numbers are faster. 112 | // This is the number of ms between draws. 113 | #define ROTATION_SPEED 0 114 | String fps = "0fps"; 115 | 116 | void setup() { 117 | Serial.begin(115200); 118 | 119 | // Turn on the background LED 120 | pinMode(TFT_LED, OUTPUT); 121 | digitalWrite(TFT_LED, HIGH); 122 | 123 | gfx.init(); 124 | gfx.fillBuffer(0); 125 | gfx.commit(); 126 | 127 | 128 | startMillis = millis(); 129 | } 130 | 131 | 132 | 133 | /** 134 | * Detected visible triangles. If calculated area > 0 the triangle 135 | * is rendered facing towards the viewer, since the vertices are CCW. 136 | * If the area is negative the triangle is CW and thus facing away from us. 137 | */ 138 | int shoelace(int x1, int y1, int x2, int y2, int x3, int y3) { 139 | // (x1y2 - y1x2) + (x2y3 - y2x3) 140 | return x1 * y2 - y1 * x2 + x2*y3 - y2*x3 + x3*y1 - y3*x1; 141 | } 142 | 143 | /** 144 | * Rotates and renders the cube. 145 | **/ 146 | void drawCube() 147 | { 148 | double speed = 90; 149 | r[0]=r[0]+PI/speed; // Add a degree 150 | r[1]=r[1]+PI/speed; // Add a degree 151 | r[2]=r[2]+PI/speed; // Add a degree 152 | if (r[0] >= 360.0*PI/90.0) r[0] = 0; 153 | if (r[1] >= 360.0*PI/90.0) r[1] = 0; 154 | if (r[2] >= 360.0*PI/90.0) r[2] = 0; 155 | 156 | float ax[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 157 | float ay[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 158 | float az[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 159 | 160 | // Calculate all vertices of the cube 161 | for (int i=0;i<8;i++) 162 | { 163 | float px2 = px[i]; 164 | float py2 = cos(r[0])*py[i] - sin(r[0])*pz[i]; 165 | float pz2 = sin(r[0])*py[i] + cos(r[0])*pz[i]; 166 | 167 | float px3 = cos(r[1])*px2 + sin(r[1])*pz2; 168 | float py3 = py2; 169 | float pz3 = -sin(r[1])*px2 + cos(r[1])*pz2; 170 | 171 | ax[i] = cos(r[2])*px3 - sin(r[2])*py3; 172 | ay[i] = sin(r[2])*px3 + cos(r[2])*py3; 173 | az[i] = pz3-150; 174 | 175 | p2x[i] = SCREEN_WIDTH/2+ax[i]*SHAPE_SIZE/az[i]; 176 | p2y[i] = SCREEN_HEIGHT/2+ay[i]*SHAPE_SIZE/az[i]; 177 | } 178 | 179 | // Fill the buffer with color 0 (Black) 180 | gfx.fillBuffer(0); 181 | 182 | for (int i = 0; i < 12; i++) { 183 | 184 | if (shoelace(p2x[faces[i][0]],p2y[faces[i][0]],p2x[faces[i][1]],p2y[faces[i][1]],p2x[faces[i][2]],p2y[faces[i][2]]) > 0) { 185 | gfx.setColor((i / 2) + 1); 186 | gfx.fillTriangle(p2x[faces[i][0]],p2y[faces[i][0]],p2x[faces[i][1]],p2y[faces[i][1]],p2x[faces[i][2]],p2y[faces[i][2]]); 187 | if (i % 2) { 188 | int avX = 0; 189 | int avY = 0; 190 | for (int v = 0; v < 3; v++) { 191 | avX += p2x[faces[i][v]]; 192 | avY += p2y[faces[i][v]]; 193 | } 194 | avX = avX / 3; 195 | avY = avY / 3; 196 | } 197 | } 198 | } 199 | gfx.setColor(1); 200 | gfx.drawString(2, 2, fps); 201 | gfx.commit(); 202 | } 203 | 204 | void loop() { 205 | 206 | drawCube(); 207 | 208 | counter++; 209 | // only calculate the fps every iterations. 210 | if (counter % interval == 0) { 211 | long millisSinceUpdate = millis() - startMillis; 212 | fps = String(interval * 1000.0 / (millisSinceUpdate)) + "fps"; 213 | startMillis = millis(); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /Introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | First you have to include the basic graphic routines and the header file matching your display: 4 | 5 | ```C++ 6 | #include 7 | #include "MiniGrafx.h" // General graphic library 8 | #include "ILI9341_SPI.h" // Hardware-specific library 9 | ``` 10 | The MiniGrafx.h is your API containing all important drawing routines. The ILI9341.h contains the driver 11 | for ILI9341 based displays. This display is available in the Squix Color display starter kit: 12 | https://blog.squix.org/product/esp8266-wifi-color-display-kit-2-4 13 | 14 | Now we will define the pins of the display which can be freely chosen: 15 | 16 | ```C++ 17 | #define TFT_DC D2 18 | #define TFT_CS D1 19 | #define TFT_LED D8 20 | ``` 21 | D2 and D1 are used for the SPI protocol. D8 controls the background light of the display. 22 | 23 | Now it get to the interesting part, the definition of the palette array. In this example we will use a 16 color palette which means that our frame buffer will only know colors represented by the values from 0 to 15. Before writing the values to the display the driver will turn these values back into the colors of the display and a pixel represented by only 4 bit suddenly will be represented by 16 (in case of the ILI9341 display). Why would we intentionally reduce the amount of available colors from 65k (2^16) to only 16? Because our embedded device might not have enough memory to keep the hole screen in the buffer. 24 | 25 | Or let me explain this in other words. Imagine you are a painter in front of a canvas. The palette you hold in 26 | your hands only has space for 16 different colors. While the canvas technically can take much more colors you 27 | decided to reduce complexity and use these 16 colors without mixing them. Got it? 28 | 29 | The values in the arrays are the aliases for the colors you can use. Internally they represent a 565 coded color: 5bit for red, 6bit for green and 5bit for blue. These are the color codes which the driver for the ILI9341 understand. The numbers on each line are the aliases for these 565 colors. By calling gfx.setColor(5) 30 | you will in fact draw ILI9341_MAROON color to the display which is the same as RGB(128, 0, 0). 31 | 32 | 33 | ```C++ 34 | uint16_t palette[] = {ILI9341_BLACK, // 0 35 | ILI9341_WHITE, // 1 36 | ILI9341_NAVY, // 2 37 | ILI9341_DARKCYAN, // 3 38 | ILI9341_DARKGREEN, // 4 39 | ILI9341_MAROON, // 5 40 | ILI9341_PURPLE, // 6 41 | ILI9341_OLIVE, // 7 42 | ILI9341_LIGHTGREY, // 8 43 | ILI9341_DARKGREY, // 9 44 | ILI9341_BLUE, // 10 45 | ILI9341_GREEN, // 11 46 | ILI9341_CYAN, // 12 47 | ILI9341_RED, // 13 48 | ILI9341_MAGENTA, // 14 49 | 0xFD80}; // 15 50 | ``` 51 | 52 | Now it's time to initialize the graphics library and the driver: 53 | 54 | ```C++ 55 | int BITS_PER_PIXEL = 4 ; // 2^4 = 16 colors 56 | 57 | // Initialize the driver 58 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 59 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 60 | ``` 61 | 62 | The MiniGrafx is very flexible when it comes to hardware support. When initializing the graphics library 63 | you define how many bits should be internally be used to represent each pixel. 64 | * 1bit: 2 colors (2^1 = 2) 65 | * 2bit: 4 colors (2^2 = 4) 66 | * 4bit: 16 colors (2^4 = 16) 67 | * 8bit 256 colors (2^8 = 256) 68 | 69 | Please bear in mind that with more bits per pixel also the memory (RAM/heap) consumption grows rapidly. Assuming your display has 240x320 pixels: 70 | * 1bit: 9600 bytes 71 | * 2bit: 19200 bytes 72 | * 4bit: 32400 bytes 73 | * 8bit: 64800 bytes 74 | 75 | So check first how much memory your embedded device offers! 76 | 77 | In the setup() method we make sure that the background light will be turned on: 78 | 79 | ```C++ 80 | pinMode(TFT_LED, OUTPUT); 81 | digitalWrite(TFT_LED, HIGH); 82 | ``` 83 | 84 | and we initialize the graphic library with gfx.init(). This will also call the driver's init method 85 | where the driver can execute methods which should only be called once. With gfx.fillBuffer(0) we clear 86 | the frame buffer and with gfx.commit() we write the content of the frame buffer to the display. This means 87 | that you usually redraw everything on the screen with every iteration. This is a best practice but there 88 | are good reasons why you don't want to do this. 89 | 90 | ```C++ 91 | gfx.init(); 92 | gfx.fillBuffer(0); 93 | gfx.commit(); 94 | ``` 95 | 96 | Now let's do some drawing in the loop method. Clear the buffer by calling gfx.fillBuffer(0). What would 97 | happen if you'd call gfx.fillBuffer(1)? This would draw the second color from the palette to the buffer 98 | which is ILI9341_WHITE. 99 | 100 | After filling the buffer with black pixels we set the color to white and draw a line from (0,0) to 101 | (20,20). Then we go on and draw a filled circle at the position (20, 20) with radius 5. 102 | 103 | ```C++ 104 | void loop() { 105 | gfx.fillBuffer(0); 106 | gfx.setColor(1); 107 | gfx.drawLine(0, 0, 20, 20); 108 | gfx.setColor(13); 109 | gfx.fillCircle(20, 20, 5); 110 | gfx.commit(); 111 | } 112 | ``` 113 | 114 | 115 | And here everything together: 116 | ```C++ 117 | #include 118 | #include "MiniGrafx.h" // General graphic library 119 | #include "ILI9341_SPI.h" // Hardware-specific library 120 | 121 | #define TFT_DC D2 122 | #define TFT_CS D1 123 | #define TFT_LED D8 124 | 125 | // defines the colors usable in the paletted 16 color frame buffer 126 | uint16_t palette[] = {ILI9341_BLACK, // 0 127 | ILI9341_WHITE, // 1 128 | ILI9341_NAVY, // 2 129 | ILI9341_DARKCYAN, // 3 130 | ILI9341_DARKGREEN, // 4 131 | ILI9341_MAROON, // 5 132 | ILI9341_PURPLE, // 6 133 | ILI9341_OLIVE, // 7 134 | ILI9341_LIGHTGREY, // 8 135 | 0x39E7, //ILI9341_DARKGREY, // 9 136 | ILI9341_BLUE, // 10 137 | ILI9341_GREEN, // 11 138 | ILI9341_CYAN, // 12 139 | ILI9341_RED, // 13 140 | ILI9341_MAGENTA, // 14 141 | 0xFD80}; // 15 142 | 143 | 144 | 145 | int SCREEN_WIDTH = 240; 146 | int SCREEN_HEIGHT = 320; 147 | int BITS_PER_PIXEL = 4 ; // 2^4 = 16 colors 148 | 149 | // Initialize the driver 150 | ILI9341_SPI tft = ILI9341_SPI(TFT_CS, TFT_DC); 151 | MiniGrafx gfx = MiniGrafx(&tft, BITS_PER_PIXEL, palette); 152 | 153 | void setup() { 154 | Serial.begin(115200); 155 | 156 | // Turn on the background LED 157 | pinMode(TFT_LED, OUTPUT); 158 | digitalWrite(TFT_LED, HIGH); 159 | 160 | // Initialize the driver only once 161 | gfx.init(); 162 | // fill the buffer with black 163 | gfx.fillBuffer(0); 164 | // write the buffer to the display 165 | gfx.commit(); 166 | } 167 | 168 | 169 | void loop() { 170 | gfx.fillBuffer(0); 171 | gfx.setColor(1); 172 | gfx.drawLine(0, 0, 20, 20); 173 | gfx.setColor(13); 174 | gfx.fillCircle(20, 20, 5); 175 | gfx.commit(); 176 | } 177 | ``` 178 | -------------------------------------------------------------------------------- /src/EPD_WaveShare_43.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #ifndef _EPD_WAVESHARE_43_ 29 | #define _EPD_WAVESHARE_43_ 30 | 31 | #include 32 | #include 33 | #include "DisplayDriver.h" 34 | 35 | #define CMD_SIZE 512 36 | 37 | /* 38 | frame format 39 | */ 40 | #define FRAME_B 0xA5 41 | #define FRAME_E0 0xCC 42 | #define FRAME_E1 0x33 43 | #define FRAME_E2 0xC3 44 | #define FRAME_E3 0x3C 45 | 46 | 47 | /* 48 | color define 49 | */ 50 | #define WHITE 0x03 51 | #define GRAY 0x02 52 | #define DARK_GRAY 0x01 53 | #define BLACK 0x00 54 | 55 | /* 56 | command define 57 | */ 58 | #define CMD_HANDSHAKE 0x00 //handshake 59 | #define CMD_SET_BAUD 0x01 //set baud 60 | #define CMD_READ_BAUD 0x02 //read baud 61 | #define CMD_MEMORYMODE 0x07 //set memory mode 62 | #define CMD_STOPMODE 0x08 //enter stop mode 63 | #define CMD_UPDATE 0x0A //update 64 | #define CMD_SCREEN_ROTATION 0x0D //set screen rotation 65 | #define CMD_LOAD_FONT 0x0E //load font 66 | #define CMD_LOAD_PIC 0x0F //load picture 67 | 68 | #define CMD_SET_COLOR 0x10 //set color 69 | #define CMD_SET_EN_FONT 0x1E //set english font 70 | #define CMD_SET_CH_FONT 0x1F //set chinese font 71 | 72 | #define CMD_DRAW_PIXEL 0x20 //set pixel 73 | #define CMD_DRAW_LINE 0x22 //draw line 74 | #define CMD_FILL_RECT 0x24 //fill rectangle 75 | #define CMD_DRAW_CIRCLE 0x26 //draw circle 76 | #define CMD_FILL_CIRCLE 0x27 //fill circle 77 | #define CMD_DRAW_TRIANGLE 0x28 //draw triangle 78 | #define CMD_FILL_TRIANGLE 0x29 //fill triangle 79 | #define CMD_CLEAR 0x2E //clear screen use back color 80 | 81 | #define CMD_DRAW_STRING 0x30 //draw string 82 | 83 | #define CMD_DRAW_BITMAP 0x70 //draw bitmap 84 | 85 | 86 | /* 87 | FONT 88 | */ 89 | #define GBK32 0x01 90 | #define GBK48 0x02 91 | #define GBK64 0x03 92 | 93 | #define ASCII32 0x01 94 | #define ASCII48 0x02 95 | #define ASCII64 0x03 96 | 97 | 98 | 99 | /* 100 | Memory Mode 101 | */ 102 | #define MEM_NAND 0 103 | #define MEM_TF 1 104 | 105 | /* 106 | set screen rotation 107 | */ 108 | #define EPD_NORMAL 0 //screen normal 109 | #define EPD_INVERSION 1 //screen inversion 110 | 111 | 112 | static const unsigned char _cmd_handshake[8] = {0xA5, 0x00, 0x09, CMD_HANDSHAKE, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_HANDSHAKE 113 | static const unsigned char _cmd_read_baud[8] = {0xA5, 0x00, 0x09, CMD_READ_BAUD, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_READ_BAUD 114 | static const unsigned char _cmd_stopmode[8] = {0xA5, 0x00, 0x09, CMD_STOPMODE, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_STOPMODE 115 | static const unsigned char _cmd_update[8] = {0xA5, 0x00, 0x09, CMD_UPDATE, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_UPDATE 116 | static const unsigned char _cmd_load_font[8] = {0xA5, 0x00, 0x09, CMD_LOAD_FONT, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_LOAD_FONT 117 | static const unsigned char _cmd_load_pic[8] = {0xA5, 0x00, 0x09, CMD_LOAD_PIC, 0xCC, 0x33, 0xC3, 0x3C}; //CMD_LOAD_PIC 118 | 119 | 120 | class EPD_WaveShare_43 : public DisplayDriver { 121 | 122 | public: 123 | 124 | EPD_WaveShare_43(Stream *serial); 125 | 126 | void init(void); 127 | 128 | void setRotation(uint8_t r); 129 | 130 | void writeBuffer(BufferInfo *bufferInfo); 131 | void setBaud(long baud); 132 | void setFastRefresh(boolean isFastRefreshEnabled); 133 | 134 | 135 | 136 | private: 137 | unsigned char _cmd_buff[CMD_SIZE]; 138 | Stream *serial; 139 | void putchars(const unsigned char * ptr, int n); 140 | unsigned char verify(const void * ptr, int n); 141 | void setMemory(unsigned char mode); 142 | void drawPixel(int x0, int y0); 143 | void update(void); 144 | void clear(void); 145 | 146 | uint16_t getPixel(uint8_t *buffer, uint16_t x, uint16_t y); 147 | void setColor(unsigned char color, unsigned char bkcolor); 148 | 149 | 150 | }; 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /examples/ILI9341/DrawPaletteImage_1Bit/image.h: -------------------------------------------------------------------------------- 1 | const char img[] PROGMEM = { 2 | 0x01, // Version: 1 3 | 0x01, // BitDepth: 1 4 | 0x00, 0x63, // Width: 99 5 | 0x00, 0x64, // Height: 100 6 | // Data. Bytes per line: 13 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 19 | 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE1, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x00, 21 | 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF0, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 22 | 0x00, 0x00, 0x0F, 0xE7, 0xE0, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x01, 23 | 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7C, 25 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x0E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 26 | 0xC0, 0x02, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 28 | 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 29 | 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 30 | 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 31 | 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, 32 | 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 33 | 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 35 | 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 36 | 0x00, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x78, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x03, 0xE0, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0xF8, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 40 | 0xE0, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 42 | 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x00, 44 | 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 45 | 0x00, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 46 | 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x0E, 0x00, 47 | 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x07, 0x0E, 0x1E, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 48 | 0x01, 0xFF, 0xFF, 0x07, 0x8E, 0x3E, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x07, 0xDF, 0x7E, 0x1F, 49 | 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x03, 0xFF, 0xFC, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 50 | 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 52 | 0x01, 0xFF, 0xF1, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x00, 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 | 0xFF, 0xF1, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 56 | 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xCF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x8E, 58 | 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 | }; 73 | -------------------------------------------------------------------------------- /examples/ILI9341/DrawPaletteImage_4Bit/image.h: -------------------------------------------------------------------------------- 1 | const char img[] PROGMEM = { 2 | 0x01, // Version: 1 3 | 0x04, // BitDepth: 4 4 | 0x00, 0x9D, // Width: 157 5 | 0x00, 0x13, // Height: 19 6 | // Round width to next byte: 160 7 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 8 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 9 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 10 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 11 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 12 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 13 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 14 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 15 | 0x11, 0x18, 0x88, 0x81, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x88, 0x88, 0x11, 0x11, 0x11, 0x11, 0x18, 0x88, 0x88, 16 | 0x88, 0x88, 0x88, 0x81, 0x11, 0x11, 0x11, 0x11, 0x18, 0x88, 0x88, 0x88, 0x11, 0x11, 0x11, 0x11, 0x18, 0x88, 0x88, 0x11, 17 | 0x11, 0x11, 0x11, 0x18, 0x88, 0x88, 0x88, 0x88, 0x88, 0x81, 0x11, 0x11, 0x11, 0x11, 0x88, 0x88, 0x81, 0x11, 0x11, 0x11, 18 | 0x11, 0x11, 0x11, 0x11, 0x18, 0x88, 0x81, 0x11, 0x11, 0x11, 0x88, 0x88, 0x88, 0x81, 0x11, 0x11, 0x10, 0x11, 0x11, 0x99, 19 | 0x00, 0x00, 0x00, 0x09, 0x81, 0x11, 0x11, 0x11, 0x18, 0x90, 0x00, 0x00, 0x09, 0x81, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 20 | 0x00, 0x00, 0x09, 0x11, 0x11, 0x11, 0x89, 0x00, 0x00, 0x00, 0x00, 0x81, 0x11, 0x11, 0x19, 0x90, 0x00, 0x00, 0x09, 0x81, 21 | 0x11, 0x18, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x98, 0x11, 0x11, 0x11, 22 | 0x11, 0x11, 0x89, 0x00, 0x00, 0x98, 0x11, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x98, 0x11, 0x10, 0x11, 0x19, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x08, 0x11, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x09, 0x81, 0x11, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x11, 0x18, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 25 | 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x89, 0x00, 0x00, 0x00, 0x00, 0x09, 0x81, 0x11, 0x11, 0x11, 26 | 0x19, 0x00, 0x00, 0x00, 0x08, 0x11, 0x11, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x10, 0x11, 0x90, 0x00, 0x00, 0x00, 27 | 0x00, 0x00, 0x09, 0x11, 0x11, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 28 | 0x09, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x11, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x81, 0x18, 29 | 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x11, 0x11, 0x11, 0x90, 30 | 0x00, 0x00, 0x00, 0x08, 0x11, 0x11, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x11, 0x90, 0x00, 0x98, 0x88, 0x89, 31 | 0x00, 0x00, 0x81, 0x11, 0x80, 0x00, 0x08, 0x88, 0x88, 0x90, 0x00, 0x91, 0x11, 0x88, 0x89, 0x00, 0x09, 0x88, 0x88, 0x88, 32 | 0x11, 0x18, 0x90, 0x00, 0x98, 0x88, 0x88, 0x88, 0x11, 0x11, 0x80, 0x00, 0x98, 0x88, 0x88, 0x90, 0x00, 0x91, 0x11, 0x88, 33 | 0x89, 0x00, 0x08, 0x88, 0x88, 0x88, 0x11, 0x18, 0x00, 0x09, 0x88, 0x88, 0x89, 0x00, 0x09, 0x11, 0x11, 0x18, 0x00, 0x00, 34 | 0x98, 0x88, 0x81, 0x11, 0x11, 0x11, 0x88, 0x88, 0x88, 0x89, 0x00, 0x09, 0x10, 0x18, 0x00, 0x09, 0x81, 0x11, 0x11, 0x90, 35 | 0x00, 0x91, 0x11, 0x90, 0x00, 0x91, 0x11, 0x11, 0x19, 0x00, 0x98, 0x11, 0x11, 0x19, 0x00, 0x01, 0x11, 0x11, 0x11, 0x11, 36 | 0x18, 0x00, 0x09, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x90, 0x00, 0x81, 0x11, 0x11, 0x10, 0x00, 0x91, 0x11, 0x11, 0x19, 37 | 0x00, 0x91, 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x18, 0x00, 0x09, 0x11, 0x11, 0x19, 0x00, 0x09, 0x11, 38 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x90, 0x00, 0x10, 0x18, 0x00, 0x09, 0x11, 0x11, 0x11, 0x80, 0x00, 39 | 0x91, 0x11, 0x90, 0x00, 0x99, 0x99, 0x99, 0x90, 0x00, 0x08, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x19, 40 | 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x90, 0x00, 0x99, 0x99, 0x99, 0x90, 0x00, 0x98, 0x11, 0x11, 0x19, 0x00, 41 | 0x91, 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 0x09, 0x99, 0x99, 0x99, 0x00, 0x09, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 42 | 0x11, 0x11, 0x11, 0x11, 0x89, 0x99, 0x99, 0x99, 0x00, 0x00, 0x80, 0x18, 0x00, 0x09, 0x11, 0x11, 0x11, 0x80, 0x00, 0x91, 43 | 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 44 | 0x08, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x11, 0x11, 0x19, 0x00, 0x91, 45 | 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 46 | 0x11, 0x11, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x00, 0x09, 0x11, 0x11, 0x11, 0x80, 0x00, 0x91, 0x11, 47 | 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 0x08, 48 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x11, 0x11, 0x19, 0x00, 0x91, 0x11, 49 | 0x11, 0x11, 0x11, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 50 | 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x00, 0x09, 0x11, 0x11, 0x11, 0x80, 0x00, 0x91, 0x11, 0x90, 51 | 0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x11, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 52 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x90, 0x00, 0x99, 0x99, 0x99, 0x99, 0x98, 0x11, 0x11, 0x11, 0x19, 0x00, 0x01, 0x11, 0x11, 53 | 0x11, 0x11, 0x19, 0x00, 0x09, 0x99, 0x99, 0x99, 0x99, 0x81, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x18, 54 | 0x00, 0x09, 0x99, 0x99, 0x99, 0x00, 0x00, 0x80, 0x18, 0x00, 0x09, 0x11, 0x11, 0x11, 0x80, 0x00, 0x91, 0x11, 0x90, 0x00, 55 | 0x91, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x18, 0x00, 0x09, 0x11, 0x11, 56 | 0x11, 0x11, 0x11, 0x11, 0x90, 0x00, 0x91, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 57 | 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x19, 0x00, 58 | 0x08, 0x11, 0x11, 0x11, 0x90, 0x00, 0x80, 0x18, 0x00, 0x09, 0x11, 0x11, 0x11, 0x80, 0x00, 0x91, 0x11, 0x80, 0x00, 0x09, 59 | 0x88, 0x88, 0x88, 0x81, 0x11, 0x11, 0x11, 0x19, 0x00, 0x09, 0x88, 0x88, 0x11, 0x11, 0x18, 0x90, 0x00, 0x98, 0x88, 0x88, 60 | 0x88, 0x11, 0x11, 0x80, 0x00, 0x08, 0x88, 0x88, 0x88, 0x81, 0x11, 0x11, 0x11, 0x19, 0x00, 0x09, 0x88, 0x88, 0x11, 0x11, 61 | 0x18, 0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0x11, 0x11, 0x18, 0x89, 0x00, 0x09, 0x88, 0x88, 0x88, 0x11, 0x18, 0x00, 0x09, 62 | 0x88, 0x88, 0x89, 0x00, 0x00, 0x10, 0x18, 0x00, 0x09, 0x11, 0x11, 0x11, 0x80, 0x00, 0x91, 0x11, 0x19, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x08, 0x11, 0x11, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x91, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 64 | 0x81, 0x11, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x11, 0x11, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x81, 0x11, 0x11, 65 | 0x90, 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x18, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x09, 0x10, 0x18, 0x00, 0x09, 0x11, 0x11, 0x11, 0x80, 0x00, 0x91, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 67 | 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x91, 0x11, 0x11, 0x19, 0x00, 0x00, 0x00, 0x00, 0x09, 0x81, 68 | 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x08, 0x11, 0x11, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x91, 0x11, 0x11, 0x19, 69 | 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x80, 0x00, 0x00, 0x00, 70 | 0x00, 0x00, 0x98, 0x10, 0x18, 0x90, 0x09, 0x11, 0x11, 0x11, 0x80, 0x00, 0x81, 0x11, 0x11, 0x18, 0x90, 0x00, 0x00, 0x00, 71 | 0x91, 0x11, 0x11, 0x11, 0x11, 0x18, 0x90, 0x00, 0x00, 0x81, 0x11, 0x11, 0x11, 0x89, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 72 | 0x11, 0x18, 0x90, 0x00, 0x00, 0x00, 0x98, 0x11, 0x11, 0x11, 0x11, 0x18, 0x90, 0x00, 0x00, 0x81, 0x11, 0x11, 0x11, 0x89, 73 | 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x11, 0x11, 0x18, 0x90, 0x00, 0x00, 0x00, 74 | 0x09, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 75 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 76 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 77 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 78 | 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 79 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 80 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 81 | 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 82 | 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 83 | }; 84 | -------------------------------------------------------------------------------- /src/EPD_WaveShare_42.h: -------------------------------------------------------------------------------- 1 | /** 2 | The MIT License (MIT) 3 | Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | SOFTWARE. 19 | 20 | Please note: We are spending a lot of time to write and maintain open source codes 21 | Please support us by buying our products from https://thingpulse.com/shop/ 22 | 23 | See more at https://thingpulse.com 24 | 25 | Many thanks go to various contributors such as Adafruit, Waveshare. 26 | */ 27 | 28 | #if !defined(EPD42_H) 29 | #define EPD42_H 1 30 | 31 | #include 32 | #include 33 | #include "DisplayDriver.h" 34 | 35 | 36 | // EPD4IN2 commands 37 | #define PANEL_SETTING 0x00 38 | #define POWER_SETTING 0x01 39 | #define POWER_OFF 0x02 40 | #define POWER_OFF_SEQUENCE_SETTING 0x03 41 | #define POWER_ON 0x04 42 | #define POWER_ON_MEASURE 0x05 43 | #define BOOSTER_SOFT_START 0x06 44 | #define DEEP_SLEEP 0x07 45 | #define DATA_START_TRANSMISSION_1 0x10 46 | #define DATA_STOP 0x11 47 | #define DISPLAY_REFRESH 0x12 48 | #define DATA_START_TRANSMISSION_2 0x13 49 | #define LUT_FOR_VCOM 0x20 50 | #define LUT_WHITE_TO_WHITE 0x21 51 | #define LUT_BLACK_TO_WHITE 0x22 52 | #define LUT_WHITE_TO_BLACK 0x23 53 | #define LUT_BLACK_TO_BLACK 0x24 54 | #define PLL_CONTROL 0x30 55 | #define TEMPERATURE_SENSOR_COMMAND 0x40 56 | #define TEMPERATURE_SENSOR_SELECTION 0x41 57 | #define TEMPERATURE_SENSOR_WRITE 0x42 58 | #define TEMPERATURE_SENSOR_READ 0x43 59 | #define VCOM_AND_DATA_INTERVAL_SETTING 0x50 60 | #define LOW_POWER_DETECTION 0x51 61 | #define TCON_SETTING 0x60 62 | #define RESOLUTION_SETTING 0x61 63 | #define GSST_SETTING 0x65 64 | #define GET_STATUS 0x71 65 | #define AUTO_MEASUREMENT_VCOM 0x80 66 | #define READ_VCOM_VALUE 0x81 67 | #define VCM_DC_SETTING 0x82 68 | #define PARTIAL_WINDOW 0x90 69 | #define PARTIAL_IN 0x91 70 | #define PARTIAL_OUT 0x92 71 | #define PROGRAM_MODE 0xA0 72 | #define ACTIVE_PROGRAMMING 0xA1 73 | #define READ_OTP 0xA2 74 | #define POWER_SAVING 0xE3 75 | #define DISPLAY_TIMEOUT 6000 76 | 77 | /*extern const unsigned char lut_vcom0[]; 78 | extern const unsigned char lut_ww[]; 79 | extern const unsigned char lut_bw[]; 80 | extern const unsigned char lut_bb[]; 81 | extern const unsigned char lut_wb[];*/ 82 | 83 | 84 | const unsigned char lut_vcom0[] = 85 | { 86 | 0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 87 | 0x00, 0x17, 0x17, 0x00, 0x00, 0x02, 88 | 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, 89 | 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02, 90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 92 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 93 | }; 94 | 95 | const unsigned char lut_vcom0_quick[] = 96 | { 97 | 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, 98 | 0x00, 0x0E, 0x00, 0x00, 0x00, 0x02, 99 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 100 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 101 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 102 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 103 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 104 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 | }; 106 | 107 | 108 | 109 | const unsigned char lut_ww[] ={ 110 | 0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 111 | 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 112 | 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, 113 | 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 114 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 115 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 116 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 117 | }; 118 | 119 | const unsigned char lut_ww_quick[] ={ 120 | 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, 121 | 0xA0, 0x0E, 0x00, 0x00, 0x00, 0x02, 122 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 123 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 124 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 125 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 126 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 127 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 128 | }; 129 | 130 | 131 | const unsigned char lut_bw[] ={ 132 | 0x40, 0x17, 0x00, 0x00, 0x00, 0x02, 133 | 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 134 | 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, 135 | 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, 136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 138 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 139 | }; 140 | 141 | 142 | const unsigned char lut_bw_quick[] ={ 143 | 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, 144 | 0xA0, 0x0E, 0x00, 0x00, 0x00, 0x02, 145 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 146 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 147 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 148 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 149 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 150 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 151 | }; 152 | 153 | const unsigned char lut_bb[] ={ 154 | 0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 155 | 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 156 | 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, 157 | 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 159 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 160 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 161 | }; 162 | 163 | const unsigned char lut_bb_quick[] ={ 164 | 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, 165 | 0x50, 0x0E, 0x00, 0x00, 0x00, 0x02, 166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 170 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 172 | }; 173 | 174 | 175 | const unsigned char lut_wb[] ={ 176 | 0x80, 0x17, 0x00, 0x00, 0x00, 0x02, 177 | 0x90, 0x17, 0x17, 0x00, 0x00, 0x02, 178 | 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, 179 | 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 182 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 183 | }; 184 | 185 | const unsigned char lut_wb_quick[] ={ 186 | 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, 187 | 0x50, 0x0E, 0x00, 0x00, 0x00, 0x02, 188 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 189 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 190 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 191 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 192 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 193 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 194 | }; 195 | 196 | 197 | class EPD_WaveShare42 : public DisplayDriver { 198 | 199 | public: 200 | EPD_WaveShare42(uint8_t csPin, uint8_t rstPin, uint8_t dcPin, uint8_t busyPin); 201 | 202 | void setRotation(uint8_t r); 203 | void init(); 204 | 205 | void writeBuffer(BufferInfo *bufferInfo); 206 | 207 | int IfInit(void); 208 | void DigitalWrite(int pin, int value); 209 | int DigitalRead(int pin); 210 | void DelayMs(unsigned int delaytime); 211 | void SpiTransfer(unsigned char data); 212 | 213 | static int getWidth(); 214 | static int getHeight(); 215 | 216 | void SendCommand(unsigned char command); 217 | void SendData(unsigned char data); 218 | void WaitUntilIdle(void); 219 | void Reset(void); 220 | void SetPartialWindow(const unsigned char* frame_buffer, int x, int y, int w, int l); 221 | void SetPartialWindowBlack(const unsigned char* buffer_black, int x, int y, int w, int l); 222 | void SetPartialWindowRed(const unsigned char* buffer_red, int x, int y, int w, int l); 223 | void SetLut(void); 224 | void DisplayFrame(const unsigned char* frame_buffer); 225 | void DisplayFrame(void); 226 | void ClearFrame(void); 227 | void Sleep(void); 228 | void setFastRefresh(boolean isFastRefreshEnabled); 229 | uint8_t getPixel(const unsigned char* buffer, uint16_t x, uint16_t y); 230 | 231 | uint8_t reverse(uint8_t in); 232 | 233 | private: 234 | boolean isFastRefreshEnabled; 235 | uint8_t csPin; 236 | uint8_t rstPin; 237 | uint8_t dcPin; 238 | uint8_t busyPin; 239 | uint8_t rotation; 240 | uint16_t delaytime; 241 | uint16_t height, width; 242 | uint16_t bufferWidth; 243 | uint16_t bufferHeight; 244 | 245 | 246 | }; 247 | 248 | #endif 249 | -------------------------------------------------------------------------------- /src/Carousel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 by Daniel Eichhorn, ThingPulse 5 | * Copyright (c) 2019 by Fabrice Weinberg 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | * 25 | */ 26 | 27 | #ifndef CAROUSEL_h 28 | #define CAROUSEL_h 29 | 30 | #include 31 | #include "MiniGrafx.h" 32 | 33 | //#define DEBUG_CAROUSEL(...) Serial.printf( __VA_ARGS__ ) 34 | 35 | #ifndef DEBUG_CAROUSEL 36 | #define DEBUG_CAROUSEL(...) 37 | #endif 38 | 39 | enum AnimationDirection { 40 | SLIDE_UP, 41 | SLIDE_DOWN, 42 | SLIDE_LEFT, 43 | SLIDE_RIGHT 44 | }; 45 | 46 | enum IndicatorPosition { 47 | TOP, 48 | RIGHT, 49 | BOTTOM, 50 | LEFT 51 | }; 52 | 53 | enum IndicatorDirection { 54 | LEFT_RIGHT, 55 | RIGHT_LEFT 56 | }; 57 | 58 | enum FrameState { 59 | IN_TRANSITION, 60 | FIXED 61 | }; 62 | 63 | 64 | const char ANIMATION_activeSymbol[] PROGMEM = { 65 | 0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00 66 | }; 67 | 68 | const char ANIMATION_inactiveSymbol[] PROGMEM = { 69 | 0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00 70 | }; 71 | 72 | 73 | // Structure of the UiState 74 | struct CarouselState { 75 | uint64_t lastUpdate = 0; 76 | uint16_t ticksSinceLastStateSwitch = 0; 77 | 78 | FrameState frameState = FIXED; 79 | uint8_t currentFrame = 0; 80 | 81 | bool isIndicatorDrawen = true; 82 | 83 | // Normal = 1, Inverse = -1; 84 | int8_t frameTransitionDirection = 1; 85 | 86 | bool manuelControll = false; 87 | 88 | // Custom data that can be used by the user 89 | void* userData = NULL; 90 | }; 91 | 92 | struct LoadingStage { 93 | const char* process; 94 | void (*callback)(); 95 | }; 96 | 97 | typedef void (*FrameCallback)(MiniGrafx *miniGrafx, CarouselState* state, int16_t x, int16_t y); 98 | typedef void (*OverlayCallback)(MiniGrafx *miniGrafx, CarouselState* state); 99 | typedef void (*LoadingDrawFunction)(MiniGrafx *miniGrafx, LoadingStage* stage, uint8_t progress); 100 | 101 | class Carousel { 102 | private: 103 | MiniGrafx *miniGrafx; 104 | uint16_t x, y, width, height; 105 | 106 | // Symbols for the Indicator 107 | IndicatorPosition indicatorPosition = BOTTOM; 108 | IndicatorDirection indicatorDirection = LEFT_RIGHT; 109 | 110 | const char* activeSymbol = ANIMATION_activeSymbol; 111 | const char* inactiveSymbol = ANIMATION_inactiveSymbol; 112 | 113 | bool shouldDrawIndicators = true; 114 | 115 | // Values for the Frames 116 | AnimationDirection frameAnimationDirection = SLIDE_RIGHT; 117 | 118 | int8_t lastTransitionDirection = 1; 119 | 120 | uint16_t ticksPerFrame = 151; // ~ 5000ms at 30 FPS 121 | uint16_t ticksPerTransition = 15; // ~ 500ms at 30 FPS 122 | 123 | bool autoTransition = true; 124 | 125 | FrameCallback* frameFunctions; 126 | uint8_t frameCount = 0; 127 | 128 | // Internally used to transition to a specific frame 129 | int8_t nextFrameNumber = -1; 130 | 131 | // Values for Overlays 132 | OverlayCallback* overlayFunctions; 133 | uint8_t overlayCount = 0; 134 | 135 | // Will the Indicator be drawen 136 | // 3 Not drawn in both frames 137 | // 2 Drawn this frame but not next 138 | // 1 Not drown this frame but next 139 | // 0 Not known yet 140 | uint8_t indicatorDrawState = 1; 141 | 142 | // Loading screen 143 | LoadingDrawFunction loadingDrawFunction = [](MiniGrafx *miniGrafx, LoadingStage* stage, uint8_t progress) { 144 | miniGrafx->setTextAlignment(TEXT_ALIGN_CENTER); 145 | miniGrafx->setFont(ArialMT_Plain_10); 146 | miniGrafx->drawString(64, 18, stage->process); 147 | //miniGrafx->drawProgressBar(4, 32, 120, 8, progress); 148 | }; 149 | 150 | // UI State 151 | CarouselState state; 152 | 153 | // Bookeeping for update 154 | uint8_t updateInterval = 33; 155 | 156 | uint8_t getNextFrameNumber(); 157 | void drawIndicator(); 158 | void drawFrame(); 159 | void drawOverlays(); 160 | void tick(); 161 | void resetState(); 162 | 163 | public: 164 | 165 | Carousel(MiniGrafx *miniGrafx, uint16_t x, uint16_t y, uint16_t width, uint16_t height); 166 | 167 | /** 168 | * Initialise the display 169 | */ 170 | void init(); 171 | 172 | /** 173 | * Configure the internal used target FPS 174 | */ 175 | void setTargetFPS(uint8_t fps); 176 | 177 | // Automatic Controll 178 | /** 179 | * Enable automatic transition to next frame after the some time can be configured with `setTimePerFrame` and `setTimePerTransition`. 180 | */ 181 | void enableAutoTransition(); 182 | 183 | /** 184 | * Disable automatic transition to next frame. 185 | */ 186 | void disableAutoTransition(); 187 | 188 | /** 189 | * Set the direction if the automatic transitioning 190 | */ 191 | void setAutoTransitionForwards(); 192 | void setAutoTransitionBackwards(); 193 | 194 | /** 195 | * Set the approx. time a frame is displayed 196 | */ 197 | void setTimePerFrame(uint16_t time); 198 | 199 | /** 200 | * Set the approx. time a transition will take 201 | */ 202 | void setTimePerTransition(uint16_t time); 203 | 204 | // Customize indicator position and style 205 | 206 | /** 207 | * Draw the indicator. 208 | * This is the defaut state for all frames if 209 | * the indicator was hidden on the previous frame 210 | * it will be slided in. 211 | */ 212 | void enableIndicator(); 213 | 214 | /** 215 | * Don't draw the indicator. 216 | * This will slide out the indicator 217 | * when transitioning to the next frame. 218 | */ 219 | void disableIndicator(); 220 | 221 | /** 222 | * Enable drawing of indicators 223 | */ 224 | void enableAllIndicators(); 225 | 226 | /** 227 | * Disable draw of indicators. 228 | */ 229 | void disableAllIndicators(); 230 | 231 | /** 232 | * Set the position of the indicator bar. 233 | */ 234 | void setIndicatorPosition(IndicatorPosition pos); 235 | 236 | /** 237 | * Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING 238 | */ 239 | void setIndicatorDirection(IndicatorDirection dir); 240 | 241 | /** 242 | * Set the symbol to indicate an active frame in the indicator bar. 243 | */ 244 | void setActiveSymbol(const char* symbol); 245 | 246 | /** 247 | * Set the symbol to indicate an inactive frame in the indicator bar. 248 | */ 249 | void setInactiveSymbol(const char* symbol); 250 | 251 | 252 | // Frame settings 253 | 254 | /** 255 | * Configure what animation is used to transition from one frame to another 256 | */ 257 | void setFrameAnimation(AnimationDirection dir); 258 | 259 | /** 260 | * Add frame drawing functions 261 | */ 262 | void setFrames(FrameCallback* frameFunctions, uint8_t frameCount); 263 | 264 | // Overlay 265 | 266 | /** 267 | * Add overlays drawing functions that are draw independent of the Frames 268 | */ 269 | void setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount); 270 | 271 | 272 | // Loading animation 273 | /** 274 | * Set the function that will draw each step 275 | * in the loading animation 276 | */ 277 | void setLoadingDrawFunction(LoadingDrawFunction loadingFunction); 278 | 279 | 280 | /** 281 | * Run the loading process 282 | */ 283 | void runLoadingProcess(LoadingStage* stages, uint8_t stagesCount); 284 | 285 | 286 | // Manual Control 287 | void nextFrame(); 288 | void previousFrame(); 289 | 290 | /** 291 | * Switch without transition to frame `frame`. 292 | */ 293 | void switchToFrame(uint8_t frame); 294 | 295 | /** 296 | * Transition to frame `frame`, when the `frame` number is bigger than the current 297 | * frame the forward animation will be used, otherwise the backwards animation is used. 298 | */ 299 | void transitionToFrame(uint8_t frame); 300 | 301 | // State Info 302 | CarouselState* getUiState(); 303 | 304 | int8_t update(); 305 | }; 306 | #endif 307 | --------------------------------------------------------------------------------