commit 4f5d2aa6503f54289386d58eaaae3b3a1a951d11 Author: monjack Date: Fri Jan 10 15:20:33 2025 +0800 first commit diff --git a/ESP01-IMAS/.gitignore b/ESP01-IMAS/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/ESP01-IMAS/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/ESP01-IMAS/.vscode/extensions.json b/ESP01-IMAS/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/ESP01-IMAS/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/ESP01-IMAS/include/README b/ESP01-IMAS/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/ESP01-IMAS/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/ESP01-IMAS/lib/README b/ESP01-IMAS/lib/README new file mode 100644 index 0000000..2593a33 --- /dev/null +++ b/ESP01-IMAS/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/ESP01-IMAS/platformio.ini b/ESP01-IMAS/platformio.ini new file mode 100644 index 0000000..108ee1d --- /dev/null +++ b/ESP01-IMAS/platformio.ini @@ -0,0 +1,15 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp12e] +platform = espressif8266 +board = esp12e +framework = arduino +lib_deps = bblanchon/ArduinoJson@^7.2.1 diff --git a/ESP01-IMAS/src/main.cpp b/ESP01-IMAS/src/main.cpp new file mode 100644 index 0000000..00b0117 --- /dev/null +++ b/ESP01-IMAS/src/main.cpp @@ -0,0 +1,124 @@ +#include +#include + +// Wi-Fi 连接信息 +const char *ssid = "Xiaomi_3A40"; +const char *password = "112233ww"; + +// 服务器信息 +const char *serverIP = "192.168.31.184"; // 服务器 IP 地址 +const int serverPort = 80; // 端口号 +const char *requestPath = "/ESP01/getData.php"; // 请求路径 + +#define Sleep_Pin 2 + +void setup() +{ + Serial.begin(115200); + WiFi.begin(ssid, password); + + // 连接到 Wi-Fi + Serial.print("Connecting to Wi-Fi"); + while (WiFi.status() != WL_CONNECTED) + { + delay(1000); + Serial.print("."); + } + Serial.println("\nWi-Fi connected!"); + + pinMode(Sleep_Pin, OUTPUT); + digitalWrite(Sleep_Pin, LOW); +} + +void loop() +{ + // 确保 Wi-Fi 连接正常 + if (WiFi.status() != WL_CONNECTED) + { + Serial.println("Wi-Fi disconnected, reconnecting..."); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) + { + delay(1000); + Serial.print("."); + } + Serial.println("\nReconnected to Wi-Fi!"); + } + + // 创建客户端 + WiFiClient client; + + if (client.connect(serverIP, serverPort)) + { + Serial.println("Connected to server"); + + // 发送 GET 请求 + client.println(String("GET ") + requestPath + " HTTP/1.1"); + client.println(String("Host: ") + serverIP); + client.println("Connection: close"); + client.println(); + + // 等待响应 + while (client.connected() || client.available()) + { + if (client.available()) + { + String line = client.readStringUntil('\n'); + if (line == "\r") + { + break; // 头部结束 + } + } + } + + // 读取 JSON 数据 + String jsonData; + while (client.available()) + { + jsonData += client.readString(); + } + + // 打印获取到的 JSON 数据 + Serial.println("Received JSON:"); + Serial.println(jsonData); + + // 解析 JSON 数据 + StaticJsonDocument<512> doc; + DeserializationError error = deserializeJson(doc, jsonData); + if (error) + { + Serial.print("Failed to parse JSON: "); + Serial.println(error.c_str()); + return; + } + + // 提取 JSON 数据 + if (doc.containsKey("standby")) + { + String standby = doc["standby"]; + Serial.print("Standby mode: "); + Serial.println(standby); + if (standby == "1") + { + Serial.println("Standby mode"); + digitalWrite(Sleep_Pin, HIGH); // 打开休眠模式 + } + else + { + Serial.println("Normal mode"); + digitalWrite(Sleep_Pin, LOW); // 关闭休眠模式 + } + } + else + { + Serial.println("Key 'standby' not found in JSON data"); + } + } + else + { + Serial.println("Failed to connect to server"); + } + + // 延时一段时间再发送下一次请求 + delay(100); +} diff --git a/ESP01-IMAS/test/README b/ESP01-IMAS/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/ESP01-IMAS/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/STM32-IMAS/.gitignore b/STM32-IMAS/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/STM32-IMAS/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/STM32-IMAS/.vscode/extensions.json b/STM32-IMAS/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/STM32-IMAS/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/STM32-IMAS/include/README b/STM32-IMAS/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/STM32-IMAS/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/STM32-IMAS/include/weather_icon.h b/STM32-IMAS/include/weather_icon.h new file mode 100644 index 0000000..80c593b --- /dev/null +++ b/STM32-IMAS/include/weather_icon.h @@ -0,0 +1,69 @@ +#define __HEIGHT 64 +#define __WIDTH 64 + +// array size is 40000 +unsigned char cloudy_icon[__HEIGHT * __WIDTH] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x92, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x9b, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x97, 0xbf, 0x00, 0x00, 0x00, 0x92, 0x7b, 0x7b, 0x7b, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x97, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x97, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x93, 0x92, 0xff, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xbf, 0x77, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9b, 0x1f, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x9f, 0x57, 0x97, 0xbf, 0xbf, 0xbf, 0x56, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x92, 0x92, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0xb7, 0x97, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x00, 0x1f, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xbf, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x9b, 0x9b, 0x00, 0xff, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xbf, 0x9b, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x93, 0x00, 0x1f, 0x9b, 0x9f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x9f, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x93, 0x9b, 0x7b, 0x9b, 0x9b, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x9b, 0x9b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x77, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x9b, 0x7b, 0x97, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x9b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x57, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x77, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x9b, 0x7b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x7b, 0x9b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, 0x9b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x7b, 0x9b, 0x9b, 0x9b, 0x7b, 0x7b, 0x9b, 0x7b, 0x7b, 0x7b, 0x9b, 0x9b, 0x9b, 0x7b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x7b, 0x9b, 0x9b, 0x7b, 0x7b, 0x9b, 0x7b, 0x9b, 0x9b, 0x7b, 0x7b, 0x7b, 0x7b, 0x96, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x9f, 0x57, 0x56, 0x56, 0x57, 0x57, 0x57, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x96, 0xbf, 0x57, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; \ No newline at end of file diff --git a/STM32-IMAS/lib/README b/STM32-IMAS/lib/README new file mode 100644 index 0000000..2593a33 --- /dev/null +++ b/STM32-IMAS/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/STM32-IMAS/platformio.ini b/STM32-IMAS/platformio.ini new file mode 100644 index 0000000..e6f0bdd --- /dev/null +++ b/STM32-IMAS/platformio.ini @@ -0,0 +1,23 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:genericSTM32F103RC] +platform = ststm32 +board = genericSTM32F103RC +framework = arduino +upload_protocol = serial +upload_speed = 500000 +lib_deps = + adafruit/Adafruit Unified Sensor@^1.1.14 + adafruit/DHT sensor library@^1.4.6 + bodmer/TFT_eSPI@^2.5.43 + bblanchon/ArduinoJson@^7.2.1 + adafruit/Adafruit GFX Library@^1.11.11 + adafruit/Adafruit SSD1306@^2.5.13 diff --git a/STM32-IMAS/src/main.cpp b/STM32-IMAS/src/main.cpp new file mode 100644 index 0000000..21b8271 --- /dev/null +++ b/STM32-IMAS/src/main.cpp @@ -0,0 +1,340 @@ + /* + An example digital clock using a TFT LCD screen to show the time. + Demonstrates use of the font printing routines. (Time updates but date does not.) + + It uses the time of compile/upload to set the time + For a more accurate clock, it would be better to use the RTClib library. + But this is just a demo... + + Make sure all the display driver and pin connections are correct by + editing the User_Setup.h file in the TFT_eSPI library folder. + + ######################################################################### + ###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ###### + ######################################################################### + + Based on clock sketch by Gilchrist 6/2/2014 1.0 + + A few colour codes: + + code color + 0x0000 Black + 0xFFFF White + 0xBDF7 Light Gray + 0x7BEF Dark Gray + 0xF800 Red + 0xFFE0 Yellow + 0xFBE0 Orange + 0x79E0 Brown + 0x7E0 Green + 0x7FF Cyan + 0x1F Blue + 0xF81F Pink + + */ + /******************************/ + // #define TFT_CS PB12 + // #define TFT_RST PB10 + // #define TFT_DC PB1 + + // #define TFT_MOSI PA7 + // #define TFT_SCLK PA5 + // #define TFT_MISO PA6 + + // #define TOUCH_CS PB15 + #include + #include // TFT 库 + #include // SPI 库 + #include "DHT.h" + #include "Wire.h" + #include "Adafruit_GFX.h" + #include "Adafruit_SSD1306.h" + #include "weather_icon.h" + #include "stm32f1xx_hal.h" + #include "ArduinoJson.h" + + + #define DHTPIN PA1 + #define DHTTYPE DHT11 // DHT 11 + + +#define MAX_IMAGE_WIDTH 200 // Adjust for your images + + // 定义OLED显示屏的尺寸 + #define SCREEN_WIDTH 128 // OLED display width, in pixels + #define SCREEN_HEIGHT 64 // OLED display height, in pixels + + #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) + #define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 + Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); + DHT dht(DHTPIN, DHTTYPE); + + TFT_eSPI tft = TFT_eSPI(); // 创建 TFT 对象 + + HardwareSerial serial1(PA10, PA9); // RX, TX + HardwareSerial serial2(PA3, PA2); // RX, TX + + char receivedData0[100]; // 用于存储接收到的数据 + // char receivedData[100]; // 用于存储接收到的数据 + String receivedData; // 用于存储接收到的数据 + int dataIndex = 0; // 数据接收指针 + int braceCount = 0; // 用于跟踪大括号的数量 + + String jsonBuffer = ""; // 用于存储接收的 JSON 数据 + bool isJsonComplete = false; // 标记 JSON 是否完整 + + String humidityStr = ""; + String temperatureStr = ""; + String fahrenheitStr = ""; + + String data = ""; + + enum weather{ + SUNNY = 1, + CLOUDY, + RAINY, + SNOWY, + WINDY, + FOG, + UNKNOWN + }; + + // PNG png; // PNG decoder instance + + // int16_t xpos = 100; + // int16_t ypos = 100; + + + // void pngDraw(PNGDRAW *pDraw); + void displayData(const char *data); // 显示接收到的数据 + void displayLocalData(String data); + // void pngDraw(PNGDRAW *pDraw); + void serialEvent1(); + void parseJson(); + + void setup() + { + + // 初始化I²C + Wire.begin(); + + // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally + if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) + { + Serial.println(F("SSD1306 allocation failed")); + for (;;) + ; // Don't proceed, loop forever + } + + // 初始化 TFT 屏幕 + tft.init(); + tft.setRotation(2); // 设置屏幕方向 + tft.fillScreen(TFT_WHITE); // 清屏 + + dht.begin(); // 初始化 DHT 传感器 + serial1.begin(115200); + serial2.begin(115200); + + + } + + void loop() + { + + float h = dht.readHumidity(); + // Read temperature as Celsius (the default) + float t = dht.readTemperature(); + // Read temperature as Fahrenheit (isFahrenheit = true) + float f = dht.readTemperature(true); + + // Check if any reads failed and exit early (to try again). + if (isnan(h) || isnan(t) || isnan(f)) + { + Serial.println(F("Failed to read from DHT sensor!")); + display.clearDisplay(); // 清屏 + display.setCursor(0, 0); + display.setTextColor(SSD1306_WHITE); // Draw white text + display.setTextSize(2); // Normal 1:1 pixel scale + display.println(F("Failed to read from DHT sensor!")); + return; + } + + // serialEvent(); // 检查串口数据 + humidityStr = String(h,2); + temperatureStr = String(t,2); + fahrenheitStr = String(f,2); + + serial1.print("Humidity: "); + serial1.print(humidityStr); + serial1.print("%\n"); + serial1.print("Temperature: "); + serial1.print(temperatureStr); + serial1.print("C\n"); + + serial2.print("Humidity: "); + serial2.print(humidityStr); + serial2.print("%\n"); + serial2.print("Temperature: "); + serial2.print(temperatureStr); + serial2.print("C\n"); + + data = "Humidity: " + humidityStr + "%\n" + "Temperature: " + temperatureStr + "C\n" + "Fahrenheit: " + fahrenheitStr + "F\n"; + + serial1.print(data); // 打印接收到的数据 + + display.clearDisplay(); // Clear display + display.setTextSize(1); // Normal 1:1 pixel scale + display.setTextColor(SSD1306_WHITE); // Draw white text + display.setCursor(0, 0); // Start at top-left corner + display.print(F("Temperature: ")); + display.print(temperatureStr); + display.println(F("C")); + + display.display(); + // displayLocalData(data); // 显示接收到的数据 + + // serialEvent1(); // 检查串口数据 + } + + void serialEvent(){ + // 检查是否有数据传入 + if (serial2.available()) + { + // 从串口读取一个字符 + char incomingByte = serial2.read(); + serial1.print(incomingByte); // 打印接收到的字符 + + // 如果接收到换行符或最大长度限制,则显示数据 + if (incomingByte == '\n' || dataIndex >= 100) + { + receivedData0[dataIndex] = '\0'; // 结束字符串 + displayData(receivedData0); // 显示数据 + dataIndex = 0; // 重置接收指针 + } + else + { + receivedData0[dataIndex++] = incomingByte; // 将字符存入缓冲区 + } + } + + // int16_t rc = png.openFLASH((uint8_t *)cloudy_icon, sizeof(cloudy_icon), pngDraw); + // if (rc == PNG_SUCCESS) + // { + // Serial.printf("image specs: (%d x %d), %d bpp, pixel type: %d\n", png.getWidth(), png.getHeight(), png.getBpp(), png.getPixelType()); + // tft.startWrite(); + // uint32_t dt = millis(); + // rc = png.decode(NULL, 0); + // Serial.print(millis() - dt); + // Serial.println("ms"); + // tft.endWrite(); + // // png.close(); // not needed for memory->memory decode + // } + } + + void displayData(const char *data) + { + // 清除屏幕内容 + tft.fillScreen(TFT_BLACK); + + // 在屏幕上显示接收到的数据 + tft.setCursor(10, 10); // 设置光标位置 + tft.setTextSize(2); // 设置文本大小 + tft.setTextColor(TFT_YELLOW, TFT_BLACK); // 设置文本颜色 + tft.println("Received Data: "); + tft.setCursor(10, 26); // 设置光标位置 + tft.setTextColor(TFT_WHITE, TFT_BLACK); // 设置文本颜色 + tft.setTextSize(3); // 设置文本大小 + tft.println(data); // 显示接收到的数据 + // tft.drawRect(10, 26, 300, 100, TFT_BLACK); // 绘制矩形框 + delay(1000); // 延时 5 秒 + } + + void displayLocalData(String data) + { + tft.setFreeFont(NULL); // 选择默认字体 + // 在屏幕上显示接收到的数据 + tft.setTextColor(TFT_RED, TFT_WHITE); // 设置文本颜色 + // tft.drawRect(10, 26, 300, 100, TFT_WHITE); // 绘制矩形框 + tft.setCursor(10, 0, 1); // 设置光标位置 + tft.setTextSize(2); // 设置文本大小 + tft.println(data); // + delay(1000); // 延时 5 秒 + } + + // void pngDraw(PNGDRAW *pDraw) + // { + // uint16_t lineBuffer[MAX_IMAGE_WIDTH]; + // png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff); + // tft.pushImage(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer); + // } + + // void serialEvent1() + // { + // while (serial2.available() > 0) + // { + // char c = serial2.read(); // 读取单个字符 + // jsonBuffer += c; // 拼接到缓冲区 + // // 读取串口数据 + + // if (c == '{') + // { + // braceCount++; + // } + // if (c == '}') + // { + // braceCount--; + // } + // if (braceCount == 0) + // { + // isJsonComplete = true; + // } + // } + // if (isJsonComplete) + // { + // serial1.println("Received complete JSON:"); + // serial1.println(jsonBuffer); + // parseJson(); + // // 处理完 JSON 数据后,清空缓冲区 + // jsonBuffer = ""; + // isJsonComplete = false; + // } + + // } + + // void parseJson() + // { + // StaticJsonDocument<512> doc; // 根据你的JSON数据大小调整这个值 + // DeserializationError error = deserializeJson(doc, jsonBuffer); + // if (error) + // { + // // 如果解析失败,打印错误信息 + // serial1.printf("deserializeJson() failed: %s\n", error.c_str()); + // return; + // } + + // // 解析成功后,你可以通过doc来访问JSON中的数据 + // const char *temperature = doc["lives"][0]["temperature"]; + // const char *humidity = doc["lives"][0]["humidity"]; + // const char *weather = doc["lives"][0]["weather"]; + // const char *city = doc["lives"][0]["city"]; + // // 根据你的JSON结构添加更多的键 + + // serial1.printf("temperature: %s\n", temperature); + // serial1.printf("humidity: %s\n", humidity); + // serial1.printf("weather: %s\n", weather); + // serial1.printf("city: %s\n", city); + // serial1.println(); + // // 处理其他键的数据 + + // // 你可以在这里将解析得到的数据发送到TFT屏幕或其他处理 + // tft.setCursor(10, 100, 2); + // tft.setTextColor(TFT_BLACK, TFT_WHITE); // 设置文本颜色 + // tft.setTextSize(1); // 设置文本大小 + // tft.println("city:" + String(city)); // 显示城市名称 + // tft.setCursor(10, 120, 2); + // tft.println("Temperature: " + String(temperature) + "C"); + // tft.setCursor(10, 136, 2); + // tft.println("Humidity: " + String(humidity) + "%"); + // tft.setCursor(10, 152, 2); + // tft.println("Weather: " + String(weather)); + // } \ No newline at end of file diff --git a/STM32-IMAS/test/README b/STM32-IMAS/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/STM32-IMAS/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/TFT-ESP32/.gitignore b/TFT-ESP32/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/TFT-ESP32/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/TFT-ESP32/.vscode/extensions.json b/TFT-ESP32/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/TFT-ESP32/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/TFT-ESP32/data/san28.bin b/TFT-ESP32/data/san28.bin new file mode 100644 index 0000000..c914ca4 Binary files /dev/null and b/TFT-ESP32/data/san28.bin differ diff --git a/TFT-ESP32/include/README b/TFT-ESP32/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/TFT-ESP32/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/TFT-ESP32/lib/README b/TFT-ESP32/lib/README new file mode 100644 index 0000000..2593a33 --- /dev/null +++ b/TFT-ESP32/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/TFT-ESP32/platformio.ini b/TFT-ESP32/platformio.ini new file mode 100644 index 0000000..25b86f7 --- /dev/null +++ b/TFT-ESP32/platformio.ini @@ -0,0 +1,42 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32dev] +platform = espressif32 +board = esp32dev +framework = arduino +lib_deps = + bodmer/TFT_eSPI@^2.5.43 + bblanchon/ArduinoJson@^7.2.1 + bodmer/JPEGDecoder@^2.0.0 +build_flags = + -Os + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -DUSER_SETUP_LOADED=1 + -DTFT_INVERSION_ON=1 + -DILI9341_DRIVER=1 + -DTFT_WIDTH=320 + -DTFT_HEIGHT=240 + -DTFT_MISO=19 + -DTFT_MOSI=23 + -DTFT_SCLK=18 + -DTFT_CS=15 + -DTFT_DC=2 + -DTFT_RST=4 + -DTOUCH_CS=33 + -DLOAD_GLCD=1 + -DLOAD_FONT2=1 + -DLOAD_FONT4=1 + -DLOAD_FONT6=1 + -DLOAD_FONT7=1 + -DLOAD_FONT8=1 + -DLOAD_GFXFF=1 + -DSMOOTH_FONT=1 + -DSPI_FREQUENCY=27000000 diff --git a/TFT-ESP32/src/main.cpp b/TFT-ESP32/src/main.cpp new file mode 100644 index 0000000..a383da8 --- /dev/null +++ b/TFT-ESP32/src/main.cpp @@ -0,0 +1,768 @@ +// Font file is stored on SD card +#include +#include + +// Graphics and font library +#include +#include + +#include +#include +#include + +#include +#include + +#define SD_CS 22 // Set GPIO 5 as chip select for SD card +#define LED_PIN 14 // Set GPIO 14 as LED output +#define HUMIDIFIER_PIN 13 // Set GPIO 13 as humidifier output +// TX (发送):GPIO16(UART2_TXD) +// RX (接收):GPIO17(UART2_RXD) + +#define MAX_IMAGE_WIDTH 240 +int16_t xpos = 0; +int16_t ypos = 0; + +const char *ssid = "Xiaomi_3A40"; +const char *password = "112233ww"; + +const char *jsonUrl = "http://monjack.cn/weatherInfo.php"; +const char *postUrl = "http://192.168.131.51/postLocalData.php"; +const char *postStatusUrl = "http://192.168.131.51/postStatus.php"; + +int dataIndex = 0; +char receivedData0[100]; // 用于存储接收到的数据 +HardwareSerial serial2(2); // UART1 实例化 + +float local_humidity = 0.0; +float temp_local_humidity = 0.0; +float local_temperature = 0.0; +float temp_local_temperature = 0.0; + +u8_t standby = 0; +u8_t reboot = 0; +u8_t humidifier = 1; +u8_t screen = 1; + +bool boot = true; + +String weather = "晴"; +String temp_weather = ""; +String temperature = "25"; +String temp_temperature = ""; +String humidity = "60"; +String temp_humidity = ""; +String wind_direction = "东北"; +String temp_wind_direction = ""; + +String comfort_clothing = "穿短裙、短裤、短袖、短外套"; + +SemaphoreHandle_t xMutex; + +TFT_eSPI tft = TFT_eSPI(); // Invoke library + +void showTime(uint32_t msTime) +{ + // tft.setCursor(0, 0); + // tft.setTextFont(1); + // tft.setTextSize(2); + // tft.setTextColor(TFT_WHITE, TFT_BLACK); + // tft.print(F(" JPEG drawn in ")); + // tft.print(msTime); + // tft.println(F(" ms ")); + Serial.print(F(" JPEG drawn in ")); + Serial.print(msTime); + Serial.println(F(" ms ")); +} + +// #################################################################################################### +// Draw a JPEG on the TFT, images will be cropped on the right/bottom sides if they do not fit +// #################################################################################################### +// This function assumes xpos,ypos is a valid screen coordinate. For convenience images that do not +// fit totally on the screen are cropped to the nearest MCU size and may leave right/bottom borders. +void jpegRender(int xpos, int ypos) +{ + + // jpegInfo(); // Print information from the JPEG file (could comment this line out) + + uint16_t *pImg; + uint16_t mcu_w = JpegDec.MCUWidth; + uint16_t mcu_h = JpegDec.MCUHeight; + uint32_t max_x = JpegDec.width; + uint32_t max_y = JpegDec.height; + + bool swapBytes = tft.getSwapBytes(); + tft.setSwapBytes(true); + + // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs) + // Typically these MCUs are 16x16 pixel blocks + // Determine the width and height of the right and bottom edge image blocks + uint32_t min_w = jpg_min(mcu_w, max_x % mcu_w); + uint32_t min_h = jpg_min(mcu_h, max_y % mcu_h); + + // save the current image block size + uint32_t win_w = mcu_w; + uint32_t win_h = mcu_h; + + // record the current time so we can measure how long it takes to draw an image + uint32_t drawTime = millis(); + + // save the coordinate of the right and bottom edges to assist image cropping + // to the screen size + max_x += xpos; + max_y += ypos; + + // Fetch data from the file, decode and display + while (JpegDec.read()) + { // While there is more data in the file + pImg = JpegDec.pImage; // Decode a MCU (Minimum Coding Unit, typically a 8x8 or 16x16 pixel block) + + // Calculate coordinates of top left corner of current MCU + int mcu_x = JpegDec.MCUx * mcu_w + xpos; + int mcu_y = JpegDec.MCUy * mcu_h + ypos; + + // check if the image block size needs to be changed for the right edge + if (mcu_x + mcu_w <= max_x) + win_w = mcu_w; + else + win_w = min_w; + + // check if the image block size needs to be changed for the bottom edge + if (mcu_y + mcu_h <= max_y) + win_h = mcu_h; + else + win_h = min_h; + + // copy pixels into a contiguous block + if (win_w != mcu_w) + { + uint16_t *cImg; + int p = 0; + cImg = pImg + win_w; + for (int h = 1; h < win_h; h++) + { + p += mcu_w; + for (int w = 0; w < win_w; w++) + { + *cImg = *(pImg + w + p); + cImg++; + } + } + } + + // calculate how many pixels must be drawn + uint32_t mcu_pixels = win_w * win_h; + + // draw image MCU block only if it will fit on the screen + if ((mcu_x + win_w) <= tft.width() && (mcu_y + win_h) <= tft.height()) + tft.pushImage(mcu_x, mcu_y, win_w, win_h, pImg); + else if ((mcu_y + win_h) >= tft.height()) + JpegDec.abort(); // Image has run off bottom of screen so abort decoding + } + + tft.setSwapBytes(swapBytes); + + showTime(millis() - drawTime); // These lines are for sketch testing only +} + +// #################################################################################################### +// Print image information to the serial port (optional) +// #################################################################################################### +// JpegDec.decodeFile(...) or JpegDec.decodeArray(...) must be called before this info is available! +void jpegInfo() +{ + + // Print information extracted from the JPEG file + Serial.println("JPEG image info"); + Serial.println("==============="); + Serial.print("Width :"); + Serial.println(JpegDec.width); + Serial.print("Height :"); + Serial.println(JpegDec.height); + Serial.print("Components :"); + Serial.println(JpegDec.comps); + Serial.print("MCU / row :"); + Serial.println(JpegDec.MCUSPerRow); + Serial.print("MCU / col :"); + Serial.println(JpegDec.MCUSPerCol); + Serial.print("Scan type :"); + Serial.println(JpegDec.scanType); + Serial.print("MCU width :"); + Serial.println(JpegDec.MCUWidth); + Serial.print("MCU height :"); + Serial.println(JpegDec.MCUHeight); + Serial.println("==============="); + Serial.println(""); +} + +// #################################################################################################### +// Show the execution time (optional) +// #################################################################################################### +// WARNING: for UNO/AVR legacy reasons printing text to the screen with the Mega might not work for +// sketch sizes greater than ~70KBytes because 16-bit address pointers are used in some libraries. + +// The Due will work fine with the HX8357_Due library. +void listDir(fs::FS &fs, const char *dirname, uint8_t levels); +void serialEvent(); +void ParseData(char *data); +void displayTask(void *parameter); +void fetchDataTask(void *parameters); +void parseJson(String jsonData); +void getWeatherInfo(); +void postData(); +void postStatus(); +void parseJson2(String jsonData); +void checkStatusTask(void *parameters); +void drawSdJpeg(const char *filename, int xpos, int ypos); + +// ------------------------------------------------------------------------- +// Setup +// ------------------------------------------------------------------------- +void setup(void) +{ + Serial.begin(115200); // Used for messages + serial2.begin(115200); // Used for messages + Serial.println("UART2 initialized"); + + // Connect to WiFi + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) + { + delay(1000); + Serial.println("Connecting to WiFi..."); + } + Serial.println("Connected to WiFi"); + + // 设置SPI频率为40MHz + SPISettings spiSettings(40000000, MSBFIRST, SPI_MODE0); + + // Initialise the SD library before the TFT so the chip select is defined + if (!SD.begin(SD_CS)) + { + Serial.println("Card Mount Failed"); + return; + } + // Initialise the TFT after the SD card! + tft.init(); + tft.setRotation(3); + tft.fillScreen(TFT_BLACK); + listDir(SD, "/", 0); + pinMode(LED_PIN, OUTPUT); // Set LED pin as output + pinMode(HUMIDIFIER_PIN, OUTPUT); // Set humidifier pin as output + digitalWrite(LED_PIN, HIGH); // Turn on LED + digitalWrite(HUMIDIFIER_PIN, HIGH); // Turn on humidifier + Serial.println("SD and TFT initialisation done."); + + Serial.println("👌👌👌👌"); + postStatus(); + + int x = 0; + int y = 0; + + drawSdJpeg("/Photos/background.jpg", x, y); // This draws a jpeg pulled off the SD Card + + + // 配置 GPIO 触发唤醒 + esp_sleep_enable_ext0_wakeup(GPIO_NUM_35, 0); // GPIO_NUM_35 为低电平唤醒 + + // 创建互斥锁 + xMutex = xSemaphoreCreateMutex(); + + // 创建任务 + xTaskCreate(displayTask, "Display Task", 4096, NULL, 1, NULL); + xTaskCreate(fetchDataTask, "Fetch Data Task", 4096, NULL, 2, NULL); + xTaskCreate(checkStatusTask, "Check Status Task", 4096, NULL, 3, NULL); +} + +// ------------------------------------------------------------------------- +// Main loop +// ------------------------------------------------------------------------- +void loop() +{ + +} + +void fetchDataTask(void *parameters){ + while (true) + { + getWeatherInfo(); + + postData(); + + vTaskDelay(500 / portTICK_PERIOD_MS); // 每0.5秒获取一次JSON数据 + } +} + +void getWeatherInfo(){ + if (WiFi.status() == WL_CONNECTED) + { + HTTPClient http; + + // 配置HTTP请求 + http.begin(jsonUrl); + + // 发送HTTP GET请求 + int httpCode = http.GET(); + + if (httpCode > 0) + { + // 如果请求成功 + if (httpCode == HTTP_CODE_OK) + { + String payload = http.getString(); // 获取响应字符串 + Serial.println("Received JSON data:"); + Serial.println(payload); + + // 解析JSON数据 + parseJson(payload); + } + } + else + { + // 如果请求失败 + Serial.print("Error on sending GET: "); + Serial.println(http.errorToString(httpCode).c_str()); + } + + http.end(); // 结束HTTP请求 + } + else + { + Serial.println("Error in WiFi connection"); + } +} + +void postStatus() +{ + if (WiFi.status() == WL_CONNECTED) + { + HTTPClient http; + // 配置HTTP请求 + http.begin(postStatusUrl); + // 设置HTTP头部 + http.addHeader("Content-Type", "application/json"); + StaticJsonDocument<100> doc; + doc["standby"] = standby; + doc["reboot"] = reboot; + doc["humidifier"] = humidifier; + doc["screen"] = screen; + + // 序列化JSON数据 + String jsonPayload; + serializeJson(doc, jsonPayload); + Serial.print("JSON Payload: "); + Serial.println(jsonPayload); + + // 发送HTTP POST请求 + int httpCode = http.POST(jsonPayload); + if (httpCode > 0) + { + // 如果请求成功 + if (httpCode == HTTP_CODE_OK) + { + String payload = http.getString(); // 获取响应字符串 + Serial.println("poststatus状态信息:"); + Serial.println(payload); + // 解析JSON数据 + parseJson2(payload); + } + else + { + Serial.print("Unexpected HTTP code: "); + Serial.println(httpCode); + } + } + else + { + // 如果请求失败 + Serial.print("Error on sending POST: "); + Serial.println(http.errorToString(httpCode).c_str()); + } + + http.end(); // 结束HTTP请求 + } + else + { + Serial.println("WiFi is not connected."); + } +} + +void postData() +{ + if (WiFi.status() == WL_CONNECTED) + { + HTTPClient http; + // 配置HTTP请求 + http.begin(postUrl); + + // 设置HTTP头部 + http.addHeader("Content-Type", "application/json"); + + StaticJsonDocument<200> doc; + doc["Humidity"] = local_humidity; + doc["Temperature"] = local_temperature; + + // 序列化JSON数据 + String jsonPayload; + serializeJson(doc, jsonPayload); + + Serial.print("JSON Payload: "); + Serial.println(jsonPayload); + + // 发送HTTP POST请求 + int httpCode = http.POST(jsonPayload); + if (httpCode > 0) + { + // 如果请求成功 + if (httpCode == HTTP_CODE_OK) + { + String payload = http.getString(); // 获取响应字符串 + Serial.println("状态信息:"); + Serial.println(payload); + // 解析JSON数据 + parseJson2(payload); + + } + } + else + { + // 如果请求失败 + Serial.print("Error on sending POST: "); + Serial.println(http.errorToString(httpCode).c_str()); + } + + http.end(); // 结束HTTP请求 + } + else + { + Serial.println("Error in WiFi connection"); + } +} + +//解析天气情况 +void parseJson(String jsonData){ + // 定义JSON文档的大小,根据实际情况调整 + const size_t capacity = JSON_OBJECT_SIZE(2) + 300; + StaticJsonDocument doc; + + // 解析JSON数据 + DeserializationError error = deserializeJson(doc, jsonData); + if (error) + { + Serial.print("deserializeJson() failed: "); + Serial.println(error.c_str()); + return; + } + + // 获取JSON中的值 + String newHumidity = doc["lives"][0]["humidity"] | "0.0"; + String newTemperature = doc["lives"][0]["temperature"] | "0.0"; + String newWeather = doc["lives"][0]["weather"] | "晴"; + String newWindDirection = doc["lives"][0]["winddirection"] | "东北"; + if(newTemperature.toInt()<4){ + comfort_clothing = "棉衣或羽绒服"; + }else if(newTemperature.toInt()<10){ + comfort_clothing = "厚外套"; + }else if(newTemperature.toInt()<20){ + comfort_clothing = "薄外套、长袖"; + }else{ + comfort_clothing = "短外套、短裤、短裙"; + } + + Serial.print("newHumidity: "); + Serial.println(newHumidity); + Serial.print("newTemperature: "); + Serial.println(newTemperature); + Serial.print("Weather: "); + Serial.println(newWeather); + Serial.print("WindDirection: "); + Serial.println(newWindDirection); + // 获取互斥锁 + if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) + { + humidity = newHumidity; + temperature = newTemperature; + weather = newWeather; + wind_direction = newWindDirection; + // 释放互斥锁 + xSemaphoreGive(xMutex); + } +} + +//解析状态信息 +void parseJson2(String jsonData){ + // 定义JSON文档的大小,根据实际情况调整 + const size_t capacity = JSON_OBJECT_SIZE(2) + 300; + StaticJsonDocument doc; + + // 解析JSON数据 + DeserializationError error = deserializeJson(doc, jsonData); + + if (error) + { + Serial.print("deserializeJson() failed: "); + Serial.println(error.c_str()); + return; + } + + // 获取JSON中的值 + u8_t newStandby = doc["standby"].as(); + u8_t newReboot = doc["reboot"].as(); + u8_t newHumidifier = doc["humidifier"].as(); + u8_t newScreen = doc["screen"].as(); + + Serial.print("😊😊screen::😊😊"); + Serial.println(newScreen); + Serial.print("😊😊standby::😊😊"); + Serial.println(newStandby); + Serial.print("😊😊reboot::😊😊"); + Serial.println(newReboot); + Serial.print("😊😊humidifier::😊😊"); + Serial.println(newHumidifier); + + // 获取互斥锁 + if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) + { + standby = newStandby; + reboot = newReboot; + humidifier = newHumidifier; + screen = newScreen; + // 释放互斥锁 + xSemaphoreGive(xMutex); + } + +} + +void displayTask(void *parameter) +{ + while (true) + { + // Check for incoming serial data + serialEvent(); + + // Name of font file (library adds leading / and .vlw) + String fileName = "MiSan20Chinese"; + + if(boot){ + tft.loadFont(fileName, SD); + tft.setTextColor(0x5ACB, TFT_WHITE, true); + tft.setCursor(30, 135); + tft.print("病房空气指标"); + boot = false; + tft.loadFont("BigFonts45", SD); + tft.setCursor(50, 160); + tft.print("良好"); + } + tft.loadFont(fileName, SD); // Use font stored on SD + if (temp_local_temperature != local_temperature) + { + tft.loadFont("MiddleNumFonts25", SD); + tft.setTextColor(0x5ACB, TFT_WHITE, true); + tft.fillRect(220, 195, 70, 20, TFT_WHITE); // Clear screen + tft.setCursor(220, 195); + tft.print(local_temperature); + tft.println("℃"); + temp_local_temperature = local_temperature; + } + if (temp_local_humidity != local_humidity) + { + tft.loadFont("MiddleNumFonts25",SD); + tft.setTextColor(0x5ACB, TFT_WHITE, true); + tft.fillRect(220, 140, 70, 20, TFT_WHITE); // Clear screen + tft.setCursor(220, 140); + tft.print(local_humidity); + tft.println("%"); + + temp_local_humidity = local_humidity; + } + tft.setTextColor(TFT_WHITE, TFT_BLACK); + if(temp_weather != weather) + { + tft.loadFont("BigFonts45", SD); + tft.setTextColor(TFT_WHITE, 0x5873FF, true); + drawSdJpeg("/Photos/cloudy.jpg",23,20); + tft.setCursor(112, 20); + tft.print(weather); + temp_weather = weather; + } + if(temp_temperature != temperature){ + tft.loadFont(fileName, SD); + tft.setTextColor(TFT_WHITE, 0x5873FF,true); + tft.setCursor(240, 20); + tft.print(temperature); + tft.print("℃"); + temp_temperature = temperature; + } + if(temp_humidity != humidity){ + tft.setTextColor(TFT_WHITE, 0x5873FF,true); + tft.setCursor(240, 60); + tft.print(humidity); + tft.print("%"); + temp_humidity = humidity; + } + // if(temp_wind_direction != wind_direction){ + // tft.fillRect(80,130,60,20,TFT_BLACK); + // tft.print(" "); + // tft.print(wind_direction); + // tft.print("风"); + // temp_wind_direction = wind_direction; + // } + + vTaskDelay(1000 / portTICK_PERIOD_MS); // 每1秒刷新一次屏幕 + } +} + +void checkStatusTask(void *parameters){ + while (true) + { + if(screen == 1){ + digitalWrite(LED_PIN, HIGH); // Turn on LED + }else{ + digitalWrite(LED_PIN, LOW); // Turn off LED + } + if(reboot == 1){ + if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE){ + reboot = 0; + xSemaphoreGive(xMutex); + } + postStatus(); + delay(1000); + ESP.restart(); + } + if(standby == 1){ + Serial.println("进入待机模式"); + delay(1000); + esp_light_sleep_start(); // 进入低功耗模式 + } + if(humidifier == 1){ + digitalWrite(HUMIDIFIER_PIN, HIGH); // Turn on humidifier + }else{ + digitalWrite(HUMIDIFIER_PIN, LOW); // Turn off humidifier + } + vTaskDelay(500 / portTICK_PERIOD_MS); // 每0.秒检查一次数据 + } +} + +void listDir(fs::FS & fs, const char *dirname, uint8_t levels) +{ + Serial.printf("Listing directory: %s\n", dirname); + + File root = fs.open(dirname); + if (!root) + { + Serial.println("Failed to open directory"); + return; + } + if (!root.isDirectory()) + { + Serial.println("Not a directory"); + return; + } + + File file = root.openNextFile(); + while (file) + { + if (file.isDirectory()) + { + Serial.print(" DIR : "); + Serial.println(file.name()); + if (levels) + { + listDir(fs, file.name(), levels - 1); + } + } + else + { + Serial.print(" FILE: "); + Serial.print(file.name()); + Serial.print(" SIZE: "); + Serial.println(file.size()); + } + file = root.openNextFile(); + } +} + +void serialEvent() +{ + // 检查是否有数据传入 + while (serial2.available()) + { + // 从串口读取一个字符 + char incomingByte = serial2.read(); + + // 如果接收到换行符或最大长度限制,则显示数据 + if (incomingByte == '\n' || dataIndex >= 100) + { + receivedData0[dataIndex] = '\0'; // 结束字符串 + ParseData(receivedData0); // 显示数据 + // Serial.println(receivedData0); + dataIndex = 0; // 重置接收指针 + } + else + { + receivedData0[dataIndex++] = incomingByte; // 将字符存入缓冲区 + } + } +} + +void ParseData(char *data) // 解析数据 +{ + char *token = strtok(data, ":"); + while (token != NULL) + { + char *value = strtok(NULL, "C\r\n"); + if (value != NULL) + { + if (strcmp(token, "Humidity") == 0) + { + local_humidity = atof(value); + Serial.print("Humidity: "); + Serial.println(local_humidity); + } + else if (strcmp(token, "Temperature") == 0) + { + local_temperature = atof(value); + Serial.print("Temperature: "); + Serial.println(local_temperature); + } + } + token = strtok(NULL, ":"); + } +} + +void drawSdJpeg(const char *filename, int xpos, int ypos) +{ + + // Open the named file (the Jpeg decoder library will close it) + File jpegFile = SD.open(filename, FILE_READ); // or, file handle reference for SD library + + if (!jpegFile) + { + Serial.print("ERROR: File \""); + Serial.print(filename); + Serial.println("\" not found!"); + return; + } + + Serial.println("==========================="); + Serial.print("Drawing file: "); + Serial.println(filename); + Serial.println("==========================="); + + // Use one of the following methods to initialise the decoder: + bool decoded = JpegDec.decodeSdFile(jpegFile); // Pass the SD file handle to the decoder, + // bool decoded = JpegDec.decodeSdFile(filename); // or pass the filename (String or character array) + + if (decoded) + { + // print information about the image to the serial port + jpegInfo(); + // render the image onto the screen at given coordinates + jpegRender(xpos, ypos); + } + else + { + Serial.println("Jpeg file format not supported!"); + } +} diff --git a/TFT-ESP32/test/README b/TFT-ESP32/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/TFT-ESP32/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/TFT-ESP32/test/test.cpp b/TFT-ESP32/test/test.cpp new file mode 100644 index 0000000..552173d --- /dev/null +++ b/TFT-ESP32/test/test.cpp @@ -0,0 +1,82 @@ +#include // TFT 显示屏库 + +TFT_eSPI tft = TFT_eSPI(); // 初始化 TFT 实例 + +const int screenWidth = 240; // 根据你的屏幕分辨率设置 +const int screenHeight = 320; +const int byteWidth = (screenWidth + 7) / 8; // 每行需要的字节数 + +// 数组用于存储二值化后的屏幕数据 +uint8_t binaryImage[screenHeight][byteWidth]; + +// 将屏幕数据读取并二值化,存储到数组中 +void binaryScreenToArray() +{ + for (int y = 0; y < screenHeight; y++) + { + uint8_t byteValue = 0; + for (int x = 0; x < screenWidth; x++) + { + // 读取像素颜色 + uint16_t color = tft.readPixel(x, y); + + // 将颜色二值化(假设TFT_WHITE为白色,其它为黑色) + if (color == TFT_WHITE) + { + byteValue |= (1 << (7 - (x % 8))); // 设置当前位为1(白色) + } + + // 每8个像素存储为一个字节 + if (x % 8 == 7 || x == screenWidth - 1) + { + binaryImage[y][x / 8] = byteValue; + byteValue = 0; + } + } + } +} + +// 将二值化后的屏幕数据通过串口发送到电脑,值之间用逗号隔开 +void sendArrayToPC() +{ + Serial.println("Start sending binary screen data:"); + + for (int y = 0; y < screenHeight; y++) + { + for (int x = 0; x < byteWidth; x++) + { + Serial.print(binaryImage[y][x], HEX); // 以十六进制格式发送每个字节 + + // 如果不是最后一个字节,则添加逗号 + if (x < byteWidth - 1) + { + Serial.print(","); // 用逗号分隔 + } + } + Serial.println(); // 每行结束后换行 + } + + Serial.println("Binary screen data sent."); +} + +void setup() +{ + Serial.begin(115200); // 初始化串口通信 + tft.init(); // 初始化屏幕 + tft.setRotation(1); // 根据需要设置屏幕的旋转 + tft.fillScreen(TFT_BLACK); // 将屏幕设置为黑色 + + // 绘制一些内容(测试用) + tft.fillCircle(120, 160, 50, TFT_WHITE); // 在屏幕中间绘制一个白色的圆圈 + + // 读取并二值化屏幕内容 + binaryScreenToArray(); + + // 将二值化后的数组通过串口传输到电脑 + sendArrayToPC(); +} + +void loop() +{ + // 主要功能在 setup 中执行,loop 中不做任何操作 +} diff --git a/TFT-ESP32/test/testmain.cpp b/TFT-ESP32/test/testmain.cpp new file mode 100644 index 0000000..9e05f28 --- /dev/null +++ b/TFT-ESP32/test/testmain.cpp @@ -0,0 +1,111 @@ +// +// FILE: [main.cpp] +// Created by GUIslice Builder version: [0.17.b34] +// +// GUIslice Builder Generated File +// +// For the latest guides, updates and support view: +// https://github.com/ImpulseAdventure/GUIslice +// +// + +// ------------------------------------------------ +// Headers to include +// ------------------------------------------------ +#include "GUIsliceProjects_GSLC.h" + +// ------------------------------------------------ +// Program Globals +// ------------------------------------------------ + +// Save some element references for direct access +// +// + +// Define debug message function +static int16_t DebugOut(char ch) +{ + if (ch == (char)'\n') + Serial.println(""); + else + Serial.write(ch); + return 0; +} + +// ------------------------------------------------ +// Callback Methods +// ------------------------------------------------ +// Common Button callback +bool CbBtnCommon(void *pvGui, void *pvElemRef, gslc_teTouch eTouch, int16_t nX, int16_t nY) +{ + // Typecast the parameters to match the GUI and element types + gslc_tsGui *pGui = (gslc_tsGui *)(pvGui); + gslc_tsElemRef *pElemRef = (gslc_tsElemRef *)(pvElemRef); + gslc_tsElem *pElem = gslc_GetElemFromRef(pGui, pElemRef); + + if (eTouch == GSLC_TOUCH_UP_IN) + { + // From the element's ID we can determine which button was pressed. + switch (pElem->nId) + { + //