Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 20601a7ecd | |||
| b487cd1e2e | |||
| 4240db93d5 | |||
| d11f49a43d | |||
| 98e13492ea |
5546
Bootstrap_Icons_34.c
Normal file
BIN
LVGL_FontGen.zip
Normal file
BIN
MaterialIconsOutlined-Regular.otf
Normal file
BIN
MaterialIconsRound-Regular.otf
Normal file
BIN
MaterialSymbolsRounded[FILL,GRAD,opsz,wght].ttf
Normal file
BIN
MaterialSymbolsRounded[FILL,GRAD,opsz,wght].woff2
Normal file
8
Raumtermostat/.vscode/settings.json
vendored
@ -71,5 +71,11 @@
|
||||
"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"
|
||||
}
|
||||
88
Raumtermostat/Raumtermostat.code-workspace
Normal file
@ -0,0 +1,88 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@ -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 < numPoints; ++i) {
|
||||
for (uint8_t i = 0; i < 1; ++i) {
|
||||
uint8_t *data = read_buffer + (i * 5) + (i == 0 ? 0 : 2);
|
||||
parseFingerData(data, &point_info[i]);
|
||||
x_array[i] = point_info[i].x;
|
||||
|
||||
@ -481,12 +481,12 @@
|
||||
/*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 1
|
||||
#define LV_FONT_MONTSERRAT_10 0
|
||||
#define LV_FONT_MONTSERRAT_12 0
|
||||
#define LV_FONT_MONTSERRAT_14 1
|
||||
#define LV_FONT_MONTSERRAT_14 0
|
||||
#define LV_FONT_MONTSERRAT_16 0
|
||||
#define LV_FONT_MONTSERRAT_18 0
|
||||
#define LV_FONT_MONTSERRAT_20 1
|
||||
#define LV_FONT_MONTSERRAT_20 0
|
||||
#define LV_FONT_MONTSERRAT_22 0
|
||||
#define LV_FONT_MONTSERRAT_24 0
|
||||
#define LV_FONT_MONTSERRAT_26 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 1
|
||||
#define LV_FONT_MONTSERRAT_38 0
|
||||
#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
|
||||
#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)
|
||||
|
||||
/*Always set a default font*/
|
||||
#define LV_FONT_DEFAULT &lv_font_montserrat_14
|
||||
#define LV_FONT_DEFAULT &symbol_font_12
|
||||
|
||||
/*Enable handling large font and/or fonts with a lot of characters.
|
||||
*The limit depends on the font size, font face and bpp.
|
||||
@ -586,7 +586,7 @@
|
||||
|
||||
#define LV_USE_ARC 1
|
||||
|
||||
#define LV_USE_BAR 0
|
||||
#define LV_USE_BAR 1
|
||||
|
||||
#define LV_USE_BUTTON 1
|
||||
|
||||
@ -611,9 +611,9 @@
|
||||
|
||||
#define LV_USE_CHART 1
|
||||
|
||||
#define LV_USE_CHECKBOX 0
|
||||
#define LV_USE_CHECKBOX 1
|
||||
|
||||
#define LV_USE_DROPDOWN 0 /*Requires: lv_label*/
|
||||
#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/
|
||||
|
||||
#define LV_USE_IMAGE 1 /*Requires: lv_label*/
|
||||
|
||||
@ -644,7 +644,7 @@
|
||||
|
||||
#define LV_USE_SCALE 1
|
||||
|
||||
#define LV_USE_SLIDER 0 /*Requires: lv_bar*/
|
||||
#define LV_USE_SLIDER 1 /*Requires: lv_bar*/
|
||||
|
||||
#define LV_USE_SPAN 1
|
||||
#if LV_USE_SPAN
|
||||
|
||||
@ -28,10 +28,8 @@
|
||||
|
||||
MQTT mqtt;
|
||||
Ticker measurementTick;
|
||||
Tahoma tahoma("1215-2900-8489.local","67ebd23e3a61763386d9");
|
||||
unsigned char ChipID = 0x00;
|
||||
volatile bool TouchEventFlag = false;
|
||||
|
||||
float barometerAltitude = 730.0; // meters ... map readings + barometer position
|
||||
//using namespace MDO;
|
||||
/*定义ESP32的SPI使用的引脚*/
|
||||
@ -123,7 +121,6 @@ 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)) {
|
||||
@ -143,7 +140,7 @@ void loop()
|
||||
{
|
||||
if(newMeasurement){
|
||||
esp_task_wdt_reset();
|
||||
update_sensorNstatus(temp, hum, seaLevelPress,presAlarm);
|
||||
update_sensor(temp, hum, seaLevelPress,presAlarm);
|
||||
test = glblData.settemp;
|
||||
newMeasurement = false;
|
||||
mqtt.sendStatus();
|
||||
@ -151,7 +148,7 @@ void loop()
|
||||
if(newHistory){
|
||||
newHistory=false;
|
||||
chart_autoscale();
|
||||
lv_chart_refresh(objects.chart);
|
||||
|
||||
}
|
||||
if(millis() - minutesTick > 60000){
|
||||
minutesTick = millis();
|
||||
@ -160,8 +157,9 @@ void loop()
|
||||
}
|
||||
}
|
||||
if(millis() - secondsTick > 1000){
|
||||
checkTahomaActions();
|
||||
secondsTick = millis();
|
||||
update_clockdots();
|
||||
update_status();
|
||||
}
|
||||
mqtt.loop();
|
||||
ui_tick();
|
||||
|
||||
@ -1,121 +1,202 @@
|
||||
#include "tahoma.h"
|
||||
|
||||
const char* rootCACertificate = "-----BEGIN CERTIFICATE-----\n"\
|
||||
"MIIDUTCCAjmgAwIBAgIBBDANBgkqhkiG9w0BAQsFADBLMRAwDgYDVQQKEwdPdmVy\n"\
|
||||
"a2l6MRAwDgYDVQQLEwdSb290IENBMRgwFgYDVQQDEw9PdmVya2l6IFJvb3QgQ0Ex\n"\
|
||||
"CzAJBgNVBAYTAkZSMB4XDTE2MDQyNzEyNTgxN1oXDTM2MDQyMjEyNTgxN1owZTEL\n"\
|
||||
"MAkGA1UEBhMCRlIxEDAOBgNVBAoTB092ZXJraXoxITAfBgNVBAsTGE92ZXJraXog\n"\
|
||||
"RGV2aWNlIFNlcnZlciBDQTEhMB8GA1UEAxMYT3ZlcmtpeiBEZXZpY2UgU2VydmVy\n"\
|
||||
"IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzr/hwPW3ykSV+Rv/\n"\
|
||||
"u+i1It8gq6aX4yLAP5vdrhzHGFrsNAhbviVe2SajBejfbuWTs0AvA03yHDsRhvlO\n"\
|
||||
"rKUXFg2ZekipgkI+yqii6bmk3Qsqp/DNCoogp+Rg0qFivT4DGxmKio1cPU4i2mXc\n"\
|
||||
"yIkSTR4bDUbhrFT+6ahEoYjcwvPaRxGUUobIpqJXDexPMzBSvy6/dLBay0Q1RMQ8\n"\
|
||||
"LSyLtc/Zl1HkNTgSen9tHoq4A0JMeheLW47/HKgMYeQkeIsjzCKduLhZea893EYY\n"\
|
||||
"tPS/EUlNfK0YiYbI4UIdNvJ6N0iu85KDreytFT7XAVnZSAbmLXuqtQC0U7EM7jEq\n"\
|
||||
"uepAuwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIB\n"\
|
||||
"BjANBgkqhkiG9w0BAQsFAAOCAQEAkxcJ80vpnS4VyBQMLbvmncg06b65tlCndSJm\n"\
|
||||
"MXMS6rwdAhUs84Gqu6H/vN3k1ix4iYty/n7MPfyYOznidMANayXurf0YMdIDagoE\n"\
|
||||
"Gv2QVOl63Oe7xhKbcdAgejDAewyXbC8+cZj156itUSQZjmNdZ/59pt7lMkV6YDR2\n"\
|
||||
"pOPnPjqG16TQ7ju2iYonhoHPd/iWs7iKcBs8/eaMYxcpqQDbX+O6hN5qPcTBfGRB\n"\
|
||||
"TFqwgSu0abNIZ3IJuSUGxkoPcIxNWLTxnwCgUN+TQTrg6rWw8T7GtSzKBljVk09R\n"\
|
||||
"9YmKHPhUN7wjNRzWiecfomTi3FTgYbrzbwCSTj3FAogCxuHAwA==\n"\
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
Tahoma::Tahoma(const String _hostname, const String _token) : connected(false) {
|
||||
hostname = _hostname;
|
||||
token = _token;
|
||||
}
|
||||
#include "settings.h"
|
||||
extern constexpr char Tahoma::serverURL[];
|
||||
extern Tahoma::rolloCommand_t Tahoma::movement[];
|
||||
Tahoma::Tahoma(void) {}
|
||||
|
||||
// Destructor
|
||||
Tahoma::~Tahoma() {
|
||||
|
||||
}
|
||||
Tahoma::~Tahoma() {}
|
||||
|
||||
String url_encode(const String &value) {
|
||||
String escaped;
|
||||
|
||||
for (uint16_t i = 0; i < value.length(); i++) {
|
||||
|
||||
char c = value.charAt(i);
|
||||
// Keep alphanumeric and other accepted characters intact
|
||||
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
escaped += c;
|
||||
continue;
|
||||
}else{
|
||||
// Any other characters are percent-encoded
|
||||
if(c < 0x10){
|
||||
escaped += "%0" + String(c, HEX);
|
||||
}else{
|
||||
escaped += '%' + String(c, HEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return escaped;
|
||||
}
|
||||
|
||||
String Tahoma::getDeviceName(const String _url)
|
||||
{
|
||||
//String url = "/enduser-mobile-web/1/enduserAPI/apiVersion"; // Construct the URL to fetch the device name
|
||||
uint8_t Tahoma::getMyDevices(bool _force_update) {
|
||||
if (!numDevs || _force_update) {
|
||||
HTTPClient http; // Create an HTTP client object
|
||||
String url = "/enduser-mobile-web/1/enduserAPI/setup/devices/" + url_encode(_url) + "/states/core:NameState"; // Construct the URL to fetch the device name
|
||||
String deviceName;
|
||||
http.begin("1215-2900-8489.local",8443,url,rootCACertificate); // Initialize the HTTP connection
|
||||
http.addHeader("Authorization", "Bearer " + token); // Add the authorization header with the token
|
||||
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
|
||||
Serial.println(response); // Print the response to the serial monitor for debugging
|
||||
if (doc["value"].isNull()) { // Check if the value is null
|
||||
Serial.println("Device not found"); // Print error message if the device is not found
|
||||
}else{
|
||||
deviceName = doc["value"].as<String>(); // Get the device name from the JSON response
|
||||
Serial.println("Device Name: " + deviceName); // Print the device name to the serial monitor
|
||||
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
|
||||
Serial.println(url); // Print the URL for debugging
|
||||
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 deviceName; // Return the device name
|
||||
}
|
||||
return numDevs;
|
||||
}
|
||||
|
||||
bool Tahoma::isDeviceSelected(uint8_t deviceIndex) {
|
||||
return devicelist[deviceIndex].selected;
|
||||
}
|
||||
|
||||
void Tahoma::getAllDevices(void){
|
||||
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 = "/enduser-mobile-web/1/enduserAPI/setup/devices/controllables/io%3AExteriorVenetianBlindIOComponent"; // Construct the URL to fetch all devices
|
||||
http.begin("1215-2900-8489.local",8443,url,rootCACertificate); // Initialize the HTTP connection
|
||||
http.addHeader("Authorization", "Bearer " + token); // Add the authorization header with the token
|
||||
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
|
||||
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
|
||||
devicelist[i].url = doc[i].as<String>(); // Get the device URL from the JSON response
|
||||
Serial.println("Device URL: " + devicelist[i].url); // Print the device URL to the serial monitor
|
||||
}
|
||||
}
|
||||
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
|
||||
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;
|
||||
}
|
||||
void Tahoma::getAllDeviceNames(void){
|
||||
for (int i = 0; i < MAX_NUM_DEVICES; i++) { // Loop through the JSON array
|
||||
if(devicelist[i].url == ""){ // Check if the device URL is empty
|
||||
break; // Break the loop if the device URL is empty
|
||||
}
|
||||
devicelist[i].name = getDeviceName(devicelist[i].url); // Get the device name using the device URL
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,36 +4,48 @@
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include <iostream>
|
||||
#include <base64.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <Ticker.h>
|
||||
#include <ArduinoJson.h> // Include the ArduinoJson library for JSON parsing
|
||||
#include <ESPAsyncWebserver.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#define MAX_NUM_DEVICES 32 // Maximum number of devices to fetch
|
||||
#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
|
||||
String url; // Device URL
|
||||
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(const String hostname, const String token);
|
||||
Tahoma(void);
|
||||
|
||||
// Destructor
|
||||
~Tahoma();
|
||||
void getAllDevices(void); // Fetches the device name from the Tahoma system
|
||||
String getDeviceName(const String _url); // Fetches the device name from the Tahoma system
|
||||
void getAllDeviceNames(void); // Fetches all device names from the Tahoma system
|
||||
private:
|
||||
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];
|
||||
String hostname; // Hostname of the Tahoma system
|
||||
String token; // Authentication token for the Tahoma system
|
||||
bool connected; // Connection status
|
||||
|
||||
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
|
||||
void fetchData();
|
||||
};
|
||||
|
||||
#endif // TAHOMA_H
|
||||
1623
Raumtermostat/src/ui/Bootstrap_Icons_10.c
Normal file
@ -1,319 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Size: 12 px
|
||||
* Bpp: 4
|
||||
* Opts: --bpp 4 --size 12 --no-compress --font bootstrap-icons.woff --range 63001-63004,62219-62221,62611,61829-61832,62719,62711,63478,62925-62930 --format lvgl -o Bootstrap_Icons_12.c
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#include "lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#ifndef BOOTSTRAP_ICONS_12
|
||||
#define BOOTSTRAP_ICONS_12 1
|
||||
#endif
|
||||
|
||||
#if BOOTSTRAP_ICONS_12
|
||||
|
||||
|
||||
/*-----------------
|
||||
* BITMAPS
|
||||
*----------------*/
|
||||
|
||||
/*Store the image of the glyphs*/
|
||||
static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
/* U+F185 "" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0xb4, 0x0, 0x0, 0x8c, 0xcc, 0x5b, 0xf1,
|
||||
0xcc, 0x20, 0xc3, 0x80, 0xaf, 0xb0, 0x14, 0x70,
|
||||
0xc7, 0x69, 0xff, 0xfe, 0x33, 0x6c, 0xc6, 0x3e,
|
||||
0xff, 0xf9, 0x63, 0x6d, 0xc3, 0x10, 0xbf, 0xa1,
|
||||
0x74, 0x70, 0x8c, 0xc2, 0xfa, 0x4c, 0xcc, 0x20,
|
||||
0x0, 0x4, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F186 "" */
|
||||
0x2, 0x33, 0x33, 0x33, 0x31, 0x0, 0x9a, 0x88,
|
||||
0x88, 0x88, 0x8b, 0x30, 0xc3, 0xbb, 0xbb, 0xbb,
|
||||
0xb0, 0x72, 0xc5, 0xff, 0xff, 0xff, 0xf1, 0x6e,
|
||||
0xc5, 0xff, 0xff, 0xff, 0xf1, 0x6a, 0xc0, 0x44,
|
||||
0x44, 0x44, 0x43, 0x70, 0x3b, 0xcc, 0xcc, 0xcc,
|
||||
0xca, 0x10,
|
||||
|
||||
/* U+F187 "" */
|
||||
0x8c, 0xcc, 0xcc, 0xcc, 0xcd, 0x40, 0xc, 0x38,
|
||||
0x88, 0x30, 0x0, 0x1b, 0x0, 0xc7, 0xff, 0xf7,
|
||||
0x0, 0x0, 0xbd, 0x1c, 0x7f, 0xff, 0x70, 0x0,
|
||||
0xb, 0xd1, 0xc3, 0x77, 0x73, 0x0, 0x1, 0xb0,
|
||||
0x8, 0xcc, 0xcc, 0xcc, 0xcc, 0xd4, 0x0,
|
||||
|
||||
/* U+F188 "" */
|
||||
0x8c, 0xcc, 0xcc, 0xcc, 0xcd, 0x40, 0xc, 0x0,
|
||||
0x0, 0x0, 0x0, 0x1b, 0x0, 0xc0, 0x0, 0x0,
|
||||
0x0, 0x0, 0xbd, 0x1c, 0x0, 0x0, 0x0, 0x0,
|
||||
0xb, 0xd1, 0xc0, 0x0, 0x0, 0x0, 0x1, 0xb0,
|
||||
0x8, 0xcc, 0xcc, 0xcc, 0xcc, 0xd4, 0x0,
|
||||
|
||||
/* U+F30B "" */
|
||||
0x0, 0x0, 0x46, 0x0, 0x0, 0x0, 0x3, 0xfd,
|
||||
0x0, 0x0, 0x0, 0x1e, 0xff, 0x70, 0x0, 0x0,
|
||||
0xbf, 0xcf, 0xf4, 0x0, 0x5, 0xf6, 0xaf, 0xff,
|
||||
0x20, 0xc, 0xd5, 0xff, 0xff, 0xe1, 0x1f, 0xff,
|
||||
0xff, 0xff, 0xf7, 0x3f, 0xff, 0xff, 0xff, 0xfb,
|
||||
0x2f, 0xff, 0xff, 0xff, 0xf9, 0xc, 0xff, 0xff,
|
||||
0xff, 0xf3, 0x2, 0xef, 0xff, 0xff, 0x80, 0x0,
|
||||
0x2a, 0xef, 0xc5, 0x0,
|
||||
|
||||
/* U+F30C "" */
|
||||
0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0xa, 0xb4,
|
||||
0x0, 0x0, 0x0, 0x77, 0xc, 0x0, 0x0, 0x3,
|
||||
0xb3, 0x4, 0xa0, 0x0, 0xb, 0x3b, 0x0, 0x78,
|
||||
0x0, 0x38, 0x93, 0x0, 0xa, 0x50, 0x93, 0x0,
|
||||
0x0, 0x0, 0xb0, 0xb4, 0x0, 0x15, 0x88, 0xd0,
|
||||
0x9f, 0xfe, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff,
|
||||
0xff, 0x90, 0x8, 0xff, 0xff, 0xfd, 0x0, 0x0,
|
||||
0x6c, 0xfe, 0x90, 0x0,
|
||||
|
||||
/* U+F30D "" */
|
||||
0x0, 0x0, 0x90, 0x0, 0x0, 0x0, 0xa, 0xb4,
|
||||
0x0, 0x0, 0x0, 0x77, 0xc, 0x0, 0x0, 0x3,
|
||||
0xb3, 0x4, 0xa0, 0x0, 0xb, 0x3b, 0x0, 0x78,
|
||||
0x0, 0x38, 0x93, 0x0, 0xa, 0x50, 0x93, 0x0,
|
||||
0x0, 0x0, 0xb0, 0xb0, 0x0, 0x0, 0x0, 0xb0,
|
||||
0x92, 0x0, 0x0, 0x0, 0xc0, 0x39, 0x0, 0x0,
|
||||
0x4, 0x90, 0x8, 0x80, 0x0, 0x4c, 0x0, 0x0,
|
||||
0x6c, 0xcc, 0x90, 0x0,
|
||||
|
||||
/* U+F493 "" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x4c, 0xb0, 0x0, 0xbb,
|
||||
0x0, 0x0, 0xc, 0x0, 0x95, 0x49, 0x0, 0x0,
|
||||
0xc0, 0x49, 0x0, 0x94, 0x0, 0x7c, 0xd, 0x65,
|
||||
0x56, 0xd0, 0x0, 0xc4, 0x84, 0x44, 0x48, 0x53,
|
||||
0x9c, 0x91, 0x0, 0x0, 0x1a, 0x2, 0xca, 0x0,
|
||||
0x0, 0x0, 0xb0, 0xc, 0x75, 0x0, 0x0, 0x49,
|
||||
0x7, 0xc1, 0xc1, 0x0, 0x1c, 0x20, 0xc, 0x3,
|
||||
0xca, 0xad, 0x40, 0x0, 0xc0, 0x0, 0x22, 0x0,
|
||||
0x4, 0xcb,
|
||||
|
||||
/* U+F4F7 "" */
|
||||
0x0, 0xb, 0x0, 0x90, 0x0, 0xd, 0x0, 0xa0,
|
||||
0x0, 0xbf, 0xcc, 0xeb, 0x0, 0xc0, 0x0, 0xc,
|
||||
0x0, 0xc0, 0x0, 0xc, 0x0, 0xc0, 0x0, 0xc,
|
||||
0x0, 0x77, 0x0, 0x88, 0x0, 0x5, 0xbd, 0x70,
|
||||
0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0x85, 0x0,
|
||||
0x7, 0xbb, 0x70, 0x0, 0x48, 0x0, 0x0, 0x0,
|
||||
0x10, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F4FF "" */
|
||||
0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x29,
|
||||
0x0, 0x0, 0x0, 0x0, 0x29, 0x1, 0x0, 0x1,
|
||||
0xc2, 0x29, 0x9, 0x60, 0xa, 0x30, 0x29, 0x0,
|
||||
0xb2, 0x1a, 0x0, 0x29, 0x0, 0x48, 0x37, 0x0,
|
||||
0x0, 0x0, 0x1b, 0x29, 0x0, 0x0, 0x0, 0x29,
|
||||
0xb, 0x10, 0x0, 0x0, 0x93, 0x3, 0xb1, 0x0,
|
||||
0x7, 0x90, 0x0, 0x2a, 0xba, 0xc6, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F5CD "" */
|
||||
0x4, 0xcc, 0x30, 0xb, 0x0, 0xb0, 0xc, 0x0,
|
||||
0xc0, 0xc, 0x0, 0xc0, 0xc, 0x22, 0xc0, 0xc,
|
||||
0x55, 0xc0, 0xc, 0x55, 0xc0, 0xc, 0x55, 0xc0,
|
||||
0x76, 0xaa, 0x66, 0x93, 0xff, 0x39, 0x58, 0x54,
|
||||
0x85, 0x7, 0xcc, 0x70, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F5CE "" */
|
||||
0x4, 0xcc, 0x30, 0xb, 0x33, 0xb0, 0xc, 0x55,
|
||||
0xc0, 0xc, 0x55, 0xc0, 0xc, 0x55, 0xc0, 0xc,
|
||||
0x55, 0xc0, 0xc, 0x55, 0xc0, 0xc, 0x55, 0xc0,
|
||||
0x76, 0xaa, 0x66, 0x93, 0xff, 0x39, 0x58, 0x54,
|
||||
0x85, 0x7, 0xcc, 0x70, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F5CF "" */
|
||||
0x4, 0xcc, 0x30, 0xb, 0x0, 0xb0, 0xc, 0x0,
|
||||
0xc0, 0xc, 0x0, 0xc0, 0xc, 0x0, 0xc0, 0xc,
|
||||
0x0, 0xc0, 0xc, 0x0, 0xc0, 0xc, 0x55, 0xc0,
|
||||
0x66, 0xaa, 0x66, 0x93, 0xff, 0x39, 0x58, 0x54,
|
||||
0x85, 0x7, 0xcc, 0x70, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F5D0 "" */
|
||||
0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x8a, 0xc4,
|
||||
0x0, 0x0, 0x0, 0xb, 0x0, 0xb0, 0x70, 0x0,
|
||||
0x0, 0xb0, 0xc, 0xc, 0xb1, 0x0, 0xb, 0x0,
|
||||
0xc0, 0xc3, 0x88, 0x40, 0xb0, 0xc, 0xc, 0x2d,
|
||||
0xe2, 0xb, 0x0, 0xc0, 0xcc, 0x24, 0x20, 0xb3,
|
||||
0x1c, 0xc, 0xb9, 0xb3, 0x3a, 0x83, 0xd0, 0xc0,
|
||||
0xbd, 0x4a, 0x3e, 0xa6, 0x5c, 0x95, 0x31, 0xb3,
|
||||
0xfe, 0x56, 0xc5, 0x0, 0x5, 0x94, 0x3c, 0x12,
|
||||
0x0, 0x0, 0x5, 0xba, 0x30, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F5D1 "" */
|
||||
0x6, 0xcc, 0x20, 0x0, 0x0, 0x0, 0xc, 0x33,
|
||||
0xa0, 0x40, 0x0, 0x0, 0xb, 0x83, 0xc0, 0xb0,
|
||||
0x2, 0x0, 0xb, 0x83, 0xc0, 0x21, 0x38, 0x0,
|
||||
0xb, 0x83, 0xc0, 0x4a, 0x40, 0x0, 0xb, 0x83,
|
||||
0xc0, 0x0, 0xb3, 0x80, 0xb, 0x83, 0xc0, 0x1,
|
||||
0xb0, 0x20, 0x2a, 0x83, 0xd0, 0x7c, 0x30, 0x0,
|
||||
0xa3, 0xc8, 0x75, 0x10, 0x3a, 0x0, 0xb3, 0xfe,
|
||||
0x46, 0xa0, 0x2, 0x0, 0x66, 0x53, 0xa2, 0x40,
|
||||
0x0, 0x0, 0x7, 0xaa, 0x40, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F5D2 "" */
|
||||
0x4, 0xcc, 0x40, 0xb, 0x0, 0xb0, 0xb, 0x0,
|
||||
0xb0, 0xb, 0x0, 0xb0, 0xb, 0x0, 0xb0, 0xb,
|
||||
0x0, 0xb0, 0xb, 0x0, 0xb0, 0xc, 0x0, 0xc0,
|
||||
0x75, 0xaa, 0x57, 0x93, 0xff, 0x39, 0x49, 0x44,
|
||||
0x94, 0x6, 0xcc, 0x60,
|
||||
|
||||
/* U+F619 "" */
|
||||
0x0, 0x0, 0x0, 0x2b, 0xbb, 0xb2, 0x0, 0x33,
|
||||
0x0, 0x0, 0x99, 0x0,
|
||||
|
||||
/* U+F61A "" */
|
||||
0x0, 0x48, 0xbb, 0x82, 0x0, 0xb, 0x93, 0x10,
|
||||
0x4b, 0x90, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0,
|
||||
0x29, 0xbb, 0x92, 0x0, 0x0, 0x0, 0x33, 0x0,
|
||||
0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
|
||||
|
||||
/* U+F61B "" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x2, 0x60, 0x0, 0x16,
|
||||
0x9b, 0xb7, 0x2c, 0x20, 0x9, 0xc6, 0x20, 0x1,
|
||||
0xc3, 0x80, 0x64, 0x1, 0x55, 0x2c, 0x20, 0x55,
|
||||
0x0, 0x8c, 0x70, 0xc2, 0xa8, 0x0, 0x0, 0x30,
|
||||
0x2c, 0x30, 0x3, 0x0, 0x0, 0x2, 0xc2, 0x6b,
|
||||
0x30, 0x0, 0x0, 0x2c, 0x23, 0x30, 0x0, 0x0,
|
||||
0x0, 0xc2, 0x9, 0x90, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+F61C "" */
|
||||
0x0, 0x16, 0xab, 0xb9, 0x50, 0x0, 0x1a, 0xb5,
|
||||
0x20, 0x2, 0x6c, 0x80, 0x73, 0x4, 0x8b, 0xb8,
|
||||
0x20, 0x64, 0x0, 0xb9, 0x31, 0x4, 0xb9, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2,
|
||||
0x9b, 0xb9, 0x20, 0x0, 0x0, 0x0, 0x3, 0x30,
|
||||
0x0, 0x0, 0x0, 0x0, 0x9, 0x90, 0x0, 0x0,
|
||||
|
||||
/* U+F7F6 "" */
|
||||
0x0, 0x6, 0x91, 0x0, 0x0, 0x0, 0x6, 0xfc,
|
||||
0x0, 0x0, 0x0, 0x8, 0xff, 0x60, 0x0, 0x0,
|
||||
0x2f, 0xff, 0xb2, 0x0, 0x1, 0xef, 0xff, 0xcc,
|
||||
0x70, 0xc, 0xff, 0xe9, 0xff, 0xf0, 0x4f, 0xff,
|
||||
0x73, 0xff, 0xf5, 0x7f, 0xf7, 0x30, 0x8f, 0xf7,
|
||||
0x6f, 0xd0, 0x0, 0xe, 0xf6, 0x2f, 0xd0, 0x0,
|
||||
0xd, 0xf2, 0x8, 0xf4, 0x0, 0x4f, 0x80, 0x0,
|
||||
0x5c, 0xcc, 0xc5, 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 = 192, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = 1},
|
||||
{.bitmap_index = 60, .adv_w = 192, .box_w = 12, .box_h = 7, .ofs_x = 0, .ofs_y = 3},
|
||||
{.bitmap_index = 102, .adv_w = 192, .box_w = 13, .box_h = 6, .ofs_x = 0, .ofs_y = 3},
|
||||
{.bitmap_index = 141, .adv_w = 192, .box_w = 13, .box_h = 6, .ofs_x = 0, .ofs_y = 3},
|
||||
{.bitmap_index = 180, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
|
||||
{.bitmap_index = 240, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
|
||||
{.bitmap_index = 300, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
|
||||
{.bitmap_index = 360, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
|
||||
{.bitmap_index = 426, .adv_w = 192, .box_w = 8, .box_h = 13, .ofs_x = 1, .ofs_y = -1},
|
||||
{.bitmap_index = 478, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0},
|
||||
{.bitmap_index = 538, .adv_w = 192, .box_w = 6, .box_h = 13, .ofs_x = 3, .ofs_y = -1},
|
||||
{.bitmap_index = 577, .adv_w = 192, .box_w = 6, .box_h = 13, .ofs_x = 3, .ofs_y = -1},
|
||||
{.bitmap_index = 616, .adv_w = 192, .box_w = 6, .box_h = 13, .ofs_x = 3, .ofs_y = -1},
|
||||
{.bitmap_index = 655, .adv_w = 192, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = 0},
|
||||
{.bitmap_index = 727, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = 0},
|
||||
{.bitmap_index = 799, .adv_w = 192, .box_w = 6, .box_h = 12, .ofs_x = 3, .ofs_y = 0},
|
||||
{.bitmap_index = 835, .adv_w = 192, .box_w = 6, .box_h = 4, .ofs_x = 3, .ofs_y = 2},
|
||||
{.bitmap_index = 847, .adv_w = 192, .box_w = 10, .box_h = 6, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 877, .adv_w = 192, .box_w = 12, .box_h = 10, .ofs_x = 0, .ofs_y = 1},
|
||||
{.bitmap_index = 937, .adv_w = 192, .box_w = 12, .box_h = 8, .ofs_x = 0, .ofs_y = 2},
|
||||
{.bitmap_index = 985, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = 0}
|
||||
};
|
||||
|
||||
/*---------------------
|
||||
* CHARACTER MAPPING
|
||||
*--------------------*/
|
||||
|
||||
static const uint16_t unicode_list_0[] = {
|
||||
0x0, 0x1, 0x2, 0x3, 0x186, 0x187, 0x188, 0x30e,
|
||||
0x372, 0x37a, 0x448, 0x449, 0x44a, 0x44b, 0x44c, 0x44d,
|
||||
0x494, 0x495, 0x496, 0x497, 0x671
|
||||
};
|
||||
|
||||
/*Collect the unicode lists and glyph_id offsets*/
|
||||
static const lv_font_fmt_txt_cmap_t cmaps[] =
|
||||
{
|
||||
{
|
||||
.range_start = 61829, .range_length = 1650, .glyph_id_start = 1,
|
||||
.unicode_list = unicode_list_0, .glyph_id_ofs_list = NULL, .list_length = 21, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*--------------------
|
||||
* 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 = NULL,
|
||||
.kern_scale = 0,
|
||||
.cmap_num = 1,
|
||||
.bpp = 4,
|
||||
.kern_classes = 0,
|
||||
.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 Bootstrap_Icons_12 = {
|
||||
#else
|
||||
lv_font_t Bootstrap_Icons_12 = {
|
||||
#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 = 14, /*The maximum line height required by the font*/
|
||||
.base_line = 1, /*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 BOOTSTRAP_ICONS_12*/
|
||||
|
||||
3712
Raumtermostat/src/ui/Bootstrap_Icons_20.c
Normal file
5545
Raumtermostat/src/ui/Bootstrap_Icons_34.c
Normal file
@ -16,16 +16,28 @@ void action_switch_screens(lv_event_t * e);
|
||||
void showDebugScreen(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 rebootESP(lv_event_t * e);
|
||||
void action_show_cursors_cb(lv_event_t * e);
|
||||
void chartDrawingCB(lv_event_t * e);
|
||||
void update_sensorNstatus(float temp, float hum, float seaLevelPress, bool presAlarm);
|
||||
void update_sensor(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
|
||||
|
||||
@ -8,52 +8,66 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _objects_t {
|
||||
lv_obj_t *main;
|
||||
lv_obj_t *second;
|
||||
lv_obj_t *debug;
|
||||
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_chart_cursor_t *chart_cursor;
|
||||
lv_chart_series_t *chart_series;
|
||||
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;
|
||||
} objects_t;
|
||||
|
||||
extern objects_t objects;
|
||||
|
||||
typedef enum ScreensEnum {
|
||||
SCREEN_ID_MAIN = 1,
|
||||
SCREEN_ID_CHART = 2,
|
||||
SCREEN_ID_DEBUG = 3
|
||||
}ScreensEnum;
|
||||
SCREEN_ID_MAIN = 0,
|
||||
SCREEN_ID_CHART = 1,
|
||||
SCREEN_ID_DEBUG = 2,
|
||||
SCREEN_ID_LEN
|
||||
} 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
|
||||
|
||||
@ -66,23 +66,52 @@ void remove_style_arc(lv_obj_t *obj) {
|
||||
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_arc,
|
||||
};
|
||||
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_arc,
|
||||
};
|
||||
remove_style_funcs[styleIndex](obj);
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,8 @@ 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_slider(lv_obj_t *obj);
|
||||
void remove_style_slider(lv_obj_t *obj);
|
||||
|
||||
|
||||
|
||||
|
||||
1485
Raumtermostat/src/ui/symbol_font_10.c
Normal file
1707
Raumtermostat/src/ui/symbol_font_12.c
Normal file
2137
Raumtermostat/src/ui/symbol_font_16.c
Normal file
5698
Raumtermostat/src/ui/symbol_font_36.c
Normal file
6208
Raumtermostat/src/ui/symbol_font_38.c
Normal file
715
Raumtermostat/src/ui/symbol_font_numbers_2bpp_34.c
Normal file
@ -0,0 +1,715 @@
|
||||
/*******************************************************************************
|
||||
* 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*/
|
||||
|
||||
@ -10,8 +10,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
LV_FONT_DECLARE(Bootstrap_Icons_16);
|
||||
LV_FONT_DECLARE(Bootstrap_Icons_18);
|
||||
//included icons in bootstrap font
|
||||
//use this list for font generator:
|
||||
/*
|
||||
@ -19,42 +17,43 @@
|
||||
0xF5CD-0xF5D2,0xF100,0xF479,0xF5D4,0xF5D3,0xF116,0xF117,0xF3F2,0xF229,0xF22C,0xF235,0xF238,0xF22D,0xF230,0xF231,0xF234
|
||||
|
||||
*/
|
||||
#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 "" //F100
|
||||
#define ICON_MENU_LINES "" //F479
|
||||
#define ICON_MENU_DOTS_H "" //F5D4
|
||||
#define ICON_MENU_DOTS_V "" //F5D3
|
||||
#define ICON_ROTATE_CW "" //F116
|
||||
#define ICON_ROTATE_CC "" //F117
|
||||
#define ICON_GRAPH "" //F3F2
|
||||
#define ICON_ARROW_DOWN_FILL "" //F229
|
||||
#define ICON_ARROW_DOWN "" //F22C
|
||||
#define ICON_ARROW_UP_FILL "" //F235
|
||||
#define ICON_ARROW_UP "" //F238
|
||||
#define ICON_ARROW_LEFT_FILL "" //F22D
|
||||
#define ICON_ARROW_LEFT "" //F230
|
||||
#define ICON_ARROW_RIGHT_FILL "" //F231
|
||||
#define ICON_ARROW_RIGHT "" //F234
|
||||
#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 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"
|
||||
|
||||
|
||||
|
||||
|
||||
/*-------------------------------
|
||||
|
||||
@ -1,225 +1,229 @@
|
||||
#include <Arduino.h>
|
||||
#include "ui.h"
|
||||
#include "screens.h"
|
||||
#include "images.h"
|
||||
#include "actions.h"
|
||||
#include "images.h"
|
||||
#include "screens.h"
|
||||
#include "vars.h"
|
||||
#include <string.h>
|
||||
#include <Arduino.h>
|
||||
#include <Arduino_GFX_Library.h>
|
||||
#include <TouchDrvCSTXXX.hpp>
|
||||
#include <Ticker.h>
|
||||
#include <TouchDrvCSTXXX.hpp>
|
||||
#include <string.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 int16_t currentScreen = -1;
|
||||
static lv_obj_t *currentScreen = NULL;
|
||||
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(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 loadScreen(lv_obj_t *screen) {
|
||||
lv_scr_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, true);
|
||||
currentScreen = screen;
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
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();
|
||||
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 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 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 DisplayInit(void) {
|
||||
ledcAttachPin(GFX_BL, GFX_BL);
|
||||
ledcSetup(GFX_BL, 2000, 10);
|
||||
ledcWrite(GFX_BL, 0);
|
||||
gfx->begin(80000000);
|
||||
gfx->fillScreen(0x0000);
|
||||
}
|
||||
|
||||
ScreensEnum ui_getCurrentScreen(void){
|
||||
return (ScreensEnum) (currentScreen + 1);
|
||||
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();
|
||||
}
|
||||
|
||||
ChartsEnum ui_getCurrentChart(void){
|
||||
return (ChartsEnum) currentChart;
|
||||
}
|
||||
lv_obj_t *ui_getCurrentScreen(void) { return currentScreen; }
|
||||
|
||||
ChartsEnum ui_getCurrentChart(void) { return (ChartsEnum)currentChart; }
|
||||
|
||||
void ui_init() {
|
||||
create_screens();
|
||||
loadScreen(SCREEN_ID_MAIN);
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void displaySleep(){
|
||||
gfx->displayOff();
|
||||
setBacklight(0,300);
|
||||
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 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(SDA,SCL); //初始化IIC,设置引脚 SCL:22 SDA:21
|
||||
Wire.setClock(200000); //设置频率400KHZ
|
||||
if(touch.begin(Wire, TouchI2CAddr, SDA, SCL)){
|
||||
Serial.println("Touch screen initialization done");
|
||||
}
|
||||
attachInterrupt(TouchInt, []() {
|
||||
isPressed = true;
|
||||
}, CHANGE);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
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();
|
||||
attachInterrupt(
|
||||
TouchInt, []() { isPressed = true; }, CHANGE);
|
||||
}
|
||||
|
||||
|
||||
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_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 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++) {
|
||||
// //gfx->writePixel(x, y, *buf16);
|
||||
bus->write16(*buf16);
|
||||
bus->write16(*buf16);
|
||||
// bus->write16bitBeRGBBitmapR1()
|
||||
buf16++;
|
||||
}
|
||||
}
|
||||
gfx->endWrite();
|
||||
/* IMPORTANT!!!
|
||||
* Inform LVGL that flushing is complete so buffer can be modified again. */
|
||||
lv_display_flush_ready(display);
|
||||
buf16++;
|
||||
}
|
||||
}
|
||||
gfx->endWrite();
|
||||
/* IMPORTANT!!!
|
||||
* Inform LVGL that flushing is complete so buffer can be modified again. */
|
||||
lv_display_flush_ready(display);
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
|
||||
#define TouchInt 8
|
||||
#define TouchRST 9
|
||||
#define SCL 7
|
||||
#define SDA 6
|
||||
#define TouchSCL 7
|
||||
#define TouchSDA 6
|
||||
|
||||
#define TouchI2CAddr 0x15
|
||||
|
||||
@ -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(ScreensEnum screenId);
|
||||
void loadScreen(lv_obj_t *screen);
|
||||
void loadChart(uint8_t chartId);
|
||||
void ui_chart_autoscale(void);
|
||||
float ui_getSetTemp(void);
|
||||
ScreensEnum ui_getCurrentScreen(void);
|
||||
lv_obj_t* ui_getCurrentScreen(void);
|
||||
ChartsEnum ui_getCurrentChart(void);
|
||||
void displaySleep();
|
||||
void displayWake();
|
||||
|
||||
7
font_converter_settings.txt
Normal file
@ -0,0 +1,7 @@
|
||||
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
|
||||
1
libdeps/seeed_xiao_esp32c3/BME280/.piopm
Normal file
@ -0,0 +1 @@
|
||||
{"type": "library", "name": "BME280", "version": "3.0.0", "spec": {"owner": "finitespace", "id": 901, "name": "BME280", "requirements": null, "uri": null}}
|
||||
675
libdeps/seeed_xiao_esp32c3/BME280/LICENSE
Normal file
@ -0,0 +1,675 @@
|
||||
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>.
|
||||
|
||||
@ -0,0 +1,141 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,102 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,145 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
12
libdeps/seeed_xiao_esp32c3/BME280/keywords.txt
Normal file
@ -0,0 +1,12 @@
|
||||
BME280I2C KEYWORD1
|
||||
BME280Spi KEYWORD1
|
||||
begin KEYWORD2
|
||||
temp KEYWORD2
|
||||
pres KEYWORD2
|
||||
hum KEYWORD2
|
||||
read KEYWORD2
|
||||
Altitude KEYWORD2
|
||||
EquivalentSeaLevelPressure KEYWORD2
|
||||
DewPoint KEYWORD2
|
||||
HeatIndex KEYWORD2
|
||||
AbsoluteHumidity KEYWORD2
|
||||
|
After Width: | Height: | Size: 225 B |
9
libdeps/seeed_xiao_esp32c3/BME280/library.properties
Normal file
@ -0,0 +1,9 @@
|
||||
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=*
|
||||
431
libdeps/seeed_xiao_esp32c3/BME280/src/BME280.cpp
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
344
libdeps/seeed_xiao_esp32c3/BME280/src/BME280.h
Normal file
@ -0,0 +1,344 @@
|
||||
/*
|
||||
|
||||
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
|
||||
102
libdeps/seeed_xiao_esp32c3/BME280/src/BME280I2C.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
105
libdeps/seeed_xiao_esp32c3/BME280/src/BME280I2C.h
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
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
|
||||
97
libdeps/seeed_xiao_esp32c3/BME280/src/BME280I2C_BRZO.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
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
|
||||
101
libdeps/seeed_xiao_esp32c3/BME280/src/BME280I2C_BRZO.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
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
|
||||
134
libdeps/seeed_xiao_esp32c3/BME280/src/BME280Spi.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
104
libdeps/seeed_xiao_esp32c3/BME280/src/BME280Spi.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
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
|
||||
152
libdeps/seeed_xiao_esp32c3/BME280/src/BME280SpiSw.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
115
libdeps/seeed_xiao_esp32c3/BME280/src/BME280SpiSw.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
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
|
||||
@ -0,0 +1,217 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
129
libdeps/seeed_xiao_esp32c3/BME280/src/EnvironmentCalculations.h
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
|
||||
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
|
||||
@ -0,0 +1 @@
|
||||
{"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}}
|
||||
498
libdeps/seeed_xiao_esp32c3/GFX Library for Arduino/README.md
Normal file
@ -0,0 +1,498 @@
|
||||
# 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...
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
## 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.
|
||||
@ -0,0 +1,264 @@
|
||||
/*******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,185 @@
|
||||
#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_ */
|
||||
@ -0,0 +1,65 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
}
|
||||
@ -0,0 +1,205 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
/*
|
||||
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()
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,395 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
}
|
||||
@ -0,0 +1,182 @@
|
||||
#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
|
||||
@ -0,0 +1,251 @@
|
||||
#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
|
||||
@ -0,0 +1,312 @@
|
||||
#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
|
||||
@ -0,0 +1,98 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
}
|
||||
@ -0,0 +1,657 @@
|
||||
/*******************************************************************************
|
||||
* 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_ */
|
||||
@ -0,0 +1,244 @@
|
||||
/*******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,355 @@
|
||||
/*******************************************************************************
|
||||
* 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)
|
||||
{
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,259 @@
|
||||
/*******************************************************************************
|
||||
* 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_
|
||||
@ -0,0 +1,189 @@
|
||||
/*******************************************************************************
|
||||
* 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()
|
||||
{
|
||||
}
|
||||
|
After Width: | Height: | Size: 570 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 31 KiB |
@ -0,0 +1,178 @@
|
||||
/*******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
@ -0,0 +1,107 @@
|
||||
/*******************************************************************************
|
||||
* 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_
|
||||
@ -0,0 +1,169 @@
|
||||
/*******************************************************************************
|
||||
* 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()
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,196 @@
|
||||
/*******************************************************************************
|
||||
* 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)
|
||||
|
After Width: | Height: | Size: 630 KiB |
@ -0,0 +1,195 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
*
|
||||
* 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:
|
||||
* 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
|
||||
******************************************************************************/
|
||||
#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 SIMD 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
|
||||
{
|
||||
uint8_t *mjpeg_buf = (uint8_t *)aligned_alloc(16, MJPEG_BUFFER_SIZE);
|
||||
if (!mjpeg_buf)
|
||||
{
|
||||
Serial.println(F("mjpeg_buf malloc failed!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t *output_buf = (uint16_t *)aligned_alloc(16, MJPEG_OUTPUT_SIZE);
|
||||
if (!output_buf)
|
||||
{
|
||||
Serial.println(F("output_buf malloc failed!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("MJPEG start"));
|
||||
|
||||
start_ms = millis();
|
||||
curr_ms = millis();
|
||||
if (!mjpeg.setup(
|
||||
MJPEG_FILENAME, mjpeg_buf,
|
||||
output_buf, MJPEG_OUTPUT_SIZE, true /* useBigEndian */))
|
||||
{
|
||||
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->draw16bitBeRGBBitmap(x, y, output_buf, 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()
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,198 @@
|
||||
/*******************************************************************************
|
||||
* ESP32_JPEG Wrapper Class
|
||||
*
|
||||
* Dependent libraries:
|
||||
* ESP32_JPEG: https://github.com/esp-arduino-libs/ESP32_JPEG.git
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#if defined(ESP32)
|
||||
#include <ESP32_JPEG_Library.h>
|
||||
|
||||
#define READ_BATCH_SIZE 1024
|
||||
|
||||
class MjpegClass
|
||||
{
|
||||
public:
|
||||
bool setup(
|
||||
const char *path, uint8_t *mjpeg_buf,
|
||||
uint16_t *output_buf, size_t output_buf_size, bool useBigEndian)
|
||||
{
|
||||
_input = fopen(path, "r");
|
||||
_mjpeg_buf = mjpeg_buf;
|
||||
_output_buf = (uint8_t *)output_buf;
|
||||
_output_buf_size = output_buf_size;
|
||||
_useBigEndian = useBigEndian;
|
||||
_read = 0;
|
||||
|
||||
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()
|
||||
{
|
||||
// Generate default configuration
|
||||
jpeg_dec_config_t config = {
|
||||
.output_type = JPEG_RAW_TYPE_RGB565_BE,
|
||||
.rotate = JPEG_ROTATE_0D,
|
||||
};
|
||||
// Create jpeg_dec
|
||||
_jpeg_dec = jpeg_dec_open(&config);
|
||||
|
||||
// Create io_callback handle
|
||||
_jpeg_io = (jpeg_dec_io_t *)calloc(1, sizeof(jpeg_dec_io_t));
|
||||
|
||||
// Create out_info handle
|
||||
_out_info = (jpeg_dec_header_info_t *)calloc(1, sizeof(jpeg_dec_header_info_t));
|
||||
|
||||
// Set input buffer and buffer len to io_callback
|
||||
_jpeg_io->inbuf = _mjpeg_buf;
|
||||
_jpeg_io->inbuf_len = _p - _mjpeg_buf;
|
||||
|
||||
jpeg_dec_parse_header(_jpeg_dec, _jpeg_io, _out_info);
|
||||
|
||||
_w = _out_info->width;
|
||||
_h = _out_info->height;
|
||||
|
||||
if ((_w * _h * 2) > _output_buf_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_jpeg_io->outbuf = _output_buf;
|
||||
|
||||
jpeg_dec_process(_jpeg_dec, _jpeg_io);
|
||||
jpeg_dec_close(_jpeg_dec);
|
||||
|
||||
free(_jpeg_io);
|
||||
free(_out_info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int16_t getWidth()
|
||||
{
|
||||
return _w;
|
||||
}
|
||||
|
||||
int16_t getHeight()
|
||||
{
|
||||
return _h;
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
fclose(_input);
|
||||
}
|
||||
|
||||
private:
|
||||
FILE *_input;
|
||||
uint8_t *_mjpeg_buf;
|
||||
uint8_t *_output_buf;
|
||||
size_t _output_buf_size;
|
||||
bool _useBigEndian;
|
||||
|
||||
jpeg_dec_handle_t *_jpeg_dec;
|
||||
jpeg_dec_io_t *_jpeg_io;
|
||||
jpeg_dec_header_info_t *_out_info;
|
||||
int16_t _w = 0, _h = 0;
|
||||
|
||||
uint8_t *_p;
|
||||
int32_t _read;
|
||||
};
|
||||
|
||||
#endif // defined(ESP32)
|
||||
|
After Width: | Height: | Size: 630 KiB |
@ -0,0 +1,246 @@
|
||||
/*******************************************************************************
|
||||
* Motion JPEG Image Viewer
|
||||
* This is a simple Motion JPEG 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
|
||||
* 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 9 earth.mjpeg
|
||||
*
|
||||
* Dependent libraries:
|
||||
* JPEGDEC: https://github.com/bitbank2/JPEGDEC.git
|
||||
*
|
||||
* Setup steps:
|
||||
* 1. Change your LCD parameters in Arduino_GFX setting
|
||||
* 2. Upload Motion 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 MJPEG_FILENAME "/earth.mjpeg"
|
||||
#define MJPEG_BUFFER_SIZE (240 * 240 * 2 / 10) // memory for a single JPEG frame
|
||||
// #define MJPEG_FILENAME "/earth128.mjpeg"
|
||||
// #define MJPEG_BUFFER_SIZE (128 * 128 * 2 / 10) // memory for a single JPEG frame
|
||||
|
||||
/*******************************************************************************
|
||||
* 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 "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;
|
||||
|
||||
// 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);
|
||||
unsigned long start = millis();
|
||||
gfx->draw16bitBeRGBBitmap(pDraw->x, pDraw->y, pDraw->pPixels, pDraw->iWidth, pDraw->iHeight);
|
||||
total_show_video += millis() - start;
|
||||
return 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 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)
|
||||
// Init SPIFLASH
|
||||
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())
|
||||
// if (!SD.begin(SS))
|
||||
// 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))
|
||||
#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
|
||||
{
|
||||
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
|
||||
File mjpegFile = SD.open(MJPEG_FILENAME, "r");
|
||||
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
|
||||
File mjpegFile = LittleFS.open(MJPEG_FILENAME, "r");
|
||||
// File mjpegFile = SD.open(MJPEG_FILENAME, "r");
|
||||
#elif defined(ESP32)
|
||||
// File mjpegFile = FFat.open(MJPEG_FILENAME, "r");
|
||||
File mjpegFile = LittleFS.open(MJPEG_FILENAME, "r");
|
||||
// File mjpegFile = SPIFFS.open(MJPEG_FILENAME, "r");
|
||||
// File mjpegFile = SD.open(MJPEG_FILENAME, "r");
|
||||
// File mjpegFile = SD_MMC.open(MJPEG_FILENAME, "r");
|
||||
#elif defined(ESP8266)
|
||||
File mjpegFile = LittleFS.open(MJPEG_FILENAME, "r");
|
||||
// File mjpegFile = SD.open(MJPEG_FILENAME, "r");
|
||||
#else
|
||||
File mjpegFile = SD.open(MJPEG_FILENAME, FILE_READ);
|
||||
#endif
|
||||
|
||||
if (!mjpegFile || mjpegFile.isDirectory())
|
||||
{
|
||||
Serial.println(F("ERROR: Failed to open " MJPEG_FILENAME " file for reading"));
|
||||
gfx->println(F("ERROR: Failed to open " MJPEG_FILENAME " file for reading"));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *mjpeg_buf = (uint8_t *)malloc(MJPEG_BUFFER_SIZE);
|
||||
if (!mjpeg_buf)
|
||||
{
|
||||
Serial.println(F("mjpeg_buf malloc failed!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("MJPEG start"));
|
||||
|
||||
start_ms = millis();
|
||||
curr_ms = millis();
|
||||
mjpeg.setup(
|
||||
&mjpegFile, mjpeg_buf, jpegDrawCallback, true /* useBigEndian */,
|
||||
0 /* x */, 0 /* y */, gfx->width() /* widthLimit */, gfx->height() /* heightLimit */);
|
||||
|
||||
while (mjpegFile.available() && mjpeg.readMjpegBuf())
|
||||
{
|
||||
// Read video
|
||||
total_read_video += millis() - curr_ms;
|
||||
curr_ms = millis();
|
||||
|
||||
// Play video
|
||||
mjpeg.drawJpg();
|
||||
total_decode_video += millis() - curr_ms;
|
||||
|
||||
curr_ms = millis();
|
||||
total_frames++;
|
||||
}
|
||||
int time_used = millis() - start_ms;
|
||||
Serial.println(F("MJPEG end"));
|
||||
mjpegFile.close();
|
||||
float fps = 1000.0 * total_frames / time_used;
|
||||
total_decode_video -= total_show_video;
|
||||
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("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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,203 @@
|
||||
/*******************************************************************************
|
||||
* JPEGDEC Wrapper Class
|
||||
*
|
||||
* Dependent libraries:
|
||||
* JPEGDEC: https://github.com/bitbank2/JPEGDEC.git
|
||||
******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <JPEGDEC.h>
|
||||
|
||||
#define READ_BATCH_SIZE 1024
|
||||
|
||||
/* 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
|
||||
|
||||
class MjpegClass
|
||||
{
|
||||
public:
|
||||
bool setup(
|
||||
Stream *input, uint8_t *mjpeg_buf, JPEG_DRAW_CALLBACK *pfnDraw, bool useBigEndian,
|
||||
int x, int y, int widthLimit, int heightLimit)
|
||||
{
|
||||
_input = input;
|
||||
_mjpeg_buf = mjpeg_buf;
|
||||
_pfnDraw = pfnDraw;
|
||||
_useBigEndian = useBigEndian;
|
||||
_x = x;
|
||||
_y = y;
|
||||
_widthLimit = widthLimit;
|
||||
_heightLimit = heightLimit;
|
||||
_read = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readMjpegBuf()
|
||||
{
|
||||
if (_read == 0)
|
||||
{
|
||||
// _mjpeg_buf empty
|
||||
_read = _input->readBytes(_mjpeg_buf, READ_BATCH_SIZE);
|
||||
}
|
||||
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 = _input->readBytes(_mjpeg_buf + 1, READ_BATCH_SIZE) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_read = _input->readBytes(_mjpeg_buf, READ_BATCH_SIZE);
|
||||
}
|
||||
_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 = _input->readBytes(_p, READ_BATCH_SIZE);
|
||||
}
|
||||
|
||||
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 += _input->readBytes(_p + _read, READ_BATCH_SIZE);
|
||||
// Serial.printf("_read: %d\n", _read - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (found_FFD9)
|
||||
{
|
||||
++_p;
|
||||
--_read;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool drawJpg()
|
||||
{
|
||||
_jpeg.openRAM(_mjpeg_buf, _p - _mjpeg_buf, _pfnDraw);
|
||||
if (_scale == -1)
|
||||
{
|
||||
// scale to fit height
|
||||
int iMaxMCUs;
|
||||
int w = _jpeg.getWidth();
|
||||
int h = _jpeg.getHeight();
|
||||
float ratio = (float)h / _heightLimit;
|
||||
if (ratio <= 1)
|
||||
{
|
||||
_scale = 0;
|
||||
iMaxMCUs = _widthLimit / 16;
|
||||
}
|
||||
else if (ratio <= 2)
|
||||
{
|
||||
_scale = JPEG_SCALE_HALF;
|
||||
iMaxMCUs = _widthLimit / 8;
|
||||
w /= 2;
|
||||
h /= 2;
|
||||
}
|
||||
else if (ratio <= 4)
|
||||
{
|
||||
_scale = JPEG_SCALE_QUARTER;
|
||||
iMaxMCUs = _widthLimit / 4;
|
||||
w /= 4;
|
||||
h /= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
_scale = JPEG_SCALE_EIGHTH;
|
||||
iMaxMCUs = _widthLimit / 2;
|
||||
w /= 8;
|
||||
h /= 8;
|
||||
}
|
||||
_jpeg.setMaxOutputSize(iMaxMCUs);
|
||||
_x = (w > _widthLimit) ? 0 : ((_widthLimit - w) / 2);
|
||||
_y = (_heightLimit - h) / 2;
|
||||
}
|
||||
if (_useBigEndian)
|
||||
{
|
||||
_jpeg.setPixelType(RGB565_BIG_ENDIAN);
|
||||
}
|
||||
_jpeg.decode(_x, _y, _scale);
|
||||
_jpeg.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Stream *_input;
|
||||
uint8_t *_mjpeg_buf;
|
||||
JPEG_DRAW_CALLBACK *_pfnDraw;
|
||||
bool _useBigEndian;
|
||||
int _x;
|
||||
int _y;
|
||||
int _widthLimit;
|
||||
int _heightLimit;
|
||||
int _scale = -1;
|
||||
|
||||
JPEGDEC _jpeg;
|
||||
|
||||
uint8_t *_p;
|
||||
int32_t _read;
|
||||
};
|
||||
|
After Width: | Height: | Size: 630 KiB |
|
After Width: | Height: | Size: 239 KiB |
@ -0,0 +1,550 @@
|
||||
/* GIMP RGB C-Source image dump (Arduino_UNO_Rev3_Ok.c) */
|
||||
|
||||
/* 1. Comment out exported struct */
|
||||
// static const struct {
|
||||
// unsigned int width;
|
||||
// unsigned int height;
|
||||
// unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||
// unsigned char pixel_data[100 * 71 * 2 + 1];
|
||||
// } gimp_image = {
|
||||
// 100, 71, 2,
|
||||
|
||||
/* 2. Add PROGMEM data declaration */
|
||||
/* 3. Fix the file tail */
|
||||
#ifdef __AVR__
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <pgmspace.h>
|
||||
#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
|
||||
static const unsigned char Arduino_UNO_Rev3_Ok[] PROGMEM =
|
||||
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\367<\337\034\327\034\327\034\327<\337<\327<\337<\337<\327<\327"
|
||||
"<\337<\327<\327<\327\034\327<\327<\327=\327\\\327\\\317<\327\\\327<\337<\337"
|
||||
"<\337<\337<\337<\337<\337<\337<\327<\337\236\367\277\367\277\367=\337<\337"
|
||||
"<\337<\337<\337<\337<\337<\337<\337\034\337<\337<\337<\327<\327<\327<\337"
|
||||
"\\\337<\327<\327<\327]\337\\\327\\\337]\327<\327\\\327<\327<\327=\327<\327"
|
||||
"<\327]\327<\327\\\327<\327=\327=\327<\327=\327\\\327<\327<\327]\327=\327"
|
||||
"=\327<\327<\327\\\327]\327\337\367\377\367\337\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377"
|
||||
"\232\276\267\215X\246\326\225\071\276z\326z\316z\316\232\316z\316z\306\071"
|
||||
"\306v\235u\225\370\235\327\205\267\215VeP\024PD\222\\P$NSnk\257s\216k\217"
|
||||
"k\317s\216k\216k\317s\217knk\257s\320{\216kNc\217s\217k\217s\257s\216kNk"
|
||||
"\257s\257s\217k\320s\257s\216k\317snkNcnk\216knknk\314R\015[Nc\314Z\015[-c"
|
||||
"\015[-c-[Nc\314R\254R-c\015[-c\015[\015[,[\014[-[\014[\015[\014[-[-[-[\014S\314R\354"
|
||||
"Rr\224\377\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\337\377\027\226\263l\363\234\367\305"
|
||||
"Y\306\030\276\031\306\071\306z\316z\316\370\275v\245\323\224\027\306\323\234"
|
||||
"\321Lq\004\217\013\222t\231\306y\316u\235\354ZD!E)Mk(Bf)jJ\014c%)E)\216sE)E)"
|
||||
"\253ZjR%!\307\071\014c\344\040\004!\313Z\247\071E)\010BjR%!\004!\314Z\004!%)jJ)B$!\206"
|
||||
")\015c\317sMc\303\030\344\030\253R\206\061\004!\350\071jJ\004!\344\030\253RE!\004\031"
|
||||
"JJ\310\071$\031\207\061\313Z\004\031\004\031\213R\206\061%)\010BIJ\344\030\004!\014S\272"
|
||||
"\276\337\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\337\377\273\276\323d\267\255Q|\330\265\273\316"
|
||||
"y\306y\316y\316\030\276\370\275\327\265\360\203T\225\025\215Q,q\004-\013Q\204"
|
||||
"\024\245\327\275\267\275\216kIJ)Jnk\253ZIJ\314ZnkiJ\212R\257s)B\313Z\015c\314"
|
||||
"Z)B\010BMk\350\071\010BnkIJ\010B\213R\014c\010B\350\071nk\206\061\347\071\313ZJJ\206"
|
||||
"\061\247\071\217s\360{-c\247\061\307\071\314Z\350\071\206\061IJ\212Rf\061E!\014["
|
||||
"E!\206\061\213R\351Af)\206\061\253ZE)\243\030\254ZF)\004!\350\071)J\344\040\303"
|
||||
"\020\015S\071\266\276\367\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\337\377\277\377\232\276\064\205\367\235u\225"
|
||||
"\031\276\334\336y\316\271\326\271\326X\316\030\276z\306\317sl;P,q\004\222\004m"
|
||||
"\023\223\214Z\316\374\336\333\336\353Z-c\354ZIB\212RMk\313Z\212J\317k\320"
|
||||
"sjB\223\224\324\214\324\224\253R\014[,[\010\062M[mc\212J\313RM[\014[\212J\256"
|
||||
"cm[jJ\354RM[\212J\313R\354R\313J\350\061(\062):\353R\313RI:\313JM[\253BjBM"
|
||||
"[\354RJ:\015S\014[iB\252JM[\353RiB\014[\353RiB\014S\257c\252J\313J\360k\014S\253"
|
||||
"B\367\245\236\367\337\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\277\377\232\276u\215\273\336\367\275\030"
|
||||
"\276\373\326y\316\272\326\332\336\231\326\370\265Y\306nk\323d\262,\221\014"
|
||||
"r\024\360\033\222d\273\316=\337\266\235(\"\202\010a\010a\000a\010a\000a\010\343\000E"
|
||||
"\011E\011e\021\217k\364\214\324\204\020l\216[\216[\257[\216cn[\257c\257[n[\256"
|
||||
"[\257c\216[\216[\216[n[n[\216[\216[nSnS\257c\360c\256[\216[mS\256[nSmS\353"
|
||||
":\354B\313:\353:\014C\313:\253B\354Z\353B\313BMKMK\354B\014K\353:\013;\014;M"
|
||||
"KMK,CMK\253\"\326\235^\367\276\367\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\337\377\276\377\232\276\064\205\327\245v"
|
||||
"\245\071\276=\347X\306\231\326\271\336\266\275\327\275\233\316\257k\017\024"
|
||||
"r\024\317\033\327\245\367\245r\\\260[\061\204\320[\317[HJ\206\061a\010$)\206\061"
|
||||
"E)e\031\246\011\306\011\206\021\324\214\330\245\330\245\353:i\"\353:(\002\212\""
|
||||
"i\"\211\"(\002\007\002\251\"\010\002\216S\014;'\002\252\062\013C'\002H\032\313:i*\007\002\007\002"
|
||||
"\007\002\212\062\347\011\007\002I\"\353B\347\001(\032i\062(\032\347\001I*\312:\245\011H*\312"
|
||||
":\347\001(\032I*\212*\347\001\346\001\211\"\007\002\353\062\216[\007\002\353\012\226\235]"
|
||||
"\357\276\367\337\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\277\377\333\306\267\235\070\256\024\215\232\316\034\337"
|
||||
"\333\326\327\275U\255\266\265Z\316\374\326\320{\360k\065\205\353\002\070\306"
|
||||
"\030\316\263|\260[r\224Nc\314J\262\234\307\071\347\071ns\257{\206\061E\021nK\263"
|
||||
"l\307\011\370\255r|\267\235-;\226\215\065\205i\022\364t\323t\061d\360S\222t\323"
|
||||
"t\253\"\327\235v\215I\002\364\204\226\225M;\020d\327\225\222li\002I\002H\012U\205"
|
||||
"Q\\H\002\263|\327\235\252*\020\\\263|\060\\I\022\024\205\262|'\012\222t\064\205\212"
|
||||
"*qd\020d\322t\313\062\323t\364|\350\001U\205u\225\353B\353\022\226\235=\347\236"
|
||||
"\367\337\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\337\377\277\377Y\246\222\\\327\265\267\275\373\336\034\337\233\316\232"
|
||||
"\316z\316z\306\071\306\232\316u\255x\316\064\235\253\012r\214\263\224\216KI"
|
||||
"\062\343\030\344\040)J\307\071\303\030\247\061E)%)\343\020H*mKRl\212\032z\276\267"
|
||||
"\235{\276\357C\013\003\360C,\013\354\002,\033\357;\014\003\353\002\317C,\003\216\063\360"
|
||||
"K,\003,\023\320C,\003\354\002\013\003\013\003\013\003\013\003\013\003\013\013\353\002\353\002\312\002\317"
|
||||
"C\353\002\353\002\216C\312\002\353\002\252\012\353\032\312\002i\002\317C\353\002\312\002\353"
|
||||
"\012\353\012\313\002\352\012\353\012\013\003\353\022\215CMCM+\225\235\034\347\236\367"
|
||||
"\337\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\337\377\336\377\027\216\060\034\030\246\322tq|\024\235\024\235\223\214\262\224"
|
||||
"\263\224\364\234\024\235\317sU\235\364\204n+.S\354Z\213\"\252:E)%!jR\307\071"
|
||||
"f))B\010BE)\004!\313B\222t\330\235\353\032\374\316\327\245\274\306qL\030\216\370"
|
||||
"\225\315\023\226}\267\205\363\\\363T\226\215Uu\017$\027\206\327\215\215\003\215"
|
||||
"\003\323T\256\003\216\003\216\003\216\003\216\003\216\003\216\003\215\003\215\003\215\003m\013\222"
|
||||
"Ln\003m\003\323\\L\003m\003M\003L\003M\003\014\003\323\\M\003m\003m\003m\003\216\023\330\225\364lm"
|
||||
"\003r\\\226\205\256\033m\013v\235<\347~\357\337\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\336\377\276\367\030\216r\004\357\013\222"
|
||||
"Ty\306X\306\023\215\262t\263\224\364\224\024\235\360{\320c\015\003\015\013\360\063"
|
||||
"V\235\327\255\021\\M[\060\204IJ\015c\024\255\313R\253R\360\203\020\204\010:I\032"
|
||||
"\023m\327\215M\023=\317\232\276\374\316QL\357\013P\004\060\014\060\004\060\014P\004P\004"
|
||||
"u]\357\003\060\004\263L\263D\020\004/\004\017\014/\004\020\004\017\004\017\004\017\004\017\004\360\003\357"
|
||||
"\013\357\003\017\004\017\004\357\003\357\003\357\003\357\003\357\003\357\003\317\003\316\003\317\003"
|
||||
"\256\003\216\013\317\003\357\003\357\003\357\003\357\013\262T\017,\017\004P\064Tm\357\003\257"
|
||||
"\013\226\225\034\347\236\367\277\367\236\367]\357]\357]\357]\357]\357]\357"
|
||||
"]\357<\357=\347\327\225\322T\322Tz\266\027\316W\316\333\316\027\246U\255\030"
|
||||
"\306z\316\323\244\323|n\003N\003\216#U\245\326\275\257S\360c\350\071\314Z-[ns"
|
||||
"\252R\314ZNk\212R\212J\354\"\323d\232\246\061$\323dU\205\266\255T\235\023\225"
|
||||
"qdT]\064]\064]\024e\023]\225m\363\\\064]\064e\064e\024]\024]\023]\023]\023]\363\\\363"
|
||||
"\\\363d\363\\\023e\222<P\004\061\004P\004P\004P\004P\004P\004\060\004\060\004\060\004\017\004\060\004\020"
|
||||
"\004\060\004\060\004P\004Q\004P\004\060\004\070\216\226u\060\014\064]\070\236P\004\317\023\225\235"
|
||||
"\034\347~\357\276\367\226\275u\265\030\316\232\336\332\346\373\346\034\357\034"
|
||||
"\357\033\357<\367<\357<\367\\\367<\357\\\367}\357<\367]\357<\357<\357<\357"
|
||||
"\231\326\357S\360\033N\003\216#\232\306\272\326\364|\257S\212B\253B)*-[\212"
|
||||
"J\247!\257cIB\010:\313\002\257#\020\064\322\024\262\034\020\064\226\245q\234\326\265"
|
||||
"\334\336\272\266\333\316\272\266\273\276=\317\272\266y\256\034\317\373\276"
|
||||
"\333\316\237\357~\347=\337\236\347\272\276y\266\333\276y\256\272\276\374"
|
||||
"\326\030\226\262\004\221\004\222\004q\004r\004q\004q\004q\004q\004p\004P\004P\004P\004p\004q\004\221\004\221"
|
||||
"\004\221\004P\004\070\206\064M\261\004\225m\272\246\221\004\360\013\226\225\035\347~\357"
|
||||
"\277\367U\255\322\244\326\305\027\306X\316\272\336\272\336\333\336\373\346"
|
||||
"\373\346\373\346\\\357<\357\034\347]\357]\357<\357\034\347\033\347\034\347<\357"
|
||||
"\367\305+\063M\033\260\033\216#\357S\060T\222L\360;(\012\010\012\060T\020l\357{\256"
|
||||
"K\320k\020t\216[\257;n\003\061,\322\034\363\014\222$\222T\322d\236\347\236\357"
|
||||
"\272\246\373\276\272\246\333\256\333\266\273\256\034\277\374\276\333\256z"
|
||||
"\246~\337\236\347\236\347\236\347\333\276]\307y\246\034\277\034\317\236\337"
|
||||
"\272\246\266]\226]\225]\225]\225]\225]\225]\226]\226]\225]u]v]\226]\226]"
|
||||
"\226]\226]\266]\226]\226]\266e\226]\266]\266e\327m\221\024\020\014\266\225\035"
|
||||
"\357~\357\276\367U\255\064\255\326\305\027\306y\326\231\326\332\336\333\346"
|
||||
"\332\336\333\336<\357\034\347]\357\\\357<\357<\357\373\346\033\347\373\346"
|
||||
"<\357\034\347\070\306i:\010\002\216#\323lrt\222t\320;N\013\014\023n#Rd\272\326\373"
|
||||
"\326n\063V\235\033\337\064\215\061L\320#\061$\064M\023-RdX\316\371\336x\306V\235"
|
||||
"\323D\323\064\363\064\322\064\322\064\323\064\323\064\322\064\322\064\322\064\322"
|
||||
",\322,\322,\323\064\263,\263,\263\064\262\064\262\064\222\064\262,\262,\262\064"
|
||||
"\262,\262,\222,\222,\262,\262,\262,\222,\221,\222,\221,\262,\262,\262,\322"
|
||||
",\322,\322,\262,\262,\222\064\262,\262,q\014\360\013\266\225=\357~\357\276\367"
|
||||
"U\265\064\255\326\305\030\316X\316\272\336\231\326\232\336\373\346\373\346"
|
||||
"\034\347\034\347\034\347<\357\373\346\373\346\373\346\373\346\373\346<\357\373"
|
||||
"\346\027\306\252B\212\022j\012\221\214\023\255\063\245\222lrD\257#\317\033\262"
|
||||
"T\070\276\071\276n\023\364\204\034\337\263tqT\021,\062$\226}\030~\222l\271\326\270"
|
||||
"\336W\316v\235\317\063\221T\020\004\262\004\322\004\322\004\262\004\262\014\262\004\262"
|
||||
"\004\262\004\262\004\222\014\262\004\261\004\262\004\261\004\221\004\221\004T]\327\205\363D"
|
||||
"q\004q\004\221\004p\004p\004q\004\221\004q\004q\004q\004q\004q\004q\004q\004\222\004q\004\221\004\221\004\222"
|
||||
"\004\222\004\222\004\222\004\221\004\221\004\020\014\226\225<\347}\357\276\367U\265\064"
|
||||
"\255\225\275\326\305\030\316y\326y\326\232\336\272\336\034\347\033\347<\357"
|
||||
"<\357\034\347\034\347<\357\333\336\272\336\373\346]\357\\\357\326\305i\062\010"
|
||||
"\012,\023qd\257;\323l\223T\217\003\360#\320#\025]\060<\257#\321#QD\257#QT\360c"
|
||||
"\357#\021$\262T\021<\257\033rd\313B\216[\360Cq<\061l\317\023\323\004\222\014\262"
|
||||
"\014\327}y\236\071\236U]\262\004\262\004\322\004\221\004ueY\236\071\246\266m\220\004\326"
|
||||
"u\272\256\266m\221\004q\004q\004q\004q\004q\004\221\004q\004q\004q\004q\004q\004q\004\221\004\221\004\221"
|
||||
"\004\221\004\221\004\221\004\221\004\221\004\221\004q\004Q$\017\014u\215<\347~\357\236\367"
|
||||
"T\255\064\265\266\305\027\316\070\316\231\326\373\346\272\336\332\336\033\347"
|
||||
"\373\346\373\346\373\346\333\336<\357\034\347\373\346\333\336\373\346\034\347"
|
||||
"<\357u\265\357s\350\011\252\012\257;\216\063\020L\021\064\022$\223T\065u\263d\231"
|
||||
"\276\373\316\061<\267\235\374\336\064\205\323\\\020,\021,\020DrLq,\262tIR\316"
|
||||
"srTq\064\360\063\061\064P\014\023=<\307\236\357}\337\236\337\237\347\272\256\262"
|
||||
"\034\262\064\273\276\237\347~\337}\337\277\347\374\306\266u\370\205\225]q\004"
|
||||
"q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004\222\004\222\004\222\004\221\004\222\004"
|
||||
"\221\004\261\004\221\024\363\\\017$\263\\=\347]\367\236\357U\265u\265\367\305\027"
|
||||
"\316\070\316\070\316\272\336\232\336\272\336\373\346\373\346\333\336<\357\034"
|
||||
"\347\373\346\373\346\373\346\373\346\333\336\373\346<\357\266\275q\204I\032"
|
||||
"(\012\021|\222\214\226\255\256C\061,\263\\\064u\263d\374\326\236\357\357\063\367"
|
||||
"\245\236\367U\215rL\021,\062,\257\003\257\003Q,\221|\216\203\316{rTrD\222D\323"
|
||||
"T\360#\333\306~\337\225m\222$\263\064\070\226\236\347\272\256\333\276~\337"
|
||||
"\027\216\221,q$\227\205\236\337z\266q\014q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004"
|
||||
"q\004q\004q\004\221\004q\004\221\004\261\004\261\004\262\004\262\004\262\004\262\004\221\004\221\004"
|
||||
"Q\014\357\003\327\215~\357\275\367T\255U\265\326\305\367\305\027\306\231\326"
|
||||
"\231\326\231\326y\326\232\336\231\326\232\336\373\346\333\346\333\336\333"
|
||||
"\346\333\346\272\336\373\346\373\346\033\347\266\275\262\204i\032(\012\320c"
|
||||
"\353J\257k\217;R$\363d\026\205\065e\024m\065u\263\\\323dU\215\363d\222D\020,\061"
|
||||
"$\257\013\260\003\317\023\262|\014k\316kQTr<sT\060T\222T\276\347\027\206\222\024"
|
||||
"\221$\221\034\221\004\030\226\236\357\236\357\326}\221\014\367\215\266\205\261"
|
||||
"\004\071\236~\337\222,q\004\221\004q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004q\004\222\004"
|
||||
"\221\004\221\004\222\004\221\004\262\004\262\004\262\004\261\004\222\004q\004P\004\360\013\030\216"
|
||||
"\236\367T\255\064\265\266\275\367\305\027\306\070\316y\326\070\316Y\326y\326"
|
||||
"\272\336\231\326\272\336\333\336\272\336\232\336\373\346\373\346\333\336"
|
||||
"\232\326\332\336\266\275\322\214\010\022m\063\357c\060t\322\224qT\061,\317#\061"
|
||||
"$\217\033.\033M#\317;\257C\357;\257;\257#\020,\021$\262L\364T\222<\364|\354R"
|
||||
"Q\204\024U\024U\060<\222T\364t\236\357Ue\266e~\277~\307\023E\221$}\337]\327\221"
|
||||
"\034ve~\327~\327\024M\266}~\357\323\064q\004\221\004q\004q\004q\004q\004q\004\221\004q\004q\004"
|
||||
"q\004q\004q\004q\004q\014\221\014P\004P\004\222\004\221\004\222\004\262\004\262\004\262\004q\004\020\004"
|
||||
"\317\003\360\013\060\024Y\256\064\255T\265\326\305\027\316Y\326\070\316Y\326Y\326"
|
||||
"\070\316\070\316X\316Y\326\232\336\070\316y\326\332\336\332\336Y\316\232\336"
|
||||
"\272\336\272\336u\265\363\234I\032\212\012\313:\020\204q\214\256+R,\360\033\021"
|
||||
"$rD\260SN[\360k\317k\360s\217c\354\"\021\064\324d\363t\262d\020L\063\215S\235"
|
||||
"\064\235qd\360CPT\062\064QD\236\347Y\236\262\004q\004q\004\261\024\272\256~\347~\357"
|
||||
"Y\236\221\004\225uUm\221\004\272\256^\337\221\024\221\004q\004\221\004q\004q\004q\004q\004q"
|
||||
"\004q\004q\004q\004q\004\221\004q\014qT\063\235\264\235\063\205\222d\064U\064U\363D\322\004"
|
||||
"\222\004\317\003-#-\063L#\317\013\226}U\265\024\255\266\275\070\316\070\316\030\316"
|
||||
"\030\316Y\326\070\316\030\316\027\316y\326X\316\231\326\231\326y\326\231\326"
|
||||
"Y\316y\326z\326z\336u\265\215k\307\001\253\022\312*\262\214\262\234\256+\061"
|
||||
",\021,\021$\360KNcNcMcNcNc.c\217c\360;\030\246\065\205Y\246\226\225\331\336\267"
|
||||
"\366\267\336\065\235\263TrD\061<R\064z\266\276\337\071\236\064UTm\333\276~\357"
|
||||
"\067\216y\236~\357\272\266Te\064]z\256\236\337\070\226q\004q\004q\004q\004q\004Q\004q\004"
|
||||
"q\004q\004\221\004q\004q\004q\004\222\004\020\024V\225\227\346\327\346w\326\322\224Y\246"
|
||||
"\034\277\232\236\221\004\061\014\313\"\014S\317{\357s\257;Uu\064\255\024\255\266"
|
||||
"\305\367\305\326\305\266\275\030\316\367\305\326\305\367\305\266\275\027\316"
|
||||
"X\326\027\306X\316\070\316\272\336\232\326y\326y\326\070\316\064\255H:\307\001"
|
||||
"\253\022\317S\360\203\263\234m+R,r\064\061$\323t\015c-c-c.c.cN[NcqD\263T\323"
|
||||
"d\223L\320C\020d\356k\017tQT\263L\222T\060\\\021\034\322$\232\256\236\347\276"
|
||||
"\347\237\357\236\327\367\205r\014\222\014\030\226~\337\276\347\236\357~\347"
|
||||
"Y\236\221\014\221\004q\004p\004q\004q\004p\004p\004q\004q\004q\004q\004q\004\221\004\221\004\020$\061T\316"
|
||||
"k\356cMKr\\\362<\322\064\262,\221\004\357\013\014C\064\255y\306\070\316\262|Tu\064"
|
||||
"\255\323\244u\265u\275\327\305\266\305\226\275u\265\266\305\225\275\266\305"
|
||||
"\367\305\027\316\070\316\030\316\070\316\030\316\070\316\027\316\367\305\070\316"
|
||||
"T\265hB\307\001J\002\313\032mC\317Sq<\361#r\064Q<\064\215-c-c-c.k.c\015c-[RL\365"
|
||||
"d\262T\020<rTU\215t\245t\225V\205\061<\061<\323d\363\064\262\014\262\014\023=\226"
|
||||
"u\226e\222$\262\014\261\004\221\004p\014q,um\225m\262\064q\004p\014q\004p\004p\004P\004q\004"
|
||||
"q\004q\004\221\004q\004Q\014q\004\221\004\221\004q\014\360\023\061,U\225IBR\204\357+\061\024"
|
||||
"Q\004\221\014\261\004\360\013rt\273\326=\347=\357U\225\064uT\265Q\224\064\255\323"
|
||||
"\244\363\254T\265\363\244\064\255\064\265u\275T\265T\265\226\275\327\275\367"
|
||||
"\305\030\316\366\305\070\316\027\316\327\305u\265\322\244\013S\014\063\216K\061"
|
||||
"t\324\214\024\205\257\063\061\064\222L\065e\024\225Nc-c-c.c.c.cM[QT\233\266Y\266"
|
||||
"\232\256u\225\031\347\070\357\331\346u\235\357K\221dr<P$\322T\030\226U}z\256"
|
||||
"U}\231\256\064}u\205\266\215\226\215z\256\266\215\024}V\205X\246\065}\020,\020"
|
||||
"$\357#\357#\020$\020$\020$\020$\360#R<\360\033\360\013\060\014\060\014\217\023\061<\263"
|
||||
"\214+c\060t\360;\061<\021<\257\023Q\004\061\014M#Y\276]\347\232\306\017<UmT\265\017"
|
||||
"\214\060\224p\234\017\214q\234P\224P\224p\224\321\234p\224\322\244\023\255\363"
|
||||
"\244\064\255\065\265\225\275T\265\063\255\023\255\322\244\356\213\312:\253\022"
|
||||
"L#U\225M[U\245\317K\317\033\364L\323T\262tNcNk-cMkMk.cMcr\\\364d\364d\364"
|
||||
"\\\323d\023}\362|\322\204\323l\223D\222D\263D\323\\\030\256\033\317\030\256\333"
|
||||
"\316\071\266\267\245\232\276\031\266Y\266qt\370\255\070\266\232\306\232\306"
|
||||
"\225\225Y\266\222TrTrT\222TrT\222LqD\360\063\020\064\257+\257+\061\064Q<Q<\062"
|
||||
"<\060D\323\214+c\020|\061D\061<\317;\317#\257\013P\004\020\014\256\013\360\063\223D"
|
||||
"\221\064\025u\367\305\367\305\367\305\367\305\367\305\327\305\327\305\367\305"
|
||||
"\367\305\327\315\027\276\267\265\266\265\266\275\326\305\326\305\326\305\327"
|
||||
"\275\367\265\327\265\326\265\323\234\014Kj\012\353\012\061\\\223T\364\\\364T"
|
||||
"\223<r<\263L\323t-c.c.c.c.c-cM[\061LQ<Q<\323T\263L\263Tq\\qT\263L\262L\222"
|
||||
"LqDsTZ\256Y\256y\256X\256\027\236\373\276\266\225\232\266Y\256\027\236\373"
|
||||
"\306Y\246v\235\327\255\273\306\267\215\222TrTrT\222TrL\222L\360\063\217\033"
|
||||
"\360\063Q<\360\063\020\064\020<\020\064\061\064\020<\323\214\307\071\020|\317+\317;\060"
|
||||
"\\\015\013\020\064\360;Uu\363d\364l\266m\316\013\025u\377\377\277\367\236\367<"
|
||||
"\347\272\326\232\326y\316\071\306\030\276\267\275pdi\002\306\001\216khR\220\234"
|
||||
"\315{\247\001f\001\206\001\206\001\306\001\347\001\212\012m\023\357C\020<\061<r<r<\020,\262"
|
||||
"D\222LnS\317k\020tL[,[,SmK\323T\263T\223DQ\064\061D\363|\022\235\262\214\060T"
|
||||
"\221\\\221D\323D\060<\017<\317#\216\023\256\023\256\013\256\023\357\033\317\023\257"
|
||||
"\023\216\023\215\003\256\013/\014\017,/\034\060\034P\024P\024P\024P\024P\024P\024P\024\256"
|
||||
"\023\361;\323<P\034Q,R\064\317#\020D\060\064r\\\357K\256C\221$\060\034\217\033\025"
|
||||
"U\316\033\215\033rdQdql\262\\\356\013\025m\377\377\337\377\337\377~\367\034\347"
|
||||
"\373\336\333\336y\316\070\306\327\305Pd\211\012H\002P\204\221\224\326\305\020"
|
||||
"|\307\001\347\001\347\001\007\002\350\001(\002-#\013\013\216K\317CQ\064q,\020,\262$q\014\222"
|
||||
"\004\317#\316+\317\063\060L\060T\060T\061TQLQ<Q\064Q$rD\367\245o\214P\214\322d\322"
|
||||
"\\\363$\360\023\317K\061d\021<\061LrLrTQLQLrLQLQLqD\021Dn+\256S/\064\060\004\060\004"
|
||||
"P\004P\004P\004P\004\060\004P\004Q\034\363\064p\004q\004P\004\060\004\256\003\360S\256;\061<\020<r<Q"
|
||||
"\034q\014\216\023q,j*\013S\313J\314J\021|Mc\216\063\024m\377\377\377\377\337\377"
|
||||
"\276\367]\357<\347\034\347\272\326Y\316\367\275Pl\252\002H\002(\012\060|\017t\010"
|
||||
"\032\347\001\347\001\010\002(\002\010\002i\012\313\022\317[\221\214\222\214Q\\UE\363T\261"
|
||||
"Tq\\\357;\060T\216\063\223d\223dQT\263l\364t\222T\360#\361#\061D\020\064\264\204"
|
||||
"O|q|\020D\021\034\360\023QL\231\276\273\306\273\306\333\306\334\326\374\316\333"
|
||||
"\326\333\316\374\316\374\316\070\246\065u\364l\324l\323d\063]UUT]\061\014\060\004"
|
||||
"\060\004P\004\060\004P\004P\004P\004P\004Q\004P\004P\004\060\014\360+\262DP\034\360C\225\215\065\215"
|
||||
"\257+\217#\020$\206!\252R\014c)B\354Z\020\204i\032\024u\377\377\377\377\377\377"
|
||||
"\337\377\276\367}\357<\347\373\336y\316\030\306ql\353\012\252\022\215S\020t\357"
|
||||
"s\256c,K\353\032\353\012,\033,\033\013\023\014\023\323\214\063\245\022\245\323|\263"
|
||||
"\024\266\235\071\306\232\326\060|\030\276\222\214\363\214V\255\323\204\027\306"
|
||||
"\231\326\060|\060<\357\033\317KpT\367\255\061\245T\255\360[\222d\357+\320C^\357"
|
||||
"~\347\374\336\374\326\233\316=\327=\347Z\306\375\336~\347\330\255\060T\226"
|
||||
"\215qT\222d\364t\357\023\064MP\014\355#\017\024\060\004P\004\060\004P\004P\004P\004P\004\060\004"
|
||||
"\060\004P\004\060\004\060\004P\004\061d\272\326\027\306\261\\Q$\017\024\206!E)\307\071jJ\212"
|
||||
"R$!\212\"\364t\377\377\377\377\377\377\377\377\337\377\276\367}\357\034\347"
|
||||
"\232\326\071\306\262lM\033\353\032\366\275\026\316R\275\024\316Ns++,C,\003,\003m\013"
|
||||
"\217+\317;q<\263D\024=\023\015\064u\221d\216S\060d\363t\222l\262d\222l\060T\317"
|
||||
"[\060L\364t\360+\317#O\013n\033\065\215\223d\020<\256#r\\\220#-\023\237\357^\347"
|
||||
"Y\276\367\245\226\225u\225\273\276z\256\070\236^\347Y\236\023m\071\256\327\225"
|
||||
"Q\\y\266\216\033\262\\P\014\017D\060,\060\004P\004\060\004P\004P\004P\004\060\004\060\004P\004\060\004"
|
||||
"\060\004\060\004P\004\360S\024\245U\255\317Kn#Q$\247\031e\061\307\071\253R\010B\205)\252"
|
||||
"*\024m\377\377\377\377\377\377\377\377\377\377\337\377\276\367]\357\333\336"
|
||||
"\232\326\363t\216\033m+\226\326V\377\067\377x\377\251Z\316\033\020\064\353*\256"
|
||||
"C\023m\357+\257\033\322\024\363\004\023\005\023%\070\256\231\316\231\326\271\316\231"
|
||||
"\326\231\306X\306\231\306y\316y\316\070\266\323d\316\033\222\\Y\256\023u<\337"
|
||||
"\024\225X\266\071\256n#-\003M\033\277\347^\347\266\225\071\266\031\266V\245\374"
|
||||
"\316\327\225z\256^\347\070\236\363T\070\226\267\205\364ty\256N#\222d\360\023"
|
||||
"\017\014\060\004P\004\060\004\060\004P\004\060\004\060\004\060\004\060\004\060\004\060\004\060\004\060\004P\004QD"
|
||||
"r\204\222\214\017$\216\013\017$F!\350A,cJJ-c\317{i\"\364t\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\276\367}\357\034\347\333\336\064}\316\023\357\023"
|
||||
"\214k\356\213\213s\254\203lK\357\033l\033jJ\357{\266\245\357+\317\033\323\024"
|
||||
"\363\014\064\005\366\245\231\326\034\357\373\346\333\346\332\346\332\336\373\346"
|
||||
"\373\346\373\346\332\336X\326U\255Pd\262t\327\225\221l\035\347\363\244\\\357"
|
||||
"\060lPD\263LQL~\357^\347\236\357\237\357~\347\236\357\236\347\236\347~\347"
|
||||
"~\347\071\236q,q,q\064\257;\360C\020D\263d\216+\216\033\216\023/\014\060\004\060\004"
|
||||
"P\004\060\004P\004\060\004/\004\060\004\060\004\060\004\060\004\060\004\215\023\011B\010:\216\033\216\023"
|
||||
"\017$\207)e)\010BjRJJIJ\212*\364t\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\337\377\236\367]\357<\347u\205\020\024q\024o\204\315\203\021\255N\224\013"
|
||||
"#\323l\266\255*J\354J\263\\\360\063\222\034\362\004\064\005\023%\363\244\034\347\272"
|
||||
"\336\272\336\231\326\272\336\272\336\272\336\272\336\332\336\232\336\271"
|
||||
"\316\030\306\317s\017\064-\023\363l\070\266\317k\030\266v\225\216#.\003-\003sl\363"
|
||||
"|\263|\024u\324l\064e\064e\064e\064]\064e\363T\024E\024M\323L\023]qT\262\\\060LM\033"
|
||||
"\360C\320;\216\063\256\033\060\014\060\004P\004\060\004\060\004/\004/\004/\004\060\004\060\004P\014\020"
|
||||
"\\u\265u\255m+\216\023\060\034E\031e)\246\061jJIB$!\252\"\364l\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\337\377\276\367\235\357}\357\266\205q\034"
|
||||
"\221\024\315kO\234\355\213\016\214\016\\\222D\364\204\212Bmk\064\215\323L\061"
|
||||
"$\023\015\064\005\024=\362\244\373\336\272\336\332\336\272\336\332\336\332\336"
|
||||
"\332\336\272\336\332\336\333\336\272\336Y\316\253R\323\\u}\024m\065u\064\205"
|
||||
"rdqT\061\064n\023\015\003n+\020TQT\357#\360#\222\024\222\004\222\014q\014\060\024\020d\357"
|
||||
"kQl\020l\316\023\061\024\217\033\257#\257\063\020LM#mC\216;\357\013\060\004\060\004\060"
|
||||
"\004\060\004\020\004\020\004\060\004\060\004\060\004P\014\021d\364\234\323\214\216\063\216\033P\034"
|
||||
"\206!)JiJjJMk\014c\252*\364t\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\337\377\337\377\236\367\236\367\327\205\222\034q\034\067\306;\357[\357\\\357"
|
||||
"t\235\222\064\261\024\253\032\060dv\205Q\064r\064Q<\022%\023\025\225\245\070\316y\326"
|
||||
"y\326\232\336\272\336\332\336\332\346\373\346\332\336\332\336\232\336\023"
|
||||
"\245mcrL\327\235QL\363|Mk\263\214\216\023N\003\017,\317+\360S-\023\317\033\360"
|
||||
"+\020\024q\004\221\004\221\004\221\004P\064\363\244\221\234P\224\017\214\255+P\004\060\034"
|
||||
"\216\033\256#\317K\354\032m\063\317C\060,\017\014\357\003\356\003\316\003\316\003\316\003"
|
||||
"\017\014\060\024\357\003\356\003\216\023\017\\M\063Q,\216\013\020\034f!e)\313Z)BIB\313"
|
||||
"Z\253\062\364l\377\377\377\377\377\377\377\377\377\377\377\377\377\377\337"
|
||||
"\377\276\367\236\367\370\215\222\034\221$\026\276\271\326\265\265\271\326Q"
|
||||
"\214\322\064QD\362\004\362\014\323\014R\024Q$\263T\063\065T\005\322D\226\255\033\347"
|
||||
"\373\346\373\336\332\336\372\336\033\347\272\336\231\336y\326\224\265\316"
|
||||
"k\215;\263L\071\246\262<\024\225\262\224\222\214QT\021DQ<M\023\262\\\354\012\317"
|
||||
"\033\360+\357\023q\004\221\004\221\004q\004P,\015ciJ(B\212Zl\033P\004\060\014\020\024\216\033"
|
||||
"\020,QD\061L\061L\327\225\071\256y\256X\246\031\246Y\246\071\256\327\215\222l\327"
|
||||
"\215\267\215\060D\060T\257;\060$n\013\020\034e\031\303\020E!iB\347\061\206\031\353"
|
||||
"\032\024m\377\377\377\377\377\377\377\377\377\377\377\377\377\377\337\377\276"
|
||||
"\367\276\367\370\215\262\034\262$u\215\226\245\225\225\266\235\065}\023%TM\363"
|
||||
"\014\023\015\024\005q\004Q$\262\034\063\005\064\005\023\005p\024\256+L\063,C\215S\256c\317k\020"
|
||||
"t\061t\222|\316c\253\062\020<r,Ue\024M\363\214/|\222\214\060L-\003\357\033.\013\317"
|
||||
"#-\023\320#\317+\357\023\221\014q\004\221\004\221\004q\014\061d\014CmC\222t/\014P\004qT"
|
||||
"\357C\216K\257S\354\032rL\222L\323d\024uTu\363l\065u\064u\323l\323d\323\\\023"
|
||||
"m\364lqD\060DQDQ<\222<\357\023(\012\307\021\247\011\347\001\007\002i\002L\003\364l\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\377\377\377\337\377\337\377\276\367"
|
||||
"\030\216\262\034\323\024\322\014\322\034\362\024\323\034\323\024\364\004\023\005\363\004"
|
||||
"\023\005\024\005Q\014R,Q$\363\034\024\015\064\005\023\015\222\024\320+\317#\360C\256K\256"
|
||||
"K\216K\317K\317C\320CrLr<\263<\324L\324Lt\205\353Z\364\224\360CN\003\061,-\003"
|
||||
"\360#M\013\317#\257#\257#Q\034\221\004\221\004q\004\020\024\263\204U\245\263\214V\245"
|
||||
"\256\033P\024\221|\326\275T\255\222tq,\317\023m\023M\033M\023m\023M\023M\023L\023M"
|
||||
"\013M\023m\013m\023n\023n\023n\023\216\023\216\023\216\023M\013\021D\216+\216\023m\003m"
|
||||
"\003\316\003\357\003\364l\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\337\377\337\377\337\367\030\216\262\034\322\034\222<\363\004\023\005\363\004\063\005"
|
||||
"\023\005\023\005\363\004\221,\363\034\061\014\257\033RLQ\064\363\024\023\005\363\024q$Q\064"
|
||||
"Q\064\257Cr\\rd\363\\\064UuM\024U\222dQ,r\064\317#\060\064\261\\\360;\020L\222L"
|
||||
"\263Dn#QDn\033-\023\257#\354\012\320\063\317\063r,\221\034\221\014\060\034\221\\Q"
|
||||
"\\qdqd\256\033\221\014\262T\256\063\256;\320KP\024\357+\222L\323D\262Dr\\\222"
|
||||
"D\262D\262D\262D\222D\262<\222D\222D\262D\262<\262<\323<\263<\060,\317+\017"
|
||||
"$\357\003\017\004\357\003\060\004\017\004\364l\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\337\377\337\377\277\367\030\216\262\034\362,\322\\\322\014"
|
||||
"\363\004\322\004\323\014\363\004\322\004\262\004\221L\322,Q\014-\003\360S\020L\322\024\023"
|
||||
"\015\021\034r\064qd\364\234,[\014[,c,[\322\214Qdq<\363\\\363$\360\033r<rL\322\\"
|
||||
"\061\034\021D\313\062\313\062-;-C\354:-CnC-C\015C\257K-K\015C\317KNCnC\016CnC-C-"
|
||||
"Cn;M;\216;M;\014;-;\015Cm;\253:-K\253R\252\062\313\062m;\014;\313:mC,;j\062\014"
|
||||
"\063m;\313:\014Cm;\354\062\253:\014\063\357\023\060\004\060\004q\004P\004\065m\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\377\377\337\377\337\377\337\367\030\216"
|
||||
"\221\024\363\024\363\014\362\004\362\014\060<\261,\216;mCL;mK\216C\222t\020T\262"
|
||||
"t\256\033Q$q\034\061$\222<\266\245\064\245\353R\313R\313Z\313Z\363\244u\235\064"
|
||||
"]\323T\224\\\263T\323L\223T\261LR<\253*mk\256s%!Mk\020\204\206\061iJ\357{\313"
|
||||
"Z\206\061\316{\256s\303\020\014c\357{\347\071iJ\317{\014c\004!mk\256s\344\030\253"
|
||||
"R\316{HJ\306\071\357{,k\303\030Mk\256{$)\313Z\256s\253Z\246\071\317{mk\303\030"
|
||||
"ms\357{\246\061\212R\357\203(J\215\023P\004q\004\221\004q\014Um\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\337\377\337\377\337\367\030\216\262\034"
|
||||
"\363\024\323\004\363\004\262$\364Tp,)B\307A\010:)J\266\265T\255\332\336z\306\322"
|
||||
"D\364L\363<\357\033\061$u\205\323\234\252Z\253R\212R\313Z\023\235\064\225\264"
|
||||
"<r\064R<Q<\262d\260#\025=\222<\354BQ\214\262\224\354Z\262\234\024\245-c\020\204"
|
||||
"\024\245\021\214ns\024\245\263\234-k\222\224\064\245\216s\360\203\064\245R\214"
|
||||
"\355b\323\234\263\234\014c\061\214\363\234\217sns\364\244Q\214\253R\222\224"
|
||||
"\323\234\354Z\317{\364\234\360{\354b\024\245\222\224\212Rr\224\363\234\014"
|
||||
"cnk\262\224)B,\023\060\004\221\004\262\004\221\014Uu\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\337\377\337\377\337\377\030\216\262\034\023\025\362"
|
||||
"\004\327}\033\327\373\316\034\317\350IHJIJjJi:qt\222|\024\205q<\323D\060$\364\064"
|
||||
"\320\023\323d\023\205\253BjJjB\212B\364|\323t\222D\360+\322DQ<\322d\360\033"
|
||||
"\363\024q\024\355:\350\071)B\011B\011:\011B\351\071\350\071\350\071\350\071\011:\011"
|
||||
"B\350\071\350\071)B*B*B*B)B\351\071\351\071\310\071\350\071\350\071\011B\350\071\350"
|
||||
"\071\310\071\310\061\310\061\310\061\310\061\310\061\310\061\310\071\310\071\351\071"
|
||||
"\011B\011:\011:\011B)BJJ)B*BkJ)B\353\022\020\004\221\004\262\004q\014uu\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\377\337\377\337\377\337\377\030\216\262"
|
||||
"\034\322\024\262\014\367\205\030\306\272\326\236\367)J)JiJIR\252B\064\205\364"
|
||||
"\204\222t\222\034\363\004\363\034Q\034\263$q\024\061\014\222\014q\014q\014Q\014\262\024"
|
||||
"\020<qd\021\034\363$R$\262,\061\034\362\004r\014\253\062F)\207\061\247\061\247\061\207"
|
||||
"\061F)E)\206\061\307\071\011B\310\071F)F)\247\061\011B)B\011B\011:\350\071IJjJ\212"
|
||||
"R\213R\213R\253R\253R\213R\350\071\351\071\310\071\350\071\310\071\310\071)BJB"
|
||||
"jJ\213RjJ\011:\011:IBIBJB\011:Nk):\313\022\357\003\261\004\222$q,vu\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\377\337\377\337\377\337\367\030\216\222"
|
||||
"\034\322<qT\266\205\326\275\272\326\235\367IB)J)JIJ\363\234\362\224\333\336"
|
||||
"\267\255p\034\363\024p<R,\223\024q\024\020\014\363\014\322\014\363\014\262\014\322"
|
||||
"\014\221$\222L\323,\323\024P\014r,\017\024\322\004Q\024\354:\005!E)F)F)E)%)%)\247\061"
|
||||
"\310\071\247\061\350\071\247\071F)\207\061\350\071\011B)B\011B\350\071)B\212RjRjJ"
|
||||
"jJjJjJjJ\011BJB)B)B*B\351\071\213R\253R\247\061\307\071\212JjJ\011:*B*BJB)B)B"
|
||||
"):\313\022\357\003\221\004\222<\221DUu\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\337\377\337\377\337\367\030\216\221\024\322\024\024E\226}\327"
|
||||
"\275\232\326~\367\010J)JJRIJ\014[ql\360sT\205\221\034\363\024\023U\221$\323\034"
|
||||
"Q\034\060\024\024eu\215\020,\061T\360[\317K\316S\023}\024urL\024}\317+\261\004\060\024"
|
||||
"\253\062\344\040\344\030\004!%)\004!\004!\004)\247\061\303\030\243\030\303\030\350\071f)"
|
||||
"\247\061\350\071)B\213R\253RJJ\313Z\354Z\314Z\313Z\354Z\354Z\313Z\354Z\314"
|
||||
"Z\213R\313ZjJjJ\011:jJ\004!\243\020\243\020f\061jJ)BJBJJJB\011:\310\071\010:\313\022"
|
||||
"\317\003\221\004\262\004\221\004vu\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\337\377\337\377\337\367\027\216\262\034\323\014\322\014\266}y\316x\316"
|
||||
"\272\306\307IHJjR)B\350)\262l\323t\363d\323\024\363\004\023\015\222\024\323\034"
|
||||
"q$\360\023QdT\245\357\063\364|\014[\253R\213R\060t\262l\317C\265\265\015\023\262"
|
||||
"\004\061\024\253:\344\040\343\030\004!E)\004!\303\040\004!\206\061\344\040\303\030\303\030"
|
||||
"\350\071\206\061\247\061\350\071*BjJ\212JJJ\253R\253R\253Z\253R\253R\253R\212"
|
||||
"R\313Z\253R\212R\253RJJJJ\011:\011B\243\020\243\030\242\020\005!\213R\011BJBjJ*B"
|
||||
"\351\071\207\061JJ\313\022\317\003q\004\322\004\222\014vu\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\337\377\337\377\337\367\027\216\221\034\262\014"
|
||||
"\322\004\323\064v]\064e\322L\011B)B)RIJ\023\235\363\234\272\326\232\316\222$\362"
|
||||
"\004\024\005q\014\263$P\024R,\017\\\224\265\216+\323\204\256s\313b\253J\221<\323"
|
||||
"<\020\064\026\306n#\261\004\061\024\314:\005!\004!%)F\061\004!\344\040%)\206\061E)\303\030"
|
||||
"\350\071\010Bf\061\350\071JJjJ\253R\014c\212R\212J\314Z\354Z\014c\213R-k\014c\014"
|
||||
"c\014c\014c\354b\314ZjJ)B\310\071\247\061\243\020%)JJkJ\011BJBJJjJ\011:\247\061J"
|
||||
"B\313\032\316\003\221\004\262\004\262\014Uu\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\337\377\337\377\336\367\367\215r\034\322\014\322\004\263\014"
|
||||
"\322\014PL\262\064g!\206)E)e)\212:\256[Qlv\225\221\034\323\004\023\005r\014\263\034"
|
||||
"\216\003\060$\263|\363\224\322D\227\235\317s\354b\353Zu\245Qd\363\\\323\234"
|
||||
"\222L\016<\020,\015C%)\004!\004!F)%)\344\040E)f\061\307\071\253RJJ\310\071\207\061\350"
|
||||
"\071JJJJjR\253R\213RjJjJ\213R\253RjJ\313Z\353b,c\014c\353b\354bIJ\011B\310\071"
|
||||
"\247\061)BjJ\253R\213RjJ\350\071\011B*B)B\011:\350\071):\312\032\256\003p\004\262\004"
|
||||
"\221\014vu\377\377\377\377\377\377\377\377\377\377\377\377\377\377\337\377"
|
||||
"\337\367\277\377\367\225\263,\023=\262L\362\024\363\014\362\014\363\014P\014/\014"
|
||||
"/\014\317C\221,\020\034q\034\261\024\322\004\362\004\023\005r\014\262\034o\013N\003\014\033"
|
||||
"m;q,\020<\357\063I\032\353\"\221<\262<r\064pT\222\064\023U\020\034NCE)%!\004!%!%)E"
|
||||
")\206\061\206\061\207\061\310\071\310\071\207\061\206\061\247\061\310\071\310\071\247"
|
||||
"\061\247\061\310\061\310\061\310\071\310\071\310\071\310\071\213R\212R\212RjJ\212"
|
||||
"R\010B\207\061\206\061f)\206)\206\061\247\061\310\071\310\071\310\071\247\061\310"
|
||||
"\071\350\071\350\071\350\071\350\071):\312\032\256\003p\004\262\004\221\014uu\377\377"
|
||||
"\377\377\377\377\377\377\377\377\377\377}\357\030\306\327\275\367\275\323"
|
||||
"|\357K\262d\323\204\023U\064]\064U\025U\064E\024M\024M\363l\023UQ<\360;q,\262\014"
|
||||
"\322\004\023\015\222\014\263$-\003\015\013\323|\370\265\061Tq,q\014\222\004\323\004\262"
|
||||
"\004\261,\222tY\276\361c\222,\060\024\015C\313Z\313Z\350A\014c-c\350A\253R-k\212"
|
||||
"R\010B-c\014c\350\071\313Z-k\010B)J-k\252R\307\071\014c\014c\206\061\212R\354Z\010"
|
||||
"B\307\071\354Z\212Rf\061\313Z\354Z\206\061)B\354ZJJ\350\071\313Z\252R\350\071"
|
||||
"\212R\313Z)BIJ\253RIB\353\032\256\003q\004\262\004\221\014vu\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\333\336\354Z\314b-c-c\347\071,[mk\317{\360\203"
|
||||
"\360{\256s\215c\014c\353R,[N[j:q\\\262T\322\024\363\004\023\005\222\014r\064-Cn[\024"
|
||||
"\235\327\275\257kMC\017$\261$\262$\357;\014K\222\224\226\265\357{\014K\215C"
|
||||
"j\062Q\214\323\234\303\030\024\245\226\265\307\071\317{v\255\020\204\010B\226\265"
|
||||
"\024\245\243\020\263\224\226\265\212R\256sv\265q\214e)U\255U\255\344\030q\214"
|
||||
"\226\265Mk\354Zv\255\263\224\344\030\065\245\226\265\307\071\060\204\226\265"
|
||||
"\020\204(B\226\265\024\245\243\020\024\245\267\265\313Z\256su\255%!\312\022\317"
|
||||
"\003q\004\262\004q\014vu\377\377\377\377\377\377\377\377\377\377\377\377\272\326"
|
||||
"\354b\015c\314Z-cE)E)e)e)\205)\206\061\206\061\206)E)%)E!E)\206\061\347\071F!"
|
||||
"m\013\323\014\023\005\262\024nK\364\234<\347\337\377\337\377\276\367U\245\212:"
|
||||
"\060d\020d\317{\033\337\235\367\337\377\337\377z\316\354Z\015[\353Z\353Z\313"
|
||||
"R\313Z\313R\313R\014[\354Z\313R\253R\313R\253R\313R\353R\253R\253R\253R\253"
|
||||
"JjJ\253R\313Z\253R\253R\253R\313R\212J\213RjJ\252R\313R\313R\252RjJ\212J"
|
||||
"\212JiJIBiJjJJBjJIBIBiJiJ\252J,\033\317\003q\004q\034q\024vu\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\232\326\354b-c-c-cf\061\247\061\206\061f\061E)E"
|
||||
")E)E)E)E)%)E)E)e)\344\040\211\"\221\014\064\005\262\034\222\214\236\377\067\306"
|
||||
"\276\367\337\377}\357\232\326\263\224,;\216[]\347\273\326\034\347\337\377"
|
||||
"\276\367\232\326\330\275\247\061e\021\242\010E!%\031E\021D\001e\001e\001e\001e\001e\001E\011"
|
||||
"E\011D\011$\001e\001$\001d\001\255k\312Z\212ZIJD\001e\001E\001e\001d\001\003\001\004\001E\001D\001\004\011E"
|
||||
"\001E\001\004\011\004\001d\001\004\001$\011e\001D\001\004\011D\001E\001\004\001\206\011,\003\317\003\220\004qD\222"
|
||||
"D\226u\377\377\377\377\377\377\377\377\377\377\377\377Y\316\015c-cNk\015c\061"
|
||||
"\204R\214\260{-c\015c\014c\014c\014c\313Z\253Z\253Z\213R\212RIBHB\364\234\257"
|
||||
";\023\025\364$z\316\276\367\231\326<\357\236\357]\357\273\336\232\326\014KV"
|
||||
"\245\337\377\033\337<\347\034\347}\357\333\336\374\336\354Z\252\032\010\032\347"
|
||||
"\031I\032\007\022i\012i\012\007\012\007\022\007\012\007\012\347\021\010\032\007\032\247\031\206\031"
|
||||
"%\011\007\032I:\212B\211:\353J(\022H\012i\002i\002H\002\206\031\206\021\010\022\307\021\206"
|
||||
"\021\010\022\347\021\206\021\246\021(\022\206\021\246\021\007\012\306\021e\021\347\021\347"
|
||||
"\021\206\021\010\022M\003m\003\256\013\020\034\221\024\226u\377\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\030\306\015c.c\015c\014c\031\306\031\306\330\275\066\245\065"
|
||||
"\245V\255V\255w\265V\255V\255v\265\062\214\025\245\263\224Lc\060\214\071\276"
|
||||
"Q\034\363\034]\337\337\377\332\336<\347]\357<\357\373\346\333\336M[\030\306"
|
||||
"\276\367\\\347]\357]\357\\\357\272\326\034\337\361{\215\033\216;m;\212\022\257"
|
||||
"K\313\"\216+UuUuum\024u\064\205\023}\262|\323\204\226\235\030\256\367\235\370"
|
||||
"\255Y\246\327\225z\266v\225\330\245\353\"\354\062\263l\370\255\071\256\070\236"
|
||||
"\030\236z\276\273\276\266\225Y\266z\276\232\276\330\255\071\256\370\235\024"
|
||||
"u\364\204\064u\064m\364|\065u-#-;nS\256;\020\024\266u\377\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\327\275Nk-c\015c\354Zr\214s\214\062\204\021\204\062"
|
||||
"\204R\214\263\224\324\234\364\234\364\234\065\245\223\224\365\234\263\224"
|
||||
"\017\204\357{\071\306\360\063\262,\034\337\276\377\332\326\\\357Y\316<\357\374"
|
||||
"\346\273\326MS\327\265\337\367\034\347]\357\373\336\373\336\373\336\232\316"
|
||||
"\256kl\023uu\323l\317\063\263t\065}\256+\060\034p\014Q\014\216#\267\245\030\276\363"
|
||||
"\234\327\275\070\266\070\256\070\256y\266u\205\327\225\232\276U\215\272\256"
|
||||
"\060L\317S\024}\266\235\327\235\327\225\226\225\070\266\334\306\266\225\071\266"
|
||||
"z\306]\327Y\266\266\225\370\225\256\023M\033/\024\020\024n\033n\033\014;Q\214T\245"
|
||||
"\024\245PT\326\205\377\377\377\377\377\377\377\377\377\377\377\377\266\265"
|
||||
"-k.c\015c\253Z\354Z\015c\354Z\314Z\314Z\253R\314Z\314Z\314Z\213R\213R\014[N"
|
||||
"kLk\315\203r\224Z\306\324L\060\064\025\245\231\316Y\316\030\306\030\306\327\275"
|
||||
"\226\255\222\214\350!r\214\071\276\030\306\370\275\327\265\226\255u\245\262"
|
||||
"\214\347)M\023\267\205\027~\360\033\064m\070\246q<\317+\262D\221\014\360\033\363"
|
||||
"|\061|\216kQ\204\364\204\327\225\367\215\326}\266\205\266\205\226\205u\205"
|
||||
"\226\205\357\063\020L\323T\226\215u\205\267\205\267\205u\215\226\215\266}\226"
|
||||
"\215\226\205\266\205u\205v\215\225m\017\014o#P\024Q\024\257#\216#qt\232\316<"
|
||||
"\347\034\337v\235\326}\377\377\377\377\377\377\377\377\377\377\377\377\226"
|
||||
"\265-c\015c\015c\314Zr\214\223\214\062\204\361{\360{\320s\260s\320{nknknk\014"
|
||||
"c\355b\216s\017\214\065\235\256K\061\034\262\064Nc\064\235\364\234\363\224\263"
|
||||
"\224\263\214\222\224\253R(*\252B\323\234\323\224\323\224\263\224r\214R\204"
|
||||
"IB\205!\215+\327\205\030~\222\024\363d\030\236\020,Q<\070\236\023E\221\024\060\034"
|
||||
"\216\023\222\064\262L\023M\363D\322D\323D\362<q$Vu\324l\221\014r\024\322$\221"
|
||||
"\014\064mZ\266Ue\060$\065}\370}P\014v\215\327\215\322\064\364t\030\236veq\064\071"
|
||||
"\256y\226P\034\064u\071\246\024\205>\357~\367~\367\023u\327\205\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\377\024\245\015c\355b\015c\313Z\061\204\263\224"
|
||||
"r\204\223\214s\214s\214\324\224\025\235\223\214\264\224\025\235\320sok\360"
|
||||
"{\211J\313*\017\014R\014q$\015K\354ZU\245\267\275\226\255\262\204\313R\350\061"
|
||||
"i*\313:)B\222\214\266\255\370\275q\204I:%\031H*\020T\225}\327u\262\014\262\\"
|
||||
"\226}\262,\317\033\030\216\064e\262\024\323l\024u\266\205\337\347]\347}\337\\"
|
||||
"\327}\337\277\357\363DUm\065u\262\034\222\004\262\004\221\014\322\\\370\255uer,"
|
||||
"\025}vu\220\004\222d\023m\262\064\363\\\020TUe\060\014\323t\064m\262\034\226\205\363"
|
||||
"l\060\064u\205Y\266\363t\322<\071\216\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\377\323\234\354b\015c\015c\313Z\350\071JJJJJJJJJJ\212R\253Z\314Z\314Z\014"
|
||||
"c\015c\314ZJJ\343\020,\003\020\014\263\004\222\024\257#\214\013\353\"\323\204v\245"
|
||||
"\010\022\307\011(\002M\003\215\013i\012\252\022\256c\030\276\313:\007\002H\002L\013\020\014\267"
|
||||
"u\367u\222\024\323ly\246\363$\020\034v}\065]\262\034\226\205\323l\326\215\236"
|
||||
"\357\373\306\333\306Y\266=\327\277\347\363D\025u\263T\321\014\262\014\322\004"
|
||||
"\322\004\024e\272\266ueQ\034y\246Y\236\221\024\267\225\272\256\262$\364t\272\276"
|
||||
"\226eq,Y\256Y\236\221\024\327\225\273\266\363,R\024r$\064E\262,\232\256\377"
|
||||
"\377\377\377\377\377\377\377\377\377\377\377r\224\253Z\314Z\314ZjR\212R\314"
|
||||
"Z\353Z\354Z\354b\354Z\354b\354Z\354b\314b\313Z\253Z\212RjJ\307\021M\013N\023"
|
||||
"\317#Q\034\223\064q\034\020\024M+L+\252\022\212\032L\033\357\033\017\024m+\256++\033"
|
||||
"\256\023K\013,\013\215\033\060\024\221\004\225]\226]\262\034\363\\\330\225\362$\020"
|
||||
"\034\024]\024U\322\034UuR\\\367\205\236\357\237\357\276\357\276\357\236\357\276"
|
||||
"\347\023=Um\263T\322\034\362\004\363\004\362\004\060,U}\266]P\014\323d\027~q\024\060D"
|
||||
"\367\215\322$\020,U\205\265U\060\034\323l\027~\322\024QL\367\215\023\035\261\004\222"
|
||||
"\014q\014\262<\034\317\377\377\377\377\377\377\377\377\377\377\377\377\034\347"
|
||||
"\232\326\071\316\266\255-S,CH*\251R,k\211JHRj:\253J\323\234U\255\364\244\360"
|
||||
"\203\216s\212\062i\002\353\"\317c\020|q|\020\064\262$r\034\262Dz\316\020\204\212"
|
||||
"R\354RMS\014K\360{\373\326\267\265\017\004\316#\014\063\314:\216;\060\064QT\364l"
|
||||
"\020D\317;\223l\222L\216\063\262\\r\\\263TPL\061L\266\215=\337\035\337=\337\035"
|
||||
"\337=\337=\337\323\\\061LQL\262LQ,\060$Q,\357\063\320K\263TQD\360CrT\222L\360"
|
||||
"C\020T\262L\360;\060L\262T\061L\320C\222\\\262L\320CQT\263TQD\061\024\221\064\030"
|
||||
"\256=\347\377\377\377\377\377\377\377\377\377\377\377\377\337\377\276\367"
|
||||
"]\367\232\326\017Tql\007\002\350Jo\224\355{gJh\012mK\332\326X\306\070\316\226\275"
|
||||
"\262\234LC\252\002\060lT\255\370\305\071\306\024\205\322\024\263\034\262TY\306u"
|
||||
"\265IJIJIJ\212R\212ZP\214\323\234\221\004\256;\313J-c\253RJB\015c\314RjB\014"
|
||||
"[\015c\212B\313J,[\313R\212B\014[\015[JB\313Z\014[\253R\253R\015[\314RkJ\313R"
|
||||
"\014[JBI:\212B\212B\212B\354R\313J\212J\253R\253JI:JJ\253R\252B)B\213JiBj"
|
||||
"B\213R\253J\212B):\212B*BjBP\064\327\245\333\336\236\367\377\377\377\377\377"
|
||||
"\377\377\377\377\377\377\377\337\377\276\367}\357\373\326\222trd\210\002\310"
|
||||
"*\010S\351Z\311:\013\013,+\327\265\030\306\370\275\030\276\063\225\014#M\013\323"
|
||||
"\214\272\326\034\347<\347\367\235\323\014\064\015q<}\347\030\306(B\211RjRiR\353"
|
||||
"bt\255\326\255\322\014\360;\243\030\000\010%!\005!A\000\203\030E)a\010\202\020%)\344"
|
||||
"\040\040\010\344\030%)A\010\201\010\206\061\304\030b\010E)\004!a\010\303\030\206\061\202"
|
||||
"\020a\020e))JJJ\213R\247\071a\010b\020F)\243\020A\010\004!\004!b\010\242\030E)\202\020"
|
||||
"a\020%!\344\030A\000\344\040%!\201\010\303\020):\065\205\272\326\236\357\277\377"
|
||||
"\377\377\377\377\377\377\377\377\377\377\377\377\337\377\276\367}\367\034"
|
||||
"\337\024}\323l+\013m\033\256\063\357;\357\033\357\023\357\023\356;\027\256\231\316"
|
||||
"\327\245\256\063\356\023/\014\060T\373\326\235\357]\347\362T\024\025\063\005\262,"
|
||||
"\367\235U\215\256[\353:\252\062\252:\013Kt\215\267\215\023\025\360;IBjJ)B\307"
|
||||
"\071\212JjJf\061\212JjJ\350\071\010:jJIB\206)IBIB\307\071(B)J\010B\247\071)B\310"
|
||||
"\071\247\071)B)B\247\061\010:IB\347\071\307\061\010:\350\071\206\061\307\061\010:\206"
|
||||
"\061f)\010:\247\061\206)\207\061\247\061\247\061f)\307\071f\061f\061\247\071\247\071"
|
||||
"J:\367\245]\357\276\367\337\377\377\377\377\377\377\377\377\377\377\377\377"
|
||||
"\377\337\377\276\367\235\357]\357\266\215P$\060,\060$P$P$Q$q$Q\034q\034\222\064"
|
||||
"\221\064\261\064q\034q\034\222\034\222\014\362\064T]\023\065\023\035\363\024\363\024\363"
|
||||
"\034\023%\362,\221\034q\024P\024P\024P\024\322$\023%\063\015\221$\256\063\216\063\255"
|
||||
"\063l+\255\063\255\063m+\316;\256\063\215+\255\063\316;\256\063\215#\256;\316\063"
|
||||
"\262t:\306Z\276Z\276Z\276Z\276Z\276\316;\215;m\063M+,#,#\014#L\063m;m\063,+M"
|
||||
"\063M\063,+,+M\063L\063L\063M\063L\063,\063,+,\063,+,\063M\063M\063\255\063\272\306\235"
|
||||
"\367\276\367\337\377\377\377\377\377\377\377\377\377\377\377\377\377\337"
|
||||
"\377\337\377\276\367]\367<\337\070\266\225\225\225\225\226\235\266\235\266"
|
||||
"\235\326\235\266\235\266\235\265\225\266\235\266\235\266\235\266\235\326"
|
||||
"\225\326\235\027\236x\246\071\266\030\246\367\235\367\235\327\245\367\235\367"
|
||||
"\245\367\235\367\235\367\235\370\235\370\235\370\235\030\236\370\245\367\245"
|
||||
"\326\245\266\235\266\245\266\245\266\245\266\245\266\235\266\235\266\235"
|
||||
"\266\245\266\245\266\245\266\245\266\245\266\235\327\235\367\255y\306y\306"
|
||||
"z\306z\306\232\306y\306\266\245\266\235\266\245\266\235\266\235\226\235\226"
|
||||
"\235\225\235\226\235\225\235\225\235u\235u\235u\235u\235u\225u\225u\225u"
|
||||
"\225U\225u\225U\225U\225T\225T\225\064\225\064\215\266\225\034\347\236\367\276"
|
||||
"\367\337\377"//,
|
||||
// };
|
||||
;
|
||||
@ -0,0 +1,92 @@
|
||||
/*******************************************************************************
|
||||
* PROGMEM Image Viewer
|
||||
* This is a simple PROGMEM bitmap image viewer example
|
||||
* Image Source: https://support.arduino.cc/hc/en-us/articles/360020652100
|
||||
*
|
||||
* How to create custom image:
|
||||
* 1. Open image in the GIMP
|
||||
* 2. Resize image to fit for the display and MCU memory
|
||||
* 3. Export Image as C-Source
|
||||
* 4. Uncheck all option and check "Save as RGB565 (16-bit)"
|
||||
* 5. Revise exported file just like "Arduino_UNO_Rev3_Ok.c"
|
||||
******************************************************************************/
|
||||
#include "Arduino_UNO_Rev3_Ok.c"
|
||||
#define IMG_WIDTH 100
|
||||
#define IMG_HEIGHT 71
|
||||
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
******************************************************************************/
|
||||
|
||||
void setup()
|
||||
{
|
||||
#ifdef DEV_DEVICE_INIT
|
||||
DEV_DEVICE_INIT();
|
||||
#endif
|
||||
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
// while(!Serial);
|
||||
Serial.println("Arduino_GFX PROGMEM 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
|
||||
|
||||
gfx->draw16bitRGBBitmap(0, 0, (const uint16_t *)Arduino_UNO_Rev3_Ok, IMG_WIDTH, IMG_HEIGHT);
|
||||
|
||||
delay(5000); // 5 seconds
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
int16_t x = random(gfx->width());
|
||||
int16_t y = random(gfx->height());
|
||||
gfx->draw16bitRGBBitmap(x, y, (const uint16_t *)Arduino_UNO_Rev3_Ok, IMG_WIDTH, IMG_HEIGHT);
|
||||
|
||||
delay(1000); // 1 second
|
||||
}
|
||||
@ -0,0 +1,278 @@
|
||||
/*******************************************************************************
|
||||
* PNG Image Viewer
|
||||
* This is a simple PNG image viewer example
|
||||
* Image Source: https://github.com/logos
|
||||
*
|
||||
* Dependent libraries:
|
||||
* PNGdec: https://github.com/bitbank2/PNGdec.git
|
||||
*
|
||||
* Setup steps:
|
||||
* 1. Change your LCD parameters in Arduino_GFX setting
|
||||
* 2. Upload PNG 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 PNG_FILENAME "/octocat.png"
|
||||
#define PNG_4BPP_FILENAME "/octocat-4bpp.png"
|
||||
|
||||
/*******************************************************************************
|
||||
* 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 <PNGdec.h>
|
||||
PNG png;
|
||||
|
||||
int16_t w, h, xOffset, yOffset;
|
||||
|
||||
// Functions to access a file on the SD card
|
||||
File pngFile;
|
||||
|
||||
void *myOpen(const char *filename, int32_t *size)
|
||||
{
|
||||
/* Wio Terminal */
|
||||
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
|
||||
pngFile = SD.open(filename, "r");
|
||||
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
|
||||
pngFile = LittleFS.open(filename, "r");
|
||||
// pngFile = SD.open(filename, "r");
|
||||
#elif defined(ESP32)
|
||||
// pngFile = FFat.open(filename, "r");
|
||||
pngFile = LittleFS.open(filename, "r");
|
||||
// pngFile = SPIFFS.open(filename, "r");
|
||||
// pngFile = SD.open(filename, "r");
|
||||
// pngFile = SD_MMC.open(filename, "r");
|
||||
#elif defined(ESP8266)
|
||||
pngFile = LittleFS.open(filename, "r");
|
||||
// pngFile = SD.open(filename, "r");
|
||||
#else
|
||||
pngFile = SD.open(filename, FILE_READ);
|
||||
#endif
|
||||
|
||||
if (!pngFile || pngFile.isDirectory())
|
||||
{
|
||||
Serial.println(F("ERROR: Failed to open " PNG_FILENAME " file for reading"));
|
||||
gfx->println(F("ERROR: Failed to open " PNG_FILENAME " file for reading"));
|
||||
}
|
||||
else
|
||||
{
|
||||
*size = pngFile.size();
|
||||
Serial.printf("Opened '%s', size: %d\n", filename, *size);
|
||||
}
|
||||
|
||||
return &pngFile;
|
||||
}
|
||||
|
||||
void myClose(void *handle)
|
||||
{
|
||||
if (pngFile)
|
||||
pngFile.close();
|
||||
}
|
||||
|
||||
int32_t myRead(PNGFILE *handle, uint8_t *buffer, int32_t length)
|
||||
{
|
||||
if (!pngFile)
|
||||
return 0;
|
||||
return pngFile.read(buffer, length);
|
||||
}
|
||||
|
||||
int32_t mySeek(PNGFILE *handle, int32_t position)
|
||||
{
|
||||
if (!pngFile)
|
||||
return 0;
|
||||
return pngFile.seek(position);
|
||||
}
|
||||
|
||||
// Function to draw pixels to the display
|
||||
void PNGDraw(PNGDRAW *pDraw)
|
||||
{
|
||||
uint16_t usPixels[320];
|
||||
uint8_t usMask[320];
|
||||
|
||||
// Serial.printf("Draw pos = 0,%d. size = %d x 1\n", pDraw->y, pDraw->iWidth);
|
||||
png.getLineAsRGB565(pDraw, usPixels, PNG_RGB565_LITTLE_ENDIAN, 0x00000000);
|
||||
png.getAlphaMask(pDraw, usMask, 1);
|
||||
gfx->draw16bitRGBBitmapWithMask(xOffset, yOffset + pDraw->y, usPixels, usMask, pDraw->iWidth, 1);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
#ifdef DEV_DEVICE_INIT
|
||||
DEV_DEVICE_INIT();
|
||||
#endif
|
||||
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
// while(!Serial);
|
||||
Serial.println("Arduino_GFX PNG Image Viewer example");
|
||||
|
||||
// Init Display
|
||||
if (!gfx->begin())
|
||||
{
|
||||
Serial.println("gfx->begin() failed!");
|
||||
}
|
||||
gfx->fillScreen(RGB565_BLACK);
|
||||
|
||||
w = gfx->width(), h = gfx->height();
|
||||
gfx->fillScreen(RGB565_BLACK);
|
||||
for (int16_t x = 0; x < w; x += 5)
|
||||
{
|
||||
gfx->drawFastVLine(x, 0, h, RGB565_PALERED);
|
||||
}
|
||||
|
||||
#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();
|
||||
int rc;
|
||||
rc = png.open(PNG_FILENAME, myOpen, myClose, myRead, mySeek, PNGDraw);
|
||||
if (rc == PNG_SUCCESS)
|
||||
{
|
||||
int16_t pw = png.getWidth();
|
||||
int16_t ph = png.getHeight();
|
||||
|
||||
xOffset = (w - pw) / 2;
|
||||
yOffset = (h - ph) / 2;
|
||||
|
||||
rc = png.decode(NULL, 0);
|
||||
|
||||
Serial.printf("Draw offset: (%d, %d), time used: %lu\n", xOffset, yOffset, millis() - start);
|
||||
Serial.printf("image specs: (%d x %d), %d bpp, pixel type: %d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
|
||||
png.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("png.open() failed!");
|
||||
}
|
||||
}
|
||||
|
||||
delay(5000); // 5 seconds
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned long start = millis();
|
||||
int rc;
|
||||
rc = png.open(PNG_4BPP_FILENAME, myOpen, myClose, myRead, mySeek, PNGDraw);
|
||||
if (rc == PNG_SUCCESS)
|
||||
{
|
||||
// random draw position
|
||||
int16_t pw = png.getWidth();
|
||||
int16_t ph = png.getHeight();
|
||||
xOffset = random(w) - (pw / 2);
|
||||
yOffset = random(h) - (ph / 2);
|
||||
|
||||
rc = png.decode(NULL, 0);
|
||||
|
||||
Serial.printf("Draw offset: (%d, %d), time used: %lu\n", xOffset, yOffset, millis() - start);
|
||||
Serial.printf("image specs: (%d x %d), %d bpp, pixel type: %d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType());
|
||||
png.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("png.open() failed!");
|
||||
}
|
||||
|
||||
delay(1000); // 1 second
|
||||
}
|
||||
@ -0,0 +1,249 @@
|
||||
/*******************************************************************************
|
||||
* TIFF Image Viewer
|
||||
* This is a simple TIFF image viewer example
|
||||
* Image Source: https://people.math.sc.edu/Burkardt/data/tif/tif.html
|
||||
* ImageMagick script: convert at3_1m4_01.tif -threshold 40% -compress group4 at3_1m4_01_g4.tif
|
||||
*
|
||||
* Dependent libraries:
|
||||
* TIFF_G4: https://github.com/bitbank2/TIFF_G4.git
|
||||
*
|
||||
* Setup steps:
|
||||
* 1. Change your LCD parameters in Arduino_GFX setting
|
||||
* 2. Upload TIFF 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 TIFF_FILENAME "/at3_1m4_01_g4.tif"
|
||||
|
||||
/*******************************************************************************
|
||||
* 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 <TIFF_G4.h>
|
||||
TIFFG4 tiff;
|
||||
int16_t display_width, display_height;
|
||||
const uint16_t us2BppToRGB565[4] = {0xffff, 0xa514, 0x528a, 0x0000};
|
||||
uint8_t *tiffBuf;
|
||||
|
||||
void TIFFDraw(TIFFDRAW *pDraw)
|
||||
{
|
||||
// Serial.println("TIFFDraw");
|
||||
uint8_t c, *src;
|
||||
int i, l;
|
||||
uint16_t usTemp[640], *d;
|
||||
|
||||
if (pDraw->y >= display_height)
|
||||
{
|
||||
return; // beyond bottom of the display
|
||||
}
|
||||
|
||||
src = pDraw->pPixels;
|
||||
if (pDraw->ucPixelType == TIFF_PIXEL_1BPP)
|
||||
{
|
||||
// Serial.printf("TIFF_PIXEL_1BPP, pDraw->iScaledWidth: %d\n", pDraw->iScaledWidth);
|
||||
memset(usTemp, 0, sizeof(usTemp)); // start with black
|
||||
for (i = 0; i < (pDraw->iScaledWidth + 7) / 8; i++)
|
||||
{
|
||||
d = &usTemp[i * 8];
|
||||
c = *src++;
|
||||
while (c)
|
||||
{
|
||||
if (c & 0x80)
|
||||
*d = 0xffff;
|
||||
c <<= 1;
|
||||
d++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pDraw->ucPixelType == TIFF_PIXEL_2BPP) // 2-bit gray anti-aliased pixels
|
||||
{
|
||||
// Serial.printf("TIFF_PIXEL_2BPP, pDraw->iScaledWidth: %d\n", pDraw->iScaledWidth);
|
||||
d = usTemp;
|
||||
l = pDraw->iScaledWidth;
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
if ((i & 0b11) == 0)
|
||||
{
|
||||
c = *src++;
|
||||
}
|
||||
*d++ = us2BppToRGB565[c >> 6];
|
||||
c <<= 2;
|
||||
}
|
||||
}
|
||||
gfx->draw16bitBeRGBBitmap(0, pDraw->y, usTemp, pDraw->iScaledWidth, 1);
|
||||
} /* TIFFDraw() */
|
||||
|
||||
void setup()
|
||||
{
|
||||
#ifdef DEV_DEVICE_INIT
|
||||
DEV_DEVICE_INIT();
|
||||
#endif
|
||||
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
// while(!Serial);
|
||||
Serial.println("Arduino_GFX TIFF 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(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
|
||||
{
|
||||
/* Wio Terminal */
|
||||
#if defined(ARDUINO_ARCH_SAMD) && defined(SEEED_GROVE_UI_WIRELESS)
|
||||
File tiffFile = SD.open(TIFF_FILENAME, "r");
|
||||
#elif defined(TARGET_RP2040) || defined(PICO_RP2350)
|
||||
File tiffFile = LittleFS.open(TIFF_FILENAME, "r");
|
||||
// File tiffFile = SD.open(TIFF_FILENAME, "r");
|
||||
#elif defined(ESP32)
|
||||
// File tiffFile = FFat.open(TIFF_FILENAME, "r");
|
||||
File tiffFile = LittleFS.open(TIFF_FILENAME, "r");
|
||||
// File tiffFile = SPIFFS.open(TIFF_FILENAME, "r");
|
||||
// File tiffFile = SD.open(TIFF_FILENAME, "r");
|
||||
#elif defined(ESP8266)
|
||||
File tiffFile = LittleFS.open(TIFF_FILENAME, "r");
|
||||
// File tiffFile = SD.open(TIFF_FILENAME, "r");
|
||||
#else
|
||||
File tiffFile = SD.open(TIFF_FILENAME, FILE_READ);
|
||||
#endif
|
||||
if (!tiffFile || tiffFile.isDirectory())
|
||||
{
|
||||
Serial.println(F("ERROR: Failed to open " TIFF_FILENAME " file for reading"));
|
||||
gfx->println(F("ERROR: Failed to open " TIFF_FILENAME " file for reading"));
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t fileSize = tiffFile.size();
|
||||
tiffBuf = (uint8_t *)malloc(fileSize);
|
||||
tiffFile.read(tiffBuf, fileSize);
|
||||
if (!tiff.openTIFF(tiffBuf, fileSize, TIFFDraw))
|
||||
{
|
||||
Serial.println(F("ERROR: Failed to decode " TIFF_FILENAME " file"));
|
||||
gfx->println(F("ERROR: Failed to decode " TIFF_FILENAME " file"));
|
||||
}
|
||||
else
|
||||
{
|
||||
int cx = tiff.getWidth(); // scale the image to fit the display
|
||||
float fScale = (float)display_width / (float)cx;
|
||||
// Use TIFF_PIXEL_1BPP for bitonal only, 2BPP for anti-aliased grayscale
|
||||
tiff.setDrawParameters(fScale, TIFF_PIXEL_2BPP, 0, 0, display_width * 2, display_height * 2, NULL);
|
||||
tiff.decode();
|
||||
tiff.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
@ -0,0 +1,245 @@
|
||||
/*Using LVGL with Arduino requires some extra steps:
|
||||
*Be sure to read the docs here: https://docs.lvgl.io/master/get-started/platforms/arduino.html */
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
/*To use the built-in examples and demos of LVGL uncomment the includes below respectively.
|
||||
*You also need to copy `lvgl/examples` to `lvgl/src/examples`. Similarly for the demos `lvgl/demos` to `lvgl/src/demos`.
|
||||
Note that the `lv_examples` library is for LVGL v7 and you shouldn't install it for this version (since LVGL v8)
|
||||
as the examples and demos are now part of the main LVGL library. */
|
||||
|
||||
// #include <examples/lv_examples.h>
|
||||
// #include <demos/lv_demos.h>
|
||||
|
||||
// #define DIRECT_MODE // Uncomment to enable full frame buffer
|
||||
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Please config the touch panel in touch.h
|
||||
******************************************************************************/
|
||||
#include "touch.h"
|
||||
|
||||
uint32_t screenWidth;
|
||||
uint32_t screenHeight;
|
||||
uint32_t bufSize;
|
||||
lv_disp_draw_buf_t draw_buf;
|
||||
lv_color_t *disp_draw_buf;
|
||||
lv_disp_drv_t disp_drv;
|
||||
|
||||
#if LV_USE_LOG != 0
|
||||
/* Serial debugging */
|
||||
void my_print(const char *buf)
|
||||
{
|
||||
Serial.printf(buf);
|
||||
Serial.flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Display flushing */
|
||||
void my_disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
#ifndef DIRECT_MODE
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
#if (LV_COLOR_16_SWAP != 0)
|
||||
gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
|
||||
#else
|
||||
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
|
||||
#endif
|
||||
#endif // #ifndef DIRECT_MODE
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
/*Read the touchpad*/
|
||||
void my_touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
|
||||
{
|
||||
if (touch_has_signal())
|
||||
{
|
||||
if (touch_touched())
|
||||
{
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
|
||||
/*Set the coordinates*/
|
||||
data->point.x = touch_last_x;
|
||||
data->point.y = touch_last_y;
|
||||
}
|
||||
else if (touch_released())
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
#ifdef DEV_DEVICE_INIT
|
||||
DEV_DEVICE_INIT();
|
||||
#endif
|
||||
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
// while(!Serial);
|
||||
Serial.println("Arduino_GFX LVGL_Arduino_v8 example ");
|
||||
String LVGL_Arduino = String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
|
||||
Serial.println(LVGL_Arduino);
|
||||
|
||||
// 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());
|
||||
|
||||
lv_init();
|
||||
|
||||
#if LV_USE_LOG != 0
|
||||
lv_log_register_print_cb(my_print); /* register print function for debugging */
|
||||
#endif
|
||||
|
||||
screenWidth = gfx->width();
|
||||
screenHeight = gfx->height();
|
||||
|
||||
#ifdef DIRECT_MODE
|
||||
bufSize = screenWidth * screenHeight;
|
||||
#else
|
||||
bufSize = screenWidth * 40;
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
#if defined(DIRECT_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
|
||||
disp_draw_buf = (lv_color_t *)gfx->getFramebuffer();
|
||||
#else // !(defined(DIRECT_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)))
|
||||
disp_draw_buf = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (!disp_draw_buf)
|
||||
{
|
||||
// remove MALLOC_CAP_INTERNAL flag try again
|
||||
disp_draw_buf = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_8BIT);
|
||||
}
|
||||
#endif // !(defined(DIRECT_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)))
|
||||
#else // !ESP32
|
||||
Serial.println("LVGL disp_draw_buf heap_caps_malloc failed! malloc again...");
|
||||
disp_draw_buf = (lv_color_t *)malloc(bufSize * 2);
|
||||
#endif // !ESP32
|
||||
if (!disp_draw_buf)
|
||||
{
|
||||
Serial.println("LVGL disp_draw_buf allocate failed!");
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, bufSize);
|
||||
|
||||
/* Initialize the display */
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
/* Change the following line to your display resolution */
|
||||
disp_drv.hor_res = screenWidth;
|
||||
disp_drv.ver_res = screenHeight;
|
||||
disp_drv.flush_cb = my_disp_flush;
|
||||
disp_drv.draw_buf = &draw_buf;
|
||||
#ifdef DIRECT_MODE
|
||||
disp_drv.direct_mode = true;
|
||||
#endif
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
/* Initialize the (dummy) input device driver */
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = my_touchpad_read;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
|
||||
/* Option 1: Create simple label */
|
||||
lv_obj_t *label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "Hello Arduino! (V" GFX_STR(LVGL_VERSION_MAJOR) "." GFX_STR(LVGL_VERSION_MINOR) "." GFX_STR(LVGL_VERSION_PATCH) ")");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
/* Option 2: Try an example. See all the examples
|
||||
* online: https://docs.lvgl.io/master/examples.html
|
||||
* source codes: https://github.com/lvgl/lvgl/tree/e7f88efa5853128bf871dde335c0ca8da9eb7731/examples */
|
||||
// lv_example_btn_1();
|
||||
|
||||
/* Option 3: Or try out a demo. Don't forget to enable the demos in lv_conf.h. E.g. LV_USE_DEMOS_WIDGETS*/
|
||||
// lv_demo_widgets();
|
||||
// lv_demo_benchmark();
|
||||
// lv_demo_keypad_encoder();
|
||||
// lv_demo_music();
|
||||
// lv_demo_stress();
|
||||
}
|
||||
|
||||
Serial.println("Setup done");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
lv_timer_handler(); /* let the GUI do its work */
|
||||
|
||||
#ifdef DIRECT_MODE
|
||||
#if defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)
|
||||
gfx->flush();
|
||||
#else // !(defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
|
||||
#if (LV_COLOR_16_SWAP != 0)
|
||||
gfx->draw16bitBeRGBBitmap(0, 0, (uint16_t *)disp_draw_buf, screenWidth, screenHeight);
|
||||
#else
|
||||
gfx->draw16bitRGBBitmap(0, 0, (uint16_t *)disp_draw_buf, screenWidth, screenHeight);
|
||||
#endif
|
||||
#endif // !(defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
|
||||
#else // !DIRECT_MODE
|
||||
#ifdef CANVAS
|
||||
gfx->flush();
|
||||
#endif
|
||||
#endif // !DIRECT_MODE
|
||||
|
||||
delay(5);
|
||||
}
|
||||
@ -0,0 +1,205 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -0,0 +1,244 @@
|
||||
/*Using LVGL with Arduino requires some extra steps:
|
||||
*Be sure to read the docs here: https://docs.lvgl.io/master/get-started/platforms/arduino.html */
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
/*To use the built-in examples and demos of LVGL uncomment the includes below respectively.
|
||||
*You also need to copy `lvgl/examples` to `lvgl/src/examples`. Similarly for the demos `lvgl/demos` to `lvgl/src/demos`.
|
||||
*Note that the `lv_examples` library is for LVGL v7 and you shouldn't install it for this version (since LVGL v8)
|
||||
*as the examples and demos are now part of the main LVGL library. */
|
||||
|
||||
// #include <examples/lv_examples.h>
|
||||
// #include <demos/lv_demos.h>
|
||||
|
||||
// #define DIRECT_MODE // Uncomment to enable full frame buffer
|
||||
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Please config the touch panel in touch.h
|
||||
******************************************************************************/
|
||||
#include "touch.h"
|
||||
|
||||
uint32_t screenWidth;
|
||||
uint32_t screenHeight;
|
||||
uint32_t bufSize;
|
||||
lv_display_t *disp;
|
||||
lv_color_t *disp_draw_buf;
|
||||
|
||||
#if LV_USE_LOG != 0
|
||||
void my_print(lv_log_level_t level, const char *buf)
|
||||
{
|
||||
LV_UNUSED(level);
|
||||
Serial.println(buf);
|
||||
Serial.flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t millis_cb(void)
|
||||
{
|
||||
return millis();
|
||||
}
|
||||
|
||||
/* LVGL calls it when a rendered image needs to copied to the display*/
|
||||
void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map)
|
||||
{
|
||||
#ifndef DIRECT_MODE
|
||||
uint32_t w = lv_area_get_width(area);
|
||||
uint32_t h = lv_area_get_height(area);
|
||||
|
||||
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)px_map, w, h);
|
||||
#endif // #ifndef DIRECT_MODE
|
||||
|
||||
/*Call it to tell LVGL you are ready*/
|
||||
lv_disp_flush_ready(disp);
|
||||
}
|
||||
|
||||
/*Read the touchpad*/
|
||||
void my_touchpad_read(lv_indev_t *indev, lv_indev_data_t *data)
|
||||
{
|
||||
if (touch_has_signal())
|
||||
{
|
||||
if (touch_touched())
|
||||
{
|
||||
data->state = LV_INDEV_STATE_PRESSED;
|
||||
|
||||
/*Set the coordinates*/
|
||||
data->point.x = touch_last_x;
|
||||
data->point.y = touch_last_y;
|
||||
}
|
||||
else if (touch_released())
|
||||
{
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = LV_INDEV_STATE_RELEASED;
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
#ifdef DEV_DEVICE_INIT
|
||||
DEV_DEVICE_INIT();
|
||||
#endif
|
||||
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
// while(!Serial);
|
||||
Serial.println("Arduino_GFX LVGL_Arduino_v9 example ");
|
||||
String LVGL_Arduino = String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
|
||||
Serial.println(LVGL_Arduino);
|
||||
|
||||
// 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());
|
||||
|
||||
lv_init();
|
||||
|
||||
/*Set a tick source so that LVGL will know how much time elapsed. */
|
||||
lv_tick_set_cb(millis_cb);
|
||||
|
||||
/* register print function for debugging */
|
||||
#if LV_USE_LOG != 0
|
||||
lv_log_register_print_cb(my_print);
|
||||
#endif
|
||||
|
||||
screenWidth = gfx->width();
|
||||
screenHeight = gfx->height();
|
||||
|
||||
#ifdef DIRECT_MODE
|
||||
bufSize = screenWidth * screenHeight;
|
||||
#else
|
||||
bufSize = screenWidth * 40;
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
#if defined(DIRECT_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
|
||||
disp_draw_buf = (lv_color_t *)gfx->getFramebuffer();
|
||||
#else // !(defined(DIRECT_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)))
|
||||
disp_draw_buf = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (!disp_draw_buf)
|
||||
{
|
||||
// remove MALLOC_CAP_INTERNAL flag try again
|
||||
disp_draw_buf = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_8BIT);
|
||||
}
|
||||
#endif // !(defined(DIRECT_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)))
|
||||
#else // !ESP32
|
||||
Serial.println("LVGL disp_draw_buf heap_caps_malloc failed! malloc again...");
|
||||
disp_draw_buf = (lv_color_t *)malloc(bufSize * 2);
|
||||
#endif // !ESP32
|
||||
if (!disp_draw_buf)
|
||||
{
|
||||
Serial.println("LVGL disp_draw_buf allocate failed!");
|
||||
}
|
||||
else
|
||||
{
|
||||
disp = lv_display_create(screenWidth, screenHeight);
|
||||
lv_display_set_flush_cb(disp, my_disp_flush);
|
||||
#ifdef DIRECT_MODE
|
||||
lv_display_set_buffers(disp, disp_draw_buf, NULL, bufSize * 2, LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||
#else
|
||||
lv_display_set_buffers(disp, disp_draw_buf, NULL, bufSize * 2, LV_DISPLAY_RENDER_MODE_PARTIAL);
|
||||
#endif
|
||||
|
||||
/*Initialize the (dummy) input device driver*/
|
||||
lv_indev_t *indev = lv_indev_create();
|
||||
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); /*Touchpad should have POINTER type*/
|
||||
lv_indev_set_read_cb(indev, my_touchpad_read);
|
||||
|
||||
/* Option 1: Create a simple label
|
||||
* ---------------------
|
||||
*/
|
||||
lv_obj_t *label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_text(label, "Hello Arduino, I'm LVGL!(V" GFX_STR(LVGL_VERSION_MAJOR) "." GFX_STR(LVGL_VERSION_MINOR) "." GFX_STR(LVGL_VERSION_PATCH) ")");
|
||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
/* Option 2: Try an example. See all the examples
|
||||
* - Online: https://docs.lvgl.io/master/examples.html
|
||||
* - Source codes: https://github.com/lvgl/lvgl/tree/master/examples
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
// lv_example_btn_1();
|
||||
|
||||
/* Option 3: Or try out a demo. Don't forget to enable the demos in lv_conf.h. E.g. LV_USE_DEMOS_WIDGETS
|
||||
* -------------------------------------------------------------------------------------------
|
||||
*/
|
||||
// lv_demo_widgets();
|
||||
// lv_demo_benchmark();
|
||||
// lv_demo_keypad_encoder();
|
||||
// lv_demo_music();
|
||||
// lv_demo_stress();
|
||||
}
|
||||
|
||||
Serial.println("Setup done");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
lv_task_handler(); /* let the GUI do its work */
|
||||
|
||||
#ifdef DIRECT_MODE
|
||||
#if defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)
|
||||
gfx->flush();
|
||||
#else // !(defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
|
||||
gfx->draw16bitRGBBitmap(0, 0, (uint16_t *)disp_draw_buf, screenWidth, screenHeight);
|
||||
#endif // !(defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
|
||||
#else // !DIRECT_MODE
|
||||
#ifdef CANVAS
|
||||
gfx->flush();
|
||||
#endif
|
||||
#endif // !DIRECT_MODE
|
||||
|
||||
delay(5);
|
||||
}
|
||||
@ -0,0 +1,205 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -0,0 +1,238 @@
|
||||
/*******************************************************************************
|
||||
* LVGL Benchmark
|
||||
* This is a benchmark demo for LVGL - Light and Versatile Graphics Library
|
||||
* import from: https://github.com/lvgl/lv_demos.git
|
||||
*
|
||||
* Dependent libraries:
|
||||
* LVGL: https://github.com/lvgl/lvgl.git
|
||||
*
|
||||
* LVGL Configuration file:
|
||||
* Copy your_arduino_path/libraries/lvgl/lv_conf_template.h
|
||||
* to your_arduino_path/libraries/lv_conf.h
|
||||
*
|
||||
* In lv_conf.h around line 15, enable config file:
|
||||
* #if 1 // Set it to "1" to enable content
|
||||
*
|
||||
* Then find and set:
|
||||
* #define LV_COLOR_DEPTH 16
|
||||
* #define LV_TICK_CUSTOM 1
|
||||
*
|
||||
* For SPI/parallel 8 display set color swap can be faster, parallel 16/RGB screen don't swap!
|
||||
* #define LV_COLOR_16_SWAP 1 // for SPI and parallel 8
|
||||
* #define LV_COLOR_16_SWAP 0 // for parallel 16 and RGB
|
||||
*
|
||||
* Disable built-in Benchmark:
|
||||
* #define LV_USE_DEMO_BENCHMARK 0
|
||||
*
|
||||
* Enables support for compressed fonts:
|
||||
* #define LV_USE_FONT_COMPRESSED 1
|
||||
*
|
||||
* Customize font size:
|
||||
* #define LV_FONT_MONTSERRAT_12 1
|
||||
* #define LV_FONT_DEFAULT &lv_font_montserrat_12
|
||||
******************************************************************************/
|
||||
#include "lv_demo_benchmark.h"
|
||||
// #define DIRECT_MODE // Uncomment to enable full frame buffer
|
||||
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Please config the touch panel in touch.h
|
||||
******************************************************************************/
|
||||
#include "touch.h"
|
||||
|
||||
uint32_t screenWidth;
|
||||
uint32_t screenHeight;
|
||||
uint32_t bufSize;
|
||||
lv_disp_draw_buf_t draw_buf;
|
||||
lv_color_t *disp_draw_buf;
|
||||
lv_disp_drv_t disp_drv;
|
||||
|
||||
/* Display flushing */
|
||||
void my_disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
|
||||
{
|
||||
#ifndef DIRECT_MODE
|
||||
uint32_t w = (area->x2 - area->x1 + 1);
|
||||
uint32_t h = (area->y2 - area->y1 + 1);
|
||||
|
||||
#if (LV_COLOR_16_SWAP != 0)
|
||||
gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
|
||||
#else
|
||||
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
|
||||
#endif
|
||||
#endif // #ifndef DIRECT_MODE
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
/*Read the touchpad*/
|
||||
void my_touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
|
||||
{
|
||||
if (touch_has_signal())
|
||||
{
|
||||
if (touch_touched())
|
||||
{
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
|
||||
/*Set the coordinates*/
|
||||
data->point.x = touch_last_x;
|
||||
data->point.y = touch_last_y;
|
||||
}
|
||||
else if (touch_released())
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
#ifdef DEV_DEVICE_INIT
|
||||
DEV_DEVICE_INIT();
|
||||
#endif
|
||||
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
// while(!Serial);
|
||||
Serial.print("Arduino_GFX LVGL Benchmark example ");
|
||||
String LVGL_Arduino = String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
|
||||
Serial.println(LVGL_Arduino);
|
||||
|
||||
// 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());
|
||||
|
||||
lv_init();
|
||||
|
||||
screenWidth = gfx->width();
|
||||
screenHeight = gfx->height();
|
||||
|
||||
#ifdef DIRECT_MODE
|
||||
bufSize = screenWidth * screenHeight;
|
||||
#else
|
||||
bufSize = screenWidth * 40;
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
#if defined(DIRECT_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
|
||||
disp_draw_buf = (lv_color_t *)gfx->getFramebuffer();
|
||||
#else // !(defined(DIRECT_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)))
|
||||
disp_draw_buf = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (!disp_draw_buf)
|
||||
{
|
||||
// remove MALLOC_CAP_INTERNAL flag try again
|
||||
disp_draw_buf = (lv_color_t *)heap_caps_malloc(bufSize * 2, MALLOC_CAP_8BIT);
|
||||
}
|
||||
#endif // !(defined(DIRECT_MODE) && (defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)))
|
||||
#else // !ESP32
|
||||
Serial.println("LVGL disp_draw_buf heap_caps_malloc failed! malloc again...");
|
||||
disp_draw_buf = (lv_color_t *)malloc(bufSize * 2);
|
||||
#endif // !ESP32
|
||||
if (!disp_draw_buf)
|
||||
{
|
||||
Serial.println("LVGL disp_draw_buf allocate failed!");
|
||||
}
|
||||
else
|
||||
{
|
||||
lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, bufSize);
|
||||
|
||||
/* Initialize the display */
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
/* Change the following line to your display resolution */
|
||||
disp_drv.hor_res = screenWidth;
|
||||
disp_drv.ver_res = screenHeight;
|
||||
disp_drv.flush_cb = my_disp_flush;
|
||||
disp_drv.draw_buf = &draw_buf;
|
||||
#ifdef DIRECT_MODE
|
||||
disp_drv.direct_mode = true;
|
||||
#endif
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
/* Initialize the (dummy) input device driver */
|
||||
static lv_indev_drv_t indev_drv;
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = my_touchpad_read;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
|
||||
lv_demo_benchmark();
|
||||
}
|
||||
|
||||
Serial.println("Setup done");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
lv_timer_handler(); /* let the GUI do its work */
|
||||
|
||||
#ifdef DIRECT_MODE
|
||||
#if defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL)
|
||||
gfx->flush();
|
||||
#else // !(defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
|
||||
#if (LV_COLOR_16_SWAP != 0)
|
||||
gfx->draw16bitBeRGBBitmap(0, 0, (uint16_t *)disp_draw_buf, screenWidth, screenHeight);
|
||||
#else
|
||||
gfx->draw16bitRGBBitmap(0, 0, (uint16_t *)disp_draw_buf, screenWidth, screenHeight);
|
||||
#endif
|
||||
#endif // !(defined(CANVAS) || defined(RGB_PANEL) || defined(DSI_PANEL))
|
||||
#else // !DIRECT_MODE
|
||||
#ifdef CANVAS
|
||||
gfx->flush();
|
||||
#endif
|
||||
#endif // !DIRECT_MODE
|
||||
|
||||
delay(5);
|
||||
}
|
||||