Compare commits
9 commits
0.0.1-beta
...
main
Author | SHA1 | Date | |
---|---|---|---|
63827d3ab6 | |||
fc868a2d81 | |||
7702398b36 | |||
d9063b606a | |||
99c34d029f | |||
f80c314247 | |||
0a3f747d00 | |||
486a1b9be2 | |||
730cc4338f |
13 changed files with 285 additions and 53 deletions
136
.forgejo/workflows/push.yaml
Normal file
136
.forgejo/workflows/push.yaml
Normal file
|
@ -0,0 +1,136 @@
|
|||
name: "BTClock CI"
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: docker
|
||||
container:
|
||||
image: ghcr.io/catthehacker/ubuntu:js-22.04
|
||||
permissions:
|
||||
contents: write
|
||||
checks: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: yarn
|
||||
cache-dependency-path: "**/yarn.lock"
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pip
|
||||
~/.platformio/.cache
|
||||
~/data/node_modules
|
||||
.pio
|
||||
data/node_modules
|
||||
key: ${{ runner.os }}-pio
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.9"
|
||||
cache: "pip"
|
||||
- name: Get current date
|
||||
id: dateAndTime
|
||||
shell: bash
|
||||
run: echo "dateAndTime=$(date +'%Y-%m-%d-%H:%M')" >> $GITHUB_OUTPUT
|
||||
- name: Install PlatformIO Core
|
||||
shell: bash
|
||||
run: pip install --upgrade platformio
|
||||
- name: Build BTClock firmware
|
||||
shell: bash
|
||||
run: pio run
|
||||
- name: Build BTClock filesystem
|
||||
shell: bash
|
||||
run: pio run --target buildfs
|
||||
- name: Copy bootloader to output folder
|
||||
run: cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin .pio
|
||||
- name: Upload artifacts
|
||||
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
|
||||
with:
|
||||
include-hidden-files: true
|
||||
retention-days: 1
|
||||
name: prepared-outputs
|
||||
path: .pio/**/*.bin
|
||||
merge:
|
||||
runs-on: docker
|
||||
container:
|
||||
image: ghcr.io/catthehacker/ubuntu:js-22.04
|
||||
permissions:
|
||||
contents: write
|
||||
checks: write
|
||||
needs: build
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
chip:
|
||||
- name: lolin_s2_mini
|
||||
version: esp32s2
|
||||
- name: lolin_s3_mini
|
||||
version: esp32s3
|
||||
- name: orangeclock
|
||||
version: esp32s3
|
||||
epd_variant: [213epd, 29epd]
|
||||
exclude:
|
||||
- chip: { name: orangeclock, version: esp32s3 }
|
||||
epd_variant: 213epd
|
||||
steps:
|
||||
- uses: https://code.forgejo.org/forgejo/download-artifact@v4
|
||||
with:
|
||||
name: prepared-outputs
|
||||
path: .pio
|
||||
- name: Install esptools.py
|
||||
run: pip install --upgrade esptool
|
||||
- name: Create merged firmware binary
|
||||
run: mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && esptool.py --chip ${{ matrix.chip.version }} merge_bin -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin --flash_mode dio 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin 0xe000 .pio/boot_app0.bin 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin 0x369000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin
|
||||
|
||||
- name: Create checksum for firmware
|
||||
shell: bash
|
||||
run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin.sha256
|
||||
|
||||
- name: Create checksum for merged binary
|
||||
run: shasum -a 256 ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.sha256
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
|
||||
with:
|
||||
name: build-${{ matrix.chip.name }}-${{ matrix.epd_variant }}
|
||||
path: |
|
||||
${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin
|
||||
${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.sha256
|
||||
release:
|
||||
runs-on: docker
|
||||
permissions:
|
||||
contents: write
|
||||
checks: write
|
||||
needs: merge
|
||||
steps:
|
||||
- name: Download matrix outputs
|
||||
uses: https://code.forgejo.org/forgejo/download-artifact@v4
|
||||
with:
|
||||
pattern: build-*
|
||||
merge-multiple: false
|
||||
path: temp
|
||||
- name: Copy files
|
||||
run: |
|
||||
mkdir -p release
|
||||
find temp -type f \( -name "*.bin" -o -name "*.sha256" \) -exec cp -f {} release/ \;
|
||||
- name: Create release
|
||||
uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0
|
||||
with:
|
||||
url: "https://git.btclock.dev"
|
||||
repo: "${{ github.repository }}"
|
||||
direction: upload
|
||||
tag: "${{ github.ref_name }}"
|
||||
sha: "${{ github.sha }}"
|
||||
release-dir: release
|
||||
token: ${{ secrets.TOKEN }}
|
||||
override: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }}
|
||||
prerelease: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }}
|
||||
release-notes-assistant: false
|
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -1,3 +1,3 @@
|
|||
[submodule "data"]
|
||||
path = data
|
||||
url = https://github.com/btclock/oc-webui.git
|
||||
url = https://git.btclock.dev/btclock/oc-webui.git
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"-DARDUINO_ORANGECLOCK",
|
||||
"-DARDUINO_ESP32S3_DEV",
|
||||
"-DIS_ORANGECLOCK",
|
||||
"-DARDUINO_USB_MODE=1",
|
||||
"-DARDUINO_USB_MODE=0",
|
||||
"-DARDUINO_RUNNING_CORE=1",
|
||||
"-DARDUINO_EVENT_RUNNING_CORE=1",
|
||||
"-DARDUINO_USB_CDC_ON_BOOT=1"
|
||||
|
|
2
data
2
data
|
@ -1 +1 @@
|
|||
Subproject commit b7c4c5ffbadcde44d6578e6a9a3498d40bf8dee6
|
||||
Subproject commit 8332fec4a1ec0045d91f063617bb441914e7b67a
|
|
@ -15,6 +15,7 @@ default_envs = lolin_s2_mini_213epd, lolin_s2_mini_29epd, lolin_s3_mini_213epd,
|
|||
[btclock_base]
|
||||
platform = espressif32
|
||||
framework = arduino
|
||||
platform_packages = platformio/framework-arduinoespressif32
|
||||
monitor_speed = 115200
|
||||
monitor_filters = esp32_exception_decoder, colorize
|
||||
board_build.filesystem = littlefs
|
||||
|
@ -24,12 +25,11 @@ build_flags =
|
|||
!python scripts/git_rev.py
|
||||
-DLAST_BUILD_TIME=$UNIX_TIME
|
||||
lib_deps =
|
||||
zinggjm/GxEPD2@^1.5.6
|
||||
zinggjm/GxEPD2@^1.6.1
|
||||
https://github.com/tzapu/WiFiManager.git#v2.0.17
|
||||
bblanchon/ArduinoJson@^7.0.3
|
||||
mathieucarbou/ESP Async WebServer
|
||||
gilmaimon/ArduinoWebsockets@^0.5.3
|
||||
fastled/FastLED@^3.6.0
|
||||
bblanchon/ArduinoJson@^7.2.1
|
||||
mathieucarbou/ESP Async WebServer@^3.0.6
|
||||
fastled/FastLED@^3.9.6
|
||||
[env:lolin_s2_mini]
|
||||
extends = btclock_base
|
||||
board = lolin_s2_mini
|
||||
|
@ -69,4 +69,6 @@ board = orangeclock
|
|||
build_flags =
|
||||
${btclock_base.build_flags}
|
||||
-D VERSION_EPD_2_9
|
||||
-D IS_ORANGECLOCK
|
||||
-D IS_ORANGECLOCK
|
||||
-D BUTTON_PIN=45
|
||||
-D NUM_LEDS=2
|
|
@ -6,6 +6,9 @@ const char *ntpServer = "pool.ntp.org";
|
|||
// const long gmtOffset_sec = 0;
|
||||
const int daylightOffset_sec = 3600;
|
||||
TaskHandle_t OTAHandle = NULL;
|
||||
SemaphoreHandle_t xButtonSemaphore = NULL;
|
||||
const TickType_t debounceDelay = pdMS_TO_TICKS(500);
|
||||
TickType_t lastButtonPressTime = 0;
|
||||
|
||||
#define STA_SSID ""
|
||||
#define STA_PASS ""
|
||||
|
@ -87,12 +90,11 @@ void setupWifi()
|
|||
randomSeed(seed);
|
||||
|
||||
// WiFi.begin(, ");
|
||||
WiFi.setAutoConnect(true);
|
||||
WiFi.setAutoReconnect(true);
|
||||
|
||||
WiFiManager wm;
|
||||
|
||||
#ifndef ARDUINO_ORANGECLOCK
|
||||
#ifndef ARDUINO_ORANGECLOCK
|
||||
// Touch pin 14 to reset
|
||||
if (touchRead(14) > 9000)
|
||||
{
|
||||
|
@ -109,7 +111,7 @@ void setupWifi()
|
|||
wm.resetSettings();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
String softAP_SSID =
|
||||
String("OrangeBTClock");
|
||||
|
@ -151,6 +153,7 @@ void setupWifi()
|
|||
Serial.println("WiFi connected");
|
||||
Serial.println("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
epdShowIp();
|
||||
// WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
||||
// enableWiFi();
|
||||
}
|
||||
|
@ -177,7 +180,6 @@ void wakeModemSleep()
|
|||
|
||||
void enableWiFi()
|
||||
{
|
||||
adc_power_on();
|
||||
delay(200);
|
||||
|
||||
WiFi.disconnect(false); // Reconnect the network
|
||||
|
@ -202,7 +204,6 @@ void enableWiFi()
|
|||
|
||||
void disableWiFi()
|
||||
{
|
||||
adc_power_off();
|
||||
WiFi.disconnect(true); // Disconnect from the network
|
||||
WiFi.mode(WIFI_OFF); // Switch WiFi off
|
||||
Serial.println("");
|
||||
|
@ -264,6 +265,44 @@ void OTAUpdateTask(void *pvParameters)
|
|||
}
|
||||
}
|
||||
|
||||
void HandleButtonTask(void *pvParameters)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (xSemaphoreTake(xButtonSemaphore, portMAX_DELAY) == pdTRUE)
|
||||
{
|
||||
TickType_t currentTime = xTaskGetTickCount();
|
||||
if ((currentTime - lastButtonPressTime) >= debounceDelay)
|
||||
{
|
||||
lastButtonPressTime = currentTime;
|
||||
|
||||
Serial.println("Button Pressed");
|
||||
|
||||
#ifdef NUM_LEDS
|
||||
leds[0] = CRGB::SkyBlue;
|
||||
leds[1] = CRGB::Black;
|
||||
|
||||
FastLED.show();
|
||||
|
||||
vTaskDelay(100);
|
||||
|
||||
leds[0] = CRGB::Black;
|
||||
leds[1] = CRGB::DarkOrange;
|
||||
|
||||
FastLED.show();
|
||||
|
||||
vTaskDelay(100);
|
||||
|
||||
leds[0] = CRGB::Black;
|
||||
leds[1] = CRGB::Black;
|
||||
|
||||
FastLED.show();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char getCurrencyIcon()
|
||||
{
|
||||
char ret;
|
||||
|
@ -286,4 +325,23 @@ char getCurrencyIcon()
|
|||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void IRAM_ATTR onButtonPress()
|
||||
{
|
||||
xSemaphoreGiveFromISR(xButtonSemaphore, NULL);
|
||||
}
|
||||
|
||||
void setupButtonISR()
|
||||
{
|
||||
xButtonSemaphore = xSemaphoreCreateBinary();
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
HandleButtonTask, // Task function
|
||||
"Button Task", // Task name
|
||||
2048, // Stack size (bytes)
|
||||
NULL, // Task parameters
|
||||
1, // Priority (1 is default)
|
||||
NULL, // Task handle
|
||||
0); // Core to run the task (0 or 1)
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
#include <Arduino.h>
|
||||
#include <Preferences.h>
|
||||
#include "shared.hpp"
|
||||
#include "driver/adc.h"
|
||||
#include <WiFiManager.h>
|
||||
#include <base64.h>
|
||||
#include "epd.hpp"
|
||||
|
@ -21,4 +20,6 @@ void wakeModemSleep();
|
|||
void setModemSleep();
|
||||
|
||||
bool inPowerSaveMode();
|
||||
char getCurrencyIcon();
|
||||
char getCurrencyIcon();
|
||||
void IRAM_ATTR onButtonPress();
|
||||
void setupButtonISR();
|
33
src/epd.cpp
33
src/epd.cpp
|
@ -22,14 +22,14 @@ void setupDisplay()
|
|||
display.setRotation(1);
|
||||
display.setFont(&Antonio_SemiBold20pt7b);
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
int16_t tbx, tby;
|
||||
uint16_t tbw, tbh;
|
||||
display.getTextBounds("OrangeBTClock", 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
// center the bounding box by transposition of the origin:
|
||||
uint16_t x = ((display.width() - tbw) / 2) - tbx;
|
||||
uint16_t y = ((display.height() - tbh) / 2) - tby;
|
||||
// int16_t tbx, tby;
|
||||
// uint16_t tbw, tbh;
|
||||
// display.getTextBounds("OrangeBTClock", 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
// // center the bounding box by transposition of the origin:
|
||||
// uint16_t x = ((display.width() - tbw) / 2) - tbx;
|
||||
// uint16_t y = ((display.height() - tbh) / 2) - tby;
|
||||
display.fillScreen(GxEPD_BLACK);
|
||||
display.setCursor(x, y);
|
||||
// display.setCursor(x, y);
|
||||
// display.print("OrangeBTClock");
|
||||
|
||||
// display.drawImage(epd_bitmap_allArray[0], GxEPD_WHITE, 0,0 250,37);
|
||||
|
@ -39,6 +39,9 @@ void setupDisplay()
|
|||
display.drawBitmap(xPos,yPos, epd_bitmap_oclogo, 250, 37, GxEPD_WHITE);
|
||||
display.display(false);
|
||||
|
||||
display.setCursor(0, 37);
|
||||
|
||||
|
||||
// display.fillScreen(GxEPD_WHITE);
|
||||
// display.drawLine(0, 10, display.width(), 10, GxEPD_BLACK);
|
||||
// display.drawLine(0, row2, display.width(), row2, GxEPD_BLACK);
|
||||
|
@ -70,6 +73,22 @@ void setupDisplay()
|
|||
// display.display(true);
|
||||
}
|
||||
|
||||
void epdShowIp() {
|
||||
display.setRotation(1);
|
||||
display.setFont(&LibreFranklin_SemiBold10pt7b);
|
||||
display.setTextColor(GxEPD_WHITE);
|
||||
String ipStr = WiFi.localIP().toString();
|
||||
int16_t tbx, tby;
|
||||
uint16_t tbw, tbh;
|
||||
display.getTextBounds(ipStr, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
// center the bounding box by transposition of the origin:
|
||||
uint16_t x = ((display.width() - tbw) / 2) - tbx;
|
||||
uint16_t y = ((display.height() - tbh) / 2) - tby + 37;
|
||||
display.setCursor(x, y);
|
||||
display.println(WiFi.localIP());
|
||||
display.display(true);
|
||||
}
|
||||
|
||||
void updateRow2(String c, char icon)
|
||||
{
|
||||
if (c.equals(currentRow2) && icon == currentIcon2)
|
||||
|
|
|
@ -9,4 +9,5 @@ void showSetupText(String t);
|
|||
void updateRow1(String c, char icon);
|
||||
void updateRow2(String c, char icon);
|
||||
void updateRow3(String c, char icon);
|
||||
void updateRows(String row1Content, String row2Content, String row3Content);
|
||||
void updateRows(String row1Content, String row2Content, String row3Content);
|
||||
void epdShowIp();
|
59
src/main.cpp
59
src/main.cpp
|
@ -8,7 +8,6 @@
|
|||
#include "config.hpp"
|
||||
#include "webserver.hpp"
|
||||
#include <data.hpp>
|
||||
#include <FastLED.h>
|
||||
|
||||
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
|
||||
#define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */
|
||||
|
@ -30,30 +29,36 @@ typedef void (*MethodPtr)(String, char);
|
|||
|
||||
MethodPtr methods[] = {nullptr, updateRow1, updateRow2, updateRow3};
|
||||
|
||||
WiFiClientSecure client;
|
||||
WiFiClient client;
|
||||
uint currentPrice = 0;
|
||||
String currentBlock = "";
|
||||
String currentFees = "";
|
||||
|
||||
#define NUM_LEDS 2
|
||||
#ifdef NUM_LEDS
|
||||
CRGB leds[NUM_LEDS];
|
||||
#endif
|
||||
|
||||
void setup()
|
||||
{
|
||||
// setCpuFrequencyMhz(40);
|
||||
Serial.begin(115200);
|
||||
|
||||
//#ifndef IS_ORANGECLOCK
|
||||
#ifndef IS_ORANGECLOCK
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
//#else
|
||||
FastLED.addLeds<WS2812B, 12, GRB>(leds, NUM_LEDS);
|
||||
leds[0] = CRGB::DarkOrange;
|
||||
#else
|
||||
|
||||
pinMode(BUTTON_PIN, INPUT_PULLUP);
|
||||
attachInterrupt(BUTTON_PIN, onButtonPress, FALLING);
|
||||
|
||||
FastLED.addLeds<WS2812B, 48, GRB>(leds, NUM_LEDS);
|
||||
leds[0] = CRGB::GreenYellow;
|
||||
leds[1] = CRGB::OrangeRed;
|
||||
|
||||
FastLED.show();
|
||||
//#endif
|
||||
|
||||
setupButtonISR();
|
||||
#endif
|
||||
|
||||
setupPreferences();
|
||||
setupDisplay();
|
||||
|
@ -66,7 +71,7 @@ void setup()
|
|||
setupWebserver();
|
||||
setupOTA();
|
||||
}
|
||||
client.setInsecure();
|
||||
// client.setInsecure();
|
||||
|
||||
#ifndef IS_ORANGECLOCK
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
|
@ -98,28 +103,28 @@ void loop()
|
|||
|
||||
return;
|
||||
}
|
||||
client.setInsecure();
|
||||
// client.setInsecure();
|
||||
|
||||
//
|
||||
|
||||
IPAddress res;
|
||||
uint result = WiFi.hostByName("mempool.space", res);
|
||||
// IPAddress res;
|
||||
// uint result = WiFi.hostByName("mempool.space", res);
|
||||
|
||||
if (result >= 0)
|
||||
{
|
||||
Serial.print("SUCCESS!");
|
||||
Serial.println(res.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
WiFi.reconnect();
|
||||
// if (result >= 0)
|
||||
// {
|
||||
// Serial.print("SUCCESS!");
|
||||
// Serial.println(res.toString());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// WiFi.reconnect();
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
Serial.print('.');
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
// while (WiFi.status() != WL_CONNECTED)
|
||||
// {
|
||||
// Serial.print('.');
|
||||
// delay(1000);
|
||||
// }
|
||||
// }
|
||||
|
||||
for (uint i = 1; i <= 3; i++)
|
||||
{
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
#include "shared.hpp"
|
||||
|
||||
volatile bool buttonPressed = false;
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <Preferences.h>
|
||||
#include <GxEPD2.h>
|
||||
#include <GxEPD2_BW.h>
|
||||
#include "utils.hpp"
|
||||
#include "fonts/fonts.hpp"
|
||||
#include <FastLED.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <WiFi.h>
|
||||
|
||||
#ifdef VERSION_EPD_2_13
|
||||
#define EPD_CLASS GxEPD2_213_B74
|
||||
|
@ -88,7 +92,7 @@ const int LINE_DATE = 100;
|
|||
#define CURRENCY_AUD "AUD"
|
||||
#define CURRENCY_JPY "JPY"
|
||||
|
||||
extern WiFiClientSecure client;
|
||||
extern WiFiClient client;
|
||||
extern GxEPD2_BW<EPD_CLASS, EPD_CLASS::HEIGHT> display;
|
||||
extern Preferences preferences;
|
||||
extern bool isUpdating;
|
||||
|
@ -101,3 +105,7 @@ extern char currentIcon1;
|
|||
extern char currentIcon2;
|
||||
extern char currentIcon3;
|
||||
|
||||
#ifdef NUM_LEDS
|
||||
extern CRGB leds[NUM_LEDS];
|
||||
#endif
|
||||
extern volatile bool buttonPressed;
|
|
@ -4,6 +4,7 @@
|
|||
#include <Arduino.h>
|
||||
#include <ArduinoJson.hpp>
|
||||
#include "shared.hpp"
|
||||
#include <esp_mac.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
template <>
|
||||
|
|
Loading…
Add table
Reference in a new issue