Compare commits

..

1 Commits
tahoma ... main

Author SHA1 Message Date
6b83634e72 add Shutter control breaking everything 2025-11-09 11:55:18 +01:00
1807 changed files with 23464 additions and 839512 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -70,12 +70,11 @@
"arduino.h": "c",
"actions.h": "c",
"glbldata.h": "c",
"vars.h": "c"
},
"C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: WebKit, ColumnLimit: 250 }",
"C_Cpp.clang_format_style": "{ BasedOnStyle: WebKit, ColumnLimit: 250 }",
"editor.wordWrapColumn": 250,
"html.format.wrapLineLength": 250,
"C_Cpp.vcFormat.wrap.preserveBlocks": "oneLiners",
"C_Cpp.formatting": "vcFormat"
"vars.h": "c",
"fonts.h": "c",
"images.h": "c",
"tahoma.h": "c",
"httpclient.h": "c",
"base64.h": "c"
}
}

View File

@ -1,88 +0,0 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.associations": {
"styles.h": "c",
"string.h": "c",
"system_error": "cpp",
"random": "c",
"screens.h": "c",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"ratio": "cpp",
"regex": "cpp",
"string_view": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"format": "cpp",
"ui.h": "c",
"lvgl.h": "c",
"symbols.h": "c",
"arduino.h": "c",
"actions.h": "c",
"glbldata.h": "c",
"vars.h": "c"
},
"C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: WebKit, ColumnLimit: 250 }",
"C_Cpp.clang_format_style": "{ BasedOnStyle: WebKit, ColumnLimit: 250 }",
"editor.wordWrapColumn": 250,
"html.format.wrapLineLength": 250,
"C_Cpp.vcFormat.wrap.preserveBlocks": "oneLiners",
"C_Cpp.formatting": "vcFormat"
}
}

View File

@ -176,7 +176,7 @@ uint8_t TouchDrvCST92xx::getPoint(int16_t *x_array, int16_t *y_array, uint8_t ge
}
*/
for (uint8_t i = 0; i < 1; ++i) {
for (uint8_t i = 0; i < numPoints; ++i) {
uint8_t *data = read_buffer + (i * 5) + (i == 0 ? 0 : 2);
parseFingerData(data, &point_info[i]);
x_array[i] = point_info[i].x;

View File

@ -14,8 +14,8 @@ board = seeed_xiao_esp32c3
monitor_speed = 115200
framework = arduino
board_build.partitions = min_spiffs.csv
upload_protocol = espota
upload_port = TMP-EG-WoZi.fritz.box
;upload_protocol = espota
;upload_port = 192.168.179.41
lib_deps =
moononournation/GFX Library for Arduino@^1.5.3
lvgl/lvgl@^9.2.2

View File

@ -481,11 +481,11 @@
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
*https://fonts.google.com/specimen/Montserrat*/
#define LV_FONT_MONTSERRAT_8 0
#define LV_FONT_MONTSERRAT_10 0
#define LV_FONT_MONTSERRAT_10 1
#define LV_FONT_MONTSERRAT_12 0
#define LV_FONT_MONTSERRAT_14 0
#define LV_FONT_MONTSERRAT_14 1
#define LV_FONT_MONTSERRAT_16 0
#define LV_FONT_MONTSERRAT_18 0
#define LV_FONT_MONTSERRAT_18 1
#define LV_FONT_MONTSERRAT_20 0
#define LV_FONT_MONTSERRAT_22 0
#define LV_FONT_MONTSERRAT_24 0
@ -495,7 +495,7 @@
#define LV_FONT_MONTSERRAT_32 0
#define LV_FONT_MONTSERRAT_34 0
#define LV_FONT_MONTSERRAT_36 0
#define LV_FONT_MONTSERRAT_38 0
#define LV_FONT_MONTSERRAT_38 1
#define LV_FONT_MONTSERRAT_40 0
#define LV_FONT_MONTSERRAT_42 0
#define LV_FONT_MONTSERRAT_44 0
@ -515,10 +515,10 @@
/*Optionally declare custom fonts here.
*You can use these fonts as default font too and they will be available globally.
*E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/
#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(symbol_font_10) LV_FONT_DECLARE(symbol_font_12) LV_FONT_DECLARE(symbol_font_16) LV_FONT_DECLARE(symbol_font_36)
#define LV_FONT_CUSTOM_DECLARE
/*Always set a default font*/
#define LV_FONT_DEFAULT &symbol_font_12
#define LV_FONT_DEFAULT &lv_font_montserrat_14
/*Enable handling large font and/or fonts with a lot of characters.
*The limit depends on the font size, font face and bpp.
@ -611,7 +611,7 @@
#define LV_USE_CHART 1
#define LV_USE_CHECKBOX 1
#define LV_USE_CHECKBOX 0
#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/

View File

@ -16,7 +16,6 @@
#include <Ticker.h>
#include <PubSubClient.h>
#include "MQTT.h"
#include <tahoma.h>
#include <esp_task_wdt.h>
#define MEASINT_S 5
@ -28,8 +27,10 @@
MQTT mqtt;
Ticker measurementTick;
unsigned char ChipID = 0x00;
volatile bool TouchEventFlag = false;
float barometerAltitude = 730.0; // meters ... map readings + barometer position
//using namespace MDO;
/*定义ESP32的SPI使用的引脚*/
@ -121,6 +122,7 @@ void setup(void)
measurementTick.attach(MEASINT_S,measure);
mqtt.begin();
getLocalTime(&glblData.bootTime);
lv_label_set_text_fmt(objects.debugTxt, "IP:\n %s\n\nHostname:\n %s\n\nMqtt-Server:\n %s\n\nMqtt-Port:\n %d\n\nMqtt-Topic:\n %s\n\nHeatBuffer:\n %d",glblData.myIP,Settings::prefs.hostname,Settings::prefs.mqtt_server,Settings::prefs.mqtt_port, Settings::prefs.mqtt_topic,glblData.enBuff);
measure();
esp_reset_reason_t reason = esp_reset_reason();
if ((reason != ESP_RST_DEEPSLEEP) && (reason != ESP_RST_SW)) {
@ -140,7 +142,7 @@ void loop()
{
if(newMeasurement){
esp_task_wdt_reset();
update_sensor(temp, hum, seaLevelPress,presAlarm);
update_sensorNstatus(temp, hum, seaLevelPress,presAlarm);
test = glblData.settemp;
newMeasurement = false;
mqtt.sendStatus();
@ -148,7 +150,7 @@ void loop()
if(newHistory){
newHistory=false;
chart_autoscale();
lv_chart_refresh(objects.chart);
}
if(millis() - minutesTick > 60000){
minutesTick = millis();
@ -157,9 +159,8 @@ void loop()
}
}
if(millis() - secondsTick > 1000){
checkTahomaActions();
secondsTick = millis();
update_status();
//update_clockdots();
}
mqtt.loop();
ui_tick();

View File

@ -1,202 +0,0 @@
#include "tahoma.h"
#include "settings.h"
extern constexpr char Tahoma::serverURL[];
extern Tahoma::rolloCommand_t Tahoma::movement[];
Tahoma::Tahoma(void) {}
// Destructor
Tahoma::~Tahoma() {}
uint8_t Tahoma::getMyDevices(bool _force_update) {
if (!numDevs || _force_update) {
HTTPClient http; // Create an HTTP client object
String url = serverURL;
url += "?action=myactors&filter=";
url += Settings::prefs.hostname; // Construct the URL to fetch all devices
http.begin(url); // Initialize the HTTP connection
int httpCode = http.GET(); // Send the GET request and get the response code
if (httpCode > 0) { // Check if the request was successful
JsonDocument doc; // Create a JSON document to parse the response
String response = http.getString(); // Get the response as a string
deserializeJson(doc, response); // Deserialize the JSON response
if (doc.size() > 0) { // Check if the JSON document is not empty
for (int i = 0; i < doc.size(); i++) { // Loop through the JSON array
if (i >= MAX_NUM_DEVICES) { // Check if the maximum number of devices
// is reached
break; // Break the loop if the maximum number of devices is reached
}
devicelist[i].name =
doc[i]["name"]
.as<String>(); // Get the device URL from the JSON response
devicelist[i].index = doc[i]["id"];
devicelist[i].selected = false;
numDevs++;
}
}
} else {
Serial.print("Error on HTTP request:"); // Print error message if the
// request failed
Serial.println(httpCode); // Print the error code
Serial.print("Error message: "); // Print error message
Serial.println(http.errorToString(httpCode)); // Print the error code
}
http.end(); // Close the HTTP connection
}
return numDevs;
}
bool Tahoma::isDeviceSelected(uint8_t deviceIndex) {
return devicelist[deviceIndex].selected;
}
Tahoma::rolloCommand_t Tahoma::getPos(int8_t deviceIndex) {
rolloCommand_t pos = {0};
if(deviceIndex < 0){
for(uint8_t i=0; i<numDevs;i++){
if(devicelist[i].selected){
deviceIndex = i;
break;
}
}
}
if (deviceIndex < numDevs) {
HTTPClient http; // Create an HTTP client object
String url = serverURL;
url += "?action=pos&device=" +
String(devicelist[deviceIndex]
.index); // Construct the URL to fetch all devices
Serial.println(url);
http.begin(url); // Initialize the HTTP connection
int httpCode = http.GET(); // Send the GET request and get the response code
if (httpCode > 0) { // Check if the request was successful
JsonDocument doc; // Create a JSON document to parse the response
String response = http.getString(); // Get the response as a string
if (!deserializeJson(
doc, response)) { // Check if the JSON was decoded wthout error
Serial.println("doc has content");
pos.rotation =
doc["rotation"]
.as<uint8_t>(); // Get the device URL from the JSON response
pos.position = doc["position"].as<uint8_t>();
Serial.println(pos.rotation);
Serial.println(pos.position);
}
} else {
Serial.print("Error on HTTP request:"); // Print error message if the
// request failed
Serial.println(httpCode); // Print the error code
Serial.print("Error message: "); // Print error message
Serial.println(http.errorToString(httpCode)); // Print the error code
}
http.end(); // Close the HTTP connection
}
return pos;
}
bool Tahoma::checkMovement(uint8_t deviceIndex) {
bool ret = true;
HTTPClient http; // Create an HTTP client object
String url = serverURL;
url += "?action=moving&device=" +
String(devicelist[deviceIndex]
.index); // Construct the URL to fetch all devices
http.begin(url); // Initialize the HTTP connection
int httpCode = http.GET(); // Send the GET request and get the response code
if (httpCode > 0) { // Check if the request was successful
String response = http.getString(); // Get the response as a string
if (response == "false") {
ret = false;
}
} else {
}
http.end(); // Close the HTTP connection
return ret;
}
uint8_t Tahoma::sendMove(uint8_t deviceIndex, uint8_t position,
uint8_t rotation) {
uint8_t ret = 0;
HTTPClient http; // Create an HTTP client object
if (deviceIndex > MAX_NUM_DEVICES || position > 100 || rotation > 100) {
return 0; // invalid parameters
}
String url = serverURL;
if (position != 0 && rotation > 20) {
movement[deviceIndex].position = position;
movement[deviceIndex].rotation = rotation;
rotation = 0;
}
url = url + "?action=move&pos=" + String(position) +
"&angle=" + String(rotation) + "&device=" +
String(devicelist[deviceIndex]
.index); // Construct the URL to fetch all devices
http.begin(url); // Initialize the HTTP connection
int httpCode = http.GET(); // Send the GET request and get the response code
if (httpCode > 0) { // Check if the request was successful
String response = http.getString(); // Get the response as a string
if (response.indexOf("stop") != -1) {
movement[deviceIndex].position = 0;
}
ret = 1;
} else {
movement[deviceIndex].position = 0;
/*Serial.print(
"Error on HTTP request:"); // Print error message if the request failed
Serial.println(httpCode); // Print the error code
Serial.print("Error message: "); // Print error message
Serial.println(http.errorToString(httpCode)); // Print the error code*/
ret = 0;
}
http.end(); // Close the HTTP connection
return ret;
}
void Tahoma::moveSelected(uint8_t position, uint8_t rotation) {
for (uint8_t i = 0; i < numDevs; i++) {
if (devicelist[i].selected) {
sendMove(i, position, rotation);
}
}
}
uint8_t Tahoma::sendfinalRot(uint8_t deviceIndex) {
uint8_t ret = 0;
HTTPClient http; // Create an HTTP client object
String url = serverURL;
if (movement[deviceIndex].position == 0) {
return 0; // no movement stored
}
url = url + "?action=move&pos=" + String(movement[deviceIndex].position) +
"&angle=" + String(movement[deviceIndex].rotation) + "&device=" +
String(devicelist[deviceIndex]
.index); // Construct the URL to fetch all devices
http.begin(url); // Initialize the HTTP connection
int httpCode = http.GET(); // Send the GET request and get the response code
if (httpCode > 0) { // Check if the request was successful
movement[deviceIndex].position = 0;
ret = 1;
} else {
ret = 0;
}
http.end(); // Close the HTTP connection
return ret;
}
void Tahoma::selectDev(uint8_t i,bool _select) {
if (i <= numDevs) {
devicelist[i].selected = _select;
}
}
void Tahoma::loop(void) {
for (uint8_t i = 0; i < numDevs; i++) {
if (movement[i].position != 0) {
Serial.print(devicelist[i].index);
if (!checkMovement(i)) {
sendfinalRot(i);
}
}
}
}

View File

@ -1,51 +0,0 @@
#ifndef TAHOMA_H
#define TAHOMA_H
#include <Arduino.h>
#include <WiFi.h>
#include <iostream>
#include <HTTPClient.h>
#include <Ticker.h>
#include <ArduinoJson.h> // Include the ArduinoJson library for JSON parsing
#define MAX_NUM_DEVICES 11 // Maximum number of devices to fetch
class Tahoma {
public:
typedef union {
uint16_t movement;
struct {
uint16_t position : 8;
uint16_t rotation : 8;
};
} rolloCommand_t;
typedef struct {
String name; // Device name
uint16_t index; // Device URL
bool selected;
} device_t;
// Constructor with hostname and token
// Initializes the Tahoma object with the provided hostname and token
Tahoma(void);
// Destructor
~Tahoma();
uint8_t getMyDevices(bool _force_update=false); // Fetches the device name from the Tahoma system
rolloCommand_t getPos(int8_t deviceIndex=-1);
uint8_t sendMove(uint8_t deviceIndex, uint8_t position, uint8_t rotation);
uint8_t sendfinalRot(uint8_t deviceIndex);
void moveSelected(uint8_t position, uint8_t rotation);
void selectDev(uint8_t i, bool _selected);
bool isDeviceSelected(uint8_t deviceIndex);
void loop(void);
device_t devicelist[MAX_NUM_DEVICES];
uint8_t numDevs{0};
static rolloCommand_t movement[MAX_NUM_DEVICES];
private:
bool checkMovement(uint8_t deviceIndex);
static constexpr char serverURL[]{"http://nas.local/smart/ajax/tahoma.php"}; // Hostname of the Tahoma system
Ticker movementCheckTicker;
// Simulate fetching data from the Tahoma system
};
#endif // TAHOMA_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3162,7 +3162,7 @@ static lv_font_fmt_txt_dsc_t font_dsc = {
#endif
};
//extern const lv_font_t lv_font_motserrat_16;
extern const lv_font_t lv_font_montserrat_18;
/*-----------------
@ -3188,7 +3188,7 @@ lv_font_t Bootstrap_Icons_18 = {
#endif
.dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */
#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9
.fallback = NULL,//&lv_font_motserrat_16,
.fallback = &lv_font_montserrat_18,
#endif
.user_data = NULL,
};

View File

@ -3675,7 +3675,7 @@ static lv_font_fmt_txt_dsc_t font_dsc = {
#endif
};
//extern const lv_font_t lv_font_motserrat_16;
extern const lv_font_t lv_font_montserrat_20;
/*-----------------
@ -3701,7 +3701,7 @@ lv_font_t Bootstrap_Icons_20 = {
#endif
.dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */
#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9
.fallback = NULL,//&lv_font_motserrat_16,
.fallback = &lv_font_montserrat_20,
#endif
.user_data = NULL,
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,30 +14,24 @@ void ui_settemp(float tmp);
void action_zoom_set_temp(lv_event_t * e);
void action_switch_screens(lv_event_t * e);
void showDebugScreen(lv_event_t * e);
void showMenuScreen(lv_event_t * e);
void showChartScreen(lv_event_t * e);
void showMainScreen(lv_event_t * e);
void showMenuScreen(lv_event_t *e);
void showRolloScreen(lv_event_t *e);
void showRolloPosScreen(lv_event_t *e);
void showRolloScreen(lv_event_t * e);
void showRolloPosScreen(lv_event_t * e);
void moveRolloUp(lv_event_t * e);
void moveRolloDown(lv_event_t * e);
void moveRolloMan(lv_event_t * e);
void rebootESP(lv_event_t * e);
void action_show_cursors_cb(lv_event_t * e);
void chartDrawingCB(lv_event_t * e);
void update_sensor(float temp, float hum, float seaLevelPress, bool presAlarm);
void update_sensorNstatus(float temp, float hum, float seaLevelPress, bool presAlarm);
void update_clockdots(void);
void update_status(void);
void update_wifi_strength(wifistrength_t strength, wifimode_t mode);
void chart_autoscale(void);
extern dataset_t glblData;
void draw_event_cb(lv_event_t* e);
void moveRolloDown(lv_event_t* e);
void moveRolloUp(lv_event_t* e);
void moveRolloMan(lv_event_t *e);
void setRolloListText(void);
void toggleRolloChooser(lv_event_t *e);
void checkTahomaActions(void);
void rotation_changed_cb(lv_event_t* e);
void pos_changed_cb(lv_event_t *e);
void rolloChanged(lv_event_t *e);
#ifdef __cplusplus

File diff suppressed because it is too large Load Diff

View File

@ -8,66 +8,63 @@ extern "C" {
#endif
typedef struct _objects_t {
lv_obj_t *mainScr;
lv_obj_t *chartScr;
lv_obj_t *debugScr;
lv_obj_t *rolloScr;
lv_obj_t *rolloPosScr;
lv_obj_t *menuScr;
lv_obj_t *temp_arc;
lv_obj_t *temp_txt;
lv_obj_t *hum_txt;
lv_obj_t *press_txt;
lv_obj_t *panel_arc;
lv_obj_t *chart;
lv_obj_t *x_scale;
lv_obj_t *y_scale;
lv_obj_t *chart_header;
lv_obj_t *left_lbl;
lv_obj_t *right_lbl;
lv_obj_t *debugTxt;
lv_obj_t *heaterIcn;
lv_obj_t *bufferIcn;
lv_obj_t *wifiIcn;
lv_obj_t *outTemp_txt;
lv_obj_t *time_txt;
lv_obj_t *deviceDropdown;
lv_obj_t *lam[9];
lv_chart_cursor_t *chart_cursor;
lv_chart_series_t *chart_series;
lv_obj_t *rolloPos;
lv_obj_t *rolloRot;
lv_obj_t *selDevicesLbl;
lv_obj_t *mainScr;
lv_obj_t *chartScr;
lv_obj_t *debugScr;
lv_obj_t *menuScr;
lv_obj_t *rolloScr;
lv_obj_t *rollo_posScr;
lv_obj_t *temp_arc;
lv_obj_t *temp_txt;
lv_obj_t *hum_txt;
lv_obj_t *press_txt;
lv_obj_t *panel_arc;
lv_obj_t *chart;
lv_obj_t *x_scale;
lv_obj_t *y_scale;
lv_obj_t *chart_header;
lv_obj_t *left_lbl;
lv_obj_t *right_lbl;
lv_obj_t *debugTxt;
lv_obj_t *heaterIcn;
lv_obj_t *bufferIcn;
lv_obj_t *wifiIcn;
lv_obj_t *alarmLED;
lv_obj_t *outTemp_txt;
lv_obj_t *time_txt;
lv_obj_t *deviceDropdown;
lv_obj_t *rolloPosSldr;
lv_obj_t *lamellaContainer;
lv_obj_t *lam[9];
lv_chart_cursor_t *chart_cursor;
lv_chart_series_t *chart_series;
} objects_t;
extern objects_t objects;
typedef enum ScreensEnum {
SCREEN_ID_MAIN = 0,
SCREEN_ID_CHART = 1,
SCREEN_ID_DEBUG = 2,
SCREEN_ID_LEN
} ScreensEnum;
SCREEN_ID_MAIN = 1,
SCREEN_ID_CHART = 2,
SCREEN_ID_DEBUG = 3,
SCREEN_ID_MENU = 4,
SCREEN_ID_ROLLO = 5,
SCREEN_ID_ROLLOPOS = 6,
}ScreensEnum;
typedef enum ChartsEnum {
CHART_ID_NONE = 0,
CHART_ID_TEMP = 1,
CHART_ID_HUM = 2,
CHART_ID_PRESS = 3,
CHART_ID_LEN
} ChartsEnum;
CHART_ID_NONE = 0,
CHART_ID_TEMP = 1,
CHART_ID_HUM = 2,
CHART_ID_PRESS = 3,
CHART_ID_LEN
}ChartsEnum;
void addStatusIcons(lv_obj_t *parent_obj);
void create_screen_main();
void create_screen_chart();
void create_screen_debug();
void create_screen_menu();
void rolloCheckbox_add(const char *txt, void *_tahomaDevice, bool _checked);
void rolloCheckbox_finish(void);
void create_screen_rollos();
void create_screen_rolloPos();
void create_screens();
#ifdef __cplusplus
}
#endif

View File

@ -6,64 +6,30 @@
#include "screens.h"
//
// Style: arc
// Style: Button
//
void init_style_arc_MAIN_DEFAULT(lv_style_t *style) {
lv_style_set_arc_width(style, 10);
lv_style_set_arc_rounded(style, true);
void init_style_button_MAIN_DEFAULT(lv_style_t *style) {
lv_style_set_bg_color(style, lv_color_hex(0xff2f3237));
lv_style_set_text_font(style, &Bootstrap_Icons_18);
};
lv_style_t *get_style_arc_MAIN_DEFAULT() {
lv_style_t *get_style_button_MAIN_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_arc_MAIN_DEFAULT(style);
init_style_button_MAIN_DEFAULT(style);
}
return style;
};
void init_style_arc_INDICATOR_DEFAULT(lv_style_t *style) {
lv_style_set_arc_color(style, lv_color_hex(0xff8ff321));
lv_style_set_bg_color(style, lv_color_hex(0xffffffff));
void add_style_button(lv_obj_t *obj) {
lv_obj_add_style(obj, get_style_button_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
};
lv_style_t *get_style_arc_INDICATOR_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_arc_INDICATOR_DEFAULT(style);
}
return style;
};
void init_style_arc_KNOB_DEFAULT(lv_style_t *style) {
lv_style_set_arc_color(style, lv_color_hex(0xff89f019));
lv_style_set_bg_color(style, lv_color_hex(0xff50a31c));
};
lv_style_t *get_style_arc_KNOB_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_arc_KNOB_DEFAULT(style);
}
return style;
};
void add_style_arc(lv_obj_t *obj) {
lv_obj_add_style(obj, get_style_arc_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_add_style(obj, get_style_arc_INDICATOR_DEFAULT(), LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_add_style(obj, get_style_arc_KNOB_DEFAULT(), LV_PART_KNOB | LV_STATE_DEFAULT);
};
void remove_style_arc(lv_obj_t *obj) {
lv_obj_remove_style(obj, get_style_arc_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_remove_style(obj, get_style_arc_INDICATOR_DEFAULT(), LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_remove_style(obj, get_style_arc_KNOB_DEFAULT(), LV_PART_KNOB | LV_STATE_DEFAULT);
void remove_style_button(lv_obj_t *obj) {
lv_obj_remove_style(obj, get_style_button_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
};
//
@ -112,6 +78,63 @@ void remove_style_slider(lv_obj_t *obj) {
};
//
//
// Style: arc
//
void init_style_arc_MAIN_DEFAULT(lv_style_t *style) {
lv_style_set_arc_width(style, 10);
lv_style_set_arc_rounded(style, true);
};
lv_style_t *get_style_arc_MAIN_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_arc_MAIN_DEFAULT(style);
}
return style;
};
void init_style_arc_INDICATOR_DEFAULT(lv_style_t *style) {
lv_style_set_arc_color(style, lv_color_hex(0xff8ff321));
lv_style_set_bg_color(style, lv_color_hex(0xffffffff));
};
lv_style_t *get_style_arc_INDICATOR_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_arc_INDICATOR_DEFAULT(style);
}
return style;
};
void init_style_arc_KNOB_DEFAULT(lv_style_t *style) {
lv_style_set_arc_color(style, lv_color_hex(0xff89f019));
lv_style_set_bg_color(style, lv_color_hex(0xff50a31c));
};
lv_style_t *get_style_arc_KNOB_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_arc_KNOB_DEFAULT(style);
}
return style;
};
void add_style_arc(lv_obj_t *obj) {
lv_obj_add_style(obj, get_style_arc_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_add_style(obj, get_style_arc_INDICATOR_DEFAULT(), LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_add_style(obj, get_style_arc_KNOB_DEFAULT(), LV_PART_KNOB | LV_STATE_DEFAULT);
};
void remove_style_arc(lv_obj_t *obj) {
lv_obj_remove_style(obj, get_style_arc_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_remove_style(obj, get_style_arc_INDICATOR_DEFAULT(), LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_remove_style(obj, get_style_arc_KNOB_DEFAULT(), LV_PART_KNOB | LV_STATE_DEFAULT);
};

View File

@ -13,11 +13,12 @@ lv_style_t *get_style_arc_INDICATOR_DEFAULT();
lv_style_t *get_style_arc_KNOB_DEFAULT();
void add_style_arc(lv_obj_t *obj);
void remove_style_arc(lv_obj_t *obj);
void add_style_button(lv_obj_t *obj);
void remove_style_button(lv_obj_t *obj);
void add_style_slider(lv_obj_t *obj);
void remove_style_slider(lv_obj_t *obj);
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,715 +0,0 @@
/*******************************************************************************
* Size: 34 px
* Bpp: 2
* Opts: --no-compress --no-prefilter --bpp 2 --size 34 --font C:\Users\m0\Desktop\LVGL_FontGen\bootstrap_jalousie(0xF100).ttf -r 62925,61696,61719,62450,61993,62005,62501,62435,61939 --font C:\Users\m0\Desktop\LVGL_FontGen\MaterialSymbolsRounded[FILL,GRAD,opsz,wght]-wght100-slnt4-opts0.ttf -r 57990,57410 --font F:\m0\Git-Projekte\Raumtempregler\LVGL_FontGen\Montserrat-Medium.ttf -r 0x20 --symbols 0123456789,.-°C --format lvgl -o C:\Users\m0\Desktop\LVGL_FontGen\symbol_font_34.c --force-fast-kern-format
******************************************************************************/
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#ifndef SYMBOL_FONT_34
#define SYMBOL_FONT_34 1
#endif
#if SYMBOL_FONT_34
/*-----------------
* BITMAPS
*----------------*/
/*Store the image of the glyphs*/
static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
/* U+0020 " " */
/* U+002C "," */
0x5, 0x3, 0xf8, 0x7f, 0xc7, 0xfc, 0x2f, 0xc0,
0xf4, 0x1f, 0x2, 0xf0, 0x3d, 0x3, 0xc0,
/* U+002D "-" */
0x3f, 0xff, 0xf0, 0xff, 0xff, 0xc3, 0xff, 0xff,
0x0,
/* U+002E "." */
0x9, 0x3, 0xfc, 0x7f, 0xc3, 0xfc, 0x1f, 0x40,
/* U+0030 "0" */
0x0, 0x2, 0xff, 0x90, 0x0, 0x0, 0xb, 0xff,
0xff, 0x40, 0x0, 0xf, 0xff, 0xff, 0xf8, 0x0,
0xf, 0xfd, 0x1, 0xff, 0x80, 0xb, 0xf8, 0x0,
0xf, 0xf0, 0x3, 0xf8, 0x0, 0x0, 0xfe, 0x1,
0xfc, 0x0, 0x0, 0x1f, 0xc0, 0xfe, 0x0, 0x0,
0x3, 0xf4, 0x3f, 0x40, 0x0, 0x0, 0xbe, 0xf,
0xc0, 0x0, 0x0, 0x2f, 0xc7, 0xf0, 0x0, 0x0,
0x7, 0xf1, 0xfc, 0x0, 0x0, 0x1, 0xfc, 0x7f,
0x0, 0x0, 0x0, 0x7f, 0x1f, 0xc0, 0x0, 0x0,
0x1f, 0xc3, 0xf0, 0x0, 0x0, 0xb, 0xf0, 0xfd,
0x0, 0x0, 0x2, 0xf8, 0x3f, 0x80, 0x0, 0x0,
0xfd, 0x7, 0xf0, 0x0, 0x0, 0x7f, 0x0, 0xfe,
0x0, 0x0, 0x3f, 0x80, 0x2f, 0xe0, 0x0, 0x3f,
0xc0, 0x3, 0xfe, 0x40, 0x7f, 0xe0, 0x0, 0x3f,
0xff, 0xff, 0xe0, 0x0, 0x2, 0xff, 0xff, 0xd0,
0x0, 0x0, 0xb, 0xfe, 0x40, 0x0,
/* U+0031 "1" */
0xbf, 0xff, 0xcb, 0xff, 0xfc, 0xbf, 0xff, 0xc0,
0x1, 0xfc, 0x0, 0x1f, 0xc0, 0x1, 0xfc, 0x0,
0x1f, 0xc0, 0x1, 0xfc, 0x0, 0x1f, 0xc0, 0x1,
0xfc, 0x0, 0x1f, 0xc0, 0x1, 0xfc, 0x0, 0x1f,
0xc0, 0x1, 0xfc, 0x0, 0x1f, 0xc0, 0x1, 0xfc,
0x0, 0x1f, 0xc0, 0x1, 0xfc, 0x0, 0x1f, 0xc0,
0x1, 0xfc, 0x0, 0x1f, 0xc0, 0x1, 0xfc, 0x0,
0x1f, 0xc0, 0x1, 0xfc,
/* U+0032 "2" */
0x0, 0x1b, 0xff, 0x80, 0x0, 0xb, 0xff, 0xff,
0xe0, 0x1, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xf9,
0x0, 0x7f, 0xe0, 0x1f, 0x0, 0x0, 0x3f, 0xc0,
0x10, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x0, 0x0,
0xfd, 0x0, 0x0, 0x0, 0x3, 0xf0, 0x0, 0x0,
0x0, 0x1f, 0xc0, 0x0, 0x0, 0x0, 0xbf, 0x0,
0x0, 0x0, 0x7, 0xf4, 0x0, 0x0, 0x0, 0x3f,
0x80, 0x0, 0x0, 0x3, 0xfc, 0x0, 0x0, 0x0,
0x7f, 0xc0, 0x0, 0x0, 0x7, 0xfc, 0x0, 0x0,
0x0, 0x7f, 0xc0, 0x0, 0x0, 0x7, 0xfc, 0x0,
0x0, 0x0, 0x7f, 0xc0, 0x0, 0x0, 0x7, 0xfc,
0x0, 0x0, 0x0, 0x7f, 0xc0, 0x0, 0x0, 0x7,
0xf8, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xff,
0xd2, 0xff, 0xff, 0xff, 0xff, 0x4b, 0xff, 0xff,
0xff, 0xfd,
/* U+0033 "3" */
0x2f, 0xff, 0xff, 0xff, 0xc2, 0xff, 0xff, 0xff,
0xfc, 0x2f, 0xff, 0xff, 0xff, 0xc0, 0x0, 0x0,
0xb, 0xf0, 0x0, 0x0, 0x2, 0xfc, 0x0, 0x0,
0x0, 0x7f, 0x40, 0x0, 0x0, 0xf, 0xe0, 0x0,
0x0, 0x3, 0xf8, 0x0, 0x0, 0x0, 0xff, 0x0,
0x0, 0x0, 0x2f, 0xc0, 0x0, 0x0, 0x3, 0xff,
0x90, 0x0, 0x0, 0x7f, 0xff, 0xd0, 0x0, 0x2,
0xaf, 0xff, 0x40, 0x0, 0x0, 0x7, 0xfc, 0x0,
0x0, 0x0, 0xf, 0xe0, 0x0, 0x0, 0x0, 0xbf,
0x0, 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0, 0x0,
0xbf, 0x0, 0x0, 0x0, 0xf, 0xe3, 0xd0, 0x0,
0x2, 0xfd, 0x7f, 0xe0, 0x1, 0xff, 0xc7, 0xff,
0xff, 0xff, 0xf0, 0xb, 0xff, 0xff, 0xf8, 0x0,
0x6, 0xff, 0xe4, 0x0,
/* U+0034 "4" */
0x0, 0x0, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0,
0x2f, 0xc0, 0x0, 0x0, 0x0, 0x7, 0xf0, 0x0,
0x0, 0x0, 0x1, 0xfd, 0x0, 0x0, 0x0, 0x0,
0x3f, 0x80, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0,
0x0, 0x0, 0x2, 0xfc, 0x0, 0x0, 0x0, 0x0,
0x7f, 0x40, 0x0, 0x0, 0x0, 0xf, 0xe0, 0x0,
0x0, 0x0, 0x3, 0xfc, 0x0, 0x0, 0x0, 0x0,
0xbf, 0x0, 0x1f, 0xc0, 0x0, 0x1f, 0xd0, 0x1,
0xfc, 0x0, 0x7, 0xf4, 0x0, 0x1f, 0xc0, 0x0,
0xfe, 0x0, 0x1, 0xfc, 0x0, 0x3f, 0xc0, 0x0,
0x1f, 0xc0, 0xb, 0xff, 0xff, 0xff, 0xff, 0xfd,
0xbf, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xff, 0xff,
0xff, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x1f, 0xc0,
0x0, 0x0, 0x0, 0x1, 0xfc, 0x0, 0x0, 0x0,
0x0, 0x1f, 0xc0, 0x0, 0x0, 0x0, 0x1, 0xfc,
0x0, 0x0, 0x0, 0x0, 0x1f, 0xc0, 0x0, 0x0,
0x0, 0x1, 0xfc, 0x0,
/* U+0035 "5" */
0x1, 0xff, 0xff, 0xff, 0xc0, 0xb, 0xff, 0xff,
0xff, 0x0, 0x2f, 0xff, 0xff, 0xfc, 0x0, 0xfd,
0x0, 0x0, 0x0, 0x3, 0xf4, 0x0, 0x0, 0x0,
0xf, 0xc0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x0,
0x0, 0x0, 0xfc, 0x0, 0x0, 0x0, 0x7, 0xf0,
0x0, 0x0, 0x0, 0x1f, 0xc0, 0x0, 0x0, 0x0,
0x7f, 0xff, 0xf9, 0x0, 0x2, 0xff, 0xff, 0xff,
0x40, 0xb, 0xff, 0xff, 0xff, 0x80, 0x0, 0x0,
0x6, 0xff, 0x40, 0x0, 0x0, 0x0, 0xff, 0x0,
0x0, 0x0, 0x1, 0xfc, 0x0, 0x0, 0x0, 0x3,
0xf4, 0x0, 0x0, 0x0, 0xf, 0xd0, 0x0, 0x0,
0x0, 0x7f, 0x7, 0x40, 0x0, 0x3, 0xfc, 0x3f,
0xe4, 0x0, 0xbf, 0xd0, 0xff, 0xff, 0xff, 0xfe,
0x0, 0x7f, 0xff, 0xff, 0xd0, 0x0, 0x6, 0xff,
0xe4, 0x0,
/* U+0036 "6" */
0x0, 0x1, 0xbf, 0xfe, 0x0, 0x0, 0x1f, 0xff,
0xff, 0xe0, 0x0, 0xbf, 0xff, 0xff, 0xc0, 0x2,
0xff, 0x80, 0x1, 0x80, 0x7, 0xfc, 0x0, 0x0,
0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0x1f, 0xc0,
0x0, 0x0, 0x0, 0x2f, 0x80, 0x0, 0x0, 0x0,
0x3f, 0x40, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x6a,
0x90, 0x0, 0x7f, 0xb, 0xff, 0xfe, 0x0, 0x7f,
0x3f, 0xff, 0xff, 0xc0, 0x7f, 0xfe, 0x40, 0x6f,
0xf0, 0x7f, 0xf4, 0x0, 0x7, 0xf4, 0x3f, 0xd0,
0x0, 0x2, 0xfc, 0x3f, 0xc0, 0x0, 0x1, 0xfc,
0x3f, 0xc0, 0x0, 0x1, 0xfc, 0x2f, 0xc0, 0x0,
0x1, 0xfc, 0xf, 0xd0, 0x0, 0x2, 0xfc, 0xf,
0xf0, 0x0, 0x7, 0xf4, 0x3, 0xfd, 0x0, 0x1f,
0xf0, 0x0, 0xff, 0xfb, 0xff, 0xc0, 0x0, 0x3f,
0xff, 0xfe, 0x0, 0x0, 0x6, 0xff, 0xe0, 0x0,
/* U+0037 "7" */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x0,
0x0, 0xfd, 0xfd, 0x0, 0x0, 0x2f, 0xcf, 0xd0,
0x0, 0x3, 0xf8, 0xfd, 0x0, 0x0, 0x7f, 0x0,
0x0, 0x0, 0xf, 0xe0, 0x0, 0x0, 0x1, 0xfc,
0x0, 0x0, 0x0, 0x3f, 0xc0, 0x0, 0x0, 0x3,
0xf4, 0x0, 0x0, 0x0, 0xbf, 0x0, 0x0, 0x0,
0xf, 0xd0, 0x0, 0x0, 0x2, 0xfc, 0x0, 0x0,
0x0, 0x3f, 0x80, 0x0, 0x0, 0x7, 0xf0, 0x0,
0x0, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x1f, 0xc0,
0x0, 0x0, 0x3, 0xfc, 0x0, 0x0, 0x0, 0x3f,
0x40, 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0, 0x0,
0xfd, 0x0, 0x0, 0x0, 0x2f, 0xc0, 0x0, 0x0,
0x3, 0xf8, 0x0, 0x0,
/* U+0038 "8" */
0x0, 0xb, 0xff, 0xe0, 0x0, 0x0, 0xff, 0xff,
0xfe, 0x0, 0x3, 0xff, 0xff, 0xff, 0xc0, 0xf,
0xf8, 0x0, 0x2f, 0xf0, 0x1f, 0xd0, 0x0, 0x7,
0xf4, 0x2f, 0xc0, 0x0, 0x3, 0xf4, 0x2f, 0x80,
0x0, 0x3, 0xf8, 0x1f, 0xc0, 0x0, 0x3, 0xf4,
0xf, 0xe0, 0x0, 0xb, 0xf0, 0xb, 0xf9, 0x0,
0x7f, 0xd0, 0x1, 0xff, 0xff, 0xff, 0x40, 0x0,
0xff, 0xff, 0xfe, 0x0, 0x7, 0xff, 0xaa, 0xff,
0xd0, 0x1f, 0xe0, 0x0, 0x1f, 0xf4, 0x3f, 0x80,
0x0, 0x3, 0xfc, 0x7f, 0x0, 0x0, 0x1, 0xfc,
0x7f, 0x0, 0x0, 0x0, 0xfd, 0x7f, 0x0, 0x0,
0x0, 0xfd, 0x7f, 0x0, 0x0, 0x1, 0xfc, 0x3f,
0xc0, 0x0, 0x3, 0xfc, 0x1f, 0xf4, 0x0, 0x1f,
0xf4, 0xb, 0xff, 0xef, 0xff, 0xd0, 0x1, 0xff,
0xff, 0xff, 0x40, 0x0, 0x1b, 0xff, 0xe4, 0x0,
/* U+0039 "9" */
0x0, 0xb, 0xff, 0x80, 0x0, 0x0, 0xbf, 0xff,
0xf8, 0x0, 0x3, 0xff, 0xff, 0xff, 0x0, 0xf,
0xf4, 0x0, 0x7f, 0xc0, 0x1f, 0xd0, 0x0, 0xf,
0xe0, 0x3f, 0x80, 0x0, 0x7, 0xf0, 0x3f, 0x40,
0x0, 0x3, 0xf8, 0x3f, 0x40, 0x0, 0x3, 0xfc,
0x3f, 0x40, 0x0, 0x3, 0xfc, 0x3f, 0x80, 0x0,
0x7, 0xfc, 0x1f, 0xd0, 0x0, 0x1f, 0xfd, 0xf,
0xf9, 0x1, 0xbf, 0xfd, 0x3, 0xff, 0xff, 0xfd,
0xfd, 0x0, 0xbf, 0xff, 0xe0, 0xfc, 0x0, 0x6,
0xa9, 0x0, 0xfc, 0x0, 0x0, 0x0, 0x1, 0xfc,
0x0, 0x0, 0x0, 0x2, 0xf8, 0x0, 0x0, 0x0,
0x3, 0xf4, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0,
0x0, 0x0, 0x3f, 0xd0, 0x2, 0x40, 0x2, 0xff,
0x80, 0x7, 0xff, 0xff, 0xfd, 0x0, 0xb, 0xff,
0xff, 0xf0, 0x0, 0x0, 0xbf, 0xfe, 0x0, 0x0,
/* U+0043 "C" */
0x0, 0x0, 0x2b, 0xff, 0x90, 0x0, 0x0, 0x1f,
0xff, 0xff, 0xf4, 0x0, 0x2, 0xff, 0xff, 0xff,
0xfc, 0x0, 0x3f, 0xfd, 0x0, 0x2f, 0xfc, 0x3,
0xff, 0x40, 0x0, 0xb, 0xd0, 0x2f, 0xf0, 0x0,
0x0, 0x5, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0,
0xb, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x80,
0x0, 0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0,
0x0, 0x7, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x1f,
0xc0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0x0, 0x0,
0x0, 0x0, 0x1, 0xfc, 0x0, 0x0, 0x0, 0x0,
0x3, 0xf4, 0x0, 0x0, 0x0, 0x0, 0xf, 0xe0,
0x0, 0x0, 0x0, 0x0, 0x2f, 0xc0, 0x0, 0x0,
0x0, 0x0, 0x3f, 0xc0, 0x0, 0x0, 0x0, 0x0,
0xbf, 0x80, 0x0, 0x0, 0x14, 0x0, 0xff, 0xc0,
0x0, 0x2, 0xf4, 0x0, 0xff, 0xe4, 0x0, 0xbf,
0xf0, 0x0, 0xbf, 0xff, 0xff, 0xff, 0x0, 0x0,
0x7f, 0xff, 0xff, 0xd0, 0x0, 0x0, 0xa, 0xff,
0xe4, 0x0,
/* U+00B0 "°" */
0x1, 0xbf, 0x40, 0xb, 0xff, 0xf0, 0x2f, 0x0,
0xbc, 0x3c, 0x0, 0x3d, 0x78, 0x0, 0x1e, 0x74,
0x0, 0xe, 0x78, 0x0, 0x1e, 0x3c, 0x0, 0x3d,
0x2f, 0x0, 0xbc, 0xb, 0xff, 0xf0, 0x1, 0xbf,
0x40,
/* U+E042 "" */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x34, 0x0, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0,
0x0, 0x0, 0x3, 0xc0, 0x0, 0x0, 0x0, 0x0,
0x3e, 0xf9, 0x0, 0x0, 0x0, 0x1, 0xc0, 0x6c,
0x0, 0x0, 0x0, 0x7, 0x0, 0x74, 0x0, 0x0,
0x0, 0x10, 0x0, 0xd0, 0x0, 0x0, 0x0, 0x0,
0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0,
0x0, 0x0, 0x0, 0x0, 0xc0, 0x0, 0x0, 0x0,
0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60,
0x0, 0x0, 0x0, 0x0, 0x3, 0xc0, 0x0, 0x0,
0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x3,
0x90, 0x0, 0x0, 0x0, 0x0, 0x66, 0x0, 0x0,
0x0, 0x0, 0x9, 0x30, 0x0, 0x0, 0x0, 0x0,
0xc2, 0x40, 0x0, 0x0, 0x0, 0x28, 0xc, 0x0,
0x0, 0x0, 0x7, 0x0, 0x30, 0x0, 0x0, 0x0,
0xc0, 0x0, 0xd0, 0x0, 0x0, 0x70, 0x0, 0x2,
0xd0, 0x0, 0x78, 0x0, 0x0, 0x2, 0xff, 0xf8,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
/* U+E286 "" */
0x0, 0xbf, 0xff, 0xff, 0xff, 0xe0, 0x0, 0x1c,
0x0, 0x0, 0x9, 0x2, 0x40, 0x1, 0x80, 0x0,
0x0, 0x90, 0x18, 0x0, 0x18, 0x0, 0x0, 0x9,
0x1, 0x80, 0x1, 0x80, 0x0, 0x0, 0x90, 0x18,
0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1,
0x80, 0x0, 0x0, 0x90, 0x18, 0x0, 0x18, 0x0,
0x0, 0x9, 0x1, 0x80, 0x1, 0x80, 0x0, 0x0,
0x90, 0x18, 0x0, 0x18, 0x0, 0x0, 0x9, 0x1,
0x80, 0x1, 0x95, 0x55, 0x55, 0xd5, 0x68, 0x0,
0x1e, 0xaa, 0xaa, 0xaf, 0xab, 0x80, 0x1, 0x80,
0x0, 0x0, 0x90, 0x18, 0x0, 0x18, 0x0, 0x0,
0x9, 0x1, 0x80, 0x1, 0x80, 0x0, 0x0, 0x90,
0x18, 0x0, 0x18, 0x0, 0x0, 0x1f, 0x1, 0x80,
0x1, 0x80, 0x0, 0x1, 0xf0, 0x18, 0x0, 0x18,
0x0, 0x0, 0x4, 0x1, 0x80, 0x1, 0x80, 0x0,
0x0, 0x0, 0x18, 0x0, 0x18, 0x0, 0x0, 0x0,
0x1, 0x80, 0x1, 0x80, 0x0, 0x0, 0x0, 0x18,
0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,
/* U+F100 "" */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4,
0x2a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xb4,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x34,
0x5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x34,
0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x34,
0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x34,
0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x34,
0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbc,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbc,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbc,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10,
/* U+F117 "" */
0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x3, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f,
0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff,
0x90, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xfe,
0x0, 0x0, 0x0, 0x0, 0x3f, 0xf1, 0xbf, 0xd0,
0x0, 0x0, 0x0, 0xb, 0xf0, 0x3, 0xf8, 0x0,
0x0, 0x0, 0x2, 0xf0, 0x0, 0x7e, 0x0, 0x0,
0x0, 0x0, 0x70, 0x0, 0x1f, 0x40, 0x0, 0x0,
0x0, 0x0, 0x0, 0xb, 0xc0, 0xb, 0x0, 0x0,
0x0, 0x0, 0x3, 0xe0, 0xf, 0x40, 0x0, 0x0,
0x0, 0x1, 0xf0, 0x1f, 0x0, 0x0, 0x0, 0x0,
0x0, 0xf0, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x0,
0xb4, 0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78,
0x2d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x78, 0x2d,
0x0, 0x0, 0x0, 0x0, 0x0, 0x78, 0x2e, 0x0,
0x0, 0x0, 0x0, 0x0, 0xb8, 0x1f, 0x0, 0x0,
0x0, 0x0, 0x0, 0xb4, 0xf, 0x0, 0x0, 0x0,
0x0, 0x0, 0xf0, 0xf, 0x40, 0x0, 0x0, 0x0,
0x1, 0xf0, 0x7, 0xc0, 0x0, 0x0, 0x0, 0x3,
0xd0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0xb, 0xc0,
0x0, 0xf8, 0x0, 0x0, 0x0, 0x2f, 0x0, 0x0,
0x7f, 0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x1f,
0xe0, 0x0, 0xb, 0xf4, 0x0, 0x0, 0x3, 0xff,
0xaa, 0xff, 0x80, 0x0, 0x0, 0x0, 0x6f, 0xff,
0xf9, 0x0, 0x0, 0x0, 0x0, 0x1, 0x69, 0x40,
0x0, 0x0,
/* U+F1F3 "" */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0xb4, 0x0, 0x0, 0x0, 0x1, 0xd0,
0x0, 0x0, 0xf, 0x40, 0x0, 0x0, 0x0, 0x2e,
0x0, 0x0, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xcb, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x5f, 0xf0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0,
0x0, 0x0, 0x0, 0x50, 0x5, 0x40, 0xf, 0xf0,
0x0, 0x0, 0x0, 0x3f, 0xc2, 0xfd, 0x0, 0xff,
0x0, 0x0, 0x0, 0x3, 0xfc, 0x3f, 0xe0, 0xf,
0xf0, 0x0, 0x0, 0x0, 0x3f, 0xc3, 0xfe, 0x0,
0xff, 0x0, 0x0, 0x0, 0x3, 0xfc, 0x2f, 0xd0,
0xf, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0xf, 0xf0, 0x7, 0xf0, 0x3f, 0x80, 0x0,
0x0, 0x0, 0xff, 0x0, 0xff, 0x83, 0xfc, 0x0,
0x0, 0x0, 0xf, 0xf0, 0xf, 0xf8, 0x7f, 0xc0,
0x0, 0x0, 0x0, 0xff, 0x0, 0xbf, 0x43, 0xfc,
0x0, 0x0, 0x0, 0xf, 0xf0, 0x1, 0x50, 0x5,
0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff,
0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f,
0xbd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7,
0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfc, 0xb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xfe, 0x0,
/* U+F229 "" */
0x1a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x3, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xd3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xfc, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff,
0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x1,
0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, 0xb, 0xff,
0xff, 0xff, 0xfe, 0x0, 0x0, 0x2f, 0xff, 0xff,
0xff, 0x80, 0x0, 0x0, 0xff, 0xff, 0xff, 0xf0,
0x0, 0x0, 0x3, 0xff, 0xff, 0xfc, 0x0, 0x0,
0x0, 0xf, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0,
0x3f, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x1, 0xff,
0xf4, 0x0, 0x0, 0x0, 0x0, 0x7, 0xfd, 0x0,
0x0, 0x0, 0x0, 0x0, 0x2f, 0x80, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
/* U+F235 "" */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x2f, 0x80, 0x0, 0x0, 0x0, 0x0, 0x7,
0xfd, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xf4,
0x0, 0x0, 0x0, 0x0, 0x3f, 0xff, 0xc0, 0x0,
0x0, 0x0, 0xf, 0xff, 0xff, 0x0, 0x0, 0x0,
0x3, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x0, 0xff,
0xff, 0xff, 0xf0, 0x0, 0x0, 0x2f, 0xff, 0xff,
0xff, 0x80, 0x0, 0xb, 0xff, 0xff, 0xff, 0xfe,
0x0, 0x1, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xd0, 0xf, 0xff,
0xff, 0xff, 0xff, 0xff, 0x3, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xd3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0x1a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0,
/* U+F3E3 "" */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x1, 0xff,
0x40, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xd7,
0xff, 0xd7, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x7f,
0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x0,
0x3f, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x0,
0x0, 0x7f, 0xfe, 0x55, 0xbf, 0xfd, 0x0, 0x0,
0x0, 0x51, 0xff, 0xd0, 0x0, 0x7, 0xff, 0x45,
0x0, 0x2, 0xff, 0xff, 0xc0, 0x0, 0x0, 0xbf,
0xff, 0x80, 0x3, 0xff, 0xfb, 0xe0, 0x0, 0x0,
0x2f, 0xff, 0xc0, 0x2, 0xff, 0xe0, 0xf4, 0x0,
0x0, 0xb, 0xff, 0x80, 0x0, 0xff, 0xc0, 0x7c,
0x0, 0x0, 0x3, 0xff, 0x0, 0x0, 0x7f, 0x40,
0x2f, 0x0, 0x0, 0x1, 0xfd, 0x0, 0x0, 0x7f,
0x0, 0xf, 0x80, 0x0, 0x0, 0xfd, 0x0, 0x1,
0xfe, 0x0, 0x3, 0xd0, 0x0, 0x0, 0xbf, 0x40,
0x1f, 0xfd, 0x0, 0x1, 0xf0, 0x0, 0x0, 0xbf,
0xf4, 0x3f, 0xfd, 0x0, 0x0, 0xbf, 0xff, 0xff,
0xff, 0xfc, 0x3f, 0xfd, 0x0, 0x0, 0xbf, 0xff,
0xff, 0xff, 0xfc, 0x1f, 0xfd, 0x0, 0x1, 0xf0,
0x0, 0x0, 0xbf, 0xf4, 0x1, 0xfe, 0x0, 0x3,
0xd0, 0x0, 0x0, 0xbf, 0x40, 0x0, 0x7f, 0x0,
0xf, 0x80, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x7f,
0x40, 0x2f, 0x0, 0x0, 0x1, 0xfd, 0x0, 0x0,
0xff, 0xc0, 0x7c, 0x0, 0x0, 0x3, 0xff, 0x0,
0x2, 0xff, 0xe0, 0xf4, 0x0, 0x0, 0xb, 0xff,
0x80, 0x3, 0xff, 0xfb, 0xe0, 0x0, 0x0, 0x2f,
0xff, 0xc0, 0x2, 0xff, 0xff, 0xc0, 0x0, 0x0,
0xbf, 0xff, 0x80, 0x0, 0x51, 0xff, 0xd0, 0x0,
0x7, 0xff, 0x45, 0x0, 0x0, 0x0, 0x7f, 0xfe,
0x55, 0xbf, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x3f,
0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x0, 0x0,
0x7f, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, 0x0,
0x0, 0x7f, 0xd7, 0xff, 0xd7, 0xfd, 0x0, 0x0,
0x0, 0x0, 0x2e, 0x1, 0xff, 0x40, 0xb8, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7d, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
/* U+F3F2 "" */
0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x5, 0xf, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x2, 0xf0, 0xf0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x7d, 0xf, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0xf, 0x80, 0xf0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x3, 0xe0, 0xf, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0xfc, 0x0, 0xf0, 0x0,
0x0, 0xf, 0x0, 0x0, 0x2f, 0x0, 0xf, 0x0,
0x0, 0x3, 0xfc, 0x0, 0x7, 0xd0, 0x0, 0xf0,
0x0, 0x0, 0xbf, 0xf0, 0x1, 0xf4, 0x0, 0xf,
0x0, 0x0, 0x1f, 0xf, 0xc0, 0x3e, 0x0, 0x0,
0xf0, 0x0, 0x3, 0xd0, 0x3f, 0xf, 0xc0, 0x0,
0xf, 0x0, 0x0, 0xf8, 0x0, 0xff, 0xf0, 0x0,
0x0, 0xf0, 0x0, 0x2f, 0x0, 0x3, 0xfc, 0x0,
0x0, 0xf, 0x0, 0x7, 0xd0, 0x0, 0xf, 0x40,
0x0, 0x0, 0xf0, 0x0, 0xf8, 0x0, 0x0, 0x0,
0x0, 0x0, 0xf, 0x0, 0x3f, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0xf0, 0x7, 0xc0, 0x0, 0x0,
0x0, 0x0, 0x0, 0xf, 0x0, 0xf4, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0xf0, 0x2e, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x40, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf,
0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff,
/* U+F425 "" */
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0xff, 0xd0, 0x1a, 0x80,
0x0, 0x0, 0x0, 0x0, 0xfc, 0x7d, 0xf, 0xf4,
0x0, 0x0, 0x0, 0x0, 0xfc, 0x7, 0xd3, 0xfd,
0x0, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x7d, 0xff,
0x40, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x7, 0xff,
0xd0, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x7f,
0xf4, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x7,
0xfd, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0,
0x7f, 0x40, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0,
0x7, 0xe0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0,
0x0, 0x7d, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0,
0x0, 0x7, 0xe0, 0x0, 0xfc, 0x0, 0x0, 0x0,
0x0, 0x0, 0xbe, 0x0, 0xff, 0x0, 0x0, 0x0,
0x0, 0x0, 0x2f, 0xe0, 0xff, 0xc0, 0x0, 0x0,
0x0, 0x0, 0xb, 0xfe, 0x3c, 0xf0, 0x0, 0x0,
0x0, 0x0, 0x2, 0xe7, 0xc0, 0x3c, 0x0, 0x0,
0x0, 0x0, 0x0, 0xb8, 0x0, 0xf, 0x0, 0x0,
0x0, 0x0, 0x0, 0x2e, 0x0, 0x3, 0xc0, 0x0,
0x0, 0x0, 0x0, 0xb, 0x80, 0x0, 0xf0, 0x0,
0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x3c, 0x0,
0x0, 0x0, 0x0, 0x0, 0xb8, 0x0, 0xf, 0x0,
0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x3, 0xc0,
0x0, 0x0, 0x0, 0x0, 0xb, 0x80, 0x0, 0xf0,
0x0, 0x0, 0x0, 0x0, 0x2, 0xe0, 0x0, 0x3c,
0x0, 0x0, 0x0, 0x0, 0x0, 0xb8, 0x0, 0xf,
0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x0, 0x3,
0xe0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x40, 0x0,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0,
0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0,
/* U+F5CD "" */
0x0, 0x1f, 0xf4, 0x0, 0x0, 0xbf, 0xfe, 0x0,
0x1, 0xf9, 0x6f, 0x40, 0x3, 0xe0, 0xb, 0xc0,
0x3, 0xc0, 0x3, 0xc0, 0x3, 0xc0, 0x3, 0xc0,
0x3, 0xc0, 0x3, 0xc0, 0x3, 0xc0, 0x3, 0xc0,
0x3, 0xc0, 0x3, 0xc0, 0x3, 0xc0, 0x3, 0xc0,
0x3, 0xc0, 0x3, 0xc0, 0x3, 0xc0, 0x3, 0xc0,
0x3, 0xc0, 0x3, 0xc0, 0x3, 0xc3, 0xc3, 0xc0,
0x3, 0xc3, 0xc3, 0xc0, 0x3, 0xc3, 0xc3, 0xc0,
0x3, 0xc3, 0xc3, 0xc0, 0x3, 0xc3, 0xc3, 0xc0,
0x3, 0xc3, 0xc3, 0xc0, 0x3, 0xc3, 0xc3, 0xc0,
0x3, 0xc3, 0xc3, 0xc0, 0x7, 0xc3, 0xc3, 0xd0,
0xf, 0x83, 0xc2, 0xf0, 0x2f, 0x3, 0xd0, 0xf8,
0x3d, 0x1f, 0xf4, 0x7c, 0x3c, 0x3f, 0xfc, 0x3c,
0x7c, 0x3f, 0xfc, 0x3d, 0x3c, 0x3f, 0xfc, 0x3d,
0x3c, 0x1f, 0xf4, 0x3c, 0x2e, 0x6, 0x90, 0xb8,
0xf, 0x80, 0x2, 0xf0, 0x7, 0xf4, 0x1f, 0xd0,
0x1, 0xff, 0xff, 0x40, 0x0, 0x1f, 0xf4, 0x0,
0x0, 0x0, 0x0, 0x0
};
/*---------------------
* GLYPH DESCRIPTION
*--------------------*/
static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
{.bitmap_index = 0, .adv_w = 146, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 0, .adv_w = 123, .box_w = 6, .box_h = 10, .ofs_x = 1, .ofs_y = -5},
{.bitmap_index = 15, .adv_w = 208, .box_w = 11, .box_h = 3, .ofs_x = 1, .ofs_y = 8},
{.bitmap_index = 24, .adv_w = 123, .box_w = 6, .box_h = 5, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 32, .adv_w = 363, .box_w = 21, .box_h = 24, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 158, .adv_w = 201, .box_w = 10, .box_h = 24, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 218, .adv_w = 312, .box_w = 19, .box_h = 24, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 332, .adv_w = 311, .box_w = 18, .box_h = 24, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 440, .adv_w = 364, .box_w = 22, .box_h = 24, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 572, .adv_w = 312, .box_w = 19, .box_h = 24, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 686, .adv_w = 336, .box_w = 20, .box_h = 24, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 806, .adv_w = 325, .box_w = 18, .box_h = 24, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 914, .adv_w = 350, .box_w = 20, .box_h = 24, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 1034, .adv_w = 336, .box_w = 20, .box_h = 24, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 1154, .adv_w = 393, .box_w = 23, .box_h = 24, .ofs_x = 1, .ofs_y = 0},
{.bitmap_index = 1292, .adv_w = 228, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 13},
{.bitmap_index = 1325, .adv_w = 544, .box_w = 22, .box_h = 26, .ofs_x = 6, .ofs_y = 4},
{.bitmap_index = 1468, .adv_w = 544, .box_w = 26, .box_h = 22, .ofs_x = 4, .ofs_y = 6},
{.bitmap_index = 1611, .adv_w = 544, .box_w = 32, .box_h = 31, .ofs_x = 1, .ofs_y = 1},
{.bitmap_index = 1859, .adv_w = 544, .box_w = 28, .box_h = 30, .ofs_x = 3, .ofs_y = 4},
{.bitmap_index = 2069, .adv_w = 544, .box_w = 34, .box_h = 35, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 2367, .adv_w = 544, .box_w = 26, .box_h = 17, .ofs_x = 4, .ofs_y = 9},
{.bitmap_index = 2478, .adv_w = 544, .box_w = 26, .box_h = 17, .ofs_x = 4, .ofs_y = 8},
{.bitmap_index = 2589, .adv_w = 544, .box_w = 36, .box_h = 36, .ofs_x = -1, .ofs_y = -1},
{.bitmap_index = 2913, .adv_w = 544, .box_w = 34, .box_h = 34, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 3202, .adv_w = 544, .box_w = 33, .box_h = 30, .ofs_x = 0, .ofs_y = 2},
{.bitmap_index = 3450, .adv_w = 544, .box_w = 16, .box_h = 35, .ofs_x = 9, .ofs_y = -1}
};
/*---------------------
* CHARACTER MAPPING
*--------------------*/
static const uint16_t unicode_list_0[] = {
0x0, 0xc, 0xd, 0xe, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x23, 0x90,
0xe022, 0xe266, 0xf0e0, 0xf0f7, 0xf1d3, 0xf209, 0xf215, 0xf3c3,
0xf3d2, 0xf405, 0xf5ad
};
/*Collect the unicode lists and glyph_id offsets*/
static const lv_font_fmt_txt_cmap_t cmaps[] =
{
{
.range_start = 32, .range_length = 62894, .glyph_id_start = 1,
.unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 27, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
}
};
/*-----------------
* KERNING
*----------------*/
/*Map glyph_ids to kern left classes*/
static const uint8_t kern_left_class_mapping[] =
{
0, 0, 1, 2, 1, 3, 0, 4,
5, 6, 7, 8, 9, 10, 3, 11,
12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
};
/*Map glyph_ids to kern right classes*/
static const uint8_t kern_right_class_mapping[] =
{
0, 0, 1, 2, 1, 3, 4, 5,
6, 7, 8, 3, 9, 10, 11, 12,
13, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
};
/*Kern values between classes*/
static const int8_t kern_class_values[] =
{
0, -4, -7, -7, 5, 5, -5, 0,
-7, 5, 0, 0, -34, -4, 2, 4,
-10, -7, -11, 4, 0, -5, 0, 0,
0, 0, -7, 4, 0, -2, -2, -5,
0, 0, -4, 0, 0, 0, 2, 5,
-4, -2, 0, 0, 0, -10, 0, -2,
0, 0, 0, 0, 0, 0, 0, 0,
-3, -3, 0, -5, -7, 0, 0, 0,
-8, 11, 5, 0, -14, -2, -7, 0,
-2, -26, 5, -4, 5, -16, 0, 0,
0, 0, -3, -3, 0, -3, -7, 0,
0, 0, -7, 5, 3, 0, 0, 0,
0, 0, 0, -4, 0, 0, 0, -10,
-28, -27, -11, 5, 0, -4, -35, -10,
0, -10, 0, -10, 3, 5, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 7, -2, -12, 5, -4, -2,
-14, -5, 0, -7, -5, -8, 5, -34,
0, 2, 23, 16, 9, -22, 4, 23,
0, 20, 0, 0
};
/*Collect the kern class' data in one place*/
static const lv_font_fmt_txt_kern_classes_t kern_classes =
{
.class_pair_values = kern_class_values,
.left_class_mapping = kern_left_class_mapping,
.right_class_mapping = kern_right_class_mapping,
.left_class_cnt = 12,
.right_class_cnt = 13,
};
/*--------------------
* ALL CUSTOM DATA
*--------------------*/
#if LVGL_VERSION_MAJOR == 8
/*Store all the custom data of the font*/
static lv_font_fmt_txt_glyph_cache_t cache;
#endif
#if LVGL_VERSION_MAJOR >= 8
static const lv_font_fmt_txt_dsc_t font_dsc = {
#else
static lv_font_fmt_txt_dsc_t font_dsc = {
#endif
.glyph_bitmap = glyph_bitmap,
.glyph_dsc = glyph_dsc,
.cmaps = cmaps,
.kern_dsc = &kern_classes,
.kern_scale = 16,
.cmap_num = 1,
.bpp = 2,
.kern_classes = 1,
.bitmap_format = 0,
#if LVGL_VERSION_MAJOR == 8
.cache = &cache
#endif
};
/*-----------------
* PUBLIC FONT
*----------------*/
/*Initialize a public general font descriptor*/
#if LVGL_VERSION_MAJOR >= 8
const lv_font_t symbol_font_34 = {
#else
lv_font_t symbol_font_34 = {
#endif
.get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/
.get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/
.line_height = 40, /*The maximum line height required by the font*/
.base_line = 5, /*Baseline measured from the bottom of the line*/
#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0)
.subpx = LV_FONT_SUBPX_NONE,
#endif
#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8
.underline_position = 0,
.underline_thickness = 0,
#endif
.dsc = &font_dsc, /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */
#if LV_VERSION_CHECK(8, 2, 0) || LVGL_VERSION_MAJOR >= 9
.fallback = NULL,
#endif
.user_data = NULL,
};
#endif /*#if SYMBOL_FONT_34*/

View File

@ -3,334 +3,334 @@
*
*/
#ifndef SYMBOLS_H
#define SYMBOLS_H
#ifndef SYMBOLS_H
#define SYMBOLS_H
#ifdef __cplusplus
extern "C" {
#endif
//included icons in bootstrap font
//use this list for font generator:
#ifdef __cplusplus
extern "C" {
#endif
LV_FONT_DECLARE(Bootstrap_Icons_12);
LV_FONT_DECLARE(Bootstrap_Icons_18);
LV_FONT_DECLARE(Bootstrap_Icons_30);
// included icons in bootstrap font
// use this list for font generator:
/*
0xF619-0xF61C,0xF7F6,0xF4FF,0xF185-0xF188,0xF30B-0xF30D,0xF493,0xF4F7,
0xF5CD-0xF5D2,0xF100,0xF479,0xF5D4,0xF5D3,0xF116,0xF117,0xF3F2,0xF229,0xF22C,0xF235,0xF238,0xF22D,0xF230,0xF231,0xF234
https://www.cogsci.ed.ac.uk/~richard/utf-8.cgi?input=f287&mode=hex
*/
#define SYM_WIFI_LOW "\xEF\x98\x99"
#define SYM_WIFI_MED "\xEF\x98\x9A"
#define SYM_WIFI_HIGH "\xEF\x98\x9C"
#define SYM_WIFI_OFF "\xEF\x98\x9B"
#define SYM_FIRE "\xEF\x9F\xB6"
#define SYM_POWER "\xEF\x93\xBF"
#define SYM_DROPLET_FULL "\xEF\x8C\x8B"
#define SYM_DROPLET_HALF "\xEF\x8C\x8C"
#define SYM_DROPLET "\xEF\x8C\x8D"
#define SYM_THERMOMETER_HALF "\xEF\x97\x8D"
#define SYM_THERMOMETER_SNOW "\xEF\x97\x90"
#define SYM_THERMOMETER_SUN "\xEF\x97\x91"
#define SYM_SHUTTER "\xEF\x84\x80"
#define SYM_ROTATE_CC "\xEF\x84\x97"
#define SYM_GRAPH "\xEF\x8F\xB2"
#define SYM_ARROW_DOWN_FILL "\xEF\x88\xA9"
#define SYM_ARROW_DOWN "\xEF\x88\xAC"
#define SYM_ARROW_UP_FILL "\xEF\x88\xB5"
#define SYM_SUNRISE "\xEF\x96\xA5"
#define SYM_SUNSET "\xEF\x96\xA7"
#define SYM_HOUSE "\xEF\x90\xA5"
#define SYM_CHECK "\xEF\x89\xB2"
#define SYM_X_LG "\xEF\x99\x99"
#define SYM_GEAR_CON "\xEF\x8F\xA3"
#define SYM_CALENDAR_WEEK "\xEF\x87\xB3"
#define ICON_WIFI_LOW "\xEF\x98\x99" // F619
#define ICON_WIFI_MED "\xEF\x98\x9A" // F61A
#define ICON_WIFI_HIGH "\xEF\x98\x9C" // F61C
#define ICON_WIFI_OFF "\xEF\x98\x9B" // F61B
#define ICON_FIRE "\xEF\x9F\xB6" // F7F6
#define ICON_POWER "\xEF\x93\xBF" // F4FF
#define ICON_BATT_CHARG "\xEF\x86\x85" // F185
#define ICON_BATT_FULL "\xEF\x86\x86" // F186
#define ICON_BATT_HALF "\xEF\x86\x87" // F187
#define ICON_BATT "\xEF\x86\x88" // F188
#define ICON_DROPLET_FULL "\xEF\x8C\x8B" // F30B
#define ICON_DROPLET_HALF "\xEF\x8C\x8C" // F30C
#define ICON_DROPLET "\xEF\x8C\x8D" // F30D
#define ICON_MOISTURE "\xEF\x92\x93" // F493
#define ICON_PLUG "\xEF\x93\xB7" // F4F7
#define ICON_THERMOMETER_HALF "\xEF\x97\x8D" // F5CD
#define ICON_THERMOMETER_HIGH "\xEF\x97\x8E" // F5CE
#define ICON_THERMOMETER_LOW "\xEF\x97\x8F" // F5CF
#define ICON_THERMOMETER_SNOW "\xEF\x97\x90" // F5D0
#define ICON_THERMOMETER_SUN "\xEF\x97\x91" // F5D1
#define ICON_THERMOMETER "\xEF\x97\x92" // F5D2
#define ICON_SHUTTER "\xEF\x84\x80" // F100
#define ICON_MENU_LINES "\xEF\x91\xB9" // F479
#define ICON_MENU_DOTS_H "\xEF\x97\x94" // F5D4
#define ICON_MENU_DOTS_V "\xEF\x97\x93" // F5D3
#define ICON_ROTATE_CW "\xEF\x84\x96" // F116
#define ICON_ROTATE_CC "\xEF\x84\x97" // F117
#define ICON_GRAPH "\xEF\x8F\xB2" // F3F2
#define ICON_ARROW_DOWN_FILL "\xEF\x88\xA9" // F229
#define ICON_ARROW_DOWN "\xEF\x88\xAC" // F22C
#define ICON_ARROW_UP_FILL "\xEF\x88\xB5" // F235
#define ICON_ARROW_UP "\xEF\x88\xB8" // F238
#define ICON_ARROW_LEFT_FILL "\xEF\x88\xAD" // F22D
#define ICON_ARROW_LEFT "\xEF\x88\xB0" // F230
#define ICON_ARROW_RIGHT_FILL "\xEF\x88\xB1" // F231
#define ICON_ARROW_RIGHT "\xEF\x88\xB4" // F234
#define SYM_BLINDS "\xEE\x8A\x86"
#define SYM_KEYBOARD_ARROW_DOWN "\xEE\x8C\x93"
#define SYM_KEYBOARD_ARROW_RIGHT "\xEE\x8C\x95"
#define SYM_KEYBOARD_ARROW_UP "\xEE\x8C\x96"
#define SYM_REPLAY "\xEE\x81\x82"
#define SYM_ECO "\xEE\xA8\xB5"
#define SYM_NATURE "\xEE\x90\x86"
#define SYM_NATURE_PEOPLE "\xEE\x90\x87"
/*-------------------------------
* Symbols from montserrat font
*-----------------------------*/
//use this list for font generator:
/*-------------------------------
* Symbols from montserrat font
*-----------------------------*/
// use this list for font generator:
/*
0x20-0x7F,0x00B0-0xB4,0x2022,0xAB,0xBB-0xBE,0x3A9,0x3C0,0x2022
µÄÖÜäöüß
*/
/*-------------------------------
* Symbols from FontAwesome font
*-----------------------------*/
/*-------------------------------
* Symbols from FontAwesome font
*-----------------------------*/
/*In the font converter use this list as range:
61441, 61448, 61451, 61452, 61453, 61457, 61459, 61461, 61465, 61468,
61473, 61478, 61479, 61480, 61502, 61507, 61512, 61515, 61516, 61517,
61521, 61522, 61523, 61524, 61543, 61544, 61550, 61552, 61553, 61556,
61559, 61560, 61561, 61563, 61587, 61589, 61636, 61637, 61639, 61641,
61664, 61671, 61674, 61683, 61724, 61732, 61787, 61931, 62016, 62017,
62018, 62019, 62020, 62087, 62099, 62189, 62212, 62810, 63426, 63650
/*In the font converter use this list as range:
61441, 61448, 61451, 61452, 61453, 61457, 61459, 61461, 61465, 61468,
61473, 61478, 61479, 61480, 61502, 61507, 61512, 61515, 61516, 61517,
61521, 61522, 61523, 61524, 61543, 61544, 61550, 61552, 61553, 61556,
61559, 61560, 61561, 61563, 61587, 61589, 61636, 61637, 61639, 61641,
61664, 61671, 61674, 61683, 61724, 61732, 61787, 61931, 62016, 62017,
62018, 62019, 62020, 62087, 62099, 62189, 62212, 62810, 63426, 63650
*/
/* These symbols can be predefined in the lv_conf.h file.
* If they are not predefined, they will use the following values
*/
/* These symbols can be predefined in the lv_conf.h file.
* If they are not predefined, they will use the following values
*/
#if !defined LV_SYMBOL_AUDIO
#define LV_SYMBOL_AUDIO "\xEF\x80\x81" /*61441, 0xF001*/
#endif
#if !defined LV_SYMBOL_AUDIO
#define LV_SYMBOL_AUDIO "\xEF\x80\x81" /*61441, 0xF001*/
#endif
#if !defined LV_SYMBOL_VIDEO
#define LV_SYMBOL_VIDEO "\xEF\x80\x88" /*61448, 0xF008*/
#endif
#if !defined LV_SYMBOL_VIDEO
#define LV_SYMBOL_VIDEO "\xEF\x80\x88" /*61448, 0xF008*/
#endif
#if !defined LV_SYMBOL_LIST
#define LV_SYMBOL_LIST "\xEF\x80\x8B" /*61451, 0xF00B*/
#endif
#if !defined LV_SYMBOL_LIST
#define LV_SYMBOL_LIST "\xEF\x80\x8B" /*61451, 0xF00B*/
#endif
#if !defined LV_SYMBOL_OK
#define LV_SYMBOL_OK "\xEF\x80\x8C" /*61452, 0xF00C*/
#endif
#if !defined LV_SYMBOL_OK
#define LV_SYMBOL_OK "\xEF\x80\x8C" /*61452, 0xF00C*/
#endif
#if !defined LV_SYMBOL_CLOSE
#define LV_SYMBOL_CLOSE "\xEF\x80\x8D" /*61453, 0xF00D*/
#endif
#if !defined LV_SYMBOL_CLOSE
#define LV_SYMBOL_CLOSE "\xEF\x80\x8D" /*61453, 0xF00D*/
#endif
#if !defined LV_SYMBOL_POWER
#define LV_SYMBOL_POWER "\xEF\x80\x91" /*61457, 0xF011*/
#endif
#if !defined LV_SYMBOL_POWER
#define LV_SYMBOL_POWER "\xEF\x80\x91" /*61457, 0xF011*/
#endif
#if !defined LV_SYMBOL_SETTINGS
#define LV_SYMBOL_SETTINGS "\xEF\x80\x93" /*61459, 0xF013*/
#endif
#if !defined LV_SYMBOL_SETTINGS
#define LV_SYMBOL_SETTINGS "\xEF\x80\x93" /*61459, 0xF013*/
#endif
#if !defined LV_SYMBOL_HOME
#define LV_SYMBOL_HOME "\xEF\x80\x95" /*61461, 0xF015*/
#endif
#if !defined LV_SYMBOL_HOME
#define LV_SYMBOL_HOME "\xEF\x80\x95" /*61461, 0xF015*/
#endif
#if !defined LV_SYMBOL_DOWNLOAD
#define LV_SYMBOL_DOWNLOAD "\xEF\x80\x99" /*61465, 0xF019*/
#endif
#if !defined LV_SYMBOL_DOWNLOAD
#define LV_SYMBOL_DOWNLOAD "\xEF\x80\x99" /*61465, 0xF019*/
#endif
#if !defined LV_SYMBOL_DRIVE
#define LV_SYMBOL_DRIVE "\xEF\x80\x9C" /*61468, 0xF01C*/
#endif
#if !defined LV_SYMBOL_DRIVE
#define LV_SYMBOL_DRIVE "\xEF\x80\x9C" /*61468, 0xF01C*/
#endif
#if !defined LV_SYMBOL_REFRESH
#define LV_SYMBOL_REFRESH "\xEF\x80\xA1" /*61473, 0xF021*/
#endif
#if !defined LV_SYMBOL_REFRESH
#define LV_SYMBOL_REFRESH "\xEF\x80\xA1" /*61473, 0xF021*/
#endif
#if !defined LV_SYMBOL_MUTE
#define LV_SYMBOL_MUTE "\xEF\x80\xA6" /*61478, 0xF026*/
#endif
#if !defined LV_SYMBOL_MUTE
#define LV_SYMBOL_MUTE "\xEF\x80\xA6" /*61478, 0xF026*/
#endif
#if !defined LV_SYMBOL_VOLUME_MID
#define LV_SYMBOL_VOLUME_MID "\xEF\x80\xA7" /*61479, 0xF027*/
#endif
#if !defined LV_SYMBOL_VOLUME_MID
#define LV_SYMBOL_VOLUME_MID "\xEF\x80\xA7" /*61479, 0xF027*/
#endif
#if !defined LV_SYMBOL_VOLUME_MAX
#define LV_SYMBOL_VOLUME_MAX "\xEF\x80\xA8" /*61480, 0xF028*/
#endif
#if !defined LV_SYMBOL_VOLUME_MAX
#define LV_SYMBOL_VOLUME_MAX "\xEF\x80\xA8" /*61480, 0xF028*/
#endif
#if !defined LV_SYMBOL_IMAGE
#define LV_SYMBOL_IMAGE "\xEF\x80\xBE" /*61502, 0xF03E*/
#endif
#if !defined LV_SYMBOL_IMAGE
#define LV_SYMBOL_IMAGE "\xEF\x80\xBE" /*61502, 0xF03E*/
#endif
#if !defined LV_SYMBOL_TINT
#define LV_SYMBOL_TINT "\xEF\x81\x83" /*61507, 0xF043*/
#endif
#if !defined LV_SYMBOL_TINT
#define LV_SYMBOL_TINT "\xEF\x81\x83" /*61507, 0xF043*/
#endif
#if !defined LV_SYMBOL_PREV
#define LV_SYMBOL_PREV "\xEF\x81\x88" /*61512, 0xF048*/
#endif
#if !defined LV_SYMBOL_PREV
#define LV_SYMBOL_PREV "\xEF\x81\x88" /*61512, 0xF048*/
#endif
#if !defined LV_SYMBOL_PLAY
#define LV_SYMBOL_PLAY "\xEF\x81\x8B" /*61515, 0xF04B*/
#endif
#if !defined LV_SYMBOL_PLAY
#define LV_SYMBOL_PLAY "\xEF\x81\x8B" /*61515, 0xF04B*/
#endif
#if !defined LV_SYMBOL_PAUSE
#define LV_SYMBOL_PAUSE "\xEF\x81\x8C" /*61516, 0xF04C*/
#endif
#if !defined LV_SYMBOL_PAUSE
#define LV_SYMBOL_PAUSE "\xEF\x81\x8C" /*61516, 0xF04C*/
#endif
#if !defined LV_SYMBOL_STOP
#define LV_SYMBOL_STOP "\xEF\x81\x8D" /*61517, 0xF04D*/
#endif
#if !defined LV_SYMBOL_STOP
#define LV_SYMBOL_STOP "\xEF\x81\x8D" /*61517, 0xF04D*/
#endif
#if !defined LV_SYMBOL_NEXT
#define LV_SYMBOL_NEXT "\xEF\x81\x91" /*61521, 0xF051*/
#endif
#if !defined LV_SYMBOL_NEXT
#define LV_SYMBOL_NEXT "\xEF\x81\x91" /*61521, 0xF051*/
#endif
#if !defined LV_SYMBOL_EJECT
#define LV_SYMBOL_EJECT "\xEF\x81\x92" /*61522, 0xF052*/
#endif
#if !defined LV_SYMBOL_EJECT
#define LV_SYMBOL_EJECT "\xEF\x81\x92" /*61522, 0xF052*/
#endif
#if !defined LV_SYMBOL_LEFT
#define LV_SYMBOL_LEFT "\xEF\x81\x93" /*61523, 0xF053*/
#endif
#if !defined LV_SYMBOL_LEFT
#define LV_SYMBOL_LEFT "\xEF\x81\x93" /*61523, 0xF053*/
#endif
#if !defined LV_SYMBOL_RIGHT
#define LV_SYMBOL_RIGHT "\xEF\x81\x94" /*61524, 0xF054*/
#endif
#if !defined LV_SYMBOL_RIGHT
#define LV_SYMBOL_RIGHT "\xEF\x81\x94" /*61524, 0xF054*/
#endif
#if !defined LV_SYMBOL_PLUS
#define LV_SYMBOL_PLUS "\xEF\x81\xA7" /*61543, 0xF067*/
#endif
#if !defined LV_SYMBOL_PLUS
#define LV_SYMBOL_PLUS "\xEF\x81\xA7" /*61543, 0xF067*/
#endif
#if !defined LV_SYMBOL_MINUS
#define LV_SYMBOL_MINUS "\xEF\x81\xA8" /*61544, 0xF068*/
#endif
#if !defined LV_SYMBOL_MINUS
#define LV_SYMBOL_MINUS "\xEF\x81\xA8" /*61544, 0xF068*/
#endif
#if !defined LV_SYMBOL_EYE_OPEN
#define LV_SYMBOL_EYE_OPEN "\xEF\x81\xAE" /*61550, 0xF06E*/
#endif
#if !defined LV_SYMBOL_EYE_OPEN
#define LV_SYMBOL_EYE_OPEN "\xEF\x81\xAE" /*61550, 0xF06E*/
#endif
#if !defined LV_SYMBOL_EYE_CLOSE
#define LV_SYMBOL_EYE_CLOSE "\xEF\x81\xB0" /*61552, 0xF070*/
#endif
#if !defined LV_SYMBOL_EYE_CLOSE
#define LV_SYMBOL_EYE_CLOSE "\xEF\x81\xB0" /*61552, 0xF070*/
#endif
#if !defined LV_SYMBOL_WARNING
#define LV_SYMBOL_WARNING "\xEF\x81\xB1" /*61553, 0xF071*/
#endif
#if !defined LV_SYMBOL_WARNING
#define LV_SYMBOL_WARNING "\xEF\x81\xB1" /*61553, 0xF071*/
#endif
#if !defined LV_SYMBOL_SHUFFLE
#define LV_SYMBOL_SHUFFLE "\xEF\x81\xB4" /*61556, 0xF074*/
#endif
#if !defined LV_SYMBOL_SHUFFLE
#define LV_SYMBOL_SHUFFLE "\xEF\x81\xB4" /*61556, 0xF074*/
#endif
#if !defined LV_SYMBOL_UP
#define LV_SYMBOL_UP "\xEF\x81\xB7" /*61559, 0xF077*/
#endif
#if !defined LV_SYMBOL_UP
#define LV_SYMBOL_UP "\xEF\x81\xB7" /*61559, 0xF077*/
#endif
#if !defined LV_SYMBOL_DOWN
#define LV_SYMBOL_DOWN "\xEF\x81\xB8" /*61560, 0xF078*/
#endif
#if !defined LV_SYMBOL_DOWN
#define LV_SYMBOL_DOWN "\xEF\x81\xB8" /*61560, 0xF078*/
#endif
#if !defined LV_SYMBOL_LOOP
#define LV_SYMBOL_LOOP "\xEF\x81\xB9" /*61561, 0xF079*/
#endif
#if !defined LV_SYMBOL_LOOP
#define LV_SYMBOL_LOOP "\xEF\x81\xB9" /*61561, 0xF079*/
#endif
#if !defined LV_SYMBOL_DIRECTORY
#define LV_SYMBOL_DIRECTORY "\xEF\x81\xBB" /*61563, 0xF07B*/
#endif
#if !defined LV_SYMBOL_DIRECTORY
#define LV_SYMBOL_DIRECTORY "\xEF\x81\xBB" /*61563, 0xF07B*/
#endif
#if !defined LV_SYMBOL_UPLOAD
#define LV_SYMBOL_UPLOAD "\xEF\x82\x93" /*61587, 0xF093*/
#endif
#if !defined LV_SYMBOL_UPLOAD
#define LV_SYMBOL_UPLOAD "\xEF\x82\x93" /*61587, 0xF093*/
#endif
#if !defined LV_SYMBOL_CALL
#define LV_SYMBOL_CALL "\xEF\x82\x95" /*61589, 0xF095*/
#endif
#if !defined LV_SYMBOL_CALL
#define LV_SYMBOL_CALL "\xEF\x82\x95" /*61589, 0xF095*/
#endif
#if !defined LV_SYMBOL_CUT
#define LV_SYMBOL_CUT "\xEF\x83\x84" /*61636, 0xF0C4*/
#endif
#if !defined LV_SYMBOL_CUT
#define LV_SYMBOL_CUT "\xEF\x83\x84" /*61636, 0xF0C4*/
#endif
#if !defined LV_SYMBOL_COPY
#define LV_SYMBOL_COPY "\xEF\x83\x85" /*61637, 0xF0C5*/
#endif
#if !defined LV_SYMBOL_COPY
#define LV_SYMBOL_COPY "\xEF\x83\x85" /*61637, 0xF0C5*/
#endif
#if !defined LV_SYMBOL_SAVE
#define LV_SYMBOL_SAVE "\xEF\x83\x87" /*61639, 0xF0C7*/
#endif
#if !defined LV_SYMBOL_SAVE
#define LV_SYMBOL_SAVE "\xEF\x83\x87" /*61639, 0xF0C7*/
#endif
#if !defined LV_SYMBOL_BARS
#define LV_SYMBOL_BARS "\xEF\x83\x89" /*61641, 0xF0C9*/
#endif
#if !defined LV_SYMBOL_BARS
#define LV_SYMBOL_BARS "\xEF\x83\x89" /*61641, 0xF0C9*/
#endif
#if !defined LV_SYMBOL_ENVELOPE
#define LV_SYMBOL_ENVELOPE "\xEF\x83\xA0" /*61664, 0xF0E0*/
#endif
#if !defined LV_SYMBOL_ENVELOPE
#define LV_SYMBOL_ENVELOPE "\xEF\x83\xA0" /*61664, 0xF0E0*/
#endif
#if !defined LV_SYMBOL_CHARGE
#define LV_SYMBOL_CHARGE "\xEF\x83\xA7" /*61671, 0xF0E7*/
#endif
#if !defined LV_SYMBOL_CHARGE
#define LV_SYMBOL_CHARGE "\xEF\x83\xA7" /*61671, 0xF0E7*/
#endif
#if !defined LV_SYMBOL_PASTE
#define LV_SYMBOL_PASTE "\xEF\x83\xAA" /*61674, 0xF0EA*/
#endif
#if !defined LV_SYMBOL_PASTE
#define LV_SYMBOL_PASTE "\xEF\x83\xAA" /*61674, 0xF0EA*/
#endif
#if !defined LV_SYMBOL_BELL
#define LV_SYMBOL_BELL "\xEF\x83\xB3" /*61683, 0xF0F3*/
#endif
#if !defined LV_SYMBOL_BELL
#define LV_SYMBOL_BELL "\xEF\x83\xB3" /*61683, 0xF0F3*/
#endif
#if !defined LV_SYMBOL_KEYBOARD
#define LV_SYMBOL_KEYBOARD "\xEF\x84\x9C" /*61724, 0xF11C*/
#endif
#if !defined LV_SYMBOL_KEYBOARD
#define LV_SYMBOL_KEYBOARD "\xEF\x84\x9C" /*61724, 0xF11C*/
#endif
#if !defined LV_SYMBOL_GPS
#define LV_SYMBOL_GPS "\xEF\x84\xA4" /*61732, 0xF124*/
#endif
#if !defined LV_SYMBOL_GPS
#define LV_SYMBOL_GPS "\xEF\x84\xA4" /*61732, 0xF124*/
#endif
#if !defined LV_SYMBOL_FILE
#define LV_SYMBOL_FILE "\xEF\x85\x9B" /*61787, 0xF158*/
#endif
#if !defined LV_SYMBOL_FILE
#define LV_SYMBOL_FILE "\xEF\x85\x9B" /*61787, 0xF158*/
#endif
#if !defined LV_SYMBOL_WIFI
#define LV_SYMBOL_WIFI "\xEF\x87\xAB" /*61931, 0xF1EB*/
#endif
#if !defined LV_SYMBOL_WIFI
#define LV_SYMBOL_WIFI "\xEF\x87\xAB" /*61931, 0xF1EB*/
#endif
#if !defined LV_SYMBOL_BATTERY_FULL
#define LV_SYMBOL_BATTERY_FULL "\xEF\x89\x80" /*62016, 0xF240*/
#endif
#if !defined LV_SYMBOL_BATTERY_FULL
#define LV_SYMBOL_BATTERY_FULL "\xEF\x89\x80" /*62016, 0xF240*/
#endif
#if !defined LV_SYMBOL_BATTERY_3
#define LV_SYMBOL_BATTERY_3 "\xEF\x89\x81" /*62017, 0xF241*/
#endif
#if !defined LV_SYMBOL_BATTERY_3
#define LV_SYMBOL_BATTERY_3 "\xEF\x89\x81" /*62017, 0xF241*/
#endif
#if !defined LV_SYMBOL_BATTERY_2
#define LV_SYMBOL_BATTERY_2 "\xEF\x89\x82" /*62018, 0xF242*/
#endif
#if !defined LV_SYMBOL_BATTERY_2
#define LV_SYMBOL_BATTERY_2 "\xEF\x89\x82" /*62018, 0xF242*/
#endif
#if !defined LV_SYMBOL_BATTERY_1
#define LV_SYMBOL_BATTERY_1 "\xEF\x89\x83" /*62019, 0xF243*/
#endif
#if !defined LV_SYMBOL_BATTERY_1
#define LV_SYMBOL_BATTERY_1 "\xEF\x89\x83" /*62019, 0xF243*/
#endif
#if !defined LV_SYMBOL_BATTERY_EMPTY
#define LV_SYMBOL_BATTERY_EMPTY "\xEF\x89\x84" /*62020, 0xF244*/
#endif
#if !defined LV_SYMBOL_BATTERY_EMPTY
#define LV_SYMBOL_BATTERY_EMPTY "\xEF\x89\x84" /*62020, 0xF244*/
#endif
#if !defined LV_SYMBOL_USB
#define LV_SYMBOL_USB "\xEF\x8a\x87" /*62087, 0xF287*/
#endif
#if !defined LV_SYMBOL_USB
#define LV_SYMBOL_USB "\xEF\x8a\x87" /*62087, 0xF287*/
#endif
#if !defined LV_SYMBOL_BLUETOOTH
#define LV_SYMBOL_BLUETOOTH "\xEF\x8a\x93" /*62099, 0xF293*/
#endif
#if !defined LV_SYMBOL_BLUETOOTH
#define LV_SYMBOL_BLUETOOTH "\xEF\x8a\x93" /*62099, 0xF293*/
#endif
#if !defined LV_SYMBOL_TRASH
#define LV_SYMBOL_TRASH "\xEF\x8B\xAD" /*62189, 0xF2ED*/
#endif
#if !defined LV_SYMBOL_TRASH
#define LV_SYMBOL_TRASH "\xEF\x8B\xAD" /*62189, 0xF2ED*/
#endif
#if !defined LV_SYMBOL_EDIT
#define LV_SYMBOL_EDIT "\xEF\x8C\x84" /*62212, 0xF304*/
#endif
#if !defined LV_SYMBOL_EDIT
#define LV_SYMBOL_EDIT "\xEF\x8C\x84" /*62212, 0xF304*/
#endif
#if !defined LV_SYMBOL_BACKSPACE
#define LV_SYMBOL_BACKSPACE "\xEF\x95\x9A" /*62810, 0xF55A*/
#endif
#if !defined LV_SYMBOL_BACKSPACE
#define LV_SYMBOL_BACKSPACE "\xEF\x95\x9A" /*62810, 0xF55A*/
#endif
#if !defined LV_SYMBOL_SD_CARD
#define LV_SYMBOL_SD_CARD "\xEF\x9F\x82" /*63426, 0xF7C2*/
#endif
#if !defined LV_SYMBOL_SD_CARD
#define LV_SYMBOL_SD_CARD "\xEF\x9F\x82" /*63426, 0xF7C2*/
#endif
#if !defined LV_SYMBOL_NEW_LINE
#define LV_SYMBOL_NEW_LINE "\xEF\xA2\xA2" /*63650, 0xF8A2*/
#endif
#if !defined LV_SYMBOL_NEW_LINE
#define LV_SYMBOL_NEW_LINE "\xEF\xA2\xA2" /*63650, 0xF8A2*/
#endif
#if !defined LV_SYMBOL_DUMMY
/** Invalid symbol at (U+F8FF). If written before a string then `lv_img` will
* show it as a label*/
#define LV_SYMBOL_DUMMY "\xEF\xA3\xBF"
#endif
#if !defined LV_SYMBOL_DUMMY
/** Invalid symbol at (U+F8FF). If written before a string then `lv_img` will show it as a label*/
#define LV_SYMBOL_DUMMY "\xEF\xA3\xBF"
#endif
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_SYMBOL_DEF_H*/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif /*LV_SYMBOL_DEF_H*/

View File

@ -1,229 +1,225 @@
#include "ui.h"
#include "actions.h"
#include "images.h"
#include "screens.h"
#include "vars.h"
#include <Arduino.h>
#include <Arduino_GFX_Library.h>
#include <Ticker.h>
#include <TouchDrvCSTXXX.hpp>
#include "ui.h"
#include "screens.h"
#include "images.h"
#include "actions.h"
#include "vars.h"
#include <string.h>
#include <Arduino_GFX_Library.h>
#include <TouchDrvCSTXXX.hpp>
#include <Ticker.h>
Arduino_DataBus *bus =
new Arduino_ESP32SPI(3 /* DC */, 5 /* CS */, 2 /* SCK */, 4 /* MOSI */,
-1 /* MISO */, FSPI /* spi_num */);
Arduino_GC9A01 *gfx =
new Arduino_GC9A01(bus, 0 /* RST */, 2 /* rotation */, true /* IPS */);
Arduino_DataBus *bus = new Arduino_ESP32SPI(3 /* DC */, 5 /* CS */, 2 /* SCK */, 4 /* MOSI */, -1 /* MISO */, FSPI /* spi_num */);
Arduino_GC9A01 *gfx = new Arduino_GC9A01(bus, 0 /* RST */, 2 /* rotation */, true /* IPS */);
TouchDrvCSTXXX touch;
Ticker fadeTicker;
bool isPressed = false, sleeping = false;
bool isPressed = false,sleeping=false;
unsigned long lastTouch;
static lv_obj_t *currentScreen = NULL;
static int16_t currentScreen = -1;
static enum ChartsEnum currentChart = CHART_ID_TEMP;
/*
static lv_obj_t *getLvglObjectFromIndex(int32_t index) {
if (index == -1) {
return 0;
}
return ((lv_obj_t **)&objects)[index];
}
*/
void loadScreen(lv_obj_t *screen) {
lv_scr_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, true);
currentScreen = screen;
void loadScreen(ScreensEnum screenId) {
currentScreen = screenId - 1;
lv_obj_t *screen = getLvglObjectFromIndex(currentScreen);
lv_scr_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false);
}
void fadeBrightness(uint16_t _newBrightness) {
uint16_t bright = ledcRead(GFX_BL);
if (_newBrightness > bright) {
bright += 10;
} else if (_newBrightness < bright) {
bright -= 10;
}
ledcWrite(GFX_BL, bright);
if (_newBrightness == bright) {
uint16_t bright = ledcRead(GFX_BL);
if (_newBrightness > bright) {
bright += 10;
} else if (_newBrightness < bright) {
bright -= 10;
}
ledcWrite(GFX_BL, bright);
if (_newBrightness == bright) {
fadeTicker.detach();
}
}
void setBacklight(uint16_t brightness, uint16_t fadeTime){
if(brightness > BL_BRIGHTNESS)
brightness = BL_BRIGHTNESS;
ledcWrite(GFX_BL,brightness);
/* uint16_t fadeTickTime = fadeTime/(abs(brightness - (uint16_t)ledcRead(GFX_BL))/10);
if(fadeTickTime < 1)
fadeTickTime = 1;
fadeTicker.detach();
}
fadeTicker.attach_ms(fadeTickTime, fadeBrightness,brightness);*/
}
void setBacklight(uint16_t brightness, uint16_t fadeTime) {
if (brightness > BL_BRIGHTNESS)
brightness = BL_BRIGHTNESS;
ledcWrite(GFX_BL, brightness);
/* uint16_t fadeTickTime = fadeTime/(abs(brightness -
(uint16_t)ledcRead(GFX_BL))/10); if(fadeTickTime < 1) fadeTickTime = 1;
fadeTicker.detach();
fadeTicker.attach_ms(fadeTickTime, fadeBrightness,brightness);*/
void DisplayInit(void){
ledcAttachPin(GFX_BL, GFX_BL);
ledcSetup(GFX_BL, 2000, 10);
ledcWrite(GFX_BL, 0);
gfx->begin(80000000);
gfx->fillScreen(0x0000);
}
void DisplayInit(void) {
ledcAttachPin(GFX_BL, GFX_BL);
ledcSetup(GFX_BL, 2000, 10);
ledcWrite(GFX_BL, 0);
gfx->begin(80000000);
gfx->fillScreen(0x0000);
void loadChart(uint8_t chartId){
if(chartId < 1 || chartId >= CHART_ID_LEN)
return;
switch(chartId){
case CHART_ID_TEMP:
lv_label_set_text(objects.chart_header,"Temperature");
lv_chart_set_ext_y_array(objects.chart,objects.chart_series,history_getTempPt());
break;
case CHART_ID_HUM:
lv_label_set_text(objects.chart_header,"Humidity");
lv_chart_set_ext_y_array(objects.chart,objects.chart_series,history_getHumPt());
break;
case CHART_ID_PRESS:
lv_label_set_text(objects.chart_header,"Pressure");
lv_chart_set_ext_y_array(objects.chart,objects.chart_series,history_getPressPt());
break;
}
currentChart = (enum ChartsEnum) chartId;
chart_autoscale();
}
void loadChart(uint8_t chartId) {
if (chartId < 1 || chartId >= CHART_ID_LEN)
return;
switch (chartId) {
case CHART_ID_TEMP:
lv_label_set_text(objects.chart_header, "Temperature");
lv_chart_set_ext_y_array(objects.chart, objects.chart_series,
history_getTempPt());
break;
case CHART_ID_HUM:
lv_label_set_text(objects.chart_header, "Humidity");
lv_chart_set_ext_y_array(objects.chart, objects.chart_series,
history_getHumPt());
break;
case CHART_ID_PRESS:
lv_label_set_text(objects.chart_header, "Pressure");
lv_chart_set_ext_y_array(objects.chart, objects.chart_series,
history_getPressPt());
break;
}
currentChart = (enum ChartsEnum)chartId;
chart_autoscale();
ScreensEnum ui_getCurrentScreen(void){
return (ScreensEnum) (currentScreen + 1);
}
lv_obj_t *ui_getCurrentScreen(void) { return currentScreen; }
ChartsEnum ui_getCurrentChart(void) { return (ChartsEnum)currentChart; }
ChartsEnum ui_getCurrentChart(void){
return (ChartsEnum) currentChart;
}
void ui_init() {
lv_disp_t *dispp = lv_disp_get_default();
lv_theme_t *theme = lv_theme_default_init(
dispp, lv_palette_main(LV_PALETTE_GREEN), lv_palette_main(LV_PALETTE_RED),
true, LV_FONT_DEFAULT);
lv_disp_set_theme(dispp, theme);
create_screen_main();
loadScreen(objects.mainScr);
create_screens();
loadScreen(SCREEN_ID_MAIN);
}
bool ui_isSleeping(void) { return sleeping; }
bool ui_isSleeping(void){
return sleeping;
}
void ui_exitSleep() {
if (sleeping) {
isPressed = true;
} else {
lastTouch = millis();
}
void ui_exitSleep(){
if(sleeping){
isPressed = true;
}else{
lastTouch = millis();
}
}
void ui_tick() {
if (millis() - lastTouch > SLEEP_TIMEOUT) {
if (!sleeping) {
displaySleep();
sleeping = true;
if(millis() - lastTouch > SLEEP_TIMEOUT){
if(!sleeping){
displaySleep();
sleeping = true;
}
unsigned long millisbefore = millis();
//while((millis()-millisbefore) < 10000 && (millis() - lastTouch) > SLEEP_TIMEOUT){
delay(200);
if (isPressed){
lastTouch = millis();
}else{
lastTouch = millis()-SLEEP_TIMEOUT-1;
}
//}
}else if(sleeping){
Serial.print("WAKE!!");
lastTouch = millis();
displayWake();
lv_obj_invalidate(objects.temp_arc);
lv_task_handler(); // let the GUI do its work
sleeping= false;
isPressed = false;
}
unsigned long millisbefore = millis();
// while((millis()-millisbefore) < 10000 && (millis() - lastTouch) >
// SLEEP_TIMEOUT){
delay(200);
if (isPressed) {
lastTouch = millis();
} else {
lastTouch = millis() - SLEEP_TIMEOUT - 1;
}
void displaySleep(){
gfx->displayOff();
setBacklight(0,300);
}
void displayWake(){
//Serial.println("wakeup");
gfx->displayOn();
delay(10);
lv_obj_invalidate(objects.temp_arc);
lv_task_handler(); // let the GUI do its work
setBacklight(BL_BRIGHTNESS,200);
}
void TouchInit()
{
pinMode(TouchRST, OUTPUT);
digitalWrite(TouchRST, LOW);
delay(30);
digitalWrite(TouchRST, HIGH);
delay(50);
touch.setPins(TouchRST, TouchInt);
Wire.begin(TouchSDA,TouchSCL); //初始化IIC设置引脚 SCL:22 SDA:21
Wire.setClock(200000); //设置频率400KHZ
if(touch.begin(Wire, TouchI2CAddr, SDA, SCL)){
Serial.println("Touch screen initialization done");
}
//}
} else if (sleeping) {
Serial.print("WAKE!!");
lastTouch = millis();
displayWake();
// lv_obj_invalidate(objects.temp_arc);
lv_task_handler(); // let the GUI do its work
sleeping = false;
isPressed = false;
attachInterrupt(TouchInt, []() {
isPressed = true;
}, CHANGE);
}
}
void displaySleep() {
gfx->displayOff();
setBacklight(0, 300);
}
void displayWake() {
// Serial.println("wakeup");
gfx->displayOn();
delay(10);
// lv_obj_invalidate(objects.temp_arc);
lv_task_handler(); // let the GUI do its work
setBacklight(BL_BRIGHTNESS, 200);
}
void TouchInit() {
pinMode(TouchRST, OUTPUT);
digitalWrite(TouchRST, LOW);
delay(30);
digitalWrite(TouchRST, HIGH);
delay(50);
touch.setPins(TouchRST, TouchInt);
Wire.begin(TouchSDA, TouchSCL); //初始化IIC设置引脚 SCL:22 SDA:21
Wire.setClock(200000); //设置频率400KHZ
if (touch.begin(Wire, TouchI2CAddr, TouchSDA, TouchSCL)) {
Serial.println("Touch screen initialization done");
}
attachInterrupt(
TouchInt, []() { isPressed = true; }, CHANGE);
}
void my_touch_read(lv_indev_t *indev, lv_indev_data_t *data) {
int16_t x = 0;
int16_t y = 0;
if (isPressed && !sleeping) {
lastTouch = millis();
isPressed = false;
uint8_t touched = touch.getPoint(&x, &y, 1);
if (touched) {
if (x > 240)
x = 240;
else if (x < 0)
x = 0;
if (y > 240)
y = 240;
else if (y < 0)
y = 0;
data->point.x = SCREEN_WIDTH - x;
data->point.y = SCREEN_HEIGHT - y;
data->state = LV_INDEV_STATE_PRESSED;
} else {
data->state = LV_INDEV_STATE_RELEASED;
void my_touch_read(lv_indev_t * indev, lv_indev_data_t * data)
{
int16_t x = 0;
int16_t y = 0;
if (isPressed && !sleeping) {
lastTouch = millis();
isPressed = false;
uint8_t touched = touch.getPoint(&x, &y, 1);
if (touched) {
data->point.x = SCREEN_WIDTH - x;
data->point.y = SCREEN_HEIGHT - y;
data->state = LV_INDEV_STATE_PRESSED;
}else {
data->state = LV_INDEV_STATE_RELEASED;
}
}
}
void log_print(lv_log_level_t level, const char * buf) {
LV_UNUSED(level);
Serial.println(buf);
Serial.flush();
}
void log_print(lv_log_level_t level, const char *buf) {
LV_UNUSED(level);
Serial.println(buf);
Serial.flush();
}
void my_flush_cb(lv_display_t *display, const lv_area_t *area,
uint8_t *px_map) {
/* The most simple case (also the slowest) to send all rendered pixels to the
* screen one-by-one. `put_px` is just an example. It needs to be
* implemented by you. */
uint16_t *buf16 =
(uint16_t *)px_map; /* Let's say it's a 16 bit (RGB565) display */
int32_t x, y;
gfx->startWrite();
gfx->writeAddrWindow(area->x1, area->y1, area->x2 - area->x1 + 1,
area->y2 - area->y1 + 1);
// bus->writeBytes(px_map,(uint32_t) (1+area->y2 - area->y1) * (1+area->x2 -
// area->x1));
for (y = area->y1; y <= area->y2; y++) {
for (x = area->x1; x <= area->x2; x++) {
void my_flush_cb(lv_display_t * display, const lv_area_t * area, uint8_t * px_map)
{
/* The most simple case (also the slowest) to send all rendered pixels to the
* screen one-by-one. `put_px` is just an example. It needs to be implemented by you. */
uint16_t * buf16 = (uint16_t *)px_map; /* Let's say it's a 16 bit (RGB565) display */
int32_t x, y;
gfx->startWrite();
gfx->writeAddrWindow(area->x1, area->y1, area->x2 - area->x1+1, area->y2 - area->y1+1);
//bus->writeBytes(px_map,(uint32_t) (1+area->y2 - area->y1) * (1+area->x2 - area->x1));
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
// //gfx->writePixel(x, y, *buf16);
bus->write16(*buf16);
bus->write16(*buf16);
// bus->write16bitBeRGBBitmapR1()
buf16++;
}
buf16++;
}
}
gfx->endWrite();
/* IMPORTANT!!!
* Inform LVGL that flushing is complete so buffer can be modified again. */
lv_display_flush_ready(display);
}
gfx->endWrite();
/* IMPORTANT!!!
* Inform LVGL that flushing is complete so buffer can be modified again. */
lv_display_flush_ready(display);
}

View File

@ -45,11 +45,11 @@ bool ui_isSleeping(void);
void ui_tick();
void DisplayInit(void);
void log_print(lv_log_level_t level, const char * buf);
void loadScreen(lv_obj_t *screen);
void loadScreen(ScreensEnum screenId);
void loadChart(uint8_t chartId);
void ui_chart_autoscale(void);
float ui_getSetTemp(void);
lv_obj_t* ui_getCurrentScreen(void);
ScreensEnum ui_getCurrentScreen(void);
ChartsEnum ui_getCurrentChart(void);
void displaySleep();
void displayWake();

View File

@ -0,0 +1,16 @@
#ifndef EEZ_LVGL_UI_EVENTS_H
#define EEZ_LVGL_UI_EVENTS_H
#include <lvgl/lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /*EEZ_LVGL_UI_EVENTS_H*/

View File

@ -0,0 +1,16 @@
#ifndef EEZ_LVGL_UI_FONTS_H
#define EEZ_LVGL_UI_FONTS_H
#include <lvgl/lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /*EEZ_LVGL_UI_FONTS_H*/

View File

@ -0,0 +1,5 @@
#include "images.h"
const ext_img_desc_t images[1] = {
0
};

View File

@ -0,0 +1,26 @@
#ifndef EEZ_LVGL_UI_IMAGES_H
#define EEZ_LVGL_UI_IMAGES_H
#include <lvgl/lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef EXT_IMG_DESC_T
#define EXT_IMG_DESC_T
typedef struct _ext_img_desc_t {
const char *name;
const lv_img_dsc_t *img_dsc;
} ext_img_desc_t;
#endif
extern const ext_img_desc_t images[1];
#ifdef __cplusplus
}
#endif
#endif /*EEZ_LVGL_UI_IMAGES_H*/

View File

@ -0,0 +1,347 @@
#include <string.h>
#include "screens.h"
#include "images.h"
#include "fonts.h"
#include "actions.h"
#include "vars.h"
#include "styles.h"
#include "ui.h"
#include <string.h>
objects_t objects;
lv_obj_t *tick_value_change_obj;
void create_screen_rollo_pos() {
lv_obj_t *obj = lv_obj_create(0);
objects.rollo_pos = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, 240, 240);
{
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_arc_create(parent_obj);
lv_obj_set_pos(obj, 88, 95);
lv_obj_set_size(obj, 93, 87);
lv_arc_set_range(obj, 0, 900);
lv_arc_set_value(obj, 0);
lv_arc_set_bg_start_angle(obj, 270);
lv_arc_set_bg_end_angle(obj, 90);
lv_obj_add_flag(obj, LV_OBJ_FLAG_ADV_HITTEST);
add_style_arc(obj);
lv_obj_set_style_arc_width(obj, 4, LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_arc_width(obj, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
lv_obj_t *obj = lv_slider_create(parent_obj);
objects.obj0 = obj;
lv_obj_set_pos(obj, 75, 68);
lv_obj_set_size(obj, 3, 140);
lv_slider_set_range(obj, 100, 0);
lv_slider_set_value(obj, 50, LV_ANIM_OFF);
add_style_slider(obj);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffa2f321), LV_PART_KNOB | LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(obj, 6, LV_PART_KNOB | LV_STATE_DEFAULT);
lv_obj_set_style_pad_left(obj, 6, LV_PART_KNOB | LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(obj, 6, LV_PART_KNOB | LV_STATE_DEFAULT);
lv_obj_set_style_pad_top(obj, 6, LV_PART_KNOB | LV_STATE_DEFAULT);
}
{
lv_obj_t *obj = lv_btn_create(parent_obj);
lv_obj_set_pos(obj, 10, 100);
lv_obj_set_size(obj, 40, 40);
add_style_button(obj);
{
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_label_create(parent_obj);
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "X");
lv_obj_set_style_align(obj, LV_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
}
}
}
{
lv_obj_t *obj = lv_obj_create(parent_obj);
objects.obj1 = obj;
lv_obj_set_pos(obj, 99, 63);
lv_obj_set_size(obj, 18, 150);
lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE|LV_OBJ_FLAG_CLICK_FOCUSABLE|LV_OBJ_FLAG_GESTURE_BUBBLE|LV_OBJ_FLAG_PRESS_LOCK|LV_OBJ_FLAG_SCROLLABLE|LV_OBJ_FLAG_SCROLL_CHAIN_HOR|LV_OBJ_FLAG_SCROLL_CHAIN_VER|LV_OBJ_FLAG_SCROLL_ELASTIC|LV_OBJ_FLAG_SCROLL_MOMENTUM|LV_OBJ_FLAG_SCROLL_WITH_ARROW|LV_OBJ_FLAG_SNAPPABLE);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xfffafafa), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(obj, 200, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_radius(obj, 5, LV_PART_MAIN | LV_STATE_DEFAULT);
{
lv_obj_t *parent_obj = obj;
{
// lam0
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lam0 = obj;
lv_obj_set_pos(obj, 7, 3);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_long_mode(obj, LV_LABEL_LONG_CLIP);
lv_label_set_text(obj, "(");
lv_obj_set_style_transform_pivot_x(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_pivot_y(obj, 7, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_rotation(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lam1
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lam1 = obj;
lv_obj_set_pos(obj, 7, 19);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "(");
lv_obj_set_style_transform_pivot_x(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_pivot_y(obj, 7, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_rotation(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lam2
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lam2 = obj;
lv_obj_set_pos(obj, 7, 35);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "(");
lv_obj_set_style_transform_pivot_x(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_pivot_y(obj, 7, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_rotation(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lam3
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lam3 = obj;
lv_obj_set_pos(obj, 7, 51);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "(");
lv_obj_set_style_transform_pivot_x(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_pivot_y(obj, 7, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_rotation(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lam4
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lam4 = obj;
lv_obj_set_pos(obj, 7, 67);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "(");
lv_obj_set_style_transform_pivot_x(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_pivot_y(obj, 7, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_rotation(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lam5
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lam5 = obj;
lv_obj_set_pos(obj, 7, 83);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "(");
lv_obj_set_style_transform_pivot_x(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_pivot_y(obj, 7, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_rotation(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lam6
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lam6 = obj;
lv_obj_set_pos(obj, 7, 99);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "(");
lv_obj_set_style_transform_pivot_x(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_pivot_y(obj, 7, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_rotation(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lam7
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lam7 = obj;
lv_obj_set_pos(obj, 7, 115);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "(");
lv_obj_set_style_transform_pivot_x(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_pivot_y(obj, 7, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_rotation(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lam8
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lam8 = obj;
lv_obj_set_pos(obj, 7, 131);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "(");
lv_obj_set_style_transform_pivot_x(obj, 3, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_pivot_y(obj, 7, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_transform_rotation(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
}
}
}
{
lv_obj_t *obj = lv_btn_create(parent_obj);
lv_obj_set_pos(obj, 193, 100);
lv_obj_set_size(obj, 40, 40);
add_style_button(obj);
{
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_label_create(parent_obj);
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "OK");
lv_obj_set_style_align(obj, LV_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
}
}
}
{
lv_obj_t *obj = lv_label_create(parent_obj);
lv_obj_set_pos(obj, 49, 9);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "Endposition\n\"Fenster Rechts\"\nfür taste AUF speichern");
lv_obj_set_style_text_align(obj, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_font(obj, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT);
}
}
tick_screen_rollo_pos();
}
void tick_screen_rollo_pos() {
}
void create_screen_menu() {
lv_obj_t *obj = lv_obj_create(0);
objects.menu = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, 240, 240);
{
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_buttonmatrix_create(parent_obj);
objects.obj2 = obj;
lv_obj_set_pos(obj, 25, 25);
lv_obj_set_size(obj, 190, 190);
static const char *map[6] = {
"Temp",
"Historie",
"\n",
"Rollos",
"Debug",
NULL,
};
lv_buttonmatrix_set_map(obj, map);
lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff15171a), LV_PART_MAIN | LV_STATE_DEFAULT);
}
}
tick_screen_menu();
}
void tick_screen_menu() {
}
void create_screen_rollos() {
lv_obj_t *obj = lv_obj_create(0);
objects.rollos = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, 240, 240);
{
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_dropdown_create(parent_obj);
lv_obj_set_pos(obj, 60, 20);
lv_obj_set_size(obj, 120, LV_SIZE_CONTENT);
lv_dropdown_set_options(obj, "Türe\nFenster\nBeide");
lv_dropdown_set_selected(obj, 1);
lv_obj_set_style_text_font(obj, &lv_font_montserrat_10, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_font(obj, &lv_font_montserrat_10, LV_PART_SELECTED | LV_STATE_DEFAULT);
}
{
lv_obj_t *obj = lv_buttonmatrix_create(parent_obj);
lv_obj_set_pos(obj, 62, 59);
lv_obj_set_size(obj, 145, 139);
static const char *map[9] = {
"^",
"#",
"\n",
"STOP",
"#",
"\n",
"\\/",
"#",
NULL,
};
static lv_buttonmatrix_ctrl_t ctrl_map[6] = {
5,
1,
5,
1,
5,
1,
};
lv_buttonmatrix_set_map(obj, map);
lv_buttonmatrix_set_ctrl_map(obj, ctrl_map);
lv_obj_set_style_pad_top(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_left(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_border_width(obj, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_pad_column(obj, 8, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_font(obj, &lv_font_montserrat_20, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
lv_obj_t *obj = lv_btn_create(parent_obj);
lv_obj_set_pos(obj, 4, 100);
lv_obj_set_size(obj, 40, 40);
add_style_button(obj);
{
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_label_create(parent_obj);
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "#");
lv_obj_set_style_align(obj, LV_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
}
}
}
}
tick_screen_rollos();
}
void tick_screen_rollos() {
}
typedef void (*tick_screen_func_t)();
tick_screen_func_t tick_screen_funcs[] = {
tick_screen_rollo_pos,
tick_screen_menu,
tick_screen_rollos,
};
void tick_screen(int screen_index) {
tick_screen_funcs[screen_index]();
}
void tick_screen_by_id(enum ScreensEnum screenId) {
tick_screen_funcs[screenId - 1]();
}
void create_screens() {
lv_disp_t *dispp = lv_disp_get_default();
lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), true, LV_FONT_DEFAULT);
lv_disp_set_theme(dispp, theme);
create_screen_rollo_pos();
create_screen_menu();
create_screen_rollos();
}

View File

@ -0,0 +1,55 @@
#ifndef EEZ_LVGL_UI_SCREENS_H
#define EEZ_LVGL_UI_SCREENS_H
#include <lvgl/lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _objects_t {
lv_obj_t *rollo_pos;
lv_obj_t *menu;
lv_obj_t *rollos;
lv_obj_t *obj0;
lv_obj_t *obj1;
lv_obj_t *lam0;
lv_obj_t *lam1;
lv_obj_t *lam2;
lv_obj_t *lam3;
lv_obj_t *lam4;
lv_obj_t *lam5;
lv_obj_t *lam6;
lv_obj_t *lam7;
lv_obj_t *lam8;
lv_obj_t *obj2;
} objects_t;
extern objects_t objects;
enum ScreensEnum {
SCREEN_ID_ROLLO_POS = 1,
SCREEN_ID_MENU = 2,
SCREEN_ID_ROLLOS = 3,
};
void create_screen_rollo_pos();
void tick_screen_rollo_pos();
void create_screen_menu();
void tick_screen_menu();
void create_screen_rollos();
void tick_screen_rollos();
void tick_screen_by_id(enum ScreensEnum screenId);
void tick_screen(int screen_index);
void create_screens();
#ifdef __cplusplus
}
#endif
#endif /*EEZ_LVGL_UI_SCREENS_H*/

View File

@ -0,0 +1,22 @@
#ifndef EEZ_LVGL_UI_STRUCTS_H
#define EEZ_LVGL_UI_STRUCTS_H
#if defined(EEZ_FOR_LVGL)
#include <eez/flow/flow.h>
#include <stdint.h>
#include <stdbool.h>
#include "vars.h"
using namespace eez;
#endif
#endif /*EEZ_LVGL_UI_STRUCTS_H*/

144
eez-project/src/ui/styles.c Normal file
View File

@ -0,0 +1,144 @@
#include "styles.h"
#include "images.h"
#include "fonts.h"
#include "ui.h"
#include "screens.h"
//
// Style: Button
//
void init_style_button_MAIN_DEFAULT(lv_style_t *style) {
lv_style_set_bg_color(style, lv_color_hex(0xff2f3237));
};
lv_style_t *get_style_button_MAIN_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_button_MAIN_DEFAULT(style);
}
return style;
};
void add_style_button(lv_obj_t *obj) {
lv_obj_add_style(obj, get_style_button_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
};
void remove_style_button(lv_obj_t *obj) {
lv_obj_remove_style(obj, get_style_button_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
};
//
// Style: arc
//
void init_style_arc_INDICATOR_DEFAULT(lv_style_t *style) {
lv_style_set_arc_color(style, lv_color_hex(0xff56f321));
};
lv_style_t *get_style_arc_INDICATOR_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_arc_INDICATOR_DEFAULT(style);
}
return style;
};
void init_style_arc_KNOB_DEFAULT(lv_style_t *style) {
lv_style_set_bg_color(style, lv_color_hex(0xffa2f321));
};
lv_style_t *get_style_arc_KNOB_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_arc_KNOB_DEFAULT(style);
}
return style;
};
void add_style_arc(lv_obj_t *obj) {
lv_obj_add_style(obj, get_style_arc_INDICATOR_DEFAULT(), LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_add_style(obj, get_style_arc_KNOB_DEFAULT(), LV_PART_KNOB | LV_STATE_DEFAULT);
};
void remove_style_arc(lv_obj_t *obj) {
lv_obj_remove_style(obj, get_style_arc_INDICATOR_DEFAULT(), LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_remove_style(obj, get_style_arc_KNOB_DEFAULT(), LV_PART_KNOB | LV_STATE_DEFAULT);
};
//
// Style: slider
//
void init_style_slider_MAIN_DEFAULT(lv_style_t *style) {
lv_style_set_bg_color(style, lv_color_hex(0xff2f3237));
lv_style_set_bg_opa(style, 255);
};
lv_style_t *get_style_slider_MAIN_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_slider_MAIN_DEFAULT(style);
}
return style;
};
void init_style_slider_INDICATOR_DEFAULT(lv_style_t *style) {
lv_style_set_bg_color(style, lv_color_hex(0xff56f321));
lv_style_set_shadow_width(style, 10);
lv_style_set_shadow_color(style, lv_color_hex(0xff56f321));
};
lv_style_t *get_style_slider_INDICATOR_DEFAULT() {
static lv_style_t *style;
if (!style) {
style = lv_malloc(sizeof(lv_style_t));
lv_style_init(style);
init_style_slider_INDICATOR_DEFAULT(style);
}
return style;
};
void add_style_slider(lv_obj_t *obj) {
lv_obj_add_style(obj, get_style_slider_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_add_style(obj, get_style_slider_INDICATOR_DEFAULT(), LV_PART_INDICATOR | LV_STATE_DEFAULT);
};
void remove_style_slider(lv_obj_t *obj) {
lv_obj_remove_style(obj, get_style_slider_MAIN_DEFAULT(), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_remove_style(obj, get_style_slider_INDICATOR_DEFAULT(), LV_PART_INDICATOR | LV_STATE_DEFAULT);
};
//
//
//
void add_style(lv_obj_t *obj, int32_t styleIndex) {
typedef void (*AddStyleFunc)(lv_obj_t *obj);
static const AddStyleFunc add_style_funcs[] = {
add_style_button,
add_style_arc,
add_style_slider,
};
add_style_funcs[styleIndex](obj);
}
void remove_style(lv_obj_t *obj, int32_t styleIndex) {
typedef void (*RemoveStyleFunc)(lv_obj_t *obj);
static const RemoveStyleFunc remove_style_funcs[] = {
remove_style_button,
remove_style_arc,
remove_style_slider,
};
remove_style_funcs[styleIndex](obj);
}

View File

@ -0,0 +1,33 @@
#ifndef EEZ_LVGL_UI_STYLES_H
#define EEZ_LVGL_UI_STYLES_H
#include <lvgl/lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
// Style: Button
lv_style_t *get_style_button_MAIN_DEFAULT();
void add_style_button(lv_obj_t *obj);
void remove_style_button(lv_obj_t *obj);
// Style: arc
lv_style_t *get_style_arc_INDICATOR_DEFAULT();
lv_style_t *get_style_arc_KNOB_DEFAULT();
void add_style_arc(lv_obj_t *obj);
void remove_style_arc(lv_obj_t *obj);
// Style: slider
lv_style_t *get_style_slider_MAIN_DEFAULT();
lv_style_t *get_style_slider_INDICATOR_DEFAULT();
void add_style_slider(lv_obj_t *obj);
void remove_style_slider(lv_obj_t *obj);
#ifdef __cplusplus
}
#endif
#endif /*EEZ_LVGL_UI_STYLES_H*/

56
eez-project/src/ui/ui.c Normal file
View File

@ -0,0 +1,56 @@
#if defined(EEZ_FOR_LVGL)
#include <eez/core/vars.h>
#endif
#include "ui.h"
#include "screens.h"
#include "images.h"
#include "actions.h"
#include "vars.h"
#if defined(EEZ_FOR_LVGL)
void ui_init() {
eez_flow_init(assets, sizeof(assets), (lv_obj_t **)&objects, sizeof(objects), images, sizeof(images), actions);
}
void ui_tick() {
eez_flow_tick();
tick_screen(g_currentScreen);
}
#else
#include <string.h>
static int16_t currentScreen = -1;
static lv_obj_t *getLvglObjectFromIndex(int32_t index) {
if (index == -1) {
return 0;
}
return ((lv_obj_t **)&objects)[index];
}
void loadScreen(enum ScreensEnum screenId) {
currentScreen = screenId - 1;
lv_obj_t *screen = getLvglObjectFromIndex(currentScreen);
lv_scr_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false);
}
void ui_init() {
create_screens();
undefined
}
void ui_tick() {
tick_screen(currentScreen);
}
#endif

33
eez-project/src/ui/ui.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef EEZ_LVGL_UI_GUI_H
#define EEZ_LVGL_UI_GUI_H
#include <lvgl/lvgl.h>
#if defined(EEZ_FOR_LVGL)
#include <eez/flow/lvgl_api.h>
#endif
#if !defined(EEZ_FOR_LVGL)
#include "screens.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
void ui_init();
void ui_tick();
#if !defined(EEZ_FOR_LVGL)
void loadScreen(enum ScreensEnum screenId);
#endif
#ifdef __cplusplus
}
#endif
#endif // EEZ_LVGL_UI_GUI_H

29
eez-project/src/ui/vars.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef EEZ_LVGL_UI_VARS_H
#define EEZ_LVGL_UI_VARS_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
// enum declarations
// Flow global variables
enum FlowGlobalVariables {
FLOW_GLOBAL_VARIABLE_NONE
};
// Native global variables
#ifdef __cplusplus
}
#endif
#endif /*EEZ_LVGL_UI_VARS_H*/

1539
eez-project/test.eez-project Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

BIN
eez.zip Normal file

Binary file not shown.

View File

@ -1,7 +0,0 @@
bootstrap-icons.woff
63001-63004,62219-62221,62611,61829-61832,62719,62711,63478,62925-62930
montserrat-regulat.ttf
0x20-0x80,0xB0, 0xB7,0xA7,0xA9,0xB0-0xB3,0xB5,0xBC-0xBE
äöüÄÖÜ
MaterialSymbolsRounded[FILL,GRAD,opsz,wght].ttf
0xe406,0xf15f,0xea35,0xea99,0xf205,0xf4c4,0xf8ca,0xe798,0xe2cd,0xefd8,0xf157,0xf172,0xf176,0xec0f,0xe818,0xe166,0xe286,0xec1f,0xec12,0xe8c7,0xe764,0xebcc,0xe86c,0xe5ca,0xe8b5,0xe15a,0xf6b9,0xea9a,0xe8b8,0xf418,0xf16f,0xe4ca,0xe4d9,0xef16,0xef10,0xe648,0xf0b0,0xf537,0xf16a,0xf166,0xf16b,0xe585,0xe846,0xf6d7,0xf6d8,0xf8bb,0xf164,0xe2cb,0xf10b,0xe5c5,0xe5c7,0xe5df,0xe5de,0xe984,0xef7d,0xe986,0xe941,0xe313,0xe314,0xe315,0xe316,0xeac3,0xead0,0xeac9,0xeacf,0xe145,0xe5cd,0xe872

View File

@ -1 +0,0 @@
{"type": "library", "name": "BME280", "version": "3.0.0", "spec": {"owner": "finitespace", "id": 901, "name": "BME280", "requirements": null, "uri": null}}

View File

@ -1,675 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -1,141 +0,0 @@
/*
BME280I2C Modes.ino
This code shows how to use predefined recommended settings from Bosch for
the BME280I2C environmental sensor.
GNU General Public License
Written: Dec 30 2015.
Last Updated: Sep 23 2017.
Connecting the BME280 Sensor:
Sensor -> Board
-----------------------------
Vin (Voltage In) -> 3.3V
Gnd (Ground) -> Gnd
SDA (Serial Data) -> A4 on Uno/Pro-Mini, 20 on Mega2560/Due, 2 Leonardo/Pro-Micro
SCK (Serial Clock) -> A5 on Uno/Pro-Mini, 21 on Mega2560/Due, 3 Leonardo/Pro-Micro
*/
#include <BME280I2C.h>
#include <Wire.h> // Needed for legacy versions of Arduino.
#define SERIAL_BAUD 115200
/* Recommended Modes -
Based on Bosch BME280I2C environmental sensor data sheet.
Weather Monitoring :
forced mode, 1 sample/minute
pressure ×1, temperature ×1, humidity ×1, filter off
Current Consumption = 0.16 μA
RMS Noise = 3.3 Pa/30 cm, 0.07 %RH
Data Output Rate 1/60 Hz
Humidity Sensing :
forced mode, 1 sample/second
pressure ×0, temperature ×1, humidity ×1, filter off
Current Consumption = 2.9 μA
RMS Noise = 0.07 %RH
Data Output Rate = 1 Hz
Indoor Navigation :
normal mode, standby time = 0.5ms
pressure ×16, temperature ×2, humidity ×1, filter = x16
Current Consumption = 633 μA
RMS Noise = 0.2 Pa/1.7 cm
Data Output Rate = 25Hz
Filter Bandwidth = 0.53 Hz
Response Time (75%) = 0.9 s
Gaming :
normal mode, standby time = 0.5ms
pressure ×4, temperature ×1, humidity ×0, filter = x16
Current Consumption = 581 μA
RMS Noise = 0.3 Pa/2.5 cm
Data Output Rate = 83 Hz
Filter Bandwidth = 1.75 Hz
Response Time (75%) = 0.3 s
*/
BME280I2C::Settings settings(
BME280::OSR_X1,
BME280::OSR_X1,
BME280::OSR_X1,
BME280::Mode_Forced,
BME280::StandbyTime_1000ms,
BME280::Filter_Off,
BME280::SpiEnable_False,
BME280I2C::I2CAddr_0x76 // I2C address. I2C specific.
);
BME280I2C bme(settings);
//////////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(SERIAL_BAUD);
while(!Serial) {} // Wait
Wire.begin();
while(!bme.begin())
{
Serial.println("Could not find BME280I2C sensor!");
delay(1000);
}
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
// Change some settings before using.
settings.tempOSR = BME280::OSR_X4;
bme.setSettings(settings);
}
//////////////////////////////////////////////////////////////////
void loop()
{
printBME280Data(&Serial);
delay(500);
}
//////////////////////////////////////////////////////////////////
void printBME280Data
(
Stream* client
)
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
client->print("Temp: ");
client->print(temp);
client->print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
client->print("\t\tHumidity: ");
client->print(hum);
client->print("% RH");
client->print("\t\tPressure: ");
client->print(pres);
client->println("Pa");
delay(1000);
}

View File

@ -1,102 +0,0 @@
/*
BME280 BRZO I2C Test.ino
This code shows how to record data from the BME280 environmental sensor
using I2C interface and https://github.com/pasko-zh/brzo_i2c library
on ESP8266.
This file is an example file, part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
Forked by Alex Shavlovsky
to support https://github.com/pasko-zh/brzo_i2c library on ESP8266.
GNU General Public License
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
Connecting the BME280 Sensor:
Sensor -> Board
-----------------------------
Vin (Voltage In) -> 3.3V
Gnd (Ground) -> Gnd
SDA (Serial Data) -> D2 on ESP8266
SCK (Serial Clock) -> D1 on ESP8266
*/
#include "Arduino.h"
#include "brzo_i2c.h"
#define USING_BRZO 1
#include "BME280I2C_BRZO.h"
#define SERIAL_BAUD 115200
const uint32_t I2C_ACK_TIMEOUT = 2000;
BME280I2C_BRZO bme; // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
bool metric = true;
//////////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(SERIAL_BAUD);
while(!Serial) {} // Wait
brzo_i2c_setup(SDA,SCL,I2C_ACK_TIMEOUT);
while(!bme.begin())
{
Serial.println("Could not find BME280 sensor!");
delay(1000);
}
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
}
//////////////////////////////////////////////////////////////////
void loop()
{
printBME280Data(&Serial);
delay(500);
}
//////////////////////////////////////////////////////////////////
void printBME280Data
(
Stream* client
)
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
client->print("Temp: ");
client->print(temp);
client->print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
client->print("\t\tHumidity: ");
client->print(hum);
client->print("% RH");
client->print("\t\tPressure: ");
client->print(pres);
client->println("Pa");
delay(1000);
}

View File

@ -1,90 +0,0 @@
/*
BME280 I2C Test.ino
This code shows how to record data from the BME280 environmental sensor
using I2C interface. This file is an example file, part of the Arduino
BME280 library.
GNU General Public License
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
Connecting the BME280 Sensor:
Sensor -> Board
-----------------------------
Vin (Voltage In) -> 3.3V
Gnd (Ground) -> Gnd
SDA (Serial Data) -> A4 on Uno/Pro-Mini, 20 on Mega2560/Due, 2 Leonardo/Pro-Micro
SCK (Serial Clock) -> A5 on Uno/Pro-Mini, 21 on Mega2560/Due, 3 Leonardo/Pro-Micro
*/
#include <BME280I2C.h>
#include <Wire.h>
#define SERIAL_BAUD 115200
BME280I2C bme; // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
//////////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(SERIAL_BAUD);
while(!Serial) {} // Wait
Wire.begin();
while(!bme.begin())
{
Serial.println("Could not find BME280 sensor!");
delay(1000);
}
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
}
//////////////////////////////////////////////////////////////////
void loop()
{
printBME280Data(&Serial);
delay(500);
}
//////////////////////////////////////////////////////////////////
void printBME280Data
(
Stream* client
)
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
client->print("Temp: ");
client->print(temp);
client->print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
client->print("\t\tHumidity: ");
client->print(hum);
client->print("% RH");
client->print("\t\tPressure: ");
client->print(pres);
client->println("Pa");
delay(1000);
}

View File

@ -1,94 +0,0 @@
/*
BME280 Spi Sw Test.ino
This code shows how to record data from the BME280 environmental sensor
using Spi interface. This file is an example file, part of the Arduino
BME280 library.
GNU General Public License
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
Connecting the BME280 Sensor:
Sensor -> Board
-----------------------------
Vin (Voltage In) -> 3.3V
Gnd (Ground) -> Gnd
SDA (Serial Data) -> A4 on Uno/Pro-Mini, 20 on Mega2560/Due, 2 Leonardo/Pro-Micro
SCK (Serial Clock) -> A5 on Uno/Pro-Mini, 21 on Mega2560/Due, 3 Leonardo/Pro-Micro
*/
#include <BME280SpiSw.h>
#define SERIAL_BAUD 115200
#define CHIP_SELECT_PIN 10
#define MOSI_PIN 11
#define MISO_PIN 12
#define SCK_PIN 13
BME280SpiSw::Settings settings(CHIP_SELECT_PIN, MOSI_PIN, MISO_PIN, SCK_PIN);
BME280SpiSw bme(settings);
bool metric = false;
//////////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(SERIAL_BAUD);
while(!Serial) {} // Wait
while(!bme.begin())
{
Serial.println("Could not find BME280 sensor!");
delay(1000);
}
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
}
//////////////////////////////////////////////////////////////////
void loop()
{
printBME280Data(&Serial);
delay(1000);
}
//////////////////////////////////////////////////////////////////
void printBME280Data
(
Stream* client
)
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
client->print("Temp: ");
client->print(temp);
client->print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
client->print("\t\tHumidity: ");
client->print(hum);
client->print("% RH");
client->print("\t\tPressure: ");
client->print(pres);
client->println("Pa");
delay(1000);
}

View File

@ -1,95 +0,0 @@
/*
BME280 Spi Test.ino
This code shows how to record data from the BME280 environmental sensor
using Spi interface. This file is an example file, part of the Arduino
BME280 library.
GNU General Public License
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
Connecting the BME280 Sensor:
Sensor -> Board
-----------------------------
Vin (Voltage In) -> 3.3V
Gnd (Ground) -> Gnd
SDA (Serial Data) -> A4 on Uno/Pro-Mini, 20 on Mega2560/Due, 2 Leonardo/Pro-Micro
SCK (Serial Clock) -> A5 on Uno/Pro-Mini, 21 on Mega2560/Due, 3 Leonardo/Pro-Micro
*/
#include <SPI.h> // Needed for legacy versions of Arduino.
#include <BME280Spi.h>
#define SERIAL_BAUD 115200
#define DEVICE_PIN 10
BME280Spi::Settings settings(DEVICE_PIN); // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
BME280Spi bme(settings);
//////////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(SERIAL_BAUD);
while(!Serial) {} // Wait
SPI.begin();
while(!bme.begin())
{
Serial.println("Could not find BME280 sensor!");
delay(1000);
}
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
}
//////////////////////////////////////////////////////////////////
void loop()
{
printBME280Data(&Serial);
delay(500);
}
//////////////////////////////////////////////////////////////////
void printBME280Data
(
Stream* client
)
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
bme.read(pres, temp, hum, tempUnit, presUnit);
client->print("Temp: ");
client->print(temp);
client->print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? 'C' :'F'));
client->print("\t\tHumidity: ");
client->print(hum);
client->print("% RH");
client->print("\t\tPressure: ");
client->print(pres);
client->println("Pa");
delay(1000);
}

View File

@ -1,145 +0,0 @@
/*
Environment_Calculations.ino
This code shows how to record data from the BME280 environmental sensor
and perform various calculations.
GNU General Public License
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
Connecting the BME280 Sensor:
Sensor -> Board
-----------------------------
Vin (Voltage In) -> 3.3V
Gnd (Ground) -> Gnd
SDA (Serial Data) -> A4 on Uno/Pro-Mini, 20 on Mega2560/Due, 2 Leonardo/Pro-Micro
SCK (Serial Clock) -> A5 on Uno/Pro-Mini, 21 on Mega2560/Due, 3 Leonardo/Pro-Micro
*/
#include <EnvironmentCalculations.h>
#include <BME280I2C.h>
#include <Wire.h>
#define SERIAL_BAUD 115200
// Assumed environmental values:
float referencePressure = 1018.6; // hPa local QFF (official meteor-station reading)
float outdoorTemp = 4.7; // °C measured local outdoor temp.
float barometerAltitude = 1650.3; // meters ... map readings + barometer position
BME280I2C::Settings settings(
BME280::OSR_X1,
BME280::OSR_X1,
BME280::OSR_X1,
BME280::Mode_Forced,
BME280::StandbyTime_1000ms,
BME280::Filter_16,
BME280::SpiEnable_False,
BME280I2C::I2CAddr_0x76
);
BME280I2C bme(settings);
//////////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(SERIAL_BAUD);
while(!Serial) {} // Wait
Wire.begin();
while(!bme.begin())
{
Serial.println("Could not find BME280 sensor!");
delay(1000);
}
switch(bme.chipModel())
{
case BME280::ChipModel_BME280:
Serial.println("Found BME280 sensor! Success.");
break;
case BME280::ChipModel_BMP280:
Serial.println("Found BMP280 sensor! No Humidity available.");
break;
default:
Serial.println("Found UNKNOWN sensor! Error!");
}
Serial.print("Assumed outdoor temperature: "); Serial.print(outdoorTemp);
Serial.print("°C\nAssumed reduced sea level Pressure: "); Serial.print(referencePressure);
Serial.print("hPa\nAssumed barometer altitude: "); Serial.print(barometerAltitude);
Serial.println("m\n***************************************");
}
//////////////////////////////////////////////////////////////////
void loop()
{
printBME280Data(&Serial);
delay(500);
}
//////////////////////////////////////////////////////////////////
void printBME280Data
(
Stream* client
)
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_hPa);
bme.read(pres, temp, hum, tempUnit, presUnit);
client->print("Temp: ");
client->print(temp);
client->print("°"+ String(tempUnit == BME280::TempUnit_Celsius ? "C" :"F"));
client->print("\t\tHumidity: ");
client->print(hum);
client->print("% RH");
client->print("\t\tPressure: ");
client->print(pres);
client->print(String(presUnit == BME280::PresUnit_hPa ? "hPa" : "Pa")); // expected hPa and Pa only
EnvironmentCalculations::AltitudeUnit envAltUnit = EnvironmentCalculations::AltitudeUnit_Meters;
EnvironmentCalculations::TempUnit envTempUnit = EnvironmentCalculations::TempUnit_Celsius;
/// To get correct local altitude/height (QNE) the reference Pressure
/// should be taken from meteorologic messages (QNH or QFF)
float altitude = EnvironmentCalculations::Altitude(pres, envAltUnit, referencePressure, outdoorTemp, envTempUnit);
float dewPoint = EnvironmentCalculations::DewPoint(temp, hum, envTempUnit);
/// To get correct seaLevel pressure (QNH, QFF)
/// the altitude value should be independent on measured pressure.
/// It is necessary to use fixed altitude point e.g. the altitude of barometer read in a map
float seaLevel = EnvironmentCalculations::EquivalentSeaLevelPressure(barometerAltitude, temp, pres, envAltUnit, envTempUnit);
float absHum = EnvironmentCalculations::AbsoluteHumidity(temp, hum, envTempUnit);
client->print("\t\tAltitude: ");
client->print(altitude);
client->print((envAltUnit == EnvironmentCalculations::AltitudeUnit_Meters ? "m" : "ft"));
client->print("\t\tDew point: ");
client->print(dewPoint);
client->print("°"+ String(envTempUnit == EnvironmentCalculations::TempUnit_Celsius ? "C" :"F"));
client->print("\t\tEquivalent Sea Level Pressure: ");
client->print(seaLevel);
client->print(String( presUnit == BME280::PresUnit_hPa ? "hPa" :"Pa")); // expected hPa and Pa only
client->print("\t\tHeat Index: ");
float heatIndex = EnvironmentCalculations::HeatIndex(temp, hum, envTempUnit);
client->print(heatIndex);
client->print("°"+ String(envTempUnit == EnvironmentCalculations::TempUnit_Celsius ? "C" :"F"));
client->print("\t\tAbsolute Humidity: ");
client->println(absHum);
delay(1000);
}

View File

@ -1,12 +0,0 @@
BME280I2C KEYWORD1
BME280Spi KEYWORD1
begin KEYWORD2
temp KEYWORD2
pres KEYWORD2
hum KEYWORD2
read KEYWORD2
Altitude KEYWORD2
EquivalentSeaLevelPressure KEYWORD2
DewPoint KEYWORD2
HeatIndex KEYWORD2
AbsoluteHumidity KEYWORD2

Before

Width:  |  Height:  |  Size: 225 B

View File

@ -1,9 +0,0 @@
name=BME280
version=3.0.0
author=Tyler Glenn <finitespaceghb2@junk.yoglenn.com>
maintainer=Tyler Glenn <finitespaceghb2@junk.yoglenn.com>
sentence=Provides a library for reading and interpreting Bosch BME280 environmental sensor data over I2C, SPI or Sw SPI.
paragraph=Reads temperature, humidity, and pressure. Includes environment calculations. Provides functions for english and metric. Also reads pressure in Pa, hPa, inHg, atm, bar, torr, N/m^2 and psi. ESP and BRZO I2C support.
category=Sensors
url=https://www.github.com/finitespace/BME280
architectures=*

View File

@ -1,431 +0,0 @@
/*
BME280.cpp
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include <Wire.h>
#include "BME280.h"
/****************************************************************/
BME280::BME280
(
const Settings& settings
):m_settings(settings),
m_initialized(false)
{
}
/****************************************************************/
bool BME280::Initialize()
{
bool success(true);
success &= ReadChipID();
if(success)
{
success &= ReadTrim();
if(m_settings.filter != Filter_Off)
{
InitializeFilter();
}
WriteSettings();
}
m_initialized = success;
return m_initialized;
}
/****************************************************************/
void BME280::InitializeFilter()
{
// Force an unfiltered measurement to populate the filter buffer.
// This fixes a bug that causes the first read to always be 28.82 °C 81732.34 hPa.
Filter filter = m_settings.filter;
m_settings.filter = Filter_Off;
WriteSettings();
float dummy;
read(dummy, dummy, dummy);
m_settings.filter = filter;
}
/****************************************************************/
bool BME280::ReadChipID()
{
uint8_t id[1];
ReadRegister(ID_ADDR, &id[0], 1);
switch(id[0])
{
case ChipModel_BME280:
m_chip_model = ChipModel_BME280;
break;
case ChipModel_BMP280:
m_chip_model = ChipModel_BMP280;
break;
default:
m_chip_model = ChipModel_UNKNOWN;
return false;
}
return true;
}
/****************************************************************/
void BME280::WriteSettings()
{
uint8_t ctrlHum, ctrlMeas, config;
CalculateRegisters(ctrlHum, ctrlMeas, config);
WriteRegister(CTRL_HUM_ADDR, ctrlHum);
WriteRegister(CTRL_MEAS_ADDR, ctrlMeas);
WriteRegister(CONFIG_ADDR, config);
}
/****************************************************************/
void BME280::setSettings
(
const Settings& settings
)
{
m_settings = settings;
WriteSettings();
}
/****************************************************************/
const BME280::Settings& BME280::getSettings() const
{
return m_settings;
}
/****************************************************************/
bool BME280::begin
(
)
{
bool success = Initialize();
success &= m_initialized;
return success;
}
/****************************************************************/
void BME280::CalculateRegisters
(
uint8_t& ctrlHum,
uint8_t& ctrlMeas,
uint8_t& config
)
{
// ctrl_hum register. (ctrl_hum[2:0] = Humidity oversampling rate.)
ctrlHum = (uint8_t)m_settings.humOSR;
// ctrl_meas register. (ctrl_meas[7:5] = temperature oversampling rate, ctrl_meas[4:2] = pressure oversampling rate, ctrl_meas[1:0] = mode.)
ctrlMeas = ((uint8_t)m_settings.tempOSR << 5) | ((uint8_t)m_settings.presOSR << 2) | (uint8_t)m_settings.mode;
// config register. (config[7:5] = standby time, config[4:2] = filter, ctrl_meas[0] = spi enable.)
config = ((uint8_t)m_settings.standbyTime << 5) | ((uint8_t)m_settings.filter << 2) | (uint8_t)m_settings.spiEnable;
}
/****************************************************************/
bool BME280::ReadTrim()
{
uint8_t ord(0);
bool success = true;
// Temp. Dig
success &= ReadRegister(TEMP_DIG_ADDR, &m_dig[ord], TEMP_DIG_LENGTH);
ord += TEMP_DIG_LENGTH;
// Pressure Dig
success &= ReadRegister(PRESS_DIG_ADDR, &m_dig[ord], PRESS_DIG_LENGTH);
ord += PRESS_DIG_LENGTH;
// Humidity Dig 1
success &= ReadRegister(HUM_DIG_ADDR1, &m_dig[ord], HUM_DIG_ADDR1_LENGTH);
ord += HUM_DIG_ADDR1_LENGTH;
// Humidity Dig 2
success &= ReadRegister(HUM_DIG_ADDR2, &m_dig[ord], HUM_DIG_ADDR2_LENGTH);
ord += HUM_DIG_ADDR2_LENGTH;
#ifdef DEBUG_ON
Serial.print("Dig: ");
for(int i = 0; i < 32; ++i)
{
Serial.print(m_dig[i], HEX);
Serial.print(" ");
}
Serial.println();
#endif
return success && ord == DIG_LENGTH;
}
/****************************************************************/
bool BME280::ReadData
(
int32_t data[SENSOR_DATA_LENGTH]
)
{
bool success;
uint8_t buffer[SENSOR_DATA_LENGTH];
// For forced mode we need to write the mode to BME280 register before reading
if (m_settings.mode == Mode_Forced)
{
WriteSettings();
}
// Registers are in order. So we can start at the pressure register and read 8 bytes.
success = ReadRegister(PRESS_ADDR, buffer, SENSOR_DATA_LENGTH);
for(int i = 0; i < SENSOR_DATA_LENGTH; ++i)
{
data[i] = static_cast<int32_t>(buffer[i]);
}
#ifdef DEBUG_ON
Serial.print("Data: ");
for(int i = 0; i < 8; ++i)
{
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.println();
#endif
return success;
}
/****************************************************************/
float BME280::CalculateTemperature
(
int32_t raw,
int32_t& t_fine,
TempUnit unit
)
{
// Code based on calibration algorthim provided by Bosch.
int32_t var1, var2, final;
uint16_t dig_T1 = (m_dig[1] << 8) | m_dig[0];
int16_t dig_T2 = (m_dig[3] << 8) | m_dig[2];
int16_t dig_T3 = (m_dig[5] << 8) | m_dig[4];
var1 = ((((raw >> 3) - ((int32_t)dig_T1 << 1))) * ((int32_t)dig_T2)) >> 11;
var2 = (((((raw >> 4) - ((int32_t)dig_T1)) * ((raw >> 4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
t_fine = var1 + var2;
final = (t_fine * 5 + 128) >> 8;
return unit == TempUnit_Celsius ? final/100.0 : final/100.0*9.0/5.0 + 32.0;
}
/****************************************************************/
float BME280::CalculateHumidity
(
int32_t raw,
int32_t t_fine
)
{
// Code based on calibration algorthim provided by Bosch.
int32_t var1;
uint8_t dig_H1 = m_dig[24];
int16_t dig_H2 = (m_dig[26] << 8) | m_dig[25];
uint8_t dig_H3 = m_dig[27];
int16_t dig_H4 = (m_dig[28] << 4) | (0x0F & m_dig[29]);
int16_t dig_H5 = (m_dig[30] << 4) | ((m_dig[29] >> 4) & 0x0F);
int8_t dig_H6 = m_dig[31];
var1 = (t_fine - ((int32_t)76800));
var1 = (((((raw << 14) - (((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * var1)) +
((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)dig_H6)) >> 10) * (((var1 *
((int32_t)dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
((int32_t)dig_H2) + 8192) >> 14));
var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)dig_H1)) >> 4));
var1 = (var1 < 0 ? 0 : var1);
var1 = (var1 > 419430400 ? 419430400 : var1);
return ((uint32_t)(var1 >> 12))/1024.0;
}
/****************************************************************/
float BME280::CalculatePressure
(
int32_t raw,
int32_t t_fine,
PresUnit unit
)
{
// Code based on calibration algorthim provided by Bosch.
int64_t var1, var2, pressure;
float final;
uint16_t dig_P1 = (m_dig[7] << 8) | m_dig[6];
int16_t dig_P2 = (m_dig[9] << 8) | m_dig[8];
int16_t dig_P3 = (m_dig[11] << 8) | m_dig[10];
int16_t dig_P4 = (m_dig[13] << 8) | m_dig[12];
int16_t dig_P5 = (m_dig[15] << 8) | m_dig[14];
int16_t dig_P6 = (m_dig[17] << 8) | m_dig[16];
int16_t dig_P7 = (m_dig[19] << 8) | m_dig[18];
int16_t dig_P8 = (m_dig[21] << 8) | m_dig[20];
int16_t dig_P9 = (m_dig[23] << 8) | m_dig[22];
var1 = (int64_t)t_fine - 128000;
var2 = var1 * var1 * (int64_t)dig_P6;
var2 = var2 + ((var1 * (int64_t)dig_P5) << 17);
var2 = var2 + (((int64_t)dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12);
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33;
if (var1 == 0) { return NAN; } // Don't divide by zero.
pressure = 1048576 - raw;
pressure = (((pressure << 31) - var2) * 3125)/var1;
var1 = (((int64_t)dig_P9) * (pressure >> 13) * (pressure >> 13)) >> 25;
var2 = (((int64_t)dig_P8) * pressure) >> 19;
pressure = ((pressure + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4);
final = ((uint32_t)pressure)/256.0;
// Conversion units courtesy of www.endmemo.com.
switch(unit){
case PresUnit_hPa: /* hPa */
final /= 100.0;
break;
case PresUnit_inHg: /* inHg */
final /= 3386.3752577878; /* final pa * 1inHg/3386.3752577878Pa */
break;
case PresUnit_atm: /* atm */
final /= 101324.99766353; /* final pa * 1 atm/101324.99766353Pa */
break;
case PresUnit_bar: /* bar */
final /= 100000.0; /* final pa * 1 bar/100kPa */
break;
case PresUnit_torr: /* torr */
final /= 133.32236534674; /* final pa * 1 torr/133.32236534674Pa */
break;
case PresUnit_psi: /* psi */
final /= 6894.744825494; /* final pa * 1psi/6894.744825494Pa */
break;
default: /* Pa (case: 0) */
break;
}
return final;
}
/****************************************************************/
float BME280::temp
(
TempUnit unit
)
{
int32_t data[8];
int32_t t_fine;
if(!ReadData(data)){ return NAN; }
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
return CalculateTemperature(rawTemp, t_fine, unit);
}
/****************************************************************/
float BME280::pres
(
PresUnit unit
)
{
int32_t data[8];
int32_t t_fine;
if(!ReadData(data)){ return NAN; }
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
uint32_t rawPressure = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
CalculateTemperature(rawTemp, t_fine);
return CalculatePressure(rawPressure, t_fine, unit);
}
/****************************************************************/
float BME280::hum()
{
int32_t data[8];
int32_t t_fine;
if(!ReadData(data)){ return NAN; }
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
uint32_t rawHumidity = (data[6] << 8) | data[7];
CalculateTemperature(rawTemp, t_fine);
return CalculateHumidity(rawHumidity, t_fine);
}
/****************************************************************/
void BME280::read
(
float& pressure,
float& temp,
float& humidity,
TempUnit tempUnit,
PresUnit presUnit
)
{
int32_t data[8];
int32_t t_fine;
if(!ReadData(data)){
pressure = temp = humidity = NAN;
return;
}
uint32_t rawPressure = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
uint32_t rawTemp = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
uint32_t rawHumidity = (data[6] << 8) | data[7];
temp = CalculateTemperature(rawTemp, t_fine, tempUnit);
pressure = CalculatePressure(rawPressure, t_fine, presUnit);
humidity = CalculateHumidity(rawHumidity, t_fine);
}
/****************************************************************/
BME280::ChipModel BME280::chipModel
(
)
{
return m_chip_model;
}

View File

@ -1,344 +0,0 @@
/*
BME280.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
*/
#ifndef TG_BME_280_H
#define TG_BME_280_H
#include "Arduino.h"
//////////////////////////////////////////////////////////////////
/// BME280 - Driver class for Bosch Bme280 sensor
///
/// Based on the data sheet provided by Bosch for
/// the Bme280 environmental sensor.
///
class BME280
{
public:
/*****************************************************************/
/* ENUMERATIONS */
/*****************************************************************/
enum TempUnit
{
TempUnit_Celsius,
TempUnit_Fahrenheit
};
enum PresUnit
{
PresUnit_Pa,
PresUnit_hPa,
PresUnit_inHg,
PresUnit_atm,
PresUnit_bar,
PresUnit_torr,
PresUnit_psi
};
enum OSR
{
OSR_Off = 0,
OSR_X1 = 1,
OSR_X2 = 2,
OSR_X4 = 3,
OSR_X8 = 4,
OSR_X16 = 5
};
enum Mode
{
Mode_Sleep = 0,
Mode_Forced = 1,
Mode_Normal = 3
};
enum StandbyTime
{
StandbyTime_500us = 0,
StandbyTime_62500us = 1,
StandbyTime_125ms = 2,
StandbyTime_250ms = 3,
StandbyTime_50ms = 4,
StandbyTime_1000ms = 5,
StandbyTime_10ms = 6,
StandbyTime_20ms = 7
};
enum Filter
{
Filter_Off = 0,
Filter_2 = 1,
Filter_4 = 2,
Filter_8 = 3,
Filter_16 = 4
};
enum SpiEnable
{
SpiEnable_False = 0,
SpiEnable_True = 1
};
enum ChipModel
{
ChipModel_UNKNOWN = 0,
ChipModel_BMP280 = 0x58,
ChipModel_BME280 = 0x60
};
/*****************************************************************/
/* STRUCTURES */
/*****************************************************************/
struct Settings
{
Settings(
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_Off,
SpiEnable _se = SpiEnable_False
): tempOSR(_tosr),
humOSR(_hosr),
presOSR(_posr),
mode(_mode),
standbyTime(_st),
filter(_filter),
spiEnable(_se) {}
OSR tempOSR;
OSR humOSR;
OSR presOSR;
Mode mode;
StandbyTime standbyTime;
Filter filter;
SpiEnable spiEnable;
};
/*****************************************************************/
/* INIT FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
/// Constructor used to create the class.
/// All parameters have default values.
BME280(
const Settings& settings);
/////////////////////////////////////////////////////////////////
/// Method used to initialize the class.
bool begin();
/*****************************************************************/
/* ENVIRONMENTAL FUNCTIONS */
/*****************************************************************/
//////////////////////////////////////////////////
/// Read the temperature from the BME280 and return a float.
float temp(
TempUnit unit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Read the pressure from the BME280 and return a float with the
/// specified unit.
float pres(
PresUnit unit = PresUnit_hPa);
/////////////////////////////////////////////////////////////////
/// Read the humidity from the BME280 and return a percentage
/// as a float.
float hum();
/////////////////////////////////////////////////////////////////
/// Read the data from the BME280 in the specified unit.
void read(
float& pressure,
float& temperature,
float& humidity,
TempUnit tempUnit = TempUnit_Celsius,
PresUnit presUnit = PresUnit_hPa);
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
////////////////////////////////////////////////////////////////
/// Method used to return ChipModel.
ChipModel chipModel();
protected:
/*****************************************************************/
/* CONSTRUCTOR INIT FUNCTIONS */
/*****************************************************************/
///////////////////////////////////////////////////////////////
/// Write configuration to BME280, return true if successful.
/// Must be called from any child classes.
virtual bool Initialize();
///////////////////////////////////////////////////////////////
/// Force a unfiltered measurement to populate the filter
/// buffer.
void InitializeFilter();
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
virtual const Settings& getSettings() const;
private:
/*****************************************************************/
/* CONSTANTS */
/*****************************************************************/
static const uint8_t CTRL_HUM_ADDR = 0xF2;
static const uint8_t CTRL_MEAS_ADDR = 0xF4;
static const uint8_t CONFIG_ADDR = 0xF5;
static const uint8_t PRESS_ADDR = 0xF7;
static const uint8_t TEMP_ADDR = 0xFA;
static const uint8_t HUM_ADDR = 0xFD;
static const uint8_t TEMP_DIG_ADDR = 0x88;
static const uint8_t PRESS_DIG_ADDR = 0x8E;
static const uint8_t HUM_DIG_ADDR1 = 0xA1;
static const uint8_t HUM_DIG_ADDR2 = 0xE1;
static const uint8_t ID_ADDR = 0xD0;
static const uint8_t TEMP_DIG_LENGTH = 6;
static const uint8_t PRESS_DIG_LENGTH = 18;
static const uint8_t HUM_DIG_ADDR1_LENGTH = 1;
static const uint8_t HUM_DIG_ADDR2_LENGTH = 7;
static const uint8_t DIG_LENGTH = 32;
static const uint8_t SENSOR_DATA_LENGTH = 8;
/*****************************************************************/
/* VARIABLES */
/*****************************************************************/
Settings m_settings;
uint8_t m_dig[32];
ChipModel m_chip_model;
bool m_initialized;
/*****************************************************************/
/* ABSTRACT FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data)=0;
/////////////////////////////////////////////////////////////////
/// Read values from BME280 registers.
virtual bool ReadRegister(
uint8_t addr,
uint8_t data[],
uint8_t length)=0;
/*****************************************************************/
/* WORKER FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
/// Calculates registers based on settings.
void CalculateRegisters(
uint8_t& ctrlHum,
uint8_t& ctrlMeas,
uint8_t& config);
/////////////////////////////////////////////////////////////////
/// Write the settings to the chip.
void WriteSettings();
/////////////////////////////////////////////////////////////////
/// Read the the chip id data from the BME280, return true if
/// successful and the id matches a known value.
bool ReadChipID();
/////////////////////////////////////////////////////////////////
/// Read the the trim data from the BME280, return true if
/// successful.
bool ReadTrim();
/////////////////////////////////////////////////////////////////
/// Read the raw data from the BME280 into an array and return
/// true if successful.
bool ReadData(
int32_t data[8]);
/////////////////////////////////////////////////////////////////
/// Calculate the temperature from the BME280 raw data and
/// BME280 trim, return a float.
float CalculateTemperature(
int32_t raw,
int32_t& t_fine,
TempUnit unit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Calculate the humidity from the BME280 raw data and BME280
/// trim, return a float.
float CalculateHumidity(
int32_t raw,
int32_t t_fine);
/////////////////////////////////////////////////////////////////
/// Calculate the pressure from the BME280 raw data and BME280
/// trim, return a float.
float CalculatePressure(
int32_t raw,
int32_t t_fine,
PresUnit unit = PresUnit_hPa);
};
#endif // TG_BME_280_H

View File

@ -1,102 +0,0 @@
/*
BME280I2CI2C.cpp
This code records data from the BME280I2C sensor and provides an API.
This file is part of the Arduino BME280I2C library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Jan 1 2016. - Happy New year!
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the BME280I2C environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include <Wire.h>
#include "BME280I2C.h"
/****************************************************************/
BME280I2C::BME280I2C
(
const Settings& settings
):BME280(settings),
m_settings(settings)
{
}
/****************************************************************/
void BME280I2C::setSettings
(
const Settings& settings
)
{
m_settings = settings;
BME280::setSettings(settings);
}
/****************************************************************/
const BME280I2C::Settings& BME280I2C::getSettings() const
{
return m_settings;
}
/****************************************************************/
bool BME280I2C::WriteRegister
(
uint8_t addr,
uint8_t data
)
{
Wire.beginTransmission(m_settings.bme280Addr);
Wire.write(addr);
Wire.write(data);
Wire.endTransmission();
return true; // TODO: Check return values from wire calls.
}
/****************************************************************/
bool BME280I2C::ReadRegister
(
uint8_t addr,
uint8_t data[],
uint8_t length
)
{
uint8_t ord(0);
Wire.beginTransmission(m_settings.bme280Addr);
Wire.write(addr);
Wire.endTransmission();
Wire.requestFrom(static_cast<uint8_t>(m_settings.bme280Addr), length);
while(Wire.available())
{
data[ord++] = Wire.read();
}
return ord == length;
}

View File

@ -1,105 +0,0 @@
/*
BME280I2C.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Sep 19 2016.
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor.
*/
#ifndef TG_BME_280_I2C_H
#define TG_BME_280_I2C_H
#include "BME280.h"
//////////////////////////////////////////////////////////////////
/// BME280I2C - I2C Implementation of BME280.
class BME280I2C: public BME280
{
public:
enum I2CAddr
{
I2CAddr_0x76 = 0x76,
I2CAddr_0x77 = 0x77
};
struct Settings : public BME280::Settings
{
Settings(
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_16,
SpiEnable _se = SpiEnable_False,
I2CAddr _addr = I2CAddr_0x76
): BME280::Settings(_tosr, _hosr, _posr, _mode, _st, _filter, _se),
bme280Addr(_addr) {}
I2CAddr bme280Addr;
};
///////////////////////////////////////////////////////////////
/// Constructor used to create the class. All parameters have
/// default values.
BME280I2C(
const Settings& settings = Settings());
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
const Settings& getSettings() const;
protected:
private:
Settings m_settings;
//////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data);
/////////////////////////////////////////////////////////////////
/// Read values from BME280 registers.
virtual bool ReadRegister(
uint8_t addr,
uint8_t data[],
uint8_t length);
};
#endif // TG_BME_280_I2C_H

View File

@ -1,97 +0,0 @@
/*
BME280I2C_BRZO.cpp
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
Forked by Alex Shavlovsky
to support https://github.com/pasko-zh/brzo_i2c library on ESP8266.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Oct 07 2017.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the BME280I2C_BRZO environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include "BME280I2C_BRZO.h"
#ifdef USING_BRZO
#include "brzo_i2c.h"
/****************************************************************/
BME280I2C_BRZO::BME280I2C_BRZO
(
const Settings& settings
):BME280I2C(settings),
m_settings(settings)
{
}
/****************************************************************/
void BME280I2C_BRZO::setSettings
(
const Settings& settings
)
{
m_settings = settings;
BME280::setSettings(settings);
}
/****************************************************************/
const BME280I2C_BRZO::Settings& BME280I2C_BRZO::getSettings() const
{
return m_settings;
}
/****************************************************************/
bool BME280I2C_BRZO::WriteRegister
(
uint8_t addr,
uint8_t data
)
{
uint8_t bf[2];
bf[0] = addr;
bf[1] = data;
brzo_i2c_start_transaction(m_settings.bme280Addr, m_settings.i2cClockRate);
brzo_i2c_write(bf, 2, false);
return (brzo_i2c_end_transaction()==0);
}
/****************************************************************/
bool BME280I2C_BRZO::ReadRegister
(
uint8_t addr,
uint8_t data[],
uint8_t length
)
{
brzo_i2c_start_transaction(m_settings.bme280Addr, m_settings.i2cClockRate);
brzo_i2c_write(&addr, 1, true);
brzo_i2c_read(data, length, false);
brzo_i2c_end_transaction();
return (brzo_i2c_end_transaction()==0);
}
#endif

View File

@ -1,101 +0,0 @@
/*
BME280I2C_BRZO.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
Forked by Alex Shavlovsky
to support https://github.com/pasko-zh/brzo_i2c library on ESP8266.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Sep 19 2016.
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor.
*/
#ifndef BME280I2C_BRZO_H
#define BME280I2C_BRZO_H
#include "BME280I2C.h"
//////////////////////////////////////////////////////////////////
/// BME280I2C_BRZO - I2C Implementation of BME280.
class BME280I2C_BRZO : public BME280I2C
{
public:
struct Settings : public BME280I2C::Settings
{
Settings(
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_Off,
SpiEnable _se = SpiEnable_False,
uint16_t _cr = 400
): BME280I2C::Settings(_tosr, _hosr, _posr, _mode, _st, _filter, _se),
i2cClockRate(_cr) {}
uint16_t i2cClockRate;
};
///////////////////////////////////////////////////////////////
/// Constructor used to create the class. All parameters have
/// default values.
BME280I2C_BRZO(
const Settings& settings = Settings());
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
const Settings& getSettings() const;
protected:
private:
Settings m_settings;
//////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data);
/////////////////////////////////////////////////////////////////
/// Read values from BME280 registers.
virtual bool ReadRegister(
uint8_t addr,
uint8_t data[],
uint8_t length);
};
#endif // BME280I2C_BRZO_H

View File

@ -1,134 +0,0 @@
/*
BME280Spi.cpp
This code records data from the BME280Spi sensor and provides an API.
This file is part of the Arduino BME280Spi library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 18 2016. - Happy Holidays!
Last Updated: Oct 07 2017.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the BME280Spi environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include "Arduino.h"
#include "BME280Spi.h"
#include <SPI.h>
/****************************************************************/
BME280Spi::BME280Spi
(
const Settings& settings
)
:BME280(settings),
m_settings(settings)
{
}
/****************************************************************/
bool BME280Spi::Initialize()
{
pinMode(m_settings.spiCsPin, OUTPUT);
digitalWrite(m_settings.spiCsPin, HIGH);
return BME280::Initialize();
}
/****************************************************************/
void BME280Spi::setSettings
(
const Settings& settings
)
{
m_settings = settings;
BME280::setSettings(settings);
}
/****************************************************************/
const BME280Spi::Settings& BME280Spi::getSettings() const
{
return m_settings;
}
/****************************************************************/
bool BME280Spi::ReadRegister
(
uint8_t addr,
uint8_t data[],
uint8_t len
)
{
SPI.beginTransaction(SPISettings(500000,MSBFIRST,SPI_MODE0));
// bme280 uses the msb to select read and write
// combine the addr with the read/write bit
uint8_t readAddr = addr | BME280_SPI_READ;
//select the device
digitalWrite(m_settings.spiCsPin, LOW);
// transfer the addr
SPI.transfer(readAddr);
// read the data
for(int i = 0; i < len; ++i)
{
// transfer 0x00 to get the data
data[i] = SPI.transfer(0);
}
// de-select the device
digitalWrite(m_settings.spiCsPin, HIGH);
SPI.endTransaction();
return true;
}
/****************************************************************/
bool BME280Spi::WriteRegister
(
uint8_t addr,
uint8_t data
)
{
SPI.beginTransaction(SPISettings(500000,MSBFIRST,SPI_MODE0));
// bme280 uses the msb to select read and write
// combine the addr with the read/write bit
uint8_t writeAddr = addr & ~0x80;
// select the device
digitalWrite(m_settings.spiCsPin, LOW);
// transfer the addr and then the data to spi device
SPI.transfer(writeAddr);
SPI.transfer(data);
// de-select the device
digitalWrite(m_settings.spiCsPin, HIGH);
SPI.endTransaction();
return true;
}

View File

@ -1,104 +0,0 @@
/*
BME280Spi.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 18 2016. - Happy Holidays!
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor.
*/
#ifndef TG_BME_280_SPI_H
#define TG_BME_280_SPI_H
#include "BME280.h"
class BME280Spi: public BME280
{
public:
struct Settings : public BME280::Settings
{
Settings(
uint8_t _cspin,
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_Off,
SpiEnable _se = SpiEnable_False
): BME280::Settings(_tosr, _hosr, _posr, _mode, _st, _filter, _se),
spiCsPin(_cspin) {}
uint8_t spiCsPin;
};
////////////////////////////////////////////////////////////////
/// Constructor used to create the class. All parameters have
/// default values.
BME280Spi(
const Settings& settings);
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
const Settings& getSettings() const;
protected:
////////////////////////////////////////////////////////////////
/// Method used at start up to initialize the class. Starts the
/// I2C interface.
virtual bool Initialize();
private:
static const uint8_t BME280_SPI_WRITE = 0x7F;
static const uint8_t BME280_SPI_READ = 0x80;
Settings m_settings;
////////////////////////////////////////////////////////////////
/// Read the data from the BME280 addr into an array and
/// return true if successful.
virtual bool ReadRegister(
uint8_t addr,
uint8_t array[],
uint8_t len);
////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data);
};
#endif // TG_BME_280_SPI_H

View File

@ -1,152 +0,0 @@
/*
BME280SpiSw.cpp
This code records data from the BME280SpiSw sensor and provides an API.
This file is part of the Arduino BME280SpiSw library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 18 2016. - Happy Holidays!
Last Updated: Dec 18 2016. - Happy Holidays!
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the BME280SpiSw environmental sensor,
calibration code based on algorithms providedBosch, some unit conversations courtesy
of www.endmemo.com, altitude equation courtesy of NOAA, and dew point equation
courtesy of Brian McNoldy at http://andrew.rsmas.miami.edu.
*/
#include "Arduino.h"
#include "BME280SpiSw.h"
/****************************************************************/
BME280SpiSw::BME280SpiSw
(
const Settings& settings
)
:BME280(settings),
m_settings(settings)
{
}
/****************************************************************/
bool BME280SpiSw::Initialize(){
digitalWrite(m_settings.spiCsPin, HIGH);
pinMode(m_settings.spiCsPin, OUTPUT);
pinMode(m_settings.spiSckPin, OUTPUT);
pinMode(m_settings.spiMosiPin, OUTPUT);
pinMode(m_settings.spiMisoPin, INPUT);
return BME280::Initialize();
}
/****************************************************************/
void BME280SpiSw::setSettings
(
const Settings& settings
)
{
m_settings = settings;
BME280::setSettings(settings);
}
/****************************************************************/
const BME280SpiSw::Settings& BME280SpiSw::getSettings() const
{
return m_settings;
}
/****************************************************************/
uint8_t BME280SpiSw::SpiTransferSw
(
uint8_t data
)
{
uint8_t resp = 0;
for (int bit = 7; bit >= 0; --bit) {
resp <<= 1;
digitalWrite(m_settings.spiSckPin, LOW);
digitalWrite(m_settings.spiMosiPin, data & (1 << bit));
digitalWrite(m_settings.spiSckPin, HIGH);
resp |= digitalRead(m_settings.spiMisoPin);
}
return resp;
}
/****************************************************************/
bool BME280SpiSw::ReadRegister
(
uint8_t addr,
uint8_t data[],
uint8_t length
)
{
// bme280 uses the msb to select read and write
// combine the addr with the read/write bit
uint8_t readAddr = addr | BME280_SPI_READ;
//select the device
digitalWrite(m_settings.spiCsPin, LOW);
// transfer the addr
SpiTransferSw(readAddr);
// read the data
for(int i = 0; i < length; ++i)
{
// transfer 0x00 to get the data
data[i] = SpiTransferSw(0);
}
// de-select the device
digitalWrite(m_settings.spiCsPin, HIGH);
return true;
}
/****************************************************************/
bool BME280SpiSw::WriteRegister
(
uint8_t addr,
uint8_t data
)
{
// bme280 uses the msb to select read and write
// combine the addr with the read/write bit
uint8_t writeAddr = addr & ~0x80;
// select the device
digitalWrite(m_settings.spiCsPin, LOW);
// transfer the addr and then the data to spi device
SpiTransferSw(writeAddr);
SpiTransferSw(data);
// de-select the device
digitalWrite(m_settings.spiCsPin, HIGH);
return true;
}

View File

@ -1,115 +0,0 @@
/*
BME280SpiSw.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 18 2016. - Happy Holidays!
Last Updated: Oct 07 2017.
This code is licensed under the GNU LGPL and is open for ditrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
Based on the data sheet provided by Bosch for the Bme280 environmental sensor.
*/
#ifndef TG_BME_280_SPI_H
#define TG_BME_280_SPI_H
#include "BME280.h"
class BME280SpiSw: public BME280{
public:
struct Settings : public BME280::Settings
{
Settings(
uint8_t _cs,
uint8_t _mosi,
uint8_t _miso,
uint8_t _sck,
OSR _tosr = OSR_X1,
OSR _hosr = OSR_X1,
OSR _posr = OSR_X1,
Mode _mode = Mode_Forced,
StandbyTime _st = StandbyTime_1000ms,
Filter _filter = Filter_Off,
SpiEnable _se = SpiEnable_False
): BME280::Settings(_tosr, _hosr, _posr, _mode, _st, _filter, _se),
spiCsPin(_cs),
spiMosiPin(_mosi),
spiMisoPin(_miso),
spiSckPin(_sck) {}
uint8_t spiCsPin;
uint8_t spiMosiPin;
uint8_t spiMisoPin;
uint8_t spiSckPin;
};
////////////////////////////////////////////////////////////////
/// Constructor for software spi
BME280SpiSw(
const Settings& settings);
/*****************************************************************/
/* ACCESSOR FUNCTIONS */
/*****************************************************************/
/////////////////////////////////////////////////////////////////
virtual void setSettings(
const Settings& settings);
/////////////////////////////////////////////////////////////////
const Settings& getSettings() const;
protected:
////////////////////////////////////////////////////////////////
/// Method used at start up to initialize the class. Starts the
/// software SPI interface.
virtual bool Initialize();
private:
static const uint8_t BME280_SPI_WRITE = 0x7F;
static const uint8_t BME280_SPI_READ = 0x80;
Settings m_settings;
////////////////////////////////////////////////////////////////
/// Does a sw spi transfer.
uint8_t SpiTransferSw(
uint8_t data);
////////////////////////////////////////////////////////////////
/// Read the data from the BME280 addr into an array and return
/// true if successful.
virtual bool ReadRegister(
uint8_t addr,
uint8_t data[],
uint8_t length);
////////////////////////////////////////////////////////////////
/// Write values to BME280 registers.
virtual bool WriteRegister(
uint8_t addr,
uint8_t data);
};
#endif // TG_BME_280_SPI_H

View File

@ -1,217 +0,0 @@
/*
EnvironmentCalculations.cpp
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Dec 30 2015.
Last Updated: Dec 23 2017.
This header must be included in any derived code or copies of the code.
*/
#include "EnvironmentCalculations.h"
#include <Arduino.h>
#include <math.h>
#define hi_coeff1 -42.379
#define hi_coeff2 2.04901523
#define hi_coeff3 10.14333127
#define hi_coeff4 -0.22475541
#define hi_coeff5 -0.00683783
#define hi_coeff6 -0.05481717
#define hi_coeff7 0.00122874
#define hi_coeff8 0.00085282
#define hi_coeff9 -0.00000199
/****************************************************************/
float EnvironmentCalculations::Altitude
(
float pressure,
AltitudeUnit altUnit,
float referencePressure,
float outdoorTemp,
TempUnit tempUnit
)
{
// Equation inverse to EquivalentSeaLevelPressure calculation.
float altitude = NAN;
if (!isnan(pressure) && !isnan(referencePressure) && !isnan(outdoorTemp))
{
if(tempUnit != TempUnit_Celsius)
outdoorTemp = (outdoorTemp - 32.0) * (5.0 / 9.0); /*conversion to [°C]*/
altitude = pow(referencePressure / pressure, 0.190234) - 1;
altitude *= ((outdoorTemp + 273.15) / 0.0065);
if(altUnit != AltitudeUnit_Meters) altitude *= 3.28084;
}
return altitude;
}
/****************************************************************/
float EnvironmentCalculations::AbsoluteHumidity
(
float temperature,
float humidity,
TempUnit tempUnit
)
{
//taken from https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/
//precision is about 0.1°C in range -30 to 35°C
//August-Roche-Magnus 6.1094 exp(17.625 x T)/(T + 243.04)
//Buck (1981) 6.1121 exp(17.502 x T)/(T + 240.97)
//reference https://www.eas.ualberta.ca/jdwilson/EAS372_13/Vomel_CIRES_satvpformulae.html
float temp = NAN;
const float mw = 18.01534; // molar mass of water g/mol
const float r = 8.31447215; // Universal gas constant J/mol/K
if (isnan(temperature) || isnan(humidity) )
{
return NAN;
}
if(tempUnit != TempUnit_Celsius)
{
temperature = (temperature - 32.0) * (5.0 / 9.0); /*conversion to [°C]*/
}
temp = pow(2.718281828, (17.67 * temperature) / (temperature + 243.5));
//return (6.112 * temp * humidity * 2.1674) / (273.15 + temperature); //simplified version
return (6.112 * temp * humidity * mw) / ((273.15 + temperature) * r); //long version
}
/****************************************************************/
//FYI: https://ehp.niehs.nih.gov/1206273/ in detail this flow graph: https://ehp.niehs.nih.gov/wp-content/uploads/2013/10/ehp.1206273.g003.png
float EnvironmentCalculations::HeatIndex
(
float temperature,
float humidity,
TempUnit tempUnit
)
{
float heatIndex(NAN);
if ( isnan(temperature) || isnan(humidity) )
{
return heatIndex;
}
if (tempUnit == TempUnit_Celsius)
{
temperature = (temperature * (9.0 / 5.0) + 32.0); /*conversion to [°F]*/
}
// Using both Rothfusz and Steadman's equations
// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
if (temperature <= 40)
{
heatIndex = temperature; //first red block
}
else
{
heatIndex = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (humidity * 0.094)); //calculate A -- from the official site, not the flow graph
if (heatIndex >= 79)
{
/*
* calculate B
* the following calculation is optimized. Simply spoken, reduzed cpu-operations to minimize used ram and runtime.
* Check the correctness with the following link:
* http://www.wolframalpha.com/input/?source=nav&i=b%3D+x1+%2B+x2*T+%2B+x3*H+%2B+x4*T*H+%2B+x5*T*T+%2B+x6*H*H+%2B+x7*T*T*H+%2B+x8*T*H*H+%2B+x9*T*T*H*H
*/
heatIndex = hi_coeff1
+ (hi_coeff2 + hi_coeff4 * humidity + temperature * (hi_coeff5 + hi_coeff7 * humidity)) * temperature
+ (hi_coeff3 + humidity * (hi_coeff6 + temperature * (hi_coeff8 + hi_coeff9 * temperature))) * humidity;
//third red block
if ((humidity < 13) && (temperature >= 80.0) && (temperature <= 112.0))
{
heatIndex -= ((13.0 - humidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);
} //fourth red block
else if ((humidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0))
{
heatIndex += (0.02 * (humidity - 85.0) * (87.0 - temperature));
}
}
}
if (tempUnit == TempUnit_Celsius)
{
return (heatIndex - 32.0) * (5.0 / 9.0); /*conversion back to [°C]*/
}
else
{
return heatIndex; //fifth red block
}
}
/****************************************************************/
float EnvironmentCalculations::EquivalentSeaLevelPressure
(
float altitude,
float temp,
float pres,
AltitudeUnit altUnit,
TempUnit tempUnit
)
{
float seaPress = NAN;
if(!isnan(altitude) && !isnan(temp) && !isnan(pres))
{
if(tempUnit != TempUnit_Celsius)
temp = (temp - 32.0) * (5.0 / 9.0); /*conversion to [°C]*/
if(altUnit != AltitudeUnit_Meters)
altitude *= 0.3048; /*conversion to meters*/
seaPress = (pres / pow(1 - ((0.0065 *altitude) / (temp + (0.0065 *altitude) + 273.15)), 5.257));
}
return seaPress;
}
/****************************************************************/
float EnvironmentCalculations::DewPoint
(
float temp,
float hum,
TempUnit tempUnit
)
{
// Equations courtesy of Brian McNoldy from http://andrew.rsmas.miami.edu;
float dewPoint = NAN;
if(!isnan(temp) && !isnan(hum))
{
if (tempUnit == TempUnit_Celsius)
{
dewPoint = 243.04 * (log(hum/100.0) + ((17.625 * temp)/(243.04 + temp)))
/(17.625 - log(hum/100.0) - ((17.625 * temp)/(243.04 + temp)));
}
else
{
float ctemp = (temp - 32.0) * 5.0/9.0;
dewPoint = 243.04 * (log(hum/100.0) + ((17.625 * ctemp)/(243.04 + ctemp)))
/(17.625 - log(hum/100.0) - ((17.625 * ctemp)/(243.04 + ctemp)));
dewPoint = dewPoint * 9.0/5.0 + 32.0;
}
}
return dewPoint;
}

View File

@ -1,129 +0,0 @@
/*
EnvironmentCalculations.h
This code records data from the BME280 sensor and provides an API.
This file is part of the Arduino BME280 library.
Copyright (C) 2016 Tyler Glenn
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Written: Oct 7 2017.
Last Updated: Dec 11 2017.
This code is licensed under the GNU LGPL and is open for distrbution
and copying in accordance with the license.
This header must be included in any derived code or copies of the code.
*/
#ifndef TG_ENVIRONMENT_CALCULATIONS_H
#define TG_ENVIRONMENT_CALCULATIONS_H
namespace EnvironmentCalculations
{
/////////////////////////////////////////////////////////////////
/// Temperature unit enumeration.
enum TempUnit
{
TempUnit_Celsius,
TempUnit_Fahrenheit
};
/////////////////////////////////////////////////////////////////
/// Altitude unit enumeration.
enum AltitudeUnit
{
AltitudeUnit_Meters,
AltitudeUnit_Feet
};
/////////////////////////////////////////////////////////////////
/// Calculate the altitude based on the pressure and temperature
/// in temptUnit.
/// @param pressure at the station in any units.
/// @param altUnit meters or feet. default=AltitudeUnit_Meters
/// @param referencePressure (usually pressure on MSL)
/// in the same units as pressure. default=1013.25hPa (ISA)
/// @param outdoorTemp temperature at the station in tempUnit
/// default=15°C (ISA)
/// @param temptUnit in °C or °F. default=TempUnit_Celsius
/// @return Calculated Altitude in altUnit.
float Altitude(
float pressure,
AltitudeUnit altUnit = AltitudeUnit_Meters,
float referencePressure = 1013.25, // [hPa] ....ISA value
float outdoorTemp = 15, // [°C] .... ISA value
TempUnit tempUnit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Calculate the heatindex based on the humidity and temperature
/// in tempUnit.
/// The formula based on the Heat Index Equation of the US National Weather Service
/// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
/// @param temperature in tempUnit
/// @param humidity in percentage
/// @param temptUnit in °C or °F. default=TempUnit_Celsius
/// @return Calculated heatindex as float in TempUnit
float HeatIndex(
float temperature,
float humidity,
TempUnit tempUnit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Calculate the absolute humidity based on the relative humidity and temperature
/// in tempUnit.
/// the formula does work for values between -30°C and 35°C with 0.1°C precision
/// @param temperature in tempUnit
/// @param humidity in percentage
/// @param tempUnit in °C. default=TempUnit_Celsius
/// @return Calculated absolute humidity in grams/m³
float AbsoluteHumidity
(
float temperature,
float humidity,
TempUnit tempUnit
);
/////////////////////////////////////////////////////////////////
/// Convert current pressure to equivalent sea-level pressure.
/// @param altitude in altUnit.
/// @param temp in tempUnit.
/// @param pressure at the station in any units.
/// @param altUnit meters or feet. default=AltitudeUnit_Meters
/// @param tempUnit in °C or °F. default=TempUnit_Celsius
/// @return Equivalent pressure at sea level. The input pressure
/// unit will determine the output
/// pressure unit.
float EquivalentSeaLevelPressure(
float altitude,
float temp,
float pres,
AltitudeUnit altUnit = AltitudeUnit_Meters,
TempUnit tempUnit = TempUnit_Celsius);
/////////////////////////////////////////////////////////////////
/// Calculate the dew point based on the temperature in tempUnit
/// and humidity.
/// @param temp in tempUnit.
/// @param hum in %.
/// @param temptUnit in °C or °F. default=TempUnit_Celsius
float DewPoint(
float temp,
float hum,
TempUnit tempUnit = TempUnit_Celsius);
}
#endif // TG_ENVIRONMENT_CALCULATIONS_H

View File

@ -1 +0,0 @@
{"type": "library", "name": "GFX Library for Arduino", "version": "1.5.6", "spec": {"owner": "moononournation", "id": 11607, "name": "GFX Library for Arduino", "requirements": null, "uri": null}}

View File

@ -1,498 +0,0 @@
# Arduino_GFX
Arduino_GFX is a Arduino graphics library supporting various displays with various data bus interfaces.
This library start rewrite from Adafruit_GFX, LovyanGFX, TFT_eSPI, Ucglib, and more...
![GitHub release (latest by date)](https://img.shields.io/github/v/release/moononournation/Arduino_GFX)
![GitHub Release Date](https://img.shields.io/github/release-date/moononournation/Arduino_GFX)
![GitHub commits since latest release (by date)](https://img.shields.io/github/commits-since/moononournation/Arduino_GFX/latest)
![GitHub last commit](https://img.shields.io/github/last-commit/moononournation/Arduino_GFX)
![GitHub Sponsors](https://img.shields.io/github/sponsors/moononournation)
![Twitter Follow](https://img.shields.io/twitter/follow/moononournation)
## Ease of use
### Simple Declaration
```C
#include <Arduino_GFX_Library.h>
Arduino_DataBus *bus = new Arduino_HWSPI(16 /* DC */, 5 /* CS */);
Arduino_GFX *gfx = new Arduino_ILI9341(bus, 17 /* RST */);
```
### And Simple Usage
```C
gfx->begin();
gfx->fillScreen(RGB565_BLACK);
gfx->setCursor(10, 10);
gfx->setTextColor(RGB565_RED);
gfx->println("Hello World!");
```
## Get Started
If you are new on this library, I always recommend try Library Example PDQgraphicstest first. You can find it at Arduino IDE -> File menu -> Examples -> GFX Library for Arduino -> PDQgraphicstest.
After open the example, you can see many tabs. The first is PDQgraphicstest, the main program. Start from the second tab, it is related header files, Arduino_GFX_databus.h, ... etc.
### Using supported Dev Device
If you are using below listed support dev device, simply select the Arduino_GFX_dev_device.h and uncomment the define of your dev device. E.g. if you are using LilyGo T-Deck:
```C
...
// #define JC3248W535
#define LILYGO_T_DECK
// #define LILYGO_T_DISPLAY
...
```
### Custom device and display
If you are not using supported dev device:
- Default DataBus is using Arduino SPI. Other DataBus can modify in Arduino_GFX_databus.h.
- Default Display is using ILI9341 LCD. Other Display can modify in Arduino_GFX_display.h.
## More Details
<details>
<summary>U8g2 Font Support</summary>
[U8g2](https://github.com/olikraus/u8g2.git) provided various font type and stored in compressed format. So U8g2 font gives more UI design possibilities and still can fit in the MCU limited storage space. Using U8g2 font in Arduino_GFX simply include U8g2lib.h before Arduino_GFX_Library.h:
```C
#include <U8g2lib.h>
#include <Arduino_GFX_Library.h>
```
And then setfont file to use:
```C
gfx->setCursor(10, 20);
gfx->setFont(u8g2_font_maniac_tr);
gfx->println("Hello World!");
```
U8g2 font list can be found at: <https://github.com/olikraus/u8g2/wiki/fntlistall>
### U8g2 Unicode (UTF8) Font Support
Another U8g2 font advantage is the font support Unicode glyphs. Simply enable setUTF8Print:
```C
gfx->begin();
gfx->fillScreen(RGB565_BLACK);
gfx->setUTF8Print(true);
```
And then print UTF8 string as usual:
```C
gfx->setCursor(0, 16);
gfx->setFont(u8g2_font_unifont_tr);
gfx->println("Hello World!");
gfx->setFont(u8g2_font_unifont_t_polish);
gfx->println("Witaj świecie!");
gfx->setFont(u8g2_font_unifont_t_vietnamese1);
gfx->println("Chào thế giới!");
gfx->setFont(u8g2_font_unifont_t_chinese2);
gfx->println("世界你好!");
gfx->setFont(u8g2_font_unifont_t_japanese1);
gfx->println("こんにちは世界!");
gfx->setFont(u8g2_font_unifont_t_korean1);
gfx->println("안녕하세요, 세계입니다!");
```
U8g2 Unifont list can be found at: <https://github.com/olikraus/u8g2/wiki/fntgrpunifont>
### Extra Fonts
Besides U8g2 generated font, Arduino_GFX also generated some useful font set:
#### [Chill-Bitmap v2.400](https://github.com/Warren2060/Chill-Bitmap)
##### u8g2_font_chill7_h_cjk
* Glyphs: 13478/13478
* Size: 254,960
* Generation script:
```console
otf2bdf ChillBitmap7x.ttf -p 6 -o ChillBitmap7x.bdf
bdfconv -v -f 1 -b 1 -m "0-4294967295" ChillBitmap7x.bdf -o u8g2_font_chill7_h_cjk.h -n u8g2_font_chill7_h_cjk
```
#### [Cubic 11 v1.013](https://github.com/ACh-K/Cubic-11)
##### u8g2_font_cubic11_h_cjk
* Glyphs: 10167/10167
* Size: 337,650
* Generation script:
```console
otf2bdf Cubic_11_1.013_R.ttf -p 9 -o Cubic_11_1.013_R.bdf
bdfconv -v -f 1 -b 1 -m "0-4294967295" Cubic_11_1.013_R.bdf -o u8g2_font_cubic11_h_cjk.h -n u8g2_font_cubic11_h_cjk
```
#### [QuanPixel](https://diaowinner.itch.io/galmuri-extended)
##### u8g2_font_quan7_h_cjk
* Glyphs: 18082/18082
* Size: 335,225
* Generation script:
```console
./bdfconv -v -f 1 -b 1 -m "0-4294967295" quan.bdf -o u8g2_font_quan7_h_cjk.h -n u8g2_font_quan7_h_cjk
```
#### [unifont_jp-14.0.02](http://unifoundry.com/pub/unifont/unifont-14.0.02/font-builds/unifont_jp-14.0.02.bdf.gz)
##### u8g2_font_unifont_h_utf8
* Glyphs: 57389/57389
* Size: 2,250,360
* Generation script:
```console
bdfconv -v -f 1 -b 1 -m "0-1114111" unifont_jp-14.0.02.bdf -o u8g2_font_unifont_h_utf8.h -n u8g2_font_unifont_h_utf8
```
##### u8g2_font_unifont_t_chinese
* Glyphs: 22145/57389
* Size: 979,557
* Generation script:
```console
bdfconv -v -f 1 -m "32-127,11904-12351,19968-40959,63744-64255,65280-65376" unifont_jp-14.0.02.bdf -o u8g2_font_unifont_t_chinese.h -n u8g2_font_unifont_t_chinese
```
##### u8g2_font_unifont_t_chinese4
* Glyphs: 7199/57389
* Size: 298,564
* Traditional Chinese common font list: <https://raw.githubusercontent.com/ButTaiwan/cjktables/master/taiwan/edu_standard_1.txt>
* Simplified Chinese common font list: <http://zht.glyphwiki.org/font/gw1197839.source>
* extra font list: 32-127,11904-12351,63744-64255,65280-65376
* Generation script:
```console
bdfconv -v -f 1 -M chinese4.list unifont_jp-14.0.02.bdf -o u8g2_font_unifont_t_chinese4.h -n u8g2_font_unifont_t_chinese4
```
##### u8g2_font_unifont_t_cjk
* Glyphs: 41364/57389
* Size: 1,704,862
* Generation script:
```console
bdfconv -v -f 1 -m "32-127,4352-4607,11904-12255,12288-19903,19968-40943,43360-43391,44032-55203,55216-55295,63744-64255,65072-65103,65280-65519" unifont_jp-14.0.02.bdf -o u8g2_font_unifont_t_cjk.h -n u8g2_font_unifont_t_cjk
```
</details>
<details>
<summary>Performance</summary>
This library is not putting speed at the first priority, but still paid much effort to make the display look smooth.
### Figures
Below are some figures compare with other 3 Arduino common display libraries.
* Arduino IDE: 1.8.15
* arduino-esp32: 1.0.6
* Dev Board: TTGO T8 v1.8
* PSRAM: disable
* Display: ILI9341
* Interface: SPI
* SPI Frequency: 40MHz
* Test time: 2021 Jun 16
| Benchmark | Adafruit_GFX | *Arduino_GFX* | Lovyan_GFX | TFT_eSPI |
| ------------------ | ------------- | ------------- | ------------- | ------------- |
| Screen fill | 195,782 | *160,094* | 154,341 | 155,938 |
| Text | 97,662 | *18,960* | 22,473 | 21,752 |
| Pixels | 1,365,211 | *903,549* | 867,702 | 775,781 |
| Lines | 1,062,311 | *412,026* | 269,060 | 264,950 |
| Horiz/Vert Lines | 17,637 | *14,197* | 13,692 | 13,833 |
| Rectangles-filled | 406,817 | *332,696* | 320,761 | 323,908 |
| Rectangles | 11,641 | *9,254* | 8,545 | 8,714 |
| Triangles-filled | 150,941 | *118,010* | 105,661 | 109,675 |
| Triangles | 58,843 | *23,570* | 15,884 | 16,277 |
| Circles-filled | 76,739 | *52,170* | 42,787 | 45,827 |
| Circles | 118,125 | *40,955* | 25,959 | 25,269 |
| Arcs-filled | N/A | *33,381* | 21,546 | N/A |
| Arcs | N/A | *66,054* | 47,901 | N/A |
| Rounded rects-fill | 408,534 | *338,136* | 318,882 | 323,189 |
| Rounded rects | 43,185 | *21,562* | 13,089 | 15,371 |
### Why Run Fast?
* No read operation. Since not all display provide read back graphic memories API, Arduino_GFX skip all read operations. It can reduce the library size footprint and sometimes reduce the operation time.
* Tailor-made data bus classes. Arduino_GFX decouple data bus operation from display driver, it is more easy to write individual data bus class for each platform.
</details>
<details>
<summary>Supported Interfaces</summary>
### Various data bus interfaces
Arduino_GFX utilizes Arduino Built-in SPI class to support 8-bit SPI for most platforms.
Most tiny displays in hobbyist electronics world support 8-bit SPI, but some require 9-bit SPI. Arduino_GFX should be the first Arduino display library that can use ESP32 SPI to support 9-bit hardware SPI. It is important to support the displays that require 9-bit SPI interface. (e.g. HX8357B, ...)
Larger displays most likely do not support standalone SPI since it is not fast enough to refresh the full screen details. Most of them support 8-bit/16-bit Parallel interface.
Some larger display require RGB + 3-bit SPI combo interface, This interface requies at most 3(9-bit SPI) + 4(CS, CD, WR, RD) + 24(RBG888) = 31 pins. Most dev board do not have enough GPIO to support this. Arduino_GFX is stick to RGB565 color, so RGB666 and RGB888 require some connection hack. E.g. RGB666 connect R5 and R6 together, B5 and B6 together to become RGB565. Then the least GPIO requirement can become 3(9-bit SPI) + 2(CD, WR) + 16(RBG565) = 21 pins. **Remember always pull down CS pin and always pull up RD pin.**
### Currently Supported data bus [[Wiki](https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class)]
* 8-bit and 9-bit hardware SPI (ESP32SPI)
* 8-bit hardware SPI (HWSPI, ESP8266SPI, mbedSPI, NRFXSPI, RPiPicoSPI)
* 8-bit and 9-bit software SPI (SWSPI)
* 8-bit parallel interface (SWPAR8, AVRPAR8, ESP32LCD8, ESP32PAR8, ESP32S2PAR8, RPiPicoPAR8, RTLPAR8, STM32PAR8)
* 16-bit parallel interface (ESP32LCD16, ESP32PAR16, ESP32S2PAR16, RPiPicoPAR16)
* RGB565+SPI interface (ESP32RGBPanel)
#### Note
ESP32LCD8, ESP32LCD16 and ESP32RGBPanel only supported by arduino-esp32 v2.x and no longer support in v3.0.
</details>
<details>
<summary>Supported Dev Board</summary>
### Currently Supported Dev Board
* Ameba RTL8722DM Board (AMB 21)
* Ameba RTL8722DM MINI Board (AMB 23)
* Arduino Mega 2560 [[demo video](https://youtu.be/Hn2cTNrkOSM)]
* Arduino Nano
* Arduino Nano BLE 33
* Arduino Pro Micro
* Arduino UNO
* Arduino UNO R4 Minima [[demo video](https://youtu.be/M1TuEU5uPb0)]
* Arduino UNO R4 WiFi [[demo video](https://youtu.be/GB90AFSLIFo)]
* ESP8266 Series
* ESP32 Series
* ESP32-C3 Series
* ESP32-S2 Series
* ESP32-S3 Series
* Raspberry Pi Pico
* Raspberry Pi Pico W
* rtlduino BW16 (by Ai-Thinker)
* Sony Spresense
* WeAct BlackPill V2.0 (BlackPill F411CE)
* [Seeed Studio XIAO SAMD21](https://www.seeedstudio.com/Seeeduino-XIAO-3Pcs-p-4546.html)
* [Seeed Studio XIAO ESP32C3](https://www.seeedstudio.com/Seeed-XIAO-ESP32C3-p-5431.html)
* [Seeed Studio XIAO ESP32S3](https://www.seeedstudio.com/XIAO-ESP32S3-p-5627.html)
</details>
<details>
<summary>Supported Dev Device</summary>
### Currently Supported Dev Device [[Wiki](https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration)]
* [ESP32-1732S019](https://www.aliexpress.com/item/1005005059421229.html) [[demo video](https://youtube.com/shorts/VS4Qb3g2dWk)] [[LVGL demo video](https://youtu.be/V5xib6OnWiM)]
* ESP32-2432S028
* ESP32-2424012 [[demo video](https://youtu.be/EXw_yEMgug8)]
* ESP32-3248S035
* ESP32-4827A043 [[demo video](https://youtu.be/pd1DTW9QHkg)] [[LVGL demo video](https://youtu.be/L8iYjiy-DUI)]
* [ESP32-4827S043](https://www.aliexpress.com/item/1005004788147691.html) [[demo video 1](https://youtu.be/60rl7QoU4Sc)] [[demo video 2](https://youtube.com/shorts/QY09u37htIk)] [[LVGL demo video](https://youtu.be/VvpILAVyPt8)]
* [ESP32-8048S043](https://www.aliexpress.com/item/1005004788147691.html) [[demo video](https://youtu.be/tXBVTAzSf58)]
* [ESP32-8048S070](https://www.aliexpress.com/item/1005004952726089.html) [[LVGL demo video](https://youtu.be/7BRGVsnQpgE)]
* [ESP32 LCDKIT](https://docs.espressif.com/projects/espressif-esp-dev-kits/en/latest/esp32/esp32-lcdkit/user_guide.html)
* [ESP32-S3-EYE](https://github.com/espressif/esp-who/blob/master/docs/en/get-started/ESP32-S3-EYE_Getting_Started_Guide.md)
* [ESP32-S3-Box](https://www.espressif.com/en/news/ESP32-S3-BOX_video)
* [ESP32-S3-Box-3](https://www.espressif.com/en/news/ESP32-S3-BOX-3)
* [ESP32-S3-RGB](https://github.com/W00ng/ESP32-S3-RGB-Panel) [[LVGL demo video](https://youtu.be/d11yUvjh34A)]
* ESP32S3-2.1-TP
* [ESPboy](https://www.espboy.com) [[demo video](https://youtu.be/Cx82XWrc8-0)]
* [Guition JC1060P470](https://www.aliexpress.com/item/1005008328088576.html) [[demo video](https://youtu.be/CF1EDSQDHQ8)] [[LVGL demo](https://youtu.be/CF1EDSQDHQ8)]
* [LILYGO T-Deck](https://www.lilygo.cc/products/t-deck?bg_ref=Ts2JN05e23) [[demo video](https://youtube.com/shorts/fXKTVqjUoPM)]
* [LILYGO T-Deck Plus](https://www.lilygo.cc/products/t-deck-plus-1?bg_ref=Ts2JN05e23)
* [LILYGO T-Display](https://www.lilygo.cc/products/lilygo®-ttgo-t-display-1-14-inch-lcd-esp32-control-board?bg_ref=Ts2JN05e23)
* [LILYGO T-Display-S3](https://www.lilygo.cc/products/t-display-s3?bg_ref=Ts2JN05e23) [[demo video](https://youtu.be/kpRC64QNQAo)]
* [LILYGO T-Display-S3 AMOLED](https://www.lilygo.cc/products/t-display-s3-amoled?bg_ref=Ts2JN05e23) [[demo video](https://youtu.be/NvOGJAMlh1M)]
* [LILYGO T-Display-S3 AMOLED 1.64](https://www.lilygo.cc/products/t-display-s3-amoled-1-64?bg_ref=Ts2JN05e23) [[demo video](https://youtu.be/5O3fQ1xNsrg)][[LVGL demo video](https://youtu.be/6UEaxWfxm9g)]
* [LILYGO T-Display S3 Long](https://www.lilygo.cc/products/t-display-s3-long?bg_ref=Ts2JN05e23)[[LVGL demo video](https://youtu.be/OuxLFwxvcVc)]
* [LILYGO T-Display S3 Pro](https://www.lilygo.cc/products/t-display-s3-pro?bg_ref=Ts2JN05e23) [[demo video](https://youtube.com/shorts/PE-GKTzbdP8)]
* [LILYGO T-QT](https://www.lilygo.cc/products/t-qt-pro?bg_ref=Ts2JN05e23) [[demo video](https://youtube.com/shorts/V1MCQ1tQ8PM)]
* [LILYGO T-RGB](https://www.lilygo.cc/products/t-rgb?bg_ref=Ts2JN05e23) [[LVGL demo video](https://youtu.be/BKEl_pWp_qQ)]
* [LILYGO T-Track](https://www.lilygo.cc/products/t-track?bg_ref=Ts2JN05e23) [[demo video](https://youtu.be/6wmUhp-5eMg)][[LVGL demo video](https://youtu.be/wQjMu5JZSkg)]
* LILYGO T-Watch
* [LILYGO T-Watch 2021](https://www.lilygo.cc/products/t-watch-2021?bg_ref=Ts2JN05e23)
* [LILYGO T4 S3](https://www.lilygo.cc/products/t4-s3?bg_ref=Ts2JN05e23)[[LVGL demo video](https://youtu.be/h4vXEYrDERM)]
* [M5Stack Core Family](https://shop.m5stack.com/collections/m5-controllers/CORE)
* [M5Stack AtomS3](https://shop.m5stack.com/products/atoms3-dev-kit-w-0-85-inch-screen)[[demo video](https://youtu.be/8u4TwZHmnN0)]
* [Makerfabs ESP32 3.5" TFT Touch with Camera](https://www.makerfabs.com/esp32-3.5-inch-tft-touch-capacitive-with-camera.html)
* [Makerfabs ESP32-S3 TFT 4.0"](https://www.makerfabs.com/esp32-s3-parallel-tft-with-touch-4-inch.html) [[demo video](https://youtu.be/Fmxd-Xu97C8)]
* [Makerfabs ESP32-S3 TFT 4.3" v1.3](https://www.makerfabs.com/esp32-s3-parallel-tft-with-touch-4-3-inch.html) [[demo video](https://youtu.be/oQ57L2gTHoo)]
* [Odroid Go](https://www.hardkernel.com/shop/odroid-go/)
* [seeed studio Wio Terminal](https://wiki.seeedstudio.com/Wio-Terminal-Getting-Started/)
* [Waveshare RP2040-LCD-0.96](https://www.waveshare.com/rp2040-lcd-0.96.htm?&aff_id=107987)
* [Waveshare RP2040-LCD-1.28](https://www.waveshare.com/rp2040-lcd-1.28.htm?&aff_id=107987)
* [Waveshare RP2350-LCD-0.96](https://www.waveshare.com/rp2350-lcd-0.96.htm?&aff_id=107987)
* [Waveshare ESP32-C6-LCD-1.47](https://www.waveshare.com/esp32-c6-lcd-1.47.htm?&aff_id=107987)
* [Waveshare ESP32-S3-Touch-LCD-2.8](https://www.waveshare.com/esp32-s3-touch-lcd-2.8.htm?&aff_id=107987)
* [wireless-tag WT-32-SC01](http://www.wireless-tag.com/portfolio/wt32-sc01/)
* [Elecrow ESP Terminal with 3.5" parallel RGB display DLC35010R](https://www.elecrow.com/esp-terminal-with-esp32-3-5-inch-parallel-480x320-tft-capacitive-touch-display-rgb-by-chip-ili9488.html) [[demo video](https://youtu.be/QRDVuwayNFw)]
* [Elecrow Wizee-ESP32 WZ8048C050](https://www.elecrow.com/esp32-display-5-inch-hmi-display-rgb-tft-lcd-touch-screen-support-lvgl.html)
* [wireless-tag ZX2D10GE10R-V4848](https://github.com/wireless-tag-com/ZX2D10GE01R-V4848)
* [wireless-tag ZX3D50CE02S](https://github.com/wireless-tag-com/ZX3D50CE02S)
* [wireless-tag ZX3D95CE01S-AR](https://github.com/wireless-tag-com/ZX3D95CE01S-AR-4848)
* [wireless-tag ZX3D95CE01S-TR](https://github.com/wireless-tag-com/ZX3D95CE01S-TR-4848) [[demo video](https://www.youtube.com/shorts/5u6_C-krK2Q)]
* [QM Smart Panlee 7.0 inch serial screen ZX7D00CE01S](http://en.smartpanle.com/product-item-19.html) [[demo video](https://youtu.be/r-zAMUzpkGE)]
</details>
<details>
<summary>Supported Display</summary>
### Currently Supported Display [[Wiki](https://github.com/moononournation/Arduino_GFX/wiki/Display-Class)]
* GC9A01 240x240 round display [[demo video](https://youtu.be/kJrAFm20-zg)]
* GC9106 80x160 [[demo video](https://youtu.be/RToGeeb1jxQ)]
* GC9107 128x128 [[demo video](https://youtube.com/shorts/V1MCQ1tQ8PM)]
* GC9503V 480x480 (RGB) [[demo video](https://youtube.com/shorts/hk7ZMBRCmjI)]
* HX8347C 240x320 [[demo video](https://youtu.be/25ymuV51YQM)]
* HX8347D 240x320 [[demo video](https://youtu.be/sv6LGkLRZjI)]
* HX8352C 240x400 [[demo video](https://youtu.be/m2xWYbS3t7s)]
* HX8357A 320x480 [[demo video](https://youtu.be/wJkLO_xCTXA)] (currently only portrait works, i.e. rotation 0 and 2)
* HX8357B 320x480 (9-bit SPI) [[demo video](https://youtu.be/pB6_LOCiUqg)]
* HX8369A 480x800 [[demo video](https://youtu.be/sXpU8bhtXKQ)] [[LVGL demo video](https://youtu.be/q575lTuVDcU)]
* ILI6122 480x800 (RGB)
* ILI6485 480x272 (RGB) [[demo video](https://youtu.be/60rl7QoU4Sc)]
* ILI9225 176x220 [[demo video](https://youtu.be/jm2UrCG27F4)]
* ILI9341 240x320 [[demo video](https://youtu.be/NtlEEL7MkQY)]
* ILI9341 240x320 (8-bit/16-bit Parallel) [[demo video](https://youtu.be/xuVx0dzQ7nM)]
* ILI9342 320x240 [[demo video](https://youtu.be/UoPpIjVSO5Q)]
* ILI9481 320x480 (18 bit color) [[demo video](https://youtu.be/YxjuuCFhlqM)]
* ILI9486 320x480 (8-bit/16-bit Parallel) [[demo video](https://youtu.be/GB90AFSLIFo)]
* ILI9486 320x480 (18 bit color) [[demo video](https://youtu.be/pZ6izDqmVds)]
* ILI9488 320x480 (3 bit color with canvas) [[demo video](https://youtu.be/r7be0WbIBYk)]
* ILI9488 320x480 (18 bit color) [[demo video](https://youtu.be/NkE-LhtLHBQ)]
* ILI9806 (8-bit/16-bit Parallel) 480x854 [[demo video](https://youtu.be/mYv-wdtWr8s)] [[LVGL demo video](https://youtu.be/PqjV8lovg_c)][[2](https://youtu.be/j31KZoQUKis)]
* JBT6K71 240x320 (8-bit Parallel) [[demo video](https://youtu.be/qid3F4Gb0mM)]
* NT35310 320x480 [[demo video](https://youtu.be/bvIz5CoYPNk)]
* NT35510 480x800 (8-bit/16-bit Parallel) [[demo video](https://youtu.be/C_1ASzUN3bg)]
* NT39125 240x376 (8-bit/16-bit Parallel) [[demo video](https://youtu.be/JGMrM18JAFA)]
* NV3007 142x428 [[demo video](https://youtube.com/shorts/ePcf0LmMgOo)]
* NV3041A 480x272 [[demo video](https://youtu.be/pd1DTW9QHkg)]
* OTM8009A 480x800 (8-bit/16-bit Parallel)
* R61529 320x480 (8-bit/16-bit Parallel) [[demo video](https://youtu.be/s93gxjbIAT8)]
* Raspberry Pi DPI Display (RPi_DPI_RGBPanel) Any Resolution [[demo video](https://youtube.com/shorts/IqQEq-VLVwI)]
* SEPS525 160x128 [[demo video](https://youtu.be/tlmvFBHYv-k)]
* SSD1283A 130x130 [[demo video](https://youtu.be/OrIchaRikiQ)]
* SSD1331 96x64 [[demo video](https://youtu.be/v20b1A_KDcQ)]
* SSD1351 128x128 [[demo video](https://youtu.be/5TIM-qMVBNQ)]
* SSD1351 128x96
* ST7735 128x160 (various tabs) [[demo video](https://youtu.be/eRBSSD_N9II)]
* ST7735 128x128 (various tabs) [[demo video](https://youtu.be/6rueSV2Ee6c)]
* ST7735 80x160 [[demo video](https://youtu.be/qESHDuYo_Mk)]
* ST7701 480x480 (RGB) [[demo video](https://youtube.com/shorts/JV8Rzxop5EQ)] [[2.1" round display demo video](https://youtube.com/shorts/WLWio1CjBoo?feature=share)] [[2.8" round display demo video](https://youtube.com/shorts/Ih_QlttWTVk?feature=share)]
* ST7789 135x240 [[demo video](https://youtu.be/Zk81_T8c20E)]
* ST7789 240x240 [[demo video](https://youtu.be/Z27zYg5uAsk)]
* ST7789 240x240 [[demo video](https://youtu.be/9AqsXMB8Qbk)]
* ST7789 240x280 round corner display [[demo video](https://youtu.be/KzDC02wg8z0)]
* ST7789 240x320 [[demo video](https://youtu.be/ZEvc1LkuVuQ)]
* ST7796 320x480 [[demo video](https://youtu.be/hUL-RuG4MAQ)]
* WEA2012 356x400 [[demo video](https://youtube.com/shorts/neDyijFrfQY)] [[LVGL demo video](https://youtube.com/shorts/z9Z_u0xg_as)]
### Tobe Support Display (Sponsors can make it happen)
* Mono display supported by co-operate with Canvas
* Multi-color e-ink display supported by co-operate with Canvas
</details>
<details>
<summary>Canvas (framebuffer)</summary>
### Canvas Class [[Wiki](https://github.com/moononournation/Arduino_GFX/wiki/Canvas-Class)]
* Arduino_Canvas (16-bit pixel)
* Arduino_Canvas_3bit (1/4 memory space of 16-bit pixel)
* Arduino_Canvas_Indexed (half memory space of 16-bit pixel)
* Arduino_Canvas_Mono (1/16 memory space of 16-bit pixel)
</details>
<details>
<summary>LVGL Support</summary>
### 3 LVGL demo in Library Examples
* LvglBenchmark [[demo video](https://youtu.be/75Qx-UEgabY)]
* LvglHelloWorld
* LvglWidgets
</details>
<details>
<summary>Feature Wishlist</summary>
### Sponsors can make it happen
* Print color Emoji Characters
* Load bitmap font files from flash / SD
* Fill Gradient (Discussion #128)
</details>
<details>
<summary>Using source code come from</summary>
* <https://github.com/adafruit/Adafruit-GFX-Library.git>
* <https://github.com/adafruit/Adafruit_ILI9341.git>
* <https://github.com/adafruit/Adafruit-SSD1351-library.git>
* <https://github.com/ananevilya/Arduino-ST7789-Library.git>
* <https://github.com/BasementCat/arduino-tft-gif.git>
* <https://github.com/Bodmer/TFT_eSPI.git>
* <https://github.com/daumemo/IPS_LCD_R61529_FT6236_Arduino_eSPI_Test.git>
* <https://github.com/espressif/arduino-esp32.git>
* <https://github.com/espressif/esp-idf.git>
* <https://github.com/gitcnd/LCDWIKI_SPI.git>
* <https://github.com/hi631/LCD_NT35510-MRB3971.git>
* <https://github.com/lcdwiki/LCDWIKI_SPI.git>
* <https://github.com/Xinyuan-LilyGO/T-RGB.git>
* <https://github.com/lovyan03/LovyanGFX.git>
* <https://github.com/modi12jin/Arduino-ESP32-WEA2012.git>
* <https://github.com/nopnop2002/esp-idf-parallel-tft.git>
* <https://github.com/olikraus/u8g2.git>
</details>
## Sponsorship vs Support
As you may already aware there are lack of sponsorship in this project. Convert the funding in terms of man power, it is much lower than 1 man hour per month. So don't expect too much on the support. Expecially the features not realted to my planned maker projects ;>
For the same reason, Arduino_GFX only focus on the Arduino IDE support. Any other IDE, e.g. PlatformIO, if you found an issue at that IDE but normal at Arduino IDE, please direct report to that IDE for better support.

View File

@ -1,264 +0,0 @@
/*******************************************************************************
* Arduino VNC
* This is a simple VNC sample
*
* Dependent libraries:
* ArduinoVNC: https://github.com/moononournation/arduinoVNC.git
*
* Touch libraries:
* FT6X36: https://github.com/strange-v/FT6X36.git
* GT911: https://github.com/TAMCTec/gt911-arduino.git
* XPT2046: https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
*
* Setup steps:
* 1. Fill your own SSID_NAME, SSID_PASSWORD, VNC_IP, VNC_PORT and VNC_PASSWORD
* 2. Change your LCD parameters in Arduino_GFX setting
******************************************************************************/
/* WiFi settings */
const char *SSID_NAME = "YourAP";
const char *SSID_PASSWORD = "PleaseInputYourPasswordHere";
const char *VNC_IP = "192.168.12.34";
const uint16_t VNC_PORT = 5901;
const char *VNC_PASSWORD = "PleaseInputYourPasswordHere";
/*******************************************************************************
* Please config the touch panel in touch.h
******************************************************************************/
#include "touch.h"
/*******************************************************************************
* Please config the optional keyboard in keyboard.h
******************************************************************************/
#include "keyboard.h"
/*******************************************************************************
* Start of Arduino_GFX setting
*
* Arduino_GFX try to find the settings depends on selected board in Arduino IDE
* Or you can define the display dev kit not in the board list
* Defalult pin list for non display dev kit:
* Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12
* ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
* ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil
* ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
* ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
* ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12
* Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16
* RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20
* RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11
* RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12
* RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10
* Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9
* Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
#include <WiFi.h>
#elif defined(RTL8722DM)
#include <WiFi.h>
#endif
#include "VNC_GFX.h"
#include <VNC.h>
VNC_GFX *vnc_gfx = new VNC_GFX(gfx);
arduinoVNC vnc = arduinoVNC(vnc_gfx);
void TFTnoWifi(void)
{
gfx->fillScreen(RGB565_BLACK);
gfx->setCursor(0, ((gfx->height() / 2) - (5 * 8)));
gfx->setTextColor(RGB565_RED);
gfx->setTextSize(5);
gfx->println("NO WIFI!");
gfx->setTextSize(2);
gfx->println();
}
void TFTnoVNC(void)
{
gfx->fillScreen(RGB565_BLACK);
gfx->setCursor(0, ((gfx->height() / 2) - (4 * 8)));
gfx->setTextColor(RGB565_GREEN);
gfx->setTextSize(4);
gfx->println("connect VNC");
gfx->setTextSize(2);
gfx->println();
gfx->print(VNC_IP);
gfx->print(":");
gfx->println(VNC_PORT);
}
void handle_touch()
{
if (touch_has_signal())
{
if (touch_touched())
{
vnc.mouseEvent(touch_last_x, touch_last_y, 0b001);
}
else if (touch_released())
{
vnc.mouseEvent(touch_last_x, touch_last_y, 0b000);
}
}
}
void handle_keyboard()
{
int key = keyboard_get_key();
if (key > 0)
{
// Serial.println(key);
switch (key)
{
case 8:
key = 0xff08; // BackSpace
break;
case 9:
key = 0xff09; // Tab
break;
case 13:
key = 0xff0d; // Return or Enter
break;
case 27:
key = 0xff1b; // Escape
break;
case 180:
key = 0xff51; // Left
break;
case 181:
key = 0xff52; // Up
break;
case 182:
key = 0xff54; // Down
break;
case 183:
key = 0xff53; // Right
break;
}
vnc.keyEvent(key, 0b001);
vnc.keyEvent(key, 0b000);
}
}
void setup(void)
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX VNC example");
// Init keyboard device
keyboard_init();
Serial.println("Init display");
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
// Init touch device
touch_init(gfx->width(), gfx->height(), gfx->getRotation());
TFTnoWifi();
Serial.println("Init WiFi");
gfx->println("Init WiFi");
#if defined(ESP32)
WiFi.mode(WIFI_STA);
WiFi.begin(SSID_NAME, SSID_PASSWORD);
#elif defined(ESP8266)
// disable sleep mode for better data rate
WiFi.setSleepMode(WIFI_NONE_SLEEP);
WiFi.mode(WIFI_STA);
WiFi.begin(SSID_NAME, SSID_PASSWORD);
#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
WiFi.mode(WIFI_STA);
WiFi.begin(SSID_NAME, SSID_PASSWORD);
#elif defined(RTL8722DM)
WiFi.begin((char *)SSID_NAME, (char *)SSID_PASSWORD);
#endif
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
gfx->print(".");
}
Serial.println(" CONNECTED");
gfx->println(" CONNECTED");
Serial.println("IP address: ");
gfx->println("IP address: ");
Serial.println(WiFi.localIP());
gfx->println(WiFi.localIP());
TFTnoVNC();
Serial.println(F("[SETUP] VNC..."));
#ifdef SEPARATE_DRAW_TASK
draw_task_setup();
#endif
vnc.begin(VNC_IP, VNC_PORT);
vnc.setPassword(VNC_PASSWORD); // optional
}
void loop()
{
if (WiFi.status() != WL_CONNECTED)
{
vnc.reconnect();
TFTnoWifi();
delay(100);
}
else
{
if (vnc.connected())
{
handle_touch();
handle_keyboard();
}
vnc.loop();
if (!vnc.connected())
{
TFTnoVNC();
// some delay to not flood the server
delay(5000);
}
}
}

View File

@ -1,185 +0,0 @@
#ifndef _VNC_GFX_H_
#define _VNC_GFX_H_
#include "Arduino_GFX_Library.h"
#include "VNC.h"
#include "VNC_config.h"
#ifdef ESP32
// #define SEPARATE_DRAW_TASK
#endif
#ifdef SEPARATE_DRAW_TASK
#define NUMBER_OF_DRAW_BUFFER 64
typedef struct
{
xQueueHandle xqh;
Arduino_GFX *gfx;
} ParamDrawTask;
typedef struct
{
int16_t x;
int16_t y;
int16_t w;
int16_t h;
bool isBitmap;
uint16_t *buf;
} DrawData;
static xQueueHandle _xqh;
static ParamDrawTask _pDrawTask;
static TaskHandle_t _draw_task_handle;
static DrawData drawDatas[NUMBER_OF_DRAW_BUFFER];
static int draw_queue_cnt = 0;
static void queueDrawTask(uint32_t x, uint32_t y, uint32_t w, uint32_t h, bool isBitmap, uint16_t *d)
{
log_i("queueDrawTask start.");
DrawData *dd = &drawDatas[draw_queue_cnt % NUMBER_OF_DRAW_BUFFER];
dd->x = x;
dd->y = y;
dd->w = w;
dd->h = h;
dd->isBitmap = isBitmap;
log_i("copy data start.");
uint16_t *p = &dd->buf[0];
if (isBitmap)
{
log_i("copy bitmap.");
int i = w * h;
while (i--)
{
*p++ = *d++;
}
}
else
{
*p = *d;
}
log_i("copy data end.");
++draw_queue_cnt;
log_i("xQueueSend start.");
xQueueSend(_xqh, &dd, portMAX_DELAY);
log_i("xQueueSend end.");
log_i("queueDrawTask end.");
}
static void draw_task(void *arg)
{
DrawData *dd;
log_i("draw_task start.");
while (xQueueReceive(_xqh, &dd, portMAX_DELAY))
{
log_i("draw_task work start: x: %d, y: %d, w: %d, h: %d.", dd->x, dd->y, dd->w, dd->h);
if (dd->isBitmap)
{
gfx->draw16bitBeRGBBitmap(dd->x, dd->y, &dd->buf[0], dd->w, dd->h);
}
else
{
gfx->fillRect(dd->x, dd->y, dd->w, dd->h, dd->buf[0]);
}
log_i("draw_task work end.");
}
vQueueDelete(_xqh);
log_i("draw_task end.");
vTaskDelete(NULL);
}
void draw_task_setup()
{
_xqh = xQueueCreate(NUMBER_OF_DRAW_BUFFER, sizeof(DrawData));
_pDrawTask.xqh = _xqh;
_pDrawTask.gfx = gfx;
log_i("xTaskCreatePinnedToCore start");
xTaskCreatePinnedToCore(
(TaskFunction_t)draw_task,
(const char *const)"Draw Task",
(const uint32_t)1600,
(void *const)&_pDrawTask,
(UBaseType_t)configMAX_PRIORITIES - 1,
(TaskHandle_t *const)&_draw_task_handle,
(const BaseType_t)0);
log_i("xTaskCreatePinnedToCore end");
for (int i = 0; i < NUMBER_OF_DRAW_BUFFER; i++)
{
if (!drawDatas[i].buf)
{
drawDatas[i].buf = (uint16_t *)malloc(FB_SIZE * 2);
}
if (drawDatas[i].buf)
{
log_i("#%d draw buffer allocated.", i);
}
else
{
log_e("#%d draw buffer allocat failed.", i);
}
}
}
#endif
class VNC_GFX : public VNCdisplay
{
public:
VNC_GFX(Arduino_GFX *gfx)
{
_gfx = gfx;
}
bool hasCopyRect(void)
{
return false;
}
uint32_t getHeight(void)
{
return _gfx->height();
}
uint32_t getWidth(void)
{
return _gfx->width();
}
void draw_area(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t *data)
{
// DEBUG_VNC("draw_area(%d, %d, %d, %d, data)\n", x, y, w, h);
#ifdef SEPARATE_DRAW_TASK
queueDrawTask(x, y, w, h, true, (uint16_t *)data);
#else
// _gfx->draw16bitBeRGBBitmap(x, y, (uint16_t *)data, w, h);
_gfx->draw16bitRGBBitmap(x, y, (uint16_t *)data, w, h);
#endif
}
void draw_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint16_t color)
{
// DEBUG_VNC("draw_rect(%d, %d, %d, %d, color)\n", x, y, w, h);
// MSB_16_SET(color, color);
#ifdef SEPARATE_DRAW_TASK
queueDrawTask(x, y, w, h, false, &color);
#else
_gfx->fillRect(x, y, w, h, color);
#endif
}
void vnc_options_override(dfb_vnc_options *opt)
{
// opt->client.bigendian = 1;
}
private:
Arduino_GFX *_gfx;
};
#endif /* _VNC_GFX_H_ */

View File

@ -1,65 +0,0 @@
/*******************************************************************************
* Keyboard libraries:
* M5Stack CardKB: no extra libraries required
https://github.com/solderparty/arduino_bbq10kbd
******************************************************************************/
/* uncomment for M5Stack CardKB */
// #define KEYBOARD_CARDKB
// #define KEYBOARD_CARDKB_SDA 19
// #define KEYBOARD_CARDKB_SCL 20
// #define KEYBOARD_CARDKB_I2C_ADDR 0x5f
/* uncomment for BBQKeyboard */
// #define KEYBOARD_BBQKB
// #define KEYBOARD_BBQKB_SDA 21
// #define KEYBOARD_BBQKB_SCL 22
#if defined(KEYBOARD_CARDKB)
#include <Wire.h>
#elif defined(KEYBOARD_BBQKB)
#include <Wire.h>
#include <BBQ10Keyboard.h>
BBQ10Keyboard keyboard;
#endif
void keyboard_init() {
#if defined(KEYBOARD_CARDKB)
Wire1.begin(KEYBOARD_CARDKB_SDA, KEYBOARD_CARDKB_SCL);
#elif defined(KEYBOARD_BBQKB)
Wire1.begin(KEYBOARD_BBQKB_SDA, KEYBOARD_BBQKB_SCL);
keyboard.begin();
keyboard.setBacklight(0.5f);
#endif
}
char keyboard_get_key() {
#if defined(KEYBOARD_CARDKB)
uint8_t bytesReceived = Wire1.requestFrom(KEYBOARD_CARDKB_I2C_ADDR, 1);
if ((bool)bytesReceived) { //If received more than zero bytes
return Wire1.read();
} else {
return 0;
}
#elif defined(KEYBOARD_BBQKB)
const int keyCount = keyboard.keyCount();
if (keyCount > 0) {
const BBQ10Keyboard::KeyEvent key = keyboard.keyEvent();
String state = "pressed";
if (key.state == BBQ10Keyboard::StateLongPress)
state = "held down";
else if (key.state == BBQ10Keyboard::StateRelease)
state = "released";
Serial.printf("key: '%c' (dec %d, hex %02x) %s\r\n", key.key, key.key, key.key, state.c_str());
if ((key.key != 0) && (key.state != BBQ10Keyboard::StateRelease)) {
return key.key;
} else {
return 0;
}
} else {
return 0;
}
#endif
}

View File

@ -1,205 +0,0 @@
/*******************************************************************************
* Touch libraries:
* XPT2046: https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
*
* Capacitive touchscreen libraries
* TouchLib: https://github.com/mmMicky/TouchLib.git
*
* #define CTS328_SLAVE_ADDRESS (0x1A)
* #define L58_SLAVE_ADDRESS (0X5A)
* #define CTS826_SLAVE_ADDRESS (0X15)
* #define CTS820_SLAVE_ADDRESS (0X15)
* #define CTS816S_SLAVE_ADDRESS (0X15)
* #define FT3267_SLAVE_ADDRESS (0x38)
* #define FT5x06_ADDR (0x38)
* #define GT911_SLAVE_ADDRESS1 (0X5D)
* #define GT911_SLAVE_ADDRESS2 (0X14)
* #define ZTW622_SLAVE1_ADDRESS (0x20)
* #define ZTW622_SLAVE2_ADDRESS (0x46)
*
******************************************************************************/
/* uncomment for XPT2046 */
// #define TOUCH_XPT2046
// #define TOUCH_XPT2046_SCK 12
// #define TOUCH_XPT2046_MISO 13
// #define TOUCH_XPT2046_MOSI 11
// #define TOUCH_XPT2046_CS 10
// #define TOUCH_XPT2046_INT 18
// #define TOUCH_XPT2046_ROTATION 0
// #define TOUCH_XPT2046_SAMPLES 50
// uncomment for most capacitive touchscreen
// #define TOUCH_MODULES_FT5x06 // GT911 / CST_SELF / CST_MUTUAL / ZTW622 / L58 / FT3267 / FT5x06
// #define TOUCH_MODULE_ADDR FT5x06_ADDR // CTS328_SLAVE_ADDRESS / L58_SLAVE_ADDRESS / CTS826_SLAVE_ADDRESS / CTS820_SLAVE_ADDRESS / CTS816S_SLAVE_ADDRESS / FT3267_SLAVE_ADDRESS / FT5x06_ADDR / GT911_SLAVE_ADDRESS1 / GT911_SLAVE_ADDRESS2 / ZTW622_SLAVE1_ADDRESS / ZTW622_SLAVE2_ADDRESS
// #define TOUCH_SCL 5
// #define TOUCH_SDA 6
// #define TOUCH_RES -1
// #define TOUCH_INT -1
// Please fill below values from Arduino_GFX Example - TouchCalibration
bool touch_swap_xy = false;
int16_t touch_map_x1 = -1;
int16_t touch_map_x2 = -1;
int16_t touch_map_y1 = -1;
int16_t touch_map_y2 = -1;
int16_t touch_max_x = 0, touch_max_y = 0;
int16_t touch_raw_x = 0, touch_raw_y = 0;
int16_t touch_last_x = 0, touch_last_y = 0;
#if defined(TOUCH_XPT2046)
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
XPT2046_Touchscreen ts(TOUCH_XPT2046_CS, TOUCH_XPT2046_INT);
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
#include <Wire.h>
#include <TouchLib.h>
TouchLib touch(Wire, TOUCH_SDA, TOUCH_SCL, TOUCH_MODULE_ADDR);
#endif // TouchLib
void touch_init(int16_t w, int16_t h, uint8_t r)
{
touch_max_x = w - 1;
touch_max_y = h - 1;
if (touch_map_x1 == -1)
{
switch (r)
{
case 3:
touch_swap_xy = true;
touch_map_x1 = touch_max_x;
touch_map_x2 = 0;
touch_map_y1 = 0;
touch_map_y2 = touch_max_y;
break;
case 2:
touch_swap_xy = false;
touch_map_x1 = touch_max_x;
touch_map_x2 = 0;
touch_map_y1 = touch_max_y;
touch_map_y2 = 0;
break;
case 1:
touch_swap_xy = true;
touch_map_x1 = 0;
touch_map_x2 = touch_max_x;
touch_map_y1 = touch_max_y;
touch_map_y2 = 0;
break;
default: // case 0:
touch_swap_xy = false;
touch_map_x1 = 0;
touch_map_x2 = touch_max_x;
touch_map_y1 = 0;
touch_map_y2 = touch_max_y;
break;
}
}
#if defined(TOUCH_XPT2046)
SPI.begin(TOUCH_XPT2046_SCK, TOUCH_XPT2046_MISO, TOUCH_XPT2046_MOSI, TOUCH_XPT2046_CS);
ts.begin();
ts.setRotation(TOUCH_XPT2046_ROTATION);
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
// Reset touchscreen
#if (TOUCH_RES > 0)
pinMode(TOUCH_RES, OUTPUT);
digitalWrite(TOUCH_RES, 0);
delay(200);
digitalWrite(TOUCH_RES, 1);
delay(200);
#endif
Wire.begin(TOUCH_SDA, TOUCH_SCL);
touch.init();
#endif // TouchLib
}
bool touch_has_signal()
{
#if defined(TOUCH_XPT2046)
return ts.tirqTouched();
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
// TODO: implement TOUCH_INT
return true;
#endif // TouchLib
return false;
}
void translate_touch_raw()
{
if (touch_swap_xy)
{
touch_last_x = map(touch_raw_y, touch_map_x1, touch_map_x2, 0, touch_max_x);
touch_last_y = map(touch_raw_x, touch_map_y1, touch_map_y2, 0, touch_max_y);
}
else
{
touch_last_x = map(touch_raw_x, touch_map_x1, touch_map_x2, 0, touch_max_x);
touch_last_y = map(touch_raw_y, touch_map_y1, touch_map_y2, 0, touch_max_y);
}
// Serial.printf("touch_raw_x: %d, touch_raw_y: %d, touch_last_x: %d, touch_last_y: %d\n", touch_raw_x, touch_raw_y, touch_last_x, touch_last_y);
}
bool touch_touched()
{
#if defined(TOUCH_XPT2046)
if (ts.touched())
{
TS_Point p = ts.getPoint();
touch_raw_x = p.x;
touch_raw_y = p.y;
int max_z = p.z;
int count = 0;
while ((ts.touched()) && (count < TOUCH_XPT2046_SAMPLES))
{
count++;
TS_Point p = ts.getPoint();
if (p.z > max_z)
{
touch_raw_x = p.x;
touch_raw_y = p.y;
max_z = p.z;
}
// Serial.printf("touch_raw_x: %d, touch_raw_y: %d, p.z: %d\n", touch_raw_x, touch_raw_y, p.z);
}
translate_touch_raw();
return true;
}
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
if (touch.read())
{
TP_Point t = touch.getPoint(0);
touch_raw_x = t.x;
touch_raw_y = t.y;
touch_last_x = touch_raw_x;
touch_last_y = touch_raw_y;
translate_touch_raw();
return true;
}
#endif // TouchLib
return false;
}
bool touch_released()
{
#if defined(TOUCH_XPT2046)
return true;
#elif defined(TOUCH_MODULE_ADDR) // TouchLib
return false;
#endif // TouchLib
return false;
}

View File

@ -1,97 +0,0 @@
/*
ASCII Table
Arduino_GFX using the 'classic' fixed-space bitmap font for Adafruit_GFX
This font using CP437 encoding (Extended ASCII)
https://en.wikipedia.org/wiki/Extended_ASCII
*/
/*******************************************************************************
* Start of Arduino_GFX setting
*
* Arduino_GFX try to find the settings depends on selected board in Arduino IDE
* Or you can define the display dev kit not in the board list
* Defalult pin list for non display dev kit:
* Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12
* ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
* ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil
* ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
* ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
* ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12
* Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16
* RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20
* RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11
* RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12
* RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10
* Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9
* Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 0 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
void setup(void)
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX AsciiTable example");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
gfx->setTextColor(RGB565_GREEN);
for (int x = 0; x < 16; x++)
{
gfx->setCursor(10 + x * 8, 2);
gfx->print(x, 16);
}
gfx->setTextColor(RGB565_BLUE);
for (int y = 0; y < 16; y++)
{
gfx->setCursor(2, 12 + y * 10);
gfx->print(y, 16);
}
char c = 0;
for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 16; x++)
{
gfx->drawChar(10 + x * 8, 12 + y * 10, c++, RGB565_WHITE, RGB565_BLACK);
}
}
delay(5000); // 5 seconds
}
void loop()
{
}

View File

@ -1,395 +0,0 @@
/*
Arduino Watch Lite Version
You may find full version at: https://github.com/moononournation/ArduinoWatch
*/
/*******************************************************************************
* Start of Arduino_GFX setting
*
* Arduino_GFX try to find the settings depends on selected board in Arduino IDE
* Or you can define the display dev kit not in the board list
* Defalult pin list for non display dev kit:
* Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12
* ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
* ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil
* ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
* ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
* ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12
* Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16
* RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20
* RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11
* RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12
* RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10
* Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9
* Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 0 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
#define BACKGROUND RGB565_BLACK
#define MARK_COLOR RGB565_WHITE
#define SUBMARK_COLOR RGB565_DARKGREY // RGB565_LIGHTGREY
#define HOUR_COLOR RGB565_WHITE
#define MINUTE_COLOR RGB565_BLUE // RGB565_LIGHTGREY
#define SECOND_COLOR RGB565_RED
#define SIXTIETH 0.016666667
#define TWELFTH 0.08333333
#define SIXTIETH_RADIAN 0.10471976
#define TWELFTH_RADIAN 0.52359878
#define RIGHT_ANGLE_RADIAN 1.5707963
static uint8_t conv2d(const char *p)
{
uint8_t v = 0;
return (10 * (*p - '0')) + (*++p - '0');
}
static int16_t w, h, center;
static int16_t hHandLen, mHandLen, sHandLen, markLen;
static float sdeg, mdeg, hdeg;
static int16_t osx = 0, osy = 0, omx = 0, omy = 0, ohx = 0, ohy = 0; // Saved H, M, S x & y coords
static int16_t nsx, nsy, nmx, nmy, nhx, nhy; // H, M, S x & y coords
static int16_t xMin, yMin, xMax, yMax; // redraw range
static int16_t hh, mm, ss;
static unsigned long targetTime; // next action time
static int16_t *cached_points;
static uint16_t cached_points_idx = 0;
static int16_t *last_cached_point;
void setup(void)
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX Clock example");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(BACKGROUND);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
// init LCD constant
w = gfx->width();
h = gfx->height();
if (w < h)
{
center = w / 2;
}
else
{
center = h / 2;
}
hHandLen = center * 3 / 8;
mHandLen = center * 2 / 3;
sHandLen = center * 5 / 6;
markLen = sHandLen / 6;
cached_points = (int16_t *)malloc((hHandLen + 1 + mHandLen + 1 + sHandLen + 1) * 2 * 2);
// Draw 60 clock marks
draw_round_clock_mark(
// draw_square_clock_mark(
center - markLen, center,
center - (markLen * 2 / 3), center,
center - (markLen / 2), center);
hh = conv2d(__TIME__);
mm = conv2d(__TIME__ + 3);
ss = conv2d(__TIME__ + 6);
targetTime = ((millis() / 1000) + 1) * 1000;
}
void loop()
{
unsigned long cur_millis = millis();
if (cur_millis >= targetTime)
{
targetTime += 1000;
ss++; // Advance second
if (ss == 60)
{
ss = 0;
mm++; // Advance minute
if (mm > 59)
{
mm = 0;
hh++; // Advance hour
if (hh > 23)
{
hh = 0;
}
}
}
}
// Pre-compute hand degrees, x & y coords for a fast screen update
sdeg = SIXTIETH_RADIAN * ((0.001 * (cur_millis % 1000)) + ss); // 0-59 (includes millis)
nsx = cos(sdeg - RIGHT_ANGLE_RADIAN) * sHandLen + center;
nsy = sin(sdeg - RIGHT_ANGLE_RADIAN) * sHandLen + center;
if ((nsx != osx) || (nsy != osy))
{
mdeg = (SIXTIETH * sdeg) + (SIXTIETH_RADIAN * mm); // 0-59 (includes seconds)
hdeg = (TWELFTH * mdeg) + (TWELFTH_RADIAN * hh); // 0-11 (includes minutes)
mdeg -= RIGHT_ANGLE_RADIAN;
hdeg -= RIGHT_ANGLE_RADIAN;
nmx = cos(mdeg) * mHandLen + center;
nmy = sin(mdeg) * mHandLen + center;
nhx = cos(hdeg) * hHandLen + center;
nhy = sin(hdeg) * hHandLen + center;
// redraw hands
redraw_hands_cached_draw_and_erase();
ohx = nhx;
ohy = nhy;
omx = nmx;
omy = nmy;
osx = nsx;
osy = nsy;
delay(1);
}
}
void draw_round_clock_mark(int16_t innerR1, int16_t outerR1, int16_t innerR2, int16_t outerR2, int16_t innerR3, int16_t outerR3)
{
float x, y;
int16_t x0, x1, y0, y1, innerR, outerR;
uint16_t c;
for (uint8_t i = 0; i < 60; i++)
{
if ((i % 15) == 0)
{
innerR = innerR1;
outerR = outerR1;
c = MARK_COLOR;
}
else if ((i % 5) == 0)
{
innerR = innerR2;
outerR = outerR2;
c = MARK_COLOR;
}
else
{
innerR = innerR3;
outerR = outerR3;
c = SUBMARK_COLOR;
}
mdeg = (SIXTIETH_RADIAN * i) - RIGHT_ANGLE_RADIAN;
x = cos(mdeg);
y = sin(mdeg);
x0 = x * outerR + center;
y0 = y * outerR + center;
x1 = x * innerR + center;
y1 = y * innerR + center;
gfx->drawLine(x0, y0, x1, y1, c);
}
}
void draw_square_clock_mark(int16_t innerR1, int16_t outerR1, int16_t innerR2, int16_t outerR2, int16_t innerR3, int16_t outerR3)
{
float x, y;
int16_t x0, x1, y0, y1, innerR, outerR;
uint16_t c;
for (uint8_t i = 0; i < 60; i++)
{
if ((i % 15) == 0)
{
innerR = innerR1;
outerR = outerR1;
c = MARK_COLOR;
}
else if ((i % 5) == 0)
{
innerR = innerR2;
outerR = outerR2;
c = MARK_COLOR;
}
else
{
innerR = innerR3;
outerR = outerR3;
c = SUBMARK_COLOR;
}
if ((i >= 53) || (i < 8))
{
x = tan(SIXTIETH_RADIAN * i);
x0 = center + (x * outerR);
y0 = center + (1 - outerR);
x1 = center + (x * innerR);
y1 = center + (1 - innerR);
}
else if (i < 23)
{
y = tan((SIXTIETH_RADIAN * i) - RIGHT_ANGLE_RADIAN);
x0 = center + (outerR);
y0 = center + (y * outerR);
x1 = center + (innerR);
y1 = center + (y * innerR);
}
else if (i < 38)
{
x = tan(SIXTIETH_RADIAN * i);
x0 = center - (x * outerR);
y0 = center + (outerR);
x1 = center - (x * innerR);
y1 = center + (innerR);
}
else if (i < 53)
{
y = tan((SIXTIETH_RADIAN * i) - RIGHT_ANGLE_RADIAN);
x0 = center + (1 - outerR);
y0 = center - (y * outerR);
x1 = center + (1 - innerR);
y1 = center - (y * innerR);
}
gfx->drawLine(x0, y0, x1, y1, c);
}
}
void redraw_hands_cached_draw_and_erase()
{
gfx->startWrite();
draw_and_erase_cached_line(center, center, nsx, nsy, SECOND_COLOR, cached_points, sHandLen + 1, false, false);
draw_and_erase_cached_line(center, center, nhx, nhy, HOUR_COLOR, cached_points + ((sHandLen + 1) * 2), hHandLen + 1, true, false);
draw_and_erase_cached_line(center, center, nmx, nmy, MINUTE_COLOR, cached_points + ((sHandLen + 1 + hHandLen + 1) * 2), mHandLen + 1, true, true);
gfx->endWrite();
}
void draw_and_erase_cached_line(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t color, int16_t *cache, int16_t cache_len, bool cross_check_second, bool cross_check_hour)
{
#if defined(ESP8266)
yield();
#endif
bool steep = _diff(y1, y0) > _diff(x1, x0);
if (steep)
{
_swap_int16_t(x0, y0);
_swap_int16_t(x1, y1);
}
int16_t dx, dy;
dx = _diff(x1, x0);
dy = _diff(y1, y0);
int16_t err = dx / 2;
int8_t xstep = (x0 < x1) ? 1 : -1;
int8_t ystep = (y0 < y1) ? 1 : -1;
x1 += xstep;
int16_t x, y, ox, oy;
for (uint16_t i = 0; i <= dx; i++)
{
if (steep)
{
x = y0;
y = x0;
}
else
{
x = x0;
y = y0;
}
ox = *(cache + (i * 2));
oy = *(cache + (i * 2) + 1);
if ((x == ox) && (y == oy))
{
if (cross_check_second || cross_check_hour)
{
write_cache_pixel(x, y, color, cross_check_second, cross_check_hour);
}
}
else
{
write_cache_pixel(x, y, color, cross_check_second, cross_check_hour);
if ((ox > 0) || (oy > 0))
{
write_cache_pixel(ox, oy, BACKGROUND, cross_check_second, cross_check_hour);
}
*(cache + (i * 2)) = x;
*(cache + (i * 2) + 1) = y;
}
if (err < dy)
{
y0 += ystep;
err += dx;
}
err -= dy;
x0 += xstep;
}
for (uint16_t i = dx + 1; i < cache_len; i++)
{
ox = *(cache + (i * 2));
oy = *(cache + (i * 2) + 1);
if ((ox > 0) || (oy > 0))
{
write_cache_pixel(ox, oy, BACKGROUND, cross_check_second, cross_check_hour);
}
*(cache + (i * 2)) = 0;
*(cache + (i * 2) + 1) = 0;
}
}
void write_cache_pixel(int16_t x, int16_t y, int16_t color, bool cross_check_second, bool cross_check_hour)
{
int16_t *cache = cached_points;
if (cross_check_second)
{
for (uint16_t i = 0; i <= sHandLen; i++)
{
if ((x == *(cache++)) && (y == *(cache)))
{
return;
}
cache++;
}
}
if (cross_check_hour)
{
cache = cached_points + ((sHandLen + 1) * 2);
for (uint16_t i = 0; i <= hHandLen; i++)
{
if ((x == *(cache++)) && (y == *(cache)))
{
return;
}
cache++;
}
}
gfx->writePixel(x, y, color);
}

View File

@ -1,79 +0,0 @@
/*******************************************************************************
* Start of Arduino_GFX setting
*
* Arduino_GFX try to find the settings depends on selected board in Arduino IDE
* Or you can define the display dev kit not in the board list
* Defalult pin list for non display dev kit:
* Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12
* ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
* ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil
* ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
* ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
* ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12
* Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16
* RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20
* RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11
* RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12
* RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10
* Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9
* Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 0 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
void setup(void)
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX Hello World example");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
gfx->setCursor(10, 10);
gfx->setTextColor(RGB565_RED);
gfx->println("Hello World!");
delay(5000); // 5 seconds
}
void loop()
{
gfx->setCursor(random(gfx->width()), random(gfx->height()));
gfx->setTextColor(random(0xffff), random(0xffff));
gfx->setTextSize(random(6) /* x scale */, random(6) /* y scale */, random(2) /* pixel_margin */);
gfx->println("Hello World!");
delay(1000); // 1 second
}

View File

@ -1,182 +0,0 @@
#ifndef FreeMono8pt7b_H
#define FreeMono8pt7b_H
#ifdef __AVR__
#include <avr/io.h>
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#undef PROGMEM
#define PROGMEM STORE_ATTR
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
// PROGMEM is defefind for T4 to place data in specific memory section
#undef PROGMEM
#define PROGMEM
#else
#define PROGMEM
#endif
const uint8_t FreeMono8pt7bBitmaps[] PROGMEM = {
0x00, 0xFE, 0x40, 0x49, 0x24, 0x92, 0x48, 0x14, 0x28, 0x53, 0xF2, 0x44,
0xBF, 0x94, 0x28, 0x50, 0x00, 0x10, 0x79, 0x12, 0x03, 0x80, 0xC0, 0xC3,
0xFC, 0x20, 0x30, 0x91, 0x21, 0x80, 0x67, 0x13, 0x09, 0x12, 0x18, 0x39,
0x04, 0x10, 0x62, 0x59, 0x62, 0x74, 0x49, 0x24, 0x1A, 0xAA, 0xA5, 0x29,
0x55, 0x6A, 0x20, 0x82, 0x7E, 0x51, 0x20, 0x21, 0x09, 0xF2, 0x10, 0x80,
0x6B, 0x48, 0xFE, 0xF0, 0x04, 0x10, 0x82, 0x10, 0x42, 0x08, 0x21, 0x04,
0x20, 0x31, 0x28, 0x61, 0x86, 0x18, 0x61, 0x48, 0xC0, 0x23, 0x28, 0x42,
0x10, 0x84, 0x27, 0xC0, 0x7B, 0x28, 0x41, 0x08, 0x62, 0x10, 0x83, 0xF0,
0xF8, 0x18, 0x10, 0x21, 0x80, 0x80, 0x81, 0x84, 0xF0, 0x08, 0xE2, 0x92,
0x49, 0x28, 0x9F, 0x08, 0x70, 0x78, 0x81, 0x03, 0xE4, 0x60, 0x40, 0x81,
0xC4, 0x70, 0x3D, 0x84, 0x20, 0xBB, 0x38, 0x61, 0x4C, 0xE0, 0xFC, 0x10,
0x42, 0x08, 0x21, 0x04, 0x10, 0x80, 0x7B, 0x38, 0x61, 0x79, 0x38, 0x61,
0xCD, 0xE0, 0x79, 0x8A, 0x0C, 0x1C, 0x6F, 0x40, 0x82, 0x09, 0xE0, 0xF0,
0x3C, 0x6C, 0x00, 0xD6, 0x80, 0x02, 0x18, 0xC6, 0x06, 0x03, 0x01, 0x80,
0xFF, 0x00, 0xFF, 0x40, 0x60, 0x30, 0x10, 0xC2, 0x18, 0x00, 0x7A, 0x10,
0x43, 0x18, 0x80, 0x00, 0x30, 0x38, 0x8A, 0x14, 0xEB, 0x54, 0xA9, 0x4F,
0x80, 0x80, 0xF0, 0x38, 0x0A, 0x05, 0x04, 0x42, 0x21, 0xF1, 0x04, 0x82,
0xE3, 0x80, 0xFC, 0x42, 0x42, 0x42, 0x7C, 0x43, 0x41, 0x41, 0xFE, 0x3D,
0x43, 0x81, 0x80, 0x80, 0x80, 0xC0, 0x61, 0x3E, 0xFC, 0x42, 0x41, 0x41,
0x41, 0x41, 0x41, 0x42, 0xFC, 0xFE, 0x42, 0x40, 0x48, 0x78, 0x48, 0x40,
0x41, 0xFF, 0xFF, 0x41, 0x40, 0x48, 0x78, 0x48, 0x40, 0x40, 0xF0, 0x3D,
0x21, 0xA0, 0x10, 0x08, 0x04, 0x3E, 0x04, 0x82, 0x3E, 0x00, 0xE7, 0x42,
0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0xE7, 0xF9, 0x08, 0x42, 0x10, 0x84,
0xF8, 0x0F, 0x02, 0x02, 0x02, 0x02, 0x82, 0x82, 0xC6, 0x7C, 0xE7, 0x21,
0x11, 0x0B, 0x06, 0x82, 0x21, 0x10, 0x84, 0xE1, 0x80, 0xE0, 0x81, 0x02,
0x04, 0x08, 0x10, 0xA1, 0xFE, 0xE1, 0xD8, 0x65, 0x29, 0x4A, 0x4C, 0x93,
0x24, 0x09, 0x02, 0xE1, 0xC0, 0xC7, 0x62, 0x62, 0x52, 0x52, 0x4A, 0x4A,
0x46, 0xE2, 0x3C, 0x42, 0xC3, 0x81, 0x81, 0x81, 0xC3, 0x42, 0x3C, 0xFC,
0x8D, 0x0A, 0x14, 0x6F, 0x90, 0x20, 0xF0, 0x3C, 0x42, 0xC3, 0x81, 0x81,
0x81, 0xC3, 0x42, 0x3C, 0x19, 0x26, 0xFC, 0x46, 0x42, 0x46, 0x78, 0x44,
0x44, 0x42, 0xE1, 0x3A, 0xCD, 0x0A, 0x03, 0xC0, 0x60, 0xE3, 0xBC, 0xFF,
0x91, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0xE7, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x66, 0x3C, 0xE3, 0xA0, 0x90, 0x44, 0x42, 0x20, 0x90,
0x50, 0x28, 0x08, 0x00, 0xF3, 0x90, 0x24, 0xC9, 0x34, 0x55, 0x14, 0xC5,
0x30, 0x8C, 0x23, 0x00, 0xC7, 0x42, 0x24, 0x28, 0x10, 0x28, 0x44, 0x42,
0xE7, 0xE3, 0xA1, 0x08, 0x82, 0x80, 0x80, 0x40, 0x20, 0x10, 0x1C, 0x00,
0xFA, 0x21, 0x08, 0x21, 0x08, 0x61, 0xFC, 0xEA, 0xAA, 0xAB, 0x82, 0x04,
0x10, 0x20, 0x81, 0x04, 0x10, 0x20, 0x81, 0xD5, 0x55, 0x57, 0x21, 0x44,
0xA1, 0xFF, 0xC0, 0x90, 0x7C, 0x02, 0x7E, 0xC2, 0x82, 0x86, 0x7B, 0x81,
0x02, 0x05, 0xCC, 0x50, 0x60, 0xC1, 0xC5, 0x70, 0x3D, 0x43, 0x81, 0x80,
0x80, 0x40, 0x3F, 0x02, 0x02, 0x02, 0x3A, 0x46, 0x82, 0x82, 0x82, 0x46,
0x3B, 0x3C, 0x86, 0x0F, 0xF8, 0x08, 0x4F, 0x00, 0x3A, 0x11, 0xF4, 0x21,
0x08, 0x47, 0x80, 0x3A, 0x8E, 0x0C, 0x18, 0x28, 0xCE, 0x81, 0x02, 0x38,
0x40, 0x40, 0x40, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x42, 0xE7, 0x20, 0x18,
0x42, 0x10, 0x84, 0xF8, 0x20, 0xF1, 0x11, 0x11, 0x11, 0x1E, 0x81, 0x02,
0x04, 0xE9, 0x14, 0x38, 0x48, 0x89, 0x1C, 0x61, 0x08, 0x42, 0x10, 0x84,
0x27, 0xC0, 0xB6, 0xC9, 0x89, 0x89, 0x89, 0x89, 0xC9, 0x5C, 0x62, 0x42,
0x42, 0x42, 0x42, 0xE7, 0x3C, 0x42, 0x81, 0x81, 0x81, 0x42, 0x3C, 0xDC,
0x62, 0x41, 0x41, 0x41, 0x62, 0x5C, 0x40, 0x40, 0xE0, 0x3B, 0x46, 0x82,
0x82, 0x82, 0x46, 0x3A, 0x02, 0x02, 0x07, 0xCC, 0xE1, 0x02, 0x04, 0x08,
0x3C, 0x00, 0x3D, 0x14, 0x0E, 0x06, 0x1F, 0x80, 0x40, 0x83, 0xE2, 0x04,
0x08, 0x10, 0x21, 0x3C, 0x8E, 0x18, 0x61, 0x86, 0x37, 0x40, 0xF3, 0x90,
0x88, 0x84, 0x41, 0x40, 0xA0, 0x30, 0xE3, 0xA0, 0x92, 0x46, 0xA3, 0x51,
0xB0, 0x88, 0xE6, 0x44, 0x28, 0x10, 0x2C, 0x42, 0xE7, 0xE7, 0x42, 0x44,
0x24, 0x28, 0x18, 0x10, 0x10, 0x20, 0xF0, 0xFA, 0x21, 0x08, 0x42, 0x07,
0xC0, 0x69, 0x25, 0x12, 0x49, 0x30, 0xFF, 0xF0, 0xC9, 0x24, 0x52, 0x49,
0x60, 0x60, 0xA4, 0x30 };
const GFXglyph FreeMono8pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 10, 0, 0 }, // 0x20 ' '
{ 1, 1, 10, 10, 4, -9 }, // 0x21 '!'
{ 3, 6, 5, 10, 2, -9 }, // 0x22 '"'
{ 7, 7, 11, 10, 1, -9 }, // 0x23 '#'
{ 17, 7, 10, 10, 1, -9 }, // 0x24 '$'
{ 26, 7, 10, 10, 1, -9 }, // 0x25 '%'
{ 35, 6, 9, 10, 2, -8 }, // 0x26 '&'
{ 42, 3, 5, 10, 3, -9 }, // 0x27 '''
{ 44, 2, 12, 10, 5, -9 }, // 0x28 '('
{ 47, 2, 12, 10, 3, -9 }, // 0x29 ')'
{ 50, 6, 6, 10, 2, -9 }, // 0x2A '*'
{ 55, 5, 7, 10, 2, -7 }, // 0x2B '+'
{ 60, 3, 5, 10, 2, -2 }, // 0x2C ','
{ 62, 7, 1, 10, 1, -4 }, // 0x2D '-'
{ 63, 2, 2, 10, 4, -1 }, // 0x2E '.'
{ 64, 6, 12, 10, 2, -10 }, // 0x2F '/'
{ 73, 6, 10, 10, 2, -9 }, // 0x30 '0'
{ 81, 5, 10, 10, 2, -9 }, // 0x31 '1'
{ 88, 6, 10, 10, 2, -9 }, // 0x32 '2'
{ 96, 7, 10, 10, 1, -9 }, // 0x33 '3'
{ 105, 6, 10, 10, 2, -9 }, // 0x34 '4'
{ 113, 7, 10, 10, 1, -9 }, // 0x35 '5'
{ 122, 6, 10, 10, 2, -9 }, // 0x36 '6'
{ 130, 6, 10, 10, 2, -9 }, // 0x37 '7'
{ 138, 6, 10, 10, 2, -9 }, // 0x38 '8'
{ 146, 7, 10, 10, 2, -9 }, // 0x39 '9'
{ 155, 2, 7, 10, 4, -6 }, // 0x3A ':'
{ 157, 3, 9, 10, 2, -6 }, // 0x3B ';'
{ 161, 7, 7, 10, 1, -7 }, // 0x3C '<'
{ 168, 8, 3, 10, 1, -5 }, // 0x3D '='
{ 171, 7, 7, 10, 1, -7 }, // 0x3E '>'
{ 178, 6, 9, 10, 2, -8 }, // 0x3F '?'
{ 185, 7, 11, 10, 2, -9 }, // 0x40 '@'
{ 195, 9, 9, 10, 0, -8 }, // 0x41 'A'
{ 206, 8, 9, 10, 1, -8 }, // 0x42 'B'
{ 215, 8, 9, 10, 1, -8 }, // 0x43 'C'
{ 224, 8, 9, 10, 1, -8 }, // 0x44 'D'
{ 233, 8, 9, 10, 1, -8 }, // 0x45 'E'
{ 242, 8, 9, 10, 1, -8 }, // 0x46 'F'
{ 251, 9, 9, 10, 1, -8 }, // 0x47 'G'
{ 262, 8, 9, 10, 1, -8 }, // 0x48 'H'
{ 271, 5, 9, 10, 2, -8 }, // 0x49 'I'
{ 277, 8, 9, 10, 1, -8 }, // 0x4A 'J'
{ 286, 9, 9, 10, 1, -8 }, // 0x4B 'K'
{ 297, 7, 9, 10, 2, -8 }, // 0x4C 'L'
{ 305, 10, 9, 10, 0, -8 }, // 0x4D 'M'
{ 317, 8, 9, 10, 1, -8 }, // 0x4E 'N'
{ 326, 8, 9, 10, 1, -8 }, // 0x4F 'O'
{ 335, 7, 9, 10, 1, -8 }, // 0x50 'P'
{ 343, 8, 11, 10, 1, -8 }, // 0x51 'Q'
{ 354, 8, 9, 10, 1, -8 }, // 0x52 'R'
{ 363, 7, 9, 10, 1, -8 }, // 0x53 'S'
{ 371, 8, 9, 10, 1, -8 }, // 0x54 'T'
{ 380, 8, 9, 10, 1, -8 }, // 0x55 'U'
{ 389, 9, 9, 10, 0, -8 }, // 0x56 'V'
{ 400, 10, 9, 10, 0, -8 }, // 0x57 'W'
{ 412, 8, 9, 10, 1, -8 }, // 0x58 'X'
{ 421, 9, 9, 10, 1, -8 }, // 0x59 'Y'
{ 432, 6, 9, 10, 2, -8 }, // 0x5A 'Z'
{ 439, 2, 12, 10, 4, -9 }, // 0x5B '['
{ 442, 6, 12, 10, 2, -10 }, // 0x5C '\'
{ 451, 2, 12, 10, 3, -9 }, // 0x5D ']'
{ 454, 6, 4, 10, 2, -9 }, // 0x5E '^'
{ 457, 10, 1, 10, 0, 2 }, // 0x5F '_'
{ 459, 2, 2, 10, 2, -9 }, // 0x60 '`'
{ 460, 8, 7, 10, 1, -6 }, // 0x61 'a'
{ 467, 7, 10, 10, 2, -9 }, // 0x62 'b'
{ 476, 8, 7, 10, 1, -6 }, // 0x63 'c'
{ 483, 8, 10, 10, 1, -9 }, // 0x64 'd'
{ 493, 7, 7, 10, 1, -6 }, // 0x65 'e'
{ 500, 5, 10, 10, 3, -9 }, // 0x66 'f'
{ 507, 7, 10, 10, 1, -6 }, // 0x67 'g'
{ 516, 8, 10, 10, 1, -9 }, // 0x68 'h'
{ 526, 5, 9, 10, 2, -8 }, // 0x69 'i'
{ 532, 4, 12, 10, 3, -8 }, // 0x6A 'j'
{ 538, 7, 10, 10, 2, -9 }, // 0x6B 'k'
{ 547, 5, 10, 10, 2, -9 }, // 0x6C 'l'
{ 554, 8, 7, 10, 1, -6 }, // 0x6D 'm'
{ 561, 8, 7, 10, 1, -6 }, // 0x6E 'n'
{ 568, 8, 7, 10, 1, -6 }, // 0x6F 'o'
{ 575, 8, 10, 10, 1, -6 }, // 0x70 'p'
{ 585, 8, 10, 10, 1, -6 }, // 0x71 'q'
{ 595, 7, 7, 10, 2, -6 }, // 0x72 'r'
{ 602, 6, 7, 10, 2, -6 }, // 0x73 's'
{ 608, 7, 9, 10, 1, -8 }, // 0x74 't'
{ 616, 6, 7, 10, 2, -6 }, // 0x75 'u'
{ 622, 9, 7, 10, 0, -6 }, // 0x76 'v'
{ 630, 9, 7, 10, 0, -6 }, // 0x77 'w'
{ 638, 8, 7, 10, 1, -6 }, // 0x78 'x'
{ 645, 8, 10, 10, 1, -6 }, // 0x79 'y'
{ 655, 6, 7, 10, 2, -6 }, // 0x7A 'z'
{ 661, 3, 12, 10, 4, -9 }, // 0x7B '{'
{ 666, 1, 12, 10, 4, -9 }, // 0x7C '|'
{ 668, 3, 12, 10, 3, -9 }, // 0x7D '}'
{ 673, 7, 3, 10, 1, -5 } }; // 0x7E '~'
const GFXfont FreeMono8pt7b PROGMEM = {
(uint8_t *)FreeMono8pt7bBitmaps,
(GFXglyph *)FreeMono8pt7bGlyphs,
0x20, 0x7E, 16 };
// Approx. 1348 bytes
#endif // FreeMono8pt7b_H

View File

@ -1,251 +0,0 @@
#ifndef FreeSansBold10pt7b_H
#define FreeSansBold10pt7b_H
#ifdef __AVR__
#include <avr/io.h>
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#undef PROGMEM
#define PROGMEM STORE_ATTR
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
// PROGMEM is defefind for T4 to place data in specific memory section
#undef PROGMEM
#define PROGMEM
#else
#define PROGMEM
#endif
const uint8_t FreeSansBold10pt7bBitmaps[] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFE, 0x48, 0x7F, 0xC0, 0xE7, 0xE7, 0xE7, 0xE7, 0x42,
0x0C, 0xC3, 0x39, 0xFF, 0xBF, 0xF7, 0xFE, 0x73, 0x0C, 0xE7, 0xFE, 0xFF,
0xDF, 0xF9, 0x8C, 0x33, 0x06, 0x60, 0x08, 0x0F, 0x87, 0xFB, 0xFE, 0xEB,
0xFA, 0x7F, 0x81, 0xF8, 0x1F, 0x82, 0xFE, 0x9F, 0xAF, 0xFF, 0xDF, 0xE3,
0xE0, 0x20, 0x3C, 0x08, 0x3F, 0x0C, 0x3F, 0xC4, 0x18, 0x66, 0x0F, 0xF2,
0x03, 0xF3, 0x00, 0xF3, 0x00, 0x01, 0x1C, 0x01, 0x9F, 0x00, 0x9F, 0xC0,
0xCC, 0x60, 0x47, 0xF0, 0x61, 0xF0, 0x60, 0x70, 0x0F, 0x00, 0xFC, 0x0F,
0xF0, 0x73, 0x83, 0x9C, 0x0F, 0xC0, 0x78, 0x0F, 0xF6, 0xE3, 0xF7, 0x0F,
0x3C, 0x79, 0xFF, 0xE7, 0xFB, 0x0F, 0x9C, 0xFF, 0xF4, 0x1C, 0x63, 0x8C,
0x71, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE1, 0xC7, 0x0C, 0x38, 0x60, 0xC0,
0xE1, 0x87, 0x0C, 0x38, 0x61, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0xE3, 0x8C,
0x71, 0x8C, 0x00, 0x10, 0x23, 0xF8, 0x82, 0x85, 0x00, 0x1C, 0x0E, 0x07,
0x1F, 0xFF, 0xFF, 0xFC, 0x70, 0x38, 0x1C, 0x00, 0xFF, 0x93, 0x80, 0xFF,
0xFE, 0xFF, 0x80, 0x08, 0xC4, 0x23, 0x18, 0x84, 0x63, 0x10, 0x8C, 0x40,
0x1E, 0x1F, 0xE7, 0xFB, 0xCF, 0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xE1, 0xF8,
0x7F, 0x3D, 0xFE, 0x7F, 0x87, 0x80, 0x0C, 0x7F, 0xFF, 0x1C, 0x71, 0xC7,
0x1C, 0x71, 0xC7, 0x1C, 0x70, 0x3E, 0x3F, 0xBF, 0xFC, 0x7E, 0x38, 0x1C,
0x0E, 0x0E, 0x1C, 0x1C, 0x1C, 0x1F, 0xFF, 0xFF, 0xFC, 0x3E, 0x3F, 0xBF,
0xFC, 0x70, 0x38, 0x1C, 0x38, 0x1E, 0x03, 0x81, 0xF8, 0xFF, 0xF7, 0xF1,
0xF0, 0x07, 0x07, 0x83, 0xC3, 0xE3, 0x71, 0x39, 0x9C, 0x8E, 0xC7, 0x7F,
0xFF, 0xFF, 0xF0, 0x70, 0x38, 0x7F, 0x9F, 0xE7, 0xF9, 0x80, 0x7E, 0x3F,
0xEF, 0xFB, 0x8F, 0x01, 0xC0, 0x7E, 0x3F, 0xFE, 0x7F, 0x8F, 0x80, 0x1F,
0x0F, 0xE7, 0xFD, 0xC0, 0xEF, 0x3F, 0xEF, 0xFF, 0xCF, 0xE1, 0xF8, 0x7F,
0x3D, 0xFE, 0x7F, 0x87, 0x80, 0xFF, 0xFF, 0xFF, 0xE0, 0x60, 0x70, 0x30,
0x38, 0x18, 0x1C, 0x0E, 0x06, 0x07, 0x03, 0x81, 0xC0, 0x1F, 0x0F, 0xFB,
0xFF, 0xF0, 0x7E, 0x0E, 0xFF, 0x9F, 0xF7, 0x8F, 0xE0, 0xFC, 0x1F, 0xC7,
0xBF, 0xE7, 0xFC, 0x3E, 0x00, 0x3E, 0x3F, 0x9F, 0xDC, 0x7E, 0x3F, 0x1F,
0x8F, 0xFF, 0x7F, 0x9D, 0xF8, 0xEF, 0xE7, 0xF1, 0xE0, 0xFF, 0x80, 0x07,
0xFC, 0xFF, 0x80, 0x07, 0xFC, 0x9C, 0x00, 0x40, 0xF0, 0xFD, 0xF8, 0xF0,
0x38, 0x0F, 0xC0, 0x7E, 0x03, 0xC0, 0x30, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0x0F, 0xC0, 0x7C, 0x03, 0xC0,
0xF0, 0xF9, 0xF8, 0xF0, 0x20, 0x00, 0x1F, 0x1F, 0xE7, 0xFB, 0xC7, 0xE1,
0xC0, 0x70, 0x1C, 0x0E, 0x07, 0x03, 0x80, 0xE0, 0x00, 0x0E, 0x03, 0x80,
0xE0, 0x03, 0xF8, 0x03, 0xFF, 0x81, 0xE0, 0xF0, 0xE0, 0x0E, 0x70, 0x01,
0x98, 0x7B, 0x36, 0x31, 0x8F, 0x18, 0x63, 0xCC, 0x18, 0xF3, 0x04, 0x3C,
0xC3, 0x1B, 0x39, 0xCE, 0xE7, 0xDF, 0x18, 0xE7, 0x87, 0x00, 0x00, 0xF0,
0x20, 0x1F, 0xF8, 0x01, 0xFC, 0x00, 0x07, 0x80, 0x1E, 0x00, 0x7C, 0x03,
0xF0, 0x0F, 0xC0, 0x73, 0x81, 0xCE, 0x07, 0x38, 0x38, 0x70, 0xFF, 0xC3,
0xFF, 0x1F, 0xFE, 0x70, 0x39, 0xC0, 0xEE, 0x03, 0xC0, 0xFF, 0x9F, 0xFB,
0xFF, 0xF0, 0x7E, 0x0F, 0xC1, 0xFF, 0xF7, 0xFC, 0xFF, 0xDC, 0x1F, 0x83,
0xF0, 0x7F, 0xFF, 0xFF, 0xBF, 0xE0, 0x0F, 0xC1, 0xFF, 0x1F, 0xFC, 0xF0,
0xFF, 0x03, 0xF0, 0x03, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x3C, 0x0E,
0xF0, 0xF7, 0xFF, 0x1F, 0xF0, 0x3F, 0x00, 0xFF, 0x8F, 0xFC, 0xFF, 0xEE,
0x0E, 0xE0, 0xFE, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0xFE,
0x0E, 0xFF, 0xEF, 0xFC, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xE0,
0x38, 0x0F, 0xFB, 0xFE, 0xFF, 0xB8, 0x0E, 0x03, 0x80, 0xFF, 0xFF, 0xFF,
0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xE0, 0x38, 0x0F, 0xFB, 0xFE, 0xFF,
0xB8, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x00, 0x0F, 0xC0, 0xFF, 0x8F,
0xFC, 0xF0, 0xF7, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x1F, 0xE0, 0xFF, 0x07,
0xFC, 0x0E, 0xF0, 0xF7, 0xFF, 0x9F, 0xEC, 0x3E, 0x60, 0xE0, 0xFC, 0x1F,
0x83, 0xF0, 0x7E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFC, 0x1F, 0x83,
0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x38, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xF8,
0xFC, 0x7F, 0xFB, 0xF8, 0xF8, 0xE0, 0xF7, 0x0F, 0x38, 0x71, 0xC7, 0x0E,
0x70, 0x77, 0x03, 0xF0, 0x1F, 0xC0, 0xF7, 0x07, 0x3C, 0x38, 0xE1, 0xC3,
0x8E, 0x1E, 0x70, 0x7B, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07,
0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0F, 0xFF, 0xFF, 0xFE, 0xF0,
0x7F, 0xC3, 0xFF, 0x8F, 0xFE, 0x3F, 0xF8, 0xFF, 0xE3, 0xFF, 0x9D, 0xFF,
0x77, 0xED, 0xDF, 0xB7, 0x7E, 0xF9, 0xFB, 0xE7, 0xE7, 0x9F, 0x9E, 0x7E,
0x79, 0xC0, 0xE0, 0xFE, 0x1F, 0xC3, 0xFC, 0x7F, 0x8F, 0xF9, 0xFB, 0x3F,
0x77, 0xE6, 0xFC, 0xFF, 0x8F, 0xF1, 0xFE, 0x1F, 0xC3, 0xF8, 0x38, 0x0F,
0xC0, 0x7F, 0x83, 0xFF, 0x1E, 0x1E, 0x70, 0x3F, 0x80, 0x7E, 0x01, 0xF8,
0x07, 0xE0, 0x1F, 0x80, 0x77, 0x03, 0xDE, 0x1E, 0x3F, 0xF0, 0x7F, 0x80,
0xFC, 0x00, 0xFF, 0x9F, 0xFB, 0xFF, 0xF0, 0xFE, 0x0F, 0xC1, 0xF8, 0x7F,
0xFF, 0xFF, 0xDF, 0xF3, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x00, 0x0F,
0xC0, 0x7F, 0x83, 0xFF, 0x1E, 0x1E, 0x70, 0x3F, 0x80, 0x7E, 0x01, 0xF8,
0x07, 0xE0, 0x1F, 0x82, 0x77, 0x1F, 0x9E, 0x1E, 0x3F, 0xF8, 0x7F, 0xF0,
0xFD, 0x80, 0xFF, 0x8F, 0xFC, 0xFF, 0xEE, 0x0E, 0xE0, 0xEE, 0x0E, 0xFF,
0xCF, 0xF8, 0xFF, 0xCE, 0x0E, 0xE0, 0xEE, 0x0E, 0xE0, 0xEE, 0x0E, 0xE0,
0xF0, 0x1F, 0x87, 0xFE, 0x7F, 0xFF, 0x07, 0xE0, 0x0E, 0x00, 0xFE, 0x07,
0xFE, 0x0F, 0xF0, 0x0F, 0x00, 0x7E, 0x0F, 0xFF, 0xE7, 0xFE, 0x1F, 0x80,
0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E,
0x01, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0xE0, 0xFC, 0x1F,
0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83,
0xF8, 0xF7, 0xFC, 0xFF, 0x87, 0xC0, 0x70, 0x3B, 0x83, 0x9C, 0x1C, 0x60,
0xE3, 0x86, 0x1C, 0x70, 0x63, 0x83, 0x98, 0x1D, 0xC0, 0x6E, 0x03, 0x60,
0x1F, 0x00, 0xF8, 0x03, 0x80, 0x1C, 0x00, 0xF0, 0xE1, 0xEE, 0x1C, 0x39,
0xC3, 0x87, 0x38, 0xF8, 0xE3, 0x1F, 0x1C, 0x73, 0xE3, 0x0E, 0x7C, 0xE1,
0xCF, 0xDC, 0x1B, 0x9B, 0x03, 0x73, 0x60, 0x7E, 0x6C, 0x0F, 0xCF, 0x80,
0xF8, 0xE0, 0x1E, 0x1C, 0x03, 0xC3, 0x80, 0x70, 0x7B, 0xC3, 0x8E, 0x38,
0x39, 0xC1, 0xDC, 0x07, 0xE0, 0x3E, 0x00, 0xE0, 0x0F, 0x80, 0x7E, 0x07,
0x70, 0x39, 0xC3, 0x8F, 0x3C, 0x39, 0xC1, 0xE0, 0xF0, 0x73, 0x83, 0x9E,
0x38, 0x71, 0xC3, 0xDC, 0x0E, 0xE0, 0x76, 0x01, 0xF0, 0x07, 0x00, 0x38,
0x01, 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0xC0, 0xF0, 0x3C, 0x07, 0x01, 0xC0,
0x78, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xCE, 0x73, 0x9C, 0xE7,
0x39, 0xCE, 0x73, 0x9C, 0xFF, 0xFE, 0xC3, 0x04, 0x18, 0x60, 0x83, 0x0C,
0x10, 0x61, 0x82, 0x0C, 0x30, 0xFF, 0xFE, 0x73, 0x9C, 0xE7, 0x39, 0xCE,
0x73, 0x9C, 0xE7, 0xFF, 0xFE, 0x1C, 0x0F, 0x07, 0x86, 0xC3, 0x33, 0x99,
0x8E, 0xC3, 0xC1, 0x80, 0xFF, 0xFF, 0xFF, 0xE6, 0x30, 0x3E, 0x1F, 0xC7,
0xFB, 0x8E, 0x07, 0x9F, 0xEE, 0x3B, 0x8E, 0xFF, 0x9F, 0xE3, 0xBC, 0xE0,
0x1C, 0x03, 0x80, 0x70, 0x0E, 0xF1, 0xFF, 0xBF, 0xF7, 0x8F, 0xE0, 0xFC,
0x1F, 0x83, 0xF8, 0xFF, 0xFD, 0xFF, 0xBB, 0xC0, 0x1F, 0x1F, 0xE7, 0xFF,
0xC7, 0xE0, 0x38, 0x0E, 0x03, 0xC7, 0x7F, 0xDF, 0xE1, 0xF0, 0x01, 0xC0,
0x70, 0x1C, 0x07, 0x1D, 0xDF, 0xF7, 0xFF, 0xCF, 0xE1, 0xF8, 0x7E, 0x1F,
0xCF, 0x7F, 0xDF, 0xF3, 0xDC, 0x1E, 0x1F, 0xE7, 0xFB, 0x87, 0xFF, 0xFF,
0xFE, 0x03, 0xC7, 0x7F, 0xDF, 0xE1, 0xE0, 0x3D, 0xF7, 0xDC, 0xFB, 0xE7,
0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x00, 0x1D, 0xDF, 0xF7, 0xFF, 0xCF,
0xE1, 0xF8, 0x7E, 0x1F, 0xCF, 0x7F, 0xDF, 0xF3, 0xDC, 0x07, 0xF3, 0xDF,
0xE3, 0xF0, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xEF, 0x3F, 0xEF, 0xFF, 0xC7,
0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xE1, 0xF8, 0x7E, 0x1C, 0xFF, 0x8F, 0xFF,
0xFF, 0xFF, 0xF8, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0xFF,
0xE0, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE3, 0xB9, 0xCE, 0xF3, 0xB8, 0xFC,
0x3F, 0x8F, 0xE3, 0x9C, 0xE7, 0xB8, 0xEE, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF8, 0xEF, 0x1E, 0xFF, 0xBF, 0xFF, 0xFF, 0xF1, 0xC7, 0xE1, 0xC7,
0xE1, 0xC7, 0xE1, 0xC7, 0xE1, 0xC7, 0xE1, 0xC7, 0xE1, 0xC7, 0xE1, 0xC7,
0xEF, 0x3F, 0xEF, 0xFF, 0xC7, 0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xE1, 0xF8,
0x7E, 0x1C, 0x1F, 0x07, 0xF9, 0xFF, 0x78, 0xFE, 0x0F, 0xC1, 0xF8, 0x3F,
0x8F, 0x7F, 0xC7, 0xF8, 0x7C, 0x00, 0xEF, 0x1F, 0xF3, 0xFF, 0x78, 0xFE,
0x0F, 0xC1, 0xF8, 0x3F, 0x8F, 0xFF, 0xDF, 0xF3, 0xBC, 0x70, 0x0E, 0x01,
0xC0, 0x38, 0x00, 0x1D, 0xCF, 0xF7, 0xFF, 0xCF, 0xE1, 0xF8, 0x7E, 0x1F,
0xCF, 0x7F, 0xDF, 0xF1, 0xDC, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0xEF, 0xFF,
0xFC, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x00, 0x3E, 0x1F, 0xEF, 0xFB, 0x87,
0xFC, 0x1F, 0xE1, 0xFF, 0x87, 0xFF, 0xDF, 0xE3, 0xF0, 0x73, 0xBF, 0xF7,
0x39, 0xCE, 0x73, 0x9E, 0xF3, 0x80, 0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xE1,
0xF8, 0x7E, 0x1F, 0x8F, 0xFF, 0xDF, 0xF3, 0xDC, 0xE0, 0xCE, 0x39, 0xC7,
0x38, 0xC3, 0x38, 0x77, 0x0E, 0xC0, 0xD8, 0x1F, 0x03, 0xC0, 0x38, 0x00,
0xE3, 0x8E, 0xC7, 0x1D, 0xCF, 0x3B, 0x9E, 0x67, 0x7C, 0xC6, 0xDB, 0x8D,
0x9F, 0x1F, 0x3C, 0x3E, 0x78, 0x38, 0xF0, 0x71, 0xC0, 0x71, 0xCF, 0x78,
0xEE, 0x0F, 0x81, 0xF0, 0x1C, 0x07, 0xC0, 0xF8, 0x3B, 0x8E, 0x39, 0xC7,
0x00, 0xE0, 0xEE, 0x39, 0xC7, 0x18, 0xC3, 0xB8, 0x77, 0x06, 0xC0, 0xF8,
0x0F, 0x01, 0xC0, 0x38, 0x06, 0x03, 0xC0, 0x78, 0x0E, 0x00, 0xFF, 0x7F,
0xBF, 0xC1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0x19,
0xCE, 0x63, 0x18, 0xC6, 0x37, 0xBC, 0x63, 0x18, 0xC6, 0x39, 0xC6, 0xFF,
0xFF, 0xE0, 0xC7, 0x38, 0xC6, 0x31, 0x8C, 0x63, 0xDE, 0xC6, 0x31, 0x8C,
0xE7, 0x30, 0x70, 0x7C, 0x63, 0xE0, 0xE0 };
const GFXglyph FreeSansBold10pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 6, 0, 0 }, // 0x20 ' '
{ 1, 3, 14, 7, 2, -13 }, // 0x21 '!'
{ 7, 8, 5, 9, 1, -14 }, // 0x22 '"'
{ 12, 11, 13, 11, 0, -12 }, // 0x23 '#'
{ 30, 10, 16, 11, 1, -14 }, // 0x24 '$'
{ 50, 17, 14, 18, 0, -13 }, // 0x25 '%'
{ 80, 13, 14, 14, 1, -13 }, // 0x26 '&'
{ 103, 3, 5, 5, 1, -14 }, // 0x27 '''
{ 105, 6, 19, 7, 1, -14 }, // 0x28 '('
{ 120, 6, 19, 7, 0, -14 }, // 0x29 ')'
{ 135, 7, 6, 8, 0, -14 }, // 0x2A '*'
{ 141, 9, 9, 12, 2, -8 }, // 0x2B '+'
{ 152, 3, 6, 5, 1, -2 }, // 0x2C ','
{ 155, 5, 3, 7, 1, -6 }, // 0x2D '-'
{ 157, 3, 3, 5, 1, -2 }, // 0x2E '.'
{ 159, 5, 14, 6, 0, -13 }, // 0x2F '/'
{ 168, 10, 14, 11, 1, -13 }, // 0x30 '0'
{ 186, 6, 14, 11, 2, -13 }, // 0x31 '1'
{ 197, 9, 14, 11, 1, -13 }, // 0x32 '2'
{ 213, 9, 14, 11, 1, -13 }, // 0x33 '3'
{ 229, 9, 14, 11, 1, -13 }, // 0x34 '4'
{ 245, 10, 14, 11, 1, -13 }, // 0x35 '5'
{ 263, 10, 14, 11, 1, -13 }, // 0x36 '6'
{ 281, 9, 14, 11, 1, -13 }, // 0x37 '7'
{ 297, 11, 14, 11, 0, -13 }, // 0x38 '8'
{ 317, 9, 14, 11, 1, -13 }, // 0x39 '9'
{ 333, 3, 10, 5, 1, -9 }, // 0x3A ':'
{ 337, 3, 13, 5, 1, -9 }, // 0x3B ';'
{ 342, 10, 10, 12, 1, -9 }, // 0x3C '<'
{ 355, 10, 8, 12, 1, -8 }, // 0x3D '='
{ 365, 10, 10, 12, 1, -9 }, // 0x3E '>'
{ 378, 10, 15, 12, 1, -14 }, // 0x3F '?'
{ 397, 18, 18, 20, 1, -14 }, // 0x40 '@'
{ 438, 14, 15, 14, 0, -14 }, // 0x41 'A'
{ 465, 11, 15, 14, 2, -14 }, // 0x42 'B'
{ 486, 13, 15, 14, 1, -14 }, // 0x43 'C'
{ 511, 12, 15, 14, 2, -14 }, // 0x44 'D'
{ 534, 10, 15, 13, 2, -14 }, // 0x45 'E'
{ 553, 10, 15, 13, 2, -14 }, // 0x46 'F'
{ 572, 13, 15, 15, 1, -14 }, // 0x47 'G'
{ 597, 11, 15, 15, 2, -14 }, // 0x48 'H'
{ 618, 3, 15, 6, 2, -14 }, // 0x49 'I'
{ 624, 9, 15, 11, 1, -14 }, // 0x4A 'J'
{ 641, 13, 15, 15, 2, -14 }, // 0x4B 'K'
{ 666, 9, 15, 12, 2, -14 }, // 0x4C 'L'
{ 683, 14, 15, 17, 2, -14 }, // 0x4D 'M'
{ 710, 11, 15, 15, 2, -14 }, // 0x4E 'N'
{ 731, 14, 15, 16, 1, -14 }, // 0x4F 'O'
{ 758, 11, 15, 14, 2, -14 }, // 0x50 'P'
{ 779, 14, 15, 16, 1, -14 }, // 0x51 'Q'
{ 806, 12, 15, 14, 2, -14 }, // 0x52 'R'
{ 829, 12, 15, 14, 1, -14 }, // 0x53 'S'
{ 852, 11, 15, 13, 1, -14 }, // 0x54 'T'
{ 873, 11, 15, 15, 2, -14 }, // 0x55 'U'
{ 894, 13, 15, 13, 0, -14 }, // 0x56 'V'
{ 919, 19, 15, 19, 0, -14 }, // 0x57 'W'
{ 955, 13, 15, 13, 0, -14 }, // 0x58 'X'
{ 980, 13, 15, 13, 0, -14 }, // 0x59 'Y'
{ 1005, 11, 15, 12, 1, -14 }, // 0x5A 'Z'
{ 1026, 5, 19, 7, 1, -14 }, // 0x5B '['
{ 1038, 6, 14, 6, 0, -13 }, // 0x5C '\'
{ 1049, 5, 19, 7, 0, -14 }, // 0x5D ']'
{ 1061, 9, 9, 12, 1, -13 }, // 0x5E '^'
{ 1072, 12, 2, 11, 0, 3 }, // 0x5F '_'
{ 1075, 4, 3, 5, 0, -14 }, // 0x60 '`'
{ 1077, 10, 11, 11, 1, -10 }, // 0x61 'a'
{ 1091, 11, 15, 12, 1, -14 }, // 0x62 'b'
{ 1112, 10, 11, 11, 1, -10 }, // 0x63 'c'
{ 1126, 10, 15, 12, 1, -14 }, // 0x64 'd'
{ 1145, 10, 11, 12, 1, -10 }, // 0x65 'e'
{ 1159, 6, 15, 7, 1, -14 }, // 0x66 'f'
{ 1171, 10, 15, 12, 1, -10 }, // 0x67 'g'
{ 1190, 10, 15, 12, 1, -14 }, // 0x68 'h'
{ 1209, 3, 15, 6, 1, -14 }, // 0x69 'i'
{ 1215, 4, 19, 6, 0, -14 }, // 0x6A 'j'
{ 1225, 10, 15, 11, 1, -14 }, // 0x6B 'k'
{ 1244, 3, 15, 5, 1, -14 }, // 0x6C 'l'
{ 1250, 16, 11, 18, 1, -10 }, // 0x6D 'm'
{ 1272, 10, 11, 12, 1, -10 }, // 0x6E 'n'
{ 1286, 11, 11, 12, 1, -10 }, // 0x6F 'o'
{ 1302, 11, 15, 12, 1, -10 }, // 0x70 'p'
{ 1323, 10, 15, 12, 1, -10 }, // 0x71 'q'
{ 1342, 6, 11, 8, 1, -10 }, // 0x72 'r'
{ 1351, 10, 11, 11, 1, -10 }, // 0x73 's'
{ 1365, 5, 13, 7, 1, -12 }, // 0x74 't'
{ 1374, 10, 11, 12, 1, -10 }, // 0x75 'u'
{ 1388, 11, 11, 11, 0, -10 }, // 0x76 'v'
{ 1404, 15, 11, 16, 0, -10 }, // 0x77 'w'
{ 1425, 11, 11, 11, 0, -10 }, // 0x78 'x'
{ 1441, 11, 15, 11, 0, -10 }, // 0x79 'y'
{ 1462, 9, 11, 10, 1, -10 }, // 0x7A 'z'
{ 1475, 5, 19, 8, 0, -14 }, // 0x7B '{'
{ 1487, 1, 19, 6, 2, -14 }, // 0x7C '|'
{ 1490, 5, 19, 8, 2, -14 }, // 0x7D '}'
{ 1502, 9, 4, 10, 0, -6 } }; // 0x7E '~'
const GFXfont FreeSansBold10pt7b PROGMEM = {
(uint8_t *)FreeSansBold10pt7bBitmaps,
(GFXglyph *)FreeSansBold10pt7bGlyphs,
0x20, 0x7E, 24 };
// Approx. 2179 bytes
#endif // FreeSansBold10pt7b_H

View File

@ -1,312 +0,0 @@
#ifndef FreeSerifBoldItalic12pt7b_H
#define FreeSerifBoldItalic12pt7b_H
#ifdef __AVR__
#include <avr/io.h>
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#undef PROGMEM
#define PROGMEM STORE_ATTR
#elif defined(__IMXRT1052__) || defined(__IMXRT1062__)
// PROGMEM is defefind for T4 to place data in specific memory section
#undef PROGMEM
#define PROGMEM
#else
#define PROGMEM
#endif
const uint8_t FreeSerifBoldItalic12pt7bBitmaps[] PROGMEM = {
0x00, 0x07, 0x07, 0x07, 0x0F, 0x0E, 0x0E, 0x0C, 0x0C, 0x08, 0x18, 0x10,
0x00, 0x00, 0x60, 0xF0, 0xF0, 0x60, 0x61, 0xF1, 0xF8, 0xF8, 0x6C, 0x34,
0x12, 0x08, 0x01, 0x8C, 0x06, 0x60, 0x31, 0x80, 0xCC, 0x06, 0x30, 0xFF,
0xF0, 0xC6, 0x03, 0x18, 0x0C, 0xC0, 0x63, 0x0F, 0xFF, 0x0C, 0x60, 0x33,
0x01, 0x8C, 0x06, 0x30, 0x19, 0x80, 0x00, 0x80, 0x08, 0x07, 0xC1, 0x97,
0x31, 0x33, 0x13, 0x3A, 0x23, 0xE0, 0x1E, 0x01, 0xF0, 0x07, 0x80, 0x7C,
0x05, 0xC4, 0xCC, 0x48, 0xCC, 0x8C, 0xF8, 0x83, 0x30, 0x1E, 0x01, 0x00,
0x00, 0x02, 0x07, 0x83, 0x03, 0x9F, 0x81, 0xC4, 0x20, 0x71, 0x10, 0x3C,
0x44, 0x0E, 0x22, 0x03, 0x88, 0x80, 0xE4, 0x40, 0x1E, 0x31, 0xE0, 0x08,
0xE4, 0x06, 0x71, 0x01, 0x3C, 0x40, 0x8E, 0x10, 0x23, 0x88, 0x10, 0xE2,
0x04, 0x39, 0x02, 0x07, 0x80, 0x00, 0xF0, 0x01, 0x98, 0x03, 0x98, 0x03,
0x98, 0x03, 0xB0, 0x03, 0xE0, 0x03, 0x80, 0x0F, 0x9F, 0x19, 0xCE, 0x31,
0xCC, 0x61, 0xC8, 0xE1, 0xC8, 0xE0, 0xF0, 0xE0, 0xE0, 0xF0, 0x70, 0x78,
0x79, 0x3F, 0xBE, 0x7F, 0xED, 0x20, 0x02, 0x08, 0x20, 0xC3, 0x0E, 0x18,
0x30, 0xE1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x20, 0x40, 0x80, 0x81, 0x01,
0x00, 0x10, 0x10, 0x20, 0x20, 0x40, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x70,
0xE1, 0x83, 0x0C, 0x18, 0x61, 0x86, 0x00, 0x00, 0x0C, 0x33, 0x6C, 0x9B,
0xAE, 0x1C, 0x3F, 0xEC, 0x9B, 0x36, 0x0C, 0x02, 0x00, 0x06, 0x00, 0x60,
0x06, 0x00, 0x60, 0x06, 0x0F, 0xFF, 0xFF, 0xF0, 0x60, 0x06, 0x00, 0x60,
0x06, 0x00, 0x60, 0x31, 0xCE, 0x31, 0x08, 0x98, 0xFF, 0xFF, 0xC0, 0x6F,
0xF6, 0x01, 0x80, 0x60, 0x30, 0x0C, 0x07, 0x01, 0x80, 0xE0, 0x30, 0x1C,
0x06, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x06, 0x03, 0x00, 0x03, 0x81, 0xC8,
0x71, 0x1C, 0x33, 0x86, 0xE1, 0xDC, 0x3B, 0x87, 0xE0, 0xFC, 0x3B, 0x87,
0x70, 0xEC, 0x39, 0x87, 0x31, 0xC2, 0x30, 0x3C, 0x00, 0x01, 0xC3, 0xF0,
0x38, 0x0E, 0x03, 0x81, 0xE0, 0x70, 0x1C, 0x0F, 0x03, 0x80, 0xE0, 0x38,
0x1E, 0x07, 0x01, 0xC0, 0xF0, 0xFF, 0x80, 0x07, 0x81, 0xF8, 0x47, 0x90,
0x70, 0x0E, 0x01, 0xC0, 0x30, 0x0E, 0x01, 0x80, 0x60, 0x18, 0x06, 0x01,
0x80, 0x40, 0x8F, 0xF3, 0xFC, 0xFF, 0x80, 0x07, 0xC3, 0x3C, 0x03, 0x80,
0x70, 0x0C, 0x03, 0x81, 0xC0, 0xFC, 0x07, 0xC0, 0x78, 0x07, 0x00, 0xE0,
0x1C, 0x03, 0x30, 0xE7, 0x10, 0x7C, 0x00, 0x00, 0x10, 0x01, 0x80, 0x3C,
0x03, 0xE0, 0x2E, 0x02, 0x70, 0x23, 0x82, 0x38, 0x21, 0xC2, 0x0E, 0x1F,
0xF9, 0xFF, 0xC0, 0x38, 0x01, 0xC0, 0x1C, 0x00, 0xE0, 0x07, 0xF0, 0x7E,
0x0F, 0xE0, 0x80, 0x08, 0x01, 0xE0, 0x1F, 0x83, 0xF8, 0x03, 0xC0, 0x1C,
0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x08, 0x61, 0x8F, 0x30, 0x7C, 0x00, 0x00,
0x60, 0x78, 0x1C, 0x0F, 0x01, 0xC0, 0x70, 0x1F, 0xC3, 0x8C, 0xE1, 0xDC,
0x3B, 0x87, 0x61, 0xEC, 0x3D, 0x87, 0x31, 0xE2, 0x38, 0x3C, 0x00, 0x3F,
0xEF, 0xF9, 0xFF, 0x60, 0xC8, 0x18, 0x06, 0x00, 0x80, 0x30, 0x0C, 0x01,
0x80, 0x60, 0x1C, 0x03, 0x00, 0xC0, 0x18, 0x06, 0x00, 0x03, 0x81, 0x88,
0x61, 0x8C, 0x31, 0x86, 0x38, 0xC7, 0xF0, 0x78, 0x0F, 0x86, 0x71, 0x87,
0x60, 0x6C, 0x0D, 0x81, 0xB0, 0x23, 0x18, 0x3E, 0x00, 0x07, 0x81, 0xC8,
0x71, 0x8E, 0x33, 0xC6, 0x70, 0xCE, 0x39, 0xC7, 0x38, 0xE3, 0x38, 0x3F,
0x01, 0xC0, 0x38, 0x0E, 0x07, 0x81, 0xC0, 0xE0, 0x00, 0x0C, 0x3C, 0x78,
0x60, 0x00, 0x00, 0x00, 0x61, 0xE3, 0xC3, 0x00, 0x0E, 0x0F, 0x0F, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x18, 0x10, 0x20, 0x40, 0x00,
0x10, 0x07, 0x01, 0xF0, 0x7C, 0x3F, 0x0F, 0x80, 0xE0, 0x0F, 0x80, 0x3E,
0x00, 0xF8, 0x03, 0xF0, 0x0F, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0x00, 0x3F, 0x00, 0x3E, 0x00, 0x7C,
0x00, 0xF8, 0x01, 0xE0, 0x1F, 0x07, 0xE0, 0xF8, 0x1F, 0x01, 0xE0, 0x0C,
0x00, 0x00, 0x1E, 0x19, 0x8C, 0xE6, 0x70, 0x38, 0x38, 0x18, 0x18, 0x18,
0x08, 0x08, 0x00, 0x00, 0x03, 0x03, 0xC1, 0xE0, 0x60, 0x00, 0x03, 0xF0,
0x07, 0x06, 0x06, 0x00, 0x86, 0x0E, 0x66, 0x0D, 0xDB, 0x0C, 0xE7, 0x06,
0x33, 0x83, 0x31, 0xC3, 0x18, 0xE1, 0x8C, 0x70, 0xCC, 0x4C, 0x66, 0x46,
0x1F, 0xC1, 0x80, 0x00, 0x30, 0x10, 0x07, 0xF0, 0x00, 0x10, 0x00, 0x30,
0x00, 0x70, 0x00, 0x70, 0x00, 0xF0, 0x01, 0xF0, 0x01, 0x78, 0x03, 0x78,
0x02, 0x38, 0x04, 0x38, 0x0C, 0x38, 0x0F, 0xF8, 0x18, 0x3C, 0x30, 0x3C,
0x20, 0x3C, 0x60, 0x3C, 0xF8, 0x7F, 0x1F, 0xFC, 0x07, 0x9E, 0x07, 0x0F,
0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x0E, 0x3C, 0x0F, 0xE0, 0x1E, 0x3C,
0x1E, 0x1E, 0x1C, 0x1E, 0x3C, 0x1E, 0x3C, 0x1E, 0x3C, 0x3E, 0x38, 0x3C,
0x7C, 0x78, 0xFF, 0xE0, 0x01, 0xF2, 0x0E, 0x1C, 0x38, 0x18, 0xF0, 0x33,
0xC0, 0x4F, 0x00, 0x9E, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC0,
0x07, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x1E, 0x04, 0x1E, 0x30, 0x0F, 0x80,
0x1F, 0xFC, 0x01, 0xE3, 0xC0, 0x70, 0x78, 0x1C, 0x0E, 0x0F, 0x03, 0xC3,
0xC0, 0xF0, 0xE0, 0x3C, 0x38, 0x0F, 0x1E, 0x03, 0xC7, 0x81, 0xF1, 0xC0,
0x78, 0xF0, 0x1E, 0x3C, 0x0F, 0x0F, 0x03, 0xC3, 0x81, 0xC1, 0xF1, 0xE0,
0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0x83, 0xC1, 0xC1, 0xC0, 0x40, 0xE0, 0x20,
0xF0, 0x00, 0x78, 0xC0, 0x38, 0x40, 0x1F, 0xE0, 0x1E, 0x70, 0x0F, 0x18,
0x07, 0x08, 0x03, 0x84, 0x03, 0xC0, 0x61, 0xE0, 0x20, 0xE0, 0x30, 0xF8,
0x78, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0x07, 0x87, 0x07, 0x02, 0x07, 0x02,
0x0F, 0x00, 0x0F, 0x18, 0x0E, 0x10, 0x0F, 0xF0, 0x1E, 0x70, 0x1E, 0x30,
0x1C, 0x20, 0x1C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x38, 0x00, 0x7C, 0x00,
0xFE, 0x00, 0x01, 0xF9, 0x03, 0xC3, 0x83, 0x81, 0xC3, 0x80, 0x43, 0xC0,
0x23, 0xC0, 0x01, 0xE0, 0x01, 0xF0, 0x00, 0xF0, 0x3F, 0xF8, 0x0F, 0x3C,
0x07, 0x9E, 0x03, 0xCF, 0x01, 0xC3, 0x80, 0xE1, 0xE0, 0xF0, 0x78, 0x70,
0x0F, 0xE0, 0x00, 0x1F, 0xE7, 0xF0, 0x78, 0x3C, 0x07, 0x83, 0xC0, 0x70,
0x3C, 0x0F, 0x03, 0x80, 0xF0, 0x78, 0x0E, 0x07, 0x80, 0xE0, 0x70, 0x1F,
0xFF, 0x01, 0xE0, 0xF0, 0x1C, 0x0F, 0x03, 0xC0, 0xE0, 0x3C, 0x1E, 0x03,
0xC1, 0xE0, 0x38, 0x1E, 0x07, 0xC3, 0xE0, 0xFE, 0x7F, 0x00, 0x1F, 0xC1,
0xE0, 0x70, 0x1C, 0x0F, 0x03, 0xC0, 0xE0, 0x38, 0x1E, 0x07, 0x81, 0xC0,
0x70, 0x3C, 0x0F, 0x03, 0x81, 0xF0, 0xFE, 0x00, 0x01, 0xFC, 0x03, 0xC0,
0x0F, 0x00, 0x38, 0x00, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x70, 0x01, 0xC0,
0x0F, 0x00, 0x3C, 0x00, 0xE0, 0x07, 0x80, 0x1E, 0x0E, 0x70, 0x3B, 0xC0,
0xCE, 0x01, 0xF0, 0x00, 0x1F, 0xEF, 0x83, 0xC1, 0x81, 0xC1, 0x80, 0xE1,
0x80, 0xF1, 0x80, 0x79, 0x00, 0x39, 0x00, 0x1F, 0x80, 0x1F, 0xE0, 0x0F,
0x70, 0x07, 0x3C, 0x07, 0x8E, 0x03, 0xC7, 0x01, 0xE3, 0xC0, 0xE0, 0xE0,
0xF8, 0x78, 0xFE, 0xFE, 0x00, 0x1F, 0xE0, 0x0F, 0x00, 0x1C, 0x00, 0x38,
0x00, 0xF0, 0x01, 0xE0, 0x03, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x3C, 0x00,
0x70, 0x00, 0xE0, 0x03, 0xC0, 0x27, 0x00, 0xCE, 0x03, 0x3C, 0x1E, 0xFF,
0xFC, 0x0F, 0x80, 0x7E, 0x0F, 0x00, 0xF0, 0x1E, 0x03, 0xE0, 0x3C, 0x0F,
0x80, 0xB8, 0x17, 0x01, 0x70, 0x5E, 0x02, 0xF1, 0xBC, 0x05, 0xE2, 0x70,
0x11, 0xC8, 0xE0, 0x23, 0xB3, 0xC0, 0x47, 0x47, 0x81, 0x0F, 0x8E, 0x02,
0x1E, 0x1C, 0x04, 0x38, 0x78, 0x08, 0x70, 0xF0, 0x30, 0xC3, 0xE0, 0xF9,
0x8F, 0xE0, 0x1F, 0x03, 0xE0, 0xF0, 0x38, 0x1E, 0x02, 0x03, 0xE0, 0xC0,
0xBC, 0x10, 0x13, 0xC2, 0x02, 0x78, 0x40, 0x47, 0x90, 0x10, 0xF2, 0x02,
0x0F, 0x40, 0x41, 0xE8, 0x18, 0x1E, 0x02, 0x03, 0xC0, 0x40, 0x38, 0x08,
0x06, 0x03, 0x00, 0x40, 0x10, 0x08, 0x00, 0x01, 0xF8, 0x07, 0x1C, 0x0E,
0x0E, 0x1E, 0x0F, 0x3C, 0x0F, 0x3C, 0x0F, 0x78, 0x0F, 0x78, 0x0F, 0xF8,
0x1F, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x78, 0x70,
0x70, 0x38, 0xE0, 0x1F, 0x80, 0x1F, 0xFC, 0x07, 0x9E, 0x07, 0x0F, 0x07,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0E, 0x1E, 0x0E, 0x3C, 0x1F, 0xF0, 0x1E,
0x00, 0x1C, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x38, 0x00, 0x38, 0x00, 0x7C,
0x00, 0xFE, 0x00, 0x01, 0xF8, 0x07, 0x1C, 0x0E, 0x0E, 0x1E, 0x0F, 0x3C,
0x0F, 0x3C, 0x0F, 0x78, 0x0F, 0x78, 0x1F, 0xF8, 0x1F, 0xF0, 0x1E, 0xF0,
0x1E, 0xF0, 0x3C, 0xF0, 0x3C, 0xF0, 0x78, 0x70, 0x70, 0x39, 0xC0, 0x0E,
0x00, 0x08, 0x02, 0x3F, 0x04, 0x7F, 0xF8, 0x83, 0xF0, 0x1F, 0xFC, 0x07,
0x9E, 0x07, 0x8F, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x1E, 0x0E,
0x3C, 0x1F, 0xF0, 0x1E, 0xF0, 0x1C, 0xF0, 0x3C, 0xF0, 0x3C, 0x78, 0x3C,
0x78, 0x3C, 0x78, 0x7C, 0x3C, 0xFE, 0x3E, 0x07, 0x91, 0xC7, 0x18, 0x73,
0x82, 0x38, 0x23, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x01, 0xE0,
0x1E, 0x40, 0xE4, 0x0E, 0x60, 0xCE, 0x1C, 0x9F, 0x00, 0x7F, 0xFE, 0xE7,
0x9D, 0x0E, 0x16, 0x3C, 0x20, 0x78, 0x40, 0xE0, 0x01, 0xC0, 0x07, 0x80,
0x0F, 0x00, 0x1C, 0x00, 0x38, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0x80, 0x0F,
0x00, 0x1E, 0x00, 0xFF, 0x00, 0x7F, 0x1F, 0x3C, 0x0E, 0x38, 0x04, 0x38,
0x0C, 0x78, 0x08, 0x78, 0x08, 0x70, 0x08, 0x70, 0x10, 0xF0, 0x10, 0xF0,
0x10, 0xF0, 0x10, 0xF0, 0x20, 0xF0, 0x20, 0xF0, 0x20, 0xF0, 0x40, 0x78,
0xC0, 0x3F, 0x00, 0xFF, 0x1F, 0x3C, 0x06, 0x3C, 0x04, 0x3C, 0x08, 0x3C,
0x08, 0x3C, 0x10, 0x1C, 0x20, 0x1C, 0x20, 0x1E, 0x40, 0x1E, 0x80, 0x1E,
0x80, 0x1F, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0C, 0x00, 0x08, 0x00, 0xFE,
0x7C, 0x79, 0xE1, 0xC1, 0x8F, 0x0E, 0x08, 0x78, 0x70, 0x43, 0xC7, 0x84,
0x1E, 0x3E, 0x20, 0x72, 0xF2, 0x03, 0x97, 0x90, 0x1D, 0x1D, 0x00, 0xE8,
0xE8, 0x07, 0x87, 0x80, 0x3C, 0x3C, 0x01, 0xC1, 0xC0, 0x0E, 0x0E, 0x00,
0x20, 0x60, 0x01, 0x02, 0x00, 0x1F, 0xCF, 0x83, 0xC1, 0x81, 0xE1, 0x80,
0x71, 0x80, 0x39, 0x80, 0x1F, 0x80, 0x07, 0x80, 0x03, 0x80, 0x01, 0xE0,
0x01, 0xF0, 0x00, 0xB8, 0x00, 0x9C, 0x00, 0x8F, 0x00, 0x83, 0x80, 0xC1,
0xC0, 0xE0, 0xF0, 0xF9, 0xFE, 0x00, 0xFE, 0x7D, 0xE0, 0x63, 0x81, 0x0F,
0x08, 0x1C, 0x40, 0x71, 0x01, 0xE8, 0x03, 0xC0, 0x0E, 0x00, 0x38, 0x01,
0xE0, 0x07, 0x80, 0x1C, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x00,
0x1F, 0xFE, 0x38, 0x78, 0x60, 0xF1, 0x83, 0xC2, 0x0F, 0x00, 0x1E, 0x00,
0x78, 0x01, 0xE0, 0x07, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF8, 0x01, 0xE0,
0x47, 0x81, 0x1F, 0x06, 0x3C, 0x3C, 0xFF, 0xF0, 0x07, 0xC1, 0x80, 0xE0,
0x30, 0x0C, 0x03, 0x01, 0xC0, 0x60, 0x18, 0x06, 0x03, 0x80, 0xC0, 0x30,
0x0C, 0x07, 0x01, 0xC0, 0x60, 0x18, 0x0E, 0x03, 0xE0, 0xC3, 0x06, 0x18,
0x61, 0x83, 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x60, 0xC3, 0x0F, 0x81, 0xC0,
0xE0, 0x60, 0x30, 0x18, 0x1C, 0x0C, 0x06, 0x03, 0x03, 0x81, 0x80, 0xC0,
0x60, 0x70, 0x38, 0x18, 0x0C, 0x0E, 0x1F, 0x00, 0x0C, 0x07, 0x81, 0xE0,
0xDC, 0x33, 0x18, 0xC6, 0x1B, 0x06, 0xC0, 0xC0, 0xFF, 0xF0, 0xC7, 0x0C,
0x30, 0x07, 0x70, 0xCE, 0x1C, 0xE3, 0x8E, 0x70, 0xC7, 0x0C, 0x71, 0xCE,
0x1C, 0xE1, 0x8E, 0x79, 0xE9, 0xA7, 0x1C, 0x02, 0x07, 0xC0, 0x38, 0x06,
0x01, 0xC0, 0x38, 0x06, 0x71, 0xF7, 0x38, 0xE7, 0x1C, 0xC3, 0xB8, 0x77,
0x1C, 0xE3, 0xB8, 0xE7, 0x18, 0xE6, 0x0F, 0x80, 0x07, 0x0C, 0xCE, 0x66,
0x07, 0x03, 0x83, 0x81, 0xC0, 0xE0, 0x70, 0xBC, 0x87, 0x80, 0x00, 0x08,
0x03, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x70, 0x01, 0xC0, 0x7F, 0x03, 0x3C,
0x1C, 0xE0, 0xE3, 0x87, 0x0E, 0x1C, 0x70, 0x71, 0xC3, 0x87, 0x0E, 0x3C,
0x38, 0xE8, 0xE5, 0xA1, 0xE7, 0x00, 0x07, 0x0C, 0xCE, 0x66, 0x37, 0x33,
0xBB, 0xB1, 0xE0, 0xE0, 0x70, 0xB8, 0x8F, 0x00, 0x00, 0x38, 0x01, 0xB0,
0x0C, 0xC0, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x7E, 0x00, 0xE0, 0x03, 0x80,
0x0E, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x03, 0x80,
0x0E, 0x00, 0x38, 0x00, 0xC0, 0x33, 0x00, 0xD8, 0x01, 0xC0, 0x00, 0x07,
0x80, 0x73, 0xC7, 0x1C, 0x38, 0xE1, 0xCF, 0x06, 0x70, 0x1E, 0x01, 0x00,
0x1C, 0x00, 0xFC, 0x07, 0xF0, 0xC7, 0x8C, 0x0C, 0x60, 0x63, 0x86, 0x07,
0xE0, 0x01, 0x00, 0xF8, 0x01, 0x80, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x31,
0xC3, 0xBE, 0x1E, 0x70, 0xE3, 0x8F, 0x38, 0x71, 0xC3, 0x8E, 0x1C, 0xE1,
0xC7, 0x0E, 0x3A, 0x71, 0xD3, 0x0F, 0x00, 0x1C, 0x71, 0xC0, 0x00, 0x6F,
0x8E, 0x31, 0xC7, 0x18, 0x63, 0x8E, 0xBC, 0xE0, 0x00, 0xE0, 0x1C, 0x03,
0x80, 0x00, 0x00, 0x0F, 0x80, 0x70, 0x0E, 0x01, 0xC0, 0x70, 0x0E, 0x01,
0xC0, 0x38, 0x0E, 0x01, 0xC0, 0x38, 0x06, 0x01, 0xC3, 0x38, 0x6E, 0x07,
0x80, 0x01, 0x00, 0xF8, 0x01, 0xC0, 0x1C, 0x00, 0xE0, 0x07, 0x00, 0x33,
0xE3, 0x8C, 0x1C, 0xC0, 0xE4, 0x06, 0x40, 0x7E, 0x03, 0xF0, 0x1D, 0x81,
0xCE, 0x0E, 0x72, 0x71, 0xA3, 0x8E, 0x00, 0x06, 0x7C, 0x70, 0xE1, 0xC3,
0x0E, 0x1C, 0x38, 0x61, 0xC3, 0x87, 0x1C, 0x38, 0x72, 0xE9, 0xE0, 0x3C,
0x73, 0xC7, 0x7D, 0x71, 0xE7, 0x9C, 0xF1, 0xCE, 0x3C, 0xF3, 0x8E, 0x39,
0xC3, 0x8E, 0x71, 0xC3, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xD7, 0x1C, 0x7B,
0x8E, 0x1C, 0x3C, 0xF1, 0xD7, 0x1E, 0x73, 0xCE, 0x3C, 0xE3, 0x8E, 0x39,
0xC7, 0x1C, 0x71, 0xC7, 0x1D, 0x71, 0xEE, 0x1C, 0x0F, 0x06, 0x63, 0x9D,
0xC7, 0x71, 0xF8, 0x7E, 0x3F, 0x8E, 0xE3, 0xB9, 0xC6, 0x60, 0xF0, 0x0F,
0x38, 0x1F, 0x70, 0x71, 0xC1, 0xC7, 0x0E, 0x1C, 0x38, 0xF0, 0xE3, 0x83,
0x8E, 0x1C, 0x70, 0x71, 0xC1, 0xCE, 0x07, 0xE0, 0x38, 0x00, 0xE0, 0x03,
0x80, 0x3F, 0x00, 0x07, 0x70, 0xCE, 0x18, 0xE3, 0x8E, 0x70, 0xE7, 0x1C,
0xF1, 0xCE, 0x1C, 0xE3, 0x8E, 0x38, 0xE7, 0x87, 0xB0, 0x07, 0x00, 0x70,
0x0F, 0x03, 0xF8, 0x0D, 0xDF, 0x71, 0xAC, 0xF0, 0x38, 0x0E, 0x03, 0x81,
0xC0, 0x70, 0x1C, 0x0E, 0x00, 0x1D, 0x99, 0x8C, 0x46, 0x23, 0x80, 0xE0,
0x70, 0x1C, 0x06, 0x23, 0x19, 0x1F, 0x00, 0x0C, 0x10, 0xE3, 0xF3, 0x86,
0x1C, 0x38, 0x71, 0xC3, 0x87, 0x0E, 0x9E, 0x38, 0x00, 0xF8, 0xE3, 0x8E,
0x38, 0xC3, 0x9C, 0x71, 0xC7, 0x18, 0x71, 0x87, 0x38, 0xE3, 0x8E, 0xFA,
0xF3, 0xAE, 0x3C, 0xF0, 0xDC, 0x33, 0x0C, 0xC2, 0x31, 0x8C, 0xC3, 0x60,
0xF0, 0x38, 0x0C, 0x02, 0x00, 0xE0, 0x86, 0xE3, 0x0C, 0xC6, 0x19, 0x9C,
0x23, 0x78, 0xC7, 0xF9, 0x0E, 0x74, 0x1C, 0xF0, 0x31, 0xC0, 0x43, 0x00,
0x84, 0x00, 0x0E, 0x31, 0xF3, 0x83, 0xA0, 0x0E, 0x00, 0x70, 0x03, 0x80,
0x1C, 0x00, 0xE0, 0x0B, 0x02, 0x5D, 0x3C, 0xF1, 0xC3, 0x00, 0x04, 0x67,
0x8C, 0x79, 0x87, 0x10, 0xE2, 0x1C, 0x81, 0x90, 0x3A, 0x07, 0x80, 0xF0,
0x1C, 0x03, 0x00, 0x60, 0x08, 0x32, 0x07, 0x80, 0x3F, 0xCF, 0xE6, 0x30,
0x08, 0x04, 0x02, 0x01, 0x00, 0xC0, 0x30, 0x1E, 0x0F, 0x98, 0x76, 0x07,
0x00, 0x01, 0xE0, 0x70, 0x1C, 0x03, 0x80, 0x60, 0x1C, 0x03, 0x80, 0x60,
0x0C, 0x03, 0x80, 0xF0, 0x3C, 0x07, 0x00, 0x40, 0x0C, 0x01, 0x80, 0x70,
0x0E, 0x01, 0xC0, 0x30, 0x03, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x00,
0xE0, 0x18, 0x06, 0x01, 0x80, 0xE0, 0x38, 0x0C, 0x03, 0x00, 0xC0, 0x10,
0x1F, 0x07, 0x03, 0x80, 0xE0, 0x30, 0x0C, 0x07, 0x01, 0x80, 0xE0, 0xE0,
0x00, 0x38, 0x0F, 0xCD, 0x1F, 0x80, 0xE0 };
const GFXglyph FreeSerifBoldItalic12pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 6, 0, 0 }, // 0x20 ' '
{ 1, 8, 17, 9, 2, -15 }, // 0x21 '!'
{ 18, 9, 7, 13, 4, -15 }, // 0x22 '"'
{ 26, 14, 16, 12, -1, -15 }, // 0x23 '#'
{ 54, 12, 20, 12, 0, -17 }, // 0x24 '$'
{ 84, 18, 18, 20, 1, -16 }, // 0x25 '%'
{ 125, 16, 17, 19, 0, -15 }, // 0x26 '&'
{ 159, 3, 7, 7, 3, -15 }, // 0x27 '''
{ 162, 7, 21, 8, 1, -15 }, // 0x28 '('
{ 181, 7, 21, 8, -1, -15 }, // 0x29 ')'
{ 200, 10, 10, 12, 1, -15 }, // 0x2A '*'
{ 213, 12, 12, 14, 1, -11 }, // 0x2B '+'
{ 231, 5, 8, 6, -2, -3 }, // 0x2C ','
{ 236, 6, 3, 8, 0, -6 }, // 0x2D '-'
{ 239, 4, 4, 6, 0, -2 }, // 0x2E '.'
{ 241, 10, 16, 8, 0, -15 }, // 0x2F '/'
{ 261, 11, 17, 12, 0, -15 }, // 0x30 '0'
{ 285, 10, 17, 12, 0, -15 }, // 0x31 '1'
{ 307, 11, 17, 12, 0, -15 }, // 0x32 '2'
{ 331, 11, 17, 12, 0, -15 }, // 0x33 '3'
{ 355, 13, 16, 12, 0, -15 }, // 0x34 '4'
{ 381, 12, 17, 12, 0, -15 }, // 0x35 '5'
{ 407, 11, 17, 12, 1, -15 }, // 0x36 '6'
{ 431, 11, 16, 12, 2, -15 }, // 0x37 '7'
{ 453, 11, 17, 12, 0, -15 }, // 0x38 '8'
{ 477, 11, 17, 12, 0, -15 }, // 0x39 '9'
{ 501, 7, 12, 6, 0, -10 }, // 0x3A ':'
{ 512, 8, 15, 6, -1, -10 }, // 0x3B ';'
{ 527, 12, 13, 14, 1, -12 }, // 0x3C '<'
{ 547, 12, 6, 14, 2, -8 }, // 0x3D '='
{ 556, 13, 13, 14, 1, -12 }, // 0x3E '>'
{ 578, 9, 17, 12, 2, -15 }, // 0x3F '?'
{ 598, 17, 16, 20, 1, -15 }, // 0x40 '@'
{ 632, 16, 17, 17, 0, -15 }, // 0x41 'A'
{ 666, 16, 17, 15, 0, -15 }, // 0x42 'B'
{ 700, 15, 17, 15, 1, -15 }, // 0x43 'C'
{ 732, 18, 17, 17, 0, -15 }, // 0x44 'D'
{ 771, 17, 17, 15, 0, -15 }, // 0x45 'E'
{ 808, 16, 17, 15, 0, -15 }, // 0x46 'F'
{ 842, 17, 17, 17, 1, -15 }, // 0x47 'G'
{ 879, 20, 17, 18, 0, -15 }, // 0x48 'H'
{ 922, 10, 17, 9, 0, -15 }, // 0x49 'I'
{ 944, 14, 18, 12, 0, -15 }, // 0x4A 'J'
{ 976, 17, 17, 16, 0, -15 }, // 0x4B 'K'
{ 1013, 15, 17, 15, 0, -15 }, // 0x4C 'L'
{ 1045, 23, 17, 21, 0, -15 }, // 0x4D 'M'
{ 1094, 19, 17, 17, 0, -15 }, // 0x4E 'N'
{ 1135, 16, 17, 16, 1, -15 }, // 0x4F 'O'
{ 1169, 16, 17, 14, 0, -15 }, // 0x50 'P'
{ 1203, 16, 21, 16, 1, -15 }, // 0x51 'Q'
{ 1245, 16, 17, 16, 0, -15 }, // 0x52 'R'
{ 1279, 12, 17, 12, 0, -15 }, // 0x53 'S'
{ 1305, 15, 17, 14, 2, -15 }, // 0x54 'T'
{ 1337, 16, 17, 17, 3, -15 }, // 0x55 'U'
{ 1371, 16, 16, 17, 3, -15 }, // 0x56 'V'
{ 1403, 21, 16, 22, 3, -15 }, // 0x57 'W'
{ 1445, 17, 17, 17, 0, -15 }, // 0x58 'X'
{ 1482, 14, 17, 15, 3, -15 }, // 0x59 'Y'
{ 1512, 15, 17, 13, 0, -15 }, // 0x5A 'Z'
{ 1544, 10, 20, 8, -1, -15 }, // 0x5B '['
{ 1569, 6, 16, 10, 3, -15 }, // 0x5C '\'
{ 1581, 9, 20, 8, -1, -15 }, // 0x5D ']'
{ 1604, 10, 9, 14, 2, -15 }, // 0x5E '^'
{ 1616, 12, 1, 12, 0, 4 }, // 0x5F '_'
{ 1618, 5, 4, 8, 2, -15 }, // 0x60 '`'
{ 1621, 12, 12, 12, 0, -10 }, // 0x61 'a'
{ 1639, 11, 18, 12, 1, -16 }, // 0x62 'b'
{ 1664, 9, 12, 10, 1, -10 }, // 0x63 'c'
{ 1678, 14, 18, 12, 0, -16 }, // 0x64 'd'
{ 1710, 9, 12, 10, 1, -10 }, // 0x65 'e'
{ 1724, 14, 22, 12, -2, -16 }, // 0x66 'f'
{ 1763, 13, 16, 12, -1, -10 }, // 0x67 'g'
{ 1789, 13, 18, 13, 0, -16 }, // 0x68 'h'
{ 1819, 6, 17, 7, 1, -15 }, // 0x69 'i'
{ 1832, 11, 21, 8, -2, -15 }, // 0x6A 'j'
{ 1861, 13, 18, 12, 0, -16 }, // 0x6B 'k'
{ 1891, 7, 18, 7, 1, -16 }, // 0x6C 'l'
{ 1907, 18, 12, 18, 0, -10 }, // 0x6D 'm'
{ 1934, 12, 12, 13, 0, -10 }, // 0x6E 'n'
{ 1952, 10, 12, 11, 1, -10 }, // 0x6F 'o'
{ 1967, 14, 16, 12, -2, -10 }, // 0x70 'p'
{ 1995, 12, 16, 12, 0, -10 }, // 0x71 'q'
{ 2019, 10, 11, 10, 0, -10 }, // 0x72 'r'
{ 2033, 9, 12, 9, 0, -10 }, // 0x73 's'
{ 2047, 7, 15, 7, 1, -13 }, // 0x74 't'
{ 2061, 12, 12, 13, 1, -10 }, // 0x75 'u'
{ 2079, 10, 11, 11, 1, -10 }, // 0x76 'v'
{ 2093, 15, 11, 16, 1, -10 }, // 0x77 'w'
{ 2114, 13, 12, 11, -1, -10 }, // 0x78 'x'
{ 2134, 11, 16, 10, -1, -10 }, // 0x79 'y'
{ 2156, 10, 13, 10, 0, -10 }, // 0x7A 'z'
{ 2173, 11, 21, 8, 0, -16 }, // 0x7B '{'
{ 2202, 2, 16, 6, 3, -15 }, // 0x7C '|'
{ 2206, 10, 21, 8, -3, -16 }, // 0x7D '}'
{ 2233, 11, 4, 14, 1, -7 } }; // 0x7E '~'
const GFXfont FreeSerifBoldItalic12pt7b PROGMEM = {
(uint8_t *)FreeSerifBoldItalic12pt7bBitmaps,
(GFXglyph *)FreeSerifBoldItalic12pt7bGlyphs,
0x20, 0x7E, 28 };
// Approx. 2911 bytes
#endif // FreeSerifBoldItalic12pt7b_H

View File

@ -1,98 +0,0 @@
/*******************************************************************************
* Start of Arduino_GFX setting
*
* Arduino_GFX try to find the settings depends on selected board in Arduino IDE
* Or you can define the display dev kit not in the board list
* Defalult pin list for non display dev kit:
* Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12
* ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
* ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil
* ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
* ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
* ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12
* Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16
* RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20
* RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11
* RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12
* RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10
* Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9
* Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 0 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
/* more fonts at: https://github.com/moononournation/ArduinoFreeFontFile.git */
#include "FreeMono8pt7b.h"
#include "FreeSansBold10pt7b.h"
#include "FreeSerifBoldItalic12pt7b.h"
void setup(void)
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX Hello World Gfxfont example");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
gfx->setCursor(10, 10);
gfx->setFont(&FreeMono8pt7b);
gfx->setTextColor(RGB565_RED);
gfx->println("Hello World!");
delay(5000); // 5 seconds
}
void loop()
{
gfx->setCursor(random(gfx->width()), random(gfx->height()));
gfx->setTextColor(random(0xffff));
uint8_t textSize = random(3);
switch (textSize)
{
case 1:
gfx->setFont(&FreeMono8pt7b);
break;
case 2:
gfx->setFont(&FreeSansBold10pt7b);
break;
default:
gfx->setFont(&FreeSerifBoldItalic12pt7b);
break;
}
gfx->println("Hello World!");
delay(1000); // 1 second
}

View File

@ -1,657 +0,0 @@
/*******************************************************************************
* GIFDEC Wrapper Class
*
* Rewrite from: https://github.com/BasementCat/arduino-tft-gif
******************************************************************************/
#ifndef _GIFCLASS_H_
#define _GIFCLASS_H_
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
#include <Seeed_FS.h>
#elif defined(ESP32) || defined(ESP8266)
#include <FS.h>
#else
#include <SD.h>
#endif
#include <sys/types.h>
#ifndef MIN
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#endif
#ifndef MAX
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#endif
#define GIF_BUF_SIZE 1024
typedef struct gd_Palette
{
int16_t len;
uint16_t colors[256];
} gd_Palette;
typedef struct gd_GCE
{
uint16_t delay;
uint8_t tindex;
uint8_t disposal;
uint8_t input;
uint8_t transparency;
} gd_GCE;
typedef struct gd_Entry
{
int32_t len;
uint16_t prefix;
uint8_t suffix;
} gd_Entry;
typedef struct gd_Table
{
int16_t bulk;
int16_t nentries;
gd_Entry *entries;
} gd_Table;
typedef struct gd_GIF
{
File *fd;
off_t anim_start;
uint16_t width, height;
uint16_t depth;
uint16_t loop_count;
gd_GCE gce;
gd_Palette *palette;
gd_Palette lct, gct;
void (*plain_text)(
struct gd_GIF *gif, uint16_t tx, uint16_t ty,
uint16_t tw, uint16_t th, uint8_t cw, uint8_t ch,
uint8_t fg, uint8_t bg);
void (*comment)(struct gd_GIF *gif);
void (*application)(struct gd_GIF *gif, char id[8], char auth[3]);
uint16_t fx, fy, fw, fh;
uint8_t bgindex;
gd_Table *table;
bool processed_first_frame;
} gd_GIF;
class GifClass
{
public:
gd_GIF *gd_open_gif(File *fd)
{
uint8_t sigver[3];
uint16_t width, height, depth;
uint8_t fdsz, bgidx, aspect;
int16_t gct_sz;
gd_GIF *gif;
// init global variables
gif_buf_last_idx = GIF_BUF_SIZE;
gif_buf_idx = gif_buf_last_idx; // no buffer yet
file_pos = 0;
/* Header */
gif_buf_read(fd, sigver, 3);
if (memcmp(sigver, "GIF", 3) != 0)
{
Serial.println(F("invalid signature"));
return NULL;
}
/* Version */
gif_buf_read(fd, sigver, 3);
if (memcmp(sigver, "89a", 3) != 0)
{
Serial.println(F("invalid version"));
return NULL;
}
/* Width x Height */
width = gif_buf_read16(fd);
height = gif_buf_read16(fd);
/* FDSZ */
gif_buf_read(fd, &fdsz, 1);
/* Presence of GCT */
if (!(fdsz & 0x80))
{
Serial.println(F("no global color table"));
return NULL;
}
/* Color Space's Depth */
depth = ((fdsz >> 4) & 7) + 1;
/* Ignore Sort Flag. */
/* GCT Size */
gct_sz = 1 << ((fdsz & 0x07) + 1);
/* Background Color Index */
gif_buf_read(fd, &bgidx, 1);
/* Aspect Ratio */
gif_buf_read(fd, &aspect, 1);
/* Create gd_GIF Structure. */
gif = (gd_GIF *)calloc(1, sizeof(*gif));
gif->fd = fd;
gif->width = width;
gif->height = height;
gif->depth = depth;
/* Read GCT */
read_palette(fd, &gif->gct, gct_sz);
gif->palette = &gif->gct;
gif->bgindex = bgidx;
gif->anim_start = file_pos; // fd->position();
gif->table = new_table();
gif->processed_first_frame = false;
return gif;
}
/* Return 1 if got a frame; 0 if got GIF trailer; -1 if error. */
int32_t gd_get_frame(gd_GIF *gif, uint8_t *frame)
{
char sep;
while (1)
{
gif_buf_read(gif->fd, (uint8_t *)&sep, 1);
if (sep == 0)
{
gif_buf_read(gif->fd, (uint8_t *)&sep, 1);
}
if (sep == ',')
{
break;
}
if (sep == ';')
{
return 0;
}
if (sep == '!')
{
read_ext(gif);
}
else
{
Serial.print(F("Read sep: ["));
Serial.print(sep);
Serial.println(F("].\n"));
return -1;
}
}
// Serial.println("Do read image");
if (read_image(gif, frame) == -1)
return -1;
return 1;
}
void gd_rewind(gd_GIF *gif)
{
#if defined(ESP32) || defined(ESP8266)
gif->fd->seek(gif->anim_start, SeekSet);
#else
gif->fd->seek(gif->anim_start);
#endif
file_pos = gif->anim_start;
gif_buf_idx = gif_buf_last_idx; // reset buffer
}
void gd_close_gif(gd_GIF *gif)
{
gif->fd->close();
free(gif->table);
free(gif);
}
private:
bool gif_buf_seek(File *fd, int16_t len)
{
if (len > (gif_buf_last_idx - gif_buf_idx))
{
#if defined(ESP32) || defined(ESP8266)
// fd->seek(len - (gif_buf_last_idx - gif_buf_idx), SeekCur);
fd->seek(file_pos + len - (gif_buf_last_idx - gif_buf_idx), SeekSet);
#else
fd->seek(file_pos + len - (gif_buf_last_idx - gif_buf_idx));
#endif
gif_buf_idx = gif_buf_last_idx;
}
else
{
gif_buf_idx += len;
}
file_pos += len;
return true;
}
int16_t gif_buf_read(File *fd, uint8_t *dest, int16_t len)
{
while (len--)
{
if (gif_buf_idx == gif_buf_last_idx)
{
gif_buf_last_idx = fd->read(gif_buf, GIF_BUF_SIZE);
gif_buf_idx = 0;
}
file_pos++;
*(dest++) = gif_buf[gif_buf_idx++];
}
return len;
}
uint8_t gif_buf_read(File *fd)
{
if (gif_buf_idx == gif_buf_last_idx)
{
gif_buf_last_idx = fd->read(gif_buf, GIF_BUF_SIZE);
gif_buf_idx = 0;
}
file_pos++;
return gif_buf[gif_buf_idx++];
}
uint16_t gif_buf_read16(File *fd)
{
return gif_buf_read(fd) + (((uint16_t)gif_buf_read(fd)) << 8);
}
void read_palette(File *fd, gd_Palette *dest, int16_t num_colors)
{
uint8_t r, g, b;
dest->len = num_colors;
for (int16_t i = 0; i < num_colors; i++)
{
r = gif_buf_read(fd);
g = gif_buf_read(fd);
b = gif_buf_read(fd);
dest->colors[i] = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
}
}
void discard_sub_blocks(gd_GIF *gif)
{
uint8_t len;
do
{
gif_buf_read(gif->fd, &len, 1);
gif_buf_seek(gif->fd, len);
} while (len);
}
void read_plain_text_ext(gd_GIF *gif)
{
if (gif->plain_text)
{
uint16_t tx, ty, tw, th;
uint8_t cw, ch, fg, bg;
gif_buf_seek(gif->fd, 1); /* block size = 12 */
tx = gif_buf_read16(gif->fd);
ty = gif_buf_read16(gif->fd);
tw = gif_buf_read16(gif->fd);
th = gif_buf_read16(gif->fd);
cw = gif_buf_read(gif->fd);
ch = gif_buf_read(gif->fd);
fg = gif_buf_read(gif->fd);
bg = gif_buf_read(gif->fd);
gif->plain_text(gif, tx, ty, tw, th, cw, ch, fg, bg);
}
else
{
/* Discard plain text metadata. */
gif_buf_seek(gif->fd, 13);
}
/* Discard plain text sub-blocks. */
discard_sub_blocks(gif);
}
void read_graphic_control_ext(gd_GIF *gif)
{
uint8_t rdit;
/* Discard block size (always 0x04). */
gif_buf_seek(gif->fd, 1);
gif_buf_read(gif->fd, &rdit, 1);
gif->gce.disposal = (rdit >> 2) & 3;
gif->gce.input = rdit & 2;
gif->gce.transparency = rdit & 1;
gif->gce.delay = gif_buf_read16(gif->fd);
gif_buf_read(gif->fd, &gif->gce.tindex, 1);
/* Skip block terminator. */
gif_buf_seek(gif->fd, 1);
}
void read_comment_ext(gd_GIF *gif)
{
if (gif->comment)
{
gif->comment(gif);
}
/* Discard comment sub-blocks. */
discard_sub_blocks(gif);
}
void read_application_ext(gd_GIF *gif)
{
char app_id[8];
char app_auth_code[3];
/* Discard block size (always 0x0B). */
gif_buf_seek(gif->fd, 1);
/* Application Identifier. */
gif_buf_read(gif->fd, (uint8_t *)app_id, 8);
/* Application Authentication Code. */
gif_buf_read(gif->fd, (uint8_t *)app_auth_code, 3);
if (!strncmp(app_id, "NETSCAPE", sizeof(app_id)))
{
/* Discard block size (0x03) and constant byte (0x01). */
gif_buf_seek(gif->fd, 2);
gif->loop_count = gif_buf_read16(gif->fd);
/* Skip block terminator. */
gif_buf_seek(gif->fd, 1);
}
else if (gif->application)
{
gif->application(gif, app_id, app_auth_code);
discard_sub_blocks(gif);
}
else
{
discard_sub_blocks(gif);
}
}
void read_ext(gd_GIF *gif)
{
uint8_t label;
gif_buf_read(gif->fd, &label, 1);
switch (label)
{
case 0x01:
read_plain_text_ext(gif);
break;
case 0xF9:
read_graphic_control_ext(gif);
break;
case 0xFE:
read_comment_ext(gif);
break;
case 0xFF:
read_application_ext(gif);
break;
default:
Serial.print("unknown extension: ");
Serial.println(label, HEX);
}
}
gd_Table *new_table()
{
// uint16_t key;
// int16_t init_bulk = MAX(1 << (key_size + 1), 0x100);
// Table *table = (Table*) malloc(sizeof(*table) + sizeof(Entry) * init_bulk);
// if (table) {
// table->bulk = init_bulk;
// table->nentries = (1 << key_size) + 2;
// table->entries = (Entry *) &table[1];
// for (key = 0; key < (1 << key_size); key++)
// table->entries[key] = (Entry) {1, 0xFFF, key};
// }
// return table;
int32_t s = sizeof(gd_Table) + (sizeof(gd_Entry) * 4096);
gd_Table *table = (gd_Table *)malloc(s);
if (table)
{
Serial.print(F("new_table() malloc: "));
Serial.println(s);
}
else
{
Serial.print(F("new_table() malloc failed: "));
Serial.println(s);
}
table->entries = (gd_Entry *)&table[1];
return table;
}
void reset_table(gd_Table *table, uint16_t key_size)
{
table->nentries = (1 << key_size) + 2;
for (uint16_t key = 0; key < (1 << key_size); key++)
{
table->entries[key] = (gd_Entry){1, 0xFFF, (uint8_t)key};
}
}
/* Add table entry. Return value:
* 0 on success
* +1 if key size must be incremented after this addition
* -1 if could not realloc table */
int32_t add_entry(gd_Table *table, int32_t len, uint16_t prefix, uint8_t suffix)
{
// Table *table = *tablep;
// if (table->nentries == table->bulk) {
// table->bulk *= 2;
// table = (Table*) realloc(table, sizeof(*table) + sizeof(Entry) * table->bulk);
// if (!table) return -1;
// table->entries = (Entry *) &table[1];
// *tablep = table;
// }
table->entries[table->nentries] = (gd_Entry){len, prefix, suffix};
table->nentries++;
if ((table->nentries & (table->nentries - 1)) == 0)
return 1;
return 0;
}
uint16_t get_key(gd_GIF *gif, uint16_t key_size, uint8_t *sub_len, uint8_t *shift, uint8_t *byte)
{
int16_t bits_read;
int16_t rpad;
int16_t frag_size;
uint16_t key;
key = 0;
for (bits_read = 0; bits_read < key_size; bits_read += frag_size)
{
rpad = (*shift + bits_read) % 8;
if (rpad == 0)
{
/* Update byte. */
if (*sub_len == 0)
gif_buf_read(gif->fd, sub_len, 1); /* Must be nonzero! */
gif_buf_read(gif->fd, byte, 1);
(*sub_len)--;
}
frag_size = MIN(key_size - bits_read, 8 - rpad);
key |= ((uint16_t)((*byte) >> rpad)) << bits_read;
}
/* Clear extra bits to the left. */
key &= (1 << key_size) - 1;
*shift = (*shift + key_size) % 8;
return key;
}
/* Compute output index of y-th input line, in frame of height h. */
int16_t interlaced_line_index(int16_t h, int16_t y)
{
int16_t p; /* number of lines in current pass */
p = (h - 1) / 8 + 1;
if (y < p) /* pass 1 */
return y * 8;
y -= p;
p = (h - 5) / 8 + 1;
if (y < p) /* pass 2 */
return y * 8 + 4;
y -= p;
p = (h - 3) / 4 + 1;
if (y < p) /* pass 3 */
return y * 4 + 2;
y -= p;
/* pass 4 */
return y * 2 + 1;
}
/* Decompress image pixels.
* Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table). */
int8_t read_image_data(gd_GIF *gif, int16_t interlace, uint8_t *frame)
{
uint8_t sub_len, shift, byte, table_is_full = 0;
uint16_t init_key_size, key_size;
int32_t frm_off, str_len = 0, p, x, y;
uint16_t key, clear, stop;
int32_t ret;
gd_Entry entry = {0, 0, 0};
// Serial.println("Read key size");
gif_buf_read(gif->fd, &byte, 1);
key_size = (uint16_t)byte;
// Serial.println("Set pos, discard sub blocks");
// start = gif->fd->position();
// discard_sub_blocks(gif);
// end = gif->fd->position();
// gif_buf_seek(gif->fd, start, SeekSet);
clear = 1 << key_size;
stop = clear + 1;
// Serial.println("New LZW table");
// table = new_table(key_size);
reset_table(gif->table, key_size);
key_size++;
init_key_size = key_size;
sub_len = shift = 0;
// Serial.println("Get init key");
key = get_key(gif, key_size, &sub_len, &shift, &byte); /* clear code */
frm_off = 0;
ret = 0;
while (1)
{
if (key == clear)
{
// Serial.println("Clear key, reset nentries");
key_size = init_key_size;
gif->table->nentries = (1 << (key_size - 1)) + 2;
table_is_full = 0;
}
else if (!table_is_full)
{
// Serial.println("Add entry to table");
ret = add_entry(gif->table, str_len + 1, key, entry.suffix);
// if (ret == -1) {
// // Serial.println("Table entry add failure");
// free(table);
// return -1;
// }
if (gif->table->nentries == 0x1000)
{
// Serial.println("Table is full");
ret = 0;
table_is_full = 1;
}
}
// Serial.println("Get key");
key = get_key(gif, key_size, &sub_len, &shift, &byte);
if (key == clear)
continue;
if (key == stop)
break;
if (ret == 1)
key_size++;
entry = gif->table->entries[key];
str_len = entry.len;
uint8_t tindex = gif->gce.tindex;
// Serial.println("Interpret key");
while (1)
{
p = frm_off + entry.len - 1;
x = p % gif->fw;
y = p / gif->fw;
if (interlace)
{
y = interlaced_line_index((int16_t)gif->fh, y);
}
if ((!gif->processed_first_frame) || (tindex != entry.suffix))
{
frame[(gif->fy + y) * gif->width + gif->fx + x] = entry.suffix;
}
if (entry.prefix == 0xFFF)
break;
else
entry = gif->table->entries[entry.prefix];
}
frm_off += str_len;
if (key < gif->table->nentries - 1 && !table_is_full)
gif->table->entries[gif->table->nentries - 1].suffix = entry.suffix;
}
// Serial.println("Done w/ img data, free table and seek to end");
// free(table);
gif_buf_read(gif->fd, &sub_len, 1); /* Must be zero! */
// gif_buf_seek(gif->fd, end, SeekSet);
gif->processed_first_frame = true;
return 0;
}
/* Read image.
* Return 0 on success or -1 on out-of-memory (w.r.t. LZW code table). */
int8_t read_image(gd_GIF *gif, uint8_t *frame)
{
uint8_t fisrz;
int16_t interlace;
/* Image Descriptor. */
// Serial.println("Read image descriptor");
gif->fx = gif_buf_read16(gif->fd);
gif->fy = gif_buf_read16(gif->fd);
gif->fw = gif_buf_read16(gif->fd);
gif->fh = gif_buf_read16(gif->fd);
// Serial.println("Read fisrz?");
gif_buf_read(gif->fd, &fisrz, 1);
interlace = fisrz & 0x40;
/* Ignore Sort Flag. */
/* Local Color Table? */
if (fisrz & 0x80)
{
/* Read LCT */
// Serial.println("Read LCT");
read_palette(gif->fd, &gif->lct, 1 << ((fisrz & 0x07) + 1));
gif->palette = &gif->lct;
}
else
{
gif->palette = &gif->gct;
}
/* Image Data. */
// Serial.println("Read image data");
return read_image_data(gif, interlace, frame);
}
void render_frame_rect(gd_GIF *gif, uint16_t *buffer, uint8_t *frame)
{
int16_t i, j, k;
uint8_t index;
i = gif->fy * gif->width + gif->fx;
for (j = 0; j < gif->fh; j++)
{
for (k = 0; k < gif->fw; k++)
{
index = frame[(gif->fy + j) * gif->width + gif->fx + k];
// color = &gif->palette->colors[index*2];
if ((!gif->gce.transparency) || (index != gif->gce.tindex))
{
buffer[(i + k)] = gif->palette->colors[index];
}
// memcpy(&buffer[(i+k)*2], color, 2);
}
i += gif->width;
}
}
int16_t gif_buf_last_idx, gif_buf_idx, file_pos;
uint8_t gif_buf[GIF_BUF_SIZE];
};
#endif /* _GIFCLASS_H_ */

View File

@ -1,244 +0,0 @@
/*******************************************************************************
* Animated GIF Image Viewer
* This is a simple Animated GIF image viewer example
* Image Source: https://www.pexels.com/video/earth-rotating-video-856356/
* cropped: x: 598 y: 178 width: 720 height: 720 resized: 240x240
* optimized with ezgif.com
*
* GIFDEC original source: https://github.com/BasementCat/arduino-tft-gif
*
* Setup steps:
* 1. Change your LCD parameters in Arduino_GFX setting
* 2. Upload Animated GIF file
* FFat (ESP32):
* upload FFat (FatFS) data with ESP32 Sketch Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* LittleFS (ESP32 / ESP8266 / Pico):
* upload LittleFS data with ESP8266 LittleFS Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* ESP8266: https://github.com/earlephilhower/arduino-esp8266littlefs-plugin
* Pico: https://github.com/earlephilhower/arduino-pico-littlefs-plugin.git
* SPIFFS (ESP32):
* upload SPIFFS data with ESP32 Sketch Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* SD:
* Most Arduino system built-in support SD file system.
* Wio Terminal require extra dependant Libraries:
* - Seeed_Arduino_FS: https://github.com/Seeed-Studio/Seeed_Arduino_FS.git
* - Seeed_Arduino_SFUD: https://github.com/Seeed-Studio/Seeed_Arduino_SFUD.git
******************************************************************************/
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
#define GIF_FILENAME "/ezgif.com-optimize.gif"
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
#define GIF_FILENAME "/ezgif.com-optimize.gif"
#elif defined(ESP32)
#define GIF_FILENAME "/ezgif.com-optimize.gif"
#else
#define GIF_FILENAME "/ezgif.com-resize.gif"
#endif
/*******************************************************************************
* Start of Arduino_GFX setting
*
* Arduino_GFX try to find the settings depends on selected board in Arduino IDE
* Or you can define the display dev kit not in the board list
* Defalult pin list for non display dev kit:
* Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12
* ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
* ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil
* ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
* ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
* ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12
* Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16
* RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20
* RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11
* RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12
* RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10
* Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9
* Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
#include <Seeed_FS.h>
#include <SD/Seeed_SD.h>
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
#include <LittleFS.h>
#include <SD.h>
#elif defined(ESP32)
#include <FFat.h>
#include <LittleFS.h>
#include <SPIFFS.h>
#include <SD.h>
#include <SD_MMC.h>
#elif defined(ESP8266)
#include <LittleFS.h>
#include <SD.h>
#else
#include <SD.h>
#endif
#include "GifClass.h"
static GifClass gifClass;
void setup()
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX Animated GIF Image Viewer example");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
if (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
if (!LittleFS.begin())
// if (!SD.begin(SS))
#elif defined(ESP32)
// if (!FFat.begin())
if (!LittleFS.begin())
// if (!SPIFFS.begin())
// SPI.begin(12 /* CLK */, 13 /* D0/MISO */, 11 /* CMD/MOSI */);
// if (!SD.begin(10 /* CS */, SPI))
// pinMode(10 /* CS */, OUTPUT);
// digitalWrite(SD_CS, HIGH);
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */);
// if (!SD_MMC.begin("/root", true /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_DEFAULT))
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */, 14 /* D1 */, 15 /* D2 */, 10 /* D3/CS */);
// if (!SD_MMC.begin("/root", false /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_HIGHSPEED))
#elif defined(ESP8266)
if (!LittleFS.begin())
// if (!SD.begin(SS))
#else
if (!SD.begin())
#endif
{
Serial.println(F("ERROR: File System Mount Failed!"));
gfx->println(F("ERROR: File System Mount Failed!"));
}
}
void loop()
{
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
File gifFile = SD.open(GIF_FILENAME, "r");
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
File gifFile = LittleFS.open(GIF_FILENAME, "r");
// File gifFile = SD.open(GIF_FILENAME, "r");
#elif defined(ESP32)
// File gifFile = FFat.open(GIF_FILENAME, "r");
File gifFile = LittleFS.open(GIF_FILENAME, "r");
// File gifFile = SPIFFS.open(GIF_FILENAME, "r");
// File gifFile = SD.open(GIF_FILENAME, "r");
#elif defined(ESP8266)
File gifFile = LittleFS.open(GIF_FILENAME, "r");
// File gifFile = SD.open(GIF_FILENAME, "r");
#else
File gifFile = SD.open(GIF_FILENAME, FILE_READ);
#endif
if (!gifFile || gifFile.isDirectory())
{
Serial.println(F("ERROR: open gifFile Failed!"));
gfx->println(F("ERROR: open gifFile Failed!"));
}
else
{
// read GIF file header
gd_GIF *gif = gifClass.gd_open_gif(&gifFile);
if (!gif)
{
Serial.println(F("gd_open_gif() failed!"));
}
else
{
uint8_t *buf = (uint8_t *)malloc(gif->width * gif->height);
if (!buf)
{
Serial.println(F("buf malloc failed!"));
}
else
{
int16_t x = (gfx->width() - gif->width) / 2;
int16_t y = (gfx->height() - gif->height) / 2;
Serial.println(F("GIF video start"));
int32_t start_ms = millis(), t_delay = 0, delay_until;
int32_t res = 1;
int32_t duration = 0, remain = 0;
while (res > 0)
{
t_delay = gif->gce.delay * 10;
res = gifClass.gd_get_frame(gif, buf);
if (res < 0)
{
Serial.println(F("ERROR: gd_get_frame() failed!"));
break;
}
else if (res > 0)
{
gfx->drawIndexedBitmap(x, y, buf, gif->palette->colors, gif->width, gif->height);
duration += t_delay;
delay_until = start_ms + duration;
while (millis() < delay_until)
{
delay(1);
remain++;
}
}
}
Serial.println(F("GIF video end"));
Serial.print(F("Actual duration: "));
Serial.print(millis() - start_ms);
Serial.print(F(", expected duration: "));
Serial.print(duration);
Serial.print(F(", remain: "));
Serial.print(remain);
Serial.print(F(" ("));
Serial.print(100.0 * remain / duration);
Serial.println(F("%)"));
gifClass.gd_close_gif(gif);
free(buf);
}
}
}
}

View File

@ -1,355 +0,0 @@
/*******************************************************************************
* Animated GIF Image Viewer
* This is a simple Animated GIF image viewer example
* Image Source: https://www.pexels.com/video/earth-rotating-video-856356/
* cropped: x: 598 y: 178 width: 720 height: 720 resized: 240x240
* optimized with ezgif.com
*
* Dependent libraries:
* AnimatedGIF: https://github.com/bitbank2/AnimatedGIF.git
*
* Setup steps:
* 1. Change your LCD parameters in Arduino_GFX setting
* 2. Upload Animated GIF file
* FFat (ESP32):
* upload FFat (FatFS) data with ESP32 Sketch Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* LittleFS (ESP32 / ESP8266 / Pico):
* upload LittleFS data with ESP8266 LittleFS Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* ESP8266: https://github.com/earlephilhower/arduino-esp8266littlefs-plugin
* Pico: https://github.com/earlephilhower/arduino-pico-littlefs-plugin.git
* SPIFFS (ESP32):
* upload SPIFFS data with ESP32 Sketch Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* SD:
* Most Arduino system built-in support SD file system.
* Wio Terminal require extra dependant Libraries:
* - Seeed_Arduino_FS: https://github.com/Seeed-Studio/Seeed_Arduino_FS.git
* - Seeed_Arduino_SFUD: https://github.com/Seeed-Studio/Seeed_Arduino_SFUD.git
******************************************************************************/
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
#define GIF_FILENAME "/ezgif.com-optimize.gif"
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
#define GIF_FILENAME "/ezgif.com-optimize.gif"
#elif defined(ESP32)
#define GIF_FILENAME "/ezgif.com-optimize.gif"
#else
#define GIF_FILENAME "/ezgif.com-resize.gif"
#endif
/*******************************************************************************
* Start of Arduino_GFX setting
*
* Arduino_GFX try to find the settings depends on selected board in Arduino IDE
* Or you can define the display dev kit not in the board list
* Defalult pin list for non display dev kit:
* Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12
* ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
* ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil
* ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
* ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
* ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12
* Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16
* RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20
* RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11
* RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12
* RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10
* Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9
* Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
#include <Seeed_FS.h>
#include <SD/Seeed_SD.h>
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
#include <LittleFS.h>
#include <SD.h>
#elif defined(ESP32)
#include <FFat.h>
#include <LittleFS.h>
#include <SPIFFS.h>
#include <SD.h>
#include <SD_MMC.h>
#elif defined(ESP8266)
#include <LittleFS.h>
#include <SD.h>
#else
#include <SD.h>
#endif
#include <AnimatedGIF.h>
AnimatedGIF gif;
File f;
int16_t display_width, display_height;
void *GIFOpenFile(const char *fname, int32_t *pSize)
{
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
f = SD.open(fname, "r");
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
f = LittleFS.open(fname, "r");
// f = SD.open(fname, "r");
#elif defined(ESP32)
// f = FFat.open(fname, "r");
f = LittleFS.open(fname, "r");
// f = SPIFFS.open(fname, "r");
// f = SD.open(fname, "r");
#elif defined(ESP8266)
f = LittleFS.open(fname, "r");
// f = SD.open(fname, "r");
#else
f = SD.open(fname, FILE_READ);
#endif
if (f)
{
*pSize = f.size();
return (void *)&f;
}
return NULL;
} /* GIFOpenFile() */
void GIFCloseFile(void *pHandle)
{
File *f = static_cast<File *>(pHandle);
if (f != NULL)
{
f->close();
}
} /* GIFCloseFile() */
int32_t GIFReadFile(GIFFILE *pFile, uint8_t *pBuf, int32_t iLen)
{
int32_t iBytesRead;
iBytesRead = iLen;
File *f = static_cast<File *>(pFile->fHandle);
// Note: If you read a file all the way to the last byte, seek() stops working
if ((pFile->iSize - pFile->iPos) < iLen)
{
iBytesRead = pFile->iSize - pFile->iPos - 1; // <-- ugly work-around
}
if (iBytesRead <= 0)
{
return 0;
}
iBytesRead = (int32_t)f->read(pBuf, iBytesRead);
pFile->iPos = f->position();
return iBytesRead;
} /* GIFReadFile() */
int32_t GIFSeekFile(GIFFILE *pFile, int32_t iPosition)
{
int i = micros();
File *f = static_cast<File *>(pFile->fHandle);
f->seek(iPosition);
pFile->iPos = (int32_t)f->position();
i = micros() - i;
// Serial.printf("Seek time = %d us\n", i);
return pFile->iPos;
} /* GIFSeekFile() */
// Draw a line of image directly on the LCD
void GIFDraw(GIFDRAW *pDraw)
{
uint8_t *s;
uint16_t *d, *usPalette, usTemp[320];
int x, y, iWidth;
iWidth = pDraw->iWidth;
if (iWidth + pDraw->iX > display_width)
{
iWidth = display_width - pDraw->iX;
}
usPalette = pDraw->pPalette;
y = pDraw->iY + pDraw->y; // current line
if (y >= display_height || pDraw->iX >= display_width || iWidth < 1)
{
return;
}
s = pDraw->pPixels;
if (pDraw->ucDisposalMethod == 2) // restore to background color
{
for (x = 0; x < iWidth; x++)
{
if (s[x] == pDraw->ucTransparent)
{
s[x] = pDraw->ucBackground;
}
}
pDraw->ucHasTransparency = 0;
}
// Apply the new pixels to the main image
if (pDraw->ucHasTransparency) // if transparency used
{
uint8_t *pEnd, c, ucTransparent = pDraw->ucTransparent;
int x, iCount;
pEnd = s + iWidth;
x = 0;
iCount = 0; // count non-transparent pixels
while (x < iWidth)
{
c = ucTransparent - 1;
d = usTemp;
while (c != ucTransparent && s < pEnd)
{
c = *s++;
if (c == ucTransparent) // done, stop
{
s--; // back up to treat it like transparent
}
else // opaque
{
*d++ = usPalette[c];
iCount++;
}
} // while looking for opaque pixels
if (iCount) // any opaque pixels?
{
gfx->draw16bitBeRGBBitmap(pDraw->iX + x, y, usTemp, iCount, 1);
x += iCount;
iCount = 0;
}
// no, look for a run of transparent pixels
c = ucTransparent;
while (c == ucTransparent && s < pEnd)
{
c = *s++;
if (c == ucTransparent)
{
iCount++;
}
else
{
s--;
}
}
if (iCount)
{
x += iCount; // skip these
iCount = 0;
}
}
}
else
{
s = pDraw->pPixels;
// Translate the 8-bit pixels through the RGB565 palette (already byte reversed)
for (x = 0; x < iWidth; x++)
{
usTemp[x] = usPalette[*s++];
}
gfx->draw16bitBeRGBBitmap(pDraw->iX, y, usTemp, iWidth, 1);
}
} /* GIFDraw() */
void setup()
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX Animated GIF Image Viewer example");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
display_width = gfx->width();
display_height = gfx->height();
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
if (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
if (!LittleFS.begin())
// if (!SD.begin(SS))
#elif defined(ESP32)
// if (!FFat.begin())
if (!LittleFS.begin())
// if (!SPIFFS.begin())
// SPI.begin(12 /* CLK */, 13 /* D0/MISO */, 11 /* CMD/MOSI */);
// if (!SD.begin(10 /* CS */, SPI))
// pinMode(10 /* CS */, OUTPUT);
// digitalWrite(SD_CS, HIGH);
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */);
// if (!SD_MMC.begin("/root", true /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_DEFAULT))
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */, 14 /* D1 */, 15 /* D2 */, 10 /* D3/CS */);
// if (!SD_MMC.begin("/root", false /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_HIGHSPEED))
#elif defined(ESP8266)
if (!LittleFS.begin())
// if (!SD.begin(SS))
#else
if (!SD.begin())
#endif
{
Serial.println(F("ERROR: File System Mount Failed!"));
gfx->println(F("ERROR: File System Mount Failed!"));
}
gif.begin(BIG_ENDIAN_PIXELS);
}
void loop()
{
if (gif.open(GIF_FILENAME, GIFOpenFile, GIFCloseFile, GIFReadFile, GIFSeekFile, GIFDraw))
{
Serial.printf("Successfully opened GIF; Canvas size = %d x %d\n", gif.getCanvasWidth(), gif.getCanvasHeight());
GIFINFO gi;
if (gif.getInfo(&gi))
{
Serial.printf("frame count: %d\n", gi.iFrameCount);
Serial.printf("duration: %d ms\n", gi.iDuration);
Serial.printf("max delay: %d ms\n", gi.iMaxDelay);
Serial.printf("min delay: %d ms\n", gi.iMinDelay);
}
unsigned long start_ms = millis();
int iFrames = 0;
while (gif.playFrame(true, NULL))
{
iFrames++;
};
Serial.printf("total decode time for %d frames = %lu ms\n", iFrames, millis() - start_ms);
gif.close();
}
else
{
Serial.printf("Error opening file = %d\n", gif.getLastError());
while (1)
{
};
}
}

View File

@ -1,259 +0,0 @@
/*******************************************************************************
* BMP Class
*
* Rewrite from: https://github.com/Jaycar-Electronics/Arduino-Picture-Frame.git
******************************************************************************/
#ifndef _BMPCLASS_H_
#define _BMPCLASS_H_
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
#include <Seeed_FS.h>
#elif defined(ESP32) || defined(ESP8266)
#include <FS.h>
#else
#include <SD.h>
#endif
typedef void(BMP_DRAW_CALLBACK)(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h);
class BmpClass
{
public:
void draw(
File *f, BMP_DRAW_CALLBACK *bmpDrawCallback, bool useBigEndian,
int16_t x, int16_t y, int16_t widthLimit, int16_t heightLimit)
{
_bmpDrawCallback = bmpDrawCallback;
_useBigEndian = useBigEndian;
_heightLimit = heightLimit;
int16_t u, v;
uint32_t xend;
getbmpparms(f);
//validate bitmap
if ((bmtype == 19778) && (bmwidth > 0) && (bmheight > 0) && (bmbpp > 0))
{
//centre image
u = (widthLimit - bmwidth) / 2;
v = (heightLimit - bmheight) / 2;
u = (u < 0) ? x : x + u;
v = (v < 0) ? y : y + v;
xend = (bmwidth > widthLimit) ? widthLimit : bmwidth;
bmpRow = (uint16_t *)malloc(xend * 2);
if (!bmpRow)
{
Serial.println(F("bmpRow malloc failed."));
}
if (bmbpp < 9)
{
bmplt = (uint16_t *)malloc(bmpltsize * 2);
if (!bmplt)
{
Serial.println(F("bmplt malloc failed."));
}
bmloadplt(f); //load palette if palettized
drawbmpal(f, u, v, xend);
free(bmplt);
}
else if (bmbpp == 16)
{
// TODO: bpp 16 should have 3 pixel types
drawbmRgb565(f, u, v, xend);
}
else
{
drawbmtrue(f, u, v, xend);
}
free(bmpRow);
}
}
private:
void bmloadplt(File *f)
{
byte r, g, b;
if (bmpltsize == 0)
{
bmpltsize = 1 << bmbpp; //load default palette size
}
f->seek(54); //palette position in type 0x28 bitmaps
for (int16_t i = 0; i < bmpltsize; i++)
{
b = f->read();
g = f->read();
r = f->read();
f->read(); //dummy byte
bmplt[i] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
}
}
void drawbmpal(File *f, int16_t u, int16_t v, uint32_t xend)
{
byte bmbitmask;
int16_t i, ystart, bmppb, p, d;
int16_t x, y;
uint16_t c;
bmbpl = ((bmbpp * bmwidth + 31) / 32) * 4; //bytes per line
bmppb = 8 / bmbpp; //pixels/byte
bmbitmask = ((1 << bmbpp) - 1); //mask for each pixel
ystart = 0;
if (bmheight > _heightLimit)
{
ystart = bmheight - _heightLimit; //don't draw if it's outside screen
}
for (y = ystart; y < bmheight; y++)
{ //invert in calculation (y=0 is bottom)
f->seek(bmdataptr + y * bmbpl); //seek to start of line
x = 0;
p = 0;
while (x < xend)
{
if (p < 1)
{
d = f->read();
p = bmppb;
}
d = d << bmbpp;
c = bmplt[(bmbitmask & (d >> 8))];
bmpRow[x] = (_useBigEndian) ? ((c >> 8) | (c << 8)) : c;
p--;
x++;
}
_bmpDrawCallback(u, v + bmheight - 1 - y, bmpRow, xend, 1);
}
}
// draw 16-bit colour (RGB565) bitmap
void drawbmRgb565(File *f, int16_t u, int16_t v, uint32_t xend)
{
int16_t i, ystart;
uint32_t x, y;
byte lo, hi;
bmbpl = ((bmbpp * bmwidth + 31) / 32) * 4; //bytes per line, due to 32bit chunks
ystart = 0;
if (bmheight > _heightLimit)
{
ystart = bmheight - _heightLimit; //don't draw if it's outside screen
}
Serial.println(xend);
for (y = ystart; y < bmheight; y++)
{ //invert in calculation (y=0 is bottom)
f->seek(bmdataptr + (y * bmbpl)); //seek at start of line
for (x = 0; x < xend; x++)
{
lo = f->read();
hi = f->read();
if (_useBigEndian)
{
bmpRow[x] = hi | lo << 8;
}
else
{
bmpRow[x] = lo | hi << 8;
}
}
_bmpDrawCallback(u, v + bmheight - 1 - y, bmpRow, xend, 1);
}
}
// draw true colour bitmap at (u,v) handles 24/32 not 16bpp yet
void drawbmtrue(File *f, int16_t u, int16_t v, uint32_t xend)
{
int16_t i, ystart;
uint32_t x, y;
byte r, g, b;
bmbpl = ((bmbpp * bmwidth + 31) / 32) * 4; //bytes per line, due to 32bit chunks
ystart = 0;
if (bmheight > _heightLimit)
{
ystart = bmheight - _heightLimit; //don't draw if it's outside screen
}
for (y = ystart; y < bmheight; y++)
{ //invert in calculation (y=0 is bottom)
f->seek(bmdataptr + y * bmbpl); //seek at start of line
for (x = 0; x < xend; x++)
{
b = f->read();
g = f->read();
r = f->read();
if (bmbpp == 32)
{
f->read(); //dummy byte for 32bit
}
bmpRow[x] = (_useBigEndian) ? ((r & 0xf8) | (g >> 5) | ((g & 0x1c) << 11) | ((b & 0xf8) << 5)) : (((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3));
}
_bmpDrawCallback(u, v + bmheight - 1 - y, bmpRow, xend, 1);
}
}
void getbmpparms(File *f)
{ //load into globals as ints-some parameters are 32 bit, but we can't handle this size anyway
byte h[48]; //header is 54 bytes typically, but we don't need it all
int16_t i;
f->seek(0); //set start of file
for (i = 0; i < 48; i++)
{
h[i] = f->read(); //read header
}
bmtype = h[0] + (h[1] << 8); //offset 0 'BM'
bmdataptr = h[10] + (h[11] << 8); //offset 0xA pointer to image data
bmhdrsize = h[14] + (h[15] << 8); //dib header size (0x28 is usual)
//files may vary here, if !=28, unsupported type, put default values
bmwidth = 0;
bmheight = 0;
bmbpp = 0;
bmpltsize = 0;
if ((bmhdrsize == 0x28) || (bmhdrsize == 0x38))
{
bmwidth = h[18] + (h[19] << 8); //width
bmheight = h[22] + (h[23] << 8); //height
bmbpp = h[28] + (h[29] << 8); //bits per pixel
bmpltsize = h[46] + (h[47] << 8); //palette size
}
// Serial.printf("bmtype: %d, bmhdrsize: %d, bmwidth: %d, bmheight: %d, bmbpp: %d\n", bmtype, bmhdrsize, bmwidth, bmheight, bmbpp);
}
byte isbmp(char n[])
{ //check if bmp extension
int16_t k;
k = strlen(n);
if (k < 5)
{
return 0; //name not long enough
}
if (n[k - 1] != 'P')
{
return 0;
}
if (n[k - 2] != 'M')
{
return 0;
}
if (n[k - 3] != 'B')
{
return 0;
}
if (n[k - 4] != '.')
{
return 0;
}
return 1; //passes all tests
}
BMP_DRAW_CALLBACK *_bmpDrawCallback;
bool _useBigEndian;
int16_t _heightLimit;
uint16_t bmtype, bmdataptr; //from header
uint32_t bmhdrsize, bmwidth, bmheight, bmbpp, bmpltsize; //from DIB Header
uint16_t bmbpl; //bytes per line- derived
uint16_t *bmplt; //palette- stored encoded for LCD
uint16_t *bmpRow;
};
#endif // _BMPCLASS_H_

View File

@ -1,189 +0,0 @@
/*******************************************************************************
* BMP Image Viewer
* This is a simple BMP image viewer example
* Image Source: https://github.blog/2014-11-24-from-sticker-to-sculpture-the-making-of-the-octocat-figurine/
*
* BMP Class original source: https://github.com/Jaycar-Electronics/Arduino-Picture-Frame.git
*
* Setup steps:
* 1. Change your LCD parameters in Arduino_GFX setting
* 2. Upload BMP file
* FFat (ESP32):
* upload FFat (FatFS) data with ESP32 Sketch Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* LittleFS (ESP32 / ESP8266 / Pico):
* upload LittleFS data with ESP8266 LittleFS Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* ESP8266: https://github.com/earlephilhower/arduino-esp8266littlefs-plugin
* Pico: https://github.com/earlephilhower/arduino-pico-littlefs-plugin.git
* SPIFFS (ESP32):
* upload SPIFFS data with ESP32 Sketch Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* SD:
* Most Arduino system built-in support SD file system.
* Wio Terminal require extra dependant Libraries:
* - Seeed_Arduino_FS: https://github.com/Seeed-Studio/Seeed_Arduino_FS.git
* - Seeed_Arduino_SFUD: https://github.com/Seeed-Studio/Seeed_Arduino_SFUD.git
******************************************************************************/
// #define BMP_FILENAME "/octocatS.bmp" // 243x128@IndexedColor
#define BMP_FILENAME "/octocatM.bmp" // 456x240@16bit
// #define BMP_FILENAME "/octocatL.bmp" // 608x320@24bit
/*******************************************************************************
* Start of Arduino_GFX setting
*
* Arduino_GFX try to find the settings depends on selected board in Arduino IDE
* Or you can define the display dev kit not in the board list
* Defalult pin list for non display dev kit:
* Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12
* ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
* ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil
* ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
* ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
* ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12
* Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16
* RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20
* RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11
* RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12
* RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10
* Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9
* Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
#include <Seeed_FS.h>
#include <SD/Seeed_SD.h>
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
#include <LittleFS.h>
#include <SD.h>
#elif defined(ESP32)
#include <FFat.h>
#include <LittleFS.h>
#include <SPIFFS.h>
#include <SD.h>
#include <SD_MMC.h>
#elif defined(ESP8266)
#include <LittleFS.h>
#include <SD.h>
#else
#include <SD.h>
#endif
#include "BmpClass.h"
static BmpClass bmpClass;
// pixel drawing callback
static void bmpDrawCallback(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h)
{
// Serial.printf("Draw pos = %d, %d. size = %d x %d\n", x, y, w, h);
gfx->draw16bitRGBBitmap(x, y, bitmap, w, h);
}
void setup()
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX BMP Image Viewer example");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
if (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
if (!LittleFS.begin())
// if (!SD.begin(SS))
#elif defined(ESP32)
// if (!FFat.begin())
if (!LittleFS.begin())
// if (!SPIFFS.begin())
// SPI.begin(12 /* CLK */, 13 /* D0/MISO */, 11 /* CMD/MOSI */);
// if (!SD.begin(10 /* CS */, SPI))
// pinMode(10 /* CS */, OUTPUT);
// digitalWrite(SD_CS, HIGH);
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */);
// if (!SD_MMC.begin("/root", true /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_DEFAULT))
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */, 14 /* D1 */, 15 /* D2 */, 10 /* D3/CS */);
// if (!SD_MMC.begin("/root", false /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_HIGHSPEED))
#elif defined(ESP8266)
if (!LittleFS.begin())
// if (!SD.begin(SS))
#else
if (!SD.begin())
#endif
{
Serial.println(F("ERROR: File System Mount Failed!"));
gfx->println(F("ERROR: File System Mount Failed!"));
}
else
{
unsigned long start = millis();
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
File bmpFile = SD.open(BMP_FILENAME, "r");
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
File bmpFile = LittleFS.open(BMP_FILENAME, "r");
// File bmpFile = SD.open(BMP_FILENAME, "r");
#elif defined(ESP32)
// File bmpFile = FFat.open(BMP_FILENAME, "r");
File bmpFile = LittleFS.open(BMP_FILENAME, "r");
// File bmpFile = SPIFFS.open(BMP_FILENAME, "r");
// File bmpFile = SD.open(BMP_FILENAME, "r");
#elif defined(ESP8266)
File bmpFile = LittleFS.open(BMP_FILENAME, "r");
// File bmpFile = SD.open(BMP_FILENAME, "r");
#else
File bmpFile = SD.open(BMP_FILENAME, FILE_READ);
#endif
// read BMP file header
bmpClass.draw(
&bmpFile, bmpDrawCallback, false /* useBigEndian */,
0 /* x */, 0 /* y */, gfx->width() /* widthLimit */, gfx->height() /* heightLimit */);
bmpFile.close();
Serial.print("Time used: ");
Serial.println(millis() - start);
}
}
void loop()
{
}

View File

@ -1,178 +0,0 @@
/*******************************************************************************
* JPEG Image Viewer
* This is a simple JPEG image viewer example
* Image Source: https://github.blog/2014-11-24-from-sticker-to-sculpture-the-making-of-the-octocat-figurine/
*
* Dependent libraries:
* JPEGDEC: https://github.com/bitbank2/JPEGDEC.git
*
* Setup steps:
* 1. Change your LCD parameters in Arduino_GFX setting
* 2. Upload JPEG file
* FFat (ESP32):
* upload FFat (FatFS) data with ESP32 Sketch Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* LittleFS (ESP32 / ESP8266 / Pico):
* upload LittleFS data with ESP8266 LittleFS Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* ESP8266: https://github.com/earlephilhower/arduino-esp8266littlefs-plugin
* Pico: https://github.com/earlephilhower/arduino-pico-littlefs-plugin.git
* SPIFFS (ESP32):
* upload SPIFFS data with ESP32 Sketch Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* SD:
* Most Arduino system built-in support SD file system.
* Wio Terminal require extra dependant Libraries:
* - Seeed_Arduino_FS: https://github.com/Seeed-Studio/Seeed_Arduino_FS.git
* - Seeed_Arduino_SFUD: https://github.com/Seeed-Studio/Seeed_Arduino_SFUD.git
******************************************************************************/
#define JPEG_FILENAME "/octocat.jpg"
/*******************************************************************************
* Start of Arduino_GFX setting
*
* Arduino_GFX try to find the settings depends on selected board in Arduino IDE
* Or you can define the display dev kit not in the board list
* Defalult pin list for non display dev kit:
* Arduino Nano, Micro and more: CS: 9, DC: 8, RST: 7, BL: 6, SCK: 13, MOSI: 11, MISO: 12
* ESP32 various dev board : CS: 5, DC: 27, RST: 33, BL: 22, SCK: 18, MOSI: 23, MISO: nil
* ESP32-C3 various dev board : CS: 7, DC: 2, RST: 1, BL: 3, SCK: 4, MOSI: 6, MISO: nil
* ESP32-S2 various dev board : CS: 34, DC: 38, RST: 33, BL: 21, SCK: 36, MOSI: 35, MISO: nil
* ESP32-S3 various dev board : CS: 40, DC: 41, RST: 42, BL: 48, SCK: 36, MOSI: 35, MISO: nil
* ESP8266 various dev board : CS: 15, DC: 4, RST: 2, BL: 5, SCK: 14, MOSI: 13, MISO: 12
* Raspberry Pi Pico dev board : CS: 17, DC: 27, RST: 26, BL: 28, SCK: 18, MOSI: 19, MISO: 16
* RTL8720 BW16 old patch core : CS: 18, DC: 17, RST: 2, BL: 23, SCK: 19, MOSI: 21, MISO: 20
* RTL8720_BW16 Official core : CS: 9, DC: 8, RST: 6, BL: 3, SCK: 10, MOSI: 12, MISO: 11
* RTL8722 dev board : CS: 18, DC: 17, RST: 22, BL: 23, SCK: 13, MOSI: 11, MISO: 12
* RTL8722_mini dev board : CS: 12, DC: 14, RST: 15, BL: 13, SCK: 11, MOSI: 9, MISO: 10
* Seeeduino XIAO dev board : CS: 3, DC: 2, RST: 1, BL: 0, SCK: 8, MOSI: 10, MISO: 9
* Teensy 4.1 dev board : CS: 39, DC: 41, RST: 40, BL: 22, SCK: 13, MOSI: 11, MISO: 12
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
#include <Seeed_FS.h>
#include <SD/Seeed_SD.h>
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
#include <LittleFS.h>
#include <SD.h>
#elif defined(ESP32)
#include <FFat.h>
#include <LittleFS.h>
#include <SPIFFS.h>
#include <SD.h>
#include <SD_MMC.h>
#elif defined(ESP8266)
#include <LittleFS.h>
#include <SD.h>
#else
#include <SD.h>
#endif
#include "JpegFunc.h"
// pixel drawing callback
static int jpegDrawCallback(JPEGDRAW *pDraw)
{
// Serial.printf("Draw pos = %d,%d. size = %d x %d\n", pDraw->x, pDraw->y, pDraw->iWidth, pDraw->iHeight);
gfx->draw16bitBeRGBBitmap(pDraw->x, pDraw->y, pDraw->pPixels, pDraw->iWidth, pDraw->iHeight);
return 1;
}
void setup()
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX JPEG Image Viewer example");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
/* Wio Terminal */
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
if (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI, 4000000UL))
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
if (!LittleFS.begin())
// if (!SD.begin(SS))
#elif defined(ESP32)
// if (!FFat.begin())
if (!LittleFS.begin())
// if (!SPIFFS.begin())
// SPI.begin(12 /* CLK */, 13 /* D0/MISO */, 11 /* CMD/MOSI */);
// if (!SD.begin(10 /* CS */, SPI))
// pinMode(10 /* CS */, OUTPUT);
// digitalWrite(10 /* CS */, HIGH);
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */);
// if (!SD_MMC.begin("/root", true /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_DEFAULT))
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */, 14 /* D1 */, 15 /* D2 */, 10 /* D3/CS */);
// if (!SD_MMC.begin("/root", false /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_HIGHSPEED))
#elif defined(ESP8266)
if (!LittleFS.begin())
// if (!SD.begin(SS))
#else
if (!SD.begin())
#endif
{
Serial.println(F("ERROR: File System Mount Failed!"));
gfx->println(F("ERROR: File System Mount Failed!"));
}
else
{
unsigned long start = millis();
jpegDraw(JPEG_FILENAME, jpegDrawCallback, true /* useBigEndian */,
0 /* x */, 0 /* y */, gfx->width() /* widthLimit */, gfx->height() /* heightLimit */);
Serial.printf("Time used: %lu\n", millis() - start);
}
delay(5000);
}
void loop()
{
int w = gfx->width();
int h = gfx->height();
unsigned long start = millis();
jpegDraw(JPEG_FILENAME, jpegDrawCallback, true /* useBigEndian */,
random(w * 2) - w /* x */,
random(h * 2) - h /* y */,
w /* widthLimit */, h /* heightLimit */);
Serial.printf("Time used: %lu\n", millis() - start);
delay(1000);
}

View File

@ -1,107 +0,0 @@
/*******************************************************************************
* JPEGDEC related function
*
* Dependent libraries:
* JPEGDEC: https://github.com/bitbank2/JPEGDEC.git
******************************************************************************/
#ifndef _JPEGFUNC_H_
#define _JPEGFUNC_H_
#include <JPEGDEC.h>
static JPEGDEC _jpeg;
static File _f;
static int _x, _y, _x_bound, _y_bound;
static void *jpegOpenFile(const char *szFilename, int32_t *pFileSize)
{
// Serial.println("jpegOpenFile");
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
_f = SD.open(szFilename, "r");
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
_f = LittleFS.open(szFilename, "r");
// _f = SDFS.open(szFilename, "r");
#elif defined(ESP32)
// _f = FFat.open(szFilename, "r");
_f = LittleFS.open(szFilename, "r");
// _f = SPIFFS.open(szFilename, "r");
// _f = SD.open(szFilename, "r");
// _f = SD_MMC.open(szFilename, "r");
#elif defined(ESP8266)
_f = LittleFS.open(szFilename, "r");
// _f = SD.open(szFilename, "r");
#else
_f = SD.open(szFilename, FILE_READ);
#endif
*pFileSize = _f.size();
return &_f;
}
static void jpegCloseFile(void *pHandle)
{
// Serial.println("jpegCloseFile");
File *f = static_cast<File *>(pHandle);
f->close();
}
static int32_t jpegReadFile(JPEGFILE *pFile, uint8_t *pBuf, int32_t iLen)
{
// Serial.printf("jpegReadFile, iLen: %d\n", iLen);
File *f = static_cast<File *>(pFile->fHandle);
size_t r = f->read(pBuf, iLen);
return r;
}
static int32_t jpegSeekFile(JPEGFILE *pFile, int32_t iPosition)
{
// Serial.printf("jpegSeekFile, pFile->iPos: %d, iPosition: %d\n", pFile->iPos, iPosition);
File *f = static_cast<File *>(pFile->fHandle);
f->seek(iPosition);
return iPosition;
}
static void jpegDraw(
const char *filename, JPEG_DRAW_CALLBACK *jpegDrawCallback, bool useBigEndian,
int x, int y, int widthLimit, int heightLimit)
{
_x = x;
_y = y;
_x_bound = _x + widthLimit - 1;
_y_bound = _y + heightLimit - 1;
_jpeg.open(filename, jpegOpenFile, jpegCloseFile, jpegReadFile, jpegSeekFile, jpegDrawCallback);
// scale to fit height
int _scale;
int iMaxMCUs;
float ratio = (float)_jpeg.getHeight() / heightLimit;
if (ratio <= 1)
{
_scale = 0;
iMaxMCUs = widthLimit / 16;
}
else if (ratio <= 2)
{
_scale = JPEG_SCALE_HALF;
iMaxMCUs = widthLimit / 8;
}
else if (ratio <= 4)
{
_scale = JPEG_SCALE_QUARTER;
iMaxMCUs = widthLimit / 4;
}
else
{
_scale = JPEG_SCALE_EIGHTH;
iMaxMCUs = widthLimit / 2;
}
_jpeg.setMaxOutputSize(iMaxMCUs);
if (useBigEndian)
{
_jpeg.setPixelType(RGB565_BIG_ENDIAN);
}
_jpeg.decode(x, y, _scale);
_jpeg.close();
}
#endif // _JPEGFUNC_H_

View File

@ -1,169 +0,0 @@
/*******************************************************************************
* ESP32 SIMD Motion JPEG Image Viewer
* This is a simple Motion JPEG image viewer example using ESP32 SIMD
* Image Source: https://www.pexels.com/video/earth-rotating-video-856356/
* cropped: x: 598 y: 178 width: 720 height: 720 resized: 240x240
* ffmpeg -i "Pexels Videos 3931.mp4" -ss 0 -t 20.4s -vf "reverse,setpts=0.5*PTS,fps=10,vflip,hflip,rotate=90,crop=720:720:178:598,scale=240:240:flags=lanczos" -q:v 11 earth.mjpeg
*
* Dependent libraries:
* ESP32_JPEG: https://github.com/esp-arduino-libs/ESP32_JPEG.git
*
* Setup steps:
* 1. Change your LCD parameters in Arduino_GFX setting
* 2. Upload Motion JPEG file
* FFat/LittleFS:
* upload FFat (FatFS) data with ESP32 Sketch Data Upload:
* ESP32: https://github.com/lorol/arduino-esp32fs-plugin
* SD:
* Most Arduino system built-in support SD file system.
******************************************************************************/
#define ROOT "/root"
#define MJPEG_FILENAME ROOT "/earth.mjpeg"
#define MJPEG_OUTPUT_SIZE (240 * 240 * 2) // memory for a output image frame
#define MJPEG_BUFFER_SIZE (MJPEG_OUTPUT_SIZE / 10) // memory for a single JPEG frame
/*******************************************************************************
* Start of Arduino_GFX setting
******************************************************************************/
#include <Arduino_GFX_Library.h>
#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */
#if defined(DISPLAY_DEV_KIT)
Arduino_GFX *gfx = create_default_Arduino_GFX();
#else /* !defined(DISPLAY_DEV_KIT) */
/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */
Arduino_DataBus *bus = create_default_Arduino_DataBus();
/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */
Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */);
#endif /* !defined(DISPLAY_DEV_KIT) */
/*******************************************************************************
* End of Arduino_GFX setting
******************************************************************************/
#include <FFat.h>
#include <LittleFS.h>
#include <SPIFFS.h>
#include <SD.h>
#include <SD_MMC.h>
#include "MjpegClass.h"
static MjpegClass mjpeg;
/* variables */
static int total_frames = 0;
static unsigned long total_read_video = 0;
static unsigned long total_decode_video = 0;
static unsigned long total_show_video = 0;
static unsigned long start_ms, curr_ms;
static int16_t x = -1, y = -1, w = -1, h = -1;
void setup()
{
#ifdef DEV_DEVICE_INIT
DEV_DEVICE_INIT();
#endif
Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("Arduino_GFX Motion JPEG ESP32P4 Decoder Image Viewer example");
// Init Display
if (!gfx->begin())
{
Serial.println("gfx->begin() failed!");
}
gfx->fillScreen(RGB565_BLACK);
#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
// if (!FFat.begin(false, ROOT))
if (!LittleFS.begin(false, ROOT))
// if (!SPIFFS.begin(false, ROOT))
// SPI.begin(12 /* CLK */, 13 /* D0/MISO */, 11 /* CMD/MOSI */);
// if (!SD.begin(10 /* CS */, SPI, 80000000L, ROOT))
// pinMode(10 /* CS */, OUTPUT);
// digitalWrite(SD_CS, HIGH);
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */);
// if (!SD_MMC.begin(ROOT, true /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_DEFAULT))
// SD_MMC.setPins(12 /* CLK */, 11 /* CMD/MOSI */, 13 /* D0/MISO */, 14 /* D1 */, 15 /* D2 */, 10 /* D3/CS */);
// if (!SD_MMC.begin(ROOT, false /* mode1bit */, false /* format_if_mount_failed */, SDMMC_FREQ_HIGHSPEED))
{
Serial.println(F("ERROR: File System Mount Failed!"));
gfx->println(F("ERROR: File System Mount Failed!"));
}
else
{
Serial.println(F("MJPEG start"));
start_ms = millis();
curr_ms = millis();
if (!mjpeg.setup(MJPEG_FILENAME))
{
Serial.println(F("mjpeg.setup() failed!"));
}
else
{
while (mjpeg.readMjpegBuf())
{
// Read video
total_read_video += millis() - curr_ms;
curr_ms = millis();
// Play video
mjpeg.decodeJpg();
total_decode_video += millis() - curr_ms;
curr_ms = millis();
if (x == -1)
{
w = mjpeg.getWidth();
h = mjpeg.getHeight();
x = (w > gfx->width()) ? 0 : ((gfx->width() - w) / 2);
y = (h > gfx->height()) ? 0 : ((gfx->height() - h) / 2);
}
gfx->draw16bitRGBBitmap(x, y, mjpeg.getOutBuf(), w, h);
total_show_video += millis() - curr_ms;
curr_ms = millis();
total_frames++;
}
int time_used = millis() - start_ms;
Serial.println(F("MJPEG end"));
float fps = 1000.0 * total_frames / time_used;
Serial.printf("Arduino_GFX ESP32 SIMD MJPEG decoder\n\n");
Serial.printf("Frame size: %d x %d\n", mjpeg.getWidth(), mjpeg.getHeight());
Serial.printf("Total frames: %d\n", total_frames);
Serial.printf("Time used: %d ms\n", time_used);
Serial.printf("Average FPS: %0.1f\n", fps);
Serial.printf("Read MJPEG: %lu ms (%0.1f %%)\n", total_read_video, 100.0 * total_read_video / time_used);
Serial.printf("Decode video: %lu ms (%0.1f %%)\n", total_decode_video, 100.0 * total_decode_video / time_used);
Serial.printf("Show video: %lu ms (%0.1f %%)\n", total_show_video, 100.0 * total_show_video / time_used);
gfx->setCursor(0, 0);
gfx->printf("Arduino_GFX ESP32 SIMD MJPEG decoder\n\n");
gfx->printf("Frame size: %d x %d\n", mjpeg.getWidth(), mjpeg.getHeight());
gfx->printf("Total frames: %d\n", total_frames);
gfx->printf("Time used: %d ms\n", time_used);
gfx->printf("Average FPS: %0.1f\n", fps);
gfx->printf("Read MJPEG: %lu ms (%0.1f %%)\n", total_read_video, 100.0 * total_read_video / time_used);
gfx->printf("Decode video: %lu ms (%0.1f %%)\n", total_decode_video, 100.0 * total_decode_video / time_used);
gfx->printf("Show video: %lu ms (%0.1f %%)\n", total_show_video, 100.0 * total_show_video / time_used);
mjpeg.close();
}
}
}
void loop()
{
}

View File

@ -1,196 +0,0 @@
/*******************************************************************************
* ESP32_JPEG Wrapper Class
*
* Dependent libraries:
* ESP32_JPEG: https://github.com/esp-arduino-libs/ESP32_JPEG.git
******************************************************************************/
#pragma once
#if defined(ESP32)
#include <driver/jpeg_decode.h>
#define READ_BATCH_SIZE 1024
class MjpegClass
{
public:
bool setup(const char *path)
{
_input = fopen(path, "r");
_read = 0;
jpeg_decode_engine_cfg_t decode_eng_cfg = {
.intr_priority = 0,
.timeout_ms = 40,
};
ESP_ERROR_CHECK(jpeg_new_decoder_engine(&decode_eng_cfg, &_decoder_engine));
jpeg_decode_cfg_t decode_cfg_rgb = {
.output_format = JPEG_DECODE_OUT_FORMAT_RGB565,
.rgb_order = JPEG_DEC_RGB_ELEMENT_ORDER_BGR,
};
size_t tx_buffer_size;
size_t rx_buffer_size;
jpeg_decode_memory_alloc_cfg_t rx_mem_cfg = {
.buffer_direction = JPEG_DEC_ALLOC_OUTPUT_BUFFER,
};
jpeg_decode_memory_alloc_cfg_t tx_mem_cfg = {
.buffer_direction = JPEG_DEC_ALLOC_INPUT_BUFFER,
};
uint32_t out_buf_size = MJPEG_OUTPUT_SIZE;
uint32_t bit_stream_size = MJPEG_BUFFER_SIZE;
_mjpeg_buf = (uint8_t *)jpeg_alloc_decoder_mem(bit_stream_size, &tx_mem_cfg, &tx_buffer_size);
_output_buf = (uint16_t *)jpeg_alloc_decoder_mem(out_buf_size, &rx_mem_cfg, &rx_buffer_size);
return true;
}
bool readMjpegBuf()
{
if (_read == 0)
{
// _mjpeg_buf empty
_read = fread(_mjpeg_buf, 1, READ_BATCH_SIZE, _input);
}
else
{
// pad previous remain data to the start of _mjpeg_buf
memcpy(_mjpeg_buf, _p, _read);
}
bool found_FFD8 = false;
_p = _mjpeg_buf;
while ((_read > 0) && (!found_FFD8))
{
while ((_read > 1) && (!found_FFD8))
{
--_read;
if ((*_p++ == 0xFF) && (*_p == 0xD8)) // JPEG header
{
// Serial.printf("Found FFD8 at: %d.\n", i);
found_FFD8 = true;
}
}
if (!found_FFD8)
{
if (*_p == 0xFF)
{
_mjpeg_buf[0] = 0xFF;
_read = fread(_mjpeg_buf + 1, 1, READ_BATCH_SIZE, _input) + 1;
}
else
{
_read = fread(_mjpeg_buf, 1, READ_BATCH_SIZE, _input);
}
_p = _mjpeg_buf;
}
}
if (!found_FFD8)
{
return false;
}
// rewind 1 byte
--_p;
++_read;
// pad JPEG header to the start of _mjpeg_buf
if (_p > _mjpeg_buf)
{
Serial.println("(_p > _mjpeg_buf)");
memcpy(_mjpeg_buf, _p, _read);
}
// skip JPEG header
_p += 2;
_read -= 2;
if (_read == 0)
{
_read = fread(_p, 1, READ_BATCH_SIZE, _input);
}
bool found_FFD9 = false;
while ((_read > 0) && (!found_FFD9))
{
while ((_read > 1) && (!found_FFD9))
{
--_read;
if ((*_p++ == 0xFF) && (*_p == 0xD9)) // JPEG trailer
{
// Serial.printf("Found FFD9 at: %d.\n", i);
found_FFD9 = true;
}
}
if (!found_FFD9)
{
_read += fread(_p + _read, 1, READ_BATCH_SIZE, _input);
// Serial.printf("_read: %d\n", _read - 1);
}
}
if (found_FFD9)
{
++_p;
--_read;
return true;
}
return false;
}
bool decodeJpg()
{
jpeg_decode_picture_info_t header_info;
ESP_ERROR_CHECK(jpeg_decoder_get_info(_mjpeg_buf, _p - _mjpeg_buf, &header_info));
_w = header_info.width;
_h = header_info.height;
uint32_t out_size;
jpeg_decode_cfg_t decode_cfg_rgb = {
.output_format = JPEG_DECODE_OUT_FORMAT_RGB565,
.rgb_order = JPEG_DEC_RGB_ELEMENT_ORDER_BGR,
};
ESP_ERROR_CHECK(jpeg_decoder_process(_decoder_engine, &decode_cfg_rgb, (const uint8_t *)_mjpeg_buf, _p - _mjpeg_buf, (uint8_t *)_output_buf, MJPEG_OUTPUT_SIZE, &out_size));
return true;
}
int16_t getWidth()
{
return _w;
}
int16_t getHeight()
{
return _h;
}
uint16_t *getOutBuf()
{
return _output_buf;
}
void close()
{
fclose(_input);
}
private:
FILE *_input;
uint8_t *_mjpeg_buf;
uint16_t *_output_buf;
jpeg_decoder_handle_t _decoder_engine;
int16_t _w = 0, _h = 0;
uint8_t *_p;
int32_t _read;
};
#endif // defined(ESP32)

Some files were not shown because too many files have changed in this diff Show More