a first version of a modular structur of the code based on a few classes, Acceptor and eInk and Button are working
This commit is contained in:
parent
493642aa90
commit
b15cf8d365
12 changed files with 589 additions and 1365 deletions
|
@ -1,289 +0,0 @@
|
|||
// Display Library example for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
|
||||
// Requires HW SPI and Adafruit_GFX. Caution: the e-paper panels require 3.3V supply AND data lines!
|
||||
//
|
||||
// Display Library based on Demo Example from Good Display: http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html
|
||||
//
|
||||
// Author: Jean-Marc Zingg
|
||||
//
|
||||
// Version: see library.properties
|
||||
//
|
||||
// Library: https://github.com/ZinggJM/GxEPD2
|
||||
|
||||
// Supporting Arduino Forum Topics:
|
||||
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
|
||||
// Good Display ePaper for Arduino: https://forum.arduino.cc/index.php?topic=436411.0
|
||||
|
||||
// *** for Waveshare ESP32 Driver board *** //
|
||||
// mapping of Waveshare ESP32 Driver Board
|
||||
// BUSY -> 25, RST -> 26, DC -> 27, CS-> 15, CLK -> 13, DIN -> 14
|
||||
// uncomment next two lines for Waveshare ESP32 Driver Board
|
||||
// #define USE_HSPI_FOR_EPD
|
||||
// #define ENABLE_GxEPD2_GFX 0
|
||||
// *** end Waveshare ESP32 Driver board *** //
|
||||
|
||||
// NOTE: you may need to adapt or select for your wiring in the processor specific conditional compile sections below
|
||||
// select the display class (only one), matching the kind of display panel
|
||||
#define GxEPD2_DISPLAY_CLASS GxEPD2_BW
|
||||
// #define GxEPD2_DISPLAY_CLASS GxEPD2_3C
|
||||
// #define GxEPD2_DISPLAY_CLASS GxEPD2_4C
|
||||
// #define GxEPD2_DISPLAY_CLASS GxEPD2_7C
|
||||
|
||||
// select the display driver class (only one) for your panel
|
||||
|
||||
#define GxEPD2_DRIVER_CLASS GxEPD2_150_BN // 1.54 inch Waveshare e-paper display
|
||||
const String display_type = "GxEPD2_150_BN";
|
||||
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_B74 // Waveshare 2.13 inch e-paper display - Version 3
|
||||
// const String display_type = "GxEPD2_213_B74";
|
||||
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_flex // Waveshare 2.13 inch e-paper display - (D) flex (yellow)
|
||||
// const String display_type = "GxEPD2_213_flex";
|
||||
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_270 // Waveshare 264x176, 2.7inch E-Ink display - Version 1
|
||||
// const String display_type = "GxEPD2_270";
|
||||
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_270_GDEY027T91 // Waveshare 264x176, 2.7inch E-Ink display - Version 2
|
||||
// const String display_type = "GxEPD2_270_GDEY027T91";
|
||||
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_154 // GDEP015OC1 200x200, IL3829, (WFC0000CZ07), no longer available
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_154_D67 // GDEH0154D67 200x200, SSD1681, (HINK-E154A07-A1)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_102 // GDEW0102T4 80x128, UC8175, (WFT0102CZA2)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_154_T8 // GDEW0154T8 152x152, UC8151 (IL0373), (WFT0154CZ17)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_154_M09 // GDEW0154M09 200x200, JD79653A, (WFT0154CZB3)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_154_M10 // GDEW0154M10 152x152, UC8151D, (WFT0154CZ17)
|
||||
/// #define GxEPD2_DRIVER_CLASS GxEPD2_154_GDEY0154D67 // GDEY0154D67 200x200, SSD1681, (FPC-B001 20.05.21)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213 // GDE0213B1 122x250, IL3895, (HINK-E0213-G01), phased out
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_B72 // GDEH0213B72 122x250, SSD1675A (IL3897), (HINK-E0213A22-A0 SLH1852)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_B73 // GDEH0213B73 122x250, SSD1675B, (HINK-E0213A22-A0 SLH1914)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_B74 // GDEM0213B74 122x250, SSD1680, FPC-7528B)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_flex // GDEW0213I5F 104x212, UC8151 (IL0373)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_M21 // GDEW0213M21 104x212, UC8151 (IL0373), (WFT0213CZ16)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_T5D // GDEW0213T5D 104x212, UC8151D, (WFT0213CZ16)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_BN // DEPG0213BN 122x250, SSD1680, (FPC-7528B), TTGO T5 V2.4.1, V2.3.1
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_GDEY0213B74 // GDEY0213B74 122x250, SSD1680, (FPC-A002 20.04.08)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_260 // GDEW026T0 152x296, UC8151 (IL0373), (WFT0154CZ17)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_260_M01 // GDEW026M01 152x296, UC8151 (IL0373), (WFT0260CZB2)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_266_BN // DEPG0266BN 152x296, SSD1680, (FPC7510), TTGO T5 V2.66, TTGO T5 V2.4.1
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_266_GDEY0266T90 // GDEY0266T90 152x296, SSD1680, (FPC-A003 HB)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290 // GDEH029A1 128x296, SSD1608 (IL3820), (E029A01-FPC-A1 SYX1553)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_T5 // GDEW029T5 128x296, UC8151 (IL0373), (WFT0290CZ10)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_T5D // GDEW029T5D 128x296, UC8151D, (WFT0290CZ10)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_I6FD // GDEW029I6FD 128x296, UC8151D, (WFT0290CZ10)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_T94 // GDEM029T94 128x296, SSD1680, (FPC-7519 rev.b)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_T94_V2 // GDEM029T94 128x296, SSD1680, (FPC-7519 rev.b), Waveshare 2.9" V2 variant
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_BS // DEPG0290BS 128x296, SSD1680, (FPC-7519 rev.b)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_M06 // GDEW029M06 128x296, UC8151D, (WFT0290CZ10)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_GDEY029T94 // GDEY029T94 128x296, SSD1680, (FPC-A005 20.06.15)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_371 // GDEW0371W7 240x416, UC8171 (IL0324), (missing)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_370_TC1 // ED037TC1 280x480, SSD1677, (ICA-FU-20 ichia 2029), Waveshare 3.7"
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_420 // GDEW042T2 400x300, UC8176 (IL0398), (WFT042CZ15)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_420_M01 // GDEW042M01 400x300, UC8176 (IL0398), (WFT042CZ15)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_420_GDEY042T91 // GDEY042T91 400x300, SSD1683 (no inking)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_583 // GDEW0583T7 600x448, UC8159c (IL0371), (missing)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_583_T8 // GDEW0583T8 648x480, EK79655 (GD7965), (WFT0583CZ61)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_583_GDEQ0583T31 // GDEQ0583T31 648x480, UC8179, (P583010-MF1-B)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_750 // GDEW075T8 640x384, UC8159c (IL0371), (WF0583CZ09)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_750_T7 // GDEW075T7 800x480, EK79655 (GD7965), (WFT0583CZ61)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_750_YT7 // GDEY075T7 800x480, UC8179 (GD7965), (FPC-C001 20.8.20)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_1160_T91 // GDEH116T91 960x640, SSD1677, (none or hidden)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_1248 // GDEW1248T3 1304x984, UC8179, (WFT1248BZ23,WFT1248BZ24)
|
||||
// 3-color e-papers
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_154c // GDEW0154Z04 200x200, IL0376F, (WFT0000CZ04), no longer available
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_154_Z90c // GDEH0154Z90 200x200, SSD1681, (HINK-E154A07-A1)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213c // GDEW0213Z16 104x212, UC8151 (IL0373), (WFT0213CZ16)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_Z19c // GDEH0213Z19 104x212, UC8151D, (HINK-E0213A20-A2 2020-11-19)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_Z98c // GDEY0213Z98 122x250, SSD1680, (FPC-A002 20.04.08)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_266c // GDEY0266Z90 152x296, SSD1680, (FPC-7510)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_270c // GDEW027C44 176x264, IL91874, (WFI0190CZ22)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290c // GDEW029Z10 128x296, UC8151 (IL0373), (WFT0290CZ10)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_Z13c // GDEH029Z13 128x296, UC8151D, (HINK-E029A10-A3 20160809)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_290_C90c // GDEM029C90 128x296, SSD1680, (FPC-7519 rev.b)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_420c // GDEW042Z15 400x300, UC8176 (IL0398), (WFT0420CZ15)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_420c_Z21 // GDEQ042Z21 400x300, UC8276, (hidden)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_583c // GDEW0583Z21 600x448, UC8159c (IL0371), (missing)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_583c_Z83 // GDEW0583Z83 648x480, EK79655 (GD7965), (WFT0583CZ61)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_750c // GDEW075Z09 640x384, UC8159c (IL0371), (WF0583CZ09)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_750c_Z08 // GDEW075Z08 800x480, EK79655 (GD7965), (WFT0583CZ61)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_750c_Z90 // GDEH075Z90 880x528, SSD1677, (HINK-E075A07-A0)
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_1248c // GDEY1248Z51 1304x984, UC8179, (WFT1248BZ23,WFT1248BZ24)
|
||||
// 4-color e-paper
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_437c // Waveshare 4.37" 4-color
|
||||
// 7-color e-paper
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_565c // Waveshare 5.65" 7-color
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_730c_GDEY073D46 // GDEY073D46 800x480 7-color, (N-FPC-001 2021.11.26)
|
||||
// grey levels parallel IF e-papers on Waveshare e-Paper IT8951 Driver HAT
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_it60 // ED060SCT 800x600
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_it60_1448x1072 // ED060KC1 1448x1072
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_it78_1872x1404 // ED078KC2 1872x1404
|
||||
// #define GxEPD2_DRIVER_CLASS GxEPD2_it103_1872x1404 // ES103TC1 1872x1404
|
||||
|
||||
// SS is usually used for CS. define here for easy change
|
||||
#ifndef EPD_CS
|
||||
#define EPD_CS SS
|
||||
#endif
|
||||
|
||||
#if defined(GxEPD2_DISPLAY_CLASS) && defined(GxEPD2_DRIVER_CLASS)
|
||||
|
||||
// somehow there should be an easier way to do this
|
||||
#define GxEPD2_BW_IS_GxEPD2_BW true
|
||||
#define GxEPD2_3C_IS_GxEPD2_3C true
|
||||
#define GxEPD2_4C_IS_GxEPD2_4C true
|
||||
#define GxEPD2_7C_IS_GxEPD2_7C true
|
||||
#define GxEPD2_1248_IS_GxEPD2_1248 true
|
||||
#define GxEPD2_1248c_IS_GxEPD2_1248c true
|
||||
#define IS_GxEPD(c, x) (c##x)
|
||||
#define IS_GxEPD2_BW(x) IS_GxEPD(GxEPD2_BW_IS_, x)
|
||||
#define IS_GxEPD2_3C(x) IS_GxEPD(GxEPD2_3C_IS_, x)
|
||||
#define IS_GxEPD2_4C(x) IS_GxEPD(GxEPD2_4C_IS_, x)
|
||||
#define IS_GxEPD2_7C(x) IS_GxEPD(GxEPD2_7C_IS_, x)
|
||||
#define IS_GxEPD2_1248(x) IS_GxEPD(GxEPD2_1248_IS_, x)
|
||||
#define IS_GxEPD2_1248c(x) IS_GxEPD(GxEPD2_1248c_IS_, x)
|
||||
|
||||
#include "GxEPD2_selection_check.h"
|
||||
|
||||
#if defined(ESP8266)
|
||||
#define MAX_DISPLAY_BUFFER_SIZE (81920ul - 34000ul - 5000ul) // ~34000 base use, change 5000 to your application use
|
||||
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) || IS_GxEPD2_4C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
|
||||
#endif
|
||||
// adapt the constructor parameters to your wiring
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=D8*/ EPD_CS, /*DC=D3*/ 0, /*RST=D4*/ 2, /*BUSY=D2*/ 4));
|
||||
// mapping of Waveshare e-Paper ESP8266 Driver Board, new version
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=15*/ EPD_CS, /*DC=4*/ 4, /*RST=2*/ 2, /*BUSY=5*/ 5));
|
||||
// mapping of Waveshare e-Paper ESP8266 Driver Board, old version
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=15*/ EPD_CS, /*DC=4*/ 4, /*RST=5*/ 5, /*BUSY=16*/ 16));
|
||||
#undef MAX_DISPLAY_BUFFER_SIZE
|
||||
#undef MAX_HEIGHT
|
||||
#endif
|
||||
|
||||
#if defined(ESP32)
|
||||
#define MAX_DISPLAY_BUFFER_SIZE 65536ul // e.g.
|
||||
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) || IS_GxEPD2_4C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
|
||||
#endif
|
||||
// adapt the constructor parameters to your wiring
|
||||
#if !IS_GxEPD2_1248(GxEPD2_DRIVER_CLASS) && !IS_GxEPD2_1248c(GxEPD2_DRIVER_CLASS)
|
||||
#if defined(ARDUINO_LOLIN_D32_PRO)
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ EPD_CS, /*DC=*/0, /*RST=*/2, /*BUSY=*/15)); // my LOLIN_D32_PRO proto board
|
||||
#else
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ EPD_CS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // my suggested wiring and proto board
|
||||
// *** uncomment next line for standard ESP32 *** //
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ 26, /*DC=*/25, /*RST=*/33, /*BUSY=*/27)); // esp32 NodeMCU following AZ Delivery guide pinout
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ 5, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // LILYGO_T5_V2.4.1
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ EPD_CS, /*DC=*/ 19, /*RST=*/ 4, /*BUSY=*/ 34)); // LILYGO® TTGO T5 2.66
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=5*/ EPD_CS, /*DC=*/ 2, /*RST=*/ 0, /*BUSY=*/ 4)); // e.g. TTGO T8 ESP32-WROVER
|
||||
// *** uncomment next line for Waveshare ESP32 Driver board *** //
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ 15, /*DC=*/ 27, /*RST=*/ 26, /*BUSY=*/ 25)); // Waveshare ESP32 Driver Board
|
||||
#endif
|
||||
#else // GxEPD2_1248 or GxEPD2_1248c
|
||||
// Waveshare 12.48 b/w or b/w/r SPI display board and frame or Good Display 12.48 b/w panel GDEW1248T3 or b/w/r panel GDEY1248Z51
|
||||
// general constructor for use with all parameters, e.g. for Waveshare ESP32 driver board mounted on connection board
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*sck=*/13, /*miso=*/12, /*mosi=*/14,
|
||||
/*cs_m1=*/23, /*cs_s1=*/22, /*cs_m2=*/16, /*cs_s2=*/19,
|
||||
/*dc1=*/25, /*dc2=*/17, /*rst1=*/33, /*rst2=*/5,
|
||||
/*busy_m1=*/32, /*busy_s1=*/26, /*busy_m2=*/18, /*busy_s2=*/4));
|
||||
#endif
|
||||
#undef MAX_DISPLAY_BUFFER_SIZE
|
||||
#undef MAX_HEIGHT
|
||||
#endif
|
||||
|
||||
// can't use package "STMF1 Boards (STM32Duino.com)" (Roger Clark) anymore with Adafruit_GFX, use "STM32 Boards (selected from submenu)" (STMicroelectronics)
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
#define MAX_DISPLAY_BUFFER_SIZE 15000ul // ~15k is a good compromise
|
||||
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) || IS_GxEPD2_4C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
|
||||
#endif
|
||||
// adapt the constructor parameters to your wiring
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=PA4*/ EPD_CS, /*DC=*/PA3, /*RST=*/PA2, /*BUSY=*/PA1));
|
||||
#undef MAX_DISPLAY_BUFFER_SIZE
|
||||
#undef MAX_HEIGHT
|
||||
#endif
|
||||
|
||||
#if defined(__AVR)
|
||||
#if defined(ARDUINO_AVR_MEGA2560) // Note: SS is on 53 on MEGA
|
||||
#define MAX_DISPLAY_BUFFER_SIZE 5000 // e.g. full height for 200x200
|
||||
#else // Note: SS is on 10 on UNO, NANO
|
||||
#define MAX_DISPLAY_BUFFER_SIZE 800 //
|
||||
#endif
|
||||
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) || IS_GxEPD2_4C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
|
||||
#endif
|
||||
// adapt the constructor parameters to your wiring
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/EPD_CS, /*DC=*/8, /*RST=*/9, /*BUSY=*/7));
|
||||
// for Arduino Micro or Arduino Leonardo with CS on 10 on my proto boards (SS would be 17) uncomment instead:
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ 10, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_SAM)
|
||||
#define MAX_DISPLAY_BUFFER_SIZE 32768ul // e.g., up to 96k
|
||||
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) || IS_GxEPD2_4C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
|
||||
#endif
|
||||
// adapt the constructor parameters to your wiring
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=10*/ EPD_CS, /*DC=*/8, /*RST=*/9, /*BUSY=*/7));
|
||||
#undef MAX_DISPLAY_BUFFER_SIZE
|
||||
#undef MAX_HEIGHT
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_SAMD)
|
||||
#define MAX_DISPLAY_BUFFER_SIZE 15000ul // ~15k is a good compromise
|
||||
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) || IS_GxEPD2_4C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
|
||||
#endif
|
||||
// adapt the constructor parameters to your wiring
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=4*/ 4, /*DC=*/7, /*RST=*/6, /*BUSY=*/5));
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=4*/ 4, /*DC=*/ 3, /*RST=*/ 2, /*BUSY=*/ 1)); // my Seed XIOA0
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=4*/ 3, /*DC=*/ 2, /*RST=*/ 1, /*BUSY=*/ 0)); // my other Seed XIOA0
|
||||
#undef MAX_DISPLAY_BUFFER_SIZE
|
||||
#undef MAX_HEIGHT
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_RP2040)
|
||||
#define MAX_DISPLAY_BUFFER_SIZE 131072ul // e.g. half of available ram
|
||||
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPLAY_BUFFER_SIZE / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) || IS_GxEPD2_4C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
|
||||
#elif IS_GxEPD2_7C(GxEPD2_DISPLAY_CLASS)
|
||||
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2) ? EPD::HEIGHT : (MAX_DISPLAY_BUFFER_SIZE) / (EPD::WIDTH / 2))
|
||||
#endif
|
||||
#if defined(ARDUINO_NANO_RP2040_CONNECT)
|
||||
// adapt the constructor parameters to your wiring
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/EPD_CS, /*DC=*/8, /*RST=*/9, /*BUSY=*/7));
|
||||
#endif
|
||||
#if defined(ARDUINO_RASPBERRY_PI_PICO)
|
||||
// adapt the constructor parameters to your wiring
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ EPD_CS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); // my proto board
|
||||
// mapping of GoodDisplay DESPI-PICO. NOTE: uses alternate HW SPI pins!
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/3, /*DC=*/2, /*RST=*/1, /*BUSY=*/0)); // DESPI-PICO
|
||||
// GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, MAX_HEIGHT(GxEPD2_DRIVER_CLASS)> display(GxEPD2_DRIVER_CLASS(/*CS=*/ 3, /*DC=*/ 2, /*RST=*/ 11, /*BUSY=*/ 10)); // DESPI-PICO modified
|
||||
#endif
|
||||
#undef MAX_DISPLAY_BUFFER_SIZE
|
||||
#undef MAX_HEIGHT
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,106 +0,0 @@
|
|||
// Display Library example for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
|
||||
// Requires HW SPI and Adafruit_GFX. Caution: the e-paper panels require 3.3V supply AND data lines!
|
||||
//
|
||||
// Display Library based on Demo Example from Good Display: http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html
|
||||
//
|
||||
// Author: Jean-Marc Zingg
|
||||
//
|
||||
// Version: see library.properties
|
||||
//
|
||||
// Library: https://github.com/ZinggJM/GxEPD2
|
||||
|
||||
// Supporting Arduino Forum Topics:
|
||||
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
|
||||
// Good Display ePaper for Arduino: https://forum.arduino.cc/index.php?topic=436411.0
|
||||
|
||||
#define GxEPD2_102_IS_BW true
|
||||
#define GxEPD2_150_BN_IS_BW true
|
||||
#define GxEPD2_154_IS_BW true
|
||||
#define GxEPD2_154_D67_IS_BW true
|
||||
#define GxEPD2_154_T8_IS_BW true
|
||||
#define GxEPD2_154_M09_IS_BW true
|
||||
#define GxEPD2_154_M10_IS_BW true
|
||||
#define GxEPD2_154_GDEY0154D67_IS_BW true
|
||||
#define GxEPD2_213_IS_BW true
|
||||
#define GxEPD2_213_B72_IS_BW true
|
||||
#define GxEPD2_213_B73_IS_BW true
|
||||
#define GxEPD2_213_B74_IS_BW true
|
||||
#define GxEPD2_213_flex_IS_BW true
|
||||
#define GxEPD2_213_M21_IS_BW true
|
||||
#define GxEPD2_213_T5D_IS_BW true
|
||||
#define GxEPD2_213_BN_IS_BW true
|
||||
#define GxEPD2_213_GDEY0213B74_IS_BW true
|
||||
#define GxEPD2_260_IS_BW true
|
||||
#define GxEPD2_260_M01_IS_BW true
|
||||
#define GxEPD2_266_BN_IS_BW true
|
||||
#define GxEPD2_266_GDEY0266T90_IS_BW true
|
||||
#define GxEPD2_270_IS_BW true
|
||||
#define GxEPD2_270_GDEY027T91_IS_BW true
|
||||
#define GxEPD2_290_IS_BW true
|
||||
#define GxEPD2_290_T5_IS_BW true
|
||||
#define GxEPD2_290_T5D_IS_BW true
|
||||
#define GxEPD2_290_I6FD_IS_BW true
|
||||
#define GxEPD2_290_T94_IS_BW true
|
||||
#define GxEPD2_290_T94_V2_IS_BW true
|
||||
#define GxEPD2_290_BS_IS_BW true
|
||||
#define GxEPD2_290_M06_IS_BW true
|
||||
#define GxEPD2_290_GDEY029T94_IS_BW true
|
||||
#define GxEPD2_371_IS_BW true
|
||||
#define GxEPD2_370_TC1_IS_BW true
|
||||
#define GxEPD2_420_IS_BW true
|
||||
#define GxEPD2_420_M01_IS_BW true
|
||||
#define GxEPD2_420_GDEY042T91_IS_BW true
|
||||
#define GxEPD2_583_IS_BW true
|
||||
#define GxEPD2_583_T8_IS_BW true
|
||||
#define GxEPD2_583_GDEQ0583T31_IS_BW true
|
||||
#define GxEPD2_750_IS_BW true
|
||||
#define GxEPD2_750_T7_IS_BW true
|
||||
#define GxEPD2_750_YT7_IS_BW true
|
||||
#define GxEPD2_1160_T91_IS_BW true
|
||||
#define GxEPD2_1248_IS_BW true
|
||||
#define GxEPD2_it60_IS_BW true
|
||||
#define GxEPD2_it60_1448x1072_IS_BW true
|
||||
#define GxEPD2_it78_1872x1404_IS_BW true
|
||||
#define GxEPD2_it103_1872x1404_IS_BW true
|
||||
// 3-color e-papers
|
||||
#define GxEPD2_154c_IS_3C true
|
||||
#define GxEPD2_154_Z90c_IS_3C true
|
||||
#define GxEPD2_213c_IS_3C true
|
||||
#define GxEPD2_213_Z19c_IS_3C true
|
||||
#define GxEPD2_213_Z98c_IS_3C true
|
||||
#define GxEPD2_266c_IS_3C true
|
||||
#define GxEPD2_270c_IS_3C true
|
||||
#define GxEPD2_290c_IS_3C true
|
||||
#define GxEPD2_290_Z13c_IS_3C true
|
||||
#define GxEPD2_290_C90c_IS_3C true
|
||||
#define GxEPD2_420c_IS_3C true
|
||||
#define GxEPD2_420c_Z21_IS_3C true
|
||||
#define GxEPD2_583c_IS_3C true
|
||||
#define GxEPD2_583c_Z83_IS_3C true
|
||||
#define GxEPD2_750c_IS_3C true
|
||||
#define GxEPD2_750c_Z08_IS_3C true
|
||||
#define GxEPD2_750c_Z90_IS_3C true
|
||||
#define GxEPD2_1248c_IS_3C true
|
||||
// 4-color e-paper
|
||||
#define GxEPD2_437c_IS_4C true
|
||||
// 7-color e-paper
|
||||
#define GxEPD2_565c_IS_7C true
|
||||
#define GxEPD2_730c_GDEY073D46_IS_7C true
|
||||
|
||||
#if defined(GxEPD2_DISPLAY_CLASS) && defined(GxEPD2_DRIVER_CLASS)
|
||||
#define IS_GxEPD2_DRIVER(c, x) (c##x)
|
||||
#define IS_GxEPD2_DRIVER_BW(x) IS_GxEPD2_DRIVER(x, _IS_BW)
|
||||
#define IS_GxEPD2_DRIVER_3C(x) IS_GxEPD2_DRIVER(x, _IS_3C)
|
||||
#define IS_GxEPD2_DRIVER_4C(x) IS_GxEPD2_DRIVER(x, _IS_4C)
|
||||
#define IS_GxEPD2_DRIVER_7C(x) IS_GxEPD2_DRIVER(x, _IS_7C)
|
||||
#if IS_GxEPD2_BW(GxEPD2_DISPLAY_CLASS) && IS_GxEPD2_DRIVER_3C(GxEPD2_DRIVER_CLASS)
|
||||
#error "GxEPD2_BW used with 3-color driver class"
|
||||
#endif
|
||||
#if IS_GxEPD2_3C(GxEPD2_DISPLAY_CLASS) && IS_GxEPD2_DRIVER_BW(GxEPD2_DRIVER_CLASS)
|
||||
#error "GxEPD2_3C used with b/w driver class"
|
||||
#endif
|
||||
#if !IS_GxEPD2_DRIVER_BW(GxEPD2_DRIVER_CLASS) && !IS_GxEPD2_DRIVER_3C(GxEPD2_DRIVER_CLASS) && !IS_GxEPD2_DRIVER_4C(GxEPD2_DRIVER_CLASS) && !IS_GxEPD2_DRIVER_7C(GxEPD2_DRIVER_CLASS)
|
||||
#error "neither BW nor 3C nor 4C nor 7C kind defined for driver class (error in GxEPD2_selection_check.h)"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,83 +0,0 @@
|
|||
// Display Library example for SPI e-paper panels from Dalian Good Display and boards from Waveshare.
|
||||
// Requires HW SPI and Adafruit_GFX. Caution: the e-paper panels require 3.3V supply AND data lines!
|
||||
//
|
||||
// Display Library based on Demo Example from Good Display: http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html
|
||||
//
|
||||
// Author: Jean-Marc Zingg
|
||||
//
|
||||
// Version: see library.properties
|
||||
//
|
||||
// Library: https://github.com/ZinggJM/GxEPD2
|
||||
|
||||
// Supporting Arduino Forum Topics:
|
||||
// Waveshare e-paper displays with SPI: http://forum.arduino.cc/index.php?topic=487007.0
|
||||
// Good Display ePaper for Arduino: https://forum.arduino.cc/index.php?topic=436411.0
|
||||
|
||||
// mapping suggestion from Waveshare SPI e-Paper to Wemos D1 mini
|
||||
// BUSY -> D2, RST -> D4, DC -> D3, CS -> D8, CLK -> D5, DIN -> D7, GND -> GND, 3.3V -> 3.3V
|
||||
// NOTE: connect 3.3k pull-down from D8 to GND if your board or shield has level converters
|
||||
// NOTE for ESP8266: using SS (GPIO15) for CS may cause boot mode problems, use different pin in case, or 4k7 pull-down
|
||||
// NOTE: connect 1k pull-up from D4 (RST) to 3.3V if your board or shield has the "clever" reset circuit, or use a different pin
|
||||
|
||||
// mapping suggestion from Waveshare SPI e-Paper to generic ESP8266
|
||||
// BUSY -> GPIO4, RST -> GPIO2, DC -> GPIO0, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
|
||||
// NOTE: connect 3.3k pull-down from GPIO15 to GND if your board or shield has level converters
|
||||
// NOTE for ESP8266: using SS (GPIO15) for CS may cause boot mode problems, use different pin in case, or 3.3k pull-down
|
||||
// NOTE: connect 1k pull-up from GPIO2 (RST) to 3.3V if your board or shield has the "clever" reset circuit, or use a different pin
|
||||
|
||||
// mapping of Waveshare e-Paper ESP8266 Driver Board, new version
|
||||
// BUSY -> GPIO5, RST -> GPIO2, DC -> GPIO4, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
|
||||
// NOTE for ESP8266: using SS (GPIO15) for CS may cause boot mode problems, add a 3.3k pull-down in case
|
||||
// the e-Paper ESP8266 Driver Board should have no boot mode issue, as it doesn't use level converters
|
||||
|
||||
// mapping of Waveshare e-Paper ESP8266 Driver Board, old version
|
||||
// BUSY -> GPIO16, RST -> GPIO5, DC -> GPIO4, CS -> GPIO15, CLK -> GPIO14, DIN -> GPIO13, GND -> GND, 3.3V -> 3.3V
|
||||
// NOTE for ESP8266: using SS (GPIO15) for CS may cause boot mode problems, add a 3.3k pull-down in case
|
||||
// the e-Paper ESP8266 Driver Board should have no boot mode issue, as it doesn't use level converters
|
||||
|
||||
// mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board
|
||||
// NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD
|
||||
// BUSY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
|
||||
|
||||
// mapping of Waveshare ESP32 Driver Board
|
||||
// BUSY -> 25, RST -> 26, DC -> 27, CS-> 15, CLK -> 13, DIN -> 14
|
||||
// NOTE: this board uses "unusual" SPI pins and requires re-mapping of HW SPI to these pins in SPIClass
|
||||
// see example GxEPD2_WS_ESP32_Driver.ino, it shows how this can be done easily
|
||||
|
||||
// mapping suggestion for ESP32, e.g. LOLIN32 D32 PRO
|
||||
// BUSY -> 15, RST -> 2, DC -> 0, CS -> 5, CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
|
||||
// note: use explicit value for CS, as SS is re-defined to TF_CS(4) in pins_arduino.h for Board: "LOLIN D32 PRO"
|
||||
|
||||
// mapping suggestion for ESP32, e.g. TTGO T8 ESP32-WROVER
|
||||
// BUSY -> 4, RST -> 0, DC -> 2, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V
|
||||
// for use with Board: "ESP32 Dev Module":
|
||||
|
||||
// new mapping suggestion for STM32F1, e.g. STM32F103C8T6 "BluePill"
|
||||
// BUSY -> A1, RST -> A2, DC -> A3, CS-> A4, CLK -> A5, DIN -> A7
|
||||
|
||||
// mapping suggestion for AVR, UNO, NANO etc.
|
||||
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
|
||||
|
||||
// mapping suggestion for AVR, Arduino Micro, Leonardo
|
||||
// note: on Leonardo board HW SPI pins are on 6-pin ICSP header
|
||||
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 15, DIN -> 16
|
||||
|
||||
// mapping of Waveshare Universal e-Paper Raw Panel Driver Shield for Arduino / NUCLEO
|
||||
// BUSY -> 7, RST -> 8, DC -> 9, CS-> 10, CLK -> 13, DIN -> 11
|
||||
|
||||
// mapping suggestion for Arduino MEGA
|
||||
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 53, CLK -> 52, DIN -> 51
|
||||
|
||||
// mapping suggestion for Arduino DUE, note: pin 77 is on board pin 10, SS is 10
|
||||
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 76, DIN -> 75
|
||||
// SPI pins are on 6 pin 2x3 SPI header, no SS on SPI header!
|
||||
|
||||
// mapping suggestion for Arduino MKR1000 or MKRZERO
|
||||
// note: can't use SS on MKR1000: is defined as 24, should be 4
|
||||
// BUSY -> 5, RST -> 6, DC -> 7, CS-> 4, CLK -> 9, DIN -> 8
|
||||
|
||||
// mapping suggestion for Arduino Nano RP2040 Connect
|
||||
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 10, CLK -> 13, DIN -> 11
|
||||
|
||||
// mapping suggestion for Raspberry Pi Pico RP2040
|
||||
// BUSY -> 7, RST -> 9, DC -> 8, CS-> 5, CLK -> 2, DIN -> 3
|
36
firmware/include/button.h
Normal file
36
firmware/include/button.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef ATMBUTTON_H
|
||||
#define ATMBUTTON_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class AtmButton {
|
||||
private:
|
||||
|
||||
uint8_t pin, ledPin;
|
||||
uint8_t ledState = LEDOFF;
|
||||
volatile bool pressed = false;
|
||||
volatile unsigned long last_pressed_ms = 0;
|
||||
volatile unsigned long pressed_at_ms = 0;
|
||||
volatile unsigned long pressed_after_ms = 0;
|
||||
|
||||
bool activeWaiting = false;
|
||||
unsigned long startWaitTime = 0;
|
||||
unsigned long lastWaitLedToggle = 0;
|
||||
|
||||
static void IRAM_ATTR buttonIsrHandler(void* arg); // Interrupt Service Routine (ISR)
|
||||
|
||||
public:
|
||||
const uint8_t LEDON = HIGH;
|
||||
const uint8_t LEDOFF = LOW;
|
||||
const unsigned long DEBOUNCE_BUTTON_MS = 200; // wait that number of ms before counting the button pressed pulse -> debouncing
|
||||
|
||||
AtmButton(uint8_t, uint8_t );
|
||||
void begin();
|
||||
bool wasPressed();
|
||||
void ledOn();
|
||||
void ledOff();
|
||||
void ledToggle();
|
||||
bool iswaitingUntilPressed(unsigned long maxTimeToWaitMs, unsigned long blinkPeriodMs);
|
||||
};
|
||||
|
||||
#endif
|
36
firmware/include/coinacceptor.h
Normal file
36
firmware/include/coinacceptor.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef COINACCEPTOR_H
|
||||
#define COINACCEPTOR_H
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
class CoinAcceptor {
|
||||
private:
|
||||
uint8_t pulsePin, enablePin;
|
||||
uint8_t accState = ACC_DISABLED;
|
||||
|
||||
volatile uint16_t coinPulses = 0;
|
||||
uint16_t coinValue = 0;
|
||||
volatile bool coinDetected = false;
|
||||
volatile unsigned long lastPulseAtMs = 0;
|
||||
static void IRAM_ATTR pulseIsrHandler(void* arg);
|
||||
|
||||
public:
|
||||
const uint8_t ACC_DISABLED = LOW;
|
||||
const uint8_t ACC_ENABLED = HIGH;
|
||||
const unsigned int* pulseValues;
|
||||
const size_t maxPulses = 0;
|
||||
const uint8_t pulseWidthMs = 0;
|
||||
uint8_t detectionError = 0;
|
||||
|
||||
CoinAcceptor(uint8_t pulsePin, uint8_t enablePin, const unsigned int* pulseValues, const size_t maxPulses, const uint8_t pulseWidthMs );
|
||||
void begin();
|
||||
void disable();
|
||||
void enable();
|
||||
uint8_t state();
|
||||
bool detectCoin();
|
||||
uint16_t getCoinValue();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
72
firmware/include/epaperdisplay.h
Normal file
72
firmware/include/epaperdisplay.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
#ifndef EPAPERDISPLAY_H
|
||||
#define EPAPERDISPLAY_H
|
||||
|
||||
#include <GxEPD2_BW.h>
|
||||
|
||||
|
||||
#undef USE_HSPI_FOR_EPD
|
||||
#define GxEPD2_DRIVER_CLASS GxEPD2_420 // 4.2 inch Waveshare e-paper display
|
||||
#define GxEPD2_DISPLAY_CLASS GxEPD2_BW<GxEPD2_DRIVER_CLASS, GxEPD2_DRIVER_CLASS::HEIGHT> // Black and White e-Paper
|
||||
static const char* display_type = "GxEPD2_420";
|
||||
|
||||
class EpaperDisplay
|
||||
{
|
||||
private:
|
||||
GxEPD2_DISPLAY_CLASS *epDisplay;
|
||||
|
||||
public:
|
||||
|
||||
EpaperDisplay(uint8_t DSPLY_PIN_CS, uint8_t DSPLY_PIN_DC, uint8_t DSPLY_PIN_RST, uint8_t DSPLY_PIN_BUSY);
|
||||
~EpaperDisplay();
|
||||
void init();
|
||||
void sleep();
|
||||
void homeScreen();
|
||||
void showInsertedAmount(const char*);
|
||||
void updateInsertedAmount(const char*);
|
||||
|
||||
void cleanScreen();
|
||||
void drawText(const char* text, uint8_t textSize, uint16_t x, uint16_t y, uint16_t fgColor, uint16_t bgColor );
|
||||
void drawText(const char* text, uint16_t x, uint16_t y);
|
||||
void updateText(const char* text, uint16_t x, uint16_t y);
|
||||
void updateText(const char* text, uint8_t textSize, uint16_t x, uint16_t y, uint16_t fgColor, uint16_t bgColor);
|
||||
|
||||
};
|
||||
|
||||
// Bitcoin Logo
|
||||
const unsigned char bitcoin_logo[] PROGMEM = {
|
||||
// 'bitcoin64, 64x64px
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
|
||||
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x7f, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x1f, 0xff, 0xfc, 0x63, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x63, 0xff, 0xfc, 0x00,
|
||||
0x00, 0x7f, 0xfe, 0x38, 0xe3, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0xe3, 0xff, 0xfe, 0x00,
|
||||
0x00, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0x00,
|
||||
0x00, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0x80,
|
||||
0x01, 0xff, 0xff, 0xc1, 0xe0, 0x3f, 0xff, 0x80, 0x01, 0xff, 0xff, 0x81, 0xf8, 0x1f, 0xff, 0x80,
|
||||
0x03, 0xff, 0xff, 0x83, 0xf8, 0x1f, 0xff, 0xc0, 0x03, 0xff, 0xff, 0x83, 0xf8, 0x1f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xff, 0x83, 0xf8, 0x1f, 0xff, 0xc0, 0x03, 0xff, 0xff, 0x01, 0xf0, 0x1f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xfe, 0x07, 0xc0, 0x7f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xfe, 0x0f, 0xe0, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfe, 0x0f, 0xf0, 0x3f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xec, 0x0f, 0xf0, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xe0, 0x0f, 0xf0, 0x3f, 0xff, 0xc0,
|
||||
0x01, 0xff, 0xc0, 0x0f, 0xf0, 0x3f, 0xff, 0x80, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0x80,
|
||||
0x01, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0x00,
|
||||
0x00, 0xff, 0xfe, 0x30, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 0x38, 0xc7, 0xff, 0xff, 0x00,
|
||||
0x00, 0x7f, 0xfe, 0x31, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xfc, 0x31, 0xff, 0xff, 0xfe, 0x00,
|
||||
0x00, 0x3f, 0xff, 0xf1, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xf1, 0xff, 0xff, 0xf8, 0x00,
|
||||
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
|
||||
#endif
|
|
@ -1,146 +0,0 @@
|
|||
#ifndef LIGHTNING_ATM_H
|
||||
#define LIGHTNING_ATM_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <GxEPD2_BW.h>
|
||||
#include <Fonts/FreeMonoBold9pt7b.h>
|
||||
#include "qrcode.h"
|
||||
#include "Bitcoin.h"
|
||||
#include <stdlib.h>
|
||||
#include <Hash.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// ########################################
|
||||
// ########### USER ACTION ###########
|
||||
// ########################################
|
||||
// Generate and copy in LNbits with the LNURLDevice extension the string for the ATM and paste it here:
|
||||
const char* lnurlDeviceString = "https://legend.lnbits.com/lnurldevice/api/v1/lnurl/idexample,keyexample,EUR";
|
||||
// #################### EXAMPLE: https://legend.lnbits.com/lnurldevice/api/v1/lnurl/idexample,keyexample,EUR
|
||||
// ########################################
|
||||
// ########################################
|
||||
// ########################################
|
||||
|
||||
// Activate for debugging over Serial (1), deactivate in production use (0)
|
||||
#define DEBUG_MODE 1
|
||||
|
||||
#define COIN_PIN 17
|
||||
#define PULSE_TIMEOUT 200
|
||||
#define LED_BUTTON_PIN 21 // old: 13 | new: 21
|
||||
#define BUTTON_PIN 32
|
||||
#define MOSFET_PIN 16 // old: 12 | new: 16
|
||||
#define QR_VERSION 6 // 20 is standard. 6 for simpler QR code, but does not always work.
|
||||
|
||||
#define DSPLY_PIN_CS 26
|
||||
#define DSPLY_PIN_DC 25
|
||||
#define DSPLY_PIN_RST 33
|
||||
#define DSPLY_PIN_BUSY 27
|
||||
#define DSPLY_PIN_CLK 18 // SCK pin SPI
|
||||
#define DSPLY_PIN_DIN 23 // MOSI pin SPI
|
||||
|
||||
// Folowing #defines are Taken from :
|
||||
//#include "GxEPD2_display_selection_new_style.h"
|
||||
const uint8_t nr_supported_display_types = 6;
|
||||
const char* supported_display_types[nr_supported_display_types] = {"GxEPD2_420", "GxEPD2_150_BN", "GxEPD2_270", "GxEPD2_270_GDEY027T91", "GxEPD2_213_B74", "GxEPD2_213_flex"};
|
||||
|
||||
#undef USE_HSPI_FOR_EPD
|
||||
#define GxEPD2_DISPLAY_CLASS GxEPD2_BW // Black and White e-Paper
|
||||
#define GxEPD2_DRIVER_CLASS GxEPD2_420 // 4.2 inch Waveshare e-paper display
|
||||
//#define GxEPD2_DRIVER_CLASS GxEPD2_150_BN // 1.54 inch Waveshare e-paper display
|
||||
const char* display_type = "GxEPD2_420";
|
||||
|
||||
// Treiber für das 4.2" Schwarz-Weiß E-Paper
|
||||
GxEPD2_DISPLAY_CLASS<GxEPD2_DRIVER_CLASS, GxEPD2_DRIVER_CLASS::HEIGHT> display(GxEPD2_DRIVER_CLASS(DSPLY_PIN_CS, DSPLY_PIN_DC, DSPLY_PIN_RST, DSPLY_PIN_BUSY)); // Waveshare ESP32 Driver Board
|
||||
|
||||
typedef struct s_qrdata
|
||||
{
|
||||
uint8_t current_y;
|
||||
uint8_t current_x;
|
||||
uint8_t start_x;
|
||||
uint8_t start_y;
|
||||
uint8_t module_size;
|
||||
uint8_t qr_size;
|
||||
} t_qrdata;
|
||||
|
||||
extern String baseURLATM;
|
||||
extern String secretATM;
|
||||
extern String currencyATM;
|
||||
|
||||
// Bitcoin Logo
|
||||
const unsigned char bitcoin_logo[] PROGMEM = {
|
||||
// 'bitcoin64, 64x64px
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
|
||||
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x7f, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x1f, 0xff, 0xfc, 0x63, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x63, 0xff, 0xfc, 0x00,
|
||||
0x00, 0x7f, 0xfe, 0x38, 0xe3, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0xe3, 0xff, 0xfe, 0x00,
|
||||
0x00, 0xff, 0xfe, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0x00,
|
||||
0x00, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0x80,
|
||||
0x01, 0xff, 0xff, 0xc1, 0xe0, 0x3f, 0xff, 0x80, 0x01, 0xff, 0xff, 0x81, 0xf8, 0x1f, 0xff, 0x80,
|
||||
0x03, 0xff, 0xff, 0x83, 0xf8, 0x1f, 0xff, 0xc0, 0x03, 0xff, 0xff, 0x83, 0xf8, 0x1f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xff, 0x83, 0xf8, 0x1f, 0xff, 0xc0, 0x03, 0xff, 0xff, 0x01, 0xf0, 0x1f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xfe, 0x07, 0xc0, 0x7f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xfe, 0x0f, 0xe0, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfe, 0x0f, 0xf0, 0x3f, 0xff, 0xc0,
|
||||
0x03, 0xff, 0xec, 0x0f, 0xf0, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xe0, 0x0f, 0xf0, 0x3f, 0xff, 0xc0,
|
||||
0x01, 0xff, 0xc0, 0x0f, 0xf0, 0x3f, 0xff, 0x80, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0x80,
|
||||
0x01, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0x00,
|
||||
0x00, 0xff, 0xfe, 0x30, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 0x38, 0xc7, 0xff, 0xff, 0x00,
|
||||
0x00, 0x7f, 0xfe, 0x31, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xfc, 0x31, 0xff, 0xff, 0xfe, 0x00,
|
||||
0x00, 0x3f, 0xff, 0xf1, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xf1, 0xff, 0xff, 0xf8, 0x00,
|
||||
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
// put function declarations here:
|
||||
void clean_screen();
|
||||
void initialize_display();
|
||||
void to_upper(char* arr);
|
||||
void qr_withdrawl_screen(const char* qr_content);
|
||||
char* makeLNURL(float total);
|
||||
int xor_encrypt(uint8_t* output, size_t outlen, uint8_t* key, size_t keylen, uint8_t* nonce, size_t nonce_len, uint64_t pin, uint64_t amount_in_cents);
|
||||
void show_inserted_amount(int amount_in_cents);
|
||||
String get_amount_string(int amount_in_cents);
|
||||
unsigned int detect_coin();
|
||||
void home_screen();
|
||||
void IRAM_ATTR button_pressed_itr();
|
||||
void wait_for_user_to_scan();
|
||||
String getValue(String data, char separator, int index);
|
||||
void display_sleep();
|
||||
void test_macro();
|
||||
|
||||
// Waveshare 1.54 inch e-ink display functions
|
||||
void home_screen_waveshare_1_54();
|
||||
void show_inserted_amount_waveshare_1_54(String amount_in_euro);
|
||||
void qr_withdrawl_screen_waveshare_1_54(const char* qr_content);
|
||||
void clean_screen_waveshare_1_54();
|
||||
|
||||
// Waveshare 2.7 inch e-ink display functions
|
||||
void home_screen_waveshare_2_7();
|
||||
void show_inserted_amount_waveshare_2_7(String amount_in_euro);
|
||||
void qr_withdrawl_screen_waveshare_2_7(const char* qr_content);
|
||||
void clean_screen_waveshare_2_7();
|
||||
|
||||
// Waveshare 2.13 inch e-ink display (250x122) functions
|
||||
void home_screen_waveshare_2_13();
|
||||
void show_inserted_amount_waveshare_2_13(String amount_in_euro);
|
||||
void qr_withdrawl_screen_waveshare_2_13(const char* qr_content);
|
||||
void clean_screen_waveshare_2_13();
|
||||
|
||||
// Waveshare 2.13 inch e-ink display (D) flex (yellow) (212x104) functions
|
||||
void home_screen_waveshare_2_13_flex();
|
||||
void show_inserted_amount_waveshare_2_13_flex(String amount_in_euro);
|
||||
void qr_withdrawl_screen_waveshare_2_13_flex(const char* qr_content);
|
||||
void clean_screen_waveshare_2_13_flex();
|
||||
|
||||
#endif
|
100
firmware/include/main.h
Normal file
100
firmware/include/main.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <GxEPD2_BW.h>
|
||||
#include <Fonts/FreeMonoBold9pt7b.h>
|
||||
#include "qrcode.h"
|
||||
#include "Bitcoin.h"
|
||||
#include <stdlib.h>
|
||||
#include <Hash.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// ########################################
|
||||
// ########### USER ACTION ###########
|
||||
// ########################################
|
||||
// Generate and copy in LNbits with the LNURLDevice extension the string for the ATM and paste it here:
|
||||
const char* lnurlDeviceString = "https://legend.lnbits.com/lnurldevice/api/v1/lnurl/idexample,keyexample,EUR";
|
||||
// #################### EXAMPLE: https://legend.lnbits.com/lnurldevice/api/v1/lnurl/idexample,keyexample,EUR
|
||||
// ########################################
|
||||
// ########################################
|
||||
// ########################################
|
||||
|
||||
// Activate for debugging over Serial (1), deactivate in production use (0)
|
||||
#define DEBUG_MODE 1
|
||||
|
||||
#define COIN_PIN 17
|
||||
|
||||
#define PULSE_TIMEOUT 200
|
||||
const uint8_t LED_BUTTON_PIN = 21; // old: 13 | new: 21
|
||||
const uint8_t BUTTON_PIN = 32;
|
||||
#define MOSFET_PIN 16 // old: 12 | new: 16
|
||||
#define QR_VERSION 6 // 20 is standard. 6 for simpler QR code, but does not always work.
|
||||
|
||||
const uint8_t DSPLY_PIN_CS = 26;
|
||||
const uint8_t DSPLY_PIN_DC = 25;
|
||||
const uint8_t DSPLY_PIN_RST = 33;
|
||||
const uint8_t DSPLY_PIN_BUSY = 27;
|
||||
|
||||
constexpr unsigned int COINS[] = { 1, 2, 5, 10, 20, 50, 100, 200};
|
||||
constexpr size_t COINS_COUNT = sizeof(COINS) / sizeof(COINS[0]);
|
||||
const unsigned long COIN_PULSE_WIDTH_MS = 45;
|
||||
|
||||
typedef struct s_qrdata
|
||||
{
|
||||
uint8_t current_y;
|
||||
uint8_t current_x;
|
||||
uint8_t start_x;
|
||||
uint8_t start_y;
|
||||
uint8_t module_size;
|
||||
uint8_t qr_size;
|
||||
} t_qrdata;
|
||||
|
||||
extern String baseURLATM;
|
||||
extern String secretATM;
|
||||
extern String currencyATM;
|
||||
|
||||
|
||||
// put function declarations here:
|
||||
void clean_screen();
|
||||
void initialize_display();
|
||||
void to_upper(char* arr);
|
||||
void qr_withdrawl_screen(const char* qr_content);
|
||||
char* makeLNURL(float total);
|
||||
int xor_encrypt(uint8_t* output, size_t outlen, uint8_t* key, size_t keylen, uint8_t* nonce, size_t nonce_len, uint64_t pin, uint64_t amount_in_cents);
|
||||
void show_inserted_amount(int amount_in_cents);
|
||||
String get_amount_string(int amount_in_cents);
|
||||
unsigned int detect_coin();
|
||||
void home_screen();
|
||||
void IRAM_ATTR button_pressed_itr();
|
||||
void wait_for_user_to_scan();
|
||||
String getValue(String data, char separator, int index);
|
||||
void display_sleep();
|
||||
void test_macro();
|
||||
|
||||
// Waveshare 1.54 inch e-ink display functions
|
||||
void home_screen_waveshare_1_54();
|
||||
void show_inserted_amount_waveshare_1_54(String amount_in_euro);
|
||||
void qr_withdrawl_screen_waveshare_1_54(const char* qr_content);
|
||||
void clean_screen_waveshare_1_54();
|
||||
|
||||
// Waveshare 2.7 inch e-ink display functions
|
||||
void home_screen_waveshare_2_7();
|
||||
void show_inserted_amount_waveshare_2_7(String amount_in_euro);
|
||||
void qr_withdrawl_screen_waveshare_2_7(const char* qr_content);
|
||||
void clean_screen_waveshare_2_7();
|
||||
|
||||
// Waveshare 2.13 inch e-ink display (250x122) functions
|
||||
void home_screen_waveshare_2_13();
|
||||
void show_inserted_amount_waveshare_2_13(String amount_in_euro);
|
||||
void qr_withdrawl_screen_waveshare_2_13(const char* qr_content);
|
||||
void clean_screen_waveshare_2_13();
|
||||
|
||||
// Waveshare 2.13 inch e-ink display (D) flex (yellow) (212x104) functions
|
||||
void home_screen_waveshare_2_13_flex();
|
||||
void show_inserted_amount_waveshare_2_13_flex(String amount_in_euro);
|
||||
void qr_withdrawl_screen_waveshare_2_13_flex(const char* qr_content);
|
||||
void clean_screen_waveshare_2_13_flex();
|
||||
|
||||
#endif
|
81
firmware/src/button.cpp
Normal file
81
firmware/src/button.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
#include "button.h"
|
||||
|
||||
// Konstruktor
|
||||
AtmButton::AtmButton(uint8_t buttonPin, uint8_t buttonLedPin) : pin(buttonPin), ledPin(buttonLedPin), pressed(false) {}
|
||||
|
||||
// Initialisierung des Pins & Interrupts
|
||||
void AtmButton::begin() {
|
||||
pinMode(ledPin, OUTPUT);
|
||||
pinMode(pin, INPUT_PULLUP);
|
||||
ledOff();
|
||||
attachInterruptArg(digitalPinToInterrupt(pin), buttonIsrHandler, this, FALLING);
|
||||
}
|
||||
|
||||
void IRAM_ATTR AtmButton::buttonIsrHandler(void* arg) {
|
||||
AtmButton* self = static_cast<AtmButton*>(arg);
|
||||
unsigned long current_ms = millis();
|
||||
if((false == self->pressed) && ((current_ms - self->last_pressed_ms) > self->DEBOUNCE_BUTTON_MS))
|
||||
{
|
||||
self->pressed = true;
|
||||
self->pressed_at_ms = current_ms;
|
||||
self->pressed_after_ms = current_ms - self->last_pressed_ms;
|
||||
self->last_pressed_ms = current_ms;
|
||||
}
|
||||
self->pressed = true;
|
||||
}
|
||||
|
||||
bool AtmButton::wasPressed() {
|
||||
if (pressed) {
|
||||
pressed = false; // Reset des Status
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AtmButton::ledOn() {
|
||||
digitalWrite(ledPin, LEDON);
|
||||
ledState = LEDON;
|
||||
}
|
||||
|
||||
void AtmButton::ledOff() {
|
||||
digitalWrite(ledPin, LEDOFF);
|
||||
ledState = LEDOFF;
|
||||
}
|
||||
|
||||
void AtmButton::ledToggle() {
|
||||
ledState = (LEDON == ledState) ? LEDOFF : LEDON;
|
||||
digitalWrite(ledPin, ledState);
|
||||
}
|
||||
|
||||
bool AtmButton::iswaitingUntilPressed(unsigned long maxTimeToWaitMs, unsigned long blinkPeriodMs)
|
||||
{
|
||||
/* will return as longs as waiting until the button is pressed */
|
||||
/* if blinkPeriodMs is 0 - there is no LED blinking */
|
||||
unsigned long currentMs = millis();
|
||||
|
||||
if(false == activeWaiting)
|
||||
{
|
||||
activeWaiting = true;
|
||||
pressed = false;
|
||||
startWaitTime = currentMs;
|
||||
lastWaitLedToggle = currentMs;
|
||||
ledOn();
|
||||
}
|
||||
|
||||
if( (true == pressed) || ((currentMs - startWaitTime) >= maxTimeToWaitMs))
|
||||
{
|
||||
ledOff();
|
||||
activeWaiting = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if( (currentMs - lastWaitLedToggle) >= blinkPeriodMs )
|
||||
{
|
||||
lastWaitLedToggle = currentMs;
|
||||
ledToggle();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
84
firmware/src/coinacceptor.cpp
Normal file
84
firmware/src/coinacceptor.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include "coinacceptor.h"
|
||||
|
||||
CoinAcceptor::CoinAcceptor(uint8_t pulsePin, uint8_t enablePin, const unsigned int* pulseValues, const size_t maxPulses, const uint8_t pulseWidthMs) :
|
||||
pulsePin(pulsePin), enablePin(enablePin), pulseValues(pulseValues), maxPulses(maxPulses), pulseWidthMs(pulseWidthMs) {}
|
||||
|
||||
// Initialisierung des Pins & Interrupts
|
||||
void CoinAcceptor::begin() {
|
||||
pinMode(enablePin, OUTPUT);
|
||||
pinMode(pulsePin, INPUT_PULLUP);
|
||||
disable();
|
||||
if(digitalRead(pulsePin) == HIGH)
|
||||
{
|
||||
Serial.println("Attaching interrupt to falling edge of coin acceptor pulse pin.");
|
||||
attachInterruptArg(digitalPinToInterrupt(pulsePin), pulseIsrHandler, this, FALLING);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Attaching interrupt to rising edge of coin acceptor pulse pin.");
|
||||
attachInterruptArg(digitalPinToInterrupt(pulsePin), pulseIsrHandler, this, RISING);
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR CoinAcceptor::pulseIsrHandler(void* arg) {
|
||||
CoinAcceptor* self = static_cast<CoinAcceptor*>(arg);
|
||||
unsigned long currentMs = micros()/1000;
|
||||
if((self->lastPulseAtMs == 0) || ((currentMs - self->lastPulseAtMs) > 1.5*self->pulseWidthMs))
|
||||
{
|
||||
self->coinDetected = true;
|
||||
self->lastPulseAtMs = currentMs;
|
||||
self->coinPulses++;
|
||||
}
|
||||
}
|
||||
|
||||
void CoinAcceptor::disable() {
|
||||
accState = ACC_DISABLED;
|
||||
digitalWrite(enablePin, accState);
|
||||
}
|
||||
|
||||
void CoinAcceptor::enable() {
|
||||
accState = ACC_ENABLED;
|
||||
coinDetected = false;
|
||||
detectionError = 0;
|
||||
coinPulses = 0;
|
||||
coinValue = 0;
|
||||
lastPulseAtMs = 0;
|
||||
digitalWrite(enablePin, accState);
|
||||
}
|
||||
|
||||
uint8_t CoinAcceptor::state() {
|
||||
return accState;
|
||||
}
|
||||
|
||||
bool CoinAcceptor::detectCoin() {
|
||||
if(true == coinDetected)
|
||||
{
|
||||
disable();
|
||||
long lastPulseBeforeMs = 0;
|
||||
long maxMsSinceLastPulse = 8*pulseWidthMs;
|
||||
do
|
||||
{
|
||||
lastPulseBeforeMs = millis() - lastPulseAtMs;
|
||||
} while ((lastPulseAtMs == 0) || (lastPulseBeforeMs < maxMsSinceLastPulse ));
|
||||
Serial.printf("DONE --- Pulses: %d, Last pulse before: %d ms (max allowed: %d). \n", coinPulses, lastPulseBeforeMs, maxMsSinceLastPulse);
|
||||
// there is one additial edge in the signal ... remove it
|
||||
coinPulses--;
|
||||
if((coinPulses > 1) && (coinPulses <= maxPulses))
|
||||
{
|
||||
coinValue = pulseValues[coinPulses-1]; // coin array index is running from 0 to maxPulses-1 ...
|
||||
Serial.printf(" --- Detected coin value: %d cents\n", coinValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.printf(" ERROR --- Number of pulses doesn't match any teached coin value\n");
|
||||
detectionError++;
|
||||
}
|
||||
coinDetected = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t CoinAcceptor::getCoinValue() {
|
||||
return coinValue;
|
||||
}
|
154
firmware/src/epaperdisplay.cpp
Normal file
154
firmware/src/epaperdisplay.cpp
Normal file
|
@ -0,0 +1,154 @@
|
|||
#include "epaperdisplay.h"
|
||||
|
||||
// *** for Waveshare ESP32 Driver board *** //
|
||||
#if defined(ESP32) && defined(USE_HSPI_FOR_EPD)
|
||||
SPIClass hspi(HSPI);
|
||||
#endif
|
||||
// *** end Waveshare ESP32 Driver board *** //
|
||||
|
||||
EpaperDisplay::EpaperDisplay(uint8_t DSPLY_PIN_CS, uint8_t DSPLY_PIN_DC, uint8_t DSPLY_PIN_RST, uint8_t DSPLY_PIN_BUSY)
|
||||
{
|
||||
epDisplay = new GxEPD2_DISPLAY_CLASS(GxEPD2_DRIVER_CLASS(DSPLY_PIN_CS, DSPLY_PIN_DC, DSPLY_PIN_RST, DSPLY_PIN_BUSY));
|
||||
}
|
||||
|
||||
EpaperDisplay::~EpaperDisplay()
|
||||
{
|
||||
}
|
||||
|
||||
void EpaperDisplay::sleep()
|
||||
{
|
||||
epDisplay->hibernate();
|
||||
}
|
||||
|
||||
void EpaperDisplay::init()
|
||||
{
|
||||
epDisplay->init(115200, true, 2, false);
|
||||
// *** for Waveshare ESP32 Driver board *** //
|
||||
#if defined(ESP32) && defined(USE_HSPI_FOR_EPD)
|
||||
hspi.begin(13, 12, 14, 15); // remap hspi for EPD (swap pins)
|
||||
epDisplay>epd2.selectSPI(hspi, SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||
#endif
|
||||
epDisplay->setRotation(1);
|
||||
|
||||
}
|
||||
|
||||
void EpaperDisplay::cleanScreen()
|
||||
{
|
||||
epDisplay->firstPage();
|
||||
do{
|
||||
epDisplay->clearScreen();
|
||||
}
|
||||
while(epDisplay->nextPage());
|
||||
epDisplay->hibernate();
|
||||
}
|
||||
|
||||
void EpaperDisplay::drawText(const char* text, uint16_t x, uint16_t y)
|
||||
{
|
||||
epDisplay->setCursor(x, y);
|
||||
epDisplay->printf(text);
|
||||
}
|
||||
|
||||
void EpaperDisplay::drawText(const char* text, uint8_t textSize, uint16_t x, uint16_t y, uint16_t fgColor, uint16_t bgColor )
|
||||
{
|
||||
epDisplay->setTextSize(textSize);
|
||||
epDisplay->setTextColor(fgColor, bgColor);
|
||||
drawText(text, x, y);
|
||||
}
|
||||
|
||||
|
||||
void EpaperDisplay::updateText(const char* text, uint16_t x, uint16_t y)
|
||||
{
|
||||
int16_t xul, yul;
|
||||
uint16_t textWidth, textHeight;
|
||||
epDisplay->getTextBounds(text, x, y, &xul, &yul, &textWidth, &textHeight);
|
||||
epDisplay->setPartialWindow(xul, yul, textWidth, textHeight);
|
||||
epDisplay->firstPage();
|
||||
do
|
||||
{
|
||||
epDisplay->setCursor(x, y);
|
||||
epDisplay->printf(text);
|
||||
} while (epDisplay->nextPage());
|
||||
}
|
||||
|
||||
void EpaperDisplay::updateText(const char* text, uint8_t textSize, uint16_t x, uint16_t y, uint16_t fgColor, uint16_t bgColor)
|
||||
{
|
||||
epDisplay->setTextSize(textSize);
|
||||
epDisplay->setTextColor(fgColor, bgColor);
|
||||
updateText(text, x, y);
|
||||
}
|
||||
|
||||
|
||||
void EpaperDisplay::homeScreen()
|
||||
{
|
||||
epDisplay->setFullWindow();
|
||||
epDisplay->firstPage();
|
||||
do
|
||||
{
|
||||
drawText("Insert Euro coins\n on the right ->\n to start ATM\n", 2, 11, 20, GxEPD_BLACK, GxEPD_WHITE);
|
||||
epDisplay->drawBitmap(172, 65, bitcoin_logo, 64, 64, GxEPD_BLACK);
|
||||
drawText("Prepare Lightning enabled Bitcoin\n wallet before starting!\n Supported coins: 1 - 50 Cent, 1 - 2 Euro\n", 1, 12, 140, GxEPD_BLACK, GxEPD_WHITE);
|
||||
} while (epDisplay->nextPage());
|
||||
epDisplay->hibernate();
|
||||
}
|
||||
|
||||
void EpaperDisplay::showInsertedAmount(const char* amount_in_euro)
|
||||
{
|
||||
epDisplay->setFullWindow();
|
||||
epDisplay->firstPage();
|
||||
do
|
||||
{
|
||||
drawText("Inserted amount:\n", 2, 11, 10, GxEPD_BLACK, GxEPD_WHITE);
|
||||
drawText(amount_in_euro, 3, 20, 75, GxEPD_BLACK, GxEPD_WHITE);
|
||||
drawText("Press button\n once finished.\n", 2, 11, 135, GxEPD_BLACK, GxEPD_WHITE);
|
||||
} while (epDisplay->nextPage());
|
||||
}
|
||||
|
||||
void EpaperDisplay::updateInsertedAmount(const char* amount_in_euro)
|
||||
{
|
||||
updateText(amount_in_euro, 3, 20, 75, GxEPD_BLACK, GxEPD_WHITE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void qr_withdrawl_screen_waveshare_2_7(const char* qr_content)
|
||||
{
|
||||
QRCode qrcoded;
|
||||
uint8_t qrcodeData[qrcode_getBufferSize(QR_VERSION)]; // 20 is "qr version"
|
||||
t_qrdata qr;
|
||||
|
||||
qrcode_initText(&qrcoded, qrcodeData, QR_VERSION, 0, qr_content);
|
||||
qr.qr_size = qrcoded.size * 3;
|
||||
qr.start_x = (264 - qr.qr_size) / 2;
|
||||
qr.start_y = (176 - qr.qr_size) / 2;
|
||||
qr.module_size = 3;
|
||||
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
for (qr.current_y = 0; qr.current_y < qrcoded.size; qr.current_y++)
|
||||
{
|
||||
for (qr.current_x = 0; qr.current_x < qrcoded.size; qr.current_x++)
|
||||
{
|
||||
if (qrcode_getModule(&qrcoded, qr.current_x, qr.current_y))
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y, qr.module_size, qr.module_size, GxEPD_BLACK);
|
||||
else
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y, qr.module_size, qr.module_size, GxEPD_WHITE);
|
||||
}
|
||||
}
|
||||
display.setCursor(11, 5);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Please scan QR code:"); // top message
|
||||
|
||||
display.setCursor(11, 155);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Reset - press button"); // bottom message
|
||||
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,126 +1,47 @@
|
|||
|
||||
|
||||
#if 0
|
||||
#include "lightning_atm.h"
|
||||
#include "main.h"
|
||||
#include "epaperdisplay.h"
|
||||
#include "button.h"
|
||||
#include "coinacceptor.h"
|
||||
|
||||
//#include <GxEPD2_BW.h> // Bibliothek für Schwarz-Weiß-Displays
|
||||
#include <Fonts/FreeMonoBold9pt7b.h>
|
||||
EpaperDisplay epDisp(DSPLY_PIN_CS, DSPLY_PIN_DC, DSPLY_PIN_RST, DSPLY_PIN_BUSY);
|
||||
AtmButton button(BUTTON_PIN, LED_BUTTON_PIN);
|
||||
CoinAcceptor cacc(COIN_PIN, MOSFET_PIN, COINS, COINS_COUNT, COIN_PULSE_WIDTH_MS);
|
||||
|
||||
// #define EPD_CS 26
|
||||
// #define EPD_DC 25
|
||||
// #define EPD_RST 33
|
||||
// #define EPD_BUSY 27
|
||||
/*------------*/
|
||||
|
||||
// // Treiber für das 4.2" Schwarz-Weiß E-Paper
|
||||
// GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));
|
||||
|
||||
void drawText(const char* text);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
/* Wichtige Pins manuell setzen
|
||||
pinMode(EPD_CS, OUTPUT);
|
||||
pinMode(EPD_DC, OUTPUT);
|
||||
pinMode(EPD_RST, OUTPUT);
|
||||
pinMode(EPD_BUSY, INPUT); // BUSY muss als INPUT definiert werden! */
|
||||
|
||||
display.init(115200, true, 2, false);
|
||||
display.setRotation(1); // 0 = Hochformat, 1 = Querformat
|
||||
|
||||
// Bildschirm löschen
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
do {
|
||||
display.fillScreen(GxEPD_WHITE);
|
||||
} while (display.nextPage());
|
||||
delay(1000);
|
||||
drawText("Text Nummer Eins."); // Beispieltext anzeigen
|
||||
delay(10000);
|
||||
drawText("Text Nummer Zwei."); // Beispieltext anzeigen
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
|
||||
void drawText(const char* text) {
|
||||
Serial.printf("Text to show: '%s'\n",text);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
do {
|
||||
display.setCursor(50, 100);
|
||||
display.setFont(&FreeMonoBold9pt7b);
|
||||
display.setTextColor(GxEPD_BLACK);
|
||||
display.print(text);
|
||||
} while (display.nextPage());
|
||||
Serial.println("Display updated.");
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#include "lightning_atm.h"
|
||||
|
||||
constexpr unsigned int COINS[] = { 0, 0, 5, 10, 20, 50, 100, 200, 1, 2 };
|
||||
volatile bool button_pressed = false;
|
||||
static unsigned int inserted_cents = 0;
|
||||
static unsigned int pulses = 0;
|
||||
static unsigned long long time_last_press = millis();
|
||||
String baseURLATM, secretATM, currencyATM;
|
||||
|
||||
// *** for Waveshare ESP32 Driver board *** //
|
||||
#if defined(ESP32) && defined(USE_HSPI_FOR_EPD)
|
||||
SPIClass hspi(HSPI);
|
||||
#endif
|
||||
// *** end Waveshare ESP32 Driver board *** //
|
||||
|
||||
//GxEPD2_BW<GxEPD2_420, GxEPD2_420::HEIGHT> display(GxEPD2_420(DSPLY_PIN_CS, DSPLY_PIN_DC, DSPLY_PIN_RST, DSPLY_PIN_BUSY));
|
||||
//GxEPD2_BW<GxEPD2_154, GxEPD2_154::HEIGHT> display(GxEPD2_154(DSPLY_PIN_CS, DSPLY_PIN_DC, DSPLY_PIN_RST, DSPLY_PIN_BUSY));
|
||||
|
||||
void IRAM_ATTR button_pressed_itr() {
|
||||
button_pressed = true;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
cacc.begin();
|
||||
button.begin();
|
||||
epDisp.init();
|
||||
epDisp.homeScreen();
|
||||
|
||||
initialize_display(); // connection to the e-ink display
|
||||
home_screen();
|
||||
Serial.printf("Selected display type: %s\n", display_type);
|
||||
|
||||
while(0 == 0){}
|
||||
|
||||
|
||||
// *** for Waveshare ESP32 Driver board *** //
|
||||
#if defined(ESP32) && defined(USE_HSPI_FOR_EPD)
|
||||
hspi.begin(13, 12, 14, 15); // remap hspi for EPD (swap pins)
|
||||
display.epd2.selectSPI(hspi, SPISettings(4000000, MSBFIRST, SPI_MODE0));
|
||||
#endif
|
||||
// *** end Waveshare ESP32 Driver board *** //
|
||||
if (DEBUG_MODE) // serial connection for debugging over USB
|
||||
while(0 == 0)
|
||||
{
|
||||
sleep(3);
|
||||
Serial.println("Setup with debug mode..."); // for monitoring with serial monitor to debug
|
||||
Serial.printf("Selected display type: %s\n", display_type);
|
||||
}
|
||||
pinMode(COIN_PIN, INPUT_PULLUP); // coin acceptor input
|
||||
pinMode(LED_BUTTON_PIN, OUTPUT); // LED of the LED Button
|
||||
pinMode(BUTTON_PIN, INPUT_PULLUP); // Button
|
||||
pinMode(MOSFET_PIN, OUTPUT); // mosfet relay to block the coin acceptor
|
||||
digitalWrite(MOSFET_PIN, LOW); // set it low to accept coins, high to block coins
|
||||
attachInterrupt(BUTTON_PIN, button_pressed_itr, FALLING); // interrupt, will set button_pressed to true when button is pressed
|
||||
home_screen(); // will show first screen
|
||||
digitalWrite(LED_BUTTON_PIN, HIGH); // light up the led
|
||||
Serial.println("Insert coin please.");
|
||||
cacc.enable();
|
||||
do
|
||||
{
|
||||
} while (false == cacc.detectCoin());
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
baseURLATM = getValue(lnurlDeviceString, ',', 0); // setup wallet data from string
|
||||
secretATM = getValue(lnurlDeviceString, ',', 1);
|
||||
currencyATM = getValue(lnurlDeviceString, ',', 2);
|
||||
|
||||
while(0==0)
|
||||
{delay(1000);}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
|
||||
#if 0
|
||||
pulses = 0;
|
||||
pulses = detect_coin(); // detect_coin() is a loop to detect the input of coins, will return the amount of pulses
|
||||
if (pulses >= 2 && pulses <= 9)
|
||||
|
@ -172,228 +93,11 @@ void loop()
|
|||
home_screen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// blocking loop which is called when the qr code is shown
|
||||
void wait_for_user_to_scan()
|
||||
{
|
||||
unsigned long long time;
|
||||
bool light_on;
|
||||
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("Waiting for user to scan qr code and press button...");
|
||||
light_on = true;
|
||||
time = millis(); // save start time
|
||||
digitalWrite(LED_BUTTON_PIN, HIGH); // light up the led
|
||||
delay(5000);
|
||||
button_pressed = false;
|
||||
Serial.println("wait for user to press button or 10 minutes to go back to home screen");
|
||||
while (!button_pressed && (millis() - time) < 600000)
|
||||
{
|
||||
if (!light_on && (millis() - time) > 30000)
|
||||
{
|
||||
digitalWrite(LED_BUTTON_PIN, HIGH);
|
||||
light_on = true;
|
||||
}
|
||||
else if (light_on && (millis() - time) > 30000)
|
||||
{
|
||||
digitalWrite(LED_BUTTON_PIN, LOW);
|
||||
light_on = false;
|
||||
}
|
||||
delay(500);
|
||||
}
|
||||
Serial.println("Exit waiting");
|
||||
}
|
||||
|
||||
unsigned int detect_coin()
|
||||
{
|
||||
unsigned long last_pulse;
|
||||
unsigned int pulses;
|
||||
bool prev_value;
|
||||
bool read_value;
|
||||
unsigned long entering_time;
|
||||
unsigned long current_time;
|
||||
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("Starting coin detection...");
|
||||
pulses = 0;
|
||||
read_value = 1;
|
||||
prev_value = digitalRead(COIN_PIN);
|
||||
digitalWrite(LED_BUTTON_PIN, HIGH);
|
||||
digitalWrite(MOSFET_PIN, LOW);
|
||||
button_pressed = false;
|
||||
entering_time = millis();
|
||||
while (true && !button_pressed)
|
||||
{
|
||||
read_value = digitalRead(COIN_PIN);
|
||||
if (read_value != prev_value && !read_value)
|
||||
{
|
||||
delay(35);
|
||||
read_value = digitalRead(COIN_PIN);
|
||||
if (!read_value)
|
||||
{
|
||||
pulses++;
|
||||
last_pulse = millis();
|
||||
digitalWrite(MOSFET_PIN, HIGH);
|
||||
}
|
||||
}
|
||||
prev_value = read_value;
|
||||
current_time = millis();
|
||||
if (pulses > 0 && (current_time - last_pulse > PULSE_TIMEOUT))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (pulses == 0 && ((current_time - entering_time) > 43200000) // refreshes the screen every 12h
|
||||
&& inserted_cents == 0)
|
||||
{
|
||||
clean_screen();
|
||||
delay(10000);
|
||||
entering_time = millis();
|
||||
home_screen();
|
||||
}
|
||||
else if (inserted_cents > 0 && (current_time - entering_time) > 360000) // break the loop if no new coin is inserted for some time
|
||||
button_pressed = true;
|
||||
}
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("Pulses: " + String(pulses));
|
||||
if (button_pressed)
|
||||
{
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("Button pressed, stopping coin detection");
|
||||
return (0);
|
||||
}
|
||||
return (pulses);
|
||||
}
|
||||
|
||||
/*
|
||||
** DISPLAY UTILS
|
||||
*/
|
||||
|
||||
bool display_check_type(const char* in_display_type)
|
||||
{
|
||||
for(size_t type_nr = 0; type_nr < nr_supported_display_types; type_nr++)
|
||||
{
|
||||
if(0 == strcmp(supported_display_types[type_nr], in_display_type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Serial.printf("No suitable display class '%s' defined.\n", in_display_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
// sleep is to put the screen in hibernation mode for longer static frames
|
||||
void display_sleep()
|
||||
{
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
void initialize_display()
|
||||
{
|
||||
display.init(115200, true, 2, false);
|
||||
}
|
||||
|
||||
void home_screen()
|
||||
{
|
||||
if (display_type == "GxEPD2_150_BN")
|
||||
home_screen_waveshare_1_54();
|
||||
else if (display_type == "GxEPD2_270")
|
||||
home_screen_waveshare_2_7();
|
||||
else if (display_type == "GxEPD2_270_GDEY027T91")
|
||||
home_screen_waveshare_2_7();
|
||||
else if (display_type == "GxEPD2_213_B74")
|
||||
home_screen_waveshare_2_13();
|
||||
else if (display_type == "GxEPD2_213_flex")
|
||||
home_screen_waveshare_2_13_flex();
|
||||
else if (display_type == "GxEPD2_420")
|
||||
home_screen_waveshare_2_13_flex();
|
||||
else
|
||||
Serial.println("No suitable display class defined.");
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("Home screen printed.");
|
||||
}
|
||||
|
||||
void show_inserted_amount(int amount_in_cents)
|
||||
{
|
||||
String amount_in_euro_string;
|
||||
|
||||
amount_in_euro_string = get_amount_string(amount_in_cents);
|
||||
if (display_type == "GxEPD2_150_BN")
|
||||
show_inserted_amount_waveshare_1_54(amount_in_euro_string);
|
||||
else if (display_type == "GxEPD2_270")
|
||||
show_inserted_amount_waveshare_2_7(amount_in_euro_string);
|
||||
else if (display_type == "GxEPD2_270_GDEY027T91")
|
||||
show_inserted_amount_waveshare_2_7(amount_in_euro_string);
|
||||
else if (display_type == "GxEPD2_213_B74")
|
||||
show_inserted_amount_waveshare_2_13(amount_in_euro_string);
|
||||
else if (display_type == "GxEPD2_213_flex")
|
||||
show_inserted_amount_waveshare_2_13_flex(amount_in_euro_string);
|
||||
else
|
||||
Serial.println("No suitable display class defined.");
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("New amount on screen.");
|
||||
}
|
||||
|
||||
void qr_withdrawl_screen(const char* qr_content)
|
||||
{
|
||||
if (display_type == "GxEPD2_150_BN")
|
||||
qr_withdrawl_screen_waveshare_1_54(qr_content);
|
||||
else if (display_type == "GxEPD2_270")
|
||||
qr_withdrawl_screen_waveshare_2_7(qr_content);
|
||||
else if (display_type == "GxEPD2_270_GDEY027T91")
|
||||
qr_withdrawl_screen_waveshare_2_7(qr_content);
|
||||
else if (display_type == "GxEPD2_213_B74")
|
||||
qr_withdrawl_screen_waveshare_2_13(qr_content);
|
||||
else if (display_type == "GxEPD2_213_flex")
|
||||
qr_withdrawl_screen_waveshare_2_13_flex(qr_content);
|
||||
else
|
||||
Serial.println("No suitable display class defined.");
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("QR generated and Withdrawl screen printed.");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Called to clean the e-ink screen for storage over longer periods
|
||||
// by button presses on home screen
|
||||
void clean_screen()
|
||||
{
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("Cleaning screen...");
|
||||
if (display_type == "GxEPD2_150_BN")
|
||||
clean_screen_waveshare_1_54();
|
||||
else if (display_type == "GxEPD2_270")
|
||||
clean_screen_waveshare_2_7();
|
||||
else if (display_type == "GxEPD2_270_GDEY027T91")
|
||||
clean_screen_waveshare_2_7();
|
||||
else if (display_type == "GxEPD2_213_B74")
|
||||
clean_screen_waveshare_2_13();
|
||||
else if (display_type == "GxEPD2_213_flex")
|
||||
clean_screen_waveshare_2_13_flex();
|
||||
else
|
||||
Serial.println("No suitable display class defined.");
|
||||
}
|
||||
|
||||
// converts a cent amount to a String like "1.15 Euro"
|
||||
String get_amount_string(int amount_in_cents)
|
||||
{
|
||||
String euro;
|
||||
String cents;
|
||||
String return_value;
|
||||
int euro_value;
|
||||
int cent_remainder;
|
||||
|
||||
euro_value = amount_in_cents / 100;
|
||||
cent_remainder = amount_in_cents % 100;
|
||||
euro = String(euro_value);
|
||||
if (cent_remainder > 9)
|
||||
cents = String(cent_remainder);
|
||||
else if (cent_remainder < 10)
|
||||
cents = "0" + String(cent_remainder);
|
||||
return_value = String(euro) + "." + String(cents) + " " + currencyATM;
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("Calculated amount string: " + return_value);
|
||||
return (return_value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
///////////////LNURL STUFF//////////////////
|
||||
|
@ -516,422 +220,3 @@ String getValue(const String data, char separator, int index)
|
|||
}
|
||||
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
|
||||
}
|
||||
|
||||
// Display functions for specific display types
|
||||
|
||||
// ################################################################
|
||||
// # Waveshare 1.54 inch e-Paper Display Modul with SPI Interface #
|
||||
// ################################################################
|
||||
|
||||
void home_screen_waveshare_1_54()
|
||||
{
|
||||
if (DEBUG_MODE)
|
||||
Serial.println("Home screen for Waveshare 1.54 inch display...");
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
|
||||
display.setCursor(0, 10);
|
||||
display.setTextSize(3);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Insert\nEuro coins\non the\nright\nside to\nstart ->");
|
||||
|
||||
display.setCursor(0, 160);
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Prepare Lightning enabled Bitcoin\nwallet before starting!\n\nSupported coins:\n5 - 50 Cent and 1 - 2 Euro");
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
void show_inserted_amount_waveshare_1_54(String amount_in_euro)
|
||||
{
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
|
||||
display.setCursor(0, 4);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Inserted amount:");
|
||||
|
||||
display.setCursor(10, 90);
|
||||
display.setTextSize(3);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(amount_in_euro);
|
||||
|
||||
display.setCursor(0, 160);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(" Press button\n once finished.");
|
||||
|
||||
display.nextPage();
|
||||
}
|
||||
|
||||
void qr_withdrawl_screen_waveshare_1_54(const char* qr_content)
|
||||
{
|
||||
QRCode qrcoded;
|
||||
uint8_t qrcodeData[qrcode_getBufferSize(QR_VERSION)]; // 20 is "qr version"
|
||||
t_qrdata qr;
|
||||
|
||||
// initialize qr code data
|
||||
qrcode_initText(&qrcoded, qrcodeData, QR_VERSION, 0, qr_content);
|
||||
qr.qr_size = qrcoded.size * 2;
|
||||
qr.start_x = (150 - qr.qr_size) / 2;
|
||||
qr.start_y = (150 - qr.qr_size) / 2;
|
||||
qr.module_size = 3;
|
||||
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
// loop trough Y and X axis to draw the qr code rectangle by rectangle
|
||||
// 0, 0 is the top left of the screen
|
||||
for (qr.current_y = 0; qr.current_y < qrcoded.size; qr.current_y++)
|
||||
{
|
||||
for (qr.current_x = 0; qr.current_x < qrcoded.size; qr.current_x++)
|
||||
{
|
||||
if (qrcode_getModule(&qrcoded, qr.current_x, qr.current_y))
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y,
|
||||
qr.module_size,
|
||||
qr.module_size,
|
||||
GxEPD_BLACK);
|
||||
else
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y,
|
||||
qr.module_size,
|
||||
qr.module_size,
|
||||
GxEPD_WHITE);
|
||||
}
|
||||
}
|
||||
// draw the text messages on the screen
|
||||
display.setCursor(0, 4);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Please scan QR:"); // top message
|
||||
display.setCursor(0, 170);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Press the \nbutton to reset"); // bottom message
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
void clean_screen_waveshare_1_54()
|
||||
{
|
||||
display.firstPage();
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
// ##############################################
|
||||
// # Waveshare 2.7 inch e-ink display functions #
|
||||
// ##############################################
|
||||
|
||||
void home_screen_waveshare_2_7()
|
||||
{
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
|
||||
display.setCursor(11, 20);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Insert Euro coins\n on the right ->\n to start ATM");
|
||||
|
||||
display.drawBitmap(172, 65, bitcoin_logo, 64, 64, GxEPD_BLACK);
|
||||
|
||||
display.setCursor(12, 140);
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Prepare Lightning enabled Bitcoin\n wallet before starting!\n Supported coins: 5 - 50 Cent, 1 - 2 Euro");
|
||||
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
void show_inserted_amount_waveshare_2_7(String amount_in_euro)
|
||||
{
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
|
||||
display.setCursor(11, 10);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Inserted amount:");
|
||||
|
||||
display.setCursor(20, 75);
|
||||
display.setTextSize(3);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(amount_in_euro);
|
||||
|
||||
display.setCursor(11, 135);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Press button\n once finished.");
|
||||
|
||||
display.nextPage();
|
||||
}
|
||||
|
||||
void qr_withdrawl_screen_waveshare_2_7(const char* qr_content)
|
||||
{
|
||||
QRCode qrcoded;
|
||||
uint8_t qrcodeData[qrcode_getBufferSize(QR_VERSION)]; // 20 is "qr version"
|
||||
t_qrdata qr;
|
||||
|
||||
qrcode_initText(&qrcoded, qrcodeData, QR_VERSION, 0, qr_content);
|
||||
qr.qr_size = qrcoded.size * 3;
|
||||
qr.start_x = (264 - qr.qr_size) / 2;
|
||||
qr.start_y = (176 - qr.qr_size) / 2;
|
||||
qr.module_size = 3;
|
||||
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
for (qr.current_y = 0; qr.current_y < qrcoded.size; qr.current_y++)
|
||||
{
|
||||
for (qr.current_x = 0; qr.current_x < qrcoded.size; qr.current_x++)
|
||||
{
|
||||
if (qrcode_getModule(&qrcoded, qr.current_x, qr.current_y))
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y, qr.module_size, qr.module_size, GxEPD_BLACK);
|
||||
else
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y, qr.module_size, qr.module_size, GxEPD_WHITE);
|
||||
}
|
||||
}
|
||||
display.setCursor(11, 5);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Please scan QR code:"); // top message
|
||||
|
||||
display.setCursor(11, 155);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Reset - press button"); // bottom message
|
||||
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
void clean_screen_waveshare_2_7()
|
||||
{
|
||||
display.firstPage();
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
// #########################################################
|
||||
// # Waveshare 2.13 inch e-ink display (250x122) functions #
|
||||
// #########################################################
|
||||
|
||||
void home_screen_waveshare_2_13()
|
||||
{
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
|
||||
display.setCursor(5, 5);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("LIGHTNING ATM");
|
||||
display.setCursor(3, 33);
|
||||
display.println("Insert coins");
|
||||
display.setCursor(3, 50);
|
||||
display.println("on the right");
|
||||
display.setCursor(3, 67);
|
||||
display.println("side to start");
|
||||
|
||||
display.drawBitmap(180, 15, bitcoin_logo, 64, 64, GxEPD_BLACK);
|
||||
|
||||
display.setCursor(0, 95);
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(" Prepare Lightning enabled Bitcoin\n wallet before starting!\n Supported coins: 2 cent to 2 euro");
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
void show_inserted_amount_waveshare_2_13(String amount_in_euro)
|
||||
{
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
|
||||
display.setCursor(10, 4);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Inserted amount:");
|
||||
|
||||
display.setCursor(35, 45);
|
||||
display.setTextSize(3);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(amount_in_euro);
|
||||
|
||||
display.setCursor(0, 85);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(" Press button\n to show QR code");
|
||||
|
||||
display.nextPage();
|
||||
}
|
||||
|
||||
void qr_withdrawl_screen_waveshare_2_13(const char* qr_content)
|
||||
{
|
||||
QRCode qrcoded;
|
||||
uint8_t qrcodeData[qrcode_getBufferSize(QR_VERSION)]; // 20 is "qr version"
|
||||
t_qrdata qr;
|
||||
|
||||
qrcode_initText(&qrcoded, qrcodeData, QR_VERSION, 0, qr_content);
|
||||
qr.qr_size = qrcoded.size * 2;
|
||||
qr.start_x = (230 - qr.qr_size) / 2;
|
||||
qr.start_y = (122 - qr.qr_size) / 2;
|
||||
qr.module_size = 2;
|
||||
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
for (qr.current_y = 0; qr.current_y < qrcoded.size; qr.current_y++)
|
||||
{
|
||||
for (qr.current_x = 0; qr.current_x < qrcoded.size; qr.current_x++)
|
||||
{
|
||||
if (qrcode_getModule(&qrcoded, qr.current_x, qr.current_y))
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y, qr.module_size, qr.module_size, GxEPD_BLACK);
|
||||
else
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y, qr.module_size, qr.module_size, GxEPD_WHITE);
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 20);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(" Scan\n\n QR\n\n code"); // top message
|
||||
|
||||
display.setCursor(181, 32);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Reset");
|
||||
display.setCursor(181, 53);
|
||||
display.println("press");
|
||||
display.setCursor(176, 77);
|
||||
display.println("button");
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
void clean_screen_waveshare_2_13()
|
||||
{
|
||||
display.firstPage();
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
// ###########################################################################
|
||||
// # Waveshare 2.13 inch e-ink display (D) flex (yellow) (212x104) functions #
|
||||
// ###########################################################################
|
||||
|
||||
void home_screen_waveshare_2_13_flex()
|
||||
{
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
|
||||
display.setCursor(5, 5);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("LIGHTNING ATM");
|
||||
display.setCursor(3, 25);
|
||||
display.println("Insert coins");
|
||||
display.setCursor(3, 42);
|
||||
display.println("on the right");
|
||||
display.setCursor(3, 59);
|
||||
display.println("side to start");
|
||||
|
||||
display.drawBitmap(151, 8, bitcoin_logo, 64, 64, GxEPD_BLACK);
|
||||
|
||||
display.setCursor(0, 80);
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(" Prepare Lightning enabled Bitcoin\n wallet before starting!\n Supported coins: 2 cent to 2 euro");
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
void show_inserted_amount_waveshare_2_13_flex(String amount_in_euro)
|
||||
{
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
|
||||
display.setCursor(0, 4);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(" Inserted amount:");
|
||||
|
||||
display.setCursor(30, 35);
|
||||
display.setTextSize(3);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(amount_in_euro);
|
||||
|
||||
display.setCursor(0, 70);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(" Press button\n to show QR code");
|
||||
|
||||
display.nextPage();
|
||||
}
|
||||
|
||||
void qr_withdrawl_screen_waveshare_2_13_flex(const char* qr_content)
|
||||
{
|
||||
QRCode qrcoded;
|
||||
uint8_t qrcodeData[qrcode_getBufferSize(QR_VERSION)]; // 20 is "qr version"
|
||||
t_qrdata qr;
|
||||
|
||||
qrcode_initText(&qrcoded, qrcodeData, QR_VERSION, 0, qr_content);
|
||||
qr.qr_size = qrcoded.size * 2;
|
||||
qr.start_x = (220 - qr.qr_size) / 2;
|
||||
qr.start_y = (105 - qr.qr_size) / 2;
|
||||
qr.module_size = 2;
|
||||
|
||||
display.setRotation(1);
|
||||
display.setFullWindow();
|
||||
display.firstPage();
|
||||
for (qr.current_y = 0; qr.current_y < qrcoded.size; qr.current_y++)
|
||||
{
|
||||
for (qr.current_x = 0; qr.current_x < qrcoded.size; qr.current_x++)
|
||||
{
|
||||
if (qrcode_getModule(&qrcoded, qr.current_x, qr.current_y))
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y, qr.module_size, qr.module_size, GxEPD_BLACK);
|
||||
else
|
||||
display.fillRect(qr.start_x + qr.module_size * qr.current_x,
|
||||
qr.start_y + qr.module_size * qr.current_y, qr.module_size, qr.module_size, GxEPD_WHITE);
|
||||
}
|
||||
}
|
||||
display.setCursor(0, 12);
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println(" Scan\n\n QR\n\n code"); // top message
|
||||
|
||||
display.setCursor(170, 37);
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);
|
||||
display.println("Reset");
|
||||
display.setCursor(170, 47);
|
||||
display.println("press");
|
||||
display.setCursor(167, 57);
|
||||
display.println("button");
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
void clean_screen_waveshare_2_13_flex()
|
||||
{
|
||||
display.firstPage();
|
||||
display.nextPage();
|
||||
display.hibernate();
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue