Implement snapshot

This commit is contained in:
fvanroie 2020-02-02 13:24:27 +01:00
parent cce876cb11
commit fe2c50a5cb
5 changed files with 101 additions and 20 deletions

View File

@ -164,6 +164,15 @@ typedef void * lv_group_user_data_t;
#if LV_USE_FILESYSTEM #if LV_USE_FILESYSTEM
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ /*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
typedef void * lv_fs_drv_user_data_t; typedef void * lv_fs_drv_user_data_t;
/*File system interface*/
#define LV_USE_FS_IF 1
#if LV_USE_FS_IF
# define LV_FS_IF_FATFS '\0'
# define LV_FS_IF_PC '\0'
# define LV_FS_IF_SPIFFS 'F'
#endif /*LV_USE_FS_IF*/
#endif #endif
/*1: Add a `user_data` to drivers and objects*/ /*1: Add a `user_data` to drivers and objects*/
@ -329,7 +338,7 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i
* #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \
* LV_FONT_DECLARE(my_font_2) * LV_FONT_DECLARE(my_font_2)
*/ */
#define LV_FONT_CUSTOM_DECLARE static lv_font_t *my_font; #define LV_FONT_CUSTOM_DECLARE static lv_font_t *my_font[5];
/*Always set a default font from the built-in fonts*/ /*Always set a default font from the built-in fonts*/
#define LV_FONT_DEFAULT &lv_font_unscii_8 #define LV_FONT_DEFAULT &lv_font_unscii_8

View File

@ -57,6 +57,11 @@ void dispatchCommand(String cmnd)
return; return;
} }
if(cmnd == F("screenshot")) {
guiTakeScreenshot("/screenhot.bmp");
return;
}
if(cmnd == F("reboot") || cmnd == F("restart")) { if(cmnd == F("reboot") || cmnd == F("restart")) {
haspReboot(true); haspReboot(true);
return; return;

View File

@ -18,6 +18,13 @@
#include "hasp_gui.h" #include "hasp_gui.h"
#include "hasp.h" #include "hasp.h"
#if LV_USE_HASP_SPIFFS
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
#include <FS.h> // Include the SPIFFS library
#endif
#define LVGL_TICK_PERIOD 30 // 30 #define LVGL_TICK_PERIOD 30 // 30
uint16_t guiSleepTime = 150; // 0.1 second resolution uint16_t guiSleepTime = 150; // 0.1 second resolution
@ -28,12 +35,19 @@ TFT_eSPI tft = TFT_eSPI(); /* TFT instance */
uint16_t calData[5] = {0, 65535, 0, 65535, 0}; uint16_t calData[5] = {0, 65535, 0, 65535, 0};
bool guiAutoCalibrate = true; bool guiAutoCalibrate = true;
static File pFileOut;
static bool bSnapshot;
static uint32_t DISP_IMPL_lvgl_formatPixel(lv_color_t color);
bool IRAM_ATTR guiCheckSleep() bool IRAM_ATTR guiCheckSleep()
{ {
bool shouldSleep = lv_disp_get_inactive_time(NULL) > guiSleepTime * 100; bool shouldSleep = lv_disp_get_inactive_time(NULL) > guiSleepTime * 100;
if(shouldSleep && !guiSleeping) { if(shouldSleep && !guiSleeping) {
dispatchIdle(F("LONG")); dispatchIdle(F("LONG"));
guiSleeping = true; guiSleeping = true;
} else if(!shouldSleep && guiSleeping) {
dispatchIdle(F("OFF"));
guiSleeping = false;
} }
return shouldSleep; return shouldSleep;
} }
@ -53,17 +67,40 @@ void tft_espi_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * c
{ {
uint16_t c; uint16_t c;
tft.startWrite(); /* Start new TFT transaction */ if(bSnapshot == true) {
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), // uint32_t data;
(area->y2 - area->y1 + 1)); /* set the working window */ uint8_t pixel[4];
for(int y = area->y1; y <= area->y2; y++) { pixel[3] = 0xFF;
for(int x = area->x1; x <= area->x2; x++) {
c = color_p->full; for(int y = area->y1; y <= area->y2; y++) {
tft.writeColor(c, 1); for(int x = area->x1; x <= area->x2; x++) {
color_p++; /* Function for converting LittlevGL pixel format to RGB888 */
// data = DISP_IMPL_lvgl_formatPixel(*color_p);
pixel[0] = (LV_COLOR_GET_B(*color_p) * 263 + 7) >> 5;
pixel[1] = (LV_COLOR_GET_G(*color_p) * 259 + 3) >> 6;
pixel[2] = (LV_COLOR_GET_R(*color_p) * 263 + 7) >> 5;
pixel[3] = 0xFF;
pFileOut.write(pixel, sizeof(pixel));
color_p++;
}
} }
} else {
tft.startWrite(); /* Start new TFT transaction */
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1),
(area->y2 - area->y1 + 1)); /* set the working window */
for(int y = area->y1; y <= area->y2; y++) {
for(int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction */
} }
tft.endWrite(); /* terminate TFT transaction */
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */ lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
} }
@ -106,10 +143,6 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
} }
bool shouldSleep = guiCheckSleep(); bool shouldSleep = guiCheckSleep();
if(!shouldSleep && guiSleeping) {
dispatchIdle(F("OFF"));
guiSleeping = false;
}
// Ignore first press? // Ignore first press?
@ -333,4 +366,39 @@ bool guiSetConfig(const JsonObject & settings)
Serial.println(); Serial.println();
return changed; return changed;
} }
/** Flush buffer.
*
* Flush buffer into a binary file.
*
* @note: data pixel should be formated to uint32_t RGBA. Imagemagick requirements.
*
* @param[in] pFileName Output binary file name.
*
*/
void guiTakeScreenshot(const char * pFileName)
{
pFileOut = SPIFFS.open(pFileName, "w");
uint8_t bmpheader[138] = {0x42, 0x4D, 0x8A, 0xB0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x7C,
0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x20, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x42, 0x47, 0x52, 0x73};
pFileOut.write(bmpheader, sizeof(bmpheader));
if(pFileOut == NULL) {
printf(("[Display] error: %s cannot be opened", pFileName));
return;
}
bSnapshot = true;
lv_obj_invalidate(lv_scr_act());
lv_refr_now(NULL); /* Will call our disp_drv.disp_flush function */
bSnapshot = false;
pFileOut.close();
printf(("[Display] data flushed to %s", pFileName));
}

View File

@ -11,6 +11,7 @@ void guiLoop(void);
void guiStop(void); void guiStop(void);
void guiCalibrate(); void guiCalibrate();
void guiTakeScreenshot(const char * pFileName);
bool guiGetConfig(const JsonObject & settings); bool guiGetConfig(const JsonObject & settings);
bool guiSetConfig(const JsonObject & settings); bool guiSetConfig(const JsonObject & settings);

View File

@ -44,8 +44,6 @@ void setup()
/* Read Config File */ /* Read Config File */
DynamicJsonDocument settings(1024); DynamicJsonDocument settings(1024);
// configGetConfig(doc);
// JsonObject settings = doc.as<JsonObject>();
configSetup(settings); configSetup(settings);
if(!settings[F("pins")][F("TFT_BCKL")].isNull()) { if(!settings[F("pins")][F("TFT_BCKL")].isNull()) {
@ -102,7 +100,7 @@ void loop()
// sdcardLoop(); // sdcardLoop();
#endif #endif
configLoop(); // configLoop();
/* Graphics Loops */ /* Graphics Loops */
// tftLoop(); // tftLoop();
@ -127,8 +125,8 @@ void loop()
mdnsLoop(wifiIsConnected); mdnsLoop(wifiIsConnected);
#endif #endif
// otaLoop(); // otaLoop(wifiIsConnected);
#endif #endif
delay(5); delay(1);
} }