Hardware components | ||||||
| × | 1 | ||||
Software apps and online services | ||||||
![]() |
| |||||
Hand tools and fabrication machines | ||||||
![]() |
| |||||
The T-LITE (M5StickC-Plus and HAT THERMAL) from m5stack is my favorite product for easily viewing thermal images. However, personally, I felt that one feature was missing. It is a function that takes pictures of yourself (so-called "seffie function"). The HAT THERMAL is fixed facing forward, so it cannot be turned backward. In order to implement the selfie function in this project, I did the following.
- Making a holder to rotate the HAT THERMAL
- Selfie mode added to firmware to flip display screen
The selfie holder consists of two parts.
The first is the base part, which connects to the M5StickC-Plus and then connects to the router part described below.
The other is the router part, which holds the HAT THERMAL. Insert the cylindrical part into the circle on the base part and rotate it.
The assembled product is shown in the image below. The M5StickC-Plus and HAT THERMAL are connected with jumper wires. The pin configuration remains unchanged.
I have attached the stl files, so those who are interested can print it out.
Custom FirmwareI created custom firmware to add Selfie Mode. The following is the repository for the original firmware.
https://github.com/m5stack/M5StickC-Plus-TLite-FW
I made the following fixes.
- Add "selfie_mode" to the parameters
- Pressing BtnA switches to Selfie Mode (However, Color Change Mode will no longer function)
- When Selfie Mode is switched, the thermal image display is reversed
If you want to build custom firmware, overwrite the repository with the attached source code and build it.
Examples of operationSelfie Mode OFF
Selfie Mode ON
//! Copyright (c) M5Stack. All rights reserved.
//! Licensed under the MIT license.
//! See LICENSE file in the project root for full license information.
#include "command_processor.hpp"
#include <esp_log.h>
#include <esp_sntp.h>
#include <esp_wifi.h>
#include <driver/gpio.h>
#include <vector>
#include <Preferences.h>
#include <WiFiServer.h>
#include <DNSServer.h>
#include <ArduinoJson.hpp> // https://github.com/bblanchon/ArduinoJson/
#include <M5Unified.hpp> // https://github.com/m5stack/M5Unified/
#include <lgfx/utility/lgfx_qrcode.h>
#include "common_header.h"
#include "screenshot_streamer.hpp"
#include "jpg/jpge.h"
#include "resource/bmp_logo.h"
#include "resource/jpg_staff.h"
#include "resource/wav_enter.h"
DNSServer dnsServer;
extern const unsigned char gWav_Click[112];
extern void webserverTask(void*);
auto& display = M5.Display;
// M5BurnerNVS burner_nvs;
screenshot_streamer_t screenshot_holder;
draw_param_t draw_param;
static constexpr const char* cloud_server_name = "ezdata.m5stack.com";
static constexpr const char* ntp_server[] = {"0.pool.ntp.org", "1.pool.ntp.org",
"2.pool.ntp.org"};
volatile bool need_wifi_reconnect = false;
extern "C" {
void esp_timer_impl_update_apb_freq(
uint32_t apb_ticks_per_us); // private in IDF
}
static constexpr const uint16_t label_ui_text_color = 0x8610u;
static constexpr const int32_t header_ui_height = 24;
static constexpr const int32_t battery_ui_width = 4;
static constexpr const uint8_t mlx_width = 16;
static constexpr const uint8_t mlx_height = 24;
static constexpr const char* graph_text_table[] = {"Cntr", "High", "Avrg",
"Low"};
static constexpr const uint32_t graph_color_table[] = {
0x00909090u, 0x00FFCF00u, 0x0000A000u, 0x0000CFFFu};
static constexpr const int step_table[] = {1, 2, 5, 10, 20, 50, 100, 200};
static constexpr const size_t step_table_len =
sizeof(step_table) / sizeof(step_table[0]);
const int32_t raw_step_offset = convertCelsiusToRaw(0.0f) - 128 * 1000;
// volatile size_t color_map_table_idx = 0;
static constexpr size_t framedata_len = 6;
framedata_t framedata[framedata_len];
volatile int idx_recv = -1;
static int smooth_move(int dst, int src) {
return (dst == src) ? dst : ((dst + src + (src < dst ? 1 : 0)) >> 1);
// return (dst == src) ? dst : ((dst * 3 + src * 5 + (src < dst ? 5 : 0)) >>
// 3);
}
static void soundStartUp(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.playRaw(wav_enter, sizeof(wav_enter), 48000);
// M5.Speaker.playRaw(wav_startup, sizeof(wav_startup), 24000);
}
}
static void soundEnter(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.playRaw(wav_enter, sizeof(wav_enter), 48000);
}
}
static void soundExit(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.playRaw(wav_enter, sizeof(wav_enter), 36000);
}
}
static void soundMoveCursor(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.playRaw(wav_enter, sizeof(wav_enter), 42000);
// M5.Speaker.tone(4400, 80);
}
}
static void soundValueChange(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.playRaw(wav_enter, sizeof(wav_enter), 48000, false, 1, 0,
true);
// M5.Speaker.tone(2200, 50, 0);
}
}
static void soundOperate(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.playRaw(wav_enter, sizeof(wav_enter), 48000);
// M5.Speaker.playRaw(wav_confirm, sizeof(wav_confirm), 48000);
}
}
static void soundUSBConnected(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.tone(1046.502f, 64, 0, false); // C6
M5.Speaker.tone(880.000f, 64, 0, false); // A5
M5.Speaker.tone(1318.510f, 64, 0, false); // E6
}
}
static void soundUSBDisconnected(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.tone(880.000f, 64, 0, false); // A5
M5.Speaker.tone(783.991f, 64, 0, false); // G5
M5.Speaker.tone(659.255f, 64, 0, false); // E5
}
}
static void soundWiFiConnected(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
// M5.Speaker.playRaw(wav_connect, sizeof(wav_connect), 24000);
M5.Speaker.tone(1046.502f, 64, 0, false); // C6
M5.Speaker.tone(1567.982f, 64, 0, false); // G6
}
}
static void soundWiFiDisconnected(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.tone(1760.000f, 64, 0, false); // A6
M5.Speaker.tone(1174.659f, 64, 0, false); // D6
}
}
static void soundCloudSuccess(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
// M5.Speaker.playRaw(wav_connect, sizeof(wav_connect), 24000);
M5.Speaker.tone(2093.005f, 48, 0, false); // C7
M5.Speaker.tone(2637.020f, 48, 0, false); // E7
M5.Speaker.tone(3135.963f, 48, 0, false); // G7
}
}
static void soundCloudError(void) {
if (draw_param.misc_volume != draw_param.misc_volume_t::misc_volume_mute) {
M5.Speaker.tone(3520.000f, 48, 0, false); // A7
M5.Speaker.tone(2793.826f, 48, 0, false); // F7
M5.Speaker.tone(2349.318f, 48, 0, false); // D7
}
}
struct rect_t {
int16_t x;
int16_t y;
int16_t w;
int16_t h;
constexpr rect_t(void) : x{0}, y{0}, w{0}, h{0} {
}
constexpr rect_t(int x_, int y_, int w_, int h_)
: x{(int16_t)x_}, y{(int16_t)y_}, w{(int16_t)w_}, h{(int16_t)h_} {
}
inline constexpr int top(void) const {
return y;
}
inline constexpr int left(void) const {
return x;
}
inline constexpr int right(void) const {
return x + w;
}
inline constexpr int bottom(void) const {
return y + h;
}
inline constexpr bool empty(void) const {
return w <= 0 || h <= 0;
}
bool smooth_move(const rect_t& src) {
if (operator==(src)) return false;
int new_b = ::smooth_move(src.bottom(), bottom());
int new_y = ::smooth_move(src.y, y);
h = new_b - new_y;
y = new_y;
int new_r = ::smooth_move(src.right(), right());
int new_x = ::smooth_move(src.x, x);
w = new_r - new_x;
x = new_x;
return true;
}
inline bool operator==(const rect_t& src) const {
return x == src.x && y == src.y && w == src.w && h == src.h;
}
inline bool operator!=(const rect_t& src) const {
return !operator==(src);
}
};
static constexpr const char NVS_NAMESPACE[] = "__tlite_nvs__";
static constexpr const char KEY_ALARM_TEMPERATURE[] = "alm_temp";
static constexpr const char KEY_ALARM_REFERENCE[] = "alm_ref";
static constexpr const char KEY_ALARM_MODE[] = "alm_mode";
// static constexpr const char KEY_ALARM_BEHAVIOR[] = "alm_behavior";
static constexpr const char KEY_SENS_REFRESHRATE[] = "refreshrate";
static constexpr const char KEY_SENS_NOISEFILTER[] = "noisefilter";
static constexpr const char KEY_SENS_MONITORAREA[] = "monitorarea";
static constexpr const char KEY_SENS_EMISSIVITY[] = "emissivity";
static constexpr const char KEY_RANGE_AUTOSWITCH[] = "range_auto";
static constexpr const char KEY_RANGE_UPPER[] = "range_upper";
static constexpr const char KEY_RANGE_LOWER[] = "range_lower";
static constexpr const char KEY_NET_RUNNING_MODE[] = "net_running";
static constexpr const char KEY_NET_JPGQUALITY[] = "jpg_quality";
static constexpr const char KEY_CLOUD_UPLOAD[] = "upload_ena";
static constexpr const char KEY_CLOUD_INTERVAL[] = "upload_int";
static constexpr const char KEY_CLOUD_TOKEN[] = "ezdata_token";
static constexpr const char KEY_NET_TIMEZONE[] = "timezone";
static constexpr const char KEY_MISC_CPUSPEED[] = "cpuspeed";
static constexpr const char KEY_MISC_BRIGHTNESS[] = "brightness";
static constexpr const char KEY_MISC_VOLUME[] = "volume";
static constexpr const char KEY_MISC_LANGUAGE[] = "language";
static constexpr const char KEY_MISC_LAYOUT[] = "layout";
static constexpr const char KEY_MISC_COLOR[] = "color";
static constexpr const char KEY_MISC_POINTER[] = "pointer";
// static constexpr const char KEY_MISC_ROTATION[] = "msc_rotation";
std::string convert(const std::string& src) {
std::string res;
int i = src.length();
for (auto c : src) {
i = (i + 1) & 15;
c = c ^ i;
res.append(1, c);
}
return res;
}
void config_param_t::saveNvs(void) {
ESP_LOGD("DEBUG", "saveNvs in");
/// ToDo:FlashROM
Preferences pref;
bool exist = pref.begin(NVS_NAMESPACE, false);
pref.putUShort(KEY_ALARM_TEMPERATURE, alarm_temperature.get());
pref.putUChar(KEY_ALARM_REFERENCE, alarm_reference);
pref.putUChar(KEY_ALARM_MODE, alarm_mode);
// pref.putUChar( KEY_ALARM_BEHAVIOR , alarm_behavior );
pref.putUChar(KEY_MISC_CPUSPEED, misc_cpuspeed);
pref.putUChar(KEY_SENS_REFRESHRATE, sens_refreshrate);
pref.putUChar(KEY_SENS_NOISEFILTER, sens_noisefilter);
pref.putUChar(KEY_SENS_MONITORAREA, sens_monitorarea);
pref.putUChar(KEY_SENS_EMISSIVITY, sens_emissivity);
pref.putUChar(KEY_RANGE_AUTOSWITCH, range_autoswitch);
pref.putUShort(KEY_RANGE_UPPER, range_temp_upper);
pref.putUShort(KEY_RANGE_LOWER, range_temp_lower);
pref.putUChar(KEY_NET_RUNNING_MODE, net_running_mode);
// pref.putUChar( KEY_NET_SETUP_MODE , net_setup_mode );
// pref.putBool( KEY_NET_WEBSERVER , net_webserver );
pref.putUChar(KEY_NET_JPGQUALITY, net_jpg_quality);
pref.putInt(KEY_NET_TIMEZONE, oncloud_timezone_sec);
// pref.putBool( KEY_CLOUD_UPLOAD , cloud_upload );
pref.putUChar(KEY_CLOUD_INTERVAL, cloud_interval);
pref.putUChar(KEY_MISC_BRIGHTNESS, misc_brightness);
pref.putUChar(KEY_MISC_VOLUME, misc_volume);
pref.putUChar(KEY_MISC_LANGUAGE, misc_language);
pref.putUChar(KEY_MISC_POINTER, misc_pointer);
pref.putUChar(KEY_MISC_LAYOUT, misc_layout);
pref.putUChar(KEY_MISC_COLOR, misc_color);
pref.putString(KEY_CLOUD_TOKEN, cloud_token.c_str());
// pref.putString(KEY_NET_SSID , net_ssid.c_str() );
// pref.putString(KEY_NET_PWD , convert(net_pwd).c_str());
// pref.putUChar( KEY_MISC_ROTATION , misc_rotation );
pref.end();
ESP_LOGD("DEBUG", "saveNvs out");
}
void config_param_t::loadNvs(void) {
loadDefault();
Preferences pref;
if (pref.begin(NVS_NAMESPACE, true)) {
alarm_temperature =
pref.getUShort(KEY_ALARM_TEMPERATURE, alarm_temperature);
alarm_reference = (alarm_reference_t)pref.getUChar(KEY_ALARM_REFERENCE,
alarm_reference);
alarm_mode = (alarm_mode_t)pref.getUChar(KEY_ALARM_MODE, alarm_mode);
// alarm_behavior = (alarm_behavior_t) pref.getUChar(
// KEY_ALARM_BEHAVIOR , alarm_behavior );
sens_refreshrate = (sens_refreshrate_t)pref.getUChar(
KEY_SENS_REFRESHRATE, sens_refreshrate);
sens_noisefilter = (sens_noisefilter_t)pref.getUChar(
KEY_SENS_NOISEFILTER, sens_noisefilter);
sens_monitorarea = (sens_monitorarea_t)pref.getUChar(
KEY_SENS_MONITORAREA, sens_monitorarea);
sens_emissivity = pref.getUChar(KEY_SENS_EMISSIVITY, sens_emissivity);
range_autoswitch = (range_autoswitch_t)pref.getUChar(
KEY_RANGE_AUTOSWITCH, range_autoswitch);
range_temp_upper = pref.getUShort(KEY_RANGE_UPPER, range_temp_upper);
range_temp_lower = pref.getUShort(KEY_RANGE_LOWER, range_temp_lower);
net_running_mode = (net_running_mode_t)pref.getUChar(
KEY_NET_RUNNING_MODE, net_running_mode);
// net_setup_mode = (net_setup_mode_t) pref.getUChar(
// KEY_NET_SETUP_MODE , net_setup_mode ); net_webserver =
// pref.getBool( KEY_NET_WEBSERVER , net_webserver );
net_jpg_quality = pref.getUChar(KEY_NET_JPGQUALITY, net_jpg_quality);
oncloud_timezone_sec =
pref.getInt(KEY_NET_TIMEZONE, oncloud_timezone_sec);
misc_cpuspeed =
(misc_cpuspeed_t)pref.getUChar(KEY_MISC_CPUSPEED, misc_cpuspeed);
misc_brightness = (misc_brightness_t)pref.getUChar(KEY_MISC_BRIGHTNESS,
misc_brightness);
misc_volume =
(misc_volume_t)pref.getUChar(KEY_MISC_VOLUME, misc_volume);
misc_language =
(misc_language_t)pref.getUChar(KEY_MISC_LANGUAGE, misc_language);
misc_pointer =
(misc_pointer_t)pref.getUChar(KEY_MISC_POINTER, misc_pointer);
misc_layout = pref.getUChar(KEY_MISC_LAYOUT, misc_layout);
misc_color = (misc_color_t)pref.getUChar(KEY_MISC_COLOR, misc_color);
// cloud_upload = (cloud_upload_t) pref.getUChar(
// KEY_CLOUD_UPLOAD , cloud_upload );
cloud_interval =
(cloud_interval_t)pref.getUChar(KEY_CLOUD_INTERVAL, cloud_interval);
cloud_token =
pref.getString(KEY_CLOUD_TOKEN, cloud_token.c_str()).c_str();
// net_ssid = pref.getString(KEY_NET_SSID ,
// net_ssid.c_str() ).c_str(); net_pwd = convert(
// pref.getString(KEY_NET_PWD ,
// convert(net_pwd).c_str()).c_str()).c_str(); misc_rotation =
// pref.getUChar( KEY_MISC_ROTATION , misc_rotation );
pref.end();
}
config_save_countdown = 0;
}
void config_param_t::loadDefault(void) {
// net_ssid.clear();
// net_pwd.clear();
net_running_mode = net_running_mode_t::net_running_mode_offline;
net_setup_mode = net_setup_mode_t ::net_setup_mode_off;
alarm_temperature = (100 + 64) * 128;
alarm_mode = alarm_mode_t ::alarm_mode_hightemp;
alarm_reference = alarm_reference_t ::alarm_reference_highest;
// alarm_behavior = alarm_behavior_t ::alarm_behavior_beep_led ;
sens_refreshrate = sens_refreshrate_t::sens_refreshrate_16;
sens_noisefilter = sens_noisefilter_t::sens_noisefilter_medium;
sens_monitorarea = sens_monitorarea_t::sens_monitorarea_30x24;
sens_emissivity = 98;
range_autoswitch = range_autoswitch_t::range_autoswitch_on;
range_temp_upper = (40 + 64) * 128;
range_temp_lower = (20 + 64) * 128;
misc_brightness = misc_brightness_t ::misc_brightness_middle;
misc_cpuspeed = misc_cpuspeed_t ::misc_cpuspeed_160;
misc_language = misc_language_t ::misc_language_en;
net_jpg_quality = 60;
cloud_interval = cloud_interval_t ::cloud_interval_30sec;
misc_layout = 0;
misc_color.setDefault();
misc_pointer = misc_pointer_t ::misc_pointer_pointtxt;
misc_volume = misc_volume_t ::misc_volume_normal;
}
void config_param_t::setEmissivity(uint8_t emissivity) {
sens_emissivity = emissivity;
command_processor::setEmissivity(emissivity);
}
void config_param_t::setTimeZoneSec(int32_t sec) {
oncloud_timezone_sec = sec;
configTime(sec, 0, ntp_server[0], ntp_server[1], ntp_server[2]);
}
void config_param_t::referenceModeChange(int add) {
alarm_reference.add(add);
/*
if (add) {
int i = alarm_reference + add;
if (i < 0)
i = alarm_reference_t::alarm_reference_max - 1;
else if (i >= alarm_reference_t::alarm_reference_max)
i = 0;
alarm_reference = (config_param_t::alarm_reference_t)i;
// show_reference_name = 50; //
alarm
}
//*/
}
/*
struct graph_filter_t {
static constexpr const size_t hist_max = 3;
// 5 : 13
// 1 3
uint16_t _hist[hist_max];
uint8_t _idx = 0;
uint16_t exec(uint16_t new_value) {
_hist[_idx] = new_value;
if (++_idx >= hist_max) { _idx = 0; }
uint32_t avg_temp = 0;
for (size_t i = 0; i < hist_max; ++i) {
size_t k = abs((int)(i - _idx) * 2 + 1);
if (k > hist_max) {
k = hist_max * 2 - k;
}
avg_temp += _hist[i] * k;
}
// ESP_LOGE("DEBUG","input:%d avg:%d", new_value, avg_temp);
return avg_temp / 5;
// return new_value;
}
};
static graph_filter_t graph_filter[4];
//*/
void draw_param_t::setup(LovyanGFX* gfx_, framedata_t* frame_array_,
int frameindex) {
_frame_array = frame_array_;
frame = &frame_array_[frameindex];
_lowest_value.set(frame->temp[frame->lowest]);
_highest_value.set(frame->temp[frame->highest]);
update(frameindex);
for (int i = 0; i < 4; ++i) {
auto tmp = frame->temp[i];
for (int j = 0; j < graph_data.data_len; ++j) {
graph_data.temp_arrays[i][j] = tmp;
}
// while (tmp != graph_filter[i].exec(tmp));
}
_prev_frameindex = -1;
}
void draw_param_t::setFont(const m5gfx::IFont* font_) {
font = font_;
display.setFont(font_);
lgfx::FontMetrics fm;
font->getDefaultMetric(&fm);
font_height = fm.height;
}
void draw_param_t::setColorTable(const uint16_t* tbl) {
color_map = tbl;
}
void draw_param_t::setColorTable(size_t idx) {
color_map = color_map_table[idx];
}
bool draw_param_t::update(int frameindex) {
if (_prev_frameindex == frameindex) return false;
_prev_frameindex = frameindex;
frame = &_frame_array[frameindex];
++update_count;
return true;
}
bool draw_param_t::range_update(void) {
if (!frame) return false;
if (range_autoswitch.get() == range_autoswitch_off) return true;
int32_t lowest = frame->temp[frame->lowest];
int32_t highest = frame->temp[frame->highest];
int32_t margin = ((highest - lowest) >> 4) + 1;
lowest = _lowest_value.exec(lowest - margin, margin);
highest = _highest_value.exec(highest + margin, margin);
if (range_temp_lower != lowest || range_temp_upper != highest) {
range_temp_lower = lowest;
range_temp_upper = highest;
temp_diff = (highest - lowest) + 1;
++modify_count;
return true;
}
return false;
}
int32_t value_smooth_t::exec(int32_t src, int32_t margin) {
/*
int32_t new_target = src << 8;
if (abs(new_target - _target) > (margin << 8)) {
_target = new_target;
}
int diff = _target - _current;
_add = ((_add + diff + 2) >> 5);
if (diff) {
_add += diff < 0 ? -1 : 1;
}
_current += _add;
return _current >> 8;
/*/
int32_t new_target = src << 8;
if (abs(new_target - _target) > (margin << 8)) {
_target = new_target;
}
int diff = _target - _current;
if (diff) {
int ta = 1;
int tdiff = abs(diff);
while (0 < (tdiff -= ta)) {
ta *= 2;
}
ta += tdiff;
if (diff < 0) {
ta = -ta;
}
_add = (_add + (ta >> 1)) >> 1;
}
// _add = ((_add + diff + 2) >> 5);
// if (diff) {
// _add += diff < 0 ? -1 : 1;
// }
_current += _add;
return _current >> 8;
//*/
}
void value_smooth_t::set(int32_t default_value) {
_target = default_value << 8;
_current = default_value << 8;
}
// static constexpr const uint32_t jpeg_len_max = 8192 * 3;
screenshot_streamer_t::screenshot_streamer_t(void) {
// JPEG (1)
_queue_canvas = xQueueCreate(1, sizeof(screenshot_streamer_t::queue_ss_t));
// WiFiClient
_queue_bufdata =
xQueueCreate(2, sizeof(screenshot_streamer_t::queue_bufdata_t));
//
_queue_client = xQueueCreate(4, sizeof(WiFiClient*));
}
void screenshot_streamer_t::requestScreenShot(WiFiClient* client) {
xQueueSendToBack(_queue_client, &client, 0);
_is_requested = true;
}
/*
#include <lwip/sockets.h> // for 'send' function
static size_t write_fd(int socketFileDescriptor, const uint8_t *buf, size_t
size)
{
int retry = 2;
size_t totalBytesSent = 0;
size_t bytesRemaining = size;
if(socketFileDescriptor < 0) {
return 0;
}
while(retry--) {
//use select to make sure the socket is ready for writing
fd_set set;
struct timeval tv;
FD_ZERO(&set); // empties the set
FD_SET(socketFileDescriptor, &set); // adds FD to the set
tv.tv_sec = 0;
tv.tv_usec = 100; // WIFI_CLIENT_SELECT_TIMEOUT_US;
if (select(socketFileDescriptor + 1, NULL, &set, NULL, &tv) < 0) {
return 0;
}
if (FD_ISSET(socketFileDescriptor, &set)) {
int res = send(socketFileDescriptor, (void*) buf, bytesRemaining,
MSG_DONTWAIT); if(res > 0) { totalBytesSent += res; if (totalBytesSent >= size)
{
//completed successfully
retry = 0;
} else {
buf += res;
bytesRemaining -= res;
retry = 2; // WIFI_CLIENT_MAX_WRITE_RETRY;
}
}
else if(res < 0) {
ESP_LOGE("DEBUG", "fail on fd %d, errno: %d, \"%s\"",
socketFileDescriptor, errno, strerror(errno)); if(errno != EAGAIN) {
//if resource was busy, can try again, otherwise give up
// stop();
retry = 0;
}
}
}
}
return totalBytesSent;
}
//*/
void screenshot_streamer_t::streamTask(void* arg) {
auto me = (screenshot_streamer_t*)arg;
queue_bufdata_t qd;
auto& cl = me->_wifi_client;
while (pdTRUE == xQueueReceive(me->_queue_bufdata, &qd, portMAX_DELAY)) {
auto len = qd.len;
auto buf = qd.bufdata;
if (qd.y0) {
xQueueReceive(me->_queue_client, &cl, 0);
}
if (cl == nullptr) {
continue;
}
if (cl->connected()) {
if (len == cl->write(buf, len)) {
continue;
}
cl->stop();
}
cl = nullptr;
}
vTaskDelete(nullptr);
}
bool screenshot_streamer_t::put_buf(const void* Pbuf, int len) {
if (len) {
_q_bufdata.len = len;
_q_bufdata.bufdata = (const uint8_t*)Pbuf;
xQueueSendToBack(_queue_bufdata, &_q_bufdata, portMAX_DELAY);
return true;
}
if (_wifi_client != nullptr) {
requestScreenShot(_wifi_client);
}
return true;
}
bool screenshot_streamer_t::initCapture(uint16_t width, uint16_t height) {
if (!_is_requested && !uxQueueMessagesWaiting(_queue_client)) {
return false;
}
_is_requested = false;
if (_width != width || _height != height) {
int num_channels = 3;
jpge::params comp_params = jpge::params();
comp_params.m_subsampling = jpge::H2V2;
comp_params.m_quality = draw_param.net_jpg_quality;
if (!_jpeg_enc.init(this, width, height, num_channels, comp_params)) {
return false;
}
_y = 0;
_width = width;
_height = height;
}
return true;
}
bool screenshot_streamer_t::addQueue(M5Canvas* canvas, uint16_t y) {
queue_ss_t queue_ss;
queue_ss.canvas = canvas;
queue_ss.y = y;
if (pdPASS != xQueueSendToBack(_queue_canvas, &queue_ss, 64)) {
// ESP_LOGD("DEBUG","queue_timeout:y:%d", y);
//
if (_wifi_client) { // wifi_is_requested
_is_requested = true;
}
return false;
}
return true;
}
screenshot_streamer_t::process_result_t screenshot_streamer_t::processCapture(
void) {
queue_ss_t queue_ss;
//
// ()
if (pdPASS != xQueuePeek(_queue_canvas, &queue_ss, 0)) {
return pr_nothing;
}
if (_y != queue_ss.y) {
//
xQueueReceive(_queue_canvas, &queue_ss, 0);
return pr_error;
}
if (queue_ss.y == 0) {
bool request = uxQueueMessagesWaiting(_queue_client);
_is_requested = request;
if (!request) {
xQueueReceive(_queue_canvas, &queue_ss, 0);
return process_result_t::pr_nothing;
}
static constexpr const char headtext[] =
"\r\n--tlite\r\nContent-type: image/jpeg\r\n\r\n";
_q_bufdata.bufdata = (const uint8_t*)headtext;
_q_bufdata.len = sizeof(headtext) - 1;
_q_bufdata.y0 = true;
xQueueSendToBack(_queue_bufdata, &_q_bufdata, portMAX_DELAY);
_q_bufdata.y0 = false;
// JPEG ()
_jpeg_enc.reinit(draw_param.net_jpg_quality);
}
_y += queue_ss.canvas->height();
bool success = true;
// bool lineend = false;
auto framebuffer = (uint16_t*)(queue_ss.canvas->getBuffer());
for (int i = 0; i < queue_ss.canvas->height(); ++i) {
success = _jpeg_enc.process_scanline565(
&framebuffer[i * queue_ss.canvas->width()]);
if (++queue_ss.y >= _height) {
break;
}
if (!success) {
break;
}
}
//
xQueueReceive(_queue_canvas, &queue_ss, 0);
// JPEG
if (success) {
_jpeg_enc.process_mcu_row();
if (_y >= _height) {
_y = 0;
_jpeg_enc.process_scanline565(nullptr);
}
return process_result_t::pr_progress;
}
// ESP_EARLY_LOGE("DEBUG","jpg encode error");
return process_result_t::pr_error;
//---------------------------------------------
}
struct ui_base_t {
bool isModified(draw_param_t* param) const {
return _prev_update_count != param->update_count ||
_prev_modify_count != param->modify_count;
}
virtual void update(draw_param_t* param) {
}
virtual bool draw(draw_param_t* param) {
bool res = _prev_update_count != param->update_count ||
_prev_modify_count != param->modify_count;
_prev_update_count = param->update_count;
_prev_modify_count = param->modify_count;
return !_client_rect.empty() && res;
}
virtual void draw(draw_param_t* param, M5Canvas* canvas, int32_t y,
int32_t h) {
}
virtual bool smoothMove(void) {
return _client_rect.smooth_move(_target_rect);
}
virtual void setTargetRect(const rect_t& rect) {
_target_rect = rect;
}
void setClientRect(const rect_t& rect) {
_client_rect = rect;
}
const rect_t& getTargetRect(void) const {
return _target_rect;
}
const rect_t& getClientRect(void) const {
return _client_rect;
}
void rotateCoordinate(int r, int& x, int& y, int& w, int& h) {
if (r) {
if (r & 1) {
std::swap(x, y);
std::swap(w, h);
}
if ((1u << r) & 0b0110) {
x = _client_rect.w - (x + w);
}
if ((1u << r) & 0b1100) {
y = _client_rect.h - (y + h);
}
}
}
protected:
// inline void clearInvalidate(void) {
// _invalidate = false;
// }
// bool _invalidate;
rect_t _client_rect;
rect_t _target_rect;
uint8_t _prev_update_count;
uint8_t _prev_modify_count;
};
class qrcode_ui_t : public ui_base_t {
public:
std::string _qr_string = "teststring";
M5Canvas _qr_canvas;
void draw(draw_param_t* param, M5Canvas* canvas, int32_t canvas_y,
int32_t h) override {
canvas->fillScreen(TFT_WHITE);
float zoom = (float)_client_rect.h / (_qr_canvas.height() + 4);
_qr_canvas.pushRotateZoom(
canvas, _client_rect.x + (_client_rect.w >> 1),
_client_rect.y + (_client_rect.h >> 1) - canvas_y, 0, zoom, zoom);
}
void show(const char* data) {
_qr_canvas.setColorDepth(1);
_qr_string = data;
for (uint8_t version = 1; version <= 40; ++version) {
QRCode qrcode;
auto qrcodeData =
(uint8_t*)alloca(lgfx_qrcode_getBufferSize(version));
if (0 !=
lgfx_qrcode_initText(&qrcode, qrcodeData, version, 0, data))
continue;
_qr_canvas.createSprite(qrcode.size, qrcode.size);
_qr_canvas.fillScreen(1);
int_fast16_t thickness = 1;
int_fast16_t lineLength = qrcode.size;
_qr_canvas.setColor(0);
uint32_t y = 0;
do {
uint32_t x = 0;
do {
if (lgfx_qrcode_getModule(&qrcode, x, y))
_qr_canvas.drawPixel(x, y);
} while (++x < qrcode.size);
} while (++y < qrcode.size);
break;
}
int w = display.height();
setTargetRect({(display.width() - w) >> 1, 0, w, w});
}
void hide(void) {
setTargetRect({display.width() >> 1, display.height() >> 1, 0, 0});
}
};
class overlay_ui_t : public ui_base_t {
static constexpr const size_t lines_max = 6;
std::string _text[lines_max];
uint16_t _textwidth[lines_max];
uint8_t _lines;
uint8_t _countdown;
public:
void show(uint8_t count, const char* text0, const char* text1 = nullptr,
const char* text2 = nullptr, const char* text3 = nullptr,
const char* text4 = nullptr, const char* text5 = nullptr) {
_countdown = count;
_text[0] = text0;
_lines = 1;
if (text1) {
_text[1] = text1;
++_lines;
if (text2) {
_text[2] = text2;
++_lines;
if (text3) {
_text[3] = text3;
++_lines;
if (text4) {
_text[4] = text4;
++_lines;
if (text5) {
_text[5] = text5;
++_lines;
}
}
}
}
}
int32_t w = 0;
for (int32_t j = _lines - 1; j >= 0; --j) {
int32_t tw = display.textWidth(_text[j].c_str());
_textwidth[j] = tw;
if (w < tw) {
w = tw;
}
}
int32_t fh = display.fontHeight();
w += fh;
int32_t h = (_lines + 1) * fh;
setTargetRect(
{(display.width() - w) >> 1, (display.height() - h) >> 1, w, h});
}
void hide(void) {
setTargetRect({display.width() >> 1, display.height() >> 1, 0, 0});
}
void update(draw_param_t* param) override {
if (_countdown && (_countdown != 255)) {
if (0 == --_countdown) {
hide();
}
}
}
void draw(draw_param_t* param, M5Canvas* canvas, int32_t canvas_y,
int32_t h) override {
{
auto canvas_w = canvas->width();
int32_t client_width = _client_rect.right() < canvas_w
? _client_rect.right()
: canvas_w;
int32_t client_x = _client_rect.x < 0 ? 0 : _client_rect.x;
client_width -= client_x;
auto client_height = _client_rect.h;
auto buf = ((uint16_t*)canvas->getBuffer()) + client_x;
int dy = _client_rect.y - canvas_y;
int dye = dy + client_height;
if (dy < 0) dy = 0;
if (dye > h) dye = h;
uint32_t cw2 = (client_width + 1) >> 1;
for (; dy < dye; ++dy) {
auto b = (uint32_t*)(&buf[canvas_w * dy]);
for (int x = 0; x < cw2; ++x) {
uint32_t tmp = b[x];
b[x] = (tmp >> 1) & 0x6F7B6F7B | ((tmp & 0x00010001) << 15);
// tmp = (tmp << 7 | tmp >> 9) & 0x7BEF;
// b[x] = tmp << 8 | tmp >> 8;
}
}
}
canvas->setTextSize(1);
canvas->setTextColor(TFT_WHITE);
canvas->setTextDatum(textdatum_t::top_left);
auto fh = param->font_height;
int32_t y =
_client_rect.y - canvas_y + ((_client_rect.h - fh * _lines) >> 1);
for (int j = 0; j < _lines; ++j, y += fh) {
if (y > canvas->height() || 0 > y + fh) {
continue;
}
if (0 == _textwidth[j]) {
continue;
}
canvas->drawString(
_text[j].c_str(),
_client_rect.x + ((_client_rect.w - _textwidth[j]) >> 1), y);
}
}
};
qrcode_ui_t qrcode_ui;
overlay_ui_t overlay_ui;
void config_param_t::misc_backtofactory_func(uint8_t) {
WiFi.mode(WIFI_MODE_STA);
WiFi.disconnect(true, true);
draw_param.loadDefault();
draw_param.saveNvs();
overlay_ui.show(64, "Reset Done.");
}
static rect_t _cursor_rect = {0, 0, 240, 0};
static rect_t _cursor_target_rect = {0, 0, 240, 0};
class control_ui_t;
static control_ui_t* _cursor_target = nullptr;
class control_ui_t : public ui_base_t {
protected:
static control_ui_t* getCursorTarget(void) {
return _cursor_target;
}
static void setCursorTarget(control_ui_t* target) {
_cursor_target = target;
if (target) {
_cursor_target_rect = target->getDisplayTargetRect();
}
}
rect_t getDisplayTargetRect(void) const {
if (_parent) {
auto r = _parent->getDisplayTargetRect();
r.x += _target_rect.x;
r.y += _target_rect.y;
r.w = _target_rect.w;
r.h = _target_rect.h;
return r;
}
return {0, 0, _target_rect.w, _target_rect.h};
...
This file has been truncated, please download it to see its full contents.
#include <stdint.h>
#include <stddef.h>
#include <M5GFX.h>
#include <WiFi.h>
static constexpr const uint8_t firmware_ver_major = 0;
static constexpr const uint8_t firmware_ver_minor = 0;
static constexpr const uint8_t firmware_ver_patch = 11;
static constexpr uint8_t frame_width = 32;
static constexpr uint8_t frame_height = 24;
static constexpr inline float convertRawToCelsius(int32_t rawdata) {
return ((float)rawdata / 128) - 64.0f;
}
static constexpr inline int32_t convertCelsiusToRaw(float temperature) {
return (temperature + 64) * 128;
}
static constexpr const char mon_tbl[12][4] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
};
static constexpr const char wday_tbl[7][4] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
};
#define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(a[0]))
static constexpr const uint16_t color_map_table[][256] = {
{
// colormap_golden
0x0004, 0x0004, 0x0004, 0x0004, 0x0005, 0x0005, 0x0825, 0x0825, 0x0825,
0x0826, 0x0826, 0x0826, 0x1027, 0x1027, 0x1027, 0x1027, 0x1828, 0x1828,
0x1848, 0x1849, 0x2049, 0x2049, 0x204A, 0x204A, 0x284A, 0x284B, 0x284B,
0x284B, 0x306C, 0x306C, 0x306C, 0x386D, 0x386D, 0x386D, 0x408E, 0x408E,
0x408E, 0x408F, 0x488F, 0x488F, 0x4890, 0x5090, 0x50B0, 0x50B0, 0x58B1,
0x58B1, 0x58B1, 0x58B1, 0x60D2, 0x60D2, 0x60D2, 0x68D2, 0x68D2, 0x68D2,
0x68F3, 0x70F3, 0x70F3, 0x70F3, 0x78F3, 0x7913, 0x7913, 0x7913, 0x8113,
0x8133, 0x8133, 0x8133, 0x8933, 0x8932, 0x8952, 0x9152, 0x9152, 0x9152,
0x9151, 0x9971, 0x9971, 0x9971, 0x9970, 0xA190, 0xA190, 0xA18F, 0xA98F,
0xA9AF, 0xA9AE, 0xA9AE, 0xB1AD, 0xB1CD, 0xB1CD, 0xB9CC, 0xB9EC, 0xB9EB,
0xB9EB, 0xC1EB, 0xC20A, 0xC20A, 0xCA09, 0xCA29, 0xCA29, 0xCA28, 0xCA28,
0xD247, 0xD247, 0xD247, 0xDA66, 0xDA66, 0xDA65, 0xDA85, 0xDA85, 0xE284,
0xE2A4, 0xE2A4, 0xE2A3, 0xEAC3, 0xEAC3, 0xEAE2, 0xEAE2, 0xEAE2, 0xF2E2,
0xF301, 0xF301, 0xF321, 0xF321, 0xF321, 0xF340, 0xFB40, 0xFB40, 0xFB60,
0xFB60, 0xFB80, 0xFB80, 0xFB80, 0xFBA0, 0xFBA0, 0xFBC0, 0xFBC0, 0xFBE0,
0xFBE0, 0xFBE0, 0xFC00, 0xFC00, 0xFC20, 0xFC20, 0xFC40, 0xFC40, 0xFC60,
0xFC60, 0xFC80, 0xFC80, 0xFC80, 0xFCA0, 0xFCA0, 0xFCC0, 0xFCE0, 0xFCE0,
0xFD00, 0xFD00, 0xFD20, 0xFD20, 0xFD40, 0xFD40, 0xFD40, 0xFD60, 0xFD60,
0xFD80, 0xFDA0, 0xFDA0, 0xFDC0, 0xFDC0, 0xFDC1, 0xFDE1, 0xFDE1, 0xFE01,
0xFE01, 0xFE21, 0xFE21, 0xFE41, 0xFE42, 0xFE62, 0xFE62, 0xFE62, 0xFE82,
0xFE82, 0xFE83, 0xFEA3, 0xFEA3, 0xFEC3, 0xFEC3, 0xFEC3, 0xFEE3, 0xFEE4,
0xFEE4, 0xFF04, 0xFF04, 0xFF04, 0xFF25, 0xFF25, 0xFF25, 0xFF45, 0xFF46,
0xFF46, 0xFF46, 0xFF67, 0xFF67, 0xFF67, 0xFF68, 0xFF68, 0xFF89, 0xFF89,
0xFF89, 0xFF8A, 0xFF8A, 0xFFAB, 0xFFAB, 0xFFAC, 0xFFAC, 0xFFAD, 0xFFAD,
0xFFAE, 0xFFCE, 0xFFCE, 0xFFCF, 0xFFD0, 0xFFD0, 0xFFD1, 0xFFD1, 0xFFD2,
0xFFD2, 0xFFD3, 0xFFD3, 0xFFD4, 0xFFD4, 0xFFD5, 0xFFF5, 0xFFF6, 0xFFF6,
0xFFF7, 0xFFF7, 0xFFF8, 0xFFF8, 0xFFF9, 0xFFF9, 0xFFF9, 0xFFFA, 0xFFFA,
0xFFFB, 0xFFFB, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFE,
0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF,
},
{
// colormap_rainbow
0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x000A,
0x002A, 0x002B, 0x004B, 0x006B, 0x008C, 0x00AC, 0x00CC, 0x00ED, 0x010D,
0x010E, 0x012E, 0x014E, 0x014F, 0x0170, 0x0190, 0x0190, 0x0191, 0x01B1,
0x01B1, 0x01B1, 0x01B2, 0x01D2, 0x01D2, 0x01F3, 0x01F3, 0x0213, 0x0214,
0x0234, 0x0234, 0x0235, 0x0255, 0x0256, 0x0276, 0x0277, 0x0277, 0x0297,
0x0297, 0x02B8, 0x02B8, 0x02D9, 0x02D9, 0x02F9, 0x02F9, 0x02FA, 0x02FA,
0x031A, 0x031A, 0x031A, 0x033B, 0x033B, 0x035B, 0x035B, 0x035B, 0x037B,
0x037B, 0x039B, 0x039B, 0x03BB, 0x03BB, 0x03DB, 0x03DB, 0x03FB, 0x03FA,
0x041A, 0x0419, 0x0439, 0x0439, 0x0438, 0x0458, 0x0457, 0x0476, 0x0C75,
0x0C94, 0x0C94, 0x0C93, 0x0C93, 0x0C92, 0x0CB1, 0x14B0, 0x14CF, 0x1CCE,
0x1CED, 0x24EC, 0x2D0B, 0x2D0A, 0x3529, 0x3D28, 0x4547, 0x4D66, 0x4D66,
0x5585, 0x5D84, 0x5DA4, 0x65A3, 0x6DC3, 0x6DC2, 0x75E2, 0x75E2, 0x7DE2,
0x8601, 0x8601, 0x8E21, 0x8E21, 0x9620, 0x9640, 0x9E40, 0xA640, 0xA660,
0xAE60, 0xAE60, 0xAE60, 0xB660, 0xBE80, 0xBE80, 0xC680, 0xC6A0, 0xC6A0,
0xCEA0, 0xCEA0, 0xD6A0, 0xD6A0, 0xDEA0, 0xDEA0, 0xDEA0, 0xE6A0, 0xE6A0,
0xE6A0, 0xE680, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE80, 0xEE81,
0xEE61, 0xF661, 0xF641, 0xF641, 0xF641, 0xF641, 0xF621, 0xF621, 0xF621,
0xFE01, 0xFDE1, 0xFDE1, 0xFDC1, 0xFDC2, 0xFDA2, 0xFD82, 0xFD62, 0xFD42,
0xFD42, 0xFD22, 0xFD22, 0xFD02, 0xFD02, 0xFCE2, 0xFCE2, 0xFCC3, 0xFCA3,
0xFC63, 0xFC43, 0xFC23, 0xFC03, 0xFBE4, 0xFBA4, 0xFB64, 0xFB44, 0xFB24,
0xFB04, 0xFAE5, 0xFAC5, 0xFA85, 0xFA65, 0xFA25, 0xF9E6, 0xF9C6, 0xF9A6,
0xF986, 0xF966, 0xF927, 0xF907, 0xF907, 0xF8E7, 0xF8E7, 0xF8E7, 0xF8E7,
0xF8C7, 0xF8C8, 0xF8C8, 0xF8C8, 0xF8C8, 0xF8C9, 0xF0C9, 0xF0C9, 0xF0C9,
0xF0CA, 0xF10A, 0xF10A, 0xF12A, 0xF14B, 0xF16B, 0xF18B, 0xF9AB, 0xF9CC,
0xFA0C, 0xFA4C, 0xFA8D, 0xFAAD, 0xFAED, 0xFAED, 0xFB0D, 0xFB2D, 0xFB2E,
0xFB2E, 0xFB6E, 0xFBAF, 0xFBCF, 0xFBEF, 0xFC10, 0xFC30, 0xFC50, 0xFC91,
0xFCB1, 0xFCF2, 0xFD12, 0xFD52, 0xFD73, 0xFD93, 0xFD93, 0xFDD4, 0xFDF4,
0xFE15, 0xFE35, 0xFE55, 0xFE76, 0xFE96, 0xFED7, 0xFED7, 0xFEF8, 0xFEF9,
0xFF19, 0xFF19, 0xFF39, 0xFF5A,
},
{
// colormap_grayscale
0x0000, 0x0000, 0x0000, 0x0000, 0x0020, 0x0020, 0x0820, 0x0820, 0x0840,
0x0840, 0x0841, 0x0841, 0x0861, 0x0861, 0x1061, 0x1061, 0x1081, 0x1081,
0x1082, 0x1082, 0x10a2, 0x10a2, 0x18a2, 0x18a2, 0x18c2, 0x18c2, 0x18c3,
0x18c3, 0x18e3, 0x18e3, 0x20e3, 0x20e3, 0x2103, 0x2103, 0x2104, 0x2104,
0x2124, 0x2124, 0x2924, 0x2924, 0x2944, 0x2944, 0x2945, 0x2945, 0x2965,
0x2965, 0x3165, 0x3165, 0x3185, 0x3185, 0x3186, 0x3186, 0x31a6, 0x31a6,
0x39a6, 0x39a6, 0x39c6, 0x39c6, 0x39c7, 0x39c7, 0x39e7, 0x39e7, 0x41e7,
0x41e7, 0x4207, 0x4207, 0x4208, 0x4208, 0x4228, 0x4228, 0x4a28, 0x4a28,
0x4a48, 0x4a48, 0x4a49, 0x4a49, 0x4a69, 0x4a69, 0x5269, 0x5269, 0x5289,
0x5289, 0x528a, 0x528a, 0x52aa, 0x52aa, 0x5aaa, 0x5aaa, 0x5aca, 0x5aca,
0x5acb, 0x5acb, 0x5aeb, 0x5aeb, 0x62eb, 0x62eb, 0x630b, 0x630b, 0x630c,
0x630c, 0x632c, 0x632c, 0x6b2c, 0x6b2c, 0x6b4c, 0x6b4c, 0x6b4d, 0x6b4d,
0x6b6d, 0x6b6d, 0x736d, 0x736d, 0x738d, 0x738d, 0x738e, 0x738e, 0x73ae,
0x73ae, 0x7bae, 0x7bae, 0x7bce, 0x7bce, 0x7bcf, 0x7bcf, 0x7bef, 0x7bef,
0x83ef, 0x83ef, 0x840f, 0x840f, 0x8410, 0x8410, 0x8430, 0x8430, 0x8c30,
0x8c30, 0x8c50, 0x8c50, 0x8c51, 0x8c51, 0x8c71, 0x8c71, 0x9471, 0x9471,
0x9491, 0x9491, 0x9492, 0x9492, 0x94b2, 0x94b2, 0x9cb2, 0x9cb2, 0x9cd2,
0x9cd2, 0x9cd3, 0x9cd3, 0x9cf3, 0x9cf3, 0xa4f3, 0xa4f3, 0xa513, 0xa513,
0xa514, 0xa514, 0xa534, 0xa534, 0xad34, 0xad34, 0xad54, 0xad54, 0xad55,
0xad55, 0xad75, 0xad75, 0xb575, 0xb575, 0xb595, 0xb595, 0xb596, 0xb596,
0xb5b6, 0xb5b6, 0xbdb6, 0xbdb6, 0xbdd6, 0xbdd6, 0xbdd7, 0xbdd7, 0xbdf7,
0xbdf7, 0xc5f7, 0xc5f7, 0xc617, 0xc617, 0xc618, 0xc618, 0xc638, 0xc638,
0xce38, 0xce38, 0xce58, 0xce58, 0xce59, 0xce59, 0xce79, 0xce79, 0xd679,
0xd679, 0xd699, 0xd699, 0xd69a, 0xd69a, 0xd6ba, 0xd6ba, 0xdeba, 0xdeba,
0xdeda, 0xdeda, 0xdedb, 0xdedb, 0xdefb, 0xdefb, 0xe6fb, 0xe6fb, 0xe71b,
0xe71b, 0xe71c, 0xe71c, 0xe73c, 0xe73c, 0xef3c, 0xef3c, 0xef5c, 0xef5c,
0xef5d, 0xef5d, 0xef7d, 0xef7d, 0xf77d, 0xf77d, 0xf79d, 0xf79d, 0xf79e,
0xf79e, 0xf7be, 0xf7be, 0xffbe, 0xffbe, 0xffde, 0xffde, 0xffdf, 0xffdf,
0xffff, 0xffff, 0xffff, 0xffff,
},
{
// colormap_ironblack
0xFFFF, 0xFFFF, 0xFFDF, 0xFFDF, 0xF7BE, 0xF7BE, 0xF79E, 0xF79E, 0xEF7D,
0xEF7D, 0xEF5D, 0xEF5D, 0xE73C, 0xE73C, 0xE71C, 0xE71C, 0xDEFB, 0xDEFB,
0xDEDB, 0xDEDB, 0xD6BA, 0xD6BA, 0xD69A, 0xD69A, 0xCE79, 0xCE79, 0xCE59,
0xCE59, 0xC638, 0xC638, 0xC618, 0xC618, 0xBDF7, 0xBDF7, 0xBDD7, 0xBDD7,
0xB5B6, 0xB5B6, 0xB596, 0xB596, 0xAD75, 0xAD75, 0xAD55, 0xAD55, 0xA534,
0xA534, 0xA514, 0xA514, 0x9CF3, 0x9CF3, 0x9CD3, 0x9CD3, 0x94B2, 0x94B2,
0x9492, 0x9492, 0x8C71, 0x8C71, 0x8C51, 0x8C51, 0x8430, 0x8430, 0x8410,
0x8410, 0x7BEF, 0x7BEF, 0x7BCF, 0x7BCF, 0x73AE, 0x73AE, 0x738E, 0x738E,
0x6B6D, 0x6B6D, 0x6B4D, 0x6B4D, 0x632C, 0x632C, 0x630C, 0x630C, 0x5AEB,
0x5AEB, 0x5ACB, 0x5ACB, 0x52AA, 0x52AA, 0x528A, 0x528A, 0x4A69, 0x4A69,
0x4A49, 0x4A49, 0x4228, 0x4228, 0x4208, 0x4208, 0x39E7, 0x39E7, 0x39C7,
0x39C7, 0x31A6, 0x31A6, 0x3186, 0x3186, 0x2965, 0x2965, 0x2945, 0x2945,
0x2124, 0x2124, 0x2104, 0x2104, 0x18E3, 0x18E3, 0x18C3, 0x18C3, 0x10A2,
0x10A2, 0x1082, 0x1082, 0x0861, 0x0861, 0x0841, 0x0841, 0x0020, 0x0020,
0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0003, 0x0804, 0x0805, 0x0806,
0x0807, 0x1008, 0x1009, 0x100A, 0x100B, 0x180C, 0x180C, 0x180D, 0x180E,
0x200F, 0x280F, 0x280F, 0x300F, 0x380F, 0x380F, 0x400F, 0x400F, 0x4810,
0x5010, 0x5010, 0x5810, 0x6010, 0x6010, 0x6810, 0x6810, 0x7011, 0x7811,
0x7811, 0x8011, 0x8011, 0x8811, 0x9011, 0x9031, 0x9831, 0x9831, 0xA031,
0xA031, 0xA831, 0xB031, 0xB031, 0xB831, 0xB851, 0xB870, 0xC08F, 0xC08F,
0xC0AE, 0xC8CD, 0xC8ED, 0xC8EC, 0xC90B, 0xD12B, 0xD14A, 0xD14A, 0xD969,
0xD988, 0xD9A8, 0xD9A7, 0xE1C6, 0xE1E5, 0xE205, 0xE205, 0xE224, 0xE244,
0xE264, 0xE284, 0xE2A3, 0xEAC3, 0xEAE3, 0xEAE2, 0xEB02, 0xEB22, 0xEB41,
0xEB61, 0xEB81, 0xF3A1, 0xF3A1, 0xF3C1, 0xF3E1, 0xF401, 0xF421, 0xF441,
0xF461, 0xF481, 0xF4A1, 0xF4C1, 0xF4E1, 0xF501, 0xF501, 0xF521, 0xF541,
0xFD61, 0xFD81, 0xFDA2, 0xFDC2, 0xFDE2, 0xFE02, 0xFE22, 0xFE22, 0xFE42,
0xFE63, 0xFE83, 0xFEA3, 0xFEC3, 0xFEE3, 0xFF03, 0xFF04, 0xFF26, 0xFF28,
0xFF4A, 0xFF4B, 0xFF6D, 0xFF6F, 0xFF91, 0xFF92, 0xFFB4, 0xFFB6, 0xFFD8,
0xFFD9, 0xFFDB, 0xFFFD, 0xFFE3,
},
{
// colormap_cam
0x480F, 0x400F, 0x400F, 0x400F, 0x4010, 0x3810, 0x3810, 0x3810, 0x3810,
0x3010, 0x3010, 0x3010, 0x2810, 0x2810, 0x2810, 0x2810, 0x2010, 0x2010,
0x2010, 0x1810, 0x1810, 0x1811, 0x1811, 0x1011, 0x1011, 0x1011, 0x0811,
0x0811, 0x0811, 0x0011, 0x0011, 0x0011, 0x0011, 0x0011, 0x0031, 0x0031,
0x0051, 0x0072, 0x0072, 0x0092, 0x00B2, 0x00B2, 0x00D2, 0x00F2, 0x00F2,
0x0112, 0x0132, 0x0152, 0x0152, 0x0172, 0x0192, 0x0192, 0x01B2, 0x01D2,
0x01F3, 0x01F3, 0x0213, 0x0233, 0x0253, 0x0253, 0x0273, 0x0293, 0x02B3,
0x02D3, 0x02D3, 0x02F3, 0x0313, 0x0333, 0x0333, 0x0353, 0x0373, 0x0394,
0x03B4, 0x03D4, 0x03D4, 0x03F4, 0x0414, 0x0434, 0x0454, 0x0474, 0x0474,
0x0494, 0x04B4, 0x04D4, 0x04F4, 0x0514, 0x0534, 0x0534, 0x0554, 0x0554,
0x0574, 0x0574, 0x0573, 0x0573, 0x0573, 0x0572, 0x0572, 0x0572, 0x0571,
0x0591, 0x0591, 0x0590, 0x0590, 0x058F, 0x058F, 0x058F, 0x058E, 0x05AE,
0x05AE, 0x05AD, 0x05AD, 0x05AD, 0x05AC, 0x05AC, 0x05AB, 0x05CB, 0x05CB,
0x05CA, 0x05CA, 0x05CA, 0x05C9, 0x05C9, 0x05C8, 0x05E8, 0x05E8, 0x05E7,
0x05E7, 0x05E6, 0x05E6, 0x05E6, 0x05E5, 0x05E5, 0x0604, 0x0604, 0x0604,
0x0603, 0x0603, 0x0602, 0x0602, 0x0601, 0x0621, 0x0621, 0x0620, 0x0620,
0x0620, 0x0620, 0x0E20, 0x0E20, 0x0E40, 0x1640, 0x1640, 0x1E40, 0x1E40,
0x2640, 0x2640, 0x2E40, 0x2E60, 0x3660, 0x3660, 0x3E60, 0x3E60, 0x3E60,
0x4660, 0x4660, 0x4E60, 0x4E80, 0x5680, 0x5680, 0x5E80, 0x5E80, 0x6680,
0x6680, 0x6E80, 0x6EA0, 0x76A0, 0x76A0, 0x7EA0, 0x7EA0, 0x86A0, 0x86A0,
0x8EA0, 0x8EC0, 0x96C0, 0x96C0, 0x9EC0, 0x9EC0, 0xA6C0, 0xAEC0, 0xAEC0,
0xB6E0, 0xB6E0, 0xBEE0, 0xBEE0, 0xC6E0, 0xC6E0, 0xCEE0, 0xCEE0, 0xD6E0,
0xD700, 0xDF00, 0xDEE0, 0xDEC0, 0xDEA0, 0xDE80, 0xDE80, 0xE660, 0xE640,
0xE620, 0xE600, 0xE5E0, 0xE5C0, 0xE5A0, 0xE580, 0xE560, 0xE540, 0xE520,
0xE500, 0xE4E0, 0xE4C0, 0xE4A0, 0xE480, 0xE460, 0xEC40, 0xEC20, 0xEC00,
0xEBE0, 0xEBC0, 0xEBA0, 0xEB80, 0xEB60, 0xEB40, 0xEB20, 0xEB00, 0xEAE0,
0xEAC0, 0xEAA0, 0xEA80, 0xEA60, 0xEA40, 0xF220, 0xF200, 0xF1E0, 0xF1C0,
0xF1A0, 0xF180, 0xF160, 0xF140, 0xF100, 0xF0E0, 0xF0C0, 0xF0A0, 0xF080,
0xF060, 0xF040, 0xF020, 0xF800,
}};
static constexpr const size_t color_map_table_len =
SIZEOF_ARRAY(color_map_table);
static constexpr const lgfx::swap565_t icon_cloud565[][16 * 14] = {
{
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x031b, 0xaa54, 0x4d6d, 0xaa54, 0x031b, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xaa54, 0x1086, 0xf085, 0x4d6d, 0xf085, 0x1086, 0xaa54, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xa633, 0x1086, 0x694c,
0x2002, 0x2002, 0x2002, 0x694c, 0x1086, 0xa633, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0xcf7d, 0x4d6d, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x4d6d, 0xcf7d, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x4002, 0x694c, 0x1086, 0xe73b, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xe73b, 0x1086, 0x694c, 0x4002, 0x2002, 0x2002, 0x2002, 0xae75, 0x1086,
0x0c65, 0x852b, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x852b, 0x0c65,
0x1086, 0xae75, 0x2002, 0x2002, 0xc633, 0x1086, 0xc212, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xc212, 0x1086,
0xc633, 0x2002, 0x494c, 0x1086, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x1086, 0x494c, 0x2002,
0x031b, 0x1086, 0x694c, 0x4002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x4002, 0x694c, 0x1086, 0x031b, 0x2002, 0x2002, 0x494c,
0x1086, 0x1086, 0x1086, 0x2002, 0x4002, 0x210e, 0x4002, 0x2002, 0x1086,
0x1086, 0x1086, 0x494c, 0x2002, 0x2002, 0x2002, 0x2002, 0x810a, 0x652b,
0x652b, 0x4002, 0x010f, 0xe217, 0x010f, 0x4002, 0x652b, 0x652b, 0x810a,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xa002,
0x2003, 0xe217, 0x2003, 0xa002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xe217,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x031b, 0xaa54, 0x4d6d, 0xaa54, 0x031b, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xaa54, 0x1086, 0xf085, 0x4d6d, 0xf085, 0x1086, 0xaa54, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xa633, 0x1086, 0x694c,
0x2002, 0x2002, 0x2002, 0x694c, 0x1086, 0xa633, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0xcf7d, 0x4d6d, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x4d6d, 0xcf7d, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x4002, 0x694c, 0x1086, 0xe73b, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xe73b, 0x1086, 0x694c, 0x4002, 0x2002, 0x2002, 0x2002, 0xae75, 0x1086,
0x0c65, 0x852b, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x852b, 0x0c65,
0x1086, 0xae75, 0x2002, 0x2002, 0xc633, 0x1086, 0xc212, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xc212, 0x1086,
0xc633, 0x2002, 0x494c, 0x1086, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x1086, 0x494c, 0x2002,
0x031b, 0x1086, 0x694c, 0x4002, 0x2002, 0x2002, 0x2002, 0x610d, 0x2002,
0x2002, 0x2002, 0x4002, 0x694c, 0x1086, 0x031b, 0x2002, 0x2002, 0x494c,
0x1086, 0x1086, 0x1086, 0x2002, 0x810e, 0xe217, 0x810e, 0x2002, 0x1086,
0x1086, 0x1086, 0x494c, 0x2002, 0x2002, 0x2002, 0x2002, 0x810a, 0x652b,
0x652b, 0xe002, 0xe003, 0xe217, 0xe003, 0xe002, 0x652b, 0x652b, 0x810a,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0xe217, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xe217,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x031b, 0xaa54, 0x4d6d, 0xaa54, 0x031b, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xaa54, 0x1086, 0xf085, 0x4d6d, 0xf085, 0x1086, 0xaa54, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xa633, 0x1086, 0x694c,
0x2002, 0x2002, 0x2002, 0x694c, 0x1086, 0xa633, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0xcf7d, 0x4d6d, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x4d6d, 0xcf7d, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x4002, 0x694c, 0x1086, 0xe73b, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xe73b, 0x1086, 0x694c, 0x4002, 0x2002, 0x2002, 0x2002, 0xae75, 0x1086,
0x0c65, 0x852b, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x852b, 0x0c65,
0x1086, 0xae75, 0x2002, 0x2002, 0xc633, 0x1086, 0xc212, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xc212, 0x1086,
0xc633, 0x2002, 0x494c, 0x1086, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xa004, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x1086, 0x494c, 0x2002,
0x031b, 0x1086, 0x694c, 0x4002, 0x2002, 0x2002, 0x010e, 0xe217, 0x010e,
0x2002, 0x2002, 0x4002, 0x694c, 0x1086, 0x031b, 0x2002, 0x2002, 0x494c,
0x1086, 0x1086, 0x1086, 0x2003, 0xa004, 0xe217, 0xa004, 0x2003, 0x1086,
0x1086, 0x1086, 0x494c, 0x2002, 0x2002, 0x2002, 0x2002, 0x810a, 0x652b,
0x652b, 0x2002, 0x2002, 0xe217, 0x2002, 0x2002, 0x652b, 0x652b, 0x810a,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0xe217, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xe003,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x031b, 0xaa54, 0x4d6d, 0xaa54, 0x031b, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xaa54, 0x1086, 0xf085, 0x4d6d, 0xf085, 0x1086, 0xaa54, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xa633, 0x1086, 0x694c,
0x2002, 0x2002, 0x2002, 0x694c, 0x1086, 0xa633, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0xcf7d, 0x4d6d, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x4d6d, 0xcf7d, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x4002, 0x694c, 0x1086, 0xe73b, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xe73b, 0x1086, 0x694c, 0x4002, 0x2002, 0x2002, 0x2002, 0xae75, 0x1086,
0x0c65, 0x852b, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x852b, 0x0c65,
0x1086, 0xae75, 0x2002, 0x2002, 0xc633, 0x1086, 0xc212, 0x2002, 0x2002,
0x2002, 0x2002, 0xe003, 0x2002, 0x2002, 0x2002, 0x2002, 0xc212, 0x1086,
0xc633, 0x2002, 0x494c, 0x1086, 0x2002, 0x2002, 0x2002, 0x2002, 0x610d,
0xe217, 0x610d, 0x2002, 0x2002, 0x2002, 0x2002, 0x1086, 0x494c, 0x2002,
0x031b, 0x1086, 0x694c, 0x4002, 0x2002, 0x4003, 0x610d, 0xe217, 0x610d,
0x4003, 0x2002, 0x4002, 0x694c, 0x1086, 0x031b, 0x2002, 0x2002, 0x494c,
0x1086, 0x1086, 0x1086, 0x2002, 0x2002, 0xe217, 0x2002, 0x2002, 0x1086,
0x1086, 0x1086, 0x494c, 0x2002, 0x2002, 0x2002, 0x2002, 0x810a, 0x652b,
0x652b, 0x2002, 0x2002, 0xe217, 0x2002, 0x2002, 0x652b, 0x652b, 0x810a,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0xa004, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x4633, 0xb39d, 0x78c6, 0xb39d, 0x4633, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x7295, 0x7def, 0x5def, 0x78c6, 0x5def, 0x7def, 0x7295, 0x6002, 0xc002,
0x6002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2b5c, 0x7def, 0x3085,
0x2002, 0x2002, 0x2002, 0x3085, 0x9bdf, 0xa426, 0x0006, 0x4003, 0x2002,
0x2002, 0x2002, 0x4002, 0xe002, 0x19cf, 0x78c6, 0x2002, 0x2002, 0x2002,
0x2002, 0x8002, 0x694f, 0xa847, 0xe005, 0x8002, 0x2002, 0x2002, 0x2002,
0xe002, 0x052f, 0xca57, 0xaa54, 0x2002, 0x2002, 0x2002, 0x8002, 0xc005,
0xc426, 0xca57, 0xb18d, 0x610a, 0x2002, 0x2002, 0x4002, 0xf9ce, 0xcb5f,
0x473f, 0x831e, 0xc002, 0x2002, 0x8002, 0xc005, 0x0006, 0x831e, 0x339e,
0x7def, 0xfad6, 0x4002, 0x2002, 0x4c64, 0x7def, 0x452b, 0xc005, 0x0006,
0xe005, 0x2003, 0xc005, 0x0006, 0xe005, 0xa002, 0x2002, 0x052b, 0x7def,
0x4c64, 0x2002, 0x1085, 0x7def, 0x2002, 0x6002, 0xc005, 0x0006, 0x2007,
0x2006, 0xe005, 0xa002, 0x2002, 0x2002, 0x2002, 0x7def, 0x1085, 0x2002,
0x673b, 0x7def, 0x318d, 0x410a, 0x6002, 0xe005, 0x6007, 0x4006, 0xa002,
0x2002, 0x2002, 0x410a, 0x518d, 0x7def, 0x673b, 0x2002, 0x2002, 0x1085,
0x7def, 0x7def, 0x7def, 0x7ce7, 0x9ad7, 0x7ce7, 0x7def, 0x7def, 0x7def,
0x7def, 0x7def, 0x1085, 0x2002, 0x2002, 0x2002, 0x2002, 0xa212, 0xc94b,
0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xa212,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x4093, 0x00fc, 0x00fc, 0x00fc, 0x4093, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x0002, 0xe021,
0x80e3, 0x00fc, 0x60ab, 0xe06a, 0x60ab, 0x00fc, 0xa0e3, 0xe021, 0x000a,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xe019, 0x00d9, 0x60f9, 0x4052,
0x2002, 0x2002, 0x2002, 0x604a, 0x60f9, 0x00d1, 0xa031, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x000a, 0x80f9, 0x20e1, 0xa0a0, 0xe019, 0x2002,
0x0012, 0xc0a0, 0x20e1, 0x60f9, 0xe011, 0x2002, 0x2002, 0x2002, 0x2002,
0x803a, 0xe0eb, 0xc0fb, 0x20c9, 0xa0a8, 0xa0a0, 0xc029, 0xc0a0, 0xa0a8,
0x00c9, 0xa0fb, 0xe0eb, 0x803a, 0x2002, 0x2002, 0x401a, 0x00fc, 0xc0db,
0xc05a, 0x603a, 0xc098, 0xa0a8, 0x40d8, 0xa0b0, 0xc0a0, 0x4042, 0xc05a,
0xc0db, 0x00fc, 0x401a, 0x2002, 0x0083, 0x00fc, 0x2002, 0x2002, 0x2002,
0xe019, 0x40d8, 0x20e0, 0x20e0, 0xa031, 0x2002, 0x2002, 0x2002, 0x00fc,
0x0083, 0x2002, 0x0083, 0x00fc, 0x2002, 0x2002, 0x0012, 0xc0a0, 0xa0a8,
0x40e0, 0xa0b0, 0xa0a0, 0xe019, 0x2002, 0x2002, 0x00fc, 0x0083, 0x2002,
0x401a, 0x00fc, 0xc0db, 0x8062, 0xe0b8, 0xe0c0, 0x00c1, 0x6072, 0x00c1,
0xe0c0, 0xe0c0, 0x6062, 0xc0db, 0x00fc, 0x401a, 0x2002, 0x2002, 0x803a,
0xa0eb, 0x60f9, 0x40f9, 0x60f9, 0xa0fb, 0x00fc, 0xc0fb, 0x80f9, 0x40f9,
0x60f9, 0x80eb, 0x803a, 0x2002, 0x2002, 0x2002, 0x2002, 0xe021, 0xa0a8,
0xc0a0, 0xe011, 0x2002, 0x2002, 0x2002, 0x000a, 0xc098, 0xa0a8, 0xa031,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x0002, 0xe011, 0x000a, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x0002, 0xe011, 0x0002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x4633, 0xb39d, 0x78c6, 0xb39d, 0x4633, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x7295, 0x7def, 0x5def, 0x78c6, 0x5def, 0x7def, 0x7295, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2b5c, 0x7def, 0x3085,
0x2002, 0x2002, 0x2002, 0x3085, 0x7def, 0x2b5c, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x1bdf, 0x78c6, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x78c6, 0x1bdf, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x610a, 0x318d, 0x7def, 0x8d6c, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x8d6c, 0x7def, 0x318d, 0x610a, 0x2002, 0x2002, 0x4002, 0xfad6, 0x7def,
0x36b6, 0x0a54, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x0a54, 0x36b6,
0x7def, 0xfad6, 0x4002, 0x2002, 0x4c64, 0x7def, 0x052b, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x052b, 0x7def,
0x4c64, 0x2002, 0x1085, 0x7def, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x7def, 0x1085, 0x2002,
0x673b, 0x7def, 0x318d, 0x410a, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x410a, 0x518d, 0x7def, 0x673b, 0x2002, 0x2002, 0x1085,
0x7def, 0x7def, 0x7def, 0x7def, 0x7def, 0x7def, 0x7def, 0x7def, 0x7def,
0x7def, 0x7def, 0x1085, 0x2002, 0x2002, 0x2002, 0x2002, 0xa212, 0xc94b,
0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xc94b, 0xa212,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
},
};
static constexpr const lgfx::swap565_t icon_wifi565[][16 * 14] = {
{
0x2002, 0x2002, 0x6112, 0x6112, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xe642,
0xe5a9, 0x84b9, 0x097b, 0x6a6b, 0x074b, 0x621a, 0x2002, 0x0012, 0xe088,
0x0081, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x400a, 0x2199, 0xc1b0,
0xe1b8, 0xc762, 0x6a6b, 0x6a6b, 0xe862, 0xc0a0, 0xa0a8, 0xc098, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x000a, 0xc098, 0xa0a8, 0xa0a0,
0xe019, 0x8442, 0x43c9, 0x23c9, 0xe1b0, 0xe011, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0xa42a, 0x6a6b, 0x2973, 0x43c1, 0x02c1, 0xc0b0, 0xa0a8,
0xc0a8, 0x23c1, 0x2973, 0x8322, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x410a, 0xc53a, 0xe63a, 0xe75a, 0x23c9, 0x61e8, 0x60e8, 0xa0a8, 0x0012,
0x495b, 0x6a6b, 0x410a, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x0012, 0xc0a0, 0x40e0, 0x61e8, 0x02c1, 0xe019, 0x400a, 0x6a6b,
0x285b, 0x2002, 0x2002, 0x2002, 0x2002, 0x821a, 0x495b, 0x086b, 0x02b9,
0xc0a8, 0xa0a8, 0xe1b0, 0x23c9, 0x02b9, 0xe019, 0xa432, 0x6a6b, 0x621a,
0x2002, 0x2002, 0x2002, 0x821a, 0xe862, 0x23c1, 0x23c9, 0x23c9, 0x6332,
0x000a, 0x02b1, 0x23c9, 0xc0a8, 0xe019, 0x6a6b, 0x074b, 0x2002, 0x2002,
0x2002, 0x2002, 0x0089, 0xa0a8, 0xc0a0, 0x086b, 0x6a6b, 0x410a, 0x000a,
0x43c1, 0x02c1, 0xc098, 0x074b, 0x6a6b, 0x2002, 0x2002, 0x2002, 0x2002,
0x20c2, 0xe0d9, 0x001a, 0x410a, 0x6a6b, 0xe642, 0x2002, 0xe75a, 0xa5b1,
0x2079, 0xc432, 0x6a6b, 0x2002, 0x2002, 0x2002, 0x608b, 0x80fc, 0x80fc,
0x608b, 0x2002, 0x285b, 0x4963, 0x2002, 0xe63a, 0x6a6b, 0x2002, 0x8322,
0x6a6b, 0x6112, 0x2002, 0x2002, 0x608b, 0x80fc, 0x80fc, 0x608b, 0x2002,
0x2853, 0x495b, 0x2002, 0xc53a, 0x6a6b, 0x2002, 0x8322, 0x6a6b, 0x6112,
0x2002, 0x2002, 0x2002, 0x608b, 0x608b, 0x2002, 0x2002, 0x821a, 0x821a,
0x2002, 0x410a, 0xa42a, 0x2002, 0x400a, 0xe642, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x6112, 0x6112, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xe642,
0x6a6b, 0x6a6b, 0x6a6b, 0x6a6b, 0x074b, 0x621a, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x400a, 0x8322, 0x8322,
0xc432, 0x074b, 0x6a6b, 0x6a6b, 0x285b, 0x410a, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0xa432, 0x6a6b, 0x6a6b, 0x8322, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0xa42a, 0x6a6b, 0x6a6b, 0x496b, 0x074b, 0x4112, 0x2002,
0x400a, 0x495b, 0x6a6b, 0x8322, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x410a, 0xc53a, 0xe63a, 0x2853, 0x6a6b, 0x6a6b, 0x074b, 0x2002, 0x2002,
0x495b, 0x6a6b, 0x410a, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0xe642, 0x6a6b, 0x285b, 0x2002, 0x400a, 0x6a6b,
0x285b, 0x2002, 0x2002, 0x2002, 0x2002, 0x821a, 0x495b, 0x4963, 0xe642,
0x410a, 0x2002, 0xa42a, 0x6a6b, 0x074b, 0x2002, 0xa432, 0x6a6b, 0x621a,
0x2002, 0x2002, 0x2002, 0x821a, 0x2853, 0x285b, 0x6a6b, 0x6a6b, 0x8322,
0x2002, 0xe642, 0x6a6b, 0x4112, 0x2002, 0x6a6b, 0x074b, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x410a, 0x4963, 0x6a6b, 0x410a, 0x2002,
0x6a6b, 0x074b, 0x2002, 0x074b, 0x6a6b, 0x2002, 0x2002, 0x2002, 0x2002,
0x608b, 0x608b, 0x2002, 0x410a, 0x6a6b, 0xe642, 0x2002, 0x2853, 0x496b,
0x2002, 0xc432, 0x6a6b, 0x2002, 0x2002, 0x2002, 0x608b, 0x80fc, 0x80fc,
0x608b, 0x2002, 0x285b, 0x4963, 0x2002, 0xe63a, 0x6a6b, 0x2002, 0x8322,
0x6a6b, 0x6112, 0x2002, 0x2002, 0x608b, 0x80fc, 0x80fc, 0x608b, 0x2002,
0x2853, 0x495b, 0x2002, 0xc53a, 0x6a6b, 0x2002, 0x8322, 0x6a6b, 0x6112,
0x2002, 0x2002, 0x2002, 0x608b, 0x608b, 0x2002, 0x2002, 0x821a, 0x821a,
0x2002, 0x410a, 0xa42a, 0x2002, 0x400a, 0xe642, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x6112, 0x6112, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xe642,
0x6a6b, 0x6a6b, 0x6a6b, 0x6a6b, 0x074b, 0x621a, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x400a, 0x8322, 0x8322,
0xc432, 0x074b, 0x6a6b, 0x6a6b, 0x285b, 0x410a, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0xa432, 0x6a6b, 0x6a6b, 0x8322, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0xa42a, 0x6a6b, 0x6a6b, 0x496b, 0x074b, 0x4112, 0x2002,
0x400a, 0x495b, 0x6a6b, 0x8322, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x410a, 0xc53a, 0xe63a, 0x2853, 0x6a6b, 0x6a6b, 0x074b, 0x2002, 0x2002,
0x495b, 0x6a6b, 0x410a, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0xe642, 0x6a6b, 0x285b, 0x2002, 0x400a, 0x6a6b,
0x285b, 0x2002, 0x2002, 0x2002, 0x2002, 0x821a, 0x495b, 0x4963, 0xe642,
0x410a, 0x2002, 0xa42a, 0x6a6b, 0x074b, 0x2002, 0xa432, 0x6a6b, 0x621a,
0x2002, 0x2002, 0x2002, 0x821a, 0x2853, 0x285b, 0x6a6b, 0x6a6b, 0x8322,
0x2002, 0xe642, 0x6a6b, 0x4112, 0x2002, 0x6a6b, 0x074b, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x410a, 0x4963, 0x6a6b, 0x410a, 0x2002,
0x6a6b, 0x074b, 0x2002, 0x074b, 0x6a6b, 0x2002, 0x2002, 0x2002, 0x2002,
0xd17c, 0xd17c, 0x2002, 0x410a, 0x6a6b, 0xe642, 0x2002, 0x2853, 0x496b,
0x2002, 0xc432, 0x6a6b, 0x2002, 0x2002, 0x2002, 0xd17c, 0xdfde, 0xdfde,
0xd17c, 0x2002, 0x285b, 0x4963, 0x2002, 0xe63a, 0x6a6b, 0x2002, 0x8322,
0x6a6b, 0x6112, 0x2002, 0x2002, 0xd17c, 0xdfde, 0xdfde, 0xd17c, 0x2002,
0x2853, 0x495b, 0x2002, 0xc53a, 0x6a6b, 0x2002, 0x8322, 0x6a6b, 0x6112,
0x2002, 0x2002, 0x2002, 0xd17c, 0xd17c, 0x2002, 0x2002, 0x821a, 0x821a,
0x2002, 0x410a, 0xa42a, 0x2002, 0x400a, 0xe642, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x6112, 0x6112, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xe642,
0x6a6b, 0x6a6b, 0x6a6b, 0x6a6b, 0x074b, 0x621a, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x400a, 0x8322, 0x8322,
0xc432, 0x074b, 0x6a6b, 0x6a6b, 0x285b, 0x410a, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0xa432, 0x6a6b, 0x6a6b, 0x8322, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0xa42a, 0x6a6b, 0x6a6b, 0x496b, 0x074b, 0x4112, 0x2002,
0x400a, 0x495b, 0x6a6b, 0x8322, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x410a, 0xc53a, 0xe63a, 0x2853, 0x6a6b, 0x6a6b, 0x074b, 0x2002, 0x2002,
0x495b, 0x6a6b, 0x410a, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0xe642, 0x6a6b, 0x285b, 0x2002, 0x400a, 0x6a6b,
0x285b, 0x2002, 0x2002, 0x2002, 0x2002, 0x683b, 0x5cc6, 0x5cc6, 0x138d,
0xa31a, 0x2002, 0xa42a, 0x6a6b, 0x074b, 0x2002, 0xa432, 0x6a6b, 0x621a,
0x2002, 0x2002, 0x2002, 0x683b, 0xf9b5, 0x3bc6, 0xdfde, 0xdfde, 0xaa4b,
0x2002, 0xe642, 0x6a6b, 0x4112, 0x2002, 0x6a6b, 0x074b, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x8312, 0x7cce, 0xdfde, 0xa31a, 0x2002,
0x6a6b, 0x074b, 0x2002, 0x074b, 0x6a6b, 0x2002, 0x2002, 0x2002, 0x2002,
0xd17c, 0xd17c, 0x2002, 0x8312, 0xdfde, 0x138d, 0x2002, 0x2853, 0x496b,
0x2002, 0xc432, 0x6a6b, 0x2002, 0x2002, 0x2002, 0xd17c, 0xdfde, 0xdfde,
0xd17c, 0x2002, 0x3bc6, 0x5cc6, 0x2002, 0xe63a, 0x6a6b, 0x2002, 0x8322,
0x6a6b, 0x6112, 0x2002, 0x2002, 0xd17c, 0xdfde, 0xdfde, 0xd17c, 0x2002,
0xf9b5, 0x5cc6, 0x2002, 0xc53a, 0x6a6b, 0x2002, 0x8322, 0x6a6b, 0x6112,
0x2002, 0x2002, 0x2002, 0xd17c, 0xd17c, 0x2002, 0x2002, 0x683b, 0x683b,
0x2002, 0x410a, 0xa42a, 0x2002, 0x400a, 0xe642, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x6112, 0x6112, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0xe642,
0x6a6b, 0x6a6b, 0x6a6b, 0x6a6b, 0x074b, 0x621a, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x400a, 0x8322, 0x8322,
0xc432, 0x074b, 0x6a6b, 0x6a6b, 0x285b, 0x410a, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0xa432, 0x6a6b, 0x6a6b, 0x8322, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x0d5c, 0xdfde, 0xdfde, 0xbfd6, 0x759d, 0xe522, 0x2002,
0x400a, 0x495b, 0x6a6b, 0x8322, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xc422, 0xd17c, 0xf284, 0xf9b5, 0xdfde, 0xdfde, 0x5595, 0x2002, 0x2002,
0x495b, 0x6a6b, 0x410a, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x4102, 0x148d, 0xdfde, 0x1abe, 0x2002, 0x400a, 0x6a6b,
0x285b, 0x2002, 0x2002, 0x2002, 0x2002, 0x683b, 0x5cc6, 0x5cc6, 0x138d,
0xa31a, 0x2002, 0x0d5c, 0xdfde, 0x5595, 0x2002, 0xa432, 0x6a6b, 0x621a,
0x2002, 0x2002, 0x2002, 0x683b, 0xf9b5, 0x3bc6, 0xdfde, 0xdfde, 0xaa4b,
0x2002, 0x148d, 0xdfde, 0xe522, 0x2002, 0x6a6b, 0x074b, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x8312, 0x7cce, 0xdfde, 0xa31a, 0x4102,
0xdfde, 0x759d, 0x2002, 0x074b, 0x6a6b, 0x2002, 0x2002, 0x2002, 0x2002,
0xd17c, 0xd17c, 0x2002, 0x8312, 0xdfde, 0x138d, 0x2002, 0xf9b5, 0xbed6,
0x2002, 0xc432, 0x6a6b, 0x2002, 0x2002, 0x2002, 0xd17c, 0xdfde, 0xdfde,
0xd17c, 0x2002, 0x3bc6, 0x5cc6, 0x2002, 0xf284, 0xdfde, 0x2002, 0x8322,
0x6a6b, 0x6112, 0x2002, 0x2002, 0xd17c, 0xdfde, 0xdfde, 0xd17c, 0x2002,
0xf9b5, 0x5cc6, 0x2002, 0xd17c, 0xdfde, 0x2002, 0x8322, 0x6a6b, 0x6112,
0x2002, 0x2002, 0x2002, 0xd17c, 0xd17c, 0x2002, 0x2002, 0x683b, 0x683b,
0x2002, 0xc422, 0x0d5c, 0x2002, 0x400a, 0xe642, 0x2002, 0x2002,
},
{
0x2002, 0x2002, 0x052b, 0x052b, 0x610a, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x148d,
0xdfde, 0xdfde, 0xdfde, 0xdfde, 0x97a5, 0x483b, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x8212, 0xeb53, 0x8943,
0x6f6c, 0x97a5, 0xdfde, 0xdfde, 0x3bbe, 0xc41a, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x4e6c, 0xdfde, 0xdfde, 0xaa4b, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x0d5c, 0xdfde, 0xdfde, 0xbfd6, 0x759d, 0xe522, 0x2002,
0x8212, 0x5cc6, 0xdfde, 0xaa4b, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0xc422, 0xd17c, 0xf284, 0xf9b5, 0xdfde, 0xdfde, 0x5595, 0x2002, 0x2002,
0x5cc6, 0xdfde, 0xc41a, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002,
0x2002, 0x2002, 0x4102, 0x148d, 0xdfde, 0x1abe, 0x2002, 0x8212, 0xdfde,
0x3bbe, 0x2002, 0x2002, 0x2002, 0x2002, 0x683b, 0x5cc6, 0x5cc6, 0x138d,
0xa31a, 0x2002, 0x0d5c, 0xdfde, 0x5595, 0x2002, 0x4e6c, 0xdfde, 0x483b,
0x2002, 0x2002, 0x2002, 0x683b, 0xf9b5, 0x3bc6, 0xdfde, 0xdfde, 0xaa4b,
0x2002, 0x148d, 0xdfde, 0xe522, 0x2002, 0xdfde, 0x97a5, 0x2002, 0x2002,
0x2002, 0x2002, 0x2002, 0x2002, 0x8312, 0x7cce, 0xdfde, 0xa31a, 0x4102,
0xdfde, 0x759d, 0x2002, 0x97a5, 0xdfde, 0x2002, 0x2002, 0x2002, 0x2002,
0xd17c, 0xd17c, 0x2002, 0x8312, 0xdfde, 0x138d, 0x2002, 0xf9b5, 0xbed6,
0x2002, 0x6f6c, 0xdfde, 0x610a, 0x2002, 0x2002, 0xd17c, 0xdfde, 0xdfde,
0xd17c, 0x2002, 0x3bc6, 0x5cc6, 0x2002, 0xf284, 0xdfde, 0x2002, 0x8943,
0xdfde, 0x052b, 0x2002, 0x2002, 0xd17c, 0xdfde, 0xdfde, 0xd17c, 0x2002,
0xf9b5, 0x5cc6, 0x2002, 0xd17c, 0xdfde, 0x2002, 0xeb53, 0xdfde, 0x052b,
0x2002, 0x2002, 0x2002, 0xd17c, 0xd17c, 0x2002, 0x2002, 0x683b, 0x683b,
0x2002, 0xc422, 0x0d5c, 0x2002, 0x8212, 0x148d, 0x2002, 0x2002,
},
};
struct framedata_t {
enum {
center,
highest,
average,
lowest,
};
uint16_t temp[4];
bool subpage;
uint16_t pixel_raw[frame_width * frame_height];
uint8_t low_x;
uint8_t low_y;
uint8_t high_x;
uint8_t high_y;
std::string getJsonData(void) const;
};
struct value_smooth_t {
int32_t exec(int32_t src, int32_t margin);
void set(int32_t default_value);
private:
int _add = 0;
int32_t _target;
int32_t _current;
};
//
struct graph_data_t {
// 256uint8_t
static constexpr const uint16_t data_len = 256;
uint16_t* temp_arrays[4] = {
nullptr,
};
uint8_t current_idx = 0;
};
extern uint8_t config_save_countdown;
struct itext_t {
virtual const char* get(void) const = 0;
inline operator const char*(void) const {
return get();
}
};
struct single_text_t : public itext_t {
const char* text;
constexpr single_text_t(const char* t1) : text{t1} {
}
const char* get(void) const override {
return text;
}
};
struct localize_text_t : public itext_t {
static uint8_t localize_index;
const char* texts[3];
constexpr localize_text_t(const char* t1, const char* t2, const char* t3)
: texts{t1, t2, t3} {
}
const char* get(void) const override {
return texts[localize_index];
}
};
//
class config_property_base_t {
public:
virtual const localize_text_t* getName(void) {
return nullptr;
}
virtual const char* getText(void) = 0;
virtual int32_t get(void) const = 0;
virtual bool set(const int32_t src) = 0;
virtual bool add(int32_t val) {
return set(get() + val);
}
};
template <typename T>
class config_property_enum_t : public config_property_base_t {
protected:
const char* const* _text_tbl;
T _value;
const T _maximum;
void (*_change_func)(T value);
public:
config_property_enum_t(const char* const* text_tbl, T value, T maximum,
void (*change_func)(T) = nullptr)
: _text_tbl{text_tbl},
_value{value},
_maximum{maximum},
_change_func{change_func} {
}
T get_enum(void) const {
return _value;
}
inline operator T(void) const {
return get_enum();
}
T operator=(T src) {
set(src);
return get_enum();
}
const char* getText(void) override {
return _text_tbl ? _text_tbl[get()] : "";
}
int32_t get(void) const override {
return _value;
}
bool set(const int32_t src) override {
T v = (T)((src < 0) ? 0
: (src < (_maximum - 1)) ? src
: (_maximum - 1));
bool result = (_value != v);
if (result) {
config_save_countdown = 255;
_value = v;
}
if (_change_func) {
_change_func(v);
}
return result;
}
bool add(int32_t val) override {
return set((val + _maximum + get()) % _maximum);
}
};
template <typename T>
class config_property_localize_enum_t : public config_property_base_t {
protected:
const localize_text_t _name;
const localize_text_t* _text_tbl;
T _default;
T _value;
const T _maximum;
void (*_change_func)(T value);
public:
config_property_localize_enum_t(const localize_text_t name,
const localize_text_t* text_tbl, T value,
T maximum, void (*change_func)(T) = nullptr)
: _name{name},
_text_tbl{text_tbl},
_default{value},
_value{value},
_maximum{maximum},
_change_func{change_func} {
}
bool setDefault(void) {
return set(_default);
}
T get_enum(void) const {
return _value;
}
inline operator T(void) const {
return get_enum();
}
T operator=(T src) {
set(src);
return get_enum();
}
const localize_text_t* getName(void) override {
return &_name;
}
const char* getText(void) override {
return _text_tbl[get()].get();
}
const char* getText(size_t idx) {
return _text_tbl[idx].get();
}
int32_t get(void) const override {
return _value;
}
bool set(const int32_t src) override {
T v = (T)((src < 0) ? 0
: (src < (_maximum - 1)) ? src
: (_maximum - 1));
bool result = (_value != v);
if (result) {
config_save_countdown = 255;
_value = v;
}
if (_change_func) {
_change_func(v);
}
return result;
}
bool add(int32_t val) override {
return set((val + _maximum + get()) % _maximum);
}
};
template <typename T>
class config_property_value_t : public config_property_base_t {
protected:
void (*_text_func)(char* text_buf, size_t buf_len, T value);
T _value;
const T _minimum;
const T _maximum;
const T _step;
void (*_change_func)(T value);
char _text_buf[16] = "";
public:
config_property_value_t(void (*text_func)(char*, size_t, T), T value,
T minimum, T maximum, T step,
void (*change_func)(T) = nullptr)
: _text_func{text_func},
_value{value},
_minimum{minimum},
_maximum{maximum},
_step{step},
_change_func{change_func} {
_text_func(_text_buf, sizeof(_text_buf), value);
}
inline operator int32_t(void) const {
return get();
}
int32_t operator=(int32_t src) {
set(src);
return get();
}
const char* getText(void) override {
return _text_buf;
}
int32_t get(void) const override {
return _value;
}
bool set(const int32_t src) override {
T v = (T)((src < _minimum) ? _minimum
: (src < _maximum + 1) ? src
: _maximum + 1);
bool result = (_value != v);
if (result) {
config_save_countdown = 255;
_value = (T)v;
}
_text_func(_text_buf, sizeof(_text_buf), v);
if (_change_func) {
_change_func(v);
}
return result;
}
bool add(int32_t val) override {
auto range = _maximum - _minimum + 1;
val = (val * _step + get() + range - _minimum) % range;
return set(val + _minimum);
}
};
struct config_param_t {
void saveNvs(void);
void loadNvs(void);
void loadDefault(void);
void setEmissivity(uint8_t emissivity);
void setTimeZoneSec(int32_t sec);
void referenceModeChange(int add = 0);
static constexpr const char* common_off_on_text[] = {"Off", "On"};
enum net_running_mode_t {
net_running_mode_offline, // 0
net_running_mode_cloud, // 1
net_running_mode_lan, // 2
net_running_mode_lan_cloud, // 3
net_running_mode_max,
};
// static constexpr const localize_text_t net_running_mode_text[] =
// { { "Offline" , "" , "" },
// { "Cloud Online", "" , "" },
// { "LAN" , "" , "LAN" },
// { "LAN+Cloud" , "+", "LAN+"},
// };
enum net_setup_mode_t {
net_setup_mode_off,
net_setup_mode_smartconfig,
net_setup_mode_accesspoint,
// net_wifi_mode_keep_connect,
// net_wifi_mode_uploading,
net_setup_mode_max,
};
// static constexpr const char* net_setup_mode_text[] = { "Off", "ESP TOUCH
// APP", "AP mode", "Keep connection", "OnCloud only" };
enum alarm_mode_t {
alarm_mode_off,
alarm_mode_lowtemp,
alarm_mode_hightemp,
alarm_mode_max,
};
// static constexpr const char* alarm_mode_text[] = { "Disable", "Lower",
// "Higher" };
enum alarm_reference_t {
alarm_reference_highest,
alarm_reference_lowest,
alarm_reference_center,
alarm_reference_average,
alarm_reference_max,
};
// static constexpr const char* alarm_reference_text[] = { "Highest",
// "Lowest", "Center", "Average" };
/*
enum alarm_behavior_t {
alarm_behavior_off,
alarm_behavior_beep,
alarm_behavior_led,
alarm_behavior_beep_led,
alarm_behavior_max,
};
static constexpr const char* alarm_behavior_text[] = { "Off", "BEEP",
"LED", "BEEP+LED" };
*/
enum misc_cpuspeed_t {
misc_cpuspeed_80,
misc_cpuspeed_160,
misc_cpuspeed_240,
misc_cpuspeed_max,
};
// static constexpr const char* misc_cpuspeed_text[] = { "80MHz", "160MHz",
// "240MHz" };
static constexpr const uint8_t misc_cpuspeed_value[] = {80, 160, 240};
enum sens_refreshrate_t {
sens_refreshrate_0_5,
sens_refreshrate_1,
sens_refreshrate_2,
sens_refreshrate_4,
sens_refreshrate_8,
sens_refreshrate_16,
sens_refreshrate_32,
sens_refreshrate_max,
};
// static constexpr const char* sens_refreshrate_text[] = { "0.5Hz", "1Hz",
// "2Hz", "4Hz", "8Hz", "16Hz", "32Hz" };
static constexpr const uint8_t sens_refreshrate_value[] = {0, 1, 2, 3,
4, 5, 6};
enum sens_noisefilter_t {
sens_noisefilter_off,
sens_noisefilter_weak,
sens_noisefilter_medium,
sens_noisefilter_strong,
sens_noisefilter_max,
};
// static constexpr const char* sens_noisefilter_text[] = { "Off", "Weak",
// "Medium", "Strong" };
static constexpr const uint8_t sens_noisefilter_value[] = {0, 4, 8, 12};
enum sens_monitorarea_t {
sens_monitorarea_16x16,
sens_monitorarea_20x20,
sens_monitorarea_24x24,
sens_monitorarea_28x24,
sens_monitorarea_30x24,
sens_monitorarea_max,
};
// static constexpr const char* sens_monitorarea_text[] = { "16x16",
// "20x20", "24x24", "28x24", "30x24" };
static constexpr const uint8_t sens_monitorarea_value[] = {
0x88u, 0xAAu, 0xCC, 0xEC, 0xFC};
enum range_autoswitch_t {
range_autoswitch_off,
range_autoswitch_on,
range_autoswitch_max,
};
enum misc_brightness_t {
misc_brightness_low,
misc_brightness_middle,
misc_brightness_high,
misc_brightness_max,
};
// static constexpr const char* misc_brightness_text[] = { "Low", "Middle",
// "High" };
static constexpr const uint8_t misc_brightness_value[] = {63, 100, 200};
enum misc_language_t {
misc_language_en,
misc_language_cn,
misc_language_ja,
misc_language_max,
};
static constexpr const char* misc_language_text[] = {"English", "",
""};
// static constexpr const lgfx::IFont* misc_language_value[] = {
// &fonts::DejaVu12, &fonts::DejaVu18, &fonts::DejaVu24 }; static constexpr
// const lgfx::IFont* misc_language_value[] = { &fonts::efontJA_14,
// &fonts::efontJA_16, &fonts::efontJA_24 };
static constexpr const lgfx::IFont* misc_language_value[] = {
&fonts::efontCN_24, &fonts::efontCN_24, &fonts::efontJA_24};
enum misc_pointer_t {
misc_pointer_off,
misc_pointer_point,
misc_pointer_pointtxt,
misc_pointer_max,
};
// static constexpr const char* misc_pointer_text[] = { "Off", "Point",
// "Point+Value" };
enum misc_volume_t {
misc_volume_mute,
misc_volume_small,
misc_volume_normal,
misc_volume_max,
};
// static constexpr const char* misc_volume_text[] = { "Mute", "Small",
// "Normal" };
static constexpr const uint8_t misc_volume_value[] = {0, 80, 160};
// enum cloud_upload_t {
// cloud_upload_off,
// cloud_upload_on,
// cloud_upload_max,
// };
enum misc_color_t {
misc_color_golden,
misc_color_rainbow,
misc_color_grayscale,
misc_color_ironblack,
misc_color_cam,
misc_color_max,
};
enum cloud_interval_t {
cloud_interval_5sec,
cloud_interval_10sec,
cloud_interval_30sec,
cloud_interval_60sec,
cloud_interval_120sec,
cloud_interval_300sec,
cloud_interval_600sec,
cloud_interval_1800sec,
cloud_interval_3600sec,
cloud_interval_max,
};
static constexpr const uint16_t cloud_interval_value[] = {
5, 10, 30, 60, 120, 300, 600, 1800, 3600};
...
This file has been truncated, please download it to see its full contents.










Comments