splittet Display into combinable parts
This commit is contained in:
parent
3fad49cfb4
commit
85e635169d
29
data/http/index.css
Normal file
29
data/http/index.css
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 8vw;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 33vmin;
|
||||||
|
font-size: 9vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.cancel {
|
||||||
|
width: 15vmin;
|
||||||
|
height: 15vmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
border: 1px solid black;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(11 / 27 * 100%);
|
||||||
|
}
|
||||||
@ -5,41 +5,11 @@
|
|||||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||||
<title>Sporttafel</title>
|
<title>Sporttafel</title>
|
||||||
<link rel="icon" href="icon.svg">
|
<link rel="icon" href="icon.svg">
|
||||||
<style>
|
<script src="index.js"></script>
|
||||||
body {
|
<link rel="stylesheet" href="index.css">
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 8vw;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
width: 33vmin;
|
|
||||||
font-size: 9vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.cancel {
|
|
||||||
width: 15vmin;
|
|
||||||
height: 15vmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
border: 1px solid black;
|
|
||||||
width: 100%;
|
|
||||||
height: calc(11 / 27 * 100%);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<svg width="800" height="325" id="display" style="background-color: black">
|
<svg width="800" height="325" id="display" style="background-color: black"></svg>
|
||||||
</svg>
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@ -68,130 +38,24 @@
|
|||||||
</td>
|
</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
<script>
|
<td>
|
||||||
|
<button onclick="get('/action/left/up')">↑</button>
|
||||||
const DEV_HOST = "10.0.0.119";
|
</td>
|
||||||
|
<td> </td>
|
||||||
const S = 100 / 27;
|
<td>
|
||||||
|
<button onclick="get('/action/right/up')">↑</button>
|
||||||
const display = document.getElementById("display");
|
</td>
|
||||||
|
</tr>
|
||||||
const segments = [];
|
<tr>
|
||||||
|
<td>
|
||||||
function url(protocol, path) {
|
<button onclick="get('/action/left/down')">↓</button>
|
||||||
const hostPart = location.host.substring(0, location.host.indexOf(":"))
|
</td>
|
||||||
const isLocal = hostPart === "" || hostPart === "localhost" || hostPart === "0";
|
<td> </td>
|
||||||
const host = isLocal ? DEV_HOST : hostPart;
|
<td>
|
||||||
const port = isLocal ? "80" : location.port;
|
<button onclick="get('/action/right/down')">↓</button>
|
||||||
return `${protocol}://${host}:${port}${path}`;
|
</td>
|
||||||
}
|
</tr>
|
||||||
|
|
||||||
function get(path) {
|
|
||||||
const request = new XMLHttpRequest();
|
|
||||||
request.open("GET", url("http", path), true);
|
|
||||||
request.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawDigit(x, y) {
|
|
||||||
drawPixel(x, y, 0, 3);
|
|
||||||
drawPixel(x, y, 0, 2);
|
|
||||||
drawPixel(x, y, 0, 1);
|
|
||||||
|
|
||||||
drawPixel(x, y, 1, 0);
|
|
||||||
drawPixel(x, y, 2, 0);
|
|
||||||
drawPixel(x, y, 3, 0);
|
|
||||||
|
|
||||||
drawPixel(x, y, 4, 1);
|
|
||||||
drawPixel(x, y, 4, 2);
|
|
||||||
drawPixel(x, y, 4, 3);
|
|
||||||
|
|
||||||
drawPixel(x, y, 4, 5);
|
|
||||||
drawPixel(x, y, 4, 6);
|
|
||||||
drawPixel(x, y, 4, 7);
|
|
||||||
|
|
||||||
drawPixel(x, y, 3, 8);
|
|
||||||
drawPixel(x, y, 2, 8);
|
|
||||||
drawPixel(x, y, 1, 8);
|
|
||||||
|
|
||||||
drawPixel(x, y, 0, 7);
|
|
||||||
drawPixel(x, y, 0, 6);
|
|
||||||
drawPixel(x, y, 0, 5);
|
|
||||||
|
|
||||||
drawPixel(x, y, 1, 4);
|
|
||||||
drawPixel(x, y, 2, 4);
|
|
||||||
drawPixel(x, y, 3, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawPixel(offsetRasterX, offsetRasterY, innerRasterX, innerRasterY) {
|
|
||||||
const segment = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
|
||||||
const x = (offsetRasterX + innerRasterX) * S;
|
|
||||||
const y = (offsetRasterY + innerRasterY) * S;
|
|
||||||
segment.setAttribute("x", x + "vw");
|
|
||||||
segment.setAttribute("y", y + "vw");
|
|
||||||
segment.setAttribute("width", S + "vw");
|
|
||||||
segment.setAttribute("height", S + "vw");
|
|
||||||
segment.setAttribute("stroke", "white");
|
|
||||||
segment.setAttribute("fill", "none");
|
|
||||||
segment.setAttribute("id", "segment" + segments.length);
|
|
||||||
display.appendChild(segment);
|
|
||||||
segments.push(segment);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawDisplay(rasterX, rasterY) {
|
|
||||||
drawDigit(rasterX, rasterY);
|
|
||||||
rasterX += 6;
|
|
||||||
drawDigit(rasterX, rasterY);
|
|
||||||
rasterX += 6;
|
|
||||||
drawPixel(rasterX, rasterY, 0, 0);
|
|
||||||
drawPixel(rasterX, rasterY + 2, 0, 0);
|
|
||||||
drawPixel(rasterX, rasterY + 6, 0, 0);
|
|
||||||
drawPixel(rasterX, rasterY + 8, 0, 0);
|
|
||||||
rasterX += 2;
|
|
||||||
drawDigit(rasterX, rasterY);
|
|
||||||
rasterX += 6;
|
|
||||||
drawDigit(rasterX, rasterY);
|
|
||||||
}
|
|
||||||
|
|
||||||
function connect() {
|
|
||||||
console.log("connecting websocket...");
|
|
||||||
const socket = new WebSocket(url("ws", "/ws"));
|
|
||||||
socket.timeout = 1;
|
|
||||||
socket.addEventListener('open', _ => {
|
|
||||||
console.log('websocket connected');
|
|
||||||
segments.forEach(segment => {
|
|
||||||
segment.setAttribute("fill", "none");
|
|
||||||
segment.setAttribute("stroke", "none");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
socket.addEventListener('message', event => {
|
|
||||||
const len = event.data.length;
|
|
||||||
let index = 0;
|
|
||||||
let start = 0;
|
|
||||||
while (start < len) {
|
|
||||||
const end = start + 3;
|
|
||||||
const color = event.data.substring(start, end);
|
|
||||||
const segment = segments[index];
|
|
||||||
segment.setAttribute("fill", "#" + color)
|
|
||||||
index++;
|
|
||||||
start = end;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
socket.addEventListener('close', _ => {
|
|
||||||
console.log('websocket disconnected');
|
|
||||||
segments.forEach(segment => {
|
|
||||||
segment.setAttribute("fill", "none");
|
|
||||||
segment.setAttribute("stroke", "white");
|
|
||||||
});
|
|
||||||
setTimeout(connect, 1000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
drawDisplay(1, 1);
|
|
||||||
setTimeout(connect, 1000);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
118
data/http/index.js
Normal file
118
data/http/index.js
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
const DEV_HOST = "10.0.0.119";
|
||||||
|
|
||||||
|
const S = 100 / 27;
|
||||||
|
|
||||||
|
const display = document.getElementById("display");
|
||||||
|
|
||||||
|
const segments = [];
|
||||||
|
|
||||||
|
function url(protocol, path) {
|
||||||
|
const hostPart = location.host.substring(0, location.host.indexOf(":"))
|
||||||
|
const isLocal = hostPart === "" || hostPart === "localhost" || hostPart === "0";
|
||||||
|
const host = isLocal ? DEV_HOST : hostPart;
|
||||||
|
const port = isLocal ? "80" : location.port;
|
||||||
|
return `${protocol}://${host}:${port}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(path) {
|
||||||
|
const request = new XMLHttpRequest();
|
||||||
|
request.open("GET", url("http", path), true);
|
||||||
|
request.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawDigit(x, y) {
|
||||||
|
drawPixel(x, y, 0, 3);
|
||||||
|
drawPixel(x, y, 0, 2);
|
||||||
|
drawPixel(x, y, 0, 1);
|
||||||
|
|
||||||
|
drawPixel(x, y, 1, 0);
|
||||||
|
drawPixel(x, y, 2, 0);
|
||||||
|
drawPixel(x, y, 3, 0);
|
||||||
|
|
||||||
|
drawPixel(x, y, 4, 1);
|
||||||
|
drawPixel(x, y, 4, 2);
|
||||||
|
drawPixel(x, y, 4, 3);
|
||||||
|
|
||||||
|
drawPixel(x, y, 4, 5);
|
||||||
|
drawPixel(x, y, 4, 6);
|
||||||
|
drawPixel(x, y, 4, 7);
|
||||||
|
|
||||||
|
drawPixel(x, y, 3, 8);
|
||||||
|
drawPixel(x, y, 2, 8);
|
||||||
|
drawPixel(x, y, 1, 8);
|
||||||
|
|
||||||
|
drawPixel(x, y, 0, 7);
|
||||||
|
drawPixel(x, y, 0, 6);
|
||||||
|
drawPixel(x, y, 0, 5);
|
||||||
|
|
||||||
|
drawPixel(x, y, 1, 4);
|
||||||
|
drawPixel(x, y, 2, 4);
|
||||||
|
drawPixel(x, y, 3, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawPixel(offsetRasterX, offsetRasterY, innerRasterX, innerRasterY) {
|
||||||
|
const segment = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
||||||
|
const x = (offsetRasterX + innerRasterX) * S;
|
||||||
|
const y = (offsetRasterY + innerRasterY) * S;
|
||||||
|
segment.setAttribute("x", x + "vw");
|
||||||
|
segment.setAttribute("y", y + "vw");
|
||||||
|
segment.setAttribute("width", S + "vw");
|
||||||
|
segment.setAttribute("height", S + "vw");
|
||||||
|
segment.setAttribute("stroke", "white");
|
||||||
|
segment.setAttribute("fill", "none");
|
||||||
|
segment.setAttribute("id", "segment" + segments.length);
|
||||||
|
display.appendChild(segment);
|
||||||
|
segments.push(segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawDisplay(rasterX, rasterY) {
|
||||||
|
drawDigit(rasterX, rasterY);
|
||||||
|
rasterX += 6;
|
||||||
|
drawDigit(rasterX, rasterY);
|
||||||
|
rasterX += 6;
|
||||||
|
drawPixel(rasterX, rasterY, 0, 0);
|
||||||
|
drawPixel(rasterX, rasterY + 2, 0, 0);
|
||||||
|
drawPixel(rasterX, rasterY + 6, 0, 0);
|
||||||
|
drawPixel(rasterX, rasterY + 8, 0, 0);
|
||||||
|
rasterX += 2;
|
||||||
|
drawDigit(rasterX, rasterY);
|
||||||
|
rasterX += 6;
|
||||||
|
drawDigit(rasterX, rasterY);
|
||||||
|
}
|
||||||
|
|
||||||
|
function connect() {
|
||||||
|
console.log("connecting websocket...");
|
||||||
|
const socket = new WebSocket(url("ws", "/ws"));
|
||||||
|
socket.timeout = 1;
|
||||||
|
socket.addEventListener('open', _ => {
|
||||||
|
console.log('websocket connected');
|
||||||
|
segments.forEach(segment => {
|
||||||
|
segment.setAttribute("fill", "none");
|
||||||
|
segment.setAttribute("stroke", "none");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
socket.addEventListener('message', event => {
|
||||||
|
const len = event.data.length;
|
||||||
|
let index = 0;
|
||||||
|
let start = 0;
|
||||||
|
while (start < len) {
|
||||||
|
const end = start + 3;
|
||||||
|
const color = event.data.substring(start, end);
|
||||||
|
const segment = segments[index];
|
||||||
|
segment.setAttribute("fill", "#" + color)
|
||||||
|
index++;
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
socket.addEventListener('close', _ => {
|
||||||
|
console.log('websocket disconnected');
|
||||||
|
segments.forEach(segment => {
|
||||||
|
segment.setAttribute("fill", "none");
|
||||||
|
segment.setAttribute("stroke", "white");
|
||||||
|
});
|
||||||
|
setTimeout(connect, 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
drawDisplay(1, 1);
|
||||||
|
setTimeout(connect, 1000);
|
||||||
@ -4,7 +4,7 @@
|
|||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
#include <core/log.h>
|
#include <core/log.h>
|
||||||
#include <display/Display.h>
|
#include <display/MyDisplay.h>
|
||||||
|
|
||||||
#define CONFIG_WRITE_DELAY_MILLIS (30 * 1000)
|
#define CONFIG_WRITE_DELAY_MILLIS (30 * 1000)
|
||||||
|
|
||||||
@ -87,6 +87,22 @@ public:
|
|||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void leftUp() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void leftDown() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void rightUp() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void rightDown() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool setConfig(const String& key, const String& valueStr) {
|
virtual bool setConfig(const String& key, const String& valueStr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -71,7 +71,7 @@ protected:
|
|||||||
|
|
||||||
void draw() override {
|
void draw() override {
|
||||||
display.clear();
|
display.clear();
|
||||||
display.strokeRect(step, step, DISPLAY_VIRTUAL_WIDTH - 1 - 2 * step, DISPLAY_VIRTUAL_HEIGHT - 1 - 2 * step);
|
display.main.strokeRect(step, step, DISPLAY_VIRTUAL_WIDTH - 1 - 2 * step, DISPLAY_VIRTUAL_HEIGHT - 1 - 2 * step);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -52,10 +52,14 @@ class AppMatch final : public App {
|
|||||||
|
|
||||||
State state = INITIAL;
|
State state = INITIAL;
|
||||||
|
|
||||||
|
int pointsLeft = 0;
|
||||||
|
|
||||||
|
int pointsRight = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit AppMatch()
|
explicit AppMatch()
|
||||||
: App(APP_MATCH_NAME) {
|
: App(APP_MATCH_NAME) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,12 +122,35 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void leftUp() override {
|
||||||
|
pointsLeft++;
|
||||||
|
markDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void leftDown() override {
|
||||||
|
pointsLeft = max(0, pointsLeft - 1);
|
||||||
|
markDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rightUp() override {
|
||||||
|
pointsRight++;
|
||||||
|
markDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rightDown() override {
|
||||||
|
pointsRight = max(0, pointsRight - 1);
|
||||||
|
markDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void _start() override {
|
void _start() override {
|
||||||
configMillis = configGet<unsigned long>(CONFIG_SECONDS_KEY, CONFIG_SECONDS_DEFAULT) * MS_PER_SEC;
|
configMillis = configGet<unsigned long>(CONFIG_SECONDS_KEY, CONFIG_SECONDS_DEFAULT) * MS_PER_SEC;
|
||||||
configCentis = configGet<bool>(CONFIG_CENTIS_KEY, CONFIG_CENTIS_DEFAULT);
|
configCentis = configGet<bool>(CONFIG_CENTIS_KEY, CONFIG_CENTIS_DEFAULT);
|
||||||
|
|
||||||
|
pointsLeft = 0;
|
||||||
|
pointsRight = 0;
|
||||||
|
|
||||||
info("config:");
|
info("config:");
|
||||||
info(" seconds = %ld", configMillis / MS_PER_SEC);
|
info(" seconds = %ld", configMillis / MS_PER_SEC);
|
||||||
info(" centis = %s", configCentis ? "true" : "false");
|
info(" centis = %s", configCentis ? "true" : "false");
|
||||||
@ -177,17 +204,21 @@ protected:
|
|||||||
}
|
}
|
||||||
if (blinkIntervalMillis == 0 || blinkState) {
|
if (blinkIntervalMillis == 0 || blinkState) {
|
||||||
if (totalMinutes > 0) {
|
if (totalMinutes > 0) {
|
||||||
display.printf("%2d:%02d", totalMinutes, partSeconds);
|
display.main.printf("%2d:%02d", totalMinutes, partSeconds);
|
||||||
} else if (totalMillis > 0) {
|
} else if (totalMillis > 0) {
|
||||||
if (configCentis) {
|
if (configCentis) {
|
||||||
display.printf("%2d.%02d", partSeconds, partCentis);
|
display.main.printf("%2d.%02d", partSeconds, partCentis);
|
||||||
} else {
|
} else {
|
||||||
display.printf(" %2d", partSeconds);
|
display.main.printf(" %2d", partSeconds);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
display.printf("00:00");
|
display.main.printf("00:00");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ReSharper disable once CppExpressionWithoutSideEffects
|
||||||
|
display.left.printf("%2d", pointsLeft);
|
||||||
|
// ReSharper disable once CppExpressionWithoutSideEffects
|
||||||
|
display.right.printf("%2d", pointsRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
12
src/core/BASICS.h
Normal file
12
src/core/BASICS.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef BASICS_H
|
||||||
|
#define BASICS_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
#define X true
|
||||||
|
#define _ false
|
||||||
|
|
||||||
|
#define countof(a) (sizeof(a) / sizeof((a)[0]))
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -53,6 +53,34 @@ void httpActionConfirm(AsyncWebServerRequest *request) {
|
|||||||
request->send(200);
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void httpActionLeftUp(AsyncWebServerRequest *request) {
|
||||||
|
if (app != nullptr) {
|
||||||
|
app->leftUp();
|
||||||
|
}
|
||||||
|
request->send(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpActionLeftDown(AsyncWebServerRequest *request) {
|
||||||
|
if (app != nullptr) {
|
||||||
|
app->leftDown();
|
||||||
|
}
|
||||||
|
request->send(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpActionRightUp(AsyncWebServerRequest *request) {
|
||||||
|
if (app != nullptr) {
|
||||||
|
app->rightUp();
|
||||||
|
}
|
||||||
|
request->send(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpActionRightDown(AsyncWebServerRequest *request) {
|
||||||
|
if (app != nullptr) {
|
||||||
|
app->rightDown();
|
||||||
|
}
|
||||||
|
request->send(200);
|
||||||
|
}
|
||||||
|
|
||||||
void httpAppConfig(AsyncWebServerRequest *request) {
|
void httpAppConfig(AsyncWebServerRequest *request) {
|
||||||
if (!request->hasArg("key")) {
|
if (!request->hasArg("key")) {
|
||||||
error("missing parameter 'key'");
|
error("missing parameter 'key'");
|
||||||
@ -97,6 +125,10 @@ void httpSetup() {
|
|||||||
server.on("/action/right", HTTP_GET, httpActionRight);
|
server.on("/action/right", HTTP_GET, httpActionRight);
|
||||||
server.on("/action/cancel", HTTP_GET, httpActionCancel);
|
server.on("/action/cancel", HTTP_GET, httpActionCancel);
|
||||||
server.on("/action/confirm", HTTP_GET, httpActionConfirm);
|
server.on("/action/confirm", HTTP_GET, httpActionConfirm);
|
||||||
|
server.on("/action/left/up", HTTP_GET, httpActionLeftUp);
|
||||||
|
server.on("/action/left/down", HTTP_GET, httpActionLeftDown);
|
||||||
|
server.on("/action/right/up", HTTP_GET, httpActionRightUp);
|
||||||
|
server.on("/action/right/down", HTTP_GET, httpActionRightDown);
|
||||||
server.on("/app/config", HTTP_GET, httpAppConfig);
|
server.on("/app/config", HTTP_GET, httpAppConfig);
|
||||||
server.serveStatic("/", LittleFS, "/http/", "max-age=86400").setDefaultFile("index.html");
|
server.serveStatic("/", LittleFS, "/http/", "max-age=86400").setDefaultFile("index.html");
|
||||||
server.onNotFound(httpNotFound);
|
server.onNotFound(httpNotFound);
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
#include "Display.h"
|
|
||||||
|
|
||||||
Display display;
|
|
||||||
@ -5,53 +5,69 @@
|
|||||||
|
|
||||||
#include <AsyncWebSocket.h>
|
#include <AsyncWebSocket.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <core/log.h>
|
||||||
|
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
#include "font.h"
|
|
||||||
#include "core/http.h"
|
#include "core/http.h"
|
||||||
|
|
||||||
#define PIXELS_PER_SEGMENT 3
|
|
||||||
#define SEGMENTS_PER_DIGIT 7
|
|
||||||
#define PIXELS_PER_DOT 1
|
|
||||||
#define DOT_COUNT 4
|
|
||||||
#define DIGIT_COUNT 4
|
|
||||||
|
|
||||||
#define PIXELS_PER_DIGIT (PIXELS_PER_SEGMENT * SEGMENTS_PER_DIGIT)
|
|
||||||
#define TOTAL_DOT_PIXEL_COUNT (PIXELS_PER_DOT * DOT_COUNT)
|
|
||||||
#define TOTAL_SEGMENT_PIXEL_COUNT (DIGIT_COUNT * PIXELS_PER_DIGIT)
|
|
||||||
#define TOTAL_PIXEL_COUNT (TOTAL_SEGMENT_PIXEL_COUNT + TOTAL_DOT_PIXEL_COUNT)
|
|
||||||
#define TOTAL_PIXEL_BYTE_COUNT (TOTAL_PIXEL_COUNT * sizeof(Color))
|
|
||||||
#define HEX_BUFFER_SIZE (TOTAL_PIXEL_BYTE_COUNT + 1)
|
|
||||||
|
|
||||||
#define DISPLAY_VIRTUAL_WIDTH 25
|
|
||||||
#define DISPLAY_VIRTUAL_HEIGHT 9
|
|
||||||
|
|
||||||
#define HEX_BUFFER_MIN_WAIT_MS 500
|
#define HEX_BUFFER_MIN_WAIT_MS 500
|
||||||
|
|
||||||
class Display {
|
class Display {
|
||||||
|
|
||||||
// Adafruit_NeoPixel leds;
|
// Adafruit_NeoPixel leds;
|
||||||
|
|
||||||
Color pixels[TOTAL_PIXEL_COUNT] = {};
|
size_t totalPixelCount;
|
||||||
|
|
||||||
|
size_t pixelByteCount;
|
||||||
|
|
||||||
|
Color *pixels;
|
||||||
|
|
||||||
|
char *hexBuffer;
|
||||||
|
|
||||||
Color color = WHITE;
|
Color color = WHITE;
|
||||||
|
|
||||||
char hexBuffer[HEX_BUFFER_SIZE] = "";
|
protected:
|
||||||
|
|
||||||
struct Mapping {
|
explicit Display(const int totalPixelCount) :/* leds(totalPixelCount, GPIO_NUM_13) ,*/ totalPixelCount(totalPixelCount), pixelByteCount(totalPixelCount * sizeof(Color)) {
|
||||||
uint8_t x;
|
|
||||||
uint8_t y;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Display() /* : leds(PIXEL_COUNT, GPIO_NUM_13) */ {
|
|
||||||
// leds.begin();
|
// leds.begin();
|
||||||
|
|
||||||
|
pixels = static_cast<Color *>(malloc(pixelByteCount));
|
||||||
|
if (pixels == nullptr) {
|
||||||
|
error("Failed to allocate memory for Display.pixels");
|
||||||
|
}
|
||||||
|
|
||||||
|
hexBuffer = static_cast<char *>(malloc(pixelByteCount + 1));
|
||||||
|
if (hexBuffer == nullptr) {
|
||||||
|
error("Failed to allocate memory for Display.hexBuffer");
|
||||||
|
} else {
|
||||||
|
*hexBuffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
setBrightness(6);
|
setBrightness(6);
|
||||||
clear();
|
clear();
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Display() {
|
||||||
|
if (pixels != nullptr) {
|
||||||
|
free(pixels);
|
||||||
|
pixels = nullptr;
|
||||||
|
}
|
||||||
|
if (hexBuffer != nullptr) {
|
||||||
|
free(hexBuffer);
|
||||||
|
hexBuffer = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void setPixel(const int index) const {
|
||||||
|
if (pixels == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pixels[index] = color;
|
||||||
|
}
|
||||||
|
|
||||||
void setColor(const Color newColor) {
|
void setColor(const Color newColor) {
|
||||||
this->color = newColor;
|
this->color = newColor;
|
||||||
}
|
}
|
||||||
@ -60,12 +76,15 @@ public:
|
|||||||
// leds.setBrightness(brightness);
|
// leds.setBrightness(brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() const {
|
||||||
memset(pixels, 0, TOTAL_PIXEL_BYTE_COUNT);
|
if (pixels == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(pixels, 0, pixelByteCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush(const bool forceNextHexBuffer = false) {
|
void flush(const bool forceNextHexBuffer = false) const {
|
||||||
// memcpy(leds.getPixels(), buffer, PIXEL_BYTE_COUNT);
|
// memcpy(leds.getPixels(), buffer, pixelByteCount);
|
||||||
// leds.show();
|
// leds.show();
|
||||||
|
|
||||||
const auto now = millis() - HEX_BUFFER_MIN_WAIT_MS;
|
const auto now = millis() - HEX_BUFFER_MIN_WAIT_MS;
|
||||||
@ -73,178 +92,43 @@ public:
|
|||||||
if (now - last >= HEX_BUFFER_MIN_WAIT_MS || forceNextHexBuffer) {
|
if (now - last >= HEX_BUFFER_MIN_WAIT_MS || forceNextHexBuffer) {
|
||||||
last = now;
|
last = now;
|
||||||
fillHexBuffer();
|
fillHexBuffer();
|
||||||
websocketSendAll(hexBuffer);
|
sendHexBufferAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printf(const char *format, ...) {
|
void sendHexBufferAll() const {
|
||||||
char buffer[64];
|
if (hexBuffer == nullptr) {
|
||||||
|
return;
|
||||||
va_list args;
|
}
|
||||||
va_start(args, format);
|
if (*hexBuffer == 0) {
|
||||||
vsnprintf(buffer, sizeof buffer, format, args);
|
return;
|
||||||
va_end(args);
|
}
|
||||||
|
websocketSendAll(hexBuffer);
|
||||||
print(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(const char *str) {
|
void sendHexBuffer(AsyncWebSocketClient *client) const {
|
||||||
auto digit = 0;
|
if (hexBuffer == nullptr) {
|
||||||
for (auto c = str; *c != 0 && digit < 4; c++) {
|
return;
|
||||||
switch (*c) {
|
|
||||||
case '\'':
|
|
||||||
case '"':
|
|
||||||
case '`':
|
|
||||||
case '.':
|
|
||||||
printDots(false, false, false, true);
|
|
||||||
digit = 2;
|
|
||||||
break;
|
|
||||||
case ',':
|
|
||||||
printDots(false, false, true, true);
|
|
||||||
digit = 2;
|
|
||||||
break;
|
|
||||||
case ':':
|
|
||||||
printDots(false, true, true, false);
|
|
||||||
digit = 2;
|
|
||||||
break;
|
|
||||||
case ';':
|
|
||||||
printDots(false, true, true, true);
|
|
||||||
digit = 2;
|
|
||||||
break;
|
|
||||||
case '|':
|
|
||||||
printDots(true, true, true, true);
|
|
||||||
digit = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printCharacter(digit++, *c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if (*hexBuffer == 0) {
|
||||||
|
return;
|
||||||
void printDots(const bool dot0, const bool dot1, const bool dot2, const bool dot3) {
|
|
||||||
auto pixel = PIXELS_PER_DIGIT * 2;
|
|
||||||
if (dot0) {
|
|
||||||
pixels[pixel] = color;
|
|
||||||
}
|
}
|
||||||
pixel++;
|
|
||||||
if (dot1) {
|
|
||||||
pixels[pixel] = color;
|
|
||||||
}
|
|
||||||
pixel++;
|
|
||||||
if (dot2) {
|
|
||||||
pixels[pixel] = color;
|
|
||||||
}
|
|
||||||
pixel++;
|
|
||||||
if (dot3) {
|
|
||||||
pixels[pixel] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printCharacter(int digit, const char character) {
|
|
||||||
auto pixel = digit * PIXELS_PER_DIGIT + (digit >= 2 ? TOTAL_DOT_PIXEL_COUNT : 0);
|
|
||||||
const auto symbol = getSymbol(character);
|
|
||||||
for (auto s = *symbol; s < *symbol + SYMBOL_SIZE; s++) {
|
|
||||||
if (*s) {
|
|
||||||
pixels[pixel++] = color;
|
|
||||||
pixels[pixel++] = color;
|
|
||||||
pixels[pixel++] = color;
|
|
||||||
} else {
|
|
||||||
pixel += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendHexBuffer(AsyncWebSocketClient *client) {
|
|
||||||
client->text(hexBuffer);
|
client->text(hexBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fillRect(const uint8_t x, uint8_t y, uint8_t w, uint8_t h) {
|
private
|
||||||
for (int dx = 0; dx < w; ++dx) {
|
:
|
||||||
for (int dy = 0; dy < h; ++dy) {
|
|
||||||
drawVirtualPixel(x + dx, y + dy);
|
void fillHexBuffer() const {
|
||||||
}
|
if (pixels == nullptr || hexBuffer == nullptr) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void strokeRect(const uint8_t x, uint8_t y, uint8_t w, uint8_t h) {
|
|
||||||
for (int dx = 0; dx < w; ++dx) {
|
|
||||||
drawVirtualPixel(x + dx, y);
|
|
||||||
drawVirtualPixel(x + dx, y + h);
|
|
||||||
}
|
|
||||||
for (int dy = 0; dy < h; ++dy) {
|
|
||||||
drawVirtualPixel(x, y + dy);
|
|
||||||
drawVirtualPixel(x + w, y + dy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawVirtualPixel(const uint8_t x, const uint8_t y) {
|
|
||||||
const auto index = findIndexForVirtualCoordinates(x, y);
|
|
||||||
if (index >= 0) {
|
|
||||||
pixels[index] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Mapping digitMapping[32] = {
|
|
||||||
// @formatter:off
|
|
||||||
{0, 3}, {0, 2}, {0, 1}, // top left
|
|
||||||
{1, 0}, {2, 0}, {3, 0}, // top
|
|
||||||
{4, 1}, {4, 2}, {4, 3}, // top right
|
|
||||||
{4, 5}, {4, 6}, {4, 7}, // bottom right
|
|
||||||
{3, 8}, {2, 8}, {1, 8}, // bottom
|
|
||||||
{0, 7}, {0, 6}, {0, 5}, // bottom left
|
|
||||||
{1, 4}, {2, 4}, {3, 4}, // middle
|
|
||||||
// @formatter:on
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t dotMapping[4] = {0, 2, 6, 8};
|
|
||||||
|
|
||||||
uint8_t findIndexForVirtualCoordinates(const uint8_t x, const uint8_t y) {
|
|
||||||
if (x < 0 || x > 24 || y < 0 || y > 8) {
|
|
||||||
return -1;
|
|
||||||
} else if (x >= 20) {
|
|
||||||
return _findIndexForVirtualCoordinates_digitRelative(x - 20, y) + 3 * PIXELS_PER_DIGIT + TOTAL_DOT_PIXEL_COUNT;
|
|
||||||
} else if (x >= 14) {
|
|
||||||
return _findIndexForVirtualCoordinates_digitRelative(x - 14, y) + 2 * PIXELS_PER_DIGIT + TOTAL_DOT_PIXEL_COUNT;
|
|
||||||
} else if (x == 12) {
|
|
||||||
return _findIndexForVirtualCoordinates_dotRelative(y) + 2 * PIXELS_PER_DIGIT;
|
|
||||||
} else if (x >= 6) {
|
|
||||||
return _findIndexForVirtualCoordinates_digitRelative(x - 6, y) + 1 * PIXELS_PER_DIGIT;
|
|
||||||
} else {
|
|
||||||
return _findIndexForVirtualCoordinates_digitRelative(x, y) + 0 * PIXELS_PER_DIGIT;;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t _findIndexForVirtualCoordinates_digitRelative(const uint8_t x, const uint8_t y) {
|
|
||||||
for (auto index = 0; index < PIXELS_PER_DIGIT; index++) {
|
|
||||||
auto item = digitMapping[index];
|
|
||||||
if (item.x == x && item.y == y) {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t _findIndexForVirtualCoordinates_dotRelative(const uint8_t y) {
|
|
||||||
for (auto index = 0; index < DOT_COUNT; index++) {
|
|
||||||
auto dotY = dotMapping[index];
|
|
||||||
if (dotY == y) {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fillHexBuffer() {
|
|
||||||
auto b = hexBuffer;
|
auto b = hexBuffer;
|
||||||
for (const auto& pixel: pixels) {
|
for (auto pixel = pixels; pixel < pixels + totalPixelCount; ++pixel) {
|
||||||
b += snprintf(b, sizeof hexBuffer - (b - hexBuffer), "%X%X%X", pixel.r / 16, pixel.g / 16, pixel.b / 16);
|
b += snprintf(b, sizeof hexBuffer - (b - hexBuffer), "%X%X%X", pixel->r / 16, pixel->g / 16, pixel->b / 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Display display;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
200
src/display/DisplayDigits4.h
Normal file
200
src/display/DisplayDigits4.h
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
#ifndef DISPLAY_DIGITS4_H
|
||||||
|
#define DISPLAY_DIGITS4_H
|
||||||
|
|
||||||
|
#include "DisplayPart.h"
|
||||||
|
#include "font.h"
|
||||||
|
|
||||||
|
#define PIXELS_PER_SEGMENT 3
|
||||||
|
#define SEGMENTS_PER_DIGIT 7
|
||||||
|
#define PIXELS_PER_DOT 1
|
||||||
|
#define DOT_COUNT 4
|
||||||
|
#define DIGIT_COUNT 4
|
||||||
|
|
||||||
|
#define PIXELS_PER_DIGIT (PIXELS_PER_SEGMENT * SEGMENTS_PER_DIGIT)
|
||||||
|
#define TOTAL_DOT_PIXEL_COUNT (PIXELS_PER_DOT * DOT_COUNT)
|
||||||
|
#define TOTAL_SEGMENT_PIXEL_COUNT (DIGIT_COUNT * PIXELS_PER_DIGIT)
|
||||||
|
#define TOTAL_POINTS_PIXEL_COUNT (4 * 3 * 5)
|
||||||
|
#define TOTAL_PIXEL_COUNT (TOTAL_SEGMENT_PIXEL_COUNT + TOTAL_DOT_PIXEL_COUNT + TOTAL_POINTS_PIXEL_COUNT)
|
||||||
|
|
||||||
|
#define DISPLAY_VIRTUAL_WIDTH 25
|
||||||
|
#define DISPLAY_VIRTUAL_HEIGHT 9
|
||||||
|
|
||||||
|
class DisplayDigits4 final : public DisplayPart {
|
||||||
|
|
||||||
|
struct Mapping {
|
||||||
|
|
||||||
|
uint8_t x;
|
||||||
|
|
||||||
|
uint8_t y;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit DisplayDigits4(Display *display, const int indexOffset)
|
||||||
|
: DisplayPart(display, indexOffset,TOTAL_PIXEL_COUNT) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
void printf(const char *format, ...) const {
|
||||||
|
char buffer[64];
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vsnprintf(buffer, sizeof buffer, format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
print(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(const char *str) const {
|
||||||
|
auto digit = 0;
|
||||||
|
for (auto c = str; *c != 0 && digit < 4; c++) {
|
||||||
|
switch (*c) {
|
||||||
|
case '\'':
|
||||||
|
case '"':
|
||||||
|
case '`':
|
||||||
|
case '.':
|
||||||
|
printDots(false, false, false, true);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
printDots(false, false, true, true);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
printDots(false, true, true, false);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
|
case ';':
|
||||||
|
printDots(false, true, true, true);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
|
case '|':
|
||||||
|
printDots(true, true, true, true);
|
||||||
|
digit = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printCharacter(digit++, *c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printDots(const bool dot0, const bool dot1, const bool dot2, const bool dot3) const {
|
||||||
|
auto pixel = PIXELS_PER_DIGIT * 2;
|
||||||
|
if (dot0) {
|
||||||
|
setIndexPixel(pixel);
|
||||||
|
}
|
||||||
|
pixel++;
|
||||||
|
if (dot1) {
|
||||||
|
setIndexPixel(pixel);
|
||||||
|
}
|
||||||
|
pixel++;
|
||||||
|
if (dot2) {
|
||||||
|
setIndexPixel(pixel);
|
||||||
|
}
|
||||||
|
pixel++;
|
||||||
|
if (dot3) {
|
||||||
|
setIndexPixel(pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printCharacter(const int digit, const char character) const {
|
||||||
|
auto pixel = digit * PIXELS_PER_DIGIT + (digit >= 2 ? TOTAL_DOT_PIXEL_COUNT : 0);
|
||||||
|
const auto symbol = getSegment7Character(character);
|
||||||
|
for (auto s = *symbol; s < *symbol + sizeof(Segment7Character); s++) {
|
||||||
|
if (*s) {
|
||||||
|
setIndexPixel(pixel++);
|
||||||
|
setIndexPixel(pixel++);
|
||||||
|
setIndexPixel(pixel++);
|
||||||
|
} else {
|
||||||
|
pixel += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillRect(const uint8_t x, const uint8_t y, const uint8_t w, const uint8_t h) const {
|
||||||
|
for (auto dx = 0; dx < w; ++dx) {
|
||||||
|
for (auto dy = 0; dy < h; ++dy) {
|
||||||
|
setRasterPixel(x + dx, y + dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void strokeRect(const uint8_t x, const uint8_t y, const uint8_t w, const uint8_t h) const {
|
||||||
|
for (auto dx = 0; dx < w; ++dx) {
|
||||||
|
setRasterPixel(x + dx, y);
|
||||||
|
setRasterPixel(x + dx, y + h);
|
||||||
|
}
|
||||||
|
for (auto dy = 0; dy < h; ++dy) {
|
||||||
|
setRasterPixel(x, y + dy);
|
||||||
|
setRasterPixel(x + w, y + dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRasterPixel(const uint8_t x, const uint8_t y) const override {
|
||||||
|
const auto index = findIndexForVirtualCoordinates(x, y);
|
||||||
|
if (index >= 0) {
|
||||||
|
setIndexPixel(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Mapping digitMapping[32] = {
|
||||||
|
// @formatter:off
|
||||||
|
{0, 3}, {0, 2}, {0, 1}, // top left
|
||||||
|
{1, 0}, {2, 0}, {3, 0}, // top
|
||||||
|
{4, 1}, {4, 2}, {4, 3}, // top right
|
||||||
|
{4, 5}, {4, 6}, {4, 7}, // bottom right
|
||||||
|
{3, 8}, {2, 8}, {1, 8}, // bottom
|
||||||
|
{0, 7}, {0, 6}, {0, 5}, // bottom left
|
||||||
|
{1, 4}, {2, 4}, {3, 4}, // middle
|
||||||
|
// @formatter:on
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t dotMapping[4] = {0, 2, 6, 8};
|
||||||
|
|
||||||
|
int findIndexForVirtualCoordinates(const uint8_t x, const uint8_t y) const {
|
||||||
|
if (x < 0 || x > 24 || y < 0 || y > 8) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (x >= 20) {
|
||||||
|
return _findIndexForVirtualCoordinates_digitRelative(x - 20, y) + 3 * PIXELS_PER_DIGIT + TOTAL_DOT_PIXEL_COUNT;
|
||||||
|
}
|
||||||
|
if (x >= 14) {
|
||||||
|
return _findIndexForVirtualCoordinates_digitRelative(x - 14, y) + 2 * PIXELS_PER_DIGIT + TOTAL_DOT_PIXEL_COUNT;
|
||||||
|
}
|
||||||
|
if (x == 12) {
|
||||||
|
return _findIndexForVirtualCoordinates_dotRelative(y) + 2 * PIXELS_PER_DIGIT;
|
||||||
|
}
|
||||||
|
if (x >= 6) {
|
||||||
|
return _findIndexForVirtualCoordinates_digitRelative(x - 6, y) + 1 * PIXELS_PER_DIGIT;
|
||||||
|
}
|
||||||
|
return _findIndexForVirtualCoordinates_digitRelative(x, y) + 0 * PIXELS_PER_DIGIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _findIndexForVirtualCoordinates_digitRelative(const uint8_t x, const uint8_t y) const {
|
||||||
|
for (auto index = 0; index < PIXELS_PER_DIGIT; index++) {
|
||||||
|
const auto item = digitMapping[index];
|
||||||
|
if (item.x == x && item.y == y) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _findIndexForVirtualCoordinates_dotRelative(const uint8_t y) const {
|
||||||
|
for (auto index = 0; index < DOT_COUNT; index++) {
|
||||||
|
const auto dotY = dotMapping[index];
|
||||||
|
if (dotY == y) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
66
src/display/DisplayMatrix.h
Normal file
66
src/display/DisplayMatrix.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#ifndef DISPLAY_MATRIX_H
|
||||||
|
#define DISPLAY_MATRIX_H
|
||||||
|
|
||||||
|
#include "DisplayPart.h"
|
||||||
|
#include "DisplayRasterFont.h"
|
||||||
|
|
||||||
|
class DisplayMatrix final : public DisplayPart {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const int rows;
|
||||||
|
|
||||||
|
DisplayMatrix(Display *display, const int indexOffset, const int cols, const int rows) : DisplayPart(display, indexOffset, cols * rows), rows(rows) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
int printf(const char *format, ...) const {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
const auto x = printf(0, 0, format, args);
|
||||||
|
va_end(args);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printf(int x, const int y, const char *format, ...) const {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
x = printf(x, y, format, args);
|
||||||
|
va_end(args);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printf(const int x, const int y, const char *format, const va_list args) const {
|
||||||
|
char buffer[128];
|
||||||
|
vsnprintf(buffer, sizeof buffer, format, args);
|
||||||
|
return print(x, y, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print(int x, const int y, const char *text) const {
|
||||||
|
for (auto c = text; *c != '\0'; ++c) {
|
||||||
|
x = print(x, y, *c) + 1;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int print(const int x, const int y, const char c) const {
|
||||||
|
auto maxWidth = 0;
|
||||||
|
const auto character = getRasterCharacter(c);
|
||||||
|
for (auto cy = 0; cy < sizeof(RasterCharacter); cy++) {
|
||||||
|
for (auto cx = 0; cx < sizeof(RasterCharacter[0]); cx++) {
|
||||||
|
if (character[y][x]) {
|
||||||
|
setRasterPixel(x + cx, y + cy);
|
||||||
|
maxWidth = max(maxWidth, x + cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x + maxWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRasterPixel(const uint8_t x, const uint8_t y) const override {
|
||||||
|
setIndexPixel(x * rows + y);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
37
src/display/DisplayPart.h
Normal file
37
src/display/DisplayPart.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef DISPLAYPART_H
|
||||||
|
#define DISPLAYPART_H
|
||||||
|
|
||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
|
||||||
|
class DisplayPart {
|
||||||
|
|
||||||
|
Display *display;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const int indexOffset;
|
||||||
|
|
||||||
|
const int totalPixelCount;
|
||||||
|
|
||||||
|
const int nextPixelIndex;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
DisplayPart(Display *display, const int indexOffset, const int totalPixelCount) : display(display), indexOffset(indexOffset), totalPixelCount(totalPixelCount), nextPixelIndex(indexOffset + totalPixelCount) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~DisplayPart() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void setRasterPixel(uint8_t x, uint8_t y) const = 0;
|
||||||
|
|
||||||
|
void setIndexPixel(const int index) const {
|
||||||
|
display->setPixel(indexOffset + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
325
src/display/DisplayRasterFont.cpp
Normal file
325
src/display/DisplayRasterFont.cpp
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
#include "DisplayRasterFont.h"
|
||||||
|
|
||||||
|
#include "../core/BASICS.h"
|
||||||
|
|
||||||
|
#define RASTER_FONT_NUMBER 0
|
||||||
|
#define RASTER_FONT_ALPHA (RASTER_FONT_NUMBER + 10)
|
||||||
|
#define RASTER_FONT_SPECIAL (RASTER_FONT_ALPHA + 26)
|
||||||
|
|
||||||
|
#define RASTER_FONT_COLON (RASTER_FONT_SPECIAL + 1)
|
||||||
|
#define RASTER_FONT_DASH (RASTER_FONT_COLON + 1)
|
||||||
|
#define RASTER_FONT_PERCENT (RASTER_FONT_DASH + 1)
|
||||||
|
#define RASTER_FONT_DEGREE (RASTER_FONT_PERCENT + 1)
|
||||||
|
#define RASTER_FONT_FALLBACK (RASTER_FONT_DEGREE + 1)
|
||||||
|
|
||||||
|
RasterCharacter *getRasterCharacter(const char character) {
|
||||||
|
if (character >= '0' && character <= '9') {
|
||||||
|
return &RASTER_FONT[character - '0' + RASTER_FONT_NUMBER];
|
||||||
|
}
|
||||||
|
if (character >= 'a' && character <= 'z') {
|
||||||
|
return &RASTER_FONT[character - 'a' + RASTER_FONT_ALPHA];
|
||||||
|
}
|
||||||
|
if (character >= 'A' && character <= 'Z') {
|
||||||
|
return &RASTER_FONT[character - 'A' + RASTER_FONT_ALPHA];
|
||||||
|
}
|
||||||
|
switch (character) {
|
||||||
|
case ':': return &RASTER_FONT[RASTER_FONT_COLON];
|
||||||
|
case '-': return &RASTER_FONT[RASTER_FONT_DASH];
|
||||||
|
case '%': return &RASTER_FONT[RASTER_FONT_PERCENT];
|
||||||
|
case '^': return &RASTER_FONT[RASTER_FONT_DEGREE];
|
||||||
|
default: {
|
||||||
|
error("[ERROR] NO RASTER MAPPING FOR CHARACTER \"%c\" = #%d\n", character, character);
|
||||||
|
return &RASTER_FONT[RASTER_FONT_FALLBACK];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RasterCharacter RASTER_FONT[] = {
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
}, // 0
|
||||||
|
{
|
||||||
|
{_, _, X},
|
||||||
|
{_, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{_, _, X},
|
||||||
|
{_, _, X},
|
||||||
|
}, // 1
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{_, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, _},
|
||||||
|
{X, X, X},
|
||||||
|
}, // 2
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{_, _, X},
|
||||||
|
{_, X, X},
|
||||||
|
{_, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
}, // 3
|
||||||
|
{
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
{_, _, X},
|
||||||
|
{_, _, X},
|
||||||
|
}, // 4
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, _},
|
||||||
|
{X, X, X},
|
||||||
|
{_, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
}, // 5
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, _},
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
}, // 6
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{_, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, _},
|
||||||
|
}, // 7
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
}, // 8
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
{_, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
}, // 9
|
||||||
|
{
|
||||||
|
{_, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
}, // A
|
||||||
|
{
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{_, X, X},
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, _},
|
||||||
|
{_, X, X},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, _},
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, X, X},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, _},
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{_, X, X},
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{_, X, _},
|
||||||
|
{_, X, _},
|
||||||
|
{_, X, _},
|
||||||
|
{_, X, _},
|
||||||
|
{_, X, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{_, _, X},
|
||||||
|
{_, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, _},
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, X},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, X, X},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{_, _, _},
|
||||||
|
{_, _, _},
|
||||||
|
{_, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{_, _, _},
|
||||||
|
{_, _, _},
|
||||||
|
{_, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, _, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{_, _, _},
|
||||||
|
{_, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
{_, X, X},
|
||||||
|
{_, _, X},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, _},
|
||||||
|
{X, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{_, X, X},
|
||||||
|
{X, _, _},
|
||||||
|
{_, X, _},
|
||||||
|
{_, _, X},
|
||||||
|
{X, X, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{_, X, _},
|
||||||
|
{_, X, _},
|
||||||
|
{_, X, _},
|
||||||
|
{_, X, _},
|
||||||
|
}, //
|
||||||
|
{
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
}, // :
|
||||||
|
{
|
||||||
|
{_, _, _},
|
||||||
|
{_, _, _},
|
||||||
|
{_, _, _},
|
||||||
|
{X, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
}, // :
|
||||||
|
{
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{X, X, X},
|
||||||
|
{X, _, X},
|
||||||
|
}, // :
|
||||||
|
{
|
||||||
|
{_, _, _},
|
||||||
|
{_, _, _},
|
||||||
|
{X, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
}, // :
|
||||||
|
{
|
||||||
|
{X, _, X},
|
||||||
|
{X, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
{_, X, _},
|
||||||
|
{X, _, _},
|
||||||
|
}, // :
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{_, X, X},
|
||||||
|
{_, X, _},
|
||||||
|
{X, _, _},
|
||||||
|
{X, X, X},
|
||||||
|
}, // :
|
||||||
|
{
|
||||||
|
{_, _, _},
|
||||||
|
{_, X, _},
|
||||||
|
{_, _, _},
|
||||||
|
{_, X, _},
|
||||||
|
{_, _, _},
|
||||||
|
}, // :
|
||||||
|
{
|
||||||
|
{_, _, _},
|
||||||
|
{_, _, _},
|
||||||
|
{X, X, X},
|
||||||
|
{_, _, _},
|
||||||
|
{_, _, _},
|
||||||
|
}, // -
|
||||||
|
{
|
||||||
|
{X, _, _},
|
||||||
|
{_, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
{X, _, _},
|
||||||
|
{_, _, X},
|
||||||
|
}, // %
|
||||||
|
{
|
||||||
|
{_, X, _},
|
||||||
|
{X, _, X},
|
||||||
|
{_, X, _},
|
||||||
|
{_, _, _},
|
||||||
|
{_, _, _},
|
||||||
|
}, // %
|
||||||
|
{
|
||||||
|
{X, X, X},
|
||||||
|
{X, X, X},
|
||||||
|
{X, X, X},
|
||||||
|
{X, X, X},
|
||||||
|
{X, X, X},
|
||||||
|
}, // FALLBACK
|
||||||
|
};
|
||||||
10
src/display/DisplayRasterFont.h
Normal file
10
src/display/DisplayRasterFont.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef RASTER_FONT_H
|
||||||
|
#define RASTER_FONT_H
|
||||||
|
|
||||||
|
typedef bool RasterCharacter[5][4];
|
||||||
|
|
||||||
|
extern RasterCharacter RASTER_FONT[];
|
||||||
|
|
||||||
|
RasterCharacter *getRasterCharacter(char character);
|
||||||
|
|
||||||
|
#endif
|
||||||
3
src/display/MyDisplay.cpp
Normal file
3
src/display/MyDisplay.cpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include "MyDisplay.h"
|
||||||
|
|
||||||
|
MyDisplay display;
|
||||||
32
src/display/MyDisplay.h
Normal file
32
src/display/MyDisplay.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef MY_DISPLAY_H
|
||||||
|
#define MY_DISPLAY_H
|
||||||
|
|
||||||
|
#include "DisplayDigits4.h"
|
||||||
|
|
||||||
|
#include "DisplayMatrix.h"
|
||||||
|
|
||||||
|
class MyDisplay : public Display {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DisplayDigits4 main;
|
||||||
|
|
||||||
|
DisplayMatrix left;
|
||||||
|
|
||||||
|
DisplayMatrix right;
|
||||||
|
|
||||||
|
explicit MyDisplay()
|
||||||
|
: Display(TOTAL_PIXEL_COUNT + 2 * 3 * 5),
|
||||||
|
main(this, 0),
|
||||||
|
left(this, main.nextPixelIndex, 3, 5),
|
||||||
|
right(this, left.nextPixelIndex, 3, 5) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
~MyDisplay() = default;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern MyDisplay display;
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,9 +1,30 @@
|
|||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include "../core/BASICS.h"
|
||||||
#include "../core/log.h"
|
|
||||||
|
|
||||||
SYMBOL SYMBOLS[][SYMBOL_SIZE] = {
|
Segment7Character *getSegment7Character(const char character) {
|
||||||
|
if (character >= '0' && character <= '9') {
|
||||||
|
return &SEGMENT7_FONT[character - '0'];
|
||||||
|
}
|
||||||
|
if (character >= 'a' && character <= 'z') {
|
||||||
|
return &SEGMENT7_FONT[character - 'a' + 10];
|
||||||
|
}
|
||||||
|
if (character >= 'A' && character <= 'Z') {
|
||||||
|
return &SEGMENT7_FONT[character - 'A' + 10];
|
||||||
|
}
|
||||||
|
switch (character) {
|
||||||
|
case '-': return &SEGMENT7_FONT[36];
|
||||||
|
case '_': return &SEGMENT7_FONT[37];
|
||||||
|
case '^': return &SEGMENT7_FONT[38];
|
||||||
|
case ' ': return &SEGMENT7_FONT[39];
|
||||||
|
default: {
|
||||||
|
error("[ERROR] NO SEGMENT7 MAPPING FOR CHARACTER \"%c\" = #%d\n", character, character);
|
||||||
|
return &SEGMENT7_FONT[countof(SEGMENT7_FONT) - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Segment7Character SEGMENT7_FONT[] = {
|
||||||
{X,X,X,X,X,X,_}, // 0
|
{X,X,X,X,X,X,_}, // 0
|
||||||
{_,_,X,X,_,_,_}, // 1
|
{_,_,X,X,_,_,_}, // 1
|
||||||
{_,X,X,_,X,X,X}, // 2
|
{_,X,X,_,X,X,X}, // 2
|
||||||
@ -45,25 +66,3 @@ SYMBOL SYMBOLS[][SYMBOL_SIZE] = {
|
|||||||
{X,X,X,_,_,_,X}, // °
|
{X,X,X,_,_,_,X}, // °
|
||||||
{_,_,_,_,_,_,_}, //
|
{_,_,_,_,_,_,_}, //
|
||||||
};
|
};
|
||||||
|
|
||||||
SYMBOL *getSymbol(const char character) {
|
|
||||||
if (character >= '0' && character <= '9') {
|
|
||||||
return SYMBOLS[character - '0'];
|
|
||||||
}
|
|
||||||
if (character >= 'a' && character <= 'z') {
|
|
||||||
return SYMBOLS[character - 'a' + 10];
|
|
||||||
}
|
|
||||||
if (character >= 'A' && character <= 'Z') {
|
|
||||||
return SYMBOLS[character - 'A' + 10];
|
|
||||||
}
|
|
||||||
switch (character) {
|
|
||||||
case '-': return SYMBOLS[36];
|
|
||||||
case '_': return SYMBOLS[37];
|
|
||||||
case '^': return SYMBOLS[38];
|
|
||||||
case ' ': return SYMBOLS[39];
|
|
||||||
default: {
|
|
||||||
error("[ERROR] NO SYMBOL MAPPING FOR CHARACTER \"%c\" = #%d\n", character, character);
|
|
||||||
return SYMBOLS[SYMBOL_SIZE - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,17 +1,10 @@
|
|||||||
#ifndef FONT_H
|
#ifndef FONT_H
|
||||||
#define FONT_H
|
#define FONT_H
|
||||||
|
|
||||||
#define X true
|
typedef const bool Segment7Character[7];
|
||||||
#define _ false
|
|
||||||
|
|
||||||
constexpr auto SYMBOL_COUNT = 39;
|
extern Segment7Character SEGMENT7_FONT[40];
|
||||||
|
|
||||||
constexpr auto SYMBOL_SIZE = 7;
|
Segment7Character *getSegment7Character(char character);
|
||||||
|
|
||||||
typedef const bool SYMBOL[SYMBOL_SIZE];
|
|
||||||
|
|
||||||
extern SYMBOL SYMBOLS[][SYMBOL_SIZE];
|
|
||||||
|
|
||||||
SYMBOL *getSymbol(char character);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -12,7 +12,7 @@ void setup() {
|
|||||||
bootDelay();
|
bootDelay();
|
||||||
fsMount();
|
fsMount();
|
||||||
httpSetup();
|
httpSetup();
|
||||||
appStart(APP_DEMO_NAME);
|
appStart(APP_MATCH_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user