Skip to content

Commit 0a96137

Browse files
committed
Updated to continually update the display
1 parent a99cdd4 commit 0a96137

File tree

2 files changed

+116
-51
lines changed

2 files changed

+116
-51
lines changed

src/lcd_tft.cpp

+97-44
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@ struct image_render_state {
6565

6666
LcdTask::LcdTask() :
6767
MicroTasks::Task(),
68-
_lcd()
68+
_tft(),
69+
#ifdef ENABLE_DOUBLE_BUFFER
70+
_back_buffer(&_tft),
71+
_screen(_back_buffer)
72+
#else
73+
_screen(_tft)
74+
#endif
6975
{
7076
}
7177

@@ -104,66 +110,106 @@ unsigned long LcdTask::loop(MicroTasks::WakeReason reason)
104110

105111
unsigned long nextUpdate = MicroTask.Infinate;
106112

113+
if(_initialise)
114+
{
115+
// We need to initialise after the Networking as that brackes the display
116+
DBUGVAR(ESP.getFreeHeap());
117+
_tft.init();
118+
_tft.setRotation(1);
119+
DBUGF("Screen initialised, size: %dx%d", _screen_width, _screen_height);
120+
121+
#ifdef ENABLE_DOUBLE_BUFFER
122+
_back_buffer_pixels = (uint16_t *)_back_buffer.createSprite(_screen_width, _screen_height);
123+
_back_buffer.setTextDatum(MC_DATUM);
124+
DBUGF("Back buffer %p", _back_buffer_pixels);
125+
#endif
126+
127+
_initialise = false;
128+
}
129+
130+
#ifdef ENABLE_DOUBLE_BUFFER
131+
_tft.startWrite();
132+
#endif
133+
107134
switch(_state)
108135
{
109136
case State::Boot:
110137
{
111138
DBUGLN("LCD UI setup");
112139

113-
_lcd.begin();
114-
_lcd.setRotation(1);
140+
if(_full_update)
141+
{
142+
_screen.fillScreen(TFT_OPENEVSE_BACK);
143+
_screen.fillSmoothRoundRect(90, 90, 300, 110, 15, TFT_WHITE);
144+
render_image("/logo.png", 104, 115);
145+
_full_update = false;
146+
}
115147

116-
_lcd.fillScreen(TFT_OPENEVSE_BACK);
117-
_lcd.fillSmoothRoundRect(90, 90, 300, 110, 15, TFT_WHITE);
118-
_lcd.fillSmoothRoundRect(90, 235, 300, 16, 8, TFT_OPENEVSE_GREEN);
119-
render_image("/logo.png", 104, 115);
148+
_screen.fillRoundRect(90, 235, 300, 16, 8, TFT_WHITE);
149+
if(_boot_progress > 0) {
150+
_screen.fillRoundRect(90, 235, _boot_progress, 16, 8, TFT_OPENEVSE_GREEN);
151+
}
152+
_boot_progress += 10;
120153

121154
pinMode(LCD_BACKLIGHT_PIN, OUTPUT);
122155
digitalWrite(LCD_BACKLIGHT_PIN, HIGH);
123-
nextUpdate = 5000;
124-
_state = State::Charge;
156+
nextUpdate = 166;
157+
if(_boot_progress >= 300) {
158+
_state = State::Charge;
159+
_full_update = true;
160+
}
125161
} break;
126162

127163
case State::Charge:
128164
{
129-
_lcd.fillRect(DISPLAY_AREA_X, DISPLAY_AREA_Y, DISPLAY_AREA_WIDTH, DISPLAY_AREA_HEIGHT, TFT_OPENEVSE_BACK);
130-
_lcd.fillSmoothRoundRect(WHITE_AREA_X, WHITE_AREA_Y, WHITE_AREA_WIDTH, WHITE_AREA_HEIGHT, 6, TFT_WHITE);
131-
render_image("/button_bar.png", BUTTON_BAR_X, BUTTON_BAR_Y);
132-
render_image("/not_connected.png", 16, 52);
165+
if(_full_update)
166+
{
167+
_screen.fillRect(DISPLAY_AREA_X, DISPLAY_AREA_Y, DISPLAY_AREA_WIDTH, DISPLAY_AREA_HEIGHT, TFT_OPENEVSE_BACK);
168+
_screen.fillSmoothRoundRect(WHITE_AREA_X, WHITE_AREA_Y, WHITE_AREA_WIDTH, WHITE_AREA_HEIGHT, 6, TFT_WHITE);
169+
render_image("/button_bar.png", BUTTON_BAR_X, BUTTON_BAR_Y);
170+
render_image("/not_connected.png", 16, 52);
171+
}
133172

134173
char buffer[32];
135174

136175
snprintf(buffer, sizeof(buffer), "%d", _evse->getChargeCurrent());
137-
render_right_text(buffer, 220, 200, &FreeSans24pt7b, TFT_BLACK, 3);
138-
_lcd.setTextSize(1);
139-
_lcd.print("A");
176+
render_right_text_box(buffer, 70, 220, 150, &FreeSans24pt7b, TFT_BLACK, TFT_WHITE, !_full_update, 3);
177+
if(_full_update) {
178+
render_left_text_box("A", 224, 200, 20, &FreeSans24pt7b, TFT_BLACK, TFT_WHITE, false, 1);
179+
}
140180

141-
render_centered_text(esp_hostname.c_str(), INFO_BOX_X, 72, INFO_BOX_WIDTH, &FreeSans9pt7b, TFT_OPENEVSE_TEXT);
181+
render_centered_text_box(esp_hostname.c_str(), INFO_BOX_X, 74, INFO_BOX_WIDTH, &FreeSans9pt7b, TFT_OPENEVSE_TEXT, TFT_WHITE, !_full_update);
142182

143183
timeval local_time;
144184
gettimeofday(&local_time, NULL);
145185
struct tm timeinfo;
146186
localtime_r(&local_time.tv_sec, &timeinfo);
147187
strftime(buffer, sizeof(buffer), "%d/%m/%Y, %l:%M %p", &timeinfo);
148-
render_centered_text(buffer, INFO_BOX_X, 94, INFO_BOX_WIDTH, &FreeSans9pt7b, TFT_OPENEVSE_TEXT);
188+
render_centered_text_box(buffer, INFO_BOX_X, 96, INFO_BOX_WIDTH, &FreeSans9pt7b, TFT_OPENEVSE_TEXT, TFT_WHITE, !_full_update);
149189

150190
uint32_t elapsed = _evse->getSessionElapsed();
151191
uint32_t hours = elapsed / 3600;
152192
uint32_t minutes = (elapsed % 3600) / 60;
153193
uint32_t seconds = elapsed % 60;
154194
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d", hours, minutes, seconds);
155-
render_info_box("ELAPSED", buffer, INFO_BOX_X, 110, INFO_BOX_WIDTH, INFO_BOX_HEIGHT);
195+
render_info_box("ELAPSED", buffer, INFO_BOX_X, 110, INFO_BOX_WIDTH, INFO_BOX_HEIGHT, _full_update);
156196

157197
get_scaled_number_value(_evse->getSessionEnergy(), 0, "Wh", buffer, sizeof(buffer));
158-
render_info_box("DELIVERED", buffer, INFO_BOX_X, 175, INFO_BOX_WIDTH, INFO_BOX_HEIGHT);
198+
render_info_box("DELIVERED", buffer, INFO_BOX_X, 175, INFO_BOX_WIDTH, INFO_BOX_HEIGHT, _full_update);
159199

160-
//nextUpdate = 1000;
200+
nextUpdate = 1000;
201+
_full_update = false;
161202
} break;
162203

163204
default:
164205
break;
165206
}
166207

208+
#ifdef ENABLE_DOUBLE_BUFFER
209+
_tft.pushImage(0, 0, _screen_width, _screen_height, _back_buffer_pixels);
210+
_tft.endWrite();
211+
#endif
212+
167213
DBUGVAR(nextUpdate);
168214
return nextUpdate;
169215
}
@@ -189,35 +235,42 @@ void LcdTask::get_scaled_number_value(double value, int precision, const char *u
189235
snprintf(buffer, size, "%.*f %s%s", precision, value, mod[index], unit);
190236
}
191237

192-
void LcdTask::render_info_box(const char *title, const char *text, int16_t x, int16_t y, int16_t width, int16_t height)
238+
void LcdTask::render_info_box(const char *title, const char *text, int16_t x, int16_t y, int16_t width, int16_t height, bool full_update)
193239
{
194-
_lcd.fillSmoothRoundRect(x, y, width, height, 6, TFT_OPENEVSE_INFO_BACK, TFT_WHITE);
195-
render_centered_text(title, x, y+22, width, &FreeSans9pt7b, TFT_OPENEVSE_GREEN);
196-
render_centered_text(text, x, y+(height-10), width, &FreeSans9pt7b, TFT_WHITE);
240+
if(full_update)
241+
{
242+
_screen.fillSmoothRoundRect(x, y, width, height, 6, TFT_OPENEVSE_INFO_BACK, TFT_WHITE);
243+
render_centered_text_box(title, x, y+24, width, &FreeSans9pt7b, TFT_OPENEVSE_GREEN, TFT_OPENEVSE_INFO_BACK, false);
244+
}
245+
render_centered_text_box(text, x, y+(height-4), width, &FreeSans9pt7b, TFT_WHITE, TFT_OPENEVSE_INFO_BACK, !full_update);
246+
}
247+
248+
void LcdTask::render_centered_text_box(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t text_colour, uint16_t back_colour, bool fill_back, uint8_t size)
249+
{
250+
render_text_box(text, x + (width / 2), y, width, font, text_colour, back_colour, fill_back, BC_DATUM, size);
197251
}
198252

199-
void LcdTask::render_centered_text(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t color, uint8_t size)
253+
void LcdTask::render_right_text_box(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t text_colour, uint16_t back_colour, bool fill_back, uint8_t size)
200254
{
201-
_lcd.setFreeFont(font);
202-
_lcd.setTextSize(size);
203-
int16_t text_width = _lcd.textWidth(text);
204-
int16_t text_x = x + ((width - text_width) / 2);
205-
_lcd.setTextColor(color);
206-
_lcd.setCursor(text_x, y);
207-
_lcd.print(text);
255+
render_text_box(text, x + width, y, width, font, text_colour, back_colour, fill_back, BR_DATUM, size);
208256
}
209257

210-
void LcdTask::render_right_text(const char *text, int16_t x, int16_t y, const GFXfont *font, uint16_t color, uint8_t size)
258+
void LcdTask::render_left_text_box(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t text_colour, uint16_t back_colour, bool fill_back, uint8_t size)
211259
{
212-
_lcd.setFreeFont(font);
213-
_lcd.setTextSize(size);
214-
int16_t text_width = _lcd.textWidth(text);
215-
int16_t text_x = x - text_width;
216-
_lcd.setTextColor(color);
217-
_lcd.setCursor(text_x, y);
218-
_lcd.print(text);
260+
render_text_box(text, x, y, width, font, text_colour, back_colour, fill_back, BL_DATUM, size);
219261
}
220262

263+
void LcdTask::render_text_box(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t text_colour, uint16_t back_colour, bool fill_back, uint8_t d, uint8_t size)
264+
{
265+
_screen.setTextDatum(d);
266+
_screen.setFreeFont(font);
267+
_screen.setTextSize(size);
268+
_screen.setTextPadding(width);
269+
_screen.setTextColor(text_colour, back_colour, /*back_colour*/TFT_BLUE);
270+
_screen.drawString(text, x, y);
271+
}
272+
273+
221274
void LcdTask::render_image(const char *filename, int16_t x, int16_t y)
222275
{
223276
StaticFile *file = NULL;
@@ -229,12 +282,12 @@ void LcdTask::render_image(const char *filename, int16_t x, int16_t y)
229282
{
230283
DBUGLN("Successfully opened png file");
231284
DBUGF("image specs: (%d x %d), %d bpp, pixel type: %d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
232-
_lcd.startWrite();
285+
_screen.startWrite();
233286
uint32_t dt = millis();
234-
image_render_state state = {&_lcd, x, y};
287+
image_render_state state = {&_screen, x, y};
235288
rc = png.decode(&state, 0);
236289
DBUG(millis() - dt); DBUGLN("ms");
237-
_lcd.endWrite();
290+
_screen.endWrite();
238291
// png.close(); // not needed for memory->memory decode
239292
}
240293
}

src/lcd_tft.h

+19-7
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,28 @@
1818
class LcdTask : public MicroTasks::Task
1919
{
2020
private:
21-
TFT_eSPI _lcd;
21+
TFT_eSPI _tft; // The TFT display
22+
23+
#ifdef ENABLE_DOUBLE_BUFFER
24+
TFT_eSprite _back_buffer; // The back buffer
25+
uint16_t *_back_buffer_pixels;
26+
#endif
27+
28+
TFT_eSPI &_screen; // What we are going to write to
2229

2330
// The TFT screen is portrate natively, so we need to rotate it
24-
const uint16_t _screenWidth = TFT_HEIGHT;
25-
const uint16_t _screenHeight = TFT_WIDTH;
31+
const uint16_t _screen_width = TFT_HEIGHT;
32+
const uint16_t _screen_height = TFT_WIDTH;
2633

2734
enum class State {
2835
Boot,
2936
Charge
3037
};
3138

3239
State _state = State::Boot;
40+
bool _full_update = true;
41+
bool _initialise = true;
42+
uint16_t _boot_progress = 0;
3343
EvseManager *_evse;
3444
Scheduler *_scheduler;
3545
ManualOverride *_manual;
@@ -40,9 +50,11 @@ class LcdTask : public MicroTasks::Task
4050
unsigned long loop(MicroTasks::WakeReason reason);
4151

4252
void render_image(const char *filename, int16_t x, int16_t y);
43-
void render_centered_text(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t color, uint8_t size = 1);
44-
void render_right_text(const char *text, int16_t x, int16_t y, const GFXfont *font, uint16_t color, uint8_t size = 1);
45-
void render_info_box(const char *title, const char *text, int16_t x, int16_t y, int16_t width, int16_t height);
53+
void render_text_box(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t text_colour, uint16_t back_colour, bool fill_back, uint8_t d, uint8_t size);
54+
void render_centered_text_box(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t text_colour, uint16_t back_colour, bool fill_back, uint8_t size = 1);
55+
void render_right_text_box(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t text_colour, uint16_t back_colour, bool fill_back, uint8_t size = 1);
56+
void render_left_text_box(const char *text, int16_t x, int16_t y, int16_t width, const GFXfont *font, uint16_t text_colour, uint16_t back_colour, bool fill_back, uint8_t size = 1);
57+
void render_info_box(const char *title, const char *text, int16_t x, int16_t y, int16_t width, int16_t height, bool full_update = true);
4658
void load_font(const char *filename);
4759

4860
void get_scaled_number_value(double value, int precision, const char *unit, char *buffer, size_t size);
@@ -57,7 +69,7 @@ class LcdTask : public MicroTasks::Task
5769
void display(const char *msg, int x, int y, int time, uint32_t flags);
5870

5971
void fill_screen(uint16_t color) {
60-
_lcd.fillScreen(color);
72+
_screen.fillScreen(color);
6173
}
6274
};
6375

0 commit comments

Comments
 (0)