More memory optimizations
This commit is contained in:
parent
e1648a9a42
commit
1f7946c30e
@ -1,5 +1,8 @@
|
|||||||
|
#include "epd.hpp"
|
||||||
|
|
||||||
int fgColor;
|
int fgColor;
|
||||||
int bgColor;
|
int bgColor;
|
||||||
|
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
|
||||||
|
|
||||||
int getBgColor()
|
int getBgColor()
|
||||||
{
|
{
|
||||||
@ -20,3 +23,83 @@ void setFgColor(int color)
|
|||||||
{
|
{
|
||||||
fgColor = color;
|
fgColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showSetupQr(const String &ssid, const String &password)
|
||||||
|
{
|
||||||
|
char displayIndex = 6;
|
||||||
|
|
||||||
|
const String text = "WIFI:S:" + ssid + ";T:WPA;P:" + password + ";;";
|
||||||
|
|
||||||
|
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
|
||||||
|
bool ok = qrcodegen_encodeText(text.c_str(), tempBuffer, qrcode, qrcodegen_Ecc_LOW,
|
||||||
|
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
|
||||||
|
|
||||||
|
const int size = qrcodegen_getSize(qrcode);
|
||||||
|
|
||||||
|
const int padding = floor(float(displays[displayIndex].width() - (size * 4)) / 2);
|
||||||
|
const int paddingY = floor(float(displays[displayIndex].height() - (size * 4)) / 2);
|
||||||
|
|
||||||
|
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
||||||
|
displays[displayIndex].fillScreen(GxEPD_WHITE);
|
||||||
|
const int border = 0;
|
||||||
|
|
||||||
|
for (int y = -border; y < size * 4 + border; y++)
|
||||||
|
{
|
||||||
|
for (int x = -border; x < size * 4 + border; x++)
|
||||||
|
{
|
||||||
|
displays[displayIndex].drawPixel(padding + x, paddingY + y, qrcodegen_getModule(qrcode, floor(float(x) / 4), floor(float(y) / 4)) ? GxEPD_BLACK : GxEPD_WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
displays[displayIndex].display(true);
|
||||||
|
|
||||||
|
displayIndex = 4;
|
||||||
|
|
||||||
|
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
||||||
|
displays[displayIndex].fillScreen(GxEPD_WHITE);
|
||||||
|
displays[displayIndex].setTextColor(GxEPD_BLACK);
|
||||||
|
displays[displayIndex].setCursor(0, 50);
|
||||||
|
displays[displayIndex].setFont(&FreeSansBold9pt7b);
|
||||||
|
displays[displayIndex].println(F("SSID:"));
|
||||||
|
displays[displayIndex].setFont(&FreeSans9pt7b);
|
||||||
|
displays[displayIndex].println(ssid);
|
||||||
|
displays[displayIndex].println("");
|
||||||
|
displays[displayIndex].setFont(&FreeSansBold9pt7b);
|
||||||
|
displays[displayIndex].println(F("Password:"));
|
||||||
|
displays[displayIndex].setFont(&FreeSans9pt7b);
|
||||||
|
displays[displayIndex].println(password);
|
||||||
|
displays[displayIndex].display(true);
|
||||||
|
|
||||||
|
displayIndex = 2;
|
||||||
|
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
||||||
|
displays[displayIndex].fillScreen(GxEPD_WHITE);
|
||||||
|
displays[displayIndex].setTextColor(GxEPD_BLACK);
|
||||||
|
displays[displayIndex].setCursor(0, 50);
|
||||||
|
displays[displayIndex].setFont(&FreeSans9pt7b);
|
||||||
|
displays[displayIndex].println(F("To setup\r\nscan QR or\r\nconnect\r\nmanually"));
|
||||||
|
// displays[displayIndex].println(F("scan QR or"));
|
||||||
|
// displays[displayIndex].println(F("connect"));
|
||||||
|
// displays[displayIndex].println(F("manually"));
|
||||||
|
displays[displayIndex].display(true);
|
||||||
|
|
||||||
|
displayIndex = 0;
|
||||||
|
|
||||||
|
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
||||||
|
displays[displayIndex].fillScreen(GxEPD_WHITE);
|
||||||
|
displays[displayIndex].setTextColor(GxEPD_BLACK);
|
||||||
|
displays[displayIndex].setCursor(0, 50);
|
||||||
|
displays[displayIndex].setFont(&FreeSansBold9pt7b);
|
||||||
|
displays[displayIndex].println(F("Welcome!"));
|
||||||
|
displays[displayIndex].display(true);
|
||||||
|
|
||||||
|
for (int i = 1; i < NUM_SCREENS; (i = i + 2))
|
||||||
|
{
|
||||||
|
displays[i].setPartialWindow(0, 0, displays[i].width(), displays[i].height());
|
||||||
|
displays[i].fillScreen(GxEPD_WHITE);
|
||||||
|
displays[i].display(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_SCREENS; i++)
|
||||||
|
{
|
||||||
|
displays[i].hibernate();
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "shared.hpp"
|
||||||
|
#include "qrcodegen.h"
|
||||||
|
|
||||||
|
#include <Fonts/FreeSansBold9pt7b.h>
|
||||||
|
#include <Fonts/FreeSans9pt7b.h>
|
||||||
|
#ifdef IS_BW
|
||||||
|
#include <GxEPD2_BW.h>
|
||||||
|
#else
|
||||||
|
#include <GxEPD2_3C.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
int getBgColor();
|
int getBgColor();
|
||||||
int getFgColor();
|
int getFgColor();
|
||||||
void setBgColor(int color);
|
void setBgColor(int color);
|
||||||
void setFgColor(int color);
|
void setFgColor(int color);
|
||||||
|
|
||||||
|
void showSetupQr(const String& ssid, const String& password);
|
||||||
|
@ -7,7 +7,7 @@ std::map<int, std::string> screenNameMap;
|
|||||||
|
|
||||||
#ifndef NO_MCP
|
#ifndef NO_MCP
|
||||||
Adafruit_MCP23X17 mcp;
|
Adafruit_MCP23X17 mcp;
|
||||||
const int MCP_INT_PIN = 8;
|
const char MCP_INT_PIN = 8;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
bool timerRunning = true;
|
bool timerRunning = true;
|
||||||
@ -27,7 +27,7 @@ Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
|
|||||||
|
|
||||||
String softAP_SSID;
|
String softAP_SSID;
|
||||||
String softAP_password;
|
String softAP_password;
|
||||||
WiFiMulti wifiMulti;
|
//WiFiMulti wifiMulti;
|
||||||
|
|
||||||
WiFiManager wm;
|
WiFiManager wm;
|
||||||
bool screenVisible[5];
|
bool screenVisible[5];
|
||||||
@ -36,20 +36,20 @@ void setupSoftAP()
|
|||||||
{
|
{
|
||||||
byte mac[6];
|
byte mac[6];
|
||||||
WiFi.macAddress(mac);
|
WiFi.macAddress(mac);
|
||||||
softAP_SSID = String("BTClock" + String(mac[5], 16) + String(mac[6], 16));
|
softAP_SSID = String("BTClock" + String(mac[5], 16) + String(mac[1], 16));
|
||||||
WiFi.setHostname(softAP_SSID.c_str());
|
WiFi.setHostname(softAP_SSID.c_str());
|
||||||
softAP_password = base64::encode(String(mac[2], 16) + String(mac[4], 16) + String(mac[5], 16) + String(mac[6], 16)).substring(2, 10);
|
softAP_password = base64::encode(String(mac[2], 16) + String(mac[4], 16) + String(mac[5], 16) + String(mac[1], 16)).substring(2, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupComponents()
|
void setupComponents()
|
||||||
{
|
{
|
||||||
if (psramInit())
|
if (psramInit())
|
||||||
{
|
{
|
||||||
Serial.println("\nPSRAM is correctly initialized");
|
Serial.println(F("PSRAM is correctly initialized"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Serial.println("PSRAM not available");
|
Serial.println(F("PSRAM not available"));
|
||||||
}
|
}
|
||||||
#ifdef WITH_RGB_LED
|
#ifdef WITH_RGB_LED
|
||||||
pixels.begin();
|
pixels.begin();
|
||||||
@ -61,12 +61,12 @@ void setupComponents()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// delay(3000);
|
// delay(3000);
|
||||||
// Serial.println("Leds should be on");
|
// Serial.println(F("Leds should be on"));
|
||||||
|
|
||||||
#ifndef NO_MCP
|
#ifndef NO_MCP
|
||||||
if (!mcp.begin_I2C())
|
if (!mcp.begin_I2C())
|
||||||
{
|
{
|
||||||
Serial.println("Error MCP23017");
|
Serial.println(F("Error MCP23017"));
|
||||||
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
|
pixels.setPixelColor(0, pixels.Color(255, 0, 0));
|
||||||
pixels.setPixelColor(1, pixels.Color(255, 0, 0));
|
pixels.setPixelColor(1, pixels.Color(255, 0, 0));
|
||||||
pixels.setPixelColor(2, pixels.Color(255, 0, 0));
|
pixels.setPixelColor(2, pixels.Color(255, 0, 0));
|
||||||
@ -77,7 +77,7 @@ void setupComponents()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Serial.println("MCP23017 ok");
|
Serial.println(F("MCP23017 ok"));
|
||||||
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
|
pixels.setPixelColor(0, pixels.Color(0, 255, 0));
|
||||||
pixels.setPixelColor(1, pixels.Color(0, 255, 0));
|
pixels.setPixelColor(1, pixels.Color(0, 255, 0));
|
||||||
pixels.setPixelColor(2, pixels.Color(0, 255, 0));
|
pixels.setPixelColor(2, pixels.Color(0, 255, 0));
|
||||||
@ -107,7 +107,7 @@ void synchronizeTime()
|
|||||||
{
|
{
|
||||||
configTime(preferences.getInt("gmtOffset", TIME_OFFSET_SECONDS), 0, NTP_SERVER);
|
configTime(preferences.getInt("gmtOffset", TIME_OFFSET_SECONDS), 0, NTP_SERVER);
|
||||||
delay(500);
|
delay(500);
|
||||||
Serial.println("Retry set time");
|
Serial.println(F("Retry set time"));
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc.setTimeStruct(timeinfo);
|
rtc.setTimeStruct(timeinfo);
|
||||||
@ -134,7 +134,7 @@ void setupWifi()
|
|||||||
pixels.setPixelColor(2, pixels.Color(255, 0, 0));
|
pixels.setPixelColor(2, pixels.Color(255, 0, 0));
|
||||||
pixels.setPixelColor(3, pixels.Color(0, 0, 255));
|
pixels.setPixelColor(3, pixels.Color(0, 0, 255));
|
||||||
pixels.show();
|
pixels.show();
|
||||||
Serial.println("Erasing WiFi Config, restarting");
|
Serial.println(F("Erasing WiFi Config, restarting"));
|
||||||
wm.resetSettings();
|
wm.resetSettings();
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
@ -252,7 +252,7 @@ void toggleScreenTimer()
|
|||||||
|
|
||||||
if (!timerRunning)
|
if (!timerRunning)
|
||||||
{
|
{
|
||||||
Serial.println("Stopping screen timer...");
|
Serial.println(F("Stopping screen timer..."));
|
||||||
for (int i = NEOPIXEL_COUNT; i >= 0; i--)
|
for (int i = NEOPIXEL_COUNT; i >= 0; i--)
|
||||||
{
|
{
|
||||||
for (int j = NEOPIXEL_COUNT; j >= 0; j--)
|
for (int j = NEOPIXEL_COUNT; j >= 0; j--)
|
||||||
@ -275,7 +275,7 @@ void toggleScreenTimer()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Serial.println("Starting screen timer...");
|
Serial.println(F("Starting screen timer..."));
|
||||||
|
|
||||||
pixels.setPixelColor(3, pixels.Color(0, 255, 0));
|
pixels.setPixelColor(3, pixels.Color(0, 255, 0));
|
||||||
pixels.setPixelColor(2, pixels.Color(0, 0, 0));
|
pixels.setPixelColor(2, pixels.Color(0, 0, 0));
|
||||||
@ -442,7 +442,7 @@ void setupI2C()
|
|||||||
|
|
||||||
if (slaveMode)
|
if (slaveMode)
|
||||||
{
|
{
|
||||||
Serial.println("I2C Slave Mode enabled");
|
Serial.println(F("I2C Slave Mode enabled"));
|
||||||
Wire.onReceive(onI2CReceive);
|
Wire.onReceive(onI2CReceive);
|
||||||
Wire.begin((uint8_t)I2C_DEV_ADDR);
|
Wire.begin((uint8_t)I2C_DEV_ADDR);
|
||||||
}
|
}
|
||||||
@ -461,5 +461,5 @@ void onI2CReceive(int len)
|
|||||||
void onI2CRequest()
|
void onI2CRequest()
|
||||||
{
|
{
|
||||||
Wire.print("I2C Packets.");
|
Wire.print("I2C Packets.");
|
||||||
Serial.println("onRequest");
|
Serial.println(F("onRequest"));
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <WiFiManager.h>
|
#include <WiFiManager.h>
|
||||||
#include <WiFiMulti.h>
|
//#include <WiFiMulti.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "shared.hpp"
|
#include "shared.hpp"
|
||||||
|
@ -9,10 +9,7 @@ void setupWebserver()
|
|||||||
// Initialize SPIFFS
|
// Initialize SPIFFS
|
||||||
if (!SPIFFS.begin(true))
|
if (!SPIFFS.begin(true))
|
||||||
{
|
{
|
||||||
pinMode(47, OUTPUT);
|
Serial.println(F("An Error has occurred while mounting SPIFFS"));
|
||||||
digitalWrite(47, HIGH);
|
|
||||||
|
|
||||||
Serial.println("An Error has occurred while mounting SPIFFS");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,14 +54,14 @@ void setupWebserver()
|
|||||||
server.begin();
|
server.begin();
|
||||||
if (!MDNS.begin(HOSTNAME))
|
if (!MDNS.begin(HOSTNAME))
|
||||||
{
|
{
|
||||||
Serial.println("Error setting up MDNS responder!");
|
Serial.println(F("Error setting up MDNS responder!"));
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MDNS.addService("http", "tcp", 80);
|
MDNS.addService("http", "tcp", 80);
|
||||||
Serial.println("Webserver should be running");
|
Serial.println(F("Webserver should be running"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,7 +109,7 @@ void onApiStatus(AsyncWebServerRequest *request)
|
|||||||
void onApiActionPause(AsyncWebServerRequest *request)
|
void onApiActionPause(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
timerRunning = false;
|
timerRunning = false;
|
||||||
Serial.println("Update timer paused");
|
Serial.println(F("Update timer paused"));
|
||||||
|
|
||||||
request->send(200);
|
request->send(200);
|
||||||
};
|
};
|
||||||
@ -137,7 +134,7 @@ void onApiActionTimerRestart(AsyncWebServerRequest *request)
|
|||||||
{
|
{
|
||||||
// moment = millis();
|
// moment = millis();
|
||||||
timerRunning = true;
|
timerRunning = true;
|
||||||
Serial.println("Update timer restarted");
|
Serial.println(F("Update timer restarted"));
|
||||||
|
|
||||||
request->send(200);
|
request->send(200);
|
||||||
}
|
}
|
||||||
@ -221,7 +218,7 @@ bool processEpdColorSettings(AsyncWebServerRequest *request)
|
|||||||
AsyncWebParameter *fgColor = request->getParam("fgColor", true);
|
AsyncWebParameter *fgColor = request->getParam("fgColor", true);
|
||||||
preferences.putUInt("fgColor", strtol(fgColor->value().c_str(), NULL, 16));
|
preferences.putUInt("fgColor", strtol(fgColor->value().c_str(), NULL, 16));
|
||||||
setFgColor(int(strtol(fgColor->value().c_str(), NULL, 16)));
|
setFgColor(int(strtol(fgColor->value().c_str(), NULL, 16)));
|
||||||
Serial.print("Setting foreground color to ");
|
Serial.print(F("Setting foreground color to "));
|
||||||
Serial.println(fgColor->value().c_str());
|
Serial.println(fgColor->value().c_str());
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
}
|
}
|
||||||
@ -231,7 +228,7 @@ bool processEpdColorSettings(AsyncWebServerRequest *request)
|
|||||||
|
|
||||||
preferences.putUInt("bgColor", strtol(bgColor->value().c_str(), NULL, 16));
|
preferences.putUInt("bgColor", strtol(bgColor->value().c_str(), NULL, 16));
|
||||||
setBgColor(int(strtol(bgColor->value().c_str(), NULL, 16)));
|
setBgColor(int(strtol(bgColor->value().c_str(), NULL, 16)));
|
||||||
Serial.print("Setting background color to ");
|
Serial.print(F("Setting background color to "));
|
||||||
Serial.println(bgColor->value().c_str());
|
Serial.println(bgColor->value().c_str());
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
}
|
}
|
||||||
@ -250,7 +247,7 @@ void onApiEpdSettingsPost(AsyncWebServerRequest *request)
|
|||||||
{
|
{
|
||||||
flashTemporaryLights(0, 255, 0);
|
flashTemporaryLights(0, 255, 0);
|
||||||
|
|
||||||
Serial.println("Settings changed");
|
Serial.println(F("Settings changed"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +381,7 @@ void onApiSettingsPost(AsyncWebServerRequest *request)
|
|||||||
{
|
{
|
||||||
flashTemporaryLights(0, 255, 0);
|
flashTemporaryLights(0, 255, 0);
|
||||||
|
|
||||||
Serial.println("Settings changed");
|
Serial.println(F("Settings changed"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,7 +501,7 @@ void onApiLightsFlash(AsyncWebServerRequest *request)
|
|||||||
void onApiLightsSetColor(AsyncWebServerRequest *request)
|
void onApiLightsSetColor(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
String rgbColor = request->pathArg(0);
|
String rgbColor = request->pathArg(0);
|
||||||
int r, g, b;
|
uint r, g, b;
|
||||||
sscanf(rgbColor.c_str(), "%02x%02x%02x", &r, &g, &b);
|
sscanf(rgbColor.c_str(), "%02x%02x%02x", &r, &g, &b);
|
||||||
setLights(r, g, b);
|
setLights(r, g, b);
|
||||||
request->send(200, "text/plain", rgbColor);
|
request->send(200, "text/plain", rgbColor);
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include "screens/blockheight.hpp"
|
#include "screens/blockheight.hpp"
|
||||||
#include "screens/ticker.hpp"
|
#include "screens/ticker.hpp"
|
||||||
#include "screens/time.hpp"
|
#include "screens/time.hpp"
|
||||||
#include "screens/sats_per_dollar.hpp"
|
//#include "screens/sats_per_dollar.hpp"
|
||||||
#include "screens/halvingcountdown.hpp"
|
#include "screens/halvingcountdown.hpp"
|
||||||
|
|
||||||
#include "tasks/ha.hpp"
|
#include "tasks/ha.hpp"
|
||||||
@ -26,7 +26,7 @@
|
|||||||
#include "tasks/button.hpp"
|
#include "tasks/button.hpp"
|
||||||
#include "tasks/led_handler.hpp"
|
#include "tasks/led_handler.hpp"
|
||||||
|
|
||||||
WiFiClient wifiClientInsecure;
|
//WiFiClient wifiClientInsecure;
|
||||||
WiFiClientSecure wifiClient;
|
WiFiClientSecure wifiClient;
|
||||||
ESP32Time rtc(3600);
|
ESP32Time rtc(3600);
|
||||||
|
|
||||||
@ -63,8 +63,9 @@ void setup()
|
|||||||
|
|
||||||
TimeScreen::init();
|
TimeScreen::init();
|
||||||
BlockHeightScreen::init();
|
BlockHeightScreen::init();
|
||||||
|
HalvingCountdownScreen::init();
|
||||||
TickerScreen::init();
|
TickerScreen::init();
|
||||||
SatsPerDollarScreen::init();
|
// SatsPerDollarScreen::init();
|
||||||
|
|
||||||
#ifdef WITH_BUTTONS
|
#ifdef WITH_BUTTONS
|
||||||
setupButtonTask();
|
setupButtonTask();
|
||||||
@ -79,7 +80,7 @@ void setup()
|
|||||||
registerNewBlockCallback(BlockHeightScreen::onNewBlock);
|
registerNewBlockCallback(BlockHeightScreen::onNewBlock);
|
||||||
registerNewBlockCallback(HalvingCountdownScreen::onNewBlock);
|
registerNewBlockCallback(HalvingCountdownScreen::onNewBlock);
|
||||||
registerNewPriceCallback(TickerScreen::onPriceUpdate);
|
registerNewPriceCallback(TickerScreen::onPriceUpdate);
|
||||||
registerNewPriceCallback(SatsPerDollarScreen::onPriceUpdate);
|
// registerNewPriceCallback(SatsPerDollarScreen::onPriceUpdate);
|
||||||
|
|
||||||
setupDisplays();
|
setupDisplays();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,26 +1,40 @@
|
|||||||
#include "blockheight.hpp"
|
#include "blockheight.hpp"
|
||||||
|
|
||||||
uint BlockHeightScreen::blockNr = 0;
|
uint BlockHeightScreen::blockNr = 0;
|
||||||
std::array<String, NUM_SCREENS> BlockHeightScreen::epdContent = { "", "", "", "", "", "", "" };
|
char **BlockHeightScreen::epdContent;
|
||||||
|
const int maxStringLength = 15;
|
||||||
//std::array<String, NUM_SCREENS> * BlockHeightScreen::epdContent = (std::array<String, NUM_SCREENS> * ) ps_malloc(7 * sizeof (std::array<String, NUM_SCREENS>));
|
char* BlockHeightScreen::psramBuffer;
|
||||||
|
|
||||||
|
|
||||||
void BlockHeightScreen::init()
|
void BlockHeightScreen::init()
|
||||||
{
|
{
|
||||||
|
BlockHeightScreen::psramBuffer = (char*)ps_malloc(NUM_SCREENS * maxStringLength);
|
||||||
|
|
||||||
|
if (BlockHeightScreen::psramBuffer == nullptr)
|
||||||
|
{
|
||||||
|
Serial.println(F("Failed to allocate memory in PSRAM"));
|
||||||
|
}
|
||||||
|
BlockHeightScreen::epdContent = new char*[NUM_SCREENS];
|
||||||
|
for (int i = 0; i < NUM_SCREENS; i++)
|
||||||
|
{
|
||||||
|
epdContent[i] = psramBuffer + i * maxStringLength;
|
||||||
|
}
|
||||||
BlockHeightScreen::blockNr = preferences.getUInt("blockHeight", 789000);
|
BlockHeightScreen::blockNr = preferences.getUInt("blockHeight", 789000);
|
||||||
setupBlockNotify();
|
setupBlockNotify();
|
||||||
BlockHeightScreen::showScreen();
|
BlockHeightScreen::showScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockHeightScreen::showScreen()
|
void BlockHeightScreen::showScreen()
|
||||||
{
|
{
|
||||||
std::string blockNrString = String(BlockHeightScreen::blockNr).c_str();
|
std::string blockNrString = String(BlockHeightScreen::blockNr).c_str();
|
||||||
blockNrString.insert(blockNrString.begin(), NUM_SCREENS - blockNrString.length(), ' ');
|
blockNrString.insert(blockNrString.begin(), NUM_SCREENS - blockNrString.length(), ' ');
|
||||||
epdContent[0] = "BLOCK/HEIGHT";
|
// epdContent[0] = "BLOCK/HEIGHT";
|
||||||
|
snprintf(BlockHeightScreen::epdContent[0], 13, "BLOCK/HEIGHT", 0);
|
||||||
|
|
||||||
for (uint i = 1; i < NUM_SCREENS; i++)
|
for (uint i = 1; i < NUM_SCREENS; i++)
|
||||||
{
|
{
|
||||||
BlockHeightScreen::epdContent[i] = blockNrString[i];
|
snprintf(BlockHeightScreen::epdContent[i], 2, &blockNrString[i], 0);
|
||||||
|
|
||||||
|
// BlockHeightScreen::epdContent[i] = blockNrString[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +45,16 @@ void BlockHeightScreen::onNewBlock(uint blockNr)
|
|||||||
BlockHeightScreen::showScreen();
|
BlockHeightScreen::showScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<String, 7> BlockHeightScreen::getEpdContent() {
|
std::array<String, NUM_SCREENS> BlockHeightScreen::getEpdContent()
|
||||||
return BlockHeightScreen::epdContent;
|
{
|
||||||
|
std::array<String, NUM_SCREENS> ret;
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_SCREENS; i++)
|
||||||
|
{
|
||||||
|
ret[i] = BlockHeightScreen::epdContent[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::copy(std::begin(BlockHeightScreen::epdContent), std::end(BlockHeightScreen::epdContent), std::begin(ret));
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
@ -6,13 +6,15 @@
|
|||||||
#include "tasks/epd.hpp"
|
#include "tasks/epd.hpp"
|
||||||
#include "tasks/blocknotify.hpp"
|
#include "tasks/blocknotify.hpp"
|
||||||
|
|
||||||
class BlockHeightScreen {
|
class BlockHeightScreen
|
||||||
protected:
|
{
|
||||||
static uint blockNr;
|
protected:
|
||||||
static std::array<String, NUM_SCREENS> epdContent;
|
static uint blockNr;
|
||||||
public:
|
static char** epdContent;
|
||||||
static void init();
|
static char* psramBuffer;
|
||||||
static void showScreen();
|
public:
|
||||||
static void onNewBlock(uint blockNr);
|
static void init();
|
||||||
static std::array<String, NUM_SCREENS> getEpdContent();
|
static void showScreen();
|
||||||
|
static void onNewBlock(uint blockNr);
|
||||||
|
static std::array<String, NUM_SCREENS> getEpdContent();
|
||||||
};
|
};
|
@ -38,6 +38,6 @@ void CountdownScreen::countdownTask(void *pvParameters)
|
|||||||
}
|
}
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
}
|
}
|
||||||
Serial.println("Countdown finished!");
|
Serial.println(F("Countdown finished!"));
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
@ -3,33 +3,63 @@
|
|||||||
uint HalvingCountdownScreen::currentBlockNr = 0;
|
uint HalvingCountdownScreen::currentBlockNr = 0;
|
||||||
uint HalvingCountdownScreen::halvingBlockNr = 0;
|
uint HalvingCountdownScreen::halvingBlockNr = 0;
|
||||||
|
|
||||||
std::array<String, NUM_SCREENS> HalvingCountdownScreen::epdContent = {"", "", "", "", "", "", ""};
|
char **HalvingCountdownScreen::epdContentP;
|
||||||
|
const int maxStringLength = 12;
|
||||||
|
char *HalvingCountdownScreen::psramBuffer;
|
||||||
|
|
||||||
|
//char HalvingCountdownScreen::epdContent[NUM_SCREENS][maxStringLength];
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
void HalvingCountdownScreen::init()
|
void HalvingCountdownScreen::init()
|
||||||
{
|
{
|
||||||
HalvingCountdownScreen::currentBlockNr = preferences.getUInt("blockHeight", 789000);
|
HalvingCountdownScreen::currentBlockNr = preferences.getUInt("blockHeight", 789000);
|
||||||
|
|
||||||
|
HalvingCountdownScreen::psramBuffer = (char *)ps_malloc(NUM_SCREENS * maxStringLength);
|
||||||
|
|
||||||
|
if (HalvingCountdownScreen::psramBuffer == nullptr)
|
||||||
|
{
|
||||||
|
Serial.println(F("Failed to allocate memory in PSRAM (HalvingCountdownScreen)"));
|
||||||
|
}
|
||||||
|
HalvingCountdownScreen::epdContentP = new char*[NUM_SCREENS];
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_SCREENS; i++)
|
||||||
|
{
|
||||||
|
epdContentP[i] = HalvingCountdownScreen::psramBuffer + i * maxStringLength;
|
||||||
|
// strcpy(epdContent[i], "x");
|
||||||
|
strcpy(epdContentP[i], "x");
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
setupBlockNotify();
|
setupBlockNotify();
|
||||||
HalvingCountdownScreen::showScreen();
|
HalvingCountdownScreen::showScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HalvingCountdownScreen::showScreen()
|
void HalvingCountdownScreen::showScreen()
|
||||||
{
|
{
|
||||||
|
if (!initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
uint minutesToHalving = HalvingCountdownScreen::getNextHalvingBlockNr() * 10;
|
uint minutesToHalving = HalvingCountdownScreen::getNextHalvingBlockNr() * 10;
|
||||||
|
|
||||||
int years = floor(minutesToHalving / 525600);
|
const int years = floor(minutesToHalving / 525600);
|
||||||
int days = floor((minutesToHalving - (years * 525600)) / (24*60));
|
const int days = floor((minutesToHalving - (years * 525600)) / (24 * 60));
|
||||||
int hours = floor((minutesToHalving - (years * 525600) - (days * (24*60))) / 60);
|
const int hours = floor((minutesToHalving - (years * 525600) - (days * (24 * 60))) / 60);
|
||||||
int mins = floor(minutesToHalving - (years * 525600) - (days * (24*60)) - (hours * 60));
|
const int mins = floor(minutesToHalving - (years * 525600) - (days * (24 * 60)) - (hours * 60));
|
||||||
// int secs = floor((minutesToHalving - (years * 525600) - (days * (24*60)) - (hours * 60) - mins) * 60);
|
// int secs = floor((minutesToHalving - (years * 525600) - (days * (24*60)) - (hours * 60) - mins) * 60);
|
||||||
|
|
||||||
epdContent[0] = F("BIT/COIN");
|
snprintf(HalvingCountdownScreen::epdContentP[0], maxStringLength, "BIT/COIN");
|
||||||
epdContent[1] = F("HALV/ING");
|
snprintf(HalvingCountdownScreen::epdContentP[1], maxStringLength, "HALV/ING");
|
||||||
epdContent[2] = String(years) + "/YRS";
|
snprintf(HalvingCountdownScreen::epdContentP[2], maxStringLength, "%d/YRS", years);
|
||||||
epdContent[3] = String(days) + "/DAYS";
|
|
||||||
epdContent[4] = String(hours) + "/HRS";
|
snprintf(HalvingCountdownScreen::epdContentP[3], maxStringLength, "%d/DAYS", days);
|
||||||
epdContent[5] = String(mins) + "/MINS";
|
snprintf(HalvingCountdownScreen::epdContentP[4], maxStringLength, "%d/HRS", hours);
|
||||||
epdContent[6] = F("TO/GO");
|
snprintf(HalvingCountdownScreen::epdContentP[5], maxStringLength, "%d/MINS", mins);
|
||||||
|
snprintf(HalvingCountdownScreen::epdContentP[6], maxStringLength, "TO/GO");
|
||||||
|
|
||||||
|
// // strcpy(epdContent[2], sprintf(String(years) + "/YRS").c_str());
|
||||||
|
// // snprintf(epdContent[2], sizeof(epdContent[2]), "%d/YRS", years);
|
||||||
|
// // strcpy(epdContent[3], String(days) + "/DAYS");
|
||||||
|
// // strcpy(epdContent[4], String(hours) + "/HRS");
|
||||||
|
// // strcpy(epdContent[5], String(mins) + "/MINS");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint HalvingCountdownScreen::getNextHalvingBlockNr()
|
uint HalvingCountdownScreen::getNextHalvingBlockNr()
|
||||||
@ -46,5 +76,14 @@ void HalvingCountdownScreen::onNewBlock(uint blockNr)
|
|||||||
|
|
||||||
std::array<String, NUM_SCREENS> HalvingCountdownScreen::getEpdContent()
|
std::array<String, NUM_SCREENS> HalvingCountdownScreen::getEpdContent()
|
||||||
{
|
{
|
||||||
return HalvingCountdownScreen::epdContent;
|
std::array<String, NUM_SCREENS> ret;
|
||||||
|
|
||||||
|
if (!initialized) return ret;
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_SCREENS; i++)
|
||||||
|
{
|
||||||
|
ret[i] = HalvingCountdownScreen::epdContentP[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
@ -6,15 +6,21 @@
|
|||||||
#include "tasks/epd.hpp"
|
#include "tasks/epd.hpp"
|
||||||
#include "tasks/blocknotify.hpp"
|
#include "tasks/blocknotify.hpp"
|
||||||
|
|
||||||
class HalvingCountdownScreen {
|
class HalvingCountdownScreen
|
||||||
protected:
|
{
|
||||||
static uint currentBlockNr;
|
protected:
|
||||||
static uint halvingBlockNr;
|
static uint currentBlockNr;
|
||||||
static std::array<String, NUM_SCREENS> epdContent;
|
static uint halvingBlockNr;
|
||||||
public:
|
//static std::array<char*, NUM_SCREENS> epdContent;
|
||||||
static void init();
|
// static char epdContent[NUM_SCREENS][12];
|
||||||
static void showScreen();
|
static char** epdContentP;
|
||||||
static void onNewBlock(uint blockNr);
|
// static char **epdContent;
|
||||||
static uint getNextHalvingBlockNr();
|
static char *psramBuffer;
|
||||||
static std::array<String, NUM_SCREENS> getEpdContent();
|
|
||||||
|
public:
|
||||||
|
static void init();
|
||||||
|
static void showScreen();
|
||||||
|
static void onNewBlock(uint blockNr);
|
||||||
|
static uint getNextHalvingBlockNr();
|
||||||
|
static std::array<String, NUM_SCREENS> getEpdContent();
|
||||||
};
|
};
|
@ -1,30 +1,30 @@
|
|||||||
#include "sats_per_dollar.hpp"
|
// #include "sats_per_dollar.hpp"
|
||||||
|
|
||||||
uint SatsPerDollarScreen::satsPerDollar = 0;
|
// uint SatsPerDollarScreen::satsPerDollar = 0;
|
||||||
std::array<String, NUM_SCREENS> SatsPerDollarScreen::epdContent = { "", "", "", "", "", "", "" };
|
// std::array<String, NUM_SCREENS> SatsPerDollarScreen::epdContent = { "", "", "", "", "", "", "" };
|
||||||
|
|
||||||
void SatsPerDollarScreen::init() {
|
// void SatsPerDollarScreen::init() {
|
||||||
SatsPerDollarScreen::satsPerDollar = int(round(1 / preferences.getFloat("btcPrice", 12345) * 10e7));
|
// SatsPerDollarScreen::satsPerDollar = int(round(1 / preferences.getFloat("btcPrice", 12345) * 10e7));
|
||||||
setupGetPriceTask();
|
// setupGetPriceTask();
|
||||||
SatsPerDollarScreen::showScreen();
|
// SatsPerDollarScreen::showScreen();
|
||||||
}
|
// }
|
||||||
|
|
||||||
void SatsPerDollarScreen::showScreen() {
|
// void SatsPerDollarScreen::showScreen() {
|
||||||
std::string satsPerDollarString = String(SatsPerDollarScreen::satsPerDollar).c_str();
|
// std::string satsPerDollarString = String(SatsPerDollarScreen::satsPerDollar).c_str();
|
||||||
satsPerDollarString.insert(satsPerDollarString.begin(), 7 - satsPerDollarString.length(), ' ');
|
// satsPerDollarString.insert(satsPerDollarString.begin(), 7 - satsPerDollarString.length(), ' ');
|
||||||
epdContent[0] = "MSCW/TIME";
|
// epdContent[0] = "MSCW/TIME";
|
||||||
for (uint i = 1; i < NUM_SCREENS; i++)
|
// for (uint i = 1; i < NUM_SCREENS; i++)
|
||||||
{
|
// {
|
||||||
SatsPerDollarScreen::epdContent[i] = satsPerDollarString[i];
|
// SatsPerDollarScreen::epdContent[i] = satsPerDollarString[i];
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
void SatsPerDollarScreen::onPriceUpdate(uint price) {
|
// void SatsPerDollarScreen::onPriceUpdate(uint price) {
|
||||||
SatsPerDollarScreen::satsPerDollar = int(round(1 / float(price) * 10e7));
|
// SatsPerDollarScreen::satsPerDollar = int(round(1 / float(price) * 10e7));
|
||||||
|
|
||||||
SatsPerDollarScreen::showScreen();
|
// SatsPerDollarScreen::showScreen();
|
||||||
}
|
// }
|
||||||
|
|
||||||
std::array<String, NUM_SCREENS> SatsPerDollarScreen::getEpdContent() {
|
// std::array<String, NUM_SCREENS> SatsPerDollarScreen::getEpdContent() {
|
||||||
return SatsPerDollarScreen::epdContent;
|
// return SatsPerDollarScreen::epdContent;
|
||||||
}
|
// }
|
@ -1,17 +1,17 @@
|
|||||||
#pragma once
|
// #pragma once
|
||||||
|
|
||||||
#include "base.hpp"
|
// #include "base.hpp"
|
||||||
#include "config.h"
|
// #include "config.h"
|
||||||
#include "shared.hpp"
|
// #include "shared.hpp"
|
||||||
#include "tasks/epd.hpp"
|
// #include "tasks/epd.hpp"
|
||||||
|
|
||||||
class SatsPerDollarScreen {
|
// class SatsPerDollarScreen {
|
||||||
protected:
|
// protected:
|
||||||
static uint satsPerDollar;
|
// static uint satsPerDollar;
|
||||||
static std::array<String, NUM_SCREENS> epdContent;
|
// static std::array<String, NUM_SCREENS> epdContent;
|
||||||
public:
|
// public:
|
||||||
static void init();
|
// static void init();
|
||||||
static void showScreen();
|
// static void showScreen();
|
||||||
static void onPriceUpdate(uint price);
|
// static void onPriceUpdate(uint price);
|
||||||
static std::array<String, NUM_SCREENS> getEpdContent();
|
// static std::array<String, NUM_SCREENS> getEpdContent();
|
||||||
};
|
// };
|
@ -1,10 +1,15 @@
|
|||||||
#include "ticker.hpp"
|
#include "ticker.hpp"
|
||||||
|
|
||||||
uint TickerScreen::price = 12345;
|
uint TickerScreen::price = 12345;
|
||||||
|
uint TickerScreen::satsPerDollar = 3000;
|
||||||
|
|
||||||
std::array<String, NUM_SCREENS> TickerScreen::epdContent = { "", "", "", "", "", "", "" };
|
std::array<String, NUM_SCREENS> TickerScreen::epdContent = { "", "", "", "", "", "", "" };
|
||||||
|
|
||||||
void TickerScreen::init() {
|
void TickerScreen::init() {
|
||||||
|
|
||||||
TickerScreen::price = preferences.getFloat("btcPrice", 12345);;
|
TickerScreen::price = preferences.getFloat("btcPrice", 12345);;
|
||||||
|
TickerScreen::satsPerDollar = int(round(1 / preferences.getFloat("btcPrice", 12345) * 10e7));
|
||||||
|
|
||||||
setupGetPriceTask();
|
setupGetPriceTask();
|
||||||
TickerScreen::showScreen();
|
TickerScreen::showScreen();
|
||||||
}
|
}
|
||||||
@ -21,9 +26,26 @@ void TickerScreen::showScreen() {
|
|||||||
|
|
||||||
void TickerScreen::onPriceUpdate(uint price) {
|
void TickerScreen::onPriceUpdate(uint price) {
|
||||||
TickerScreen::price = price;
|
TickerScreen::price = price;
|
||||||
|
TickerScreen::satsPerDollar = int(round(1 / float(price) * 10e7));
|
||||||
|
|
||||||
TickerScreen::showScreen();
|
TickerScreen::showScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<String, NUM_SCREENS> TickerScreen::getEpdContent() {
|
std::array<String, NUM_SCREENS> TickerScreen::getEpdContent() {
|
||||||
return TickerScreen::epdContent;
|
return TickerScreen::epdContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<String, NUM_SCREENS> TickerScreen::getEpdContentSats() {
|
||||||
|
std::array<String, NUM_SCREENS> epdContentSats = { "", "", "", "", "", "", "" };
|
||||||
|
|
||||||
|
std::string satsPerDollarString = String(TickerScreen::satsPerDollar).c_str();
|
||||||
|
satsPerDollarString.insert(satsPerDollarString.begin(), NUM_SCREENS - satsPerDollarString.length(), ' ');
|
||||||
|
epdContentSats[0] = "MSCW/TIME";
|
||||||
|
for (uint i = 1; i < NUM_SCREENS; i++)
|
||||||
|
{
|
||||||
|
epdContentSats[i] = satsPerDollarString[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return epdContentSats;
|
||||||
}
|
}
|
@ -9,11 +9,13 @@ class TickerScreen
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
static uint price;
|
static uint price;
|
||||||
static std::array<String, NUM_SCREENS> epdContent;
|
static uint satsPerDollar;
|
||||||
|
|
||||||
|
static std::array<String, NUM_SCREENS> epdContent;
|
||||||
public:
|
public:
|
||||||
static void init();
|
static void init();
|
||||||
static void showScreen();
|
static void showScreen();
|
||||||
static void onPriceUpdate(uint price);
|
static void onPriceUpdate(uint price);
|
||||||
static std::array<String, NUM_SCREENS> getEpdContent();
|
static std::array<String, NUM_SCREENS> getEpdContent();
|
||||||
|
static std::array<String, NUM_SCREENS> getEpdContentSats();
|
||||||
};
|
};
|
@ -1,11 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
//##include <Crypto.h>
|
//##include <Crypto.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#ifdef IS_BW
|
||||||
|
#include <GxEPD2_BW.h>
|
||||||
|
#else
|
||||||
|
#include <GxEPD2_3C.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <WiFiClientSecure.h>
|
#include <WiFiClientSecure.h>
|
||||||
#ifndef NO_MCP
|
#ifndef NO_MCP
|
||||||
#include <Adafruit_MCP23X17.h>
|
#include <Adafruit_MCP23X17.h>
|
||||||
@ -19,7 +26,7 @@
|
|||||||
typedef std::function<void()> EventCallback;
|
typedef std::function<void()> EventCallback;
|
||||||
typedef std::function<void(uint number)> EventCallbackWithNumber;
|
typedef std::function<void(uint number)> EventCallbackWithNumber;
|
||||||
|
|
||||||
extern WiFiClient wifiClientInsecure;
|
//extern WiFiClient wifiClientInsecure;
|
||||||
extern WiFiClientSecure wifiClient;
|
extern WiFiClientSecure wifiClient;
|
||||||
|
|
||||||
extern ESP32Time rtc;
|
extern ESP32Time rtc;
|
||||||
@ -32,9 +39,11 @@ extern bool timerRunning;
|
|||||||
extern uint timerSeconds;
|
extern uint timerSeconds;
|
||||||
extern uint32_t moment;
|
extern uint32_t moment;
|
||||||
|
|
||||||
|
extern GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT> displays[NUM_SCREENS];
|
||||||
|
|
||||||
#ifndef NO_MCP
|
#ifndef NO_MCP
|
||||||
extern Adafruit_MCP23X17 mcp;
|
extern Adafruit_MCP23X17 mcp;
|
||||||
extern const int MCP_INT_PIN;
|
extern const char MCP_INT_PIN;
|
||||||
#endif
|
#endif
|
||||||
#ifdef WITH_RGB_LED
|
#ifdef WITH_RGB_LED
|
||||||
extern Adafruit_NeoPixel pixels;
|
extern Adafruit_NeoPixel pixels;
|
||||||
@ -53,13 +62,17 @@ const PROGMEM int screens[5] = { SCREEN_BLOCK_HEIGHT, SCREEN_MSCW_TIME, SCREEN_B
|
|||||||
const uint screenCount = sizeof(screens) / sizeof(int);
|
const uint screenCount = sizeof(screens) / sizeof(int);
|
||||||
|
|
||||||
struct SpiRamAllocator {
|
struct SpiRamAllocator {
|
||||||
void* allocate(size_t size) {
|
void* allocate(size_t size) {
|
||||||
return ps_malloc(size);
|
return heap_caps_malloc(size, MALLOC_CAP_SPIRAM);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
void deallocate(void* pointer) {
|
||||||
void deallocate(void* pointer) {
|
heap_caps_free(pointer);
|
||||||
free(pointer);
|
}
|
||||||
}
|
|
||||||
|
void* reallocate(void* ptr, size_t new_size) {
|
||||||
|
return heap_caps_realloc(ptr, new_size, MALLOC_CAP_SPIRAM);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using SpiRamJsonDocument = BasicJsonDocument<SpiRamAllocator>;
|
using SpiRamJsonDocument = BasicJsonDocument<SpiRamAllocator>;
|
||||||
|
@ -20,11 +20,11 @@ void checkBitcoinBlock(void *pvParameters)
|
|||||||
uint blockHeight = preferences.getUInt("blockHeight", currentBlockHeight);
|
uint blockHeight = preferences.getUInt("blockHeight", currentBlockHeight);
|
||||||
|
|
||||||
|
|
||||||
useBitcoind = preferences.getBool("useNode", false) && wifiClientInsecure.connect(preferences.getString("rpcHost", BITCOIND_HOST).c_str(), preferences.getUInt("rpcPort", BITCOIND_PORT));
|
useBitcoind = preferences.getBool("useNode", false) && wifiClient.connect(preferences.getString("rpcHost", BITCOIND_HOST).c_str(), preferences.getUInt("rpcPort", BITCOIND_PORT));
|
||||||
if (useBitcoind)
|
if (useBitcoind)
|
||||||
Serial.println("bitcoind node is reachable, using this for blocks.");
|
Serial.println(F("bitcoind node is reachable, using this for blocks."));
|
||||||
else
|
else
|
||||||
Serial.println("bitcoind node is not reachable, using mempool API instead.");
|
Serial.println(F("bitcoind node is not reachable, using mempool API instead."));
|
||||||
|
|
||||||
IPAddress result;
|
IPAddress result;
|
||||||
|
|
||||||
@ -36,53 +36,53 @@ void checkBitcoinBlock(void *pvParameters)
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
HTTPClient http;
|
HTTPClient *http = new HTTPClient();
|
||||||
http.setUserAgent(USER_AGENT);
|
http->setUserAgent(USER_AGENT);
|
||||||
|
|
||||||
if (useBitcoind)
|
if (useBitcoind)
|
||||||
{
|
{
|
||||||
StaticJsonDocument<200> jsonDoc;
|
StaticJsonDocument<200> jsonDoc;
|
||||||
|
|
||||||
http.begin(preferences.getString("rpcHost", BITCOIND_HOST).c_str(), preferences.getUInt("rpcPort", BITCOIND_PORT));
|
http->begin(preferences.getString("rpcHost", BITCOIND_HOST).c_str(), preferences.getUInt("rpcPort", BITCOIND_PORT));
|
||||||
http.addHeader("Content-Type", "application/json");
|
http->addHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
const String payload = "{\"jsonrpc\":\"1.0\",\"id\":\"current_block_height\",\"method\":\"getblockcount\",\"params\":[]}";
|
const String payload = "{\"jsonrpc\":\"1.0\",\"id\":\"current_block_height\",\"method\":\"getblockcount\",\"params\":[]}";
|
||||||
const String authEncoded = base64::encode(preferences.getString("rpcUser", BITCOIND_RPC_USER) + ":" + preferences.getString("rpcPass", BITCOIND_RPC_PASS));
|
const String authEncoded = base64::encode(preferences.getString("rpcUser", BITCOIND_RPC_USER) + ":" + preferences.getString("rpcPass", BITCOIND_RPC_PASS));
|
||||||
http.addHeader("Authorization", "Basic " + authEncoded);
|
http->addHeader("Authorization", "Basic " + authEncoded);
|
||||||
|
|
||||||
int httpCode = http.POST(payload);
|
int httpCode = http->POST(payload);
|
||||||
if (httpCode > 0 || httpCode != HTTP_CODE_UNAUTHORIZED)
|
if (httpCode > 0 || httpCode != HTTP_CODE_UNAUTHORIZED)
|
||||||
{
|
{
|
||||||
String response = http.getString();
|
String response = http->getString();
|
||||||
deserializeJson(jsonDoc, response);
|
deserializeJson(jsonDoc, response);
|
||||||
blockHeight = jsonDoc["result"];
|
blockHeight = jsonDoc["result"];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Serial.println("Error in HTTP request to bitcoind");
|
Serial.println(F("Error in HTTP request to bitcoind"));
|
||||||
}
|
}
|
||||||
|
|
||||||
http.end();
|
http->end();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
http.begin("https://" + preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE) + "/api/blocks/tip/height");
|
http->begin("https://" + preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE) + "/api/blocks/tip/height");
|
||||||
int httpCode = http.GET();
|
int httpCode = http->GET();
|
||||||
|
|
||||||
if (httpCode > 0 && httpCode == HTTP_CODE_OK)
|
if (httpCode > 0 && httpCode == HTTP_CODE_OK)
|
||||||
{
|
{
|
||||||
String blockHeightStr = http.getString();
|
String blockHeightStr = http->getString();
|
||||||
blockHeight = blockHeightStr.toInt();
|
blockHeight = blockHeightStr.toInt();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Serial.print(F("Error in HTTP request to mempool API: "));
|
Serial.print(F("Error in HTTP request to mempool API: "));
|
||||||
Serial.print(httpCode);
|
Serial.print(httpCode);
|
||||||
Serial.println(http.errorToString(httpCode));
|
Serial.println(http->errorToString(httpCode));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
http.end();
|
http->end();
|
||||||
}
|
}
|
||||||
if (blockHeight > currentBlockHeight)
|
if (blockHeight > currentBlockHeight)
|
||||||
{
|
{
|
||||||
@ -93,7 +93,7 @@ void checkBitcoinBlock(void *pvParameters)
|
|||||||
currentBlockHeight = blockHeight;
|
currentBlockHeight = blockHeight;
|
||||||
preferences.putUInt("blockHeight", currentBlockHeight);
|
preferences.putUInt("blockHeight", currentBlockHeight);
|
||||||
}
|
}
|
||||||
|
delete http;
|
||||||
vTaskDelay(pdMS_TO_TICKS(BLOCKNOTIFY_WAIT_TIME)); // wait 1 minute before checking again
|
vTaskDelay(pdMS_TO_TICKS(BLOCKNOTIFY_WAIT_TIME)); // wait 1 minute before checking again
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ void setupBlockNotify()
|
|||||||
// xTaskCreate(bitcoinEventHandler, "bitcoinEventHandler", 10000, NULL, 110, NULL);
|
// xTaskCreate(bitcoinEventHandler, "bitcoinEventHandler", 10000, NULL, 110, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerNewBlockCallback(EventCallbackWithNumber cb)
|
void registerNewBlockCallback(const EventCallbackWithNumber cb)
|
||||||
{
|
{
|
||||||
blockEventCallbacks.push_back(cb);
|
blockEventCallbacks.push_back(cb);
|
||||||
}
|
}
|
@ -22,6 +22,6 @@ void checkBitcoinBlock(void *pvParameters);
|
|||||||
//void bitcoinEventHandler(void *pvParameters);
|
//void bitcoinEventHandler(void *pvParameters);
|
||||||
void setupBlockNotify();
|
void setupBlockNotify();
|
||||||
|
|
||||||
void registerNewBlockCallback(EventCallbackWithNumber cb);
|
void registerNewBlockCallback(const EventCallbackWithNumber cb);
|
||||||
int getBlockFromBitcoind();
|
int getBlockFromBitcoind();
|
||||||
int getBlockFromMempoolSpace();
|
int getBlockFromMempoolSpace();
|
@ -47,7 +47,7 @@ void buttonTask(void *parameter)
|
|||||||
void IRAM_ATTR handleButtonInterrupt()
|
void IRAM_ATTR handleButtonInterrupt()
|
||||||
{
|
{
|
||||||
buttonPressed = true;
|
buttonPressed = true;
|
||||||
// Serial.println("ISR");
|
// Serial.println(F("ISR"));
|
||||||
// uint pin = mcp.getLastInterruptPin();
|
// uint pin = mcp.getLastInterruptPin();
|
||||||
|
|
||||||
// if (pin == 1)
|
// if (pin == 1)
|
||||||
@ -70,7 +70,7 @@ void setupButtonTask()
|
|||||||
// attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, FALLING);
|
// attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, FALLING);
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerNewButtonCallback(EventCallback cb)
|
void registerNewButtonCallback(const EventCallback cb)
|
||||||
{
|
{
|
||||||
buttonEventCallbacks.push_back(cb);
|
buttonEventCallbacks.push_back(cb);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ extern TaskHandle_t buttonTaskHandle;
|
|||||||
|
|
||||||
void buttonTask(void *pvParameters);
|
void buttonTask(void *pvParameters);
|
||||||
void setupButtonTask();
|
void setupButtonTask();
|
||||||
void registerNewButtonCallback(EventCallback cb);
|
void registerNewButtonCallback(const EventCallback cb);
|
||||||
void IRAM_ATTR handleButtonInterrupt();
|
void IRAM_ATTR handleButtonInterrupt();
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,17 +1,12 @@
|
|||||||
#include "epd.hpp"
|
#include "epd.hpp"
|
||||||
|
|
||||||
#ifdef IS_S3
|
#ifdef IS_S3
|
||||||
// reversed
|
const char EPD_CS[NUM_SCREENS] = {2, 4, 6, 10, 33, 21, 17};
|
||||||
// const int EPD_CS[7] = {17, 21, 33, 10, 6, 4, 2};
|
const char EPD_BUSY[NUM_SCREENS] = {3, 5, 7, 9, 37, 18, 16};
|
||||||
// const int EPD_BUSY[7] = {16, 18, 37, 9, 7, 5, 3};
|
const char EPD_RESET_MPD[NUM_SCREENS] = {8, 9, 10, 11, 12, 13, 14};
|
||||||
// const int EPD_RESET_MPD[7] = {14, 13, 12, 11, 10, 9, 8};
|
|
||||||
|
|
||||||
const int EPD_CS[NUM_SCREENS] = {2, 4, 6, 10, 33, 21, 17};
|
const char EPD_DC = 14;
|
||||||
const int EPD_BUSY[NUM_SCREENS] = {3, 5, 7, 9, 37, 18, 16};
|
const char RST_PIN = 15;
|
||||||
const int EPD_RESET_MPD[NUM_SCREENS] = {8, 9, 10, 11, 12, 13, 14};
|
|
||||||
|
|
||||||
const int EPD_DC = 14;
|
|
||||||
const int RST_PIN = 15;
|
|
||||||
#elif defined(IS_S2)
|
#elif defined(IS_S2)
|
||||||
|
|
||||||
// reversed
|
// reversed
|
||||||
@ -56,7 +51,7 @@ GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT> displays[NUM_SCREENS] = {
|
|||||||
GxEPD2_213_B74(EPD_CS[6], EPD_DC, /*RST=*/-1, EPD_BUSY[6]),
|
GxEPD2_213_B74(EPD_CS[6], EPD_DC, /*RST=*/-1, EPD_BUSY[6]),
|
||||||
};
|
};
|
||||||
|
|
||||||
//GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT> * displays2 = (GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT> *) ps_malloc(7 * sizeof (GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT>));
|
// GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT> * displays2 = (GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT> *) ps_malloc(7 * sizeof (GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT>));
|
||||||
|
|
||||||
const int SEM_WAIT_TIME = 10000;
|
const int SEM_WAIT_TIME = 10000;
|
||||||
|
|
||||||
@ -81,7 +76,10 @@ std::array<String, 7> currentEpdContent;
|
|||||||
std::array<String, 7> epdContent;
|
std::array<String, 7> epdContent;
|
||||||
TaskHandle_t tasks[NUM_SCREENS];
|
TaskHandle_t tasks[NUM_SCREENS];
|
||||||
SemaphoreHandle_t epdUpdateSemaphore[NUM_SCREENS];
|
SemaphoreHandle_t epdUpdateSemaphore[NUM_SCREENS];
|
||||||
uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
|
//
|
||||||
|
|
||||||
|
//int *qrcode = (int *) ps_malloc(qrcodegen_BUFFER_LEN_MAX * sizeof(uint8_t));
|
||||||
|
|
||||||
|
|
||||||
void setupDisplays()
|
void setupDisplays()
|
||||||
{
|
{
|
||||||
@ -91,7 +89,7 @@ void setupDisplays()
|
|||||||
|
|
||||||
void resetAllDisplays()
|
void resetAllDisplays()
|
||||||
{
|
{
|
||||||
#ifdef NO_MCP
|
#ifdef NO_MCP
|
||||||
digitalWrite(RST_PIN, HIGH);
|
digitalWrite(RST_PIN, HIGH);
|
||||||
pinMode(RST_PIN, OUTPUT);
|
pinMode(RST_PIN, OUTPUT);
|
||||||
delay(20);
|
delay(20);
|
||||||
@ -99,23 +97,24 @@ void resetAllDisplays()
|
|||||||
delay(20);
|
delay(20);
|
||||||
digitalWrite(RST_PIN, HIGH);
|
digitalWrite(RST_PIN, HIGH);
|
||||||
delay(200);
|
delay(200);
|
||||||
#else
|
#else
|
||||||
for (int i = 0; i < NUM_SCREENS; i++) {
|
for (int i = 0; i < NUM_SCREENS; i++)
|
||||||
|
{
|
||||||
resetSingleDisplay(i);
|
resetSingleDisplay(i);
|
||||||
}
|
}
|
||||||
#endif NO_MCP
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetSingleDisplay(int i)
|
void resetSingleDisplay(int i)
|
||||||
{
|
{
|
||||||
#ifndef NO_MCP
|
#ifndef NO_MCP
|
||||||
mcp.digitalWrite(EPD_RESET_MPD[i], HIGH);
|
mcp.digitalWrite(EPD_RESET_MPD[i], HIGH);
|
||||||
delay(20);
|
delay(20);
|
||||||
mcp.digitalWrite(EPD_RESET_MPD[i], LOW);
|
mcp.digitalWrite(EPD_RESET_MPD[i], LOW);
|
||||||
delay(20);
|
delay(20);
|
||||||
mcp.digitalWrite(EPD_RESET_MPD[i], HIGH);
|
mcp.digitalWrite(EPD_RESET_MPD[i], HIGH);
|
||||||
delay(200);
|
delay(200);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void initDisplays()
|
void initDisplays()
|
||||||
@ -166,7 +165,7 @@ void taskEpd(void *pvParameters)
|
|||||||
epdContent = TickerScreen::getEpdContent();
|
epdContent = TickerScreen::getEpdContent();
|
||||||
break;
|
break;
|
||||||
case SCREEN_MSCW_TIME:
|
case SCREEN_MSCW_TIME:
|
||||||
epdContent = SatsPerDollarScreen::getEpdContent();
|
epdContent = TickerScreen::getEpdContentSats();
|
||||||
break;
|
break;
|
||||||
case SCREEN_TIME:
|
case SCREEN_TIME:
|
||||||
epdContent = TimeScreen::getEpdContent();
|
epdContent = TimeScreen::getEpdContent();
|
||||||
@ -182,10 +181,8 @@ void taskEpd(void *pvParameters)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool updatedThisCycle = false;
|
bool updatedThisCycle = false;
|
||||||
|
|
||||||
|
|
||||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||||
{
|
{
|
||||||
if (epdContent[i].compareTo(currentEpdContent[i]) != 0)
|
if (epdContent[i].compareTo(currentEpdContent[i]) != 0)
|
||||||
@ -214,12 +211,12 @@ void taskEpd(void *pvParameters)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_RGB_LED
|
#ifdef WITH_RGB_LED
|
||||||
if (updatedThisCycle && preferences.getBool("ledFlashOnUpd", false))
|
if (updatedThisCycle && preferences.getBool("ledFlashOnUpd", false))
|
||||||
{
|
{
|
||||||
xTaskNotifyGive(ledHandlerTaskHandle);
|
xTaskNotifyGive(ledHandlerTaskHandle);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
}
|
}
|
||||||
@ -321,7 +318,7 @@ void updateDisplay(void *pvParameters)
|
|||||||
bool updatePartial = true;
|
bool updatePartial = true;
|
||||||
|
|
||||||
// Full Refresh every half hour
|
// Full Refresh every half hour
|
||||||
if (!lastFullRefresh[epdIndex] || (millis() - lastFullRefresh[epdIndex]) > (preferences.getUInt("fullRefreshMin", 30) * 60 * 1000))
|
if (!lastFullRefresh[epdIndex] || (millis() - lastFullRefresh[epdIndex]) > (preferences.getUInt("fullRefreshMin", 30) * 60 * 1000))
|
||||||
{
|
{
|
||||||
updatePartial = false;
|
updatePartial = false;
|
||||||
lastFullRefresh[epdIndex] = millis();
|
lastFullRefresh[epdIndex] = millis();
|
||||||
@ -346,96 +343,3 @@ void updateDisplay(void *pvParameters)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showSetupQr(String ssid, String password)
|
|
||||||
{
|
|
||||||
int displayIndex = 6;
|
|
||||||
|
|
||||||
const String text = "WIFI:S:" + ssid + ";T:WPA;P:" + password + ";;";
|
|
||||||
|
|
||||||
uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
|
|
||||||
bool ok = qrcodegen_encodeText(text.c_str(), tempBuffer, qrcode, qrcodegen_Ecc_LOW,
|
|
||||||
qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
|
|
||||||
|
|
||||||
const int size = qrcodegen_getSize(qrcode);
|
|
||||||
|
|
||||||
const int padding = floor(float(displays[displayIndex].width() - (size * 4)) / 2);
|
|
||||||
const int paddingY = floor(float(displays[displayIndex].height() - (size * 4)) / 2);
|
|
||||||
|
|
||||||
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
|
||||||
displays[displayIndex].firstPage();
|
|
||||||
|
|
||||||
displays[displayIndex].fillScreen(GxEPD_WHITE);
|
|
||||||
int border = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
for (int y = -border; y < size * 4 + border; y++)
|
|
||||||
{
|
|
||||||
for (int x = -border; x < size * 4 + border; x++)
|
|
||||||
{
|
|
||||||
displays[displayIndex].drawPixel(padding + x, paddingY + y, qrcodegen_getModule(qrcode, floor(float(x) / 4), floor(float(y) / 4)) ? GxEPD_BLACK : GxEPD_WHITE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (displays[displayIndex].nextPage());
|
|
||||||
|
|
||||||
displayIndex = 4;
|
|
||||||
|
|
||||||
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
|
||||||
displays[displayIndex].firstPage();
|
|
||||||
|
|
||||||
displays[displayIndex].fillScreen(GxEPD_WHITE);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
displays[displayIndex].setTextColor(GxEPD_BLACK);
|
|
||||||
displays[displayIndex].setCursor(0, 50);
|
|
||||||
displays[displayIndex].setFont(&FreeSansBold9pt7b);
|
|
||||||
displays[displayIndex].println("SSID:");
|
|
||||||
displays[displayIndex].setFont(&FreeSans9pt7b);
|
|
||||||
displays[displayIndex].println(ssid);
|
|
||||||
displays[displayIndex].println("");
|
|
||||||
displays[displayIndex].setFont(&FreeSansBold9pt7b);
|
|
||||||
displays[displayIndex].println("Password:");
|
|
||||||
displays[displayIndex].setFont(&FreeSans9pt7b);
|
|
||||||
displays[displayIndex].println(password);
|
|
||||||
} while (displays[displayIndex].nextPage());
|
|
||||||
|
|
||||||
displayIndex = 2;
|
|
||||||
|
|
||||||
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
|
||||||
displays[displayIndex].firstPage();
|
|
||||||
|
|
||||||
displays[displayIndex].fillScreen(GxEPD_WHITE);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
displays[displayIndex].setTextColor(GxEPD_BLACK);
|
|
||||||
displays[displayIndex].setCursor(0, 50);
|
|
||||||
displays[displayIndex].setFont(&FreeSans9pt7b);
|
|
||||||
displays[displayIndex].println("To setup");
|
|
||||||
displays[displayIndex].println("scan QR or");
|
|
||||||
displays[displayIndex].println("connect");
|
|
||||||
displays[displayIndex].println("manually");
|
|
||||||
} while (displays[displayIndex].nextPage());
|
|
||||||
|
|
||||||
displayIndex = 0;
|
|
||||||
|
|
||||||
displays[displayIndex].setPartialWindow(0, 0, displays[displayIndex].width(), displays[displayIndex].height());
|
|
||||||
displays[displayIndex].firstPage();
|
|
||||||
|
|
||||||
displays[displayIndex].fillScreen(GxEPD_WHITE);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
displays[displayIndex].setTextColor(GxEPD_BLACK);
|
|
||||||
displays[displayIndex].setCursor(0, 50);
|
|
||||||
displays[displayIndex].setFont(&FreeSansBold9pt7b);
|
|
||||||
displays[displayIndex].println("Welcome!");
|
|
||||||
} while (displays[displayIndex].nextPage());
|
|
||||||
|
|
||||||
for (int i = 1; i < NUM_SCREENS; (i = i+2)) {
|
|
||||||
displays[i].setPartialWindow(0, 0, displays[i].width(), displays[i].height());
|
|
||||||
displays[i].fillScreen(GxEPD_WHITE);
|
|
||||||
displays[i].display(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < NUM_SCREENS; i++) {
|
|
||||||
displays[i].hibernate();
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,8 +5,7 @@
|
|||||||
#else
|
#else
|
||||||
#include <GxEPD2_3C.h>
|
#include <GxEPD2_3C.h>
|
||||||
#endif
|
#endif
|
||||||
#include <Fonts/FreeSansBold9pt7b.h>
|
|
||||||
#include <Fonts/FreeSans9pt7b.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "screens/blockheight.hpp"
|
#include "screens/blockheight.hpp"
|
||||||
@ -17,7 +16,6 @@
|
|||||||
#include "screens/custom_text.hpp"
|
#include "screens/custom_text.hpp"
|
||||||
#include "screens/halvingcountdown.hpp"
|
#include "screens/halvingcountdown.hpp"
|
||||||
|
|
||||||
#include "qrcodegen.h"
|
|
||||||
|
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
#include <freertos/task.h>
|
#include <freertos/task.h>
|
||||||
@ -47,4 +45,3 @@ void refreshDisplay(void *pvParameters);
|
|||||||
void fullRefresh(void *pvParameters);
|
void fullRefresh(void *pvParameters);
|
||||||
void updateDisplay(void *pvParameters);
|
void updateDisplay(void *pvParameters);
|
||||||
//void genQrCode(String text, uint8_t *qrcode[qrcodegen_BUFFER_LEN_MAX]);
|
//void genQrCode(String text, uint8_t *qrcode[qrcodegen_BUFFER_LEN_MAX]);
|
||||||
void showSetupQr(String ssid, String password);
|
|
@ -14,29 +14,37 @@ TaskHandle_t getPriceTaskHandle;
|
|||||||
|
|
||||||
void taskGetPrice(void *pvParameters)
|
void taskGetPrice(void *pvParameters)
|
||||||
{
|
{
|
||||||
|
IPAddress result;
|
||||||
|
|
||||||
|
int err = WiFi.hostByName("api.coingecko.com", result) ;
|
||||||
|
|
||||||
|
if (err != 1) {
|
||||||
|
flashTemporaryLights(255, 255, 0);
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
HTTPClient http;
|
HTTPClient* http = new HTTPClient();
|
||||||
http.setUserAgent(USER_AGENT);
|
http->setUserAgent(USER_AGENT);
|
||||||
|
|
||||||
if (true)
|
if (true)
|
||||||
{
|
{
|
||||||
// Send HTTP request to CoinGecko API
|
// Send HTTP request to CoinGecko API
|
||||||
http.begin(cgApiUrl);
|
http->begin(cgApiUrl);
|
||||||
|
|
||||||
int httpCode = http.GET();
|
int httpCode = http->GET();
|
||||||
|
|
||||||
// Parse JSON response and extract average price
|
// Parse JSON response and extract average price
|
||||||
float usdPrice, eurPrice;
|
float usdPrice, eurPrice;
|
||||||
if (httpCode == 200)
|
if (httpCode == 200)
|
||||||
{
|
{
|
||||||
String payload = http.getString();
|
String payload = http->getString();
|
||||||
SpiRamJsonDocument doc(768);
|
SpiRamJsonDocument doc(768);
|
||||||
deserializeJson(doc, payload);
|
deserializeJson(doc, payload);
|
||||||
JsonObject bpi = doc["bitcoin"];
|
JsonObject bpi = doc["bitcoin"];
|
||||||
usdPrice = bpi["usd"];
|
usdPrice = bpi["usd"];
|
||||||
eurPrice = bpi["eur"];
|
eurPrice = bpi["eur"];
|
||||||
for (auto &callback : priceEventCallbacks)
|
for (EventCallbackWithNumber &callback : priceEventCallbacks)
|
||||||
{ // Loop through all the event callbacks and call them
|
{ // Loop through all the event callbacks and call them
|
||||||
callback(usdPrice);
|
callback(usdPrice);
|
||||||
}
|
}
|
||||||
@ -52,21 +60,21 @@ void taskGetPrice(void *pvParameters)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Send HTTP request to CoinDesk API
|
// Send HTTP request to CoinDesk API
|
||||||
http.begin(apiUrl);
|
http->begin(apiUrl);
|
||||||
|
|
||||||
int httpCode = http.GET();
|
int httpCode = http->GET();
|
||||||
|
|
||||||
// Parse JSON response and extract average price
|
// Parse JSON response and extract average price
|
||||||
float usdPrice, eurPrice;
|
float usdPrice, eurPrice;
|
||||||
if (httpCode == 200)
|
if (httpCode == 200)
|
||||||
{
|
{
|
||||||
String payload = http.getString();
|
String payload = http->getString();
|
||||||
SpiRamJsonDocument doc(768);
|
SpiRamJsonDocument doc(768);
|
||||||
deserializeJson(doc, payload);
|
deserializeJson(doc, payload);
|
||||||
JsonObject bpi = doc["bpi"];
|
JsonObject bpi = doc["bpi"];
|
||||||
usdPrice = bpi["USD"]["rate_float"];
|
usdPrice = bpi["USD"]["rate_float"];
|
||||||
eurPrice = bpi["EUR"]["rate_float"];
|
eurPrice = bpi["EUR"]["rate_float"];
|
||||||
for (auto &callback : priceEventCallbacks)
|
for (EventCallbackWithNumber &callback : priceEventCallbacks)
|
||||||
{ // Loop through all the event callbacks and call them
|
{ // Loop through all the event callbacks and call them
|
||||||
callback(usdPrice);
|
callback(usdPrice);
|
||||||
}
|
}
|
||||||
@ -81,7 +89,9 @@ void taskGetPrice(void *pvParameters)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
http.end();
|
http->end();
|
||||||
|
|
||||||
|
delete http;
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(PRICE_WAIT_TIME));
|
vTaskDelay(pdMS_TO_TICKS(PRICE_WAIT_TIME));
|
||||||
}
|
}
|
||||||
@ -91,12 +101,12 @@ void setupGetPriceTask()
|
|||||||
{
|
{
|
||||||
if (getPriceTaskHandle == nullptr)
|
if (getPriceTaskHandle == nullptr)
|
||||||
{
|
{
|
||||||
xTaskCreate(taskGetPrice, "getPrice", 8192, NULL, 1, &getPriceTaskHandle);
|
xTaskCreate(taskGetPrice, "getPrice", 6144, NULL, 1, &getPriceTaskHandle);
|
||||||
vTaskSuspend(getPriceTaskHandle);
|
vTaskSuspend(getPriceTaskHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerNewPriceCallback(EventCallbackWithNumber cb)
|
void registerNewPriceCallback(const EventCallbackWithNumber cb)
|
||||||
{
|
{
|
||||||
priceEventCallbacks.push_back(cb);
|
priceEventCallbacks.push_back(cb);
|
||||||
}
|
}
|
@ -6,9 +6,10 @@
|
|||||||
#include <freertos/task.h>
|
#include <freertos/task.h>
|
||||||
#include "shared.hpp"
|
#include "shared.hpp"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "lib/functions.hpp"
|
||||||
|
|
||||||
extern TaskHandle_t getPriceTaskHandle;
|
extern TaskHandle_t getPriceTaskHandle;
|
||||||
|
|
||||||
void taskGetPrice(void *pvParameters);
|
void taskGetPrice(void *pvParameters);
|
||||||
void setupGetPriceTask();
|
void setupGetPriceTask();
|
||||||
void registerNewPriceCallback(EventCallbackWithNumber cb);
|
void registerNewPriceCallback(const EventCallbackWithNumber cb);
|
@ -38,7 +38,7 @@ void setupMinuteEvent()
|
|||||||
xTaskCreate(minuteTask, "MinuteTask", 2048, NULL, 1, &minuteTaskHandle); // Create the FreeRTOS task
|
xTaskCreate(minuteTask, "MinuteTask", 2048, NULL, 1, &minuteTaskHandle); // Create the FreeRTOS task
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerNewMinuteCallback(EventCallback cb)
|
void registerNewMinuteCallback(const EventCallback cb)
|
||||||
{
|
{
|
||||||
minuteEventCallbacks.push_back(cb);
|
minuteEventCallbacks.push_back(cb);
|
||||||
}
|
}
|
@ -11,4 +11,4 @@ extern TaskHandle_t minuteTaskHandle;
|
|||||||
|
|
||||||
void minuteTask(void *pvParameters);
|
void minuteTask(void *pvParameters);
|
||||||
void setupMinuteEvent();
|
void setupMinuteEvent();
|
||||||
void registerNewMinuteCallback(EventCallback cb);
|
void registerNewMinuteCallback(const EventCallback cb);
|
Loading…
Reference in New Issue
Block a user