Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions firmware/lib/cw-cf-0x01
Submodule cw-cf-0x01 added at a56389
4 changes: 4 additions & 0 deletions firmware/lib/cw-commons/CWPreferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct ClockwiseParams

const char* const PREF_SWAP_BLUE_GREEN = "swapBlueGreen";
const char* const PREF_USE_24H_FORMAT = "use24hFormat";
const char* const CHAIN = "chain";
const char* const PREF_DISPLAY_BRIGHT = "displayBright";
const char* const PREF_DISPLAY_ABC_MIN = "autoBrightMin";
const char* const PREF_DISPLAY_ABC_MAX = "autoBrightMax";
Expand All @@ -28,6 +29,7 @@ struct ClockwiseParams

bool swapBlueGreen;
bool use24hFormat;
bool chain;
uint8_t displayBright;
uint16_t autoBrightMin;
uint16_t autoBrightMax;
Expand Down Expand Up @@ -57,6 +59,7 @@ struct ClockwiseParams
{
preferences.putBool(PREF_SWAP_BLUE_GREEN, swapBlueGreen);
preferences.putBool(PREF_USE_24H_FORMAT, use24hFormat);
preferences.putBool(CHAIN, chain);
preferences.putUInt(PREF_DISPLAY_BRIGHT, displayBright);
preferences.putUInt(PREF_DISPLAY_ABC_MIN, autoBrightMin);
preferences.putUInt(PREF_DISPLAY_ABC_MAX, autoBrightMax);
Expand All @@ -75,6 +78,7 @@ struct ClockwiseParams
{
swapBlueGreen = preferences.getBool(PREF_SWAP_BLUE_GREEN, false);
use24hFormat = preferences.getBool(PREF_USE_24H_FORMAT, true);
chain = preferences.getBool(CHAIN, false);
displayBright = preferences.getUInt(PREF_DISPLAY_BRIGHT, 32);
autoBrightMin = preferences.getUInt(PREF_DISPLAY_ABC_MIN, 0);
autoBrightMax = preferences.getUInt(PREF_DISPLAY_ABC_MAX, 0);
Expand Down
101 changes: 69 additions & 32 deletions firmware/lib/cw-commons/CWWebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct ClockwiseWebServer
bool force_restart;
const char* HEADER_TEMPLATE_D = "X-%s: %d\r\n";
const char* HEADER_TEMPLATE_S = "X-%s: %s\r\n";

static ClockwiseWebServer *getInstance()
{
static ClockwiseWebServer base;
Expand All @@ -40,7 +40,6 @@ struct ClockwiseWebServer
if (force_restart)
StatusController::getInstance()->forceRestart();


WiFiClient client = server.available();
if (client)
{
Expand Down Expand Up @@ -83,69 +82,107 @@ struct ClockwiseWebServer

void processRequest(WiFiClient client, String method, String path, String key, String value)
{
if (method == "GET" && path == "/") {
if (method == "GET" && path == "/")
{
client.println("HTTP/1.0 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println(SETTINGS_PAGE);
} else if (method == "GET" && path == "/get") {
}
else if (method == "GET" && path == "/get")
{
getCurrentSettings(client);
} else if (method == "GET" && path == "/read") {
if (key == "pin") {
}
else if (method == "GET" && path == "/read")
{
if (key == "pin")
{
readPin(client, key, value.toInt());
}
} else if (method == "POST" && path == "/restart") {
}
else if (method == "POST" && path == "/restart")
{
client.println("HTTP/1.0 204 No Content");
force_restart = true;
} else if (method == "POST" && path == "/set") {
}
else if (method == "POST" && path == "/set")
{
ClockwiseParams::getInstance()->load();
//a baby seal has died due this ifs
if (key == ClockwiseParams::getInstance()->PREF_DISPLAY_BRIGHT) {
// a baby seal has died due this ifs
if (key == ClockwiseParams::getInstance()->PREF_DISPLAY_BRIGHT)
{
ClockwiseParams::getInstance()->displayBright = value.toInt();
} else if (key == ClockwiseParams::getInstance()->PREF_WIFI_SSID) {
}
else if (key == ClockwiseParams::getInstance()->PREF_WIFI_SSID)
{
ClockwiseParams::getInstance()->wifiSsid = value;
} else if (key == ClockwiseParams::getInstance()->PREF_WIFI_PASSWORD) {
}
else if (key == ClockwiseParams::getInstance()->PREF_WIFI_PASSWORD)
{
ClockwiseParams::getInstance()->wifiPwd = value;
} else if (key == "autoBright") { //autoBright=0010,0800
ClockwiseParams::getInstance()->autoBrightMin = value.substring(0,4).toInt();
ClockwiseParams::getInstance()->autoBrightMax = value.substring(5,9).toInt();
} else if (key == ClockwiseParams::getInstance()->PREF_SWAP_BLUE_GREEN) {
}
else if (key == "autoBright")
{ // autoBright=0010,0800
ClockwiseParams::getInstance()->autoBrightMin = value.substring(0, 4).toInt();
ClockwiseParams::getInstance()->autoBrightMax = value.substring(5, 9).toInt();
}
else if (key == ClockwiseParams::getInstance()->PREF_SWAP_BLUE_GREEN)
{
ClockwiseParams::getInstance()->swapBlueGreen = (value == "1");
} else if (key == ClockwiseParams::getInstance()->PREF_USE_24H_FORMAT) {
}
else if (key == ClockwiseParams::getInstance()->PREF_USE_24H_FORMAT)
{
ClockwiseParams::getInstance()->use24hFormat = (value == "1");
} else if (key == ClockwiseParams::getInstance()->PREF_LDR_PIN) {
}
else if (key == ClockwiseParams::getInstance()->CHAIN)
{
ClockwiseParams::getInstance()->chain = (value == "1");
}
else if (key == ClockwiseParams::getInstance()->PREF_LDR_PIN)
{
ClockwiseParams::getInstance()->ldrPin = value.toInt();
} else if (key == ClockwiseParams::getInstance()->PREF_TIME_ZONE) {
}
else if (key == ClockwiseParams::getInstance()->PREF_TIME_ZONE)
{
ClockwiseParams::getInstance()->timeZone = value;
} else if (key == ClockwiseParams::getInstance()->PREF_NTP_SERVER) {
}
else if (key == ClockwiseParams::getInstance()->PREF_NTP_SERVER)
{
ClockwiseParams::getInstance()->ntpServer = value;
} else if (key == ClockwiseParams::getInstance()->PREF_CANVAS_FILE) {
}
else if (key == ClockwiseParams::getInstance()->PREF_CANVAS_FILE)
{
ClockwiseParams::getInstance()->canvasFile = value;
} else if (key == ClockwiseParams::getInstance()->PREF_CANVAS_SERVER) {
}
else if (key == ClockwiseParams::getInstance()->PREF_CANVAS_SERVER)
{
ClockwiseParams::getInstance()->canvasServer = value;
} else if (key == ClockwiseParams::getInstance()->PREF_MANUAL_POSIX) {
}
else if (key == ClockwiseParams::getInstance()->PREF_MANUAL_POSIX)
{
ClockwiseParams::getInstance()->manualPosix = value;
} else if (key == ClockwiseParams::getInstance()->PREF_DISPLAY_ROTATION) {
}
else if (key == ClockwiseParams::getInstance()->PREF_DISPLAY_ROTATION)
{
ClockwiseParams::getInstance()->displayRotation = value.toInt();
}
ClockwiseParams::getInstance()->save();
client.println("HTTP/1.0 204 No Content");
}
}



void readPin(WiFiClient client, String key, uint16_t pin) {
void readPin(WiFiClient client, String key, uint16_t pin)
{
ClockwiseParams::getInstance()->load();

client.println("HTTP/1.0 204 No Content");
client.printf(HEADER_TEMPLATE_D, key, analogRead(pin));

client.println();
}


void getCurrentSettings(WiFiClient client) {
void getCurrentSettings(WiFiClient client)
{
ClockwiseParams::getInstance()->load();

client.println("HTTP/1.0 204 No Content");
Expand All @@ -155,7 +192,8 @@ struct ClockwiseWebServer
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_DISPLAY_ABC_MAX, ClockwiseParams::getInstance()->autoBrightMax);
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_SWAP_BLUE_GREEN, ClockwiseParams::getInstance()->swapBlueGreen);
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_USE_24H_FORMAT, ClockwiseParams::getInstance()->use24hFormat);
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_LDR_PIN, ClockwiseParams::getInstance()->ldrPin);
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->CHAIN, ClockwiseParams::getInstance()->chain);
client.printf(HEADER_TEMPLATE_D, ClockwiseParams::getInstance()->PREF_LDR_PIN, ClockwiseParams::getInstance()->ldrPin);
client.printf(HEADER_TEMPLATE_S, ClockwiseParams::getInstance()->PREF_TIME_ZONE, ClockwiseParams::getInstance()->timeZone.c_str());
client.printf(HEADER_TEMPLATE_S, ClockwiseParams::getInstance()->PREF_WIFI_SSID, ClockwiseParams::getInstance()->wifiSsid.c_str());
client.printf(HEADER_TEMPLATE_S, ClockwiseParams::getInstance()->PREF_NTP_SERVER, ClockwiseParams::getInstance()->ntpServer.c_str());
Expand All @@ -169,5 +207,4 @@ struct ClockwiseWebServer
client.printf(HEADER_TEMPLATE_S, "CLOCKFACE_NAME", CLOCKFACE_NAME);
client.println();
}

};
10 changes: 9 additions & 1 deletion firmware/lib/cw-commons/SettingsWebPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ const char SETTINGS_PAGE[] PROGMEM = R""""(
save: "updatePreference('use24hFormat', Number(use24h.checked))",
property: "use24hFormat"
},
{
title: "Chain 64x32 panels",
description: "Use two 64x32 LED Panels instead of one single 64x64",
formInput: "<input class='w3-check' type='checkbox' id='chain' " + (settings.chain == '1' ? "checked" : "") + "><label for='chain'> Yep</label>",
icon: "fa-clock-o",
save: "updatePreference('chain', Number(chain.checked))",
property: "chain"
},
{
title: "Swap Blue/Green pins?",
description: "Swap Blue and Green pins because the panel is RBG instead of RGB",
Expand Down Expand Up @@ -229,7 +237,7 @@ const char SETTINGS_PAGE[] PROGMEM = R""""(
}

//Local
//createCards({ "displayBright": 30, "swapBlueGreen": 1, "use24hFormat": 0, "timeZone": "Europe/Lisbon", "ntpServer": "pool.ntp.org", "wifiSsid": "test", "autoBrightMin":0, "autoBrightMax":800, "ldrPin":35, "cw_fw_version":"1.2.2", "clockface_name":"cw-cf-0x07", "canvasServer":"raw.githubusercontent.com", "canvasFile":"star-wars.json" });
//createCards({ "displayBright": 30, "swapBlueGreen": 1, "use24hFormat": 0, , "chain" : 0, "timeZone": "Europe/Lisbon", "ntpServer": "pool.ntp.org", "wifiSsid": "test", "autoBrightMin":0, "autoBrightMax":800, "ldrPin":35, "cw_fw_version":"1.2.2", "clockface_name":"cw-cf-0x07", "canvasServer":"raw.githubusercontent.com", "canvasFile":"star-wars.json" });

//Embedded
begin();
Expand Down
31 changes: 26 additions & 5 deletions firmware/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <Arduino.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#include <ESP32-VirtualMatrixPanel-I2S-DMA.h>

// Clockface
#include <Clockface.h>
Expand All @@ -15,7 +15,22 @@

#define ESP32_LED_BUILTIN 2

// Single 64x64 LED panel use case
#define PANEL_RES_X 64
#define PANEL_RES_Y 64
#define NUM_COLS 1
#define NUM_ROWS 1

// Chained 64x32 panels use case
// #define CHAINED_PANEL_RES_X 64
#define CHAINED_PANEL_RES_Y 32
#define CHAINED_NUM_ROWS 2
// #define CHAINED_NUM_COLS 1

#define VIRTUAL_MATRIX_CHAIN_TYPE CHAIN_BOTTOM_LEFT_UP

MatrixPanel_I2S_DMA *dma_display = nullptr;
VirtualMatrixPanel *virtualDisp = nullptr;

Clockface *clockface;

Expand All @@ -28,7 +43,11 @@ uint8_t currentBrightSlot = -1;

void displaySetup(bool swapBlueGreen, uint8_t displayBright, uint8_t displayRotation)
{
HUB75_I2S_CFG mxconfig(64, 64, 1);
HUB75_I2S_CFG mxconfig(
PANEL_RES_X,
ClockwiseParams::getInstance()->chain ? CHAINED_PANEL_RES_Y : PANEL_RES_Y,
ClockwiseParams::getInstance()->chain ? (CHAINED_NUM_ROWS * NUM_COLS) : (NUM_ROWS * NUM_COLS)
);

if (swapBlueGreen)
{
Expand All @@ -46,8 +65,10 @@ void displaySetup(bool swapBlueGreen, uint8_t displayBright, uint8_t displayRota
dma_display = new MatrixPanel_I2S_DMA(mxconfig);
dma_display->begin();
dma_display->setBrightness8(displayBright);
dma_display->clearScreen();
dma_display->setRotation(displayRotation);

virtualDisp = new VirtualMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, VIRTUAL_MATRIX_CHAIN_TYPE);
virtualDisp->clearScreen();
virtualDisp->setRotation(displayRotation);
}

void automaticBrightControl()
Expand Down Expand Up @@ -90,7 +111,7 @@ void setup()
pinMode(ClockwiseParams::getInstance()->ldrPin, INPUT);

displaySetup(ClockwiseParams::getInstance()->swapBlueGreen, ClockwiseParams::getInstance()->displayBright, ClockwiseParams::getInstance()->displayRotation);
clockface = new Clockface(dma_display);
clockface = new Clockface(virtualDisp);

autoBrightEnabled = (ClockwiseParams::getInstance()->autoBrightMax > 0);

Expand Down