Skip to content

Commit 73b8b2d

Browse files
authored
Merge pull request #5 from amrikarisma/bugfix/layout-display
Bugfix/layout display
2 parents 3e0f385 + 3f2ca3d commit 73b8b2d

12 files changed

Lines changed: 447 additions & 67 deletions

CHANGELOG.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,48 @@
104104

105105
---
106106

107+
## [1.2.1] - 2025-07-12
108+
109+
### 🚀 Performance Optimizations
110+
- **Improved FPS**: Optimized display refresh rates from 15-25fps to 30-40fps target
111+
- **Reduced Serial Communication**: Increased serial update interval from 10ms to 20ms
112+
- **Smart Display Updates**: Added time-based update throttling for display components
113+
- **Efficient Memory Usage**: Optimized sprite operations and memory allocations
114+
115+
### 🔧 WiFi & WebServer Improvements
116+
- **Fixed WiFi Timeout**: Corrected WiFi shutdown logic after 1 minute of inactivity
117+
- **Power Management**: Proper WiFi and Bluetooth shutdown for power saving
118+
- **Manual WiFi Restart**: Added 'w' command to restart WiFi/WebServer via serial
119+
- **Reduced Debug Overhead**: Optimized debug print frequencies to reduce serial load
120+
121+
### 🖥️ Display Performance
122+
- **Throttled Updates**:
123+
- RPM display updates: every 100ms max
124+
- Panel updates: every 50ms max
125+
- Indicator updates: every 100ms max
126+
- RPM bar updates: every 75ms max
127+
- **Selective Redraws**: Only update display elements when values actually change
128+
- **Optimized Debug Display**: Reduced debug info update frequency to 1000ms
129+
130+
### 🎨 Splash Screen Improvements
131+
- **Eliminated Slide Animations**: Replaced risky slide animations with safe fade effects
132+
- **Fade-In Title**: Smooth fade-in animation for main title
133+
- **Fade-In Website**: Cyan fade-in effect for website text
134+
- **No Ghosting**: Completely eliminated text ghosting issues
135+
136+
### 🛠️ System Optimizations
137+
- **Reduced CPU Load**: Optimized main loop with yield() calls and reduced polling
138+
- **Better Multitasking**: Improved ESP32 task scheduling with strategic delays
139+
- **Enhanced Debug Info**: Added WiFi status and connection info to debug output
140+
- **Memory Efficiency**: Maintained stable memory usage at 15.9% RAM, 87.5% Flash
141+
142+
### 📋 New Serial Commands
143+
- **'w' Command**: Restart WiFi and WebServer manually
144+
- **Enhanced Help**: Updated help system with all available commands
145+
- **Improved Debug**: Better debug information display
146+
147+
---
148+
107149
### 💡 Highlights
108150
This version represents a major leap forward in functionality and user experience. The modular architecture makes the code more maintainable, while the web-based configuration system gives users unprecedented control over their display layout.
109151

src/CANHandler.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
#include "CANHandler.h"
2+
#include "DisplayConfig.h"
23
#include "Config.h"
34
#include "DataTypes.h"
45
#include <esp32_can.h>
56
#include "Arduino.h"
67

78
void setupCAN() {
89
CAN0.setCANPins(GPIO_NUM_17, GPIO_NUM_16); // RX, TX
9-
CAN0.begin(500000); // 500Kbps
10+
CAN0.begin(getCanSpeed()); // Use configurable CAN speed
1011
CAN0.watchFor(0x360); // RPM, MAP, TPS
1112
CAN0.watchFor(0x361); // Fuel Pressure
1213
CAN0.watchFor(0x362); // Ignition Angle (Leading)
@@ -18,7 +19,7 @@ void setupCAN() {
1819
CAN0.watchFor(0x3E4); // Indicator
1920

2021
isCANMode = true; // Set communication mode indicator
21-
Serial.println("CAN mode aktif.");
22+
Serial.printf("CAN mode aktif. Speed: %u bps\n", getCanSpeed());
2223
}
2324

2425
void canTask(void *pvParameters) {

src/DisplayConfig.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ DisplayConfiguration defaultDisplayConfig = {
3131
8, // activePanelCount
3232
8, // activeIndicatorCount
3333
0, // rpmDisplayMode (bar)
34-
true // showSystemIndicators
34+
true, // showSystemIndicators
35+
500000 // canSpeed default 500Kbps
3536
};
3637

3738
DisplayConfiguration currentDisplayConfig;
@@ -167,3 +168,17 @@ uint16_t getDataSourceColor(uint8_t dataSource, float value) {
167168
return TFT_WHITE;
168169
}
169170
}
171+
172+
uint32_t getCanSpeed() {
173+
if (currentDisplayConfig.canSpeed == 500000 || currentDisplayConfig.canSpeed == 1000000) {
174+
return currentDisplayConfig.canSpeed;
175+
} else {
176+
// Jika belum pernah di-set atau nilai tidak valid, pakai default 500000
177+
return 500000;
178+
}
179+
}
180+
181+
void setCanSpeed(uint32_t speed) {
182+
currentDisplayConfig.canSpeed = speed;
183+
saveDisplayConfig();
184+
}

src/DisplayConfig.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ struct DisplayConfiguration {
6868
uint8_t activeIndicatorCount; // Number of active indicators
6969
uint8_t rpmDisplayMode; // RPM display mode (0=bar, 1=digital)
7070
bool showSystemIndicators; // Show CAN/SER, DEBUG, SIM
71+
uint32_t canSpeed; // CAN speed in bps (e.g. 500000, 1000000)
7172
};
7273

7374
// Default configuration
@@ -84,5 +85,8 @@ bool getIndicatorValue(uint8_t indicator);
8485
const char* getDataSourceName(uint8_t dataSource);
8586
const char* getIndicatorName(uint8_t indicator);
8687
uint16_t getDataSourceColor(uint8_t dataSource, float value);
88+
// New CAN speed accessors
89+
uint32_t getCanSpeed();
90+
void setCanSpeed(uint32_t speed);
8791

8892
#endif // DISPLAY_CONFIG_H

src/DisplayManager.cpp

Lines changed: 59 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "DataTypes.h"
44
#include "DisplayConfig.h"
55
#include "drawing_utils.h"
6+
#include "SplashScreen.h"
67
#include "NotoSansBold15.h"
78
#include "NotoSansBold36.h"
89
#include <EEPROM.h>
@@ -21,20 +22,8 @@ void setupDisplay() {
2122
}
2223

2324
void drawSplashScreenWithImage() {
24-
display.fillScreen(TFT_BLACK);
25-
display.loadFont(AA_FONT_LARGE);
26-
display.setTextColor(TFT_WHITE, TFT_BLACK);
27-
28-
display.setTextDatum(TC_DATUM);
29-
int centerX = display.width() / 2;
30-
int centerY = (display.height() / 2) - 35;
31-
32-
display.drawString("MAZDUINO Display", centerX, centerY);
33-
display.loadFont(AA_FONT_SMALL);
34-
display.drawString("Firmware version: " + String(version), centerX, centerY + 50);
35-
display.drawString("www.mazduino.com", centerX, 300);
36-
37-
delay(5000);
25+
// Use the new modular animated splash screen
26+
showAnimatedSplashScreen();
3827
}
3928

4029
void drawConfigurablePanels(bool setup) {
@@ -43,14 +32,14 @@ void drawConfigurablePanels(bool setup) {
4332
// RPM bar occupies roughly Y=40 to Y=150, so panels moved to avoid collision
4433
// Each panel is 80px tall, fitting 2 main panels per column + 1 bottom panel each
4534
int panelPositions[8][2] = {
46-
{5, 10}, // Position 0: Left-Top (AFR) - Y=160 to Y=240
47-
{5, 100}, // Position 1: Left-Middle (TPS) - Y=245 to Y=325
48-
{5, 190}, // Position 2: Left-Bottom (IAT) - Y=280 to Y=360, will be clipped but user requested
49-
{365, 10}, // Position 3: Right-Top (MAP) - Y=160 to Y=240
50-
{365, 100}, // Position 4: Right-Middle (ADV) - Y=245 to Y=325
51-
{365, 190}, // Position 5: Right-Bottom (FP) - Y=280 to Y=360, will be clipped but user requested
52-
{120, 190}, // Position 6: Center-Left (Coolant) - moved to center to avoid overlap
53-
{240, 190} // Position 7: Center-Right (Voltage) - moved to center to avoid overlap
35+
{5, 20}, // Position 0: Left-Top (AFR) - Y=160 to Y=240
36+
{5, 110}, // Position 1: Left-Middle (TPS) - Y=245 to Y=325
37+
{5, 200}, // Position 2: Left-Bottom (IAT) - Y=280 to Y=360, will be clipped but user requested
38+
{365, 20}, // Position 3: Right-Top (MAP) - Y=160 to Y=240
39+
{365, 110}, // Position 4: Right-Middle (ADV) - Y=245 to Y=325
40+
{365, 200}, // Position 5: Right-Bottom (FP) - Y=280 to Y=360, will be clipped but user requested
41+
{120, 200}, // Position 6: Center-Left (Coolant) - moved to center to avoid overlap
42+
{240, 200} // Position 7: Center-Right (Voltage) - moved to center to avoid overlap
5443
};
5544

5645
// Draw each enabled panel
@@ -67,14 +56,14 @@ void drawModularDataPanel(const DisplayPanel &panel, bool setup) {
6756
// RPM bar occupies roughly Y=40 to Y=150, so panels moved to avoid collision
6857
// Each panel is 80px tall, fitting 2 main panels per column + 1 bottom panel each
6958
int panelPositions[8][2] = {
70-
{5, 10}, // Position 0: Left-Top (AFR) - Y=160 to Y=240
71-
{5, 100}, // Position 1: Left-Middle (TPS) - Y=245 to Y=325
72-
{5, 190}, // Position 2: Left-Bottom (IAT) - Y=280 to Y=360, will be clipped but user requested
73-
{365, 10}, // Position 3: Right-Top (MAP) - Y=160 to Y=240
74-
{365, 100}, // Position 4: Right-Middle (ADV) - Y=245 to Y=325
75-
{365, 190}, // Position 5: Right-Bottom (FP) - Y=280 to Y=360, will be clipped but user requested
76-
{120, 190}, // Position 6: Center-Left (Coolant) - moved to center to avoid overlap
77-
{240, 190} // Position 7: Center-Right (Voltage) - moved to center to avoid overlap
59+
{5, 20}, // Position 0: Left-Top (AFR) - Y=160 to Y=240
60+
{5, 110}, // Position 1: Left-Middle (TPS) - Y=245 to Y=325
61+
{5, 200}, // Position 2: Left-Bottom (IAT) - Y=280 to Y=360, will be clipped but user requested
62+
{365, 20}, // Position 3: Right-Top (MAP) - Y=160 to Y=240
63+
{365, 110}, // Position 4: Right-Middle (ADV) - Y=245 to Y=325
64+
{365, 200}, // Position 5: Right-Bottom (FP) - Y=280 to Y=360, will be clipped but user requested
65+
{120, 200}, // Position 6: Center-Left (Coolant) - moved to center to avoid overlap
66+
{240, 200} // Position 7: Center-Right (Voltage) - moved to center to avoid overlap
7867
};
7968

8069
if (panel.position >= 8) return;
@@ -106,19 +95,24 @@ void drawConfigurableIndicators() {
10695
int indicatorY = 285; // Positioned in the middle area
10796
int indicatorWidth = 60; // Made slightly smaller to fit better
10897

98+
// Pack enabled indicators without gaps
99+
int currentPosition = 0;
109100
for (int i = 0; i < currentDisplayConfig.activeIndicatorCount; i++) {
110101
IndicatorConfig &indicator = currentDisplayConfig.indicators[i];
111102
if (indicator.enabled && indicator.position < 8) {
112103
bool state = getIndicatorValue(indicator.indicator);
113-
drawSmallButton(indicatorX + (indicatorWidth * indicator.position), indicatorY, indicator.label, state);
104+
// Use currentPosition instead of indicator.position to pack without gaps
105+
drawSmallButton(indicatorX + (indicatorWidth * currentPosition), indicatorY, indicator.label, state);
106+
currentPosition++; // Increment position for next enabled indicator
114107
}
115108
}
116109
}
117110

118111
// New function to replace itemDraw with configurable panels
119112
void drawConfigurableData(bool setup) {
120-
// Draw RPM (always shown)
121-
if (lastRpm != rpm || setup) {
113+
// Draw RPM with reduced frequency update (only when changed or setup)
114+
static uint32_t lastRpmUpdate = 0;
115+
if (lastRpm != rpm || setup || (millis() - lastRpmUpdate > 100)) {
122116
drawRPMBarBlocks(rpm);
123117
spr.loadFont(AA_FONT_LARGE);
124118
spr.createSprite(100, 50);
@@ -129,13 +123,22 @@ void drawConfigurableData(bool setup) {
129123
spr.pushSprite(190, 140);
130124
spr.deleteSprite();
131125
lastRpm = rpm;
126+
lastRpmUpdate = millis();
132127
}
133128

134-
// Draw configurable panels
135-
drawConfigurablePanels(setup);
129+
// Draw configurable panels with reduced frequency
130+
static uint32_t lastPanelUpdate = 0;
131+
if (setup || (millis() - lastPanelUpdate > 50)) { // Update panels every 50ms max
132+
drawConfigurablePanels(setup);
133+
lastPanelUpdate = millis();
134+
}
136135

137-
// Draw configurable indicators
138-
drawConfigurableIndicators();
136+
// Draw configurable indicators with reduced frequency
137+
static uint32_t lastIndicatorUpdate = 0;
138+
if (setup || (millis() - lastIndicatorUpdate > 100)) { // Update indicators every 100ms max
139+
drawConfigurableIndicators();
140+
lastIndicatorUpdate = millis();
141+
}
139142
}
140143

141144
void startUpDisplay() {
@@ -167,21 +170,27 @@ void drawDataBox(int x, int y, const char *label, const float value, uint16_t la
167170
const int LABEL_HEIGHT = BOX_HEIGHT / 2;
168171

169172
if (setup) {
173+
// Clear the entire data box area first only during setup
174+
display.fillRect(x, y, BOX_WIDTH, BOX_HEIGHT, TFT_BLACK);
175+
170176
spr.loadFont(AA_FONT_SMALL);
171177
spr.createSprite(BOX_WIDTH, LABEL_HEIGHT);
178+
spr.fillSprite(TFT_BLACK); // Clear sprite background
172179
spr.setTextColor(labelColor, TFT_BLACK, true);
173-
spr.drawString(label, 50, 5);
174180
spr.setTextDatum(TC_DATUM);
181+
spr.drawString(label, 50, 5);
175182
if (label == "AFR") {
176183
spr.pushSprite(x - 10, y);
177184
} else {
178185
spr.pushSprite(x, y);
179186
}
187+
spr.deleteSprite();
180188
}
181189

182-
if (valueToCompare != value) {
190+
if (setup || valueToCompare != value) {
183191
spr.loadFont(AA_FONT_LARGE);
184192
spr.createSprite(BOX_WIDTH, LABEL_HEIGHT);
193+
spr.fillSprite(TFT_BLACK); // Clear sprite background
185194
spr.setTextDatum(TC_DATUM);
186195
spr_width = spr.textWidth("333");
187196
spr.setTextColor(labelColor, TFT_BLACK, true);
@@ -196,16 +205,17 @@ void drawDataBox(int x, int y, const char *label, const float value, uint16_t la
196205
}
197206

198207
void drawData() {
199-
// Use configurable display system
208+
// Use configurable display system with performance optimizations
200209
drawConfigurableData(false);
201210

202211
#if ENABLE_SIMULATOR
203-
// Draw simulator indicator if simulator is active
212+
// Draw simulator indicator if simulator is active (with reduced update frequency)
204213
static uint8_t lastSimMode = SIMULATOR_MODE_OFF;
214+
static uint32_t lastSimUpdate = 0;
205215
uint8_t currentSimMode = getSimulatorMode();
206216

207-
// Only redraw if simulator mode has changed
208-
if (currentSimMode != lastSimMode) {
217+
// Only redraw if simulator mode has changed or every 500ms
218+
if (currentSimMode != lastSimMode || (millis() - lastSimUpdate > 500)) {
209219
if (currentSimMode != SIMULATOR_MODE_OFF) {
210220
// Clear the SIM area first
211221
display.fillRect(display.width() - 30, 5, 25, 15, TFT_BLACK);
@@ -221,17 +231,19 @@ void drawData() {
221231
}
222232

223233
lastSimMode = currentSimMode;
234+
lastSimUpdate = millis();
224235
}
225236
#endif
226237

227-
// Draw communication mode indicator (top left)
238+
// Draw communication mode indicator (top left) with reduced update frequency
228239
static bool lastCommMode = true; // Track changes
229240
static String lastCommText = "";
241+
static uint32_t lastCommUpdate = 0;
230242

231243
String currentCommText = isCANMode ? "CAN" : "SER";
232244

233-
// Only redraw if communication mode has changed
234-
if (isCANMode != lastCommMode || currentCommText != lastCommText) {
245+
// Only redraw if communication mode has changed or every 1000ms
246+
if (isCANMode != lastCommMode || currentCommText != lastCommText || (millis() - lastCommUpdate > 1000)) {
235247
// Clear the comm mode area first
236248
display.fillRect(5, 5, 40, 15, TFT_BLACK);
237249

@@ -243,18 +255,17 @@ void drawData() {
243255

244256
lastCommMode = isCANMode;
245257
lastCommText = currentCommText;
258+
lastCommUpdate = millis();
246259
}
247260

248261
#if ENABLE_DEBUG_MODE
249-
// Draw debug information at center top if debug mode is active
250262
static bool lastDebugMode = false;
251263
static String lastDebugInfo = "";
252264

253265
if (debugMode) {
254266
// Create debug info string - show only essential info in one line
255267
String debugInfo = "CPU:" + String(cpuUsage, 1) + "% FPS:" + String(fps, 1) + " Heap:" + String(ESP.getFreeHeap()/1024) + "K";
256268

257-
// Only redraw if debug info has changed or we just entered debug mode
258269
if (debugInfo != lastDebugInfo || !lastDebugMode) {
259270
int centerX = display.width() / 2;
260271

src/GlobalVariables.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "Config.h"
33

44
// Configuration variables from Config.h
5-
const char *version = "1.2.0";
5+
const char *version = "1.2.1";
66
const char *ssid = "MAZDUINO_Display";
77
const char *password = "12345678";
88

0 commit comments

Comments
 (0)