Skip to content

Commit bdc991a

Browse files
authored
Merge pull request #18 from dorianim/feat/hub75-display
Feat: hub75 display
2 parents e582b04 + 1f885c0 commit bdc991a

File tree

12 files changed

+823
-117
lines changed

12 files changed

+823
-117
lines changed

display/.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"ostream": "cpp",
1111
"tuple": "cpp",
1212
"type_traits": "cpp",
13-
"utility": "cpp"
13+
"utility": "cpp",
14+
"ctime": "cpp"
1415
}
1516
}

display/include/advent_pro_regular.h

Lines changed: 377 additions & 0 deletions
Large diffs are not rendered by default.

display/include/display.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#pragma once
2+
3+
#include <Adafruit_NeoMatrix.h>
4+
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
5+
6+
#include "timer.h"
7+
8+
class Display {
9+
public:
10+
static Display *from(MatrixPanel_I2S_DMA *matrix);
11+
12+
virtual void setup() = 0;
13+
virtual void loop() = 0;
14+
15+
void printLoading(const char *text);
16+
void printWifiSetup(String id);
17+
void printError(int error);
18+
void printTimer(timer::ActiveSegment segment);
19+
20+
protected:
21+
Display();
22+
void _start();
23+
const char *_getErrorText();
24+
25+
enum DisplayState { Loading, WifiSetupNeeded, Error, Timer };
26+
27+
DisplayState _state;
28+
const char *_loadingText;
29+
String _wifiId;
30+
int _errorCode;
31+
timer::ActiveSegment _segment;
32+
33+
private:
34+
static void __loop(void *arg);
35+
};
36+
37+
class Hub75_Display : public Display {
38+
public:
39+
Hub75_Display(MatrixPanel_I2S_DMA *matrix);
40+
41+
virtual void setup() override;
42+
virtual void loop() override;
43+
44+
private:
45+
void _setTextColor(uint32_t c);
46+
void _setTextColor(uint8_t r, uint8_t g, uint8_t b);
47+
void _printBrandAnimationLetter(char letter, uint8_t &brightness,
48+
uint16_t &delay);
49+
50+
MatrixPanel_I2S_DMA *_matrix;
51+
52+
const char *brand_letters = "Itsblue.de";
53+
uint8_t brand_letter_brightnesses[10] = {0xff};
54+
uint16_t brand_letter_delays[10] = {0};
55+
const uint8_t DIM_STEP = 6;
56+
const uint8_t DIM_TO = 130;
57+
const uint8_t DIM_DELAY = 150;
58+
const uint8_t DIM_DELAY_ININTIAL_STEP = (((0xff - 100) / DIM_STEP) / 3);
59+
};

display/include/socket.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
#include <Arduino.h>
44

5+
#include "display.h"
56
#include "timer.h"
67

78
namespace socket {
89

910
void init(String timerId);
1011
void loop();
1112

12-
timer::TimerData timerData();
13+
bool connected();
1314
TIME offset();
1415
int error();
1516
} // namespace socket

display/include/timer.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ struct TimerSegment {
1111
unsigned long count_to;
1212
bool sound;
1313
uint32_t color;
14+
char label[32];
1415
};
1516

1617
enum class PreStartBehaviour { SHOW_ZERO, RUN_NORMALLY };
1718

1819
struct DisplayOptions {
1920
PreStartBehaviour pre_start_behaviour;
21+
bool clock;
2022
};
2123

2224
struct TimerData {
@@ -31,7 +33,10 @@ struct TimerData {
3133
struct ActiveSegment {
3234
long seconds;
3335
uint32_t color;
36+
const char *label;
37+
TIME currentTime;
3438
};
3539

36-
ActiveSegment calculateCurrentSegment(TimerData timerData, TIME timeOffset);
40+
TimerData *timerData();
41+
ActiveSegment calculateCurrentSegment(TIME timeOffset);
3742
}; // namespace timer

display/include/wifi.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
#include <Adafruit_NeoMatrix.h>
44

5+
#include "display.h"
6+
57
namespace wifi {
68

7-
bool init(Adafruit_NeoMatrix *matrix, bool reset);
9+
bool init(Display *display);
10+
void reset();
811
void loop();
912
bool connected();
1013
String timerId();
14+
float timezoneOffset();
1115
} // namespace wifi

display/platformio.ini

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,20 @@
88
; Please visit documentation for the other options and examples
99
; https://docs.platformio.org/page/projectconf.html
1010

11-
[env:nodemcuv2]
12-
platform = espressif8266
13-
board = nodemcuv2
11+
[env:esp32dev]
12+
platform = espressif32
13+
board = esp32dev
1414
framework = arduino
1515
monitor_speed = 115200
16-
monitor_filters = esp8266_exception_decoder
16+
monitor_filters = esp32_exception_decoder
1717
build_type = debug
18-
upload_port = 10.37.91.251/u
19-
extra_scripts = upload_script.py
20-
upload_protocol = custom
18+
#upload_port = 10.37.91.251/u
19+
#extra_scripts = upload_script.py
20+
#upload_protocol = custom
2121
lib_deps =
2222
bblanchon/ArduinoJson@^6.18.2
2323
adafruit/Adafruit GFX Library@^1.10.10
2424
adafruit/Adafruit NeoMatrix@^1.2.0
2525
links2004/WebSockets@^2.3.7
26-
https://github.com/tzapu/WiFiManager.git
26+
https://github.com/tzapu/WiFiManager.git
27+
mrfaptastic/ESP32 HUB75 LED MATRIX PANEL DMA Display@^3.0.8

display/src/display.cpp

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
#include "WiFi.h"
2+
3+
#include "display.h"
4+
#include "time.h"
5+
#include "wifi.h"
6+
7+
#include "advent_pro_regular.h"
8+
9+
Display::Display() : _state(Loading), _loadingText("starting up") {}
10+
11+
void Display::_start() {
12+
xTaskCreate(Display::__loop, "display", 10000, this, 10, NULL);
13+
}
14+
15+
const char *Display::_getErrorText() {
16+
switch (this->_errorCode) {
17+
case 404:
18+
return "Timer not found";
19+
default:
20+
return "";
21+
}
22+
}
23+
24+
void Display::__loop(void *arg) {
25+
Display *that = (Display *)arg;
26+
that->setup();
27+
28+
for (;;) {
29+
that->loop();
30+
}
31+
}
32+
33+
Display *Display::from(MatrixPanel_I2S_DMA *matrix) {
34+
return new Hub75_Display(matrix);
35+
}
36+
37+
void Display::printLoading(const char *text) {
38+
this->_loadingText = text;
39+
this->_state = Loading;
40+
}
41+
void Display::printWifiSetup(String id) {
42+
this->_wifiId = id;
43+
this->_state = WifiSetupNeeded;
44+
}
45+
void Display::printError(int error) {
46+
this->_errorCode = error;
47+
this->_state = Error;
48+
}
49+
void Display::printTimer(timer::ActiveSegment segment) {
50+
this->_segment = segment;
51+
this->_state = Timer;
52+
}
53+
54+
/*
55+
* Hub75_Display
56+
*/
57+
58+
Hub75_Display::Hub75_Display(MatrixPanel_I2S_DMA *matrix)
59+
: Display(), _matrix(matrix) {
60+
61+
_matrix->begin();
62+
_matrix->clearScreen();
63+
_matrix->flipDMABuffer();
64+
_matrix->setBrightness8(250);
65+
66+
for (int i = 0; i < 10; i++) {
67+
brand_letter_delays[i] = i * DIM_DELAY_ININTIAL_STEP;
68+
}
69+
70+
this->_start();
71+
}
72+
73+
void Hub75_Display::setup() {}
74+
75+
void Hub75_Display::loop() {
76+
_matrix->clearScreen();
77+
_matrix->setCursor(0, 0);
78+
79+
switch (this->_state) {
80+
case Loading: {
81+
_matrix->setFont(&AdventPro_Regular18pt7b);
82+
_matrix->setTextSize(1);
83+
_matrix->setCursor(4, 40);
84+
for (int i = 0; i < 10; i++) {
85+
_printBrandAnimationLetter(brand_letters[i], brand_letter_brightnesses[i],
86+
brand_letter_delays[i]);
87+
}
88+
89+
_matrix->setFont();
90+
_setTextColor(0xffffff);
91+
uint8_t textlen = strlen(_loadingText);
92+
_matrix->setCursor((128 - textlen * 6) / 2, 54);
93+
_matrix->print(_loadingText);
94+
break;
95+
}
96+
case WifiSetupNeeded:
97+
_setTextColor(0xaaaaaa);
98+
_matrix->setTextSize(1);
99+
_matrix->setCursor(0, 0);
100+
_matrix->println("Please setup:");
101+
_matrix->println("1. Connect to WiFi");
102+
_setTextColor(0x0000ff);
103+
_matrix->println(" display-" + this->_wifiId);
104+
_setTextColor(0xBB274B);
105+
_matrix->println("2. Setup");
106+
_setTextColor(0xaaaaaa);
107+
_matrix->println("3. enter Timer ID");
108+
_setTextColor(0xBB274B);
109+
_matrix->println("4. Go back");
110+
_matrix->println("5. Configure WiFi");
111+
break;
112+
case Error: {
113+
_setTextColor(0xffffff);
114+
_matrix->setCursor(49, 3);
115+
_matrix->print("ERROR");
116+
117+
_setTextColor(0xff0000);
118+
_matrix->setTextSize(4);
119+
_matrix->setCursor(28, 15);
120+
_matrix->print(this->_errorCode);
121+
122+
_matrix->setTextSize(1);
123+
_setTextColor(0xffffff);
124+
uint8_t textlen = strlen(_getErrorText());
125+
_matrix->setCursor((128 - textlen * 6) / 2, 47);
126+
_matrix->print(_getErrorText());
127+
128+
String ip = WiFi.localIP().toString();
129+
_matrix->setCursor((128 - ip.length() * 6) / 2, 56);
130+
_matrix->print(WiFi.localIP().toString());
131+
break;
132+
}
133+
case Timer: {
134+
_matrix->setFont();
135+
136+
_matrix->setTextSize(1);
137+
_setTextColor(0xff, 0xff, 0xff);
138+
uint8_t textlen = strlen(_segment.label);
139+
_matrix->setCursor((128 - textlen * 6) / 2, 3);
140+
_matrix->print(_segment.label);
141+
142+
_setTextColor(_segment.color);
143+
_matrix->setTextSize(5);
144+
_matrix->setTextWrap(false);
145+
_matrix->setCursor(1, 15);
146+
_matrix->printf("%02d", _segment.seconds / 60);
147+
148+
_matrix->setCursor(51, 15);
149+
_matrix->print(":");
150+
_matrix->setCursor(71, 15);
151+
_matrix->printf("%02d", _segment.seconds % 60);
152+
153+
if (timer::timerData()->display_options.clock) {
154+
time_t timer =
155+
(_segment.currentTime / 1000) + ((60 * 60) * wifi::timezoneOffset());
156+
tm *time = localtime(&timer);
157+
_matrix->setTextSize(1);
158+
_setTextColor(0xff, 0xff, 0xff);
159+
_matrix->setCursor(49, 54);
160+
161+
_matrix->printf("%02d:%02d", time->tm_hour, time->tm_min);
162+
}
163+
164+
break;
165+
}
166+
}
167+
168+
// if ((millis() / 1000) % 2)
169+
// _matrix->drawPixel(0, 0, _matrix->color333(0xff, 0xff, 0xff));
170+
171+
_matrix->flipDMABuffer();
172+
vTaskDelay(10);
173+
}
174+
175+
void Hub75_Display::_printBrandAnimationLetter(char letter, uint8_t &brightness,
176+
uint16_t &delay) {
177+
_setTextColor(0, 0, brightness);
178+
_matrix->print(letter);
179+
if (brightness > DIM_TO && delay == 0) {
180+
brightness -= DIM_STEP;
181+
} else if (brightness <= DIM_TO && delay == 0) {
182+
delay = DIM_DELAY;
183+
} else if (brightness < 0xff && delay == DIM_DELAY &&
184+
0xff - brightness > DIM_STEP) {
185+
brightness += DIM_STEP;
186+
} else if (brightness < 0xff && delay == DIM_DELAY) {
187+
brightness = 0xff;
188+
} else {
189+
delay--;
190+
}
191+
}
192+
193+
void Hub75_Display::_setTextColor(uint32_t c) {
194+
_setTextColor(c >> 16, c >> 8, c);
195+
}
196+
void Hub75_Display::_setTextColor(uint8_t r, uint8_t g, uint8_t b) {
197+
uint16_t packed =
198+
((uint16_t)(r & 0xF8) << 8) | ((uint16_t)(g & 0xFC) << 3) | (b >> 3);
199+
200+
_matrix->setTextColor(packed);
201+
}

0 commit comments

Comments
 (0)