changed the way how to select which display is used. This is still in test and there is also some testcode include

This commit is contained in:
Jens Noack 2025-02-18 09:21:39 +01:00
parent 019f8768cd
commit 493642aa90
8 changed files with 229 additions and 99 deletions

2
firmware/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.pio/
.vscode/

View file

@ -17,8 +17,8 @@
// mapping of Waveshare ESP32 Driver Board // mapping of Waveshare ESP32 Driver Board
// BUSY -> 25, RST -> 26, DC -> 27, CS-> 15, CLK -> 13, DIN -> 14 // BUSY -> 25, RST -> 26, DC -> 27, CS-> 15, CLK -> 13, DIN -> 14
// uncomment next two lines for Waveshare ESP32 Driver Board // uncomment next two lines for Waveshare ESP32 Driver Board
#define USE_HSPI_FOR_EPD // #define USE_HSPI_FOR_EPD
#define ENABLE_GxEPD2_GFX 0 // #define ENABLE_GxEPD2_GFX 0
// *** end Waveshare ESP32 Driver board *** // // *** end Waveshare ESP32 Driver board *** //
// NOTE: you may need to adapt or select for your wiring in the processor specific conditional compile sections below // NOTE: you may need to adapt or select for your wiring in the processor specific conditional compile sections below
@ -30,14 +30,14 @@
// select the display driver class (only one) for your panel // select the display driver class (only one) for your panel
// #define GxEPD2_DRIVER_CLASS GxEPD2_150_BN // 1.54 inch Waveshare e-paper display #define GxEPD2_DRIVER_CLASS GxEPD2_150_BN // 1.54 inch Waveshare e-paper display
// const String display_type = "GxEPD2_150_BN"; const String display_type = "GxEPD2_150_BN";
// #define GxEPD2_DRIVER_CLASS GxEPD2_213_B74 // Waveshare 2.13 inch e-paper display - Version 3 // #define GxEPD2_DRIVER_CLASS GxEPD2_213_B74 // Waveshare 2.13 inch e-paper display - Version 3
// const String display_type = "GxEPD2_213_B74"; // const String display_type = "GxEPD2_213_B74";
#define GxEPD2_DRIVER_CLASS GxEPD2_213_flex // Waveshare 2.13 inch e-paper display - (D) flex (yellow) // #define GxEPD2_DRIVER_CLASS GxEPD2_213_flex // Waveshare 2.13 inch e-paper display - (D) flex (yellow)
const String display_type = "GxEPD2_213_flex"; // const String display_type = "GxEPD2_213_flex";
// #define GxEPD2_DRIVER_CLASS GxEPD2_270 // Waveshare 264x176, 2.7inch E-Ink display - Version 1 // #define GxEPD2_DRIVER_CLASS GxEPD2_270 // Waveshare 264x176, 2.7inch E-Ink display - Version 1
// const String display_type = "GxEPD2_270"; // const String display_type = "GxEPD2_270";

View file

@ -1,39 +1,37 @@
This directory is intended for project header files. This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'. by including it, with the C preprocessing directive `#include'.
```src/main.c ```src/main.c
#include "header.h" #include "header.h"
int main (void) int main (void)
{ {
... ...
} }
``` ```
Including a header file produces the same results as copying the header file Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program. find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'. In C, the convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot. Read more about using header files in official GCC documentation:
Read more about using header files in official GCC documentation: * Include Syntax
* Include Operation
* Include Syntax * Once-Only Headers
* Include Operation * Computed Includes
* Once-Only Headers
* Computed Includes https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View file

@ -9,30 +9,20 @@
#include <stdlib.h> #include <stdlib.h>
#include <Hash.h> #include <Hash.h>
#include <ctype.h> #include <ctype.h>
#include <stdio.h>
// ######################################## // ########################################
// ########### USER ACTION ########### // ########### USER ACTION ###########
// ######################################## // ########################################
// Generate and copy in LNbits with the LNURLDevice extension the string for the ATM and paste it here: // Generate and copy in LNbits with the LNURLDevice extension the string for the ATM and paste it here:
const String lnurlDeviceString = "https://legend.lnbits.com/lnurldevice/api/v1/lnurl/idexample,keyexample,EUR"; 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 // #################### EXAMPLE: https://legend.lnbits.com/lnurldevice/api/v1/lnurl/idexample,keyexample,EUR
// ######################################## // ########################################
// ######################################## // ########################################
// ######################################## // ########################################
// select the display class and display driver class in the following file (new style):
// 1.54 inch Waveshare e-paper display is "GxEPD2_DRIVER_CLASS GxEPD2_150_BN"
// Waveshare 264x176, 2.7inch E-Ink display - Version 1 = "GxEPD2_DRIVER_CLASS GxEPD2_270"
// Waveshare 264x176, 2.7inch E-Ink display - Version 2 = "GxEPD2_DRIVER_CLASS GxEPD2_270_GDEY027T91"
// Waveshare 2.13 inch e-paper display version 3 is "GxEPD2_DRIVER_CLASS GxEPD2_213_B74"
// Waveshare 2.13 inch e-paper display (D) flex (yellow) is "GxEPD2_DRIVER_CLASS GxEPD2_213_flex"
// use search to find the correct line, and uncomment the other display drivers in this header file:
#include "GxEPD2_display_selection_new_style.h"
// OTHER OPTIONS:
// Activate for debugging over Serial (1), deactivate in production use (0) // Activate for debugging over Serial (1), deactivate in production use (0)
#define DEBUG_MODE 0 #define DEBUG_MODE 1
#define COIN_PIN 17 #define COIN_PIN 17
#define PULSE_TIMEOUT 200 #define PULSE_TIMEOUT 200
@ -41,6 +31,27 @@ const String lnurlDeviceString = "https://legend.lnbits.com/lnurldevice/api/v1/l
#define MOSFET_PIN 16 // old: 12 | new: 16 #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 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 typedef struct s_qrdata
{ {
uint8_t current_y; uint8_t current_y;

46
firmware/lib/README Normal file
View file

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into the executable file.
The source code of each library should be placed in a separate directory
("lib/your_library_name/[Code]").
For example, see the structure of the following example libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Example contents of `src/main.c` using Foo and Bar:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
The PlatformIO Library Dependency Finder will find automatically dependent
libraries by scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View file

@ -12,7 +12,7 @@
platform = espressif32 platform = espressif32
board = esp32dev board = esp32dev
framework = arduino framework = arduino
monitor_speed = 9600 monitor_speed = 115200
lib_deps = lib_deps =
zinggjm/GxEPD2@^1.5.2 zinggjm/GxEPD2@^1.5.2
ricmoo/QRCode@^0.0.1 ricmoo/QRCode@^0.0.1

View file

@ -1,12 +1,72 @@
#if 0
#include "lightning_atm.h" #include "lightning_atm.h"
const unsigned int COINS[] = { 0, 0, 5, 10, 20, 50, 100, 200, 1, 2 }; //#include <GxEPD2_BW.h> // Bibliothek für Schwarz-Weiß-Displays
bool button_pressed = false; #include <Fonts/FreeMonoBold9pt7b.h>
unsigned int inserted_cents = 0;
unsigned long long time_last_press = millis(); // #define EPD_CS 26
String baseURLATM; // #define EPD_DC 25
String secretATM; // #define EPD_RST 33
String currencyATM; // #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 *** // // *** for Waveshare ESP32 Driver board *** //
#if defined(ESP32) && defined(USE_HSPI_FOR_EPD) #if defined(ESP32) && defined(USE_HSPI_FOR_EPD)
@ -14,11 +74,24 @@ SPIClass hspi(HSPI);
#endif #endif
// *** end Waveshare ESP32 Driver board *** // // *** 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() void setup()
{ {
Serial.begin(115200);
initialize_display(); // connection to the e-ink display initialize_display(); // connection to the e-ink display
Serial.begin(9600); home_screen();
Serial.printf("Selected display type: %s\n", display_type);
while(0 == 0){}
// *** for Waveshare ESP32 Driver board *** // // *** for Waveshare ESP32 Driver board *** //
#if defined(ESP32) && defined(USE_HSPI_FOR_EPD) #if defined(ESP32) && defined(USE_HSPI_FOR_EPD)
hspi.begin(13, 12, 14, 15); // remap hspi for EPD (swap pins) hspi.begin(13, 12, 14, 15); // remap hspi for EPD (swap pins)
@ -29,7 +102,7 @@ void setup()
{ {
sleep(3); sleep(3);
Serial.println("Setup with debug mode..."); // for monitoring with serial monitor to debug Serial.println("Setup with debug mode..."); // for monitoring with serial monitor to debug
Serial.println("Selected display type: " + display_type); Serial.printf("Selected display type: %s\n", display_type);
} }
pinMode(COIN_PIN, INPUT_PULLUP); // coin acceptor input pinMode(COIN_PIN, INPUT_PULLUP); // coin acceptor input
pinMode(LED_BUTTON_PIN, OUTPUT); // LED of the LED Button pinMode(LED_BUTTON_PIN, OUTPUT); // LED of the LED Button
@ -46,9 +119,9 @@ void setup()
void loop() void loop()
{ {
unsigned int pulses = 0;
unsigned long long time_last_press;
pulses = 0;
pulses = detect_coin(); // detect_coin() is a loop to detect the input of coins, will return the amount of pulses 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) if (pulses >= 2 && pulses <= 9)
{ {
@ -101,12 +174,6 @@ void loop()
} }
} }
// function to handle the button interrupt
void IRAM_ATTR button_pressed_itr()
{
button_pressed = true;
}
// blocking loop which is called when the qr code is shown // blocking loop which is called when the qr code is shown
void wait_for_user_to_scan() void wait_for_user_to_scan()
{ {
@ -202,37 +269,28 @@ unsigned int detect_coin()
** DISPLAY UTILS ** 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 // sleep is to put the screen in hibernation mode for longer static frames
void display_sleep() void display_sleep()
{ {
if (display_type == "GxEPD2_150_BN")
display.hibernate(); display.hibernate();
else if (display_type == "GxEPD2_270")
display.hibernate();
else if (display_type == "GxEPD2_270_GDEY027T91")
display.hibernate();
else if (display_type == "GxEPD2_213_B74")
display.hibernate();
else if (display_type == "GxEPD2_213_flex")
display.hibernate();
else
Serial.println("No suitable display class defined.");
} }
void initialize_display() void initialize_display()
{ {
if (display_type == "GxEPD2_150_BN")
display.init(115200, true, 2, false); display.init(115200, true, 2, false);
else if (display_type == "GxEPD2_270")
display.init(115200, true, 2, false);
else if (display_type == "GxEPD2_270_GDEY027T91")
display.init(115200, true, 2, false);
else if (display_type == "GxEPD2_213_B74")
display.init(115200, true, 2, false);
else if (display_type == "GxEPD2_213_flex")
display.init(115200, true, 2, false);
else
Serial.println("No suitable display class defined.");
} }
void home_screen() void home_screen()
@ -247,6 +305,8 @@ void home_screen()
home_screen_waveshare_2_13(); home_screen_waveshare_2_13();
else if (display_type == "GxEPD2_213_flex") else if (display_type == "GxEPD2_213_flex")
home_screen_waveshare_2_13_flex(); home_screen_waveshare_2_13_flex();
else if (display_type == "GxEPD2_420")
home_screen_waveshare_2_13_flex();
else else
Serial.println("No suitable display class defined."); Serial.println("No suitable display class defined.");
if (DEBUG_MODE) if (DEBUG_MODE)
@ -872,4 +932,6 @@ void clean_screen_waveshare_2_13_flex()
display.firstPage(); display.firstPage();
display.nextPage(); display.nextPage();
display.hibernate(); display.hibernate();
} }
#endif

11
firmware/test/README Normal file
View file

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html