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
/*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;
/*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
/*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) \
* 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*/
#define LV_FONT_DEFAULT &lv_font_unscii_8

View File

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

View File

@ -18,6 +18,13 @@
#include "hasp_gui.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
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};
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 shouldSleep = lv_disp_get_inactive_time(NULL) > guiSleepTime * 100;
if(shouldSleep && !guiSleeping) {
dispatchIdle(F("LONG"));
guiSleeping = true;
} else if(!shouldSleep && guiSleeping) {
dispatchIdle(F("OFF"));
guiSleeping = false;
}
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;
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++;
if(bSnapshot == true) {
// uint32_t data;
uint8_t pixel[4];
pixel[3] = 0xFF;
for(int y = area->y1; y <= area->y2; y++) {
for(int x = area->x1; x <= area->x2; x++) {
/* 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 */
}
@ -106,10 +143,6 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
}
bool shouldSleep = guiCheckSleep();
if(!shouldSleep && guiSleeping) {
dispatchIdle(F("OFF"));
guiSleeping = false;
}
// Ignore first press?
@ -333,4 +366,39 @@ bool guiSetConfig(const JsonObject & settings)
Serial.println();
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 guiCalibrate();
void guiTakeScreenshot(const char * pFileName);
bool guiGetConfig(const JsonObject & settings);
bool guiSetConfig(const JsonObject & settings);

View File

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