FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
Protogen--opensource/main.cpp at Protogenboris-patch-2 · Protogenboris/Protogen--opensource · GitHub
Protogenboris
Protogen--opensource
Repository navigation
Code
Issues
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
Protogen--opensource
/
main.cpp
Copy path
More file actions
More file actions
Latest commit
History
History
History
305 lines (247 loc) · 11.1 KB
Breadcrumbs
Protogen--opensource
/
main.cpp
Copy path
File metadata and controls
305 lines (247 loc) · 11.1 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#
include
<
Arduino.h
>
#
include
<
ESP32-HUB75-MatrixPanel-I2S-DMA.h
>
#
include
<
U8g2lib.h
>
#
include
<
Adafruit_GFX.h
>
//
ESP-NOW and WiFi includes disabled for minimal build
//
#include <WiFi.h>
//
#include <QuickEspNow.h>
//
#include <esp_now.h>
//
#include <esp_wifi.h>
#
include
<
SPI.h
>
#
include
<
Adafruit_I2CDevice.h
>
#
include
"
faces.h
"
//
#include "boop.h" // Disabled - no sensors in minimal build
//
#include "speech.h" // Disabled - no sensors in minimal build
//
#include "espnowcom.h" // Disabled - no wireless control yet
#
include
"
scaling.h
"
#
include
"
oled_menu.h
"
//
#define ENABLE_BOOP
//
#define ENABLE_MIC
#
define
double_buffer
true
//
Define display pins
#
define
R1_PIN
42
#
define
G1_PIN
41
#
define
B1_PIN
40
#
define
R2_PIN
14
#
define
G2_PIN
12
#
define
B2_PIN
13
#
define
A_PIN
19
#
define
B_PIN
16
#
define
C_PIN
5
#
define
D_PIN
17
#
define
E_PIN
-
1
//
required for 1/32 scan panels, like 64x64. Any available pin would do, i.e. IO32
#
define
LAT_PIN
4
#
define
OE_PIN
15
#
define
CLK_PIN
18
//
Button pin for face switching
#
define
BUTTON_PIN
21
//
GPIO21 for face switching button
//
Define global variables here (main.cpp is the main file)
volatile
bool
faceUpdateRequested =
false
;
volatile
char
requestedCommand =
0
;
volatile
bool
displayUpdateNeeded =
true
;
const
uint16_t
* currentFaceBitmap =
nullptr
;
const
char
* currentFaceName =
"
Unknown
"
;
unsigned
long
currentMillis = millis();
//
Initialize MatrixPanel_I2S_DMA for LED panels
MatrixPanel_I2S_DMA *display =
nullptr
;
HUB75_I2S_CFG
mxconfig
(
64
,
//
Module width
32
,
//
Module height
2
//
Chain length
);
//
QuickEspNow espnow; // Disabled for minimal build
SemaphoreHandle_t displayMutex = xSemaphoreCreateMutex();
void
Task2code
(
void
* pvParameters);
//
ESP-NOW functions temporarily disabled
//
extern void processFaceUpdate();
hw_timer_t
* timer =
NULL
;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
//
/ Predefining up task variables for dual core operation
TaskHandle_t Task1;
TaskHandle_t Task2;
//
Function to draw a bitmap to the display with mirroring on the second panel
void
drawBitmap
(
const
uint16_t
* bitmap,
int16_t
x,
int16_t
y,
int16_t
width,
int16_t
height) {
if
(bitmap ==
nullptr
) {
ESP_LOGE
(
"
DRAW
"
,
"
Bitmap is null
"
);
return
;
}
//
Draw on the first panel (left side, 0-63)
for
(
int16_t
j =
0
; j < height; j++) {
for
(
int16_t
i =
0
; i < width && i <
64
; i++) {
uint16_t
color =
pgm_read_word
(&bitmap[j * width + i]);
//
Enhance brightness by boosting RGB components
uint8_t
r = ((color >>
11
) &
0x1F
) <<
3
;
//
Extract and scale red (5 bits)
uint8_t
g = ((color >>
5
) &
0x3F
) <<
2
;
//
Extract and scale green (6 bits)
uint8_t
b = (color &
0x1F
) <<
3
;
//
Extract and scale blue (5 bits)
//
Boost brightness by 30%
r =
min
(
255
, (
int
)(r *
1
));
g =
min
(
255
, (
int
)(g *
1
));
b =
min
(
255
, (
int
)(b *
80
));
//
Convert back to 565 format
uint16_t
enhancedColor = ((r >>
3
) <<
11
) | ((g >>
2
) <<
5
) | (b >>
3
);
display->
drawPixel
(x + i, y + j, enhancedColor);
}
}
//
Draw mirrored on the second panel (right side, 64-127)
for
(
int16_t
j =
0
; j < height; j++) {
for
(
int16_t
i =
0
; i < width && i <
64
; i++) {
uint16_t
color =
pgm_read_word
(&bitmap[j * width + i]);
//
Enhance brightness by boosting RGB components
uint8_t
r = ((color >>
11
) &
0x1F
) <<
3
;
//
Extract and scale red (5 bits)
uint8_t
g = ((color >>
5
) &
0x3F
) <<
2
;
//
Extract and scale green (6 bits)
uint8_t
b = (color &
0x1F
) <<
3
;
//
Extract and scale blue (5 bits)
//
Boost brightness by 30%
r =
min
(
255
, (
int
)(r *
1
));
g =
min
(
255
, (
int
)(g *
1
));
b =
min
(
255
, (
int
)(b *
80
));
//
Convert back to 565 format
uint16_t
enhancedColor = ((r >>
3
) <<
11
) | ((g >>
2
) <<
5
) | (b >>
3
);
//
Mirror horizontally by drawing at (127-i) instead of (64+i)
display->
drawPixel
(
127
- i, y + j, enhancedColor);
}
}
}
void
setup
() {
Serial.
begin
(
115200
);
while
(!Serial &&
millis
() <
3000
);
//
Wait for serial to be ready
ESP_LOGI
(
"
SETUP
"
,
"
Starting setup with free heap: %d
"
,
ESP
.
getFreeHeap
());
ESP_LOGI
(
"
SETUP
"
,
"
Initializing display...
"
);
//
Configure pins explicitly
mxconfig.
gpio
.
r1
=
R1_PIN
;
mxconfig.
gpio
.
g1
=
G1_PIN
;
mxconfig.
gpio
.
b1
=
B1_PIN
;
mxconfig.
gpio
.
r2
=
R2_PIN
;
mxconfig.
gpio
.
g2
=
G2_PIN
;
mxconfig.
gpio
.
b2
=
B2_PIN
;
mxconfig.
gpio
.
a
=
A_PIN
;
mxconfig.
gpio
.
b
=
B_PIN
;
mxconfig.
gpio
.
c
=
C_PIN
;
mxconfig.
gpio
.
d
=
D_PIN
;
mxconfig.
gpio
.
e
=
E_PIN
;
mxconfig.
gpio
.
lat
=
LAT_PIN
;
mxconfig.
gpio
.
oe
=
OE_PIN
;
mxconfig.
gpio
.
clk
=
CLK_PIN
;
//
Set double buffering
mxconfig.
double_buff
= double_buffer;
mxconfig.
i2sspeed
=
HUB75_I2S_CFG
::
HZ_20M
;
//
Fastest clock
mxconfig.
min_refresh_rate
=
200
;
//
Minimum refresh rate for maximum brightness
//
mxconfig.latch_blanking = 1; // Minimal blanking
mxconfig.
clkphase
=
true
;
//
Try false for ICN2037BP
//
Initialize the display
display =
new
MatrixPanel_I2S_DMA
(mxconfig);
if
(display ==
nullptr
) {
ESP_LOGE
(
"
SETUP
"
,
"
Error: Failed to allocate display memory
"
);
while
(
1
) {
delay
(
100
); }
//
Halt execution
}
ESP_LOGI
(
"
SETUP
"
,
"
Display allocated, beginning initialization...
"
);
if
(
not
display->
begin
()) {
ESP_LOGE
(
"
SETUP
"
,
"
Error: Panel failed to initialize
"
);
delete
display;
display =
nullptr
;
while
(
1
) {
delay
(
100
); }
//
Halt execution
}
ESP_LOGI
(
"
SETUP
"
,
"
Display initialized successfully with free heap: %d
"
,
ESP
.
getFreeHeap
());
display->
setBrightness8
(
255
);
display->
fillScreen
(display->
color565
(
0
,
0
,
0
));
//
Initialize button for face switching
pinMode
(
BUTTON_PIN
,
INPUT_PULLUP
);
//
Use internal pullup resistor
//
Initialize the first face
initFaces
();
setFace
(
0
);
//
Start with the first face
currentFaceBitmap =
getCurrentFace
();
currentFaceName =
getcurrentFaceName
();
Serial.
printf
(
"
Protogen ready! Press button on GPIO%d to cycle faces.
\n
"
,
BUTTON_PIN
);
Serial.
printf
(
"
Starting with: %s
\n
"
, currentFaceName);
//
This sets up dual core processing
xTaskCreatePinnedToCore
(
Task2code,
//
Task function.
"
Task2
"
,
//
name of task.
10000
,
//
Stack size of task
NULL
,
//
parameter of the task
10
,
//
priority of the task
&Task2,
//
Task handle to keep track of created task
0
//
pin task to core 0
);
//
Initialize custom modules - minimal build
//
initBoop(); // Disabled - no sensors needed for now
//
initSpeech(); // Disabled - no sensors needed for now
initOLED
();
//
Keep OLED for status display
//
initESPNow(); // Disabled - ProtoPaw controller not needed yet
}
void
loop
() {
//
Minimal build - display management and button control
//
Handle button press for face switching
static
bool
lastButtonState =
HIGH
;
static
unsigned
long
lastDebounceTime =
0
;
static
int
currentFaceIndex =
1
;
//
Start with Calm_face (index 1)
const
unsigned
long
debounceDelay =
50
;
//
50ms debounce
bool
buttonReading =
digitalRead
(
BUTTON_PIN
);
//
Check if button state changed (with debounce)
if
(buttonReading != lastButtonState) {
lastDebounceTime =
millis
();
}
if
((
millis
() - lastDebounceTime) > debounceDelay) {
//
Button state has been stable for debounce period
if
(buttonReading ==
LOW
&& lastButtonState ==
HIGH
) {
//
Button was just pressed (HIGH to LOW transition)
currentFaceIndex = (currentFaceIndex +
1
) %
7
;
//
Cycle through 7 faces
setFace
(currentFaceIndex);
currentFaceBitmap =
getCurrentFace
();
currentFaceName =
getcurrentFaceName
();
displayUpdateNeeded =
true
;
//
Trigger display refresh
Serial.
printf
(
"
Button pressed! Face changed to: %s (index %d)
\n
"
, currentFaceName, currentFaceIndex);
}
}
lastButtonState = buttonReading;
//
Update OLED info panel with current face status
updateOLED
(currentFaceBitmap, currentFaceName);
//
ESP-NOW face updates temporarily disabled for testing
//
Check and process face update
//
if (faceUpdateRequested) {
//
faceUpdateRequested = false; // Reset the flag
//
processFaceUpdate();
//
displayUpdateNeeded = true; // Trigger display refresh
//
}
//
Face changes are now controlled by ESP-NOW commands only
//
Removed auto-cycling to prevent conflicts with ProtoPaw controller
delay
(
10
);
//
Small delay to prevent watchdog issues
}
//
Note: displayUpdateNeeded is already declared as global variable above
static
const
uint16_t
* lastDrawnFace =
nullptr
;
void
Task2code
(
void
* pvParameters) {
ESP_LOGI
(
"
TASK2
"
,
"
Display rendering task started
"
);
//
Wait a bit for the display to be fully initialized
vTaskDelay
(
1000
/ portTICK_PERIOD_MS);
for
(;;) {
//
Only redraw if face changed or update requested
if
(displayUpdateNeeded || currentFaceBitmap != lastDrawnFace) {
//
Check if display is valid
if
(display ==
nullptr
) {
ESP_LOGE
(
"
TASK2
"
,
"
Error: display is null
"
);
vTaskDelay
(
1000
/ portTICK_PERIOD_MS);
continue
;
}
//
Synchronize access to display
if
(
xSemaphoreTake
(displayMutex,
pdMS_TO_TICKS
(
100
))) {
//
Clear the display
display->
fillScreen
(display->
color565
(
0
,
0
,
0
));
//
Draw the current face bitmap if available
if
(currentFaceBitmap !=
nullptr
) {
drawBitmap
(currentFaceBitmap,
0
,
0
,
64
,
32
);
lastDrawnFace = currentFaceBitmap;
ESP_LOGI
(
"
TASK2
"
,
"
Face updated: %s
"
, currentFaceName);
}
//
Only flip if double buffering is enabled
#
if
defined(double_buffer) && double_buffer == true
display->
flipDMABuffer
();
#
endif
displayUpdateNeeded =
false
;
xSemaphoreGive
(displayMutex);
}
else
{
ESP_LOGW
(
"
TASK2
"
,
"
Failed to acquire display mutex
"
);
}
}
//
Reduced frequency - only check every 50ms instead of 25ms
vTaskDelay
(
50
/ portTICK_PERIOD_MS);
}
}
Back
|
FazBrowse Home
|
New Git URL