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
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
Add a link
Reference in a new issue