rewrite
This commit is contained in:
parent
8b74a90ebb
commit
46ddc8425f
67
Docs.md
Normal file
67
Docs.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# Веб-сервер ESP8266 & P10 PAnel
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
Этот проект реализует подключение и взаимодействие через веб-сервер ESP8266 и LED панели P10 4*3
|
||||||
|
|
||||||
|
## Возможности
|
||||||
|
- Обработка веб-запросов
|
||||||
|
- Изменение текста на матрице
|
||||||
|
- Реализовано 4 режима работы матрицы
|
||||||
|
- Вывод инвормации в JSON-формате
|
||||||
|
|
||||||
|
## Используемые библиотеки
|
||||||
|
- ESP8266WiFi
|
||||||
|
- Ticker
|
||||||
|
- DMD2
|
||||||
|
- ESPAsyncWebServer
|
||||||
|
- ESPAsyncTCP
|
||||||
|
- ArduinoJSON
|
||||||
|
|
||||||
|
## Установка
|
||||||
|
Клонируйте репозиторий:
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/
|
||||||
|
```
|
||||||
|
|
||||||
|
Установите недостающие библиотеки и загрузите код на ESP8266
|
||||||
|
|
||||||
|
## Путь и тело запроса
|
||||||
|
|
||||||
|
**GET /api/led**
|
||||||
|
Возвращает текущее состояние панели
|
||||||
|
|
||||||
|
**POST /api/text**
|
||||||
|
Принимает текст отображающийся на панели
|
||||||
|
Пример запроса:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"text":"Hello \nfrom \nGitTea"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
**POST /api/led**
|
||||||
|
Изменяет состояние панели (Включение/выключение) и изменяет режим работы панели
|
||||||
|
Пример запроса:
|
||||||
|
Запрос на включение/выключение:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"panel": "on"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"panel": "off"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Запрос на изменение режима: (state : 1-4)
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"state": "1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Запросы на включение и изменение режима могут приниматься вместе:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"panel": "on",
|
||||||
|
"state": "3"
|
||||||
|
}
|
||||||
|
```
|
302
ESP82_PANEL.ino
Normal file
302
ESP82_PANEL.ino
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <Ticker.h>
|
||||||
|
#include <DMD2.h>
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <fonts/Font_BOLD.h>
|
||||||
|
#include "data/output.h"
|
||||||
|
#include "data/kitleft.h"
|
||||||
|
|
||||||
|
const uint8_t* FONT = Font_BOLD;
|
||||||
|
const int WIDTH = 4; // Количество матриц в ширину
|
||||||
|
const int HEIGHT = 3; // Количество матриц в высоту
|
||||||
|
|
||||||
|
AsyncWebServer server(80);
|
||||||
|
String displayText = "Привет из СКБ \"КИТ\"";
|
||||||
|
bool isON = true;
|
||||||
|
bool showText = true;
|
||||||
|
bool scroll = true;
|
||||||
|
const char* skb = "СКБ";
|
||||||
|
const char* kit = "\"КИТ\"";
|
||||||
|
const char* ictib = "ИКТИБ";
|
||||||
|
const char* ssid = "SKBKIT";
|
||||||
|
const char* password = "skbkit2024";
|
||||||
|
IPAddress staticIP(10, 131, 170, 4);
|
||||||
|
IPAddress gateway(10, 131, 170, 1);
|
||||||
|
IPAddress subnet(255, 255, 255, 0);
|
||||||
|
|
||||||
|
SPIDMD dmd(WIDTH, HEIGHT);
|
||||||
|
DMD_TextBox* box = nullptr; // Указатель на текстовый бокс
|
||||||
|
Ticker ticker;
|
||||||
|
|
||||||
|
void setupWiFi() {
|
||||||
|
WiFi.begin(ssid, password);
|
||||||
|
if (!WiFi.config(staticIP, gateway, subnet)) {
|
||||||
|
Serial.println("Failed WiFi connect!");
|
||||||
|
} else {
|
||||||
|
Serial.println("Static WiFi configured!");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("\nConnected to WiFi");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawBinaryArrayKit() {
|
||||||
|
dmd.clearScreen();
|
||||||
|
|
||||||
|
for (int x = 0; x < WIDTH * 32; x++) {
|
||||||
|
for (int y = 0; y < HEIGHT * 16; y++) {
|
||||||
|
int idx = y * (WIDTH * 32) + x; // Индекс с учетом полной ширины
|
||||||
|
if (output[idx] == 1) {
|
||||||
|
dmd.setPixel(x, y, GRAPHICS_ON);
|
||||||
|
} else {
|
||||||
|
dmd.setPixel(x, y, GRAPHICS_OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawBinaryArrayKitLeft() {
|
||||||
|
dmd.clearScreen();
|
||||||
|
|
||||||
|
for (int x = 0; x < WIDTH * 32; x++) {
|
||||||
|
for (int y = 0; y < HEIGHT * 16; y++) {
|
||||||
|
int idx = y * (WIDTH * 32) + x; // Индекс с учетом полной ширины
|
||||||
|
if (kitleft[idx] == 1) {
|
||||||
|
dmd.setPixel(x, y, GRAPHICS_ON);
|
||||||
|
} else {
|
||||||
|
dmd.setPixel(x, y, GRAPHICS_OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void switchDisplayMode() {
|
||||||
|
if (isON) {
|
||||||
|
if (showText) {
|
||||||
|
drawScrollingText(); // Запускаем скролл текста на второй строке
|
||||||
|
} else {
|
||||||
|
drawBinaryArrayKit();
|
||||||
|
}
|
||||||
|
showText = !showText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void switchDisplayModeScroll() {
|
||||||
|
if (isON && scroll) {
|
||||||
|
//box->scrollX(1); // Двигаем текст влево
|
||||||
|
//box->drawScrollingText();
|
||||||
|
dmd.marqueeScrollX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawScrollingText() {
|
||||||
|
if (!box) {
|
||||||
|
box = new DMD_TextBox(dmd, 0, 17, WIDTH * 32, HEIGHT * 16); // Устанавливаем текстовый бокс на вторую строку
|
||||||
|
} else {
|
||||||
|
box->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
box->print(displayText.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void drawText() {
|
||||||
|
dmd.clearScreen();
|
||||||
|
|
||||||
|
if (!box) { // Создаём текстовый бокс только один раз
|
||||||
|
box = new DMD_TextBox(dmd, 0, 0, WIDTH * 32, HEIGHT * 16);
|
||||||
|
} else {
|
||||||
|
box->clear(); // Очищаем текущий бокс перед обновлением текста
|
||||||
|
}
|
||||||
|
|
||||||
|
box->print(displayText.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleText(AsyncWebServerRequest* request, const JsonVariant& json) {
|
||||||
|
if (!json.containsKey("text")) {
|
||||||
|
request->send(400, "application/json", "{\"error\": \"Missing text field\"}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
displayText = json["text"].as<String>();
|
||||||
|
drawText();
|
||||||
|
|
||||||
|
request->send(200, "application/json", "{\"status\": \"OK\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleTurn(AsyncWebServerRequest* request, const JsonVariant& json) {
|
||||||
|
String panelTurn = json["panel"].as<String>();
|
||||||
|
String panelState = json["state"].as<String>();
|
||||||
|
|
||||||
|
if (json.containsKey("panel")) {
|
||||||
|
panelTurn = json["panel"].as<String>();
|
||||||
|
}
|
||||||
|
if (json.containsKey("state")) {
|
||||||
|
panelState = json["state"].as<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ticker.detach();
|
||||||
|
|
||||||
|
if (!panelTurn.isEmpty()) {
|
||||||
|
if (panelTurn == "on") {
|
||||||
|
isON = true;
|
||||||
|
} else if (panelTurn == "off") {
|
||||||
|
isON = false;
|
||||||
|
dmd.clearScreen();
|
||||||
|
dmd.drawFilledBox(0, 0, WIDTH * 32 - 1, HEIGHT * 16 - 1, GRAPHICS_OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!panelState.isEmpty()) {
|
||||||
|
if (panelState == "1") { // Скролинг текста
|
||||||
|
dmd.clearScreen();
|
||||||
|
dmd.selectFont(FONT);
|
||||||
|
dmd.drawLine(0, 14, 16, 14, GRAPHICS_ON); // x y x y
|
||||||
|
dmd.drawLine(0, 13, 16, 13, GRAPHICS_ON);
|
||||||
|
|
||||||
|
dmd.drawLine(16, 14, 20, 5, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(16, 13, 20, 4, GRAPHICS_ON);
|
||||||
|
|
||||||
|
dmd.drawLine(20, 5, 30, 5, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(20, 4, 30, 4, GRAPHICS_ON);
|
||||||
|
|
||||||
|
dmd.drawCircle(33, 4, 3, GRAPHICS_ON);
|
||||||
|
dmd.drawCircle(33, 4, 2, GRAPHICS_ON); //1 line
|
||||||
|
|
||||||
|
dmd.drawLine(20, 14, 40, 14, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(20, 13, 40, 13, GRAPHICS_ON);
|
||||||
|
|
||||||
|
dmd.drawLine(40, 14, 45, 5, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(40, 13, 45, 4, GRAPHICS_ON);
|
||||||
|
|
||||||
|
dmd.drawLine(45, 5, 60, 5, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(45, 4, 60, 4, GRAPHICS_ON);
|
||||||
|
|
||||||
|
dmd.drawLine(60, 5, 65, 14, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(60, 4, 65, 13, GRAPHICS_ON);
|
||||||
|
|
||||||
|
dmd.drawLine(65, 14, 75, 14, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(65, 13, 75, 13, GRAPHICS_ON);
|
||||||
|
dmd.drawCircle(78, 13, 3, GRAPHICS_ON);
|
||||||
|
dmd.drawCircle(78, 13, 2, GRAPHICS_ON); //2 line
|
||||||
|
|
||||||
|
dmd.drawCircle(68, 4, 3, GRAPHICS_ON);
|
||||||
|
dmd.drawCircle(68, 4, 2, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(71, 5, 85, 5, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(71, 4, 85, 4, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(85, 5, 90, 14, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(85, 4, 90, 13, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(90, 14, 100, 14, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(90, 13, 100, 13, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(100, 14, 105, 5, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(100, 13, 105, 4, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(105, 5, 128, 5, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(105, 4, 128, 4, GRAPHICS_ON); // 3 line
|
||||||
|
|
||||||
|
// ======================================
|
||||||
|
|
||||||
|
dmd.drawLine(0, 35, 16, 35, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(0, 36, 16, 36, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(16, 35, 21, 43, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(16, 36, 21, 44, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(21, 43, 31, 43, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(21, 44, 31, 44, GRAPHICS_ON);
|
||||||
|
dmd.drawCircle(34, 44, 3, GRAPHICS_ON);
|
||||||
|
dmd.drawCircle(34, 44, 2, GRAPHICS_ON); // 1 line
|
||||||
|
|
||||||
|
dmd.drawLine(20, 35, 40, 35, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(20, 36, 40, 36, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(40, 35, 45, 43, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(40, 36, 45, 44, GRAPHICS_ON); // 2 line
|
||||||
|
|
||||||
|
dmd.drawLine(45, 43, 60, 43, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(45, 44, 60, 44, GRAPHICS_ON);
|
||||||
|
|
||||||
|
dmd.drawLine(60, 43, 65, 35, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(60, 44, 65, 36, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(65, 35, 75, 35, GRAPHICS_ON);
|
||||||
|
dmd.drawLine(65, 36, 75, 36, GRAPHICS_ON);
|
||||||
|
dmd.drawCircle(78, 36, 3, GRAPHICS_ON);
|
||||||
|
dmd.drawCircle(78, 36, 2, GRAPHICS_ON);
|
||||||
|
} else if (panelState == "2") { // Текст и картинка динамика
|
||||||
|
dmd.clearScreen();
|
||||||
|
drawText();
|
||||||
|
ticker.attach(5, switchDisplayMode);
|
||||||
|
dmd.clearScreen();
|
||||||
|
drawBinaryArrayKit();
|
||||||
|
} else if (panelState == "3") { // Текст и картинка статика
|
||||||
|
dmd.clearScreen();
|
||||||
|
drawBinaryArrayKitLeft();
|
||||||
|
dmd.drawString_P(79, 2, skb);
|
||||||
|
dmd.drawString_P(71, 17, kit);
|
||||||
|
dmd.drawString_P(68, 32, ictib);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String response = "{\"panel\" : " + String(isON ? "\"on\"" : "\"off\"") + ", \"state\" : " + (panelState.isEmpty() ? "null" : panelState) + "}";
|
||||||
|
request->send(200, "application/json", response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
setupWiFi();
|
||||||
|
dmd.setBrightness(255);
|
||||||
|
dmd.selectFont(FONT);
|
||||||
|
dmd.begin();
|
||||||
|
dmd.clearScreen();
|
||||||
|
|
||||||
|
box = new DMD_TextBox(dmd, 0, 0, WIDTH * 32, HEIGHT * 16); // Создаём текстовый бокс один раз
|
||||||
|
|
||||||
|
box->print("Hello");
|
||||||
|
|
||||||
|
server.on(
|
||||||
|
"/api/text", HTTP_POST,
|
||||||
|
[](AsyncWebServerRequest* request) {},
|
||||||
|
NULL,
|
||||||
|
[](AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t, size_t) {
|
||||||
|
StaticJsonDocument<256> jsonReq;
|
||||||
|
DeserializationError error = deserializeJson(jsonReq, data, len);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
request->send(400, "application/json", "{\"error\": \"Invalid JSON\"}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleText(request, jsonReq.as<JsonVariant>()); // Передаём как const JsonVariant&
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/api/led", HTTP_GET, [](AsyncWebServerRequest* request) {
|
||||||
|
if (isON) {
|
||||||
|
request->send(200, "application/json", "{\"panel\" : \"on\"}");
|
||||||
|
} else if (!isON) {
|
||||||
|
request->send(200, "application/json", "{\"panel\" : \"off\"}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on(
|
||||||
|
"/api/led", HTTP_POST, [](AsyncWebServerRequest* request) {},
|
||||||
|
NULL, [](AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t, size_t) {
|
||||||
|
StaticJsonDocument<256> jsonReq;
|
||||||
|
DeserializationError error = deserializeJson(jsonReq, data, len);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
request->send(400, "application/json", "{\"error\": \"Invalid JSON\"}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTurn(request, jsonReq.as<JsonVariant>());
|
||||||
|
});
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
}
|
17
README.md
17
README.md
@ -1,17 +0,0 @@
|
|||||||
# The code for the panel P10 + ESP32
|
|
||||||
*********
|
|
||||||
* List of features
|
|
||||||
+ Edit text in real time via HomeAssistiant
|
|
||||||
+ Split sentences into lines (features)
|
|
||||||
+ Add a drawing as a binary image
|
|
||||||
+ Panel operation modes(-> Text scroll -> Image ->) || (static image + static text)
|
|
||||||
+ OTA (Over The Air Updates) (features)
|
|
||||||
+ State of panel
|
|
||||||
+ Remote panel on/off
|
|
||||||
# Docs for API
|
|
||||||
* Endpoints
|
|
||||||
+ 10.131.170.4 - the local static IP
|
|
||||||
+ /api/text - endpoint for editing text (POST)
|
|
||||||
+ /api/led - endpint for on/off panel (POST)
|
|
||||||
+ /api/led - endpoint for check on/off panel (GET), return "{"led":"true"}" if panel ON and "{"led":"false"}" if panel OFF
|
|
||||||
+ /api/state - endpoint for swith operation modes (POST), body: ({"State" : "1"} -> static image and static text) || body: ({"State" : "2"} -> Text scroll -> Image ->)
|
|
1
data/.venv/bin/python
Symbolic link
1
data/.venv/bin/python
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
python3
|
1
data/.venv/bin/python3
Symbolic link
1
data/.venv/bin/python3
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/usr/bin/python3
|
1
data/.venv/bin/python3.12
Symbolic link
1
data/.venv/bin/python3.12
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
python3
|
1
data/.venv/lib64
Symbolic link
1
data/.venv/lib64
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
lib
|
5
data/.venv/pyvenv.cfg
Normal file
5
data/.venv/pyvenv.cfg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
home = /usr/bin
|
||||||
|
include-system-site-packages = false
|
||||||
|
version = 3.12.3
|
||||||
|
executable = /usr/bin/python3.12
|
||||||
|
command = /usr/bin/python3 -m venv /home/maks_gejn/Arduino/ESP82_PANEL/data/.venv
|
BIN
data/kit128 (copy).bmp
Normal file
BIN
data/kit128 (copy).bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
5
data/kitleft.h
Normal file
5
data/kitleft.h
Normal file
File diff suppressed because one or more lines are too long
39
data/main.py
Normal file
39
data/main.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import argparse
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--input", required=True, help="input image path")
|
||||||
|
parser.add_argument("--output", required=False, default='output.h', help="path to output file")
|
||||||
|
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_args()
|
||||||
|
image = cv2.imread(args.input, cv2.IMREAD_GRAYSCALE)
|
||||||
|
if image is None:
|
||||||
|
print(
|
||||||
|
f"Could not read image {args.input}. "
|
||||||
|
f"Please, check that you passed the correct path"
|
||||||
|
)
|
||||||
|
exit()
|
||||||
|
|
||||||
|
image = cv2.resize(image, (128, 48))
|
||||||
|
image[image > 0] = 1
|
||||||
|
image = 1 - image
|
||||||
|
image = list(np.ravel(image))
|
||||||
|
image_text = ''
|
||||||
|
for i, pixel_data in enumerate(image):
|
||||||
|
image_text += str(pixel_data)
|
||||||
|
if i != len(image) - 1:
|
||||||
|
image_text += ', '
|
||||||
|
text = f"#ifndef _OUTPUT_\n#define _OUTPUT_\nbyte output[128*64] = {{ {image_text} }};\n\n#endif"
|
||||||
|
|
||||||
|
with open(args.output, 'w') as f:
|
||||||
|
f.write(text)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
5
data/output.h
Normal file
5
data/output.h
Normal file
File diff suppressed because one or more lines are too long
2704
fonts/Font_BOLD.h
Normal file
2704
fonts/Font_BOLD.h
Normal file
File diff suppressed because it is too large
Load Diff
25
output.h
25
output.h
@ -1,25 +0,0 @@
|
|||||||
#ifndef _OUTPUT_
|
|
||||||
#define _OUTPUT_
|
|
||||||
|
|
||||||
byte output[16 * 32] = {
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
};
|
|
||||||
|
|
||||||
const int dataSize = sizeof(output) / sizeof(output[0]);
|
|
||||||
|
|
||||||
#endif
|
|
64
output.txt
64
output.txt
@ -1,64 +0,0 @@
|
|||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000
|
|
||||||
11100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000000000000
|
|
||||||
11100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001101100000000
|
|
||||||
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001101101111111
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001101111111
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001101111111
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100111110
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110011100
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111011000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001011000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001110000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000111111111111111000000000000000000000000000000000000111000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000001111111111111111111111111100000000000000000000000000110011000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000001111111111111111111111111111110000000000000000001111001000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000001110111111111111111111111111111111111101111111111111111100000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000001111011111111111111111111111111111111101111111111111111110000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000001111100000000000000000011111111111111110111111111111111100000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000111111111111111111111001111111111111111011111111110011000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000111111111111111111111100111111111111111100000000000111000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000111111111111111111111110011111111111111111111111111110000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000011111111111110111111111001111111111111111111111111100000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000001111111111100011111111100111111111111111111111111000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000111111111100011111111110000000011111111111111110000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000011111111110111111111111111111000000011111111100000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111101111110000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111111111111111110111000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111111110000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000001111111111111111111111110000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111110000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000001111110000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000111111000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000011111000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000111100000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000011110000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
11111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
|
224
panel.ino
224
panel.ino
@ -1,224 +0,0 @@
|
|||||||
//------------------Include Libraries------------------//
|
|
||||||
#include <WiFi.h>
|
|
||||||
#include <WebServer.h>
|
|
||||||
#include <DMD32.h>
|
|
||||||
#include <fonts/Font_BOLD.h>
|
|
||||||
#include <SPIFFS.h>
|
|
||||||
#include <ESPAsyncWebServer.h>
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
#include "data/output.h"
|
|
||||||
//------------------------------------------------------//
|
|
||||||
|
|
||||||
#define DEBUG 1
|
|
||||||
|
|
||||||
//------------------Settings for panel------------------//
|
|
||||||
#define FONT Font_BOLD
|
|
||||||
#define DISPLAYS_ACROSS 1
|
|
||||||
#define DISPLAYS_DOWN 1
|
|
||||||
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Wi-Fi Settings----------------------//
|
|
||||||
const char *ssid = "SKBKIT";
|
|
||||||
const char *password = "skbkit2024";
|
|
||||||
IPAddress staticIP(10, 131, 170, 4);
|
|
||||||
IPAddress gateway(10, 131, 170, 1);
|
|
||||||
IPAddress subnet(255, 255, 255, 0);
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Web Server Settings-----------------//
|
|
||||||
AsyncWebServer server(80);
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Other Variables---------------------//
|
|
||||||
String displayText = "Привет из СКБ \"КИТ\"";
|
|
||||||
bool isScrolling = true;
|
|
||||||
bool showImage = false;
|
|
||||||
unsigned long lastScrollTime = 0;
|
|
||||||
unsigned long scrollDuration = 5000;
|
|
||||||
unsigned long imageStartTime = 0;
|
|
||||||
hw_timer_t *timer = NULL;
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Wi-Fi Connection Setup-------------//
|
|
||||||
void setupWiFi() {
|
|
||||||
WiFi.begin(ssid, password);
|
|
||||||
if (!WiFi.config(staticIP, gateway, subnet)) {
|
|
||||||
Serial.println("Failed to configure Static IP");
|
|
||||||
} else {
|
|
||||||
Serial.println("Static IP configured!");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (WiFi.status() != WL_CONNECTED) {
|
|
||||||
delay(500);
|
|
||||||
Serial.print(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.println("\nConnected to WiFi");
|
|
||||||
Serial.println(WiFi.localIP());
|
|
||||||
}
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Web Server Handlers-----------------//
|
|
||||||
void handleText(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
|
|
||||||
JsonDocument jsonReq;
|
|
||||||
String dataRequest = String((char *)data, len);
|
|
||||||
DeserializationError error = deserializeJson(jsonReq, dataRequest);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
Serial.println(F("deserializeJson() failed"));
|
|
||||||
request->send(400, "text/html", "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jsonReq["text"].is<String>()) {
|
|
||||||
displayText = jsonReq["text"].as<String>();
|
|
||||||
}
|
|
||||||
|
|
||||||
request->send(200, "text/html; charset=UTF-8", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleStateChange(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
|
|
||||||
JsonDocument jsonReq;
|
|
||||||
String dataRequest = String((char *)data, len);
|
|
||||||
DeserializationError error = deserializeJson(jsonReq, dataRequest);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
request->send(400, "text/html", "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String state = jsonReq["state"];
|
|
||||||
|
|
||||||
if (state == "1") {
|
|
||||||
dmd.clearScreen(true); // Reset the screen
|
|
||||||
displayText = "Привет из СКБ \"КИТ\"";
|
|
||||||
} else if (state == "2") {
|
|
||||||
isScrolling = true;
|
|
||||||
lastScrollTime = millis();
|
|
||||||
showImage = false;
|
|
||||||
} else if (state == "3") {
|
|
||||||
showImage = true;
|
|
||||||
imageStartTime = millis();
|
|
||||||
}
|
|
||||||
|
|
||||||
request->send(200, "text/html", "");
|
|
||||||
}
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Panel Management--------------------//
|
|
||||||
void handlePanelState(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
|
|
||||||
JsonDocument jsonReq;
|
|
||||||
String dataRequest = String((char *)data, len);
|
|
||||||
DeserializationError error = deserializeJson(jsonReq, dataRequest);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
request->send(400, "text/html", "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String state = jsonReq["panel"];
|
|
||||||
if (state == "on") {
|
|
||||||
displayText = "Привет из СКБ \"КИТ\"";
|
|
||||||
} else if (state == "off") {
|
|
||||||
displayText = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
request->send(200, "text/html", "");
|
|
||||||
}
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Display Binary Array Function------//
|
|
||||||
void displayBinaryArray() {
|
|
||||||
for (int y = 0; y < 32; y++) {
|
|
||||||
for (int x = 0; x < 16; x++) {
|
|
||||||
int idx = x * 32 + y;
|
|
||||||
if (output[idx] == 1) {
|
|
||||||
dmd.writePixel(x, y, GRAPHICS_NORMAL, true);
|
|
||||||
} else {
|
|
||||||
dmd.writePixel(x, y, GRAPHICS_NORMAL, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Marquee Scroll Function-------------//
|
|
||||||
void scrollText() {
|
|
||||||
dmd.drawMarquee(displayText.c_str(), displayText.length(), (32 * DISPLAYS_ACROSS) - 1, 0);
|
|
||||||
|
|
||||||
long start = millis();
|
|
||||||
long timer = start;
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
while (!ret) {
|
|
||||||
if ((timer + 30) < millis()) {
|
|
||||||
ret = dmd.stepMarquee(-1, 0);
|
|
||||||
timer = millis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (millis() - lastScrollTime >= scrollDuration) {
|
|
||||||
isScrolling = false;
|
|
||||||
showImage = true;
|
|
||||||
imageStartTime = millis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Timer Interrupt Function------------//
|
|
||||||
void IRAM_ATTR triggerScan() {
|
|
||||||
dmd.scanDisplayBySPI();
|
|
||||||
}
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Setup Function-----------------------//
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
dmd.selectFont(FONT);
|
|
||||||
SPIFFS.begin(true);
|
|
||||||
pinMode(22, OUTPUT);
|
|
||||||
|
|
||||||
setupWiFi();
|
|
||||||
|
|
||||||
server.on("/api/led", HTTP_GET, [](AsyncWebServerRequest *request) {
|
|
||||||
String state = isScrolling ? "true" : "false";
|
|
||||||
request->send(200, "application/json", "{\"state\": \"" + state + "\"}");
|
|
||||||
});
|
|
||||||
|
|
||||||
server.on("/api/led", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, handlePanelState);
|
|
||||||
server.on("/api/text", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, handleText);
|
|
||||||
server.on("/api/state", HTTP_POST, [](AsyncWebServerRequest *request) {}, NULL, handleStateChange);
|
|
||||||
|
|
||||||
server.begin();
|
|
||||||
|
|
||||||
uint8_t cpuClock = ESP.getCpuFreqMHz();
|
|
||||||
timer = timerBegin(0, cpuClock, true);
|
|
||||||
timerAttachInterrupt(timer, &triggerScan, true);
|
|
||||||
timerAlarmWrite(timer, 300, true);
|
|
||||||
timerAlarmEnable(timer);
|
|
||||||
|
|
||||||
dmd.clearScreen(true);
|
|
||||||
}
|
|
||||||
//-------------------------------------------------------//
|
|
||||||
|
|
||||||
//------------------Loop Function------------------------//
|
|
||||||
void loop() {
|
|
||||||
dmd.clearScreen(true);
|
|
||||||
|
|
||||||
if (isScrolling) {
|
|
||||||
scrollText();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showImage) {
|
|
||||||
displayBinaryArray();
|
|
||||||
if (millis() - imageStartTime >= 5000) {
|
|
||||||
showImage = false;
|
|
||||||
isScrolling = true;
|
|
||||||
lastScrollTime = millis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(500);
|
|
||||||
}
|
|
||||||
//-------------------------------------------------------//
|
|
Loading…
x
Reference in New Issue
Block a user