first commit
This commit is contained in:
78
.gitignore
vendored
Normal file
78
.gitignore
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# macOS
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Directory metadata
|
||||
.directory
|
||||
|
||||
# Temporary files
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
*.bak
|
||||
*.tmp
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
|
||||
# Build artifacts and directories
|
||||
**/build/
|
||||
build/
|
||||
*.o
|
||||
*.a
|
||||
*.out
|
||||
*.exe # For any host-side utilities compiled on Windows
|
||||
|
||||
# ESP-IDF specific build outputs
|
||||
*.bin
|
||||
*.elf
|
||||
*.map
|
||||
flasher_args.json # Generated in build directory
|
||||
sdkconfig.old
|
||||
sdkconfig
|
||||
|
||||
# ESP-IDF dependencies
|
||||
# For older versions or manual component management
|
||||
/components/.idf/
|
||||
**/components/.idf/
|
||||
# For modern ESP-IDF component manager
|
||||
managed_components/
|
||||
# If ESP-IDF tools are installed/referenced locally to the project
|
||||
.espressif/
|
||||
|
||||
# CMake generated files
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
CTestTestfile.cmake
|
||||
|
||||
# Python environment files
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
__pycache__/
|
||||
*.egg-info/
|
||||
dist/
|
||||
|
||||
# Virtual environment folders
|
||||
venv/
|
||||
.venv/
|
||||
env/
|
||||
|
||||
# Language Servers
|
||||
.clangd/
|
||||
.ccls-cache/
|
||||
compile_commands.json
|
||||
|
||||
# Windows specific
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# User-specific configuration files
|
||||
*.user
|
||||
*.workspace # General workspace files, can be from various tools
|
||||
*.suo # Visual Studio Solution User Options
|
||||
*.sln.docstates # Visual Studio
|
||||
6
CMakeLists.txt
Executable file
6
CMakeLists.txt
Executable file
@@ -0,0 +1,6 @@
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(BotanicalBuddy)
|
||||
164
CONSOLE_SIMPLE_INIT_BLOG_ZH.md
Normal file
164
CONSOLE_SIMPLE_INIT_BLOG_ZH.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 用 `console_simple_init` 给 ESP-IDF 项目加一个可交互控制台(中文实践)
|
||||
|
||||
很多时候我们在调 ESP32 项目时,会遇到这种场景:
|
||||
|
||||
- 想临时执行一个命令看状态
|
||||
- 想在线触发某个动作(比如开关某个外设)
|
||||
- 不想每次都改代码、烧录、再看日志
|
||||
|
||||
这时候,一个可交互的 Console 就非常有价值。
|
||||
|
||||
这篇文章记录一个通用做法:在任何 ESP-IDF 项目里,用 `espressif/console_simple_init` 快速接入命令行控制台。
|
||||
|
||||
## 一、为什么用它
|
||||
|
||||
原生 `esp_console` 功能很完整,但初始化流程相对分散。`console_simple_init` 的价值在于把常用步骤封装成了 4 个 API:
|
||||
|
||||
- `console_cmd_init()`:初始化控制台
|
||||
- `console_cmd_user_register()`:注册用户命令
|
||||
- `console_cmd_all_register()`:自动注册插件命令
|
||||
- `console_cmd_start()`:启动 REPL
|
||||
|
||||
一句话:快速可用,适合先跑通再扩展。
|
||||
|
||||
## 二、接入步骤
|
||||
|
||||
### 1. 添加组件依赖
|
||||
|
||||
```bash
|
||||
idf.py add-dependency "espressif/console_simple_init^1.1.0"
|
||||
```
|
||||
|
||||
或者在 `idf_component.yml` 里手动添加:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
idf: ">=5.0"
|
||||
espressif/console_simple_init: ^1.1.0
|
||||
```
|
||||
|
||||
### 2. 在 CMake 里声明依赖
|
||||
|
||||
在你的组件 `CMakeLists.txt`(例如 `main/CMakeLists.txt`)里:
|
||||
|
||||
```cmake
|
||||
idf_component_register(
|
||||
SRCS "main.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES console_simple_init console
|
||||
)
|
||||
```
|
||||
|
||||
这里建议把 `console` 显式写上,能避免一类常见的 include/IntelliSense 问题(后文会讲)。
|
||||
|
||||
### 3. 在代码里初始化并注册命令
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include "esp_check.h"
|
||||
#include "console_simple_init.h"
|
||||
|
||||
static int cmd_hello(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
printf("hello from console\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// 你的项目里需确保 NVS 和默认事件循环已初始化
|
||||
|
||||
ESP_ERROR_CHECK(console_cmd_init());
|
||||
ESP_ERROR_CHECK(console_cmd_user_register("hello", cmd_hello));
|
||||
ESP_ERROR_CHECK(console_cmd_all_register()); // 可选
|
||||
ESP_ERROR_CHECK(console_cmd_start());
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 烧录后验证
|
||||
|
||||
```bash
|
||||
idf.py flash monitor
|
||||
```
|
||||
|
||||
在 `esp>` 提示符输入:
|
||||
|
||||
- `help`
|
||||
- `hello`
|
||||
|
||||
如果能看到输出,说明接入成功。
|
||||
|
||||
## 三、一个很常见的坑
|
||||
|
||||
### 现象
|
||||
|
||||
- `#include "console_simple_init.h"` 报 include 错
|
||||
- 或提示找不到 `esp_console.h`
|
||||
|
||||
### 本质
|
||||
|
||||
`console_simple_init.h` 会依赖 `esp_console.h`。如果你的组件没有显式依赖 `console`,编辑器索引有时会解析不到。
|
||||
|
||||
### 解决
|
||||
|
||||
1. CMake 增加 `REQUIRES console`
|
||||
2. 执行:
|
||||
|
||||
```bash
|
||||
idf.py reconfigure
|
||||
idf.py build
|
||||
```
|
||||
|
||||
3. 在 VS Code 刷新索引(Reset IntelliSense Database + Reload Window)
|
||||
|
||||
## 四、另一个常见坑:串口写入超时
|
||||
|
||||
### 现象
|
||||
|
||||
Monitor 日志里反复出现:
|
||||
|
||||
- `Writing to serial is timing out...`
|
||||
|
||||
### 本质
|
||||
|
||||
Console 所用的通道(UART / USB CDC / USB Serial/JTAG)和你当前 monitor 连接端口不一致。
|
||||
|
||||
### 解决
|
||||
|
||||
在 `menuconfig` 里把 console 输出通道配置成和你实际连接一致:
|
||||
|
||||
- `Component config -> ESP System Settings -> Channel for console output`
|
||||
|
||||
改完后重新 build + flash。
|
||||
|
||||
## 五、为什么它适合做“运维入口”
|
||||
|
||||
当项目复杂起来后,你会很自然地需要这些命令:
|
||||
|
||||
- `status`:看系统状态
|
||||
- `sensor`:看传感器实时值
|
||||
- `pump on/off`:控制执行器
|
||||
- `wifi status`:看联网状态
|
||||
|
||||
有了 console,这些能力都能在不改 UI 的情况下快速加上。
|
||||
|
||||
## 六、我建议的演进路线
|
||||
|
||||
1. 先做 1~2 个命令跑通链路
|
||||
2. 加参数解析和错误提示
|
||||
3. 按模块分组命令(sensor/io/net)
|
||||
4. 给危险动作加确认机制
|
||||
|
||||
## 七、总结
|
||||
|
||||
`console_simple_init` 的优势不是“功能比 `esp_console` 更多”,而是把接入门槛降得很低:
|
||||
|
||||
- 依赖加上
|
||||
- 几个 API 调用
|
||||
- 很快就能得到可交互的调试入口
|
||||
|
||||
对于早期开发和现场调试,它能显著减少反复烧录的成本。
|
||||
|
||||
|
||||
174
CONSOLE_SIMPLE_INIT_TUTORIAL.md
Normal file
174
CONSOLE_SIMPLE_INIT_TUTORIAL.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# ESP-IDF `console_simple_init` Tutorial (Project-Independent)
|
||||
|
||||
This guide is a standalone tutorial for adding and using `espressif/console_simple_init` in any ESP-IDF project.
|
||||
|
||||
## 1. What This Component Does
|
||||
|
||||
`console_simple_init` is a convenience wrapper around ESP-IDF console/REPL setup.
|
||||
|
||||
It provides these APIs:
|
||||
|
||||
- `console_cmd_init()`
|
||||
- `console_cmd_user_register()`
|
||||
- `console_cmd_all_register()`
|
||||
- `console_cmd_start()`
|
||||
|
||||
Header:
|
||||
|
||||
```c
|
||||
#include "console_simple_init.h"
|
||||
```
|
||||
|
||||
## 2. Add Dependency
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
idf.py add-dependency "espressif/console_simple_init^1.1.0"
|
||||
```
|
||||
|
||||
Or edit your component manifest (`idf_component.yml`):
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
idf: ">=5.0"
|
||||
espressif/console_simple_init: ^1.1.0
|
||||
```
|
||||
|
||||
## 3. Declare CMake Dependency
|
||||
|
||||
In your component `CMakeLists.txt` (for example `main/CMakeLists.txt`):
|
||||
|
||||
```cmake
|
||||
idf_component_register(
|
||||
SRCS "main.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES console_simple_init console
|
||||
)
|
||||
```
|
||||
|
||||
Why include `console` explicitly?
|
||||
|
||||
- `console_simple_init.h` uses `esp_console.h`.
|
||||
- Explicit `REQUIRES console` avoids include path and IntelliSense issues.
|
||||
|
||||
## 4. Minimal Working Example
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include "esp_check.h"
|
||||
#include "console_simple_init.h"
|
||||
|
||||
static int cmd_hello(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
printf("hello from console\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// Ensure required system init is done in your app:
|
||||
// - NVS initialized
|
||||
// - default event loop created
|
||||
|
||||
ESP_ERROR_CHECK(console_cmd_init());
|
||||
ESP_ERROR_CHECK(console_cmd_user_register("hello", cmd_hello));
|
||||
ESP_ERROR_CHECK(console_cmd_all_register()); // optional
|
||||
ESP_ERROR_CHECK(console_cmd_start());
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Preconditions
|
||||
|
||||
Before starting console, make sure your app has initialized:
|
||||
|
||||
- NVS (`nvs_flash_init`)
|
||||
- default event loop (`esp_event_loop_create_default`)
|
||||
|
||||
If your project already has a network/bootstrap module, these may already be done.
|
||||
|
||||
## 6. How to Use at Runtime
|
||||
|
||||
1. Flash firmware.
|
||||
2. Open monitor (`idf.py monitor`).
|
||||
3. At prompt `esp>`, type:
|
||||
|
||||
```text
|
||||
help
|
||||
hello
|
||||
```
|
||||
|
||||
## 7. Console Channel Selection (Important)
|
||||
|
||||
Pick the console channel to match your physical connection:
|
||||
|
||||
- UART
|
||||
- USB CDC
|
||||
- USB Serial/JTAG
|
||||
|
||||
If channel and monitor port do not match, you may see warnings like write timeout when typing commands.
|
||||
|
||||
Configure via `menuconfig`:
|
||||
|
||||
- `Component config -> ESP System Settings -> Channel for console output`
|
||||
|
||||
Then rebuild and flash.
|
||||
|
||||
## 8. Common Issues
|
||||
|
||||
### Issue A: `#include` errors for `console_simple_init.h` or `esp_console.h`
|
||||
|
||||
Checklist:
|
||||
|
||||
- Added dependency in `idf_component.yml`
|
||||
- Added `REQUIRES console_simple_init console` in `CMakeLists.txt`
|
||||
- Re-run:
|
||||
|
||||
```bash
|
||||
idf.py reconfigure
|
||||
idf.py build
|
||||
```
|
||||
|
||||
- Refresh editor index/IntelliSense
|
||||
|
||||
### Issue B: Serial port busy while flashing
|
||||
|
||||
Another monitor/process holds the port.
|
||||
|
||||
- Close monitor first
|
||||
- Retry `idf.py flash`
|
||||
|
||||
### Issue C: Console starts but input behaves poorly
|
||||
|
||||
Your terminal may not support escape sequences/history editing.
|
||||
|
||||
Use a terminal that supports VT sequences.
|
||||
|
||||
## 9. Next Step Ideas
|
||||
|
||||
- Add commands for system status (`status`)
|
||||
- Add commands for peripheral control (`pump on`, `light off`)
|
||||
- Add argument parsing and help text
|
||||
- Group commands by module for maintainability
|
||||
|
||||
## 10. Quick Command Template
|
||||
|
||||
Use this template to add a command quickly:
|
||||
|
||||
```c
|
||||
static int cmd_name(int argc, char **argv)
|
||||
{
|
||||
// parse args
|
||||
// run logic
|
||||
// print result
|
||||
return 0;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(console_cmd_user_register("name", cmd_name));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
This tutorial is intentionally generic so it can be reused in any ESP-IDF codebase.
|
||||
198
README.md
Normal file
198
README.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# BotanicalBuddy
|
||||
|
||||
基于 ESP-IDF 的智能盆栽系统固件项目(ESP32-C3)。
|
||||
|
||||
当前结论:单片机端核心功能已完成,可直接联调 App/小程序侧。
|
||||
|
||||
## 固件完成度
|
||||
|
||||
- 环境采集:土壤湿度、空气温湿度、光照强度
|
||||
- 本地显示:LCD + LVGL 多页面轮播
|
||||
- 设备控制:水泵、补光灯(高电平有效)
|
||||
- 自动控制:阈值 + 回差控制
|
||||
- 手动控制:MQTT 远程开关泵/灯
|
||||
- 模式切换:`auto` / `manual`
|
||||
- 告警推送:超阈值边沿事件上报
|
||||
- 状态上报:周期性遥测(含模式与执行器状态)
|
||||
- Wi-Fi 配网:SoftAP + Captive Portal
|
||||
- 状态网页:独立 HTTP 状态看板与 JSON API(端口 8080)
|
||||
|
||||
## 系统架构
|
||||
|
||||
- `main/`:业务编排、控制循环、MQTT 回调对接
|
||||
- `components/wifi-connect/`:配网与路由连接
|
||||
- `components/lvgl_st7735s_use/`:LCD 与 LVGL 端口
|
||||
- `components/ui/`:界面对象与变量绑定
|
||||
- `components/i2c_master_messager/`:AHT30、BH1750 采集
|
||||
- `components/capactive_soil_moisture_sensor_V2.0/`:土壤湿度采集
|
||||
- `components/io_device_control/`:水泵/补光灯 GPIO 控制
|
||||
- `components/mqtt_control/`:MQTT 连接、发布、控制指令解析
|
||||
- `main/auto_ctrl_thresholds.*`:阈值存取与校验
|
||||
- `main/auto_alerts.*`:告警判定与回调分发
|
||||
- `main/status_web.*`:独立状态网页服务(HTTP 8080)
|
||||
|
||||
## 状态网页(独立于配网页)
|
||||
|
||||
- 配网页面:`http://192.168.4.1`(仅 SoftAP 配网阶段)
|
||||
- 状态页面:`http://<设备STA_IP>:8080/`
|
||||
- 状态 API:`http://<设备STA_IP>:8080/api/status`
|
||||
|
||||
说明:
|
||||
- 两个网页服务独立运行,端口不同、职责不同。
|
||||
- 状态页用于运行态观测,不承载 Wi-Fi 配网流程。
|
||||
|
||||
`/api/status` 当前主要字段:
|
||||
- `temp`、`hum`、`soil`、`lux`:传感器字符串值
|
||||
- `pump`、`light`:执行器状态(`on/off`)
|
||||
- `mode`:控制模式(`auto/manual`)
|
||||
- `soil_on`、`soil_off`、`light_on`、`light_off`:自动控制阈值
|
||||
- `wifi_status`:Wi-Fi 状态(`idle/provisioning/connecting/connected/failed/timeout`)
|
||||
- `sta_ip`:STA 当前 IP
|
||||
- `mqtt_connected`:MQTT 连接状态(布尔)
|
||||
- `i2c_ready`、`soil_sensor_ready`:关键外设初始化状态(布尔)
|
||||
- `loop_counter`:主循环计数
|
||||
- `uptime_ms`:设备运行时长(毫秒)
|
||||
- `free_heap`、`min_free_heap`、`largest_block`:堆内存指标
|
||||
- `app_version`:固件版本字符串
|
||||
- `snapshot_update_ms`、`snapshot_update_count`、`snapshot_age_ms`:状态快照时间与更新统计
|
||||
|
||||
## 运行逻辑
|
||||
|
||||
1. 上电初始化 Wi-Fi、LCD、传感器、IO。
|
||||
2. Wi-Fi 连通后启动 MQTT 与 Console。
|
||||
3. 主循环每 1s 执行:
|
||||
- 采集传感器并刷新 UI 数据。
|
||||
- 若 `mode=auto`,按阈值进行泵灯自动控制。
|
||||
- 进行告警边沿判定并发布告警消息。
|
||||
- 每 5s 发布一次状态遥测消息。
|
||||
4. 收到 MQTT 控制消息时:
|
||||
- 可切模式(`auto/manual`)。
|
||||
- 可更新阈值(四个阈值需同条下发)。
|
||||
- 可手动控制泵灯开关。
|
||||
|
||||
## 开发环境
|
||||
|
||||
- Linux
|
||||
- ESP-IDF `v5.5.2`
|
||||
- 目标芯片:`esp32c3`
|
||||
|
||||
## 编译与烧录
|
||||
|
||||
1. 配置环境变量
|
||||
```bash
|
||||
export IDF_PATH=/home/beihong/esp/v5.5.2/esp-idf
|
||||
source $IDF_PATH/export.sh
|
||||
```
|
||||
|
||||
2. 构建
|
||||
```bash
|
||||
idf.py set-target esp32c3
|
||||
idf.py build
|
||||
```
|
||||
|
||||
3. 烧录并监视日志
|
||||
```bash
|
||||
idf.py -p /dev/ttyACM0 flash monitor
|
||||
```
|
||||
|
||||
## MQTT 协议
|
||||
|
||||
### ESP32 -> WEX
|
||||
|
||||
1. 告警消息主题:`topic/alert/esp32_iothome_001`
|
||||
|
||||
```json
|
||||
{
|
||||
"metric": "light",
|
||||
"state": "alarm"
|
||||
}
|
||||
```
|
||||
|
||||
字段:
|
||||
- `metric`:`soil` 或 `light`
|
||||
- `state`:`normal` 或 `alarm`
|
||||
|
||||
2. 状态消息主题:`topic/sensor/esp32_BotanicalBuddy_001`
|
||||
|
||||
```json
|
||||
{
|
||||
"temp": "34.3",
|
||||
"hum": "30.5",
|
||||
"soil": "0",
|
||||
"lux": "40",
|
||||
"pump": "on",
|
||||
"light": "off",
|
||||
"mode": "auto",
|
||||
"soil_on": 35.0,
|
||||
"soil_off": 45.0,
|
||||
"light_on": 100.0,
|
||||
"light_off": 350.0
|
||||
}
|
||||
```
|
||||
|
||||
字段:
|
||||
- `pump`:`on/off`
|
||||
- `light`:`on/off`
|
||||
- `mode`:`auto/manual`
|
||||
- `soil_on`:土壤湿度低阈值(低于该值自动开泵)
|
||||
- `soil_off`:土壤湿度高阈值(高于该值自动关泵)
|
||||
- `light_on`:光照低阈值(低于该值自动开灯)
|
||||
- `light_off`:光照高阈值(高于该值自动关灯)
|
||||
|
||||
### WEX -> ESP32
|
||||
|
||||
控制主题:`topic/control/esp32_BotanicalBuddy_001`
|
||||
|
||||
1. 切换模式
|
||||
```json
|
||||
{ "mode": "manual" }
|
||||
```
|
||||
```json
|
||||
{ "mode": "auto" }
|
||||
```
|
||||
|
||||
2. 手动控制(建议先切到 `manual`)
|
||||
```json
|
||||
{ "pump": "on", "light": "off" }
|
||||
```
|
||||
|
||||
3. 更新自动阈值(四个字段需同时下发)
|
||||
```json
|
||||
{
|
||||
"soil_on": 35,
|
||||
"soil_off": 45,
|
||||
"light_on": 100,
|
||||
"light_off": 350
|
||||
}
|
||||
```
|
||||
|
||||
4. 混合下发(同一条消息可同时包含模式、阈值、手动开关)
|
||||
```json
|
||||
{
|
||||
"mode": "auto",
|
||||
"soil_on": 35,
|
||||
"soil_off": 45,
|
||||
"light_on": 100,
|
||||
"light_off": 350,
|
||||
"pump": "off",
|
||||
"light": "on"
|
||||
}
|
||||
```
|
||||
|
||||
兼容输入:
|
||||
- `pump/light` 支持 `on/off`、`true/false`、`1/0`
|
||||
- `mode` 支持 `auto/manual`,也兼容 `true/false`、`1/0`(`true/1=auto`)
|
||||
|
||||
## 联调建议
|
||||
|
||||
1. 先下发 `{"mode":"manual"}`,验证手动泵灯控制。
|
||||
2. 再下发阈值并切 `{"mode":"auto"}`,观察自动控制接管。
|
||||
3. 注意阈值含回差:
|
||||
- 土壤:`soil_on` 开泵,`soil_off` 关泵
|
||||
- 光照:`light_on` 开灯,`light_off` 关灯
|
||||
|
||||
## 说明
|
||||
|
||||
- 当前 README 聚焦单片机固件能力与联调协议。
|
||||
- App/小程序页面与云端业务可按本协议直接对接。
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "capactive_soil_moisture_sensor_V2.0.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES esp_adc)
|
||||
@@ -0,0 +1,172 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "esp_adc/adc_cali.h"
|
||||
#include "esp_adc/adc_cali_scheme.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "capactive_soil_moisture_sensor_V2.0.h"
|
||||
|
||||
static const char *TAG = "cap_soil_v2";
|
||||
|
||||
static adc_oneshot_unit_handle_t s_adc_handle = NULL;
|
||||
static adc_cali_handle_t s_cali_handle = NULL;
|
||||
static bool s_cali_enabled = false;
|
||||
static bool s_inited = false;
|
||||
|
||||
static cap_soil_sensor_config_t s_cfg = {
|
||||
.unit = CAP_SOIL_SENSOR_DEFAULT_UNIT,
|
||||
.channel = CAP_SOIL_SENSOR_DEFAULT_CHANNEL,
|
||||
.atten = ADC_ATTEN_DB_12,
|
||||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||
.air_raw = 620,
|
||||
.water_raw = 308,
|
||||
};
|
||||
|
||||
static float map_raw_to_percent(int raw)
|
||||
{
|
||||
// 教程经验:湿度与输出值成反比,air_raw(干) > water_raw(湿)。
|
||||
int span = s_cfg.air_raw - s_cfg.water_raw;
|
||||
if (span <= 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float percent = ((float)(s_cfg.air_raw - raw) * 100.0f) / (float)span;
|
||||
if (percent < 0.0f) {
|
||||
percent = 0.0f;
|
||||
}
|
||||
if (percent > 100.0f) {
|
||||
percent = 100.0f;
|
||||
}
|
||||
return percent;
|
||||
}
|
||||
|
||||
static cap_soil_level_t map_percent_to_level(float percent)
|
||||
{
|
||||
// 三段划分:0~33 干燥,34~66 湿润,67~100 非常潮湿。
|
||||
if (percent < 33.34f) {
|
||||
return CAP_SOIL_LEVEL_DRY;
|
||||
}
|
||||
if (percent < 66.67f) {
|
||||
return CAP_SOIL_LEVEL_MOIST;
|
||||
}
|
||||
return CAP_SOIL_LEVEL_WET;
|
||||
}
|
||||
|
||||
static esp_err_t try_create_adc_calibration(const cap_soil_sensor_config_t *cfg)
|
||||
{
|
||||
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
|
||||
adc_cali_curve_fitting_config_t cali_cfg = {
|
||||
.unit_id = cfg->unit,
|
||||
.chan = cfg->channel,
|
||||
.atten = cfg->atten,
|
||||
.bitwidth = cfg->bitwidth,
|
||||
};
|
||||
esp_err_t ret = adc_cali_create_scheme_curve_fitting(&cali_cfg, &s_cali_handle);
|
||||
if (ret == ESP_OK) {
|
||||
s_cali_enabled = true;
|
||||
ESP_LOGI(TAG, "ADC calibration enabled");
|
||||
return ESP_OK;
|
||||
}
|
||||
ESP_LOGW(TAG, "ADC calibration unavailable: %s", esp_err_to_name(ret));
|
||||
return ret;
|
||||
#else
|
||||
(void)cfg;
|
||||
ESP_LOGW(TAG, "ADC calibration scheme not supported on this target");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t cap_soil_sensor_init(const cap_soil_sensor_config_t *config)
|
||||
{
|
||||
if (s_inited) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (config != NULL) {
|
||||
s_cfg = *config;
|
||||
}
|
||||
|
||||
adc_oneshot_unit_init_cfg_t unit_cfg = {
|
||||
.unit_id = s_cfg.unit,
|
||||
.ulp_mode = ADC_ULP_MODE_DISABLE,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(adc_oneshot_new_unit(&unit_cfg, &s_adc_handle), TAG, "adc unit init failed");
|
||||
|
||||
adc_oneshot_chan_cfg_t chan_cfg = {
|
||||
.atten = s_cfg.atten,
|
||||
.bitwidth = s_cfg.bitwidth,
|
||||
};
|
||||
esp_err_t ret = adc_oneshot_config_channel(s_adc_handle, s_cfg.channel, &chan_cfg);
|
||||
if (ret != ESP_OK) {
|
||||
adc_oneshot_del_unit(s_adc_handle);
|
||||
s_adc_handle = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
(void)try_create_adc_calibration(&s_cfg);
|
||||
s_inited = true;
|
||||
ESP_LOGI(TAG,
|
||||
"sensor init ok (unit=%d, ch=%d, air_raw=%d, water_raw=%d)",
|
||||
(int)s_cfg.unit,
|
||||
(int)s_cfg.channel,
|
||||
s_cfg.air_raw,
|
||||
s_cfg.water_raw);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t cap_soil_sensor_read(cap_soil_sensor_data_t *out_data)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(out_data != NULL, ESP_ERR_INVALID_ARG, TAG, "out_data is null");
|
||||
ESP_RETURN_ON_FALSE(s_inited && s_adc_handle != NULL, ESP_ERR_INVALID_STATE, TAG, "sensor not initialized");
|
||||
|
||||
int raw = 0;
|
||||
ESP_RETURN_ON_ERROR(adc_oneshot_read(s_adc_handle, s_cfg.channel, &raw), TAG, "adc read failed");
|
||||
|
||||
int mv = -1;
|
||||
if (s_cali_enabled && s_cali_handle != NULL) {
|
||||
if (adc_cali_raw_to_voltage(s_cali_handle, raw, &mv) != ESP_OK) {
|
||||
mv = -1;
|
||||
}
|
||||
}
|
||||
|
||||
float moisture = map_raw_to_percent(raw);
|
||||
out_data->raw = raw;
|
||||
out_data->voltage_mv = mv;
|
||||
out_data->moisture_percent = moisture;
|
||||
out_data->level = map_percent_to_level(moisture);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t cap_soil_sensor_set_calibration(int air_raw, int water_raw)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(air_raw > water_raw, ESP_ERR_INVALID_ARG, TAG, "need air_raw > water_raw");
|
||||
s_cfg.air_raw = air_raw;
|
||||
s_cfg.water_raw = water_raw;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t cap_soil_sensor_deinit(void)
|
||||
{
|
||||
if (!s_inited) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (s_cali_enabled && s_cali_handle != NULL) {
|
||||
#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
|
||||
adc_cali_delete_scheme_curve_fitting(s_cali_handle);
|
||||
#endif
|
||||
s_cali_handle = NULL;
|
||||
s_cali_enabled = false;
|
||||
}
|
||||
|
||||
if (s_adc_handle != NULL) {
|
||||
ESP_RETURN_ON_ERROR(adc_oneshot_del_unit(s_adc_handle), TAG, "adc unit delete failed");
|
||||
s_adc_handle = NULL;
|
||||
}
|
||||
|
||||
s_inited = false;
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_adc/adc_oneshot.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// 你当前接在 GPIO0(ESP32-C3 对应 ADC1_CH0),这里作为默认值。
|
||||
#define CAP_SOIL_SENSOR_DEFAULT_UNIT ADC_UNIT_1
|
||||
#define CAP_SOIL_SENSOR_DEFAULT_CHANNEL ADC_CHANNEL_0
|
||||
|
||||
typedef enum {
|
||||
CAP_SOIL_LEVEL_DRY = 0,
|
||||
CAP_SOIL_LEVEL_MOIST,
|
||||
CAP_SOIL_LEVEL_WET,
|
||||
} cap_soil_level_t;
|
||||
|
||||
typedef struct {
|
||||
adc_unit_t unit;
|
||||
adc_channel_t channel;
|
||||
adc_atten_t atten;
|
||||
adc_bitwidth_t bitwidth;
|
||||
|
||||
// 标定值:空气中读数(干)通常更大,水中读数(湿)通常更小。
|
||||
int air_raw;
|
||||
int water_raw;
|
||||
} cap_soil_sensor_config_t;
|
||||
|
||||
typedef struct {
|
||||
int raw;
|
||||
int voltage_mv;
|
||||
float moisture_percent;
|
||||
cap_soil_level_t level;
|
||||
} cap_soil_sensor_data_t;
|
||||
|
||||
esp_err_t cap_soil_sensor_init(const cap_soil_sensor_config_t *config);
|
||||
esp_err_t cap_soil_sensor_read(cap_soil_sensor_data_t *out_data);
|
||||
esp_err_t cap_soil_sensor_set_calibration(int air_raw, int water_raw);
|
||||
esp_err_t cap_soil_sensor_deinit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
3
components/console_user_cmds/CMakeLists.txt
Normal file
3
components/console_user_cmds/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "console_user_cmds.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES console_simple_init console i2c_master_messager io_device_control wifi-connect capactive_soil_moisture_sensor_V2.0)
|
||||
292
components/console_user_cmds/console_user_cmds.c
Normal file
292
components/console_user_cmds/console_user_cmds.c
Normal file
@@ -0,0 +1,292 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_check.h"
|
||||
#include "console_simple_init.h"
|
||||
#include "console_user_cmds.h"
|
||||
#include "capactive_soil_moisture_sensor_V2.0.h"
|
||||
#include "i2c_master_messager.h"
|
||||
#include "io_device_control.h"
|
||||
#include "wifi-connect.h"
|
||||
|
||||
static const char *wifi_status_to_str(wifi_connect_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case WIFI_CONNECT_STATUS_IDLE:
|
||||
return "idle";
|
||||
case WIFI_CONNECT_STATUS_PROVISIONING:
|
||||
return "provisioning";
|
||||
case WIFI_CONNECT_STATUS_CONNECTING:
|
||||
return "connecting";
|
||||
case WIFI_CONNECT_STATUS_CONNECTED:
|
||||
return "connected";
|
||||
case WIFI_CONNECT_STATUS_FAILED:
|
||||
return "failed";
|
||||
case WIFI_CONNECT_STATUS_TIMEOUT:
|
||||
return "timeout";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *soil_level_to_str(cap_soil_level_t level)
|
||||
{
|
||||
switch (level) {
|
||||
case CAP_SOIL_LEVEL_DRY:
|
||||
return "dry";
|
||||
case CAP_SOIL_LEVEL_MOIST:
|
||||
return "moist";
|
||||
case CAP_SOIL_LEVEL_WET:
|
||||
return "wet";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// hello: 最小可用命令,用于验证 console 链路是否正常。
|
||||
static int cmd_hello(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
printf("hello from BotanicalBuddy\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// sensor: 读取一次传感器缓存数据并打印,便于快速排查现场状态。
|
||||
static int cmd_sensor(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
i2c_master_messager_data_t data = {0};
|
||||
esp_err_t ret = i2c_master_messager_get_data(&data);
|
||||
if (ret != ESP_OK) {
|
||||
printf("sensor read failed: %s\n", esp_err_to_name(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (data.bh1750.valid) {
|
||||
printf("BH1750: lux=%.1f, ts=%lld ms\n",
|
||||
data.bh1750.lux,
|
||||
(long long)data.bh1750.last_update_ms);
|
||||
} else {
|
||||
printf("BH1750: invalid, err=%s\n", esp_err_to_name(data.bh1750.last_error));
|
||||
}
|
||||
|
||||
if (data.aht30.valid) {
|
||||
printf("AHT30: temp=%.1f C, hum=%.1f %%, ts=%lld ms\n",
|
||||
data.aht30.temperature_c,
|
||||
data.aht30.humidity_rh,
|
||||
(long long)data.aht30.last_update_ms);
|
||||
} else {
|
||||
printf("AHT30: invalid, err=%s\n", esp_err_to_name(data.aht30.last_error));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool parse_on_off_arg(const char *arg, bool *on)
|
||||
{
|
||||
if (strcmp(arg, "on") == 0 || strcmp(arg, "1") == 0) {
|
||||
*on = true;
|
||||
return true;
|
||||
}
|
||||
if (strcmp(arg, "off") == 0 || strcmp(arg, "0") == 0) {
|
||||
*on = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// pump: 控制水泵开关,参数支持 on/off 或 1/0。
|
||||
static int cmd_pump(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("usage: pump <on|off>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool on = false;
|
||||
if (!parse_on_off_arg(argv[1], &on)) {
|
||||
printf("invalid arg: %s\n", argv[1]);
|
||||
printf("usage: pump <on|off>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
esp_err_t ret = io_device_control_set_pump(on);
|
||||
if (ret != ESP_OK) {
|
||||
printf("set pump failed: %s\n", esp_err_to_name(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("pump: %s\n", on ? "on" : "off");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// light: 控制补光灯开关,参数支持 on/off 或 1/0。
|
||||
static int cmd_light(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
printf("usage: light <on|off>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool on = false;
|
||||
if (!parse_on_off_arg(argv[1], &on)) {
|
||||
printf("invalid arg: %s\n", argv[1]);
|
||||
printf("usage: light <on|off>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
esp_err_t ret = io_device_control_set_light(on);
|
||||
if (ret != ESP_OK) {
|
||||
printf("set light failed: %s\n", esp_err_to_name(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("light: %s\n", on ? "on" : "off");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// wifi: 查询或控制配网状态,支持 status/start/stop/clear 子命令。
|
||||
static int cmd_wifi(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2 || strcmp(argv[1], "status") == 0) {
|
||||
wifi_connect_config_t cfg = {0};
|
||||
esp_err_t cfg_ret = wifi_connect_get_config(&cfg);
|
||||
printf("wifi status: %s\n", wifi_status_to_str(wifi_connect_get_status()));
|
||||
if (cfg_ret == ESP_OK && cfg.has_config) {
|
||||
printf("saved ssid: %s\n", cfg.ssid);
|
||||
} else {
|
||||
printf("saved config: none\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "start") == 0) {
|
||||
esp_err_t ret = wifi_connect_start();
|
||||
if (ret != ESP_OK) {
|
||||
printf("wifi start failed: %s\n", esp_err_to_name(ret));
|
||||
return 1;
|
||||
}
|
||||
printf("wifi start requested\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "stop") == 0) {
|
||||
esp_err_t ret = wifi_connect_stop();
|
||||
if (ret != ESP_OK) {
|
||||
printf("wifi stop failed: %s\n", esp_err_to_name(ret));
|
||||
return 1;
|
||||
}
|
||||
printf("wifi stop requested\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "clear") == 0) {
|
||||
esp_err_t ret = wifi_connect_clear_config();
|
||||
if (ret != ESP_OK) {
|
||||
printf("wifi clear failed: %s\n", esp_err_to_name(ret));
|
||||
return 1;
|
||||
}
|
||||
printf("wifi config cleared\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("usage: wifi <status|start|stop|clear>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// soil: 查询土壤湿度,或动态更新空气/水中标定值。
|
||||
static int cmd_soil(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2 || strcmp(argv[1], "read") == 0) {
|
||||
cap_soil_sensor_data_t data = {0};
|
||||
esp_err_t ret = cap_soil_sensor_read(&data);
|
||||
if (ret != ESP_OK) {
|
||||
printf("soil read failed: %s\n", esp_err_to_name(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("soil raw=%d, mv=%d, moisture=%.1f%%, level=%s\n",
|
||||
data.raw,
|
||||
data.voltage_mv,
|
||||
data.moisture_percent,
|
||||
soil_level_to_str(data.level));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "cal") == 0) {
|
||||
if (argc < 4) {
|
||||
printf("usage: soil cal <air_raw> <water_raw>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int air_raw = (int)strtol(argv[2], NULL, 10);
|
||||
int water_raw = (int)strtol(argv[3], NULL, 10);
|
||||
esp_err_t ret = cap_soil_sensor_set_calibration(air_raw, water_raw);
|
||||
if (ret != ESP_OK) {
|
||||
printf("soil cal failed: %s\n", esp_err_to_name(ret));
|
||||
printf("hint: air_raw should be greater than water_raw\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("soil calibration updated: air=%d, water=%d\n", air_raw, water_raw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("usage: soil <read|cal <air_raw> <water_raw>>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
esp_err_t console_user_cmds_register(void)
|
||||
{
|
||||
const esp_console_cmd_t hello_cmd = {
|
||||
.command = "hello",
|
||||
.help = "打印欢迎信息。用法: hello",
|
||||
.func = cmd_hello,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(esp_console_cmd_register(&hello_cmd), "console_user_cmds", "register hello failed");
|
||||
|
||||
const esp_console_cmd_t sensor_cmd = {
|
||||
.command = "sensor",
|
||||
.help = "打印当前传感器缓存数据。用法: sensor",
|
||||
.func = cmd_sensor,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(esp_console_cmd_register(&sensor_cmd), "console_user_cmds", "register sensor failed");
|
||||
|
||||
const esp_console_cmd_t pump_cmd = {
|
||||
.command = "pump",
|
||||
.help = "控制水泵。用法: pump <on|off>",
|
||||
.hint = "<on|off>",
|
||||
.func = cmd_pump,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(esp_console_cmd_register(&pump_cmd), "console_user_cmds", "register pump failed");
|
||||
|
||||
const esp_console_cmd_t light_cmd = {
|
||||
.command = "light",
|
||||
.help = "控制补光灯。用法: light <on|off>",
|
||||
.hint = "<on|off>",
|
||||
.func = cmd_light,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(esp_console_cmd_register(&light_cmd), "console_user_cmds", "register light failed");
|
||||
|
||||
const esp_console_cmd_t wifi_cmd = {
|
||||
.command = "wifi",
|
||||
.help = "Wi-Fi 状态与控制。用法: wifi <status|start|stop|clear>",
|
||||
.hint = "<status|start|stop|clear>",
|
||||
.func = cmd_wifi,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(esp_console_cmd_register(&wifi_cmd), "console_user_cmds", "register wifi failed");
|
||||
|
||||
const esp_console_cmd_t soil_cmd = {
|
||||
.command = "soil",
|
||||
.help = "土壤湿度读取与标定。用法: soil <read|cal <air_raw> <water_raw>>",
|
||||
.hint = "<read|cal>",
|
||||
.func = cmd_soil,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(esp_console_cmd_register(&soil_cmd), "console_user_cmds", "register soil failed");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
5
components/console_user_cmds/include/console_user_cmds.h
Normal file
5
components/console_user_cmds/include/console_user_cmds.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
esp_err_t console_user_cmds_register(void);
|
||||
5
components/i2c_master_messager/CMakeLists.txt
Normal file
5
components/i2c_master_messager/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
idf_component_register(
|
||||
SRCS "i2c_master_messager.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES bh1750 k0i05__esp_ahtxx esp_driver_i2c esp_driver_gpio esp_timer
|
||||
)
|
||||
38
components/i2c_master_messager/Kconfig.projbuild
Normal file
38
components/i2c_master_messager/Kconfig.projbuild
Normal file
@@ -0,0 +1,38 @@
|
||||
menu "I2C 传感器管理"
|
||||
|
||||
config I2C_MASTER_MESSAGER_ENABLE_INTERNAL_PULLUP
|
||||
bool "启用 I2C 内部上拉电阻"
|
||||
default y
|
||||
help
|
||||
启用后,SCL/SDA 会使用芯片内部上拉。
|
||||
如果你的硬件已经有外部上拉电阻,通常也可以关闭该选项。
|
||||
|
||||
config I2C_MASTER_MESSAGER_BH1750_ENABLE
|
||||
bool "启用 BH1750 光照传感器"
|
||||
default y
|
||||
help
|
||||
关闭后将不会初始化与读取 BH1750。
|
||||
|
||||
config I2C_MASTER_MESSAGER_BH1750_READ_PERIOD_MS
|
||||
int "BH1750 采样周期 (ms)"
|
||||
range 100 10000
|
||||
default 500
|
||||
depends on I2C_MASTER_MESSAGER_BH1750_ENABLE
|
||||
help
|
||||
BH1750 的轮询间隔,单位毫秒。
|
||||
|
||||
config I2C_MASTER_MESSAGER_AHT30_ENABLE
|
||||
bool "启用 AHT30 温湿度传感器"
|
||||
default y
|
||||
help
|
||||
关闭后将不会初始化与读取 AHT30。
|
||||
|
||||
config I2C_MASTER_MESSAGER_AHT30_READ_PERIOD_MS
|
||||
int "AHT30 采样周期 (ms)"
|
||||
range 100 10000
|
||||
default 2000
|
||||
depends on I2C_MASTER_MESSAGER_AHT30_ENABLE
|
||||
help
|
||||
AHT30 的轮询间隔,单位毫秒。
|
||||
|
||||
endmenu
|
||||
109
components/i2c_master_messager/README.md
Normal file
109
components/i2c_master_messager/README.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# i2c_master_messager
|
||||
|
||||
`i2c_master_messager` 用于统一管理工程中的 I2C 传感器。
|
||||
当前已接入:
|
||||
|
||||
- BH1750 光照传感器(使用驱动默认地址)
|
||||
- AHT30 温湿度传感器(使用驱动默认地址)
|
||||
|
||||
设计目标:
|
||||
|
||||
- 提供统一的数据结构,方便其他模块读取
|
||||
- 提供独立采集任务,周期性更新数据
|
||||
- 为后续新增其他 I2C 传感器预留扩展位置
|
||||
- 各传感器驱动相互独立,管理层只做调度与数据汇总
|
||||
- 支持每个传感器独立采样周期(例如光照快采、温湿度慢采)
|
||||
|
||||
## 驱动分层
|
||||
|
||||
- `k0i05__esp_ahtxx`:AHT30 驱动组件(通过组件管理器引入)
|
||||
- `bh1750`:使用 ESP 组件管理器驱动
|
||||
- `i2c_master_messager.c`:统一总线管理、任务轮询、线程安全数据缓存
|
||||
|
||||
## 对外数据结构
|
||||
|
||||
头文件:`include/i2c_master_messager.h`
|
||||
|
||||
- `i2c_master_messager_data_t`
|
||||
- `bh1750.lux`:光照强度(lx)
|
||||
- `bh1750.valid`:当前数据是否有效
|
||||
- `bh1750.last_update_ms`:最后一次成功更新时间(毫秒)
|
||||
- `bh1750.last_error`:最后一次采集错误码
|
||||
- `aht30.temperature_c`:温度(摄氏度)
|
||||
- `aht30.humidity_rh`:湿度(%RH)
|
||||
- `aht30.valid`:当前数据是否有效
|
||||
- `aht30.last_update_ms`:最后一次成功更新时间(毫秒)
|
||||
- `aht30.last_error`:最后一次采集错误码
|
||||
|
||||
后续新增传感器时,建议继续在 `i2c_master_messager_data_t` 中增加对应字段。
|
||||
|
||||
## API
|
||||
|
||||
- `esp_err_t i2c_master_messager_init(const i2c_master_messager_config_t *config);`
|
||||
- 初始化 I2C 总线(传感器驱动在任务中懒初始化)
|
||||
- `esp_err_t i2c_master_messager_start(void);`
|
||||
- 启动循环采集任务
|
||||
- `esp_err_t i2c_master_messager_stop(void);`
|
||||
- 停止采集任务
|
||||
- `esp_err_t i2c_master_messager_get_data(i2c_master_messager_data_t *out_data);`
|
||||
- 读取当前缓存数据(线程安全)
|
||||
- `esp_err_t i2c_master_messager_deinit(void);`
|
||||
- 释放总线和传感器资源
|
||||
|
||||
## menuconfig 配置
|
||||
|
||||
路径:`Component config -> I2C Master Messager`
|
||||
|
||||
- `启用 BH1750 光照传感器`:开关 BH1750
|
||||
- `启用 I2C 内部上拉电阻`:控制是否打开芯片内部上拉
|
||||
- `BH1750 采样周期 (ms)`:光照采样周期
|
||||
- `启用 AHT30 温湿度传感器`:开关 AHT30
|
||||
- `AHT30 采样周期 (ms)`:温湿度采样周期
|
||||
|
||||
这两个周期相互独立,可按业务需求分别调优。
|
||||
|
||||
## 使用示例
|
||||
|
||||
```c
|
||||
#include "esp_check.h"
|
||||
#include "i2c_master_messager.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
i2c_master_messager_config_t cfg = {
|
||||
.i2c_port = I2C_NUM_0,
|
||||
.scl_io_num = GPIO_NUM_5,
|
||||
.sda_io_num = GPIO_NUM_4,
|
||||
.i2c_enable_internal_pullup = true,
|
||||
.bh1750_enable = true,
|
||||
.aht30_enable = true,
|
||||
.bh1750_read_period_ms = 500,
|
||||
.aht30_read_period_ms = 2000,
|
||||
.bh1750_mode = BH1750_CONTINUE_1LX_RES,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(i2c_master_messager_init(&cfg));
|
||||
ESP_ERROR_CHECK(i2c_master_messager_start());
|
||||
|
||||
while (1) {
|
||||
i2c_master_messager_data_t data;
|
||||
if (i2c_master_messager_get_data(&data) == ESP_OK && data.bh1750.valid && data.aht30.valid) {
|
||||
printf("BH1750: %.2f lx, AHT30: %.2f C %.2f %%RH\n",
|
||||
data.bh1750.lux,
|
||||
data.aht30.temperature_c,
|
||||
data.aht30.humidity_rh);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 扩展建议
|
||||
|
||||
新增其他传感器时,建议按以下步骤扩展:
|
||||
|
||||
1. 在 `i2c_master_messager_data_t` 中增加该传感器的数据结构
|
||||
2. 在 `i2c_master_messager_config_t` 中增加该传感器配置项
|
||||
3. 在任务循环中按需完成驱动初始化与重试
|
||||
4. 在采集任务中加入周期读取逻辑并更新共享数据
|
||||
5. 在 `deinit()` 中释放对应资源
|
||||
356
components/i2c_master_messager/i2c_master_messager.c
Normal file
356
components/i2c_master_messager/i2c_master_messager.c
Normal file
@@ -0,0 +1,356 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "driver/i2c_master.h"
|
||||
#include "ahtxx.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
#include "i2c_master_messager.h"
|
||||
|
||||
static const char *TAG = "i2c_master_messager";
|
||||
#define BH1750_REINIT_INTERVAL_MS (3000)
|
||||
#define AHT30_REINIT_INTERVAL_MS (3000)
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
bool owns_i2c_bus;
|
||||
bool bh1750_ready;
|
||||
bool aht30_ready;
|
||||
i2c_master_messager_config_t config;
|
||||
i2c_master_bus_handle_t i2c_bus;
|
||||
bh1750_handle_t bh1750;
|
||||
ahtxx_handle_t aht30;
|
||||
i2c_master_messager_data_t data;
|
||||
SemaphoreHandle_t lock;
|
||||
TaskHandle_t task_handle;
|
||||
} i2c_master_messager_ctx_t;
|
||||
|
||||
static i2c_master_messager_ctx_t g_ctx;
|
||||
|
||||
static esp_err_t i2c_master_messager_try_init_bh1750(void)
|
||||
{
|
||||
if (!g_ctx.config.bh1750_enable) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (g_ctx.bh1750 != NULL) {
|
||||
bh1750_delete(g_ctx.bh1750);
|
||||
g_ctx.bh1750 = NULL;
|
||||
}
|
||||
|
||||
esp_err_t ret = bh1750_create(g_ctx.i2c_bus, BH1750_I2C_ADDRESS_DEFAULT, &g_ctx.bh1750);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = bh1750_power_on(g_ctx.bh1750);
|
||||
if (ret != ESP_OK) {
|
||||
bh1750_delete(g_ctx.bh1750);
|
||||
g_ctx.bh1750 = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = bh1750_set_measure_mode(g_ctx.bh1750, g_ctx.config.bh1750_mode);
|
||||
if (ret != ESP_OK) {
|
||||
bh1750_delete(g_ctx.bh1750);
|
||||
g_ctx.bh1750 = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
g_ctx.bh1750_ready = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t i2c_master_messager_try_init_aht30(void)
|
||||
{
|
||||
if (!g_ctx.config.aht30_enable) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (g_ctx.aht30 != NULL) {
|
||||
ahtxx_delete(g_ctx.aht30);
|
||||
g_ctx.aht30 = NULL;
|
||||
}
|
||||
|
||||
ahtxx_config_t aht_cfg = I2C_AHT30_CONFIG_DEFAULT;
|
||||
esp_err_t ret = ahtxx_init(g_ctx.i2c_bus, &aht_cfg, &g_ctx.aht30);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
g_ctx.aht30_ready = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void i2c_master_messager_task(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int64_t last_bh1750_reinit_ms = 0;
|
||||
int64_t last_bh1750_read_ms = 0;
|
||||
int64_t last_aht30_read_ms = 0;
|
||||
int64_t last_aht30_reinit_ms = 0;
|
||||
while (1) {
|
||||
int64_t now_ms = esp_timer_get_time() / 1000;
|
||||
|
||||
if (g_ctx.config.bh1750_enable && !g_ctx.bh1750_ready &&
|
||||
(now_ms - last_bh1750_reinit_ms) >= BH1750_REINIT_INTERVAL_MS) {
|
||||
last_bh1750_reinit_ms = now_ms;
|
||||
esp_err_t init_ret = i2c_master_messager_try_init_bh1750();
|
||||
if (init_ret == ESP_OK) {
|
||||
ESP_LOGI(TAG, "BH1750 reinit success");
|
||||
} else {
|
||||
ESP_LOGW(TAG, "BH1750 reinit failed: %s", esp_err_to_name(init_ret));
|
||||
if (xSemaphoreTake(g_ctx.lock, pdMS_TO_TICKS(100)) == pdTRUE) {
|
||||
g_ctx.data.bh1750.valid = false;
|
||||
g_ctx.data.bh1750.last_error = init_ret;
|
||||
xSemaphoreGive(g_ctx.lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ctx.bh1750_ready && g_ctx.bh1750 != NULL &&
|
||||
(now_ms - last_bh1750_read_ms) >= g_ctx.config.bh1750_read_period_ms) {
|
||||
float lux = 0.0f;
|
||||
esp_err_t bh1750_ret = bh1750_get_data(g_ctx.bh1750, &lux);
|
||||
last_bh1750_read_ms = now_ms;
|
||||
|
||||
if (xSemaphoreTake(g_ctx.lock, pdMS_TO_TICKS(100)) == pdTRUE) {
|
||||
g_ctx.data.bh1750.valid = (bh1750_ret == ESP_OK);
|
||||
g_ctx.data.bh1750.last_error = bh1750_ret;
|
||||
if (bh1750_ret == ESP_OK) {
|
||||
g_ctx.data.bh1750.lux = lux;
|
||||
g_ctx.data.bh1750.last_update_ms = now_ms;
|
||||
}
|
||||
xSemaphoreGive(g_ctx.lock);
|
||||
}
|
||||
|
||||
if (bh1750_ret != ESP_OK) {
|
||||
ESP_LOGW(TAG, "bh1750_get_data failed: %s", esp_err_to_name(bh1750_ret));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ctx.config.aht30_enable && !g_ctx.aht30_ready &&
|
||||
(now_ms - last_aht30_reinit_ms) >= AHT30_REINIT_INTERVAL_MS) {
|
||||
last_aht30_reinit_ms = now_ms;
|
||||
esp_err_t init_ret = i2c_master_messager_try_init_aht30();
|
||||
if (init_ret == ESP_OK) {
|
||||
ESP_LOGI(TAG, "AHT30 reinit success");
|
||||
} else {
|
||||
ESP_LOGW(TAG, "AHT30 reinit failed: %s", esp_err_to_name(init_ret));
|
||||
if (xSemaphoreTake(g_ctx.lock, pdMS_TO_TICKS(100)) == pdTRUE) {
|
||||
g_ctx.data.aht30.valid = false;
|
||||
g_ctx.data.aht30.last_error = init_ret;
|
||||
xSemaphoreGive(g_ctx.lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ctx.aht30_ready && g_ctx.aht30 != NULL &&
|
||||
(now_ms - last_aht30_read_ms) >= g_ctx.config.aht30_read_period_ms) {
|
||||
float temperature_c = 0.0f;
|
||||
float humidity_rh = 0.0f;
|
||||
esp_err_t aht30_ret = ahtxx_get_measurement(g_ctx.aht30, &temperature_c, &humidity_rh);
|
||||
last_aht30_read_ms = now_ms;
|
||||
|
||||
if (xSemaphoreTake(g_ctx.lock, pdMS_TO_TICKS(100)) == pdTRUE) {
|
||||
g_ctx.data.aht30.valid = (aht30_ret == ESP_OK);
|
||||
g_ctx.data.aht30.last_error = aht30_ret;
|
||||
if (aht30_ret == ESP_OK) {
|
||||
g_ctx.data.aht30.temperature_c = temperature_c;
|
||||
g_ctx.data.aht30.humidity_rh = humidity_rh;
|
||||
g_ctx.data.aht30.last_update_ms = now_ms;
|
||||
}
|
||||
xSemaphoreGive(g_ctx.lock);
|
||||
}
|
||||
|
||||
if (aht30_ret != ESP_OK) {
|
||||
ESP_LOGW(TAG, "ahtxx_get_measurement failed: %s", esp_err_to_name(aht30_ret));
|
||||
if (aht30_ret == ESP_ERR_INVALID_STATE || aht30_ret == ESP_ERR_TIMEOUT) {
|
||||
if (g_ctx.aht30 != NULL) {
|
||||
ahtxx_delete(g_ctx.aht30);
|
||||
g_ctx.aht30 = NULL;
|
||||
}
|
||||
g_ctx.aht30_ready = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(I2C_MASTER_MESSAGER_MIN_PERIOD_MS));
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_messager_init(const i2c_master_messager_config_t *config)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(config != NULL, ESP_ERR_INVALID_ARG, TAG, "config is null");
|
||||
ESP_RETURN_ON_FALSE(config->bh1750_enable || config->aht30_enable,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
TAG,
|
||||
"at least one sensor must be enabled");
|
||||
ESP_RETURN_ON_FALSE(!config->bh1750_enable ||
|
||||
config->bh1750_read_period_ms >= I2C_MASTER_MESSAGER_MIN_PERIOD_MS,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
TAG,
|
||||
"bh1750_read_period_ms too small");
|
||||
ESP_RETURN_ON_FALSE(!config->aht30_enable ||
|
||||
config->aht30_read_period_ms >= I2C_MASTER_MESSAGER_MIN_PERIOD_MS,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
TAG,
|
||||
"aht30_read_period_ms too small");
|
||||
|
||||
if (g_ctx.initialized) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
memset(&g_ctx, 0, sizeof(g_ctx));
|
||||
g_ctx.config = *config;
|
||||
|
||||
g_ctx.lock = xSemaphoreCreateMutex();
|
||||
ESP_RETURN_ON_FALSE(g_ctx.lock != NULL, ESP_ERR_NO_MEM, TAG, "failed to create mutex");
|
||||
|
||||
const i2c_master_bus_config_t bus_cfg = {
|
||||
.i2c_port = config->i2c_port,
|
||||
.sda_io_num = config->sda_io_num,
|
||||
.scl_io_num = config->scl_io_num,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.glitch_ignore_cnt = 7,
|
||||
.flags.enable_internal_pullup = config->i2c_enable_internal_pullup,
|
||||
};
|
||||
|
||||
esp_err_t ret = i2c_new_master_bus(&bus_cfg, &g_ctx.i2c_bus);
|
||||
if (ret != ESP_OK) {
|
||||
if (ret == ESP_ERR_INVALID_STATE) {
|
||||
ESP_LOGW(TAG,
|
||||
"i2c port %d already initialized, trying to reuse existing master bus",
|
||||
config->i2c_port);
|
||||
ret = i2c_master_get_bus_handle(config->i2c_port, &g_ctx.i2c_bus);
|
||||
if (ret != ESP_OK || g_ctx.i2c_bus == NULL) {
|
||||
ESP_LOGE(TAG,
|
||||
"failed to reuse i2c bus on port %d: %s",
|
||||
config->i2c_port,
|
||||
esp_err_to_name(ret));
|
||||
vSemaphoreDelete(g_ctx.lock);
|
||||
g_ctx.lock = NULL;
|
||||
return (ret == ESP_OK) ? ESP_ERR_INVALID_STATE : ret;
|
||||
}
|
||||
g_ctx.owns_i2c_bus = false;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "i2c_new_master_bus failed: %s", esp_err_to_name(ret));
|
||||
vSemaphoreDelete(g_ctx.lock);
|
||||
g_ctx.lock = NULL;
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
g_ctx.owns_i2c_bus = true;
|
||||
}
|
||||
|
||||
if (!config->bh1750_enable) {
|
||||
g_ctx.data.bh1750.valid = false;
|
||||
g_ctx.data.bh1750.last_error = ESP_ERR_NOT_SUPPORTED;
|
||||
} else {
|
||||
g_ctx.data.bh1750.valid = false;
|
||||
g_ctx.data.bh1750.last_error = ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!config->aht30_enable) {
|
||||
g_ctx.data.aht30.valid = false;
|
||||
g_ctx.data.aht30.last_error = ESP_ERR_NOT_SUPPORTED;
|
||||
} else {
|
||||
g_ctx.data.aht30.valid = false;
|
||||
g_ctx.data.aht30.last_error = ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
g_ctx.initialized = true;
|
||||
ESP_LOGI(TAG,
|
||||
"initialized: port=%d scl=%d sda=%d pullup_int=%d bh1750(en=%d,ready=%d,default,%ums) aht30(en=%d,ready=%d,default,%ums)",
|
||||
config->i2c_port,
|
||||
config->scl_io_num,
|
||||
config->sda_io_num,
|
||||
config->i2c_enable_internal_pullup,
|
||||
config->bh1750_enable,
|
||||
g_ctx.bh1750_ready,
|
||||
config->bh1750_read_period_ms,
|
||||
config->aht30_enable,
|
||||
g_ctx.aht30_ready,
|
||||
config->aht30_read_period_ms);
|
||||
ESP_LOGI(TAG,
|
||||
"i2c bus is ready; sensor drivers will initialize lazily in task loop");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_messager_start(void)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(g_ctx.initialized, ESP_ERR_INVALID_STATE, TAG, "not initialized");
|
||||
if (g_ctx.task_handle != NULL) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
BaseType_t ok = xTaskCreate(i2c_master_messager_task,
|
||||
"i2c_msg_task",
|
||||
4096,
|
||||
NULL,
|
||||
5,
|
||||
&g_ctx.task_handle);
|
||||
ESP_RETURN_ON_FALSE(ok == pdPASS, ESP_ERR_NO_MEM, TAG, "failed to create task");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_messager_stop(void)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(g_ctx.initialized, ESP_ERR_INVALID_STATE, TAG, "not initialized");
|
||||
if (g_ctx.task_handle != NULL) {
|
||||
vTaskDelete(g_ctx.task_handle);
|
||||
g_ctx.task_handle = NULL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_messager_get_data(i2c_master_messager_data_t *out_data)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(g_ctx.initialized, ESP_ERR_INVALID_STATE, TAG, "not initialized");
|
||||
ESP_RETURN_ON_FALSE(out_data != NULL, ESP_ERR_INVALID_ARG, TAG, "out_data is null");
|
||||
ESP_RETURN_ON_FALSE(g_ctx.lock != NULL, ESP_ERR_INVALID_STATE, TAG, "lock not ready");
|
||||
|
||||
ESP_RETURN_ON_FALSE(xSemaphoreTake(g_ctx.lock, pdMS_TO_TICKS(100)) == pdTRUE,
|
||||
ESP_ERR_TIMEOUT,
|
||||
TAG,
|
||||
"failed to lock shared data");
|
||||
*out_data = g_ctx.data;
|
||||
xSemaphoreGive(g_ctx.lock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_messager_deinit(void)
|
||||
{
|
||||
if (!g_ctx.initialized) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
i2c_master_messager_stop();
|
||||
|
||||
if (g_ctx.bh1750 != NULL) {
|
||||
bh1750_delete(g_ctx.bh1750);
|
||||
g_ctx.bh1750 = NULL;
|
||||
}
|
||||
|
||||
if (g_ctx.aht30 != NULL) {
|
||||
ahtxx_delete(g_ctx.aht30);
|
||||
g_ctx.aht30 = NULL;
|
||||
}
|
||||
|
||||
if (g_ctx.i2c_bus != NULL && g_ctx.owns_i2c_bus) {
|
||||
i2c_del_master_bus(g_ctx.i2c_bus);
|
||||
}
|
||||
g_ctx.i2c_bus = NULL;
|
||||
g_ctx.owns_i2c_bus = false;
|
||||
|
||||
if (g_ctx.lock != NULL) {
|
||||
vSemaphoreDelete(g_ctx.lock);
|
||||
g_ctx.lock = NULL;
|
||||
}
|
||||
|
||||
memset(&g_ctx, 0, sizeof(g_ctx));
|
||||
return ESP_OK;
|
||||
}
|
||||
57
components/i2c_master_messager/include/i2c_master_messager.h
Normal file
57
components/i2c_master_messager/include/i2c_master_messager.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bh1750.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/i2c_types.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
i2c_port_num_t i2c_port;
|
||||
gpio_num_t scl_io_num;
|
||||
gpio_num_t sda_io_num;
|
||||
bool i2c_enable_internal_pullup;
|
||||
bool bh1750_enable;
|
||||
bool aht30_enable;
|
||||
uint16_t bh1750_read_period_ms;
|
||||
uint16_t aht30_read_period_ms;
|
||||
bh1750_measure_mode_t bh1750_mode;
|
||||
} i2c_master_messager_config_t;
|
||||
|
||||
typedef struct {
|
||||
float lux;
|
||||
bool valid;
|
||||
int64_t last_update_ms;
|
||||
esp_err_t last_error;
|
||||
} i2c_bh1750_data_t;
|
||||
|
||||
typedef struct {
|
||||
float temperature_c;
|
||||
float humidity_rh;
|
||||
bool valid;
|
||||
int64_t last_update_ms;
|
||||
esp_err_t last_error;
|
||||
} i2c_aht30_data_t;
|
||||
|
||||
typedef struct {
|
||||
i2c_bh1750_data_t bh1750;
|
||||
i2c_aht30_data_t aht30;
|
||||
} i2c_master_messager_data_t;
|
||||
|
||||
#define I2C_MASTER_MESSAGER_MIN_PERIOD_MS (100)
|
||||
|
||||
esp_err_t i2c_master_messager_init(const i2c_master_messager_config_t *config);
|
||||
esp_err_t i2c_master_messager_start(void);
|
||||
esp_err_t i2c_master_messager_stop(void);
|
||||
esp_err_t i2c_master_messager_get_data(i2c_master_messager_data_t *out_data);
|
||||
esp_err_t i2c_master_messager_deinit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
3
components/io_device_control/CMakeLists.txt
Normal file
3
components/io_device_control/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "io_device_control.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES esp_driver_gpio)
|
||||
42
components/io_device_control/README.md
Normal file
42
components/io_device_control/README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# io_device_control
|
||||
|
||||
`io_device_control` 组件用于统一管理项目中的简单 IO 外设控制。
|
||||
|
||||
当前定义:
|
||||
|
||||
- `GPIO1`:水泵控制(高电平有效)
|
||||
- `GPIO0`:光照控制(高电平有效)
|
||||
|
||||
## 对外接口
|
||||
|
||||
头文件:`include/io_device_control.h`
|
||||
|
||||
- `esp_err_t io_device_control_init(void);`
|
||||
- 初始化 GPIO 输出方向,并将水泵与光照默认置为关闭(低电平)。
|
||||
- `esp_err_t io_device_control_set_pump(bool on);`
|
||||
- 控制水泵开关,`true` 为开,`false` 为关。
|
||||
- `esp_err_t io_device_control_set_light(bool on);`
|
||||
- 控制光照开关,`true` 为开,`false` 为关。
|
||||
|
||||
## 使用方式
|
||||
|
||||
在 `app_main` 中先初始化,后续在业务逻辑中按需调用控制接口。
|
||||
|
||||
```c
|
||||
#include "esp_check.h"
|
||||
#include "io_device_control.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(io_device_control_init());
|
||||
|
||||
// 后续按需调用
|
||||
// ESP_ERROR_CHECK(io_device_control_set_pump(true));
|
||||
// ESP_ERROR_CHECK(io_device_control_set_light(true));
|
||||
}
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 控制接口在未初始化时会返回 `ESP_ERR_INVALID_STATE`。
|
||||
- 若硬件驱动电路为反相,请在硬件层或组件内部统一处理,不建议在业务层散落取反逻辑。
|
||||
20
components/io_device_control/include/io_device_control.h
Normal file
20
components/io_device_control/include/io_device_control.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Initializes GPIO0/GPIO1 outputs and sets both devices off by default.
|
||||
esp_err_t io_device_control_init(void);
|
||||
|
||||
// High level control APIs, both are active-high outputs.
|
||||
esp_err_t io_device_control_set_pump(bool on);
|
||||
esp_err_t io_device_control_set_light(bool on);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
60
components/io_device_control/io_device_control.c
Normal file
60
components/io_device_control/io_device_control.c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "io_device_control.h"
|
||||
|
||||
static const char *TAG = "io_device_control";
|
||||
|
||||
#define IO_DEVICE_PUMP_GPIO GPIO_NUM_1
|
||||
#define IO_DEVICE_LIGHT_GPIO GPIO_NUM_10
|
||||
|
||||
static bool s_inited = false;
|
||||
|
||||
static esp_err_t io_device_control_set_level(gpio_num_t pin, bool on)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(s_inited, ESP_ERR_INVALID_STATE, TAG, "not initialized");
|
||||
return gpio_set_level(pin, on ? 1 : 0);
|
||||
}
|
||||
|
||||
esp_err_t io_device_control_init(void)
|
||||
{
|
||||
if (s_inited) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
const gpio_config_t out_cfg = {
|
||||
.pin_bit_mask = (1ULL << IO_DEVICE_PUMP_GPIO) | (1ULL << IO_DEVICE_LIGHT_GPIO),
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE,
|
||||
};
|
||||
|
||||
ESP_RETURN_ON_ERROR(gpio_config(&out_cfg), TAG, "gpio_config failed");
|
||||
|
||||
// Active-high outputs; default low keeps devices off at boot.
|
||||
ESP_RETURN_ON_ERROR(gpio_set_level(IO_DEVICE_PUMP_GPIO, 0), TAG, "set pump default failed");
|
||||
ESP_RETURN_ON_ERROR(gpio_set_level(IO_DEVICE_LIGHT_GPIO, 0), TAG, "set light default failed");
|
||||
|
||||
s_inited = true;
|
||||
ESP_LOGI(TAG, "initialized: pump=GPIO%d light=GPIO%d active_high=1", IO_DEVICE_PUMP_GPIO, IO_DEVICE_LIGHT_GPIO);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t io_device_control_set_pump(bool on)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(io_device_control_set_level(IO_DEVICE_PUMP_GPIO, on),
|
||||
TAG,
|
||||
"set pump failed");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t io_device_control_set_light(bool on)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(io_device_control_set_level(IO_DEVICE_LIGHT_GPIO, on),
|
||||
TAG,
|
||||
"set light failed");
|
||||
return ESP_OK;
|
||||
}
|
||||
4
components/lvgl_st7735s_use/CMakeLists.txt
Normal file
4
components/lvgl_st7735s_use/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
idf_component_register(SRCS "lvgl_st7735s_use.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES driver esp_lcd esp_lvgl_port
|
||||
)
|
||||
105
components/lvgl_st7735s_use/README.md
Normal file
105
components/lvgl_st7735s_use/README.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# lvgl_st7735s_use 组件说明
|
||||
|
||||
`lvgl_st7735s_use` 是项目中的 LCD 显示组件,基于 `esp_lcd + esp_lvgl_port`,用于快速驱动 ST77xx 系列 SPI 屏并显示 LVGL 界面。
|
||||
|
||||
---
|
||||
|
||||
## 功能概览
|
||||
|
||||
- 初始化 SPI LCD(含背光、面板、显示偏移)
|
||||
- 初始化 LVGL 端口并注册显示设备
|
||||
- 默认创建一个居中标签用于快速验证显示链路
|
||||
- 提供运行时更新中心文本接口
|
||||
- 支持可配置方向、镜像与偏移
|
||||
- 支持可选三色测试图(调试用)
|
||||
|
||||
---
|
||||
|
||||
## 对外 API
|
||||
|
||||
头文件:`include/lvgl_st7735s_use.h`
|
||||
|
||||
- `esp_err_t start_lvgl_demo(void);`
|
||||
- 完成 LCD + LVGL 初始化并创建默认界面
|
||||
|
||||
- `esp_err_t lvgl_st7735s_set_center_text(const char *text);`
|
||||
- 运行时更新中心标签文字(线程安全,内部已加锁)
|
||||
|
||||
---
|
||||
|
||||
## 关键配置项(可直接改宏)
|
||||
|
||||
在 `include/lvgl_st7735s_use.h` 中:
|
||||
|
||||
### 1) 屏幕与 SPI
|
||||
|
||||
- `EXAMPLE_LCD_H_RES` / `EXAMPLE_LCD_V_RES`
|
||||
- `EXAMPLE_LCD_PIXEL_CLK_HZ`
|
||||
- `EXAMPLE_LCD_SPI_NUM`
|
||||
- `EXAMPLE_LCD_CMD_BITS` / `EXAMPLE_LCD_PARAM_BITS`
|
||||
|
||||
建议:首次点亮优先用较低时钟(如 `10MHz`),稳定后再升频。
|
||||
|
||||
### 2) 方向与偏移(重点)
|
||||
|
||||
- `EXAMPLE_LCD_GAP_X`
|
||||
- `EXAMPLE_LCD_GAP_Y`
|
||||
- `EXAMPLE_LCD_ROT_SWAP_XY`
|
||||
- `EXAMPLE_LCD_ROT_MIRROR_X`
|
||||
- `EXAMPLE_LCD_ROT_MIRROR_Y`
|
||||
|
||||
说明:
|
||||
- 当前项目已验证一组可用参数(顺时针 90° + 26 偏移)。
|
||||
- 若出现“文字偏移/边缘花屏/方向反了”,优先微调上述宏,不要同时在多层重复旋转。
|
||||
|
||||
### 3) 调试项
|
||||
|
||||
- `EXAMPLE_LCD_ENABLE_COLOR_TEST`
|
||||
- `1`:上电先画 RGB 三色测试图(便于确认硬件链路)
|
||||
- `0`:跳过测试,直接进入 LVGL
|
||||
|
||||
---
|
||||
|
||||
## 在主程序中调用
|
||||
|
||||
```c
|
||||
#include "esp_check.h"
|
||||
#include "lvgl_st7735s_use.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(start_lvgl_demo());
|
||||
ESP_ERROR_CHECK(lvgl_st7735s_set_center_text("BotanicalBuddy"));
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1) 背光亮但没有内容
|
||||
|
||||
优先排查:
|
||||
- 面板型号与驱动是否匹配(ST7735S / ST7789)
|
||||
- SPI 模式、时钟是否过高
|
||||
- 方向/偏移参数是否正确
|
||||
|
||||
### 2) 文字方向反了或显示偏移
|
||||
|
||||
优先调整:
|
||||
- `EXAMPLE_LCD_ROT_*`
|
||||
- `EXAMPLE_LCD_GAP_X / EXAMPLE_LCD_GAP_Y`
|
||||
|
||||
### 3) 想快速确认硬件链路是否通
|
||||
|
||||
把 `EXAMPLE_LCD_ENABLE_COLOR_TEST` 设为 `1`,观察是否能显示三色图。
|
||||
|
||||
---
|
||||
|
||||
## 依赖
|
||||
|
||||
由组件 `CMakeLists.txt` 声明:
|
||||
|
||||
- `driver`
|
||||
- `esp_lcd`
|
||||
- `esp_lvgl_port`
|
||||
56
components/lvgl_st7735s_use/include/lvgl_st7735s_use.h
Normal file
56
components/lvgl_st7735s_use/include/lvgl_st7735s_use.h
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* LCD size */
|
||||
#define EXAMPLE_LCD_H_RES (160)
|
||||
#define EXAMPLE_LCD_V_RES (80)
|
||||
|
||||
/* LCD SPI总线配置 */
|
||||
#define EXAMPLE_LCD_SPI_NUM (SPI2_HOST) // 使用SPI2主机接口进行通信
|
||||
|
||||
/* LCD显示参数配置 */
|
||||
#define EXAMPLE_LCD_PIXEL_CLK_HZ (10 * 1000 * 1000) // 先用10MHz提高兼容性,点亮后再逐步升频
|
||||
|
||||
/* LCD命令和参数配置 */
|
||||
#define EXAMPLE_LCD_CMD_BITS (8) // 命令位数为8位,用于发送LCD控制命令
|
||||
#define EXAMPLE_LCD_PARAM_BITS (8) // 参数位数为8位,用于发送命令参数
|
||||
|
||||
/* LCD颜色和缓冲区配置 */
|
||||
#define EXAMPLE_LCD_BITS_PER_PIXEL (16) // 每个像素使用16位颜色(RGB565格式)
|
||||
#define EXAMPLE_LCD_DRAW_BUFF_DOUBLE (1) // 启用双缓冲模式,提高显示流畅度
|
||||
#define EXAMPLE_LCD_DRAW_BUFF_HEIGHT (50) // 绘图缓冲区高度为50行,影响刷新性能
|
||||
|
||||
/* LCD背光配置 */
|
||||
#define EXAMPLE_LCD_BL_ON_LEVEL (1) // 背光开启电平为高电平(1)
|
||||
|
||||
/* LCD方向/偏移配置(当前为顺时针90°,并保留26偏移) */
|
||||
#define EXAMPLE_LCD_GAP_X (1)
|
||||
#define EXAMPLE_LCD_GAP_Y (26)
|
||||
#define EXAMPLE_LCD_ROT_SWAP_XY (1)
|
||||
#define EXAMPLE_LCD_ROT_MIRROR_X (1)
|
||||
#define EXAMPLE_LCD_ROT_MIRROR_Y (0)
|
||||
|
||||
/* 调试项:上电后是否先显示三色测试图 */
|
||||
#define EXAMPLE_LCD_ENABLE_COLOR_TEST (0)
|
||||
|
||||
/* LCD pins */
|
||||
#define EXAMPLE_LCD_GPIO_SCLK (GPIO_NUM_2)
|
||||
#define EXAMPLE_LCD_GPIO_MOSI (GPIO_NUM_3)
|
||||
#define EXAMPLE_LCD_GPIO_RST (GPIO_NUM_9)
|
||||
#define EXAMPLE_LCD_GPIO_DC (GPIO_NUM_8)
|
||||
#define EXAMPLE_LCD_GPIO_CS (GPIO_NUM_7)
|
||||
#define EXAMPLE_LCD_GPIO_BL (GPIO_NUM_6)
|
||||
|
||||
esp_err_t start_lvgl_demo(void);
|
||||
esp_err_t lvgl_st7735s_set_center_text(const char *text);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
246
components/lvgl_st7735s_use/lvgl_st7735s_use.c
Normal file
246
components/lvgl_st7735s_use/lvgl_st7735s_use.c
Normal file
@@ -0,0 +1,246 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "lvgl_st7735s_use.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_lcd_panel_io.h"
|
||||
#include "esp_lcd_panel_vendor.h"
|
||||
#include "esp_lcd_panel_ops.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
static const char *TAG = "lvgl_st7735s_use";
|
||||
|
||||
static esp_lcd_panel_io_handle_t lcd_io = NULL;
|
||||
static esp_lcd_panel_handle_t lcd_panel = NULL;
|
||||
static lv_display_t *lvgl_disp = NULL;
|
||||
static lv_obj_t *s_center_label = NULL;
|
||||
|
||||
#if EXAMPLE_LCD_ENABLE_COLOR_TEST
|
||||
static esp_err_t app_lcd_color_test(void)
|
||||
{
|
||||
const size_t pixels = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES;
|
||||
uint16_t *frame = calloc(pixels, sizeof(uint16_t));
|
||||
ESP_RETURN_ON_FALSE(frame != NULL, ESP_ERR_NO_MEM, TAG, "分配测试帧缓冲失败");
|
||||
|
||||
for (int y = 0; y < EXAMPLE_LCD_V_RES; y++) {
|
||||
for (int x = 0; x < EXAMPLE_LCD_H_RES; x++) {
|
||||
uint16_t color;
|
||||
if (x < EXAMPLE_LCD_H_RES / 3) {
|
||||
color = 0xF800; // 红
|
||||
} else if (x < (EXAMPLE_LCD_H_RES * 2) / 3) {
|
||||
color = 0x07E0; // 绿
|
||||
} else {
|
||||
color = 0x001F; // 蓝
|
||||
}
|
||||
frame[y * EXAMPLE_LCD_H_RES + x] = color;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t err = esp_lcd_panel_draw_bitmap(lcd_panel, 0, 0, EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES, frame);
|
||||
free(frame);
|
||||
ESP_RETURN_ON_ERROR(err, TAG, "三色测试绘制失败");
|
||||
|
||||
ESP_LOGI(TAG, "LCD三色测试图已发送");
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 初始化LCD硬件和SPI接口
|
||||
*
|
||||
* 该函数负责初始化LCD所需的GPIO、SPI总线,并配置LCD面板
|
||||
* 包括背光控制、SPI总线配置、面板IO配置和面板驱动安装
|
||||
*
|
||||
* @return esp_err_t 初始化结果,ESP_OK表示成功
|
||||
*/
|
||||
static esp_err_t app_lcd_init(void)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
gpio_config_t bk_gpio_config = {
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pin_bit_mask = 1ULL << EXAMPLE_LCD_GPIO_BL
|
||||
};
|
||||
ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
|
||||
|
||||
ESP_LOGI(TAG, "初始化SPI总线");
|
||||
const spi_bus_config_t buscfg = {
|
||||
.sclk_io_num = EXAMPLE_LCD_GPIO_SCLK,
|
||||
.mosi_io_num = EXAMPLE_LCD_GPIO_MOSI,
|
||||
.miso_io_num = GPIO_NUM_NC,
|
||||
.quadwp_io_num = GPIO_NUM_NC,
|
||||
.quadhd_io_num = GPIO_NUM_NC,
|
||||
.max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT * sizeof(uint16_t),
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(spi_bus_initialize(EXAMPLE_LCD_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO), TAG, "SPI初始化失败");
|
||||
|
||||
ESP_LOGI(TAG, "安装面板IO");
|
||||
const esp_lcd_panel_io_spi_config_t io_config = {
|
||||
.dc_gpio_num = EXAMPLE_LCD_GPIO_DC,
|
||||
.cs_gpio_num = EXAMPLE_LCD_GPIO_CS,
|
||||
.pclk_hz = EXAMPLE_LCD_PIXEL_CLK_HZ,
|
||||
.lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
|
||||
.lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
|
||||
.spi_mode = 0,
|
||||
.trans_queue_depth = 10,
|
||||
};
|
||||
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)EXAMPLE_LCD_SPI_NUM, &io_config, &lcd_io), err, TAG, "创建面板IO失败");
|
||||
|
||||
ESP_LOGI(TAG, "安装LCD驱动");
|
||||
const esp_lcd_panel_dev_config_t panel_config = {
|
||||
.reset_gpio_num = EXAMPLE_LCD_GPIO_RST,
|
||||
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(6, 0, 0)
|
||||
.rgb_endian = LCD_RGB_ENDIAN_RGB,
|
||||
#else
|
||||
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_BGR,
|
||||
#endif
|
||||
.bits_per_pixel = EXAMPLE_LCD_BITS_PER_PIXEL,
|
||||
};
|
||||
|
||||
ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7789(lcd_io, &panel_config, &lcd_panel), err, TAG, "创建面板失败");
|
||||
ESP_GOTO_ON_ERROR(esp_lcd_panel_reset(lcd_panel), err, TAG, "面板复位失败");
|
||||
ESP_GOTO_ON_ERROR(esp_lcd_panel_init(lcd_panel), err, TAG, "面板初始化失败");
|
||||
ESP_GOTO_ON_ERROR(esp_lcd_panel_swap_xy(lcd_panel, false), err, TAG, "设置面板swap_xy失败");
|
||||
ESP_GOTO_ON_ERROR(esp_lcd_panel_mirror(lcd_panel, false, false), err, TAG, "设置面板镜像失败");
|
||||
|
||||
ESP_GOTO_ON_ERROR(esp_lcd_panel_set_gap(lcd_panel, EXAMPLE_LCD_GAP_X, EXAMPLE_LCD_GAP_Y), err, TAG, "设置显示偏移失败");
|
||||
ESP_LOGI(TAG, "面板基准参数已应用: gap=(%d,%d)", EXAMPLE_LCD_GAP_X, EXAMPLE_LCD_GAP_Y);
|
||||
|
||||
ESP_GOTO_ON_ERROR(esp_lcd_panel_invert_color(lcd_panel, true), err, TAG, "设置反色失败");
|
||||
ESP_GOTO_ON_ERROR(esp_lcd_panel_disp_on_off(lcd_panel, true), err, TAG, "打开显示失败");
|
||||
|
||||
ESP_RETURN_ON_ERROR(gpio_set_level(EXAMPLE_LCD_GPIO_BL, EXAMPLE_LCD_BL_ON_LEVEL), TAG, "背光引脚置位失败");
|
||||
ESP_LOGI(TAG, "背光已打开,电平=%d", EXAMPLE_LCD_BL_ON_LEVEL);
|
||||
|
||||
return ret;
|
||||
|
||||
// 错误处理标签,用于清理资源
|
||||
err:
|
||||
if (lcd_panel) {
|
||||
esp_lcd_panel_del(lcd_panel);
|
||||
lcd_panel = NULL;
|
||||
}
|
||||
if (lcd_io) {
|
||||
esp_lcd_panel_io_del(lcd_io);
|
||||
lcd_io = NULL;
|
||||
}
|
||||
spi_bus_free(EXAMPLE_LCD_SPI_NUM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化LVGL图形库
|
||||
*
|
||||
* 该函数负责初始化LVGL库,并配置显示设备
|
||||
* 包括LVGL任务配置、显示缓冲区配置和旋转设置
|
||||
*
|
||||
* @return esp_err_t 初始化结果,ESP_OK表示成功
|
||||
*/
|
||||
static esp_err_t app_lvgl_init(void)
|
||||
{
|
||||
const lvgl_port_cfg_t lvgl_cfg = {
|
||||
.task_priority = 4,
|
||||
.task_stack = 4096,
|
||||
.task_affinity = -1,
|
||||
.task_max_sleep_ms = 500,
|
||||
.timer_period_ms = 5
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL端口初始化失败");
|
||||
|
||||
ESP_LOGI(TAG, "添加LCD屏幕");
|
||||
const lvgl_port_display_cfg_t disp_cfg = {
|
||||
.io_handle = lcd_io,
|
||||
.panel_handle = lcd_panel,
|
||||
.buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT,
|
||||
.double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE,
|
||||
.hres = EXAMPLE_LCD_H_RES,
|
||||
.vres = EXAMPLE_LCD_V_RES,
|
||||
.monochrome = false,
|
||||
#if LVGL_VERSION_MAJOR >= 9
|
||||
.color_format = LV_COLOR_FORMAT_RGB565,
|
||||
#endif
|
||||
.rotation = {
|
||||
.swap_xy = EXAMPLE_LCD_ROT_SWAP_XY,
|
||||
.mirror_x = EXAMPLE_LCD_ROT_MIRROR_X,
|
||||
.mirror_y = EXAMPLE_LCD_ROT_MIRROR_Y,
|
||||
},
|
||||
.flags = {
|
||||
.buff_dma = true,
|
||||
#if LVGL_VERSION_MAJOR >= 9
|
||||
.swap_bytes = false,
|
||||
#endif
|
||||
}};
|
||||
|
||||
lvgl_disp = lvgl_port_add_disp(&disp_cfg);
|
||||
ESP_RETURN_ON_FALSE(lvgl_disp != NULL, ESP_FAIL, TAG, "添加LVGL显示设备失败");
|
||||
ESP_LOGI(TAG, "LVGL旋转已应用: swap_xy=%d mirror_x=%d mirror_y=%d",
|
||||
EXAMPLE_LCD_ROT_SWAP_XY, EXAMPLE_LCD_ROT_MIRROR_X, EXAMPLE_LCD_ROT_MIRROR_Y);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建并显示LVGL主界面
|
||||
*
|
||||
* 该函数负责创建LVGL的用户界面元素,包括图像、标签和按钮
|
||||
* 并设置它们的位置和属性
|
||||
*/
|
||||
static void app_main_display(void)
|
||||
{
|
||||
lv_obj_t *scr = lv_scr_act();
|
||||
|
||||
lvgl_port_lock(0);
|
||||
|
||||
lv_obj_set_style_bg_color(scr, lv_color_white(), 0);
|
||||
lv_obj_set_style_bg_opa(scr, LV_OPA_COVER, 0);
|
||||
|
||||
s_center_label = lv_label_create(scr);
|
||||
lv_label_set_text(s_center_label, "BotanicalBuddy\nloading...");
|
||||
lv_label_set_recolor(s_center_label, false);
|
||||
lv_label_set_long_mode(s_center_label, LV_LABEL_LONG_WRAP);
|
||||
lv_obj_set_size(s_center_label, EXAMPLE_LCD_H_RES - 6, EXAMPLE_LCD_V_RES - 6);
|
||||
lv_obj_set_style_text_color(s_center_label, lv_color_black(), 0);
|
||||
lv_obj_set_style_text_font(s_center_label, &lv_font_montserrat_14, 0);
|
||||
lv_obj_set_style_text_align(s_center_label, LV_TEXT_ALIGN_CENTER, 0);
|
||||
lv_obj_set_style_pad_all(s_center_label, 0, 0);
|
||||
lv_obj_align(s_center_label, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
lvgl_port_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 启动LVGL演示程序
|
||||
*
|
||||
* 该函数是程序的入口点,负责初始化LCD硬件、LVGL库,并显示主界面
|
||||
*/
|
||||
esp_err_t lvgl_st7735s_set_center_text(const char *text)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(text != NULL, ESP_ERR_INVALID_ARG, TAG, "text is null");
|
||||
ESP_RETURN_ON_FALSE(s_center_label != NULL, ESP_ERR_INVALID_STATE, TAG, "label not ready");
|
||||
|
||||
lvgl_port_lock(0);
|
||||
lv_label_set_text(s_center_label, text);
|
||||
lv_obj_align(s_center_label, LV_ALIGN_CENTER, 0, 0);
|
||||
lvgl_port_unlock();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t start_lvgl_demo(void)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(app_lcd_init(), TAG, "LCD初始化失败");
|
||||
|
||||
#if EXAMPLE_LCD_ENABLE_COLOR_TEST
|
||||
ESP_RETURN_ON_ERROR(app_lcd_color_test(), TAG, "LCD测试图绘制失败");
|
||||
vTaskDelay(pdMS_TO_TICKS(300));
|
||||
#endif
|
||||
|
||||
ESP_RETURN_ON_ERROR(app_lvgl_init(), TAG, "LVGL初始化失败");
|
||||
|
||||
app_main_display();
|
||||
return ESP_OK;
|
||||
}
|
||||
3
components/mqtt_control/CMakeLists.txt
Normal file
3
components/mqtt_control/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "mqtt_control.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES mqtt cjson)
|
||||
49
components/mqtt_control/include/mqtt_control.h
Normal file
49
components/mqtt_control/include/mqtt_control.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "mqtt_client.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
bool has_mode;
|
||||
bool auto_mode;
|
||||
|
||||
bool has_thresholds;
|
||||
float soil_on_pct;
|
||||
float soil_off_pct;
|
||||
float light_on_lux;
|
||||
float light_off_lux;
|
||||
|
||||
bool has_pump;
|
||||
bool pump_on;
|
||||
|
||||
bool has_light;
|
||||
bool light_on;
|
||||
} mqtt_control_command_t;
|
||||
|
||||
typedef esp_err_t (*mqtt_control_command_handler_t)(const mqtt_control_command_t *cmd, void *user_ctx);
|
||||
|
||||
esp_err_t mqtt_control_start(void);
|
||||
esp_err_t mqtt_control_stop(void);
|
||||
|
||||
esp_err_t mqtt_control_register_command_handler(mqtt_control_command_handler_t handler, void *user_ctx);
|
||||
|
||||
bool mqtt_control_is_connected(void);
|
||||
|
||||
// Generic publish API for any topic.
|
||||
esp_err_t mqtt_control_publish(const char *topic,
|
||||
const char *payload,
|
||||
int qos,
|
||||
int retain);
|
||||
|
||||
// Publish telemetry payload to default sensor topic.
|
||||
esp_err_t mqtt_control_publish_sensor(const char *payload, int qos, int retain);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
377
components/mqtt_control/mqtt_control.c
Normal file
377
components/mqtt_control/mqtt_control.c
Normal file
@@ -0,0 +1,377 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "cJSON.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_mac.h"
|
||||
|
||||
#include "mqtt_control.h"
|
||||
|
||||
// MQTT 服务器地址(协议+域名+端口)
|
||||
#define MQTT_BROKER_URL "mqtt://beihong.wang:1883"
|
||||
// MQTT 用户名
|
||||
#define MQTT_USERNAME "BotanicalBuddy"
|
||||
// MQTT 密码
|
||||
#define MQTT_PASSWORD "YTGui8979HI"
|
||||
// 传感器数据发布主题
|
||||
#define MQTT_SENSOR_TOPIC "topic/sensor/esp32_BotanicalBuddy_001"
|
||||
// 控制指令订阅主题
|
||||
#define MQTT_CONTROL_TOPIC "topic/control/esp32_BotanicalBuddy_001"
|
||||
|
||||
|
||||
static const char *TAG = "mqtt_control"; // 日志标签
|
||||
|
||||
static esp_mqtt_client_handle_t g_mqtt_client = NULL; // 全局 MQTT 客户端句柄
|
||||
static bool g_mqtt_connected = false; // MQTT 连接状态标志
|
||||
static mqtt_control_command_handler_t g_cmd_handler = NULL;
|
||||
static void *g_cmd_user_ctx = NULL;
|
||||
|
||||
static bool json_read_bool(cJSON *root, const char *key, bool *out)
|
||||
{
|
||||
cJSON *item = cJSON_GetObjectItemCaseSensitive(root, key);
|
||||
if (item == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (cJSON_IsBool(item))
|
||||
{
|
||||
*out = cJSON_IsTrue(item);
|
||||
return true;
|
||||
}
|
||||
if (cJSON_IsNumber(item))
|
||||
{
|
||||
*out = (item->valuedouble != 0.0);
|
||||
return true;
|
||||
}
|
||||
if (cJSON_IsString(item) && item->valuestring != NULL)
|
||||
{
|
||||
if (strcasecmp(item->valuestring, "on") == 0 ||
|
||||
strcasecmp(item->valuestring, "true") == 0 ||
|
||||
strcmp(item->valuestring, "1") == 0)
|
||||
{
|
||||
*out = true;
|
||||
return true;
|
||||
}
|
||||
if (strcasecmp(item->valuestring, "off") == 0 ||
|
||||
strcasecmp(item->valuestring, "false") == 0 ||
|
||||
strcmp(item->valuestring, "0") == 0)
|
||||
{
|
||||
*out = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool json_read_float(cJSON *root, const char *key, float *out)
|
||||
{
|
||||
cJSON *item = cJSON_GetObjectItemCaseSensitive(root, key);
|
||||
if (!cJSON_IsNumber(item))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*out = (float)item->valuedouble;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool json_read_mode_auto(cJSON *root, const char *key, bool *out_auto)
|
||||
{
|
||||
cJSON *item = cJSON_GetObjectItemCaseSensitive(root, key);
|
||||
if (item == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cJSON_IsString(item) && item->valuestring != NULL)
|
||||
{
|
||||
if (strcasecmp(item->valuestring, "auto") == 0)
|
||||
{
|
||||
*out_auto = true;
|
||||
return true;
|
||||
}
|
||||
if (strcasecmp(item->valuestring, "manual") == 0)
|
||||
{
|
||||
*out_auto = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cJSON_IsBool(item))
|
||||
{
|
||||
*out_auto = cJSON_IsTrue(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cJSON_IsNumber(item))
|
||||
{
|
||||
*out_auto = (item->valuedouble != 0.0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static esp_err_t mqtt_parse_control_command(const char *data, int data_len, mqtt_control_command_t *out_cmd)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(data != NULL && data_len > 0, ESP_ERR_INVALID_ARG, TAG, "invalid mqtt data");
|
||||
ESP_RETURN_ON_FALSE(out_cmd != NULL, ESP_ERR_INVALID_ARG, TAG, "out_cmd is null");
|
||||
|
||||
memset(out_cmd, 0, sizeof(*out_cmd));
|
||||
|
||||
cJSON *root = cJSON_ParseWithLength(data, (size_t)data_len);
|
||||
ESP_RETURN_ON_FALSE(root != NULL, ESP_ERR_INVALID_ARG, TAG, "control json parse failed");
|
||||
|
||||
float soil_on = 0.0f;
|
||||
float soil_off = 0.0f;
|
||||
float light_on_lux = 0.0f;
|
||||
float light_off_lux = 0.0f;
|
||||
|
||||
bool has_soil_on = json_read_float(root, "soil_on", &soil_on);
|
||||
bool has_soil_off = json_read_float(root, "soil_off", &soil_off);
|
||||
bool has_light_on = json_read_float(root, "light_on", &light_on_lux);
|
||||
bool has_light_off = json_read_float(root, "light_off", &light_off_lux);
|
||||
|
||||
out_cmd->has_mode = json_read_mode_auto(root, "mode", &out_cmd->auto_mode);
|
||||
|
||||
if (has_soil_on && has_soil_off && has_light_on && has_light_off)
|
||||
{
|
||||
out_cmd->has_thresholds = true;
|
||||
out_cmd->soil_on_pct = soil_on;
|
||||
out_cmd->soil_off_pct = soil_off;
|
||||
out_cmd->light_on_lux = light_on_lux;
|
||||
out_cmd->light_off_lux = light_off_lux;
|
||||
}
|
||||
|
||||
out_cmd->has_pump = json_read_bool(root, "pump", &out_cmd->pump_on);
|
||||
out_cmd->has_light = json_read_bool(root, "light", &out_cmd->light_on);
|
||||
|
||||
cJSON_Delete(root);
|
||||
|
||||
ESP_RETURN_ON_FALSE(out_cmd->has_mode || out_cmd->has_thresholds || out_cmd->has_pump || out_cmd->has_light,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
TAG,
|
||||
"no valid control fields in payload");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 判断接收到的 MQTT 主题是否与预期主题匹配
|
||||
*
|
||||
* @param event_topic 事件中的主题字符串
|
||||
* @param event_topic_len 事件中主题的长度
|
||||
* @param expected 预期的主题字符串
|
||||
* @return true 匹配成功;false 匹配失败
|
||||
*/
|
||||
static bool mqtt_topic_match(const char *event_topic, int event_topic_len, const char *expected)
|
||||
{
|
||||
size_t expected_len = strlen(expected);
|
||||
return expected_len == (size_t)event_topic_len && strncmp(event_topic, expected, expected_len) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MQTT 事件处理回调函数
|
||||
*
|
||||
* 处理连接、断开、订阅、数据接收等事件。
|
||||
*
|
||||
* @param handler_args 用户传入的参数(未使用)
|
||||
* @param base 事件基类型(ESP-MQTT)
|
||||
* @param event_id 具体事件 ID
|
||||
* @param event_data 事件数据指针
|
||||
*/
|
||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
(void)handler_args;
|
||||
ESP_LOGD(TAG, "event base=%s id=%" PRIi32, base, event_id);
|
||||
|
||||
esp_mqtt_event_handle_t event = (esp_mqtt_event_handle_t)event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
|
||||
switch ((esp_mqtt_event_id_t)event_id)
|
||||
{
|
||||
case MQTT_EVENT_CONNECTED: {
|
||||
g_mqtt_connected = true;
|
||||
ESP_LOGI(TAG, "MQTT connected");
|
||||
// 连接成功后订阅控制主题
|
||||
int msg_id = esp_mqtt_client_subscribe(client, MQTT_CONTROL_TOPIC, 1);
|
||||
ESP_LOGI(TAG, "subscribe topic=%s msg_id=%d", MQTT_CONTROL_TOPIC, msg_id);
|
||||
break;
|
||||
}
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
g_mqtt_connected = false;
|
||||
ESP_LOGW(TAG, "MQTT disconnected");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT subscribed msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT data topic=%.*s data=%.*s",
|
||||
event->topic_len,
|
||||
event->topic,
|
||||
event->data_len,
|
||||
event->data);
|
||||
|
||||
// 如果是控制主题的数据,则解析控制命令(待实现)
|
||||
if (mqtt_topic_match(event->topic, event->topic_len, MQTT_CONTROL_TOPIC))
|
||||
{
|
||||
mqtt_control_command_t cmd = {0};
|
||||
esp_err_t parse_ret = mqtt_parse_control_command(event->data, event->data_len, &cmd);
|
||||
if (parse_ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(TAG, "控制命令解析失败: %s", esp_err_to_name(parse_ret));
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_cmd_handler != NULL)
|
||||
{
|
||||
esp_err_t handle_ret = g_cmd_handler(&cmd, g_cmd_user_ctx);
|
||||
if (handle_ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(TAG, "控制命令处理失败: %s", esp_err_to_name(handle_ret));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGW(TAG, "未注册控制命令处理器,忽略控制消息");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGE(TAG, "MQTT error type=%d", event->error_handle ? event->error_handle->error_type : -1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 启动 MQTT 客户端
|
||||
*
|
||||
* 初始化客户端、注册事件回调、启动连接。
|
||||
*
|
||||
* @return esp_err_t 启动结果,ESP_OK 表示成功
|
||||
*/
|
||||
esp_err_t mqtt_control_start(void)
|
||||
{
|
||||
if (g_mqtt_client != NULL)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// 生成基于 MAC 地址后三字节的唯一客户端 ID
|
||||
char client_id[32] = {0};
|
||||
uint8_t mac[6] = {0};
|
||||
ESP_RETURN_ON_ERROR(esp_read_mac(mac, ESP_MAC_WIFI_STA), TAG, "read mac failed");
|
||||
snprintf(client_id, sizeof(client_id), "esp32_%02x%02x%02x", mac[3], mac[4], mac[5]);
|
||||
|
||||
// 配置 MQTT 客户端参数
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = MQTT_BROKER_URL,
|
||||
.credentials.username = MQTT_USERNAME,
|
||||
.credentials.client_id = client_id,
|
||||
.credentials.authentication.password = MQTT_PASSWORD,
|
||||
};
|
||||
|
||||
g_mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
ESP_RETURN_ON_FALSE(g_mqtt_client != NULL, ESP_FAIL, TAG, "mqtt client init failed");
|
||||
|
||||
ESP_RETURN_ON_ERROR(esp_mqtt_client_register_event(g_mqtt_client,
|
||||
ESP_EVENT_ANY_ID,
|
||||
mqtt_event_handler,
|
||||
NULL),
|
||||
TAG,
|
||||
"register event failed");
|
||||
|
||||
ESP_RETURN_ON_ERROR(esp_mqtt_client_start(g_mqtt_client), TAG, "start mqtt client failed");
|
||||
ESP_LOGI(TAG, "MQTT started with client_id=%s", client_id);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mqtt_control_register_command_handler(mqtt_control_command_handler_t handler, void *user_ctx)
|
||||
{
|
||||
g_cmd_handler = handler;
|
||||
g_cmd_user_ctx = user_ctx;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 停止并销毁 MQTT 客户端
|
||||
*
|
||||
* @return esp_err_t 停止结果,ESP_OK 表示成功
|
||||
*/
|
||||
esp_err_t mqtt_control_stop(void)
|
||||
{
|
||||
if (g_mqtt_client == NULL)
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ret = esp_mqtt_client_stop(g_mqtt_client);
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_mqtt_client_destroy(g_mqtt_client);
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
g_mqtt_client = NULL;
|
||||
g_mqtt_connected = false;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 查询 MQTT 当前连接状态
|
||||
*
|
||||
* @return true 已连接;false 未连接
|
||||
*/
|
||||
bool mqtt_control_is_connected(void)
|
||||
{
|
||||
return g_mqtt_connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发布 MQTT 消息到指定主题
|
||||
*
|
||||
* @param topic 目标主题
|
||||
* @param payload 消息载荷
|
||||
* @param qos 服务质量等级(0,1,2)
|
||||
* @param retain 是否保留消息
|
||||
* @return esp_err_t 发布结果
|
||||
*/
|
||||
esp_err_t mqtt_control_publish(const char *topic,
|
||||
const char *payload,
|
||||
int qos,
|
||||
int retain)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(topic != NULL, ESP_ERR_INVALID_ARG, TAG, "topic is null");
|
||||
ESP_RETURN_ON_FALSE(payload != NULL, ESP_ERR_INVALID_ARG, TAG, "payload is null");
|
||||
ESP_RETURN_ON_FALSE(g_mqtt_client != NULL, ESP_ERR_INVALID_STATE, TAG, "mqtt not started");
|
||||
|
||||
int msg_id = esp_mqtt_client_publish(g_mqtt_client, topic, payload, 0, qos, retain);
|
||||
ESP_RETURN_ON_FALSE(msg_id >= 0, ESP_FAIL, TAG, "publish failed");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发布传感器数据到预定义的传感器主题
|
||||
*
|
||||
* @param payload 传感器数据字符串
|
||||
* @param qos 服务质量
|
||||
* @param retain 是否保留消息
|
||||
* @return esp_err_t 发布结果
|
||||
*/
|
||||
esp_err_t mqtt_control_publish_sensor(const char *payload, int qos, int retain)
|
||||
{
|
||||
return mqtt_control_publish(MQTT_SENSOR_TOPIC, payload, qos, retain);
|
||||
}
|
||||
22
components/ui/.eez-project-build
Normal file
22
components/ui/.eez-project-build
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"files": [
|
||||
"actions.h",
|
||||
"fonts.h",
|
||||
"images.c",
|
||||
"images.h",
|
||||
"screens.c",
|
||||
"screens.h",
|
||||
"structs.h",
|
||||
"styles.c",
|
||||
"styles.h",
|
||||
"ui.c",
|
||||
"ui.h",
|
||||
"ui_font_source_han_sans_sc_medium_22.c",
|
||||
"ui_font_source_han_sans_sc_medium_36.c",
|
||||
"ui_image_humi.c",
|
||||
"ui_image_light.c",
|
||||
"ui_image_mois.c",
|
||||
"ui_image_temp.c",
|
||||
"vars.h"
|
||||
]
|
||||
}
|
||||
5
components/ui/CMakeLists.txt
Normal file
5
components/ui/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
idf_component_register(
|
||||
SRC_DIRS "."
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES lvgl esp_lvgl_port
|
||||
)
|
||||
14
components/ui/actions.h
Normal file
14
components/ui/actions.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef EEZ_LVGL_UI_EVENTS_H
|
||||
#define EEZ_LVGL_UI_EVENTS_H
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*EEZ_LVGL_UI_EVENTS_H*/
|
||||
27
components/ui/fonts.h
Normal file
27
components/ui/fonts.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef EEZ_LVGL_UI_FONTS_H
|
||||
#define EEZ_LVGL_UI_FONTS_H
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const lv_font_t ui_font_source_han_sans_sc_medium_22;
|
||||
extern const lv_font_t ui_font_source_han_sans_sc_medium_36;
|
||||
|
||||
#ifndef EXT_FONT_DESC_T
|
||||
#define EXT_FONT_DESC_T
|
||||
typedef struct _ext_font_desc_t {
|
||||
const char *name;
|
||||
const void *font_ptr;
|
||||
} ext_font_desc_t;
|
||||
#endif
|
||||
|
||||
extern ext_font_desc_t fonts[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*EEZ_LVGL_UI_FONTS_H*/
|
||||
8
components/ui/images.c
Normal file
8
components/ui/images.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "images.h"
|
||||
|
||||
const ext_img_desc_t images[4] = {
|
||||
{ "temp", &img_temp },
|
||||
{ "humi", &img_humi },
|
||||
{ "mois", &img_mois },
|
||||
{ "light", &img_light },
|
||||
};
|
||||
29
components/ui/images.h
Normal file
29
components/ui/images.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef EEZ_LVGL_UI_IMAGES_H
|
||||
#define EEZ_LVGL_UI_IMAGES_H
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const lv_img_dsc_t img_temp;
|
||||
extern const lv_img_dsc_t img_humi;
|
||||
extern const lv_img_dsc_t img_mois;
|
||||
extern const lv_img_dsc_t img_light;
|
||||
|
||||
#ifndef EXT_IMG_DESC_T
|
||||
#define EXT_IMG_DESC_T
|
||||
typedef struct _ext_img_desc_t {
|
||||
const char *name;
|
||||
const lv_img_dsc_t *img_dsc;
|
||||
} ext_img_desc_t;
|
||||
#endif
|
||||
|
||||
extern const ext_img_desc_t images[4];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*EEZ_LVGL_UI_IMAGES_H*/
|
||||
342
components/ui/screens.c
Normal file
342
components/ui/screens.c
Normal file
@@ -0,0 +1,342 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "screens.h"
|
||||
#include "images.h"
|
||||
#include "fonts.h"
|
||||
#include "actions.h"
|
||||
#include "vars.h"
|
||||
#include "styles.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
objects_t objects;
|
||||
|
||||
//
|
||||
// Event handlers
|
||||
//
|
||||
|
||||
lv_obj_t *tick_value_change_obj;
|
||||
|
||||
//
|
||||
// Screens
|
||||
//
|
||||
|
||||
void create_screen_temperature() {
|
||||
lv_obj_t *obj = lv_obj_create(0);
|
||||
objects.temperature = obj;
|
||||
lv_obj_set_pos(obj, 0, 0);
|
||||
lv_obj_set_size(obj, 160, 80);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
{
|
||||
lv_obj_t *parent_obj = obj;
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj0 = obj;
|
||||
lv_obj_set_pos(obj, 36, 0);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_source_han_sans_sc_medium_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "空气温度");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj1 = obj;
|
||||
lv_obj_set_pos(obj, 7, 30);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xff00ff48), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_source_han_sans_sc_medium_36, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_image_create(parent_obj);
|
||||
objects.obj2 = obj;
|
||||
lv_obj_set_pos(obj, 105, 23);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_image_set_src(obj, &img_temp);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_bg_opa(obj, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
tick_screen_temperature();
|
||||
}
|
||||
|
||||
void tick_screen_temperature() {
|
||||
{
|
||||
const char *new_val = get_var_air_temperature();
|
||||
const char *cur_val = lv_label_get_text(objects.obj1);
|
||||
if (strcmp(new_val, cur_val) != 0) {
|
||||
tick_value_change_obj = objects.obj1;
|
||||
lv_label_set_text(objects.obj1, new_val);
|
||||
tick_value_change_obj = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void create_screen_humidity() {
|
||||
lv_obj_t *obj = lv_obj_create(0);
|
||||
objects.humidity = obj;
|
||||
lv_obj_set_pos(obj, 0, 0);
|
||||
lv_obj_set_size(obj, 160, 80);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_bg_opa(obj, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
{
|
||||
lv_obj_t *parent_obj = obj;
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj3 = obj;
|
||||
lv_obj_set_pos(obj, 36, 0);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_source_han_sans_sc_medium_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "空气湿度");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj4 = obj;
|
||||
lv_obj_set_pos(obj, 7, 30);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xffd81e06), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_source_han_sans_sc_medium_36, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_image_create(parent_obj);
|
||||
objects.obj5 = obj;
|
||||
lv_obj_set_pos(obj, 105, 23);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_image_set_src(obj, &img_humi);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
tick_screen_humidity();
|
||||
}
|
||||
|
||||
void tick_screen_humidity() {
|
||||
{
|
||||
const char *new_val = get_var_air_humidity();
|
||||
const char *cur_val = lv_label_get_text(objects.obj4);
|
||||
if (strcmp(new_val, cur_val) != 0) {
|
||||
tick_value_change_obj = objects.obj4;
|
||||
lv_label_set_text(objects.obj4, new_val);
|
||||
tick_value_change_obj = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void create_screen_moisture() {
|
||||
lv_obj_t *obj = lv_obj_create(0);
|
||||
objects.moisture = obj;
|
||||
lv_obj_set_pos(obj, 0, 0);
|
||||
lv_obj_set_size(obj, 160, 80);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_bg_opa(obj, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
{
|
||||
lv_obj_t *parent_obj = obj;
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj6 = obj;
|
||||
lv_obj_set_pos(obj, 36, 0);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_source_han_sans_sc_medium_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "土壤湿度");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj7 = obj;
|
||||
lv_obj_set_pos(obj, 7, 30);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xff1296db), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_source_han_sans_sc_medium_36, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_image_create(parent_obj);
|
||||
objects.obj8 = obj;
|
||||
lv_obj_set_pos(obj, 105, 23);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_image_set_src(obj, &img_mois);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
tick_screen_moisture();
|
||||
}
|
||||
|
||||
void tick_screen_moisture() {
|
||||
{
|
||||
const char *new_val = get_var_soil_moisture();
|
||||
const char *cur_val = lv_label_get_text(objects.obj7);
|
||||
if (strcmp(new_val, cur_val) != 0) {
|
||||
tick_value_change_obj = objects.obj7;
|
||||
lv_label_set_text(objects.obj7, new_val);
|
||||
tick_value_change_obj = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void create_screen_intensity() {
|
||||
lv_obj_t *obj = lv_obj_create(0);
|
||||
objects.intensity = obj;
|
||||
lv_obj_set_pos(obj, 0, 0);
|
||||
lv_obj_set_size(obj, 160, 80);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_bg_opa(obj, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
{
|
||||
lv_obj_t *parent_obj = obj;
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj9 = obj;
|
||||
lv_obj_set_pos(obj, 36, 0);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_source_han_sans_sc_medium_22, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "光照强度");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_label_create(parent_obj);
|
||||
objects.obj10 = obj;
|
||||
lv_obj_set_pos(obj, 7, 30);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_text_color(obj, lv_color_hex(0xff13227a), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_text_font(obj, &ui_font_source_han_sans_sc_medium_36, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
lv_label_set_text(obj, "");
|
||||
}
|
||||
{
|
||||
lv_obj_t *obj = lv_image_create(parent_obj);
|
||||
objects.obj11 = obj;
|
||||
lv_obj_set_pos(obj, 105, 23);
|
||||
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
|
||||
lv_image_set_src(obj, &img_light);
|
||||
lv_obj_set_style_bg_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
tick_screen_intensity();
|
||||
}
|
||||
|
||||
void tick_screen_intensity() {
|
||||
{
|
||||
const char *new_val = get_var_light_intensity();
|
||||
const char *cur_val = lv_label_get_text(objects.obj10);
|
||||
if (strcmp(new_val, cur_val) != 0) {
|
||||
tick_value_change_obj = objects.obj10;
|
||||
lv_label_set_text(objects.obj10, new_val);
|
||||
tick_value_change_obj = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*tick_screen_func_t)();
|
||||
tick_screen_func_t tick_screen_funcs[] = {
|
||||
tick_screen_temperature,
|
||||
tick_screen_humidity,
|
||||
tick_screen_moisture,
|
||||
tick_screen_intensity,
|
||||
};
|
||||
void tick_screen(int screen_index) {
|
||||
tick_screen_funcs[screen_index]();
|
||||
}
|
||||
void tick_screen_by_id(enum ScreensEnum screenId) {
|
||||
tick_screen_funcs[screenId - 1]();
|
||||
}
|
||||
|
||||
//
|
||||
// Fonts
|
||||
//
|
||||
|
||||
ext_font_desc_t fonts[] = {
|
||||
{ "SourceHanSansSC-Medium_22", &ui_font_source_han_sans_sc_medium_22 },
|
||||
{ "SourceHanSansSC-Medium_36", &ui_font_source_han_sans_sc_medium_36 },
|
||||
#if LV_FONT_MONTSERRAT_8
|
||||
{ "MONTSERRAT_8", &lv_font_montserrat_8 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_10
|
||||
{ "MONTSERRAT_10", &lv_font_montserrat_10 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_12
|
||||
{ "MONTSERRAT_12", &lv_font_montserrat_12 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_14
|
||||
{ "MONTSERRAT_14", &lv_font_montserrat_14 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_16
|
||||
{ "MONTSERRAT_16", &lv_font_montserrat_16 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_18
|
||||
{ "MONTSERRAT_18", &lv_font_montserrat_18 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_20
|
||||
{ "MONTSERRAT_20", &lv_font_montserrat_20 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_22
|
||||
{ "MONTSERRAT_22", &lv_font_montserrat_22 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_24
|
||||
{ "MONTSERRAT_24", &lv_font_montserrat_24 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_26
|
||||
{ "MONTSERRAT_26", &lv_font_montserrat_26 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_28
|
||||
{ "MONTSERRAT_28", &lv_font_montserrat_28 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_30
|
||||
{ "MONTSERRAT_30", &lv_font_montserrat_30 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_32
|
||||
{ "MONTSERRAT_32", &lv_font_montserrat_32 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_34
|
||||
{ "MONTSERRAT_34", &lv_font_montserrat_34 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_36
|
||||
{ "MONTSERRAT_36", &lv_font_montserrat_36 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_38
|
||||
{ "MONTSERRAT_38", &lv_font_montserrat_38 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_40
|
||||
{ "MONTSERRAT_40", &lv_font_montserrat_40 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_42
|
||||
{ "MONTSERRAT_42", &lv_font_montserrat_42 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_44
|
||||
{ "MONTSERRAT_44", &lv_font_montserrat_44 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_46
|
||||
{ "MONTSERRAT_46", &lv_font_montserrat_46 },
|
||||
#endif
|
||||
#if LV_FONT_MONTSERRAT_48
|
||||
{ "MONTSERRAT_48", &lv_font_montserrat_48 },
|
||||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
// Color themes
|
||||
//
|
||||
|
||||
uint32_t active_theme_index = 0;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void create_screens() {
|
||||
|
||||
// Set default LVGL theme
|
||||
lv_display_t *dispp = lv_display_get_default();
|
||||
lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), false, LV_FONT_DEFAULT);
|
||||
lv_display_set_theme(dispp, theme);
|
||||
|
||||
// Initialize screens
|
||||
// Create screens
|
||||
create_screen_temperature();
|
||||
create_screen_humidity();
|
||||
create_screen_moisture();
|
||||
create_screen_intensity();
|
||||
}
|
||||
63
components/ui/screens.h
Normal file
63
components/ui/screens.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef EEZ_LVGL_UI_SCREENS_H
|
||||
#define EEZ_LVGL_UI_SCREENS_H
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Screens
|
||||
|
||||
enum ScreensEnum {
|
||||
_SCREEN_ID_FIRST = 1,
|
||||
SCREEN_ID_TEMPERATURE = 1,
|
||||
SCREEN_ID_HUMIDITY = 2,
|
||||
SCREEN_ID_MOISTURE = 3,
|
||||
SCREEN_ID_INTENSITY = 4,
|
||||
_SCREEN_ID_LAST = 4
|
||||
};
|
||||
|
||||
typedef struct _objects_t {
|
||||
lv_obj_t *temperature;
|
||||
lv_obj_t *humidity;
|
||||
lv_obj_t *moisture;
|
||||
lv_obj_t *intensity;
|
||||
lv_obj_t *obj0;
|
||||
lv_obj_t *obj1;
|
||||
lv_obj_t *obj2;
|
||||
lv_obj_t *obj3;
|
||||
lv_obj_t *obj4;
|
||||
lv_obj_t *obj5;
|
||||
lv_obj_t *obj6;
|
||||
lv_obj_t *obj7;
|
||||
lv_obj_t *obj8;
|
||||
lv_obj_t *obj9;
|
||||
lv_obj_t *obj10;
|
||||
lv_obj_t *obj11;
|
||||
} objects_t;
|
||||
|
||||
extern objects_t objects;
|
||||
|
||||
void create_screen_temperature();
|
||||
void tick_screen_temperature();
|
||||
|
||||
void create_screen_humidity();
|
||||
void tick_screen_humidity();
|
||||
|
||||
void create_screen_moisture();
|
||||
void tick_screen_moisture();
|
||||
|
||||
void create_screen_intensity();
|
||||
void tick_screen_intensity();
|
||||
|
||||
void tick_screen_by_id(enum ScreensEnum screenId);
|
||||
void tick_screen(int screen_index);
|
||||
|
||||
void create_screens();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*EEZ_LVGL_UI_SCREENS_H*/
|
||||
4
components/ui/structs.h
Normal file
4
components/ui/structs.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#ifndef EEZ_LVGL_UI_STRUCTS_H
|
||||
#define EEZ_LVGL_UI_STRUCTS_H
|
||||
|
||||
#endif /*EEZ_LVGL_UI_STRUCTS_H*/
|
||||
6
components/ui/styles.c
Normal file
6
components/ui/styles.c
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "styles.h"
|
||||
#include "images.h"
|
||||
#include "fonts.h"
|
||||
|
||||
#include "ui.h"
|
||||
#include "screens.h"
|
||||
14
components/ui/styles.h
Normal file
14
components/ui/styles.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef EEZ_LVGL_UI_STYLES_H
|
||||
#define EEZ_LVGL_UI_STYLES_H
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*EEZ_LVGL_UI_STYLES_H*/
|
||||
32
components/ui/ui.c
Normal file
32
components/ui/ui.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "ui.h"
|
||||
#include "screens.h"
|
||||
#include "images.h"
|
||||
#include "actions.h"
|
||||
#include "vars.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static int16_t currentScreen = -1;
|
||||
|
||||
static lv_obj_t *getLvglObjectFromIndex(int32_t index) {
|
||||
if (index == -1) {
|
||||
return 0;
|
||||
}
|
||||
return ((lv_obj_t **)&objects)[index];
|
||||
}
|
||||
|
||||
void loadScreen(enum ScreensEnum screenId) {
|
||||
currentScreen = screenId - 1;
|
||||
lv_obj_t *screen = getLvglObjectFromIndex(currentScreen);
|
||||
lv_scr_load_anim(screen, LV_SCR_LOAD_ANIM_FADE_IN, 200, 0, false);
|
||||
}
|
||||
|
||||
void ui_init() {
|
||||
create_screens();
|
||||
loadScreen(SCREEN_ID_TEMPERATURE);
|
||||
|
||||
}
|
||||
|
||||
void ui_tick() {
|
||||
tick_screen(currentScreen);
|
||||
}
|
||||
21
components/ui/ui.h
Normal file
21
components/ui/ui.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef EEZ_LVGL_UI_GUI_H
|
||||
#define EEZ_LVGL_UI_GUI_H
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#include "screens.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void ui_init();
|
||||
void ui_tick();
|
||||
|
||||
void loadScreen(enum ScreensEnum screenId);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // EEZ_LVGL_UI_GUI_H
|
||||
3331
components/ui/ui_font_source_han_sans_sc_medium_22.c
Normal file
3331
components/ui/ui_font_source_han_sans_sc_medium_22.c
Normal file
File diff suppressed because it is too large
Load Diff
5692
components/ui/ui_font_source_han_sans_sc_medium_36.c
Normal file
5692
components/ui/ui_font_source_han_sans_sc_medium_36.c
Normal file
File diff suppressed because it is too large
Load Diff
119
components/ui/ui_image_humi.c
Normal file
119
components/ui/ui_image_humi.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_LVGL_H_INCLUDE_SYSTEM)
|
||||
#include <lvgl.h>
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_IMG_HUMI
|
||||
#define LV_ATTRIBUTE_IMG_HUMI
|
||||
#endif
|
||||
|
||||
static const
|
||||
LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_HUMI
|
||||
uint8_t img_humi_map[] = {
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd0,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xd1,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xd0,0xe0,0xd0,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd8,0xe0,0xd0,0x01,0xd1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0xff,0xff,0xff,0xff,0x40,0x9f,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xbf,0x00,0x20,0xdf,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0x40,0x00,0x00,0x00,0x60,0xff,0xff,0xff,0xff,0x60,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xbf,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x60,0x20,0xbf,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0x20,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xbf,0x00,0x00,0x40,0xff,0xff,0xff,0xdf,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xdf,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x7f,0x00,0x00,0x40,0xff,0xff,0xdf,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0x7f,0x00,0x00,0x20,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0x9f,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x60,0xff,0xff,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0xff,0xff,0xdf,0x60,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0xdf,0xdf,0xbf,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x20,0x60,0x9f,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xff,0xbf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x60,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0x9f,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xbf,0x7f,0x20,0x00,0x00,0x00,0x00,0x20,0x7f,0x9f,0xbf,0xff,0xff,0xdf,0xdf,0x9f,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xbf,0x7f,0x60,0x60,0x7f,0x9f,0xdf,0xff,0xff,0xff,0x9f,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x9f,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x60,0x7f,0xbf,0xdf,0xbf,0x9f,0x7f,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
};
|
||||
|
||||
const lv_image_dsc_t img_humi = {
|
||||
.header = {
|
||||
.magic = LV_IMAGE_HEADER_MAGIC,
|
||||
.cf = LV_COLOR_FORMAT_RGB565A8,
|
||||
.flags = 0,
|
||||
.w = 48,
|
||||
.h = 48,
|
||||
.stride = 100,
|
||||
.reserved_2 = 0,
|
||||
},
|
||||
.data_size = sizeof(img_humi_map),
|
||||
.data = img_humi_map,
|
||||
.reserved = NULL,
|
||||
};
|
||||
119
components/ui/ui_image_light.c
Normal file
119
components/ui/ui_image_light.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_LVGL_H_INCLUDE_SYSTEM)
|
||||
#include <lvgl.h>
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_IMG_LIGHT
|
||||
#define LV_ATTRIBUTE_IMG_LIGHT
|
||||
#endif
|
||||
|
||||
static const
|
||||
LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_LIGHT
|
||||
uint8_t img_light_map[] = {
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x2f,0x11,0x2f,0x11,0x2f,0x11,0x2f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0xee,0x10,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x2f,0x11,0x2f,0x11,0x2f,0x11,0x2f,0x11,0x2f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x2f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x0f,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x7f,0x7f,0x7f,0x7f,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x7f,0x9f,0x9f,0x9f,0x9f,0x7f,0x9f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0xaf,0x9f,0x7f,0x7f,0x7f,0x9f,0x40,0x9f,0x9f,0x9f,0x9f,0x7f,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x88,0x88,0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x9f,0x9f,0x9f,0x9f,0x9f,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x7f,0xbf,0xbf,0xbf,0xbf,0x60,0x9f,0x7f,0x60,0x60,0x74,0x9c,0x60,0x60,0x60,0x60,0x60,0x60,0x7f,0x9f,0x7f,0xbf,0xbf,0xbf,0x9f,0x7f,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0xdf,0x20,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0x7f,0x00,0x00,0x00,0xbf,0xff,0x7f,0xff,0xff,0x7f,0xff,0xdf,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xbf,0x40,0x00,0x00,0x7f,0xff,0xdf,0x00,0xff,0xff,0x20,0xbf,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0x40,0x00,0xff,0xff,0x20,0x20,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0x9f,0x00,0x00,0x00,0x9f,0xff,0x9f,0x00,0x00,0xff,0xff,0x20,0x00,0x9f,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0x9f,0x00,0x00,0xbf,0xff,0xdf,0x20,0x00,0xff,0xff,0x20,0x00,0x20,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0x9f,0x00,0x20,0xbf,0xff,0xdf,0x20,0xff,0xff,0x20,0x00,0x00,0xbf,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0x9f,0x00,0x20,0xbf,0xff,0xdf,0xff,0xff,0x20,0x00,0x7f,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0x9f,0x00,0x20,0xdf,0xff,0xff,0xff,0x20,0x40,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0x7f,0x00,0x60,0xff,0xff,0x9f,0x00,0x20,0xdf,0xff,0xff,0x60,0xff,0xff,0x7f,0xbf,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0x9f,0x00,0x20,0xff,0xff,0xff,0xff,0xbf,0x00,0xdf,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0x7f,0x00,0x60,0xff,0xbf,0x00,0x00,0xff,0xff,0xff,0xdf,0x00,0x00,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0x7f,0x00,0x20,0x00,0x00,0x00,0xff,0xff,0xdf,0x20,0x00,0x7f,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xff,0xff,0x40,0x00,0x40,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0x7f,0x00,0x00,0x00,0xff,0xff,0x20,0x7f,0xff,0xff,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,0x7f,0xff,0xff,0x60,0x00,0x00,0xff,0xff,0xff,0xff,0xff,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,0x7f,0xff,0x9f,0x00,0x00,0xdf,0xff,0xff,0xdf,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x20,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x7f,0x7f,0x7f,0x7f,0x60,0x20,0x20,0x20,0x20,0x3c,0x20,0x74,0x74,0x74,0x74,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x7f,0xbf,0xbf,0xbf,0xbf,0x9f,0x9f,0x7f,0x60,0x60,0x60,0x60,0x60,0x60,0x9c,0x74,0x60,0x60,0x60,0x9f,0x60,0xbf,0xbf,0xbf,0xbf,0x7f,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x9f,0x9f,0x9f,0x9f,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x88,0x88,0x88,0x88,0x88,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x7f,0x9f,0x9f,0x9f,0x9f,0x60,0x9f,0x7f,0x7f,0x7f,0x9f,0xaf,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x9f,0x9f,0x40,0x9f,0x9f,0x9f,0x7f,0x7f,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
};
|
||||
|
||||
const lv_image_dsc_t img_light = {
|
||||
.header = {
|
||||
.magic = LV_IMAGE_HEADER_MAGIC,
|
||||
.cf = LV_COLOR_FORMAT_RGB565A8,
|
||||
.flags = 0,
|
||||
.w = 48,
|
||||
.h = 48,
|
||||
.stride = 100,
|
||||
.reserved_2 = 0,
|
||||
},
|
||||
.data_size = sizeof(img_light_map),
|
||||
.data = img_light_map,
|
||||
.reserved = NULL,
|
||||
};
|
||||
119
components/ui/ui_image_mois.c
Normal file
119
components/ui/ui_image_mois.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_LVGL_H_INCLUDE_SYSTEM)
|
||||
#include <lvgl.h>
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_IMG_MOIS
|
||||
#define LV_ATTRIBUTE_IMG_MOIS
|
||||
#endif
|
||||
|
||||
static const
|
||||
LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_MOIS
|
||||
uint8_t img_mois_map[] = {
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7a,0x0c,0xbb,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xff,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,
|
||||
0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,
|
||||
0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xba,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0xbb,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x20,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,0x7f,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x40,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x60,0x9f,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x60,0x00,0x40,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x00,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0x9f,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xdf,0xff,0xff,0x9f,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0x7f,0x20,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xdf,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0xff,0x7f,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0x60,0x00,0x00,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,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,0x20,0xff,0xff,0x60,0x00,0x00,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,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,0x20,0xff,0xff,0x9f,0x00,0x00,0x20,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xdf,0xbf,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0x20,0x00,0x00,0x00,0x40,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xbf,0x7f,0x60,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x20,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x16,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0x7f,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xdf,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0xa3,0xff,0xff,0xba,0x01,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x7f,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x7f,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xff,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x9f,0xdf,0xff,0xff,0xff,0xdf,0x9f,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x51,0xff,0xff,0xff,0xff,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0xff,0xff,0xff,0xff,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x50,0xa6,0xab,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x7f,0xdf,0xdf,0xbf,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x60,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xbf,0xff,0xff,0xdf,0x9f,0x40,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xdf,0x9f,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x7f,0xbf,0xff,0xff,0xff,0xff,0xff,0xdf,0xbf,0x9f,0x60,0x40,0x00,0x00,0x00,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,
|
||||
0x40,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xdf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,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,0xff,0x40,0x00,0x00,0x00,0xbf,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,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,
|
||||
0x00,0x20,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,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x60,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,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x7f,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,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,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,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x20,0x7f,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,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x7f,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,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,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,0xff,0xff,0xff,0xff,0xff,0xdf,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xbf,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,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x7f,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x9f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x7f,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x9f,0xbf,0xdf,0xdf,0xff,0xdf,0xdf,0xdf,0xbf,0x7f,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
};
|
||||
|
||||
const lv_image_dsc_t img_mois = {
|
||||
.header = {
|
||||
.magic = LV_IMAGE_HEADER_MAGIC,
|
||||
.cf = LV_COLOR_FORMAT_RGB565A8,
|
||||
.flags = 0,
|
||||
.w = 48,
|
||||
.h = 48,
|
||||
.stride = 100,
|
||||
.reserved_2 = 0,
|
||||
},
|
||||
.data_size = sizeof(img_mois_map),
|
||||
.data = img_mois_map,
|
||||
.reserved = NULL,
|
||||
};
|
||||
119
components/ui/ui_image_temp.c
Normal file
119
components/ui/ui_image_temp.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifdef __has_include
|
||||
#if __has_include("lvgl.h")
|
||||
#ifndef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#define LV_LVGL_H_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
|
||||
#include "lvgl.h"
|
||||
#elif defined(LV_LVGL_H_INCLUDE_SYSTEM)
|
||||
#include <lvgl.h>
|
||||
#elif defined(LV_BUILD_TEST)
|
||||
#include "../lvgl.h"
|
||||
#else
|
||||
#include "lvgl/lvgl.h"
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_MEM_ALIGN
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
#ifndef LV_ATTRIBUTE_IMG_TEMP
|
||||
#define LV_ATTRIBUTE_IMG_TEMP
|
||||
#endif
|
||||
|
||||
static const
|
||||
LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_TEMP
|
||||
uint8_t img_temp_map[] = {
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xa5,0x1f,0xa5,0x1f,0xa5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,0x1f,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,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,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xc5,0x1f,0xa5,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,0x9f,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x9f,0xff,0xdf,0xbf,0x9f,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x20,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,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,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xbf,0x7f,0x60,0x7f,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,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,0xff,0xff,0x9f,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0x9f,0x00,0x00,0x00,0x60,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xdf,0xdf,0x9f,0x00,0x00,0x00,0x9f,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x40,0x60,0x60,0x60,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x9f,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x7f,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x60,0x00,0x00,0x00,0x20,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x7f,0x40,0x00,0x20,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0xbf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x20,0x20,0x20,0x20,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x00,0x00,0x40,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0x9f,0x9f,0x9f,0x9f,0x9f,0x7f,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0x7f,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xdf,0x40,0x00,0x60,0xff,0xff,0xdf,0x00,0x20,0xbf,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x60,0xff,0xff,0xdf,0x00,0x00,0x20,0x7f,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x60,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xdf,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x40,0xdf,0xff,0xff,0xdf,0x7f,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xdf,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9f,0xff,0xff,0xff,0xff,0xdf,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x60,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x20,0x00,0x00,0x40,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xff,0xff,0x9f,0x20,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0x20,0x00,0x00,0x40,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x00,0xbf,0xff,0xff,0xbf,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xff,0xff,0xdf,0x7f,0x00,0x00,0x60,0xff,0xff,0xff,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x7f,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0x20,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x7f,0xff,0xff,0xbf,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x40,0xff,0xff,0xdf,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xdf,0x20,0x00,0x00,0x20,0x7f,0xff,0xff,0xff,0xff,0xbf,0x00,0x00,0x7f,0xff,0xff,0xbf,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x60,0xff,0xff,0xdf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x60,0xdf,0xff,0xff,0xbf,0x00,0x00,0x7f,0xff,0xff,0xdf,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x60,0xff,0xff,0xdf,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x9f,0xdf,0x00,0x00,0x40,0xff,0xff,0xff,0x00,0x00,0x00,0x60,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x9f,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xff,0xff,0xff,0x60,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0xff,0xff,0xff,0x60,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0xff,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xdf,0x00,0x00,0x00,0x20,0x7f,0xff,0xff,0xff,0xff,0xdf,0x40,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0x9f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x20,0x60,0x7f,0x40,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0x9f,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xdf,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x7f,0xff,0xff,0xff,0xff,0x40,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xff,0xdf,0x9f,0x60,0x40,0x7f,0x7f,0xff,0xff,0xff,0xff,0xff,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x60,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x9f,0xbf,0xff,0xff,0xdf,0xbf,0x7f,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
};
|
||||
|
||||
const lv_image_dsc_t img_temp = {
|
||||
.header = {
|
||||
.magic = LV_IMAGE_HEADER_MAGIC,
|
||||
.cf = LV_COLOR_FORMAT_RGB565A8,
|
||||
.flags = 0,
|
||||
.w = 48,
|
||||
.h = 48,
|
||||
.stride = 100,
|
||||
.reserved_2 = 0,
|
||||
},
|
||||
.data_size = sizeof(img_temp_map),
|
||||
.data = img_temp_map,
|
||||
.reserved = NULL,
|
||||
};
|
||||
48
components/ui/vars.c
Normal file
48
components/ui/vars.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <string.h>
|
||||
#include "vars.h"
|
||||
|
||||
char air_temperature[100] = { 0 };
|
||||
|
||||
const char *get_var_air_temperature() {
|
||||
return air_temperature;
|
||||
}
|
||||
|
||||
void set_var_air_temperature(const char *value) {
|
||||
strncpy(air_temperature, value, sizeof(air_temperature) / sizeof(char));
|
||||
air_temperature[sizeof(air_temperature) / sizeof(char) - 1] = 0;
|
||||
}
|
||||
|
||||
char air_humidity[100] = { 0 };
|
||||
|
||||
const char *get_var_air_humidity() {
|
||||
return air_humidity;
|
||||
}
|
||||
|
||||
void set_var_air_humidity(const char *value) {
|
||||
strncpy(air_humidity, value, sizeof(air_humidity) / sizeof(char));
|
||||
air_humidity[sizeof(air_humidity) / sizeof(char) - 1] = 0;
|
||||
}
|
||||
|
||||
|
||||
char soil_moisture[100] = { 0 };
|
||||
|
||||
const char *get_var_soil_moisture() {
|
||||
return soil_moisture;
|
||||
}
|
||||
|
||||
void set_var_soil_moisture(const char *value) {
|
||||
strncpy(soil_moisture, value, sizeof(soil_moisture) / sizeof(char));
|
||||
soil_moisture[sizeof(soil_moisture) / sizeof(char) - 1] = 0;
|
||||
}
|
||||
|
||||
char light_intensity[100] = { 0 };
|
||||
|
||||
const char *get_var_light_intensity() {
|
||||
return light_intensity;
|
||||
}
|
||||
|
||||
void set_var_light_intensity(const char *value) {
|
||||
strncpy(light_intensity, value, sizeof(light_intensity) / sizeof(char));
|
||||
light_intensity[sizeof(light_intensity) / sizeof(char) - 1] = 0;
|
||||
}
|
||||
|
||||
37
components/ui/vars.h
Normal file
37
components/ui/vars.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef EEZ_LVGL_UI_VARS_H
|
||||
#define EEZ_LVGL_UI_VARS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// enum declarations
|
||||
|
||||
// Flow global variables
|
||||
|
||||
enum FlowGlobalVariables {
|
||||
FLOW_GLOBAL_VARIABLE_AIR_TEMPERATURE = 0,
|
||||
FLOW_GLOBAL_VARIABLE_AIR_HUMIDITY = 1,
|
||||
FLOW_GLOBAL_VARIABLE_SOIL_MOISTURE = 2,
|
||||
FLOW_GLOBAL_VARIABLE_LIGHT_INTENSITY = 3
|
||||
};
|
||||
|
||||
// Native global variables
|
||||
|
||||
extern const char *get_var_air_temperature();
|
||||
extern void set_var_air_temperature(const char *value);
|
||||
extern const char *get_var_air_humidity();
|
||||
extern void set_var_air_humidity(const char *value);
|
||||
extern const char *get_var_soil_moisture();
|
||||
extern void set_var_soil_moisture(const char *value);
|
||||
extern const char *get_var_light_intensity();
|
||||
extern void set_var_light_intensity(const char *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*EEZ_LVGL_UI_VARS_H*/
|
||||
365
components/wifi-connect/BLOG.md
Normal file
365
components/wifi-connect/BLOG.md
Normal file
@@ -0,0 +1,365 @@
|
||||
# ESP32 配网组件设计实践:聚焦功能与实现,而不是项目绑定
|
||||
|
||||
很多 ESP32 设备在开发阶段都把“配网”当成一个小功能,但真正落地后会发现:
|
||||
|
||||
- 用户第一次接入要顺畅
|
||||
- 失败后要能恢复
|
||||
- 日志要便于现场排障
|
||||
|
||||
这篇文章只讲配网组件本身,聚焦能力设计和实现思路,不依赖具体业务项目。
|
||||
|
||||
---
|
||||
|
||||
## 一、目标能力定义
|
||||
|
||||
一个可落地的配网组件,建议至少包含以下能力:
|
||||
|
||||
- 按键触发配网
|
||||
- 常驻配网模式(可选)
|
||||
- SoftAP + Web Portal 配网
|
||||
- DNS 劫持与常见 Captive Portal 兼容
|
||||
- 凭据持久化(NVS)与重启自动重连
|
||||
- 清除历史配置(API + Web)
|
||||
- 状态机与可读日志
|
||||
|
||||
这几项组合起来,才能覆盖“首次成功 + 失败恢复 + 现场维护”三个关键场景。
|
||||
|
||||
图示(整体功能目标关联):
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[按键任务/业务触发] --> B[进入 provisioning]
|
||||
B --> C[启动 SoftAP]
|
||||
B --> D[启动 HTTP Server]
|
||||
B --> E[启动 DNS Hijack]
|
||||
D --> F[/api/scan]
|
||||
D --> G[/api/connect]
|
||||
D --> H[/api/status]
|
||||
D --> I[/api/clear]
|
||||
G --> J[设置 STA 参数]
|
||||
J --> K[发起 esp_wifi_connect]
|
||||
K --> L{Wi-Fi/IP 事件}
|
||||
L -->|成功| M[状态=connected]
|
||||
L -->|失败| N[状态=failed]
|
||||
I --> O[清除 NVS 凭据]
|
||||
O --> P[清空运行态缓存]
|
||||
P --> B
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、组件架构(通用)
|
||||
|
||||
```text
|
||||
[按键任务] --> [进入配网]
|
||||
|
|
||||
+--> SoftAP + HTTP Server + DNS Hijack
|
||||
|
||||
[Web] -- /api/scan --> Wi-Fi 扫描
|
||||
[Web] -- /api/connect --> 设置 STA 并发起连接
|
||||
[Web] -- /api/status --> 轮询状态
|
||||
[Web] -- /api/clear --> 清除已保存配置
|
||||
|
||||
[Wi-Fi/IP 事件] --> 更新状态机 + 打印日志 + 保存凭据
|
||||
```
|
||||
|
||||
推荐状态机:
|
||||
|
||||
- `idle`
|
||||
- `provisioning`
|
||||
- `connecting`
|
||||
- `connected`
|
||||
- `failed`
|
||||
- `timeout`
|
||||
|
||||
图示(状态机):
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> idle
|
||||
idle --> provisioning: wifi_connect_start()
|
||||
provisioning --> connecting: POST /api/connect
|
||||
connecting --> connected: GOT_IP
|
||||
connecting --> failed: AUTH_FAIL / NO_AP / ...
|
||||
connecting --> timeout: connect timeout
|
||||
failed --> provisioning: POST /api/clear
|
||||
timeout --> provisioning: POST /api/clear
|
||||
connected --> provisioning: 常驻配网继续开放入口(可选)
|
||||
connected --> idle: stop provisioning(按策略)
|
||||
```
|
||||
|
||||
上图展示了组件的主要数据流与恢复路径。
|
||||
|
||||
---
|
||||
|
||||
## 三、对外 API 设计建议
|
||||
|
||||
推荐保持“少而稳”的接口:
|
||||
|
||||
```c
|
||||
esp_err_t wifi_connect_init(void);
|
||||
esp_err_t wifi_connect_start(void);
|
||||
esp_err_t wifi_connect_stop(void);
|
||||
wifi_connect_status_t wifi_connect_get_status(void);
|
||||
esp_err_t wifi_connect_get_config(wifi_connect_config_t *config);
|
||||
esp_err_t wifi_connect_clear_config(void);
|
||||
```
|
||||
|
||||
设计原则:
|
||||
|
||||
- `init` 只做初始化和基础恢复
|
||||
- `start/stop` 控制配网生命周期
|
||||
- `get_status` 作为 UI/接口层统一读取入口
|
||||
- `clear_config` 提供失败恢复通道
|
||||
|
||||
可以展示一段“典型调用顺序”代码:
|
||||
|
||||
```c
|
||||
ESP_ERROR_CHECK(wifi_connect_init());
|
||||
|
||||
// 按键触发或业务触发时
|
||||
ESP_ERROR_CHECK(wifi_connect_start());
|
||||
|
||||
// UI 侧轮询状态
|
||||
wifi_connect_status_t st = wifi_connect_get_status();
|
||||
|
||||
// 需要恢复出厂配网时
|
||||
ESP_ERROR_CHECK(wifi_connect_clear_config());
|
||||
```
|
||||
|
||||
图示(API 生命周期时序):
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant App as 应用层
|
||||
participant WC as wifi-connect
|
||||
participant WiFi as esp_wifi
|
||||
participant Web as 配网页面
|
||||
|
||||
App->>WC: wifi_connect_init()
|
||||
WC-->>App: ESP_OK
|
||||
|
||||
App->>WC: wifi_connect_start()
|
||||
WC->>WiFi: 开启 APSTA / 事件注册
|
||||
WC-->>App: ESP_OK
|
||||
|
||||
Web->>WC: POST /api/connect(ssid,pass)
|
||||
WC->>WiFi: esp_wifi_disconnect()
|
||||
WC->>WiFi: esp_wifi_set_config()
|
||||
WC->>WiFi: esp_wifi_connect()
|
||||
|
||||
WiFi-->>WC: WIFI_EVENT / IP_EVENT
|
||||
alt 获取到 IP
|
||||
WC-->>Web: status=connected
|
||||
else 连接失败或超时
|
||||
WC-->>Web: status=failed|timeout
|
||||
end
|
||||
|
||||
Web->>WC: POST /api/clear
|
||||
WC-->>Web: status=provisioning
|
||||
```
|
||||
|
||||
上图对应完整 API 生命周期(init -> start -> connecting -> connected/failed -> clear)。
|
||||
|
||||
---
|
||||
|
||||
## 四、关键实现点
|
||||
|
||||
### 1) Web 配网页面保持轻量
|
||||
|
||||
不一定要引入前端框架。对于资源受限设备,内嵌简洁 HTML/JS 往往更稳定。
|
||||
|
||||
建议页面只保留核心动作:
|
||||
|
||||
- 扫描网络
|
||||
- 提交连接
|
||||
- 查看状态
|
||||
- 清除配置
|
||||
|
||||
### 2) Captive Portal 兼容是体验关键
|
||||
|
||||
仅提供首页 URL 通常不够。建议额外处理:
|
||||
|
||||
- 常见探测路径(如 `generate_204` 等)
|
||||
- 未知路径统一 302 到配网页
|
||||
|
||||
这样手机系统弹门户页面成功率会明显提高。
|
||||
|
||||
示例代码(伪代码):
|
||||
|
||||
```c
|
||||
static esp_err_t captive_redirect_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_status(req, "302 Found");
|
||||
httpd_resp_set_hdr(req, "Location", "http://192.168.4.1/");
|
||||
return httpd_resp_send(req, NULL, 0);
|
||||
}
|
||||
|
||||
// 注册常见探测路径
|
||||
httpd_register_uri_handler(server, &uri_generate_204);
|
||||
httpd_register_uri_handler(server, &uri_hotspot_detect);
|
||||
httpd_register_uri_handler(server, &uri_ncsi);
|
||||
```
|
||||
|
||||
可直接使用以下流程图(对应 Captive Portal 重定向路径):
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[手机连接设备 AP] --> B[访问任意域名]
|
||||
B --> C[DNS Hijack 返回 192.168.4.1]
|
||||
C --> D[HTTP 探测路径请求<br/>/generate_204 等]
|
||||
D --> E[302 Location: http://192.168.4.1/]
|
||||
E --> F[打开配网页面]
|
||||
F --> G[扫描 / 连接 / 清除配置]
|
||||
```
|
||||
|
||||
### 3) 连接前主动断开旧连接
|
||||
|
||||
这是一个高频坑:设备已有 STA 连接时,直接连接新 AP 可能导致超时或异常状态。
|
||||
|
||||
建议在 `esp_wifi_set_config + esp_wifi_connect` 前先执行 `esp_wifi_disconnect()`,并对异常返回做日志记录。
|
||||
|
||||
示例代码:
|
||||
|
||||
```c
|
||||
esp_err_t err = esp_wifi_disconnect();
|
||||
if (err != ESP_OK && err != ESP_ERR_WIFI_NOT_CONNECT) {
|
||||
ESP_LOGW(TAG, "disconnect before reconnect failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &cfg));
|
||||
ESP_ERROR_CHECK(esp_wifi_connect());
|
||||
```
|
||||
|
||||
### 4) “清除配置”必须打通全链路
|
||||
|
||||
建议同时提供:
|
||||
|
||||
- SDK API:`wifi_connect_clear_config()`
|
||||
- HTTP API:`POST /api/clear`
|
||||
- 页面按钮:`清除已保存`
|
||||
|
||||
这样现场人员无需改固件即可恢复设备。
|
||||
|
||||
建议把清除动作写成“存储层 + 运行态”两段:
|
||||
|
||||
```c
|
||||
esp_err_t wifi_connect_clear_config(void)
|
||||
{
|
||||
// 1) 清 NVS 凭据
|
||||
ESP_RETURN_ON_ERROR(nvs_erase_key(nvs, "ssid"), TAG, "erase ssid failed");
|
||||
ESP_RETURN_ON_ERROR(nvs_erase_key(nvs, "pass"), TAG, "erase pass failed");
|
||||
ESP_RETURN_ON_ERROR(nvs_commit(nvs), TAG, "nvs commit failed");
|
||||
|
||||
// 2) 清内存态并回到 provisioning
|
||||
memset(&s_ctx.pending_cfg, 0, sizeof(s_ctx.pending_cfg));
|
||||
s_ctx.status = WIFI_CONNECT_STATUS_PROVISIONING;
|
||||
return ESP_OK;
|
||||
}
|
||||
```
|
||||
|
||||
可直接使用以下流程图(对应 clear 后状态回到 provisioning):
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[开始清除配置] --> B[擦除 NVS:ssid]
|
||||
B --> C[擦除 NVS:pass]
|
||||
C --> D[nvs_commit]
|
||||
D --> E[清空 pending 配置缓存]
|
||||
E --> F[清空错误原因/中间状态]
|
||||
F --> G[状态切回 provisioning]
|
||||
G --> H[前端轮询显示 可重新配网]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、日志策略(非常重要)
|
||||
|
||||
建议日志遵循“状态 + 原因”格式,例如:
|
||||
|
||||
- `【状态】配网已启动:热点已开启,SSID=...`
|
||||
- `【状态】开始连接路由器:目标网络=...`
|
||||
- `【状态】联网成功:获取 IP=...`
|
||||
- `【状态】连接失败:原因=...`
|
||||
|
||||
这样做的收益是:
|
||||
|
||||
- 开发调试快
|
||||
- 测试可直接定位阶段
|
||||
- 现场人员无需先理解底层驱动日志
|
||||
|
||||
可展示一个统一日志函数风格:
|
||||
|
||||
```c
|
||||
static void log_state_i(const char *title, const char *detail)
|
||||
{
|
||||
ESP_LOGI(TAG, "【状态】%s:%s", title, detail ? detail : "-");
|
||||
}
|
||||
```
|
||||
|
||||
如需补充非 Mermaid 图,建议仅放一张关键串口日志截图(启动配网、连接中、成功/失败重试)。
|
||||
|
||||
---
|
||||
|
||||
## 六、常见问题与排障思路
|
||||
|
||||
### 问题 1:手机连上 AP 但页面不弹
|
||||
|
||||
排查:
|
||||
|
||||
- 手动访问 `http://192.168.4.1`
|
||||
- 检查 DNS 劫持和门户探测路径是否启用
|
||||
- 检查 HTTP 服务是否启动成功
|
||||
|
||||
### 问题 2:提交密码后长时间连接失败
|
||||
|
||||
排查:
|
||||
|
||||
- 是否先断开旧 STA
|
||||
- 是否正确处理了连接超时和重试
|
||||
- 失败原因是否上报到状态机和前端
|
||||
|
||||
### 问题 3:配网失败后无法恢复
|
||||
|
||||
排查:
|
||||
|
||||
- NVS 清除逻辑是否真正执行
|
||||
- 内存态缓存是否同时清空
|
||||
- 配网状态是否回到 `provisioning`
|
||||
|
||||
---
|
||||
|
||||
## 七、测试清单(可复用)
|
||||
|
||||
建议每次迭代最少覆盖:
|
||||
|
||||
1. 首次配网成功
|
||||
2. 密码错误后重试成功
|
||||
3. 连接旧网状态下切换新网成功
|
||||
4. 清除配置后重新配网成功
|
||||
5. 重启后自动重连
|
||||
6. 空闲超时与手动停止路径可用
|
||||
|
||||
这 6 条通过后,组件稳定性通常会显著提升。
|
||||
|
||||
---
|
||||
|
||||
## 八、可继续增强的方向
|
||||
|
||||
- 配网页面安全增强(鉴权/会话)
|
||||
- 多语言提示
|
||||
- 更细粒度错误码映射
|
||||
- BLE 辅助配网
|
||||
- 命令行/远程维护接口联动
|
||||
|
||||
---
|
||||
|
||||
## 结语
|
||||
|
||||
配网组件的核心价值,不是“让设备连上一次网”,而是:
|
||||
|
||||
- 功能完整
|
||||
- 异常可恢复
|
||||
- 排障可落地
|
||||
|
||||
当这三件事做好后,它才是一个能复用、能维护、能上线的基础能力组件。
|
||||
5
components/wifi-connect/CMakeLists.txt
Normal file
5
components/wifi-connect/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
idf_component_register(
|
||||
SRCS "wifi-connect.c"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES esp_wifi esp_timer esp_event esp_netif nvs_flash esp_http_server lwip driver
|
||||
)
|
||||
87
components/wifi-connect/Kconfig.projbuild
Normal file
87
components/wifi-connect/Kconfig.projbuild
Normal file
@@ -0,0 +1,87 @@
|
||||
menu "WiFi Connect"
|
||||
|
||||
choice WIFI_CONNECT_PROVISION_MODE
|
||||
prompt "Provisioning mode"
|
||||
default WIFI_CONNECT_PROVISION_MODE_BUTTON
|
||||
help
|
||||
Select how provisioning mode is entered.
|
||||
|
||||
config WIFI_CONNECT_PROVISION_MODE_BUTTON
|
||||
bool "Button triggered (default)"
|
||||
help
|
||||
Enter provisioning only when button long-press is detected.
|
||||
|
||||
config WIFI_CONNECT_PROVISION_MODE_ALWAYS_ON
|
||||
bool "Always-on provisioning"
|
||||
help
|
||||
Start provisioning automatically on boot and keep it running.
|
||||
Provisioning will not auto-stop after idle timeout or STA connect.
|
||||
|
||||
endchoice
|
||||
|
||||
config WIFI_CONNECT_BUTTON_GPIO
|
||||
int "Provision button GPIO"
|
||||
range 0 21
|
||||
default 9
|
||||
help
|
||||
GPIO used for entering provisioning mode.
|
||||
|
||||
config WIFI_CONNECT_BUTTON_ACTIVE_LEVEL
|
||||
int "Provision button active level"
|
||||
range 0 1
|
||||
default 0
|
||||
help
|
||||
Active level of provisioning button. 0 means active-low.
|
||||
|
||||
config WIFI_CONNECT_DEBOUNCE_MS
|
||||
int "Button debounce time (ms)"
|
||||
range 10 200
|
||||
default 40
|
||||
|
||||
config WIFI_CONNECT_LONG_PRESS_MS
|
||||
int "Button long press trigger time (ms)"
|
||||
range 500 10000
|
||||
default 2000
|
||||
|
||||
config WIFI_CONNECT_BUTTON_STARTUP_GUARD_MS
|
||||
int "Button startup guard time (ms)"
|
||||
range 0 30000
|
||||
default 5000
|
||||
help
|
||||
Ignore button long-press detection during startup guard window.
|
||||
Useful when button pin is shared with other peripherals.
|
||||
|
||||
config WIFI_CONNECT_BUTTON_RELEASE_ARM_MS
|
||||
int "Button release arm time (ms)"
|
||||
range 20 2000
|
||||
default 200
|
||||
help
|
||||
Require button to stay in released level for this duration
|
||||
before long-press detection is armed.
|
||||
|
||||
config WIFI_CONNECT_CONNECT_TIMEOUT_SEC
|
||||
int "Wi-Fi connect timeout (sec)"
|
||||
range 5 180
|
||||
default 30
|
||||
|
||||
config WIFI_CONNECT_IDLE_TIMEOUT_SEC
|
||||
int "Provisioning idle timeout (sec)"
|
||||
range 30 1800
|
||||
default 300
|
||||
|
||||
config WIFI_CONNECT_MAX_SCAN_RESULTS
|
||||
int "Maximum scan results"
|
||||
range 5 50
|
||||
default 20
|
||||
|
||||
config WIFI_CONNECT_AP_MAX_CONNECTIONS
|
||||
int "SoftAP max connections"
|
||||
range 1 10
|
||||
default 4
|
||||
|
||||
config WIFI_CONNECT_AP_GRACEFUL_STOP_SEC
|
||||
int "AP keep-alive after STA connected (sec)"
|
||||
range 0 120
|
||||
default 15
|
||||
|
||||
endmenu
|
||||
28
components/wifi-connect/QUICK_POSTER.md
Normal file
28
components/wifi-connect/QUICK_POSTER.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# BotanicalBuddy 配网四步卡(张贴版)
|
||||
|
||||
## 第 1 步:长按按键
|
||||
长按设备配网键约 2 秒,进入配网模式。
|
||||
|
||||
## 第 2 步:连接热点
|
||||
手机连接 Wi-Fi:ESP32-xxxxxx
|
||||
|
||||
## 第 3 步:打开页面
|
||||
浏览器访问:http://192.168.4.1
|
||||
|
||||
## 第 4 步:提交路由器信息
|
||||
选择家里 Wi-Fi,输入密码,点击“连接”。
|
||||
|
||||
---
|
||||
|
||||
## 失败时先做这三件事
|
||||
1. 确认访问的是 http://192.168.4.1(不是 https)
|
||||
2. 确认输入的 Wi-Fi 密码正确
|
||||
3. 路由器使用 2.4G,设备离路由器更近一点再试
|
||||
|
||||
---
|
||||
|
||||
## 二维码占位(贴纸用)
|
||||
建议制作一个二维码,内容指向:
|
||||
http://192.168.4.1
|
||||
|
||||
打印时把二维码贴在本段下方空白区域即可。
|
||||
165
components/wifi-connect/README.md
Normal file
165
components/wifi-connect/README.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# wifi-connect 组件说明
|
||||
|
||||
`wifi-connect` 是一个基于 ESP-IDF 的 Wi-Fi 配网组件,支持:
|
||||
|
||||
- 长按按键进入配网模式
|
||||
- 启动 SoftAP + Captive Portal(网页配网)
|
||||
- 手机连接热点后,通过网页扫描并选择路由器
|
||||
- 保存 Wi-Fi 凭据到 NVS
|
||||
- 下次开机自动重连
|
||||
- 支持两种配网模式:按键触发 / 常驻配网
|
||||
|
||||
面向最终用户的一页版操作说明见:`USER_GUIDE.md`
|
||||
现场打印张贴版(四步卡)见:`QUICK_POSTER.md`
|
||||
|
||||
---
|
||||
|
||||
## 目录结构
|
||||
|
||||
- `wifi-connect.c`:组件主实现(按键、APSTA、HTTP、DNS、状态机)
|
||||
- `include/wifi-connect.h`:对外 API
|
||||
- `Kconfig.projbuild`:组件配置项
|
||||
- `CMakeLists.txt`:组件构建依赖
|
||||
|
||||
---
|
||||
|
||||
## 对外 API
|
||||
|
||||
头文件:`include/wifi-connect.h`
|
||||
|
||||
- `esp_err_t wifi_connect_init(void);`
|
||||
- 初始化组件(NVS、Wi-Fi、事件、按键任务等)
|
||||
- 尝试自动连接已保存网络
|
||||
|
||||
- `esp_err_t wifi_connect_start(void);`
|
||||
- 启动配网(APSTA + HTTP + DNS)
|
||||
|
||||
- `esp_err_t wifi_connect_stop(void);`
|
||||
- 停止配网(关闭热点与相关服务)
|
||||
|
||||
- `wifi_connect_status_t wifi_connect_get_status(void);`
|
||||
- 获取当前状态:`idle / provisioning / connecting / connected / failed / timeout`
|
||||
|
||||
- `esp_err_t wifi_connect_get_config(wifi_connect_config_t *config);`
|
||||
- 读取已保存的 Wi-Fi 凭据
|
||||
|
||||
- `esp_err_t wifi_connect_clear_config(void);`
|
||||
- 清除已保存的 Wi-Fi 凭据(SSID/密码)
|
||||
|
||||
---
|
||||
|
||||
## 快速使用
|
||||
|
||||
在 `main/main.c`:
|
||||
|
||||
```c
|
||||
#include "esp_check.h"
|
||||
#include "wifi-connect.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(wifi_connect_init());
|
||||
}
|
||||
```
|
||||
|
||||
运行后:
|
||||
|
||||
1. 选择配网模式:
|
||||
- 按键触发模式:长按配置按键进入配网
|
||||
- 常驻配网模式:上电自动进入配网
|
||||
2. 手机连接 `ESP32-xxxxxx` 热点
|
||||
3. 打开 `http://192.168.4.1`
|
||||
4. 选择 Wi-Fi 并输入密码提交
|
||||
5. 配网行为:
|
||||
- 按键触发模式:连接成功后按配置自动关闭热点
|
||||
- 常驻配网模式:配网热点保持开启,不自动关闭
|
||||
|
||||
如需清空历史凭据,可在配网页面点击“清除已保存”。
|
||||
|
||||
---
|
||||
|
||||
## Kconfig 配置项
|
||||
|
||||
在 `idf.py menuconfig` 中:`WiFi Connect` 菜单
|
||||
|
||||
- `Provisioning mode`:配网模式(二选一)
|
||||
- `Button triggered`:按键触发配网(默认)
|
||||
- `Always-on provisioning`:常驻配网(上电自动进入且不自动关闭)
|
||||
|
||||
- `WIFI_CONNECT_BUTTON_GPIO`:进入配网的按键 GPIO
|
||||
- `WIFI_CONNECT_BUTTON_ACTIVE_LEVEL`:按键有效电平
|
||||
- `WIFI_CONNECT_DEBOUNCE_MS`:按键去抖时间
|
||||
- `WIFI_CONNECT_LONG_PRESS_MS`:长按触发时长
|
||||
- `WIFI_CONNECT_BUTTON_STARTUP_GUARD_MS`:上电保护窗口(该时间内忽略长按检测)
|
||||
- `WIFI_CONNECT_BUTTON_RELEASE_ARM_MS`:松手解锁时间(先稳定松手再允许长按触发)
|
||||
- `WIFI_CONNECT_CONNECT_TIMEOUT_SEC`:连接路由器超时
|
||||
- `WIFI_CONNECT_IDLE_TIMEOUT_SEC`:配网页面空闲超时
|
||||
- `WIFI_CONNECT_MAX_SCAN_RESULTS`:扫描网络最大数量
|
||||
- `WIFI_CONNECT_AP_MAX_CONNECTIONS`:SoftAP 最大连接数
|
||||
- `WIFI_CONNECT_AP_GRACEFUL_STOP_SEC`:联网成功后 AP 延迟关闭秒数
|
||||
|
||||
---
|
||||
|
||||
## 日志与状态说明(中文)
|
||||
|
||||
组件会输出统一中文状态日志,例如:
|
||||
|
||||
- `【状态】wifi-connect 初始化完成`
|
||||
- `【状态】检测到按键长按:开始进入配网模式`
|
||||
- `【状态】配网已启动:配网热点已开启,SSID=...`
|
||||
- `【状态】开始连接路由器:收到配网请求,目标网络=...`
|
||||
- `【状态】联网成功:已连接 ...,获取 IP=...`
|
||||
- `【状态】配网已停止:热点已关闭,设备继续以 STA 模式运行`
|
||||
|
||||
说明:ESP-IDF 驱动层(如 `wifi:`、`esp_netif_lwip:`)仍会输出英文日志,这是框架默认行为。
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1) 手机连上热点但不自动弹出页面
|
||||
|
||||
- 手动访问:`http://192.168.4.1`
|
||||
- 确认手机没有强制使用 HTTPS
|
||||
- 查看串口是否有 `配网已启动`、`DNS 劫持服务已启动` 日志
|
||||
|
||||
### 2) 提交后连接失败
|
||||
|
||||
- 检查密码是否正确
|
||||
- 查看日志中的失败原因码(`连接失败,原因=...`)
|
||||
- 检查路由器是否禁用了新设备接入
|
||||
- 若曾保存过旧配置,可先在页面点击“清除已保存”后再重试
|
||||
|
||||
### 4) 按键未按下却误触发配网
|
||||
|
||||
- 常见原因是按键引脚与 LCD/外设复用,初始化期间电平抖动被误判为长按
|
||||
- 可增大 `WIFI_CONNECT_BUTTON_STARTUP_GUARD_MS`(如 8000~10000)
|
||||
- 可增大 `WIFI_CONNECT_BUTTON_RELEASE_ARM_MS`(如 300~500)
|
||||
- 若硬件允许,优先给配网按键使用独立 GPIO
|
||||
|
||||
### 5) 成功后热点消失是否正常
|
||||
|
||||
- 在按键触发模式下:正常,可通过 `WIFI_CONNECT_AP_GRACEFUL_STOP_SEC` 调整关闭延时
|
||||
- 在常驻配网模式下:热点不会自动关闭
|
||||
|
||||
---
|
||||
|
||||
## 依赖
|
||||
|
||||
由 `CMakeLists.txt` 声明:
|
||||
|
||||
- `esp_wifi`
|
||||
- `esp_timer`
|
||||
- `esp_event`
|
||||
- `esp_netif`
|
||||
- `nvs_flash`
|
||||
- `esp_http_server`
|
||||
- `lwip`
|
||||
- `driver`
|
||||
|
||||
---
|
||||
|
||||
## 版本建议
|
||||
|
||||
- 推荐 ESP-IDF `v5.5.x`
|
||||
- 当前项目验证环境:`esp-idf v5.5.2`(ESP32-C3)
|
||||
82
components/wifi-connect/USER_GUIDE.md
Normal file
82
components/wifi-connect/USER_GUIDE.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# BotanicalBuddy 配网操作手册(用户版)
|
||||
|
||||
> 适用对象:现场测试、家人用户、非开发人员
|
||||
> 目标:让设备快速连上家里 Wi-Fi
|
||||
|
||||
---
|
||||
|
||||
## 1. 开始前准备
|
||||
|
||||
- 手机已打开 Wi-Fi
|
||||
- 记住家里 Wi-Fi 名称和密码
|
||||
- 设备已上电
|
||||
|
||||
---
|
||||
|
||||
## 2. 进入配网模式
|
||||
|
||||
有两种工作模式,请按项目配置使用:
|
||||
|
||||
1. 按键触发模式:长按设备上的配网按键(约 2 秒)
|
||||
2. 常驻配网模式:设备上电后会自动开启配网
|
||||
3. 当看到“配网已启动”后,手机 Wi-Fi 列表会出现:`ESP32-xxxxxx`
|
||||
|
||||
---
|
||||
|
||||
## 3. 手机连接设备热点
|
||||
|
||||
1. 在手机 Wi-Fi 中连接 `ESP32-xxxxxx`
|
||||
2. 若系统自动弹出页面,直接进入下一步
|
||||
3. 若没有自动弹出,手动打开浏览器输入:
|
||||
|
||||
`http://192.168.4.1`
|
||||
|
||||
> 注意:必须是 `http`,不要用 `https`
|
||||
|
||||
---
|
||||
|
||||
## 4. 选择路由器并提交
|
||||
|
||||
1. 点击“扫描网络”
|
||||
2. 选择你家的 Wi-Fi
|
||||
3. 输入 Wi-Fi 密码
|
||||
4. 点击“连接”
|
||||
|
||||
成功后页面会提示连接成功:
|
||||
|
||||
- 按键触发模式:设备热点会在几秒后自动关闭(正常现象)
|
||||
- 常驻配网模式:设备热点保持开启(正常现象)
|
||||
|
||||
---
|
||||
|
||||
## 5. 成功后的现象
|
||||
|
||||
- 设备不再广播 `ESP32-xxxxxx`
|
||||
- 串口会显示“联网成功,获取 IP=... ”
|
||||
- 设备进入正常工作状态
|
||||
|
||||
---
|
||||
|
||||
## 6. 常见问题
|
||||
|
||||
### Q1:手机连上热点但打不开页面
|
||||
|
||||
- 手动访问:`http://192.168.4.1`
|
||||
- 关闭手机“私人 DNS / 智能网络切换 / VPN”后重试
|
||||
- 确认没有强制跳 HTTPS
|
||||
|
||||
### Q2:提示连接失败
|
||||
|
||||
- 检查 Wi-Fi 密码是否正确
|
||||
- 确认路由器 2.4G 可用(ESP32-C3 使用 2.4G)
|
||||
- 路由器信号太弱时,靠近路由器后重试
|
||||
|
||||
### Q3:配网成功后热点消失了
|
||||
|
||||
- 这是正常设计:设备连上路由器后会自动关闭配网热点
|
||||
|
||||
---
|
||||
|
||||
## 7. 一句话速记
|
||||
|
||||
长按按键 → 连 `ESP32-xxxxxx` → 打开 `http://192.168.4.1` → 选 Wi-Fi + 输密码 → 等待成功提示。
|
||||
34
components/wifi-connect/include/wifi-connect.h
Normal file
34
components/wifi-connect/include/wifi-connect.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
WIFI_CONNECT_STATUS_IDLE = 0,
|
||||
WIFI_CONNECT_STATUS_PROVISIONING,
|
||||
WIFI_CONNECT_STATUS_CONNECTING,
|
||||
WIFI_CONNECT_STATUS_CONNECTED,
|
||||
WIFI_CONNECT_STATUS_FAILED,
|
||||
WIFI_CONNECT_STATUS_TIMEOUT,
|
||||
} wifi_connect_status_t;
|
||||
|
||||
typedef struct {
|
||||
bool has_config;
|
||||
char ssid[33];
|
||||
char password[65];
|
||||
} wifi_connect_config_t;
|
||||
|
||||
esp_err_t wifi_connect_init(void);
|
||||
esp_err_t wifi_connect_start(void);
|
||||
esp_err_t wifi_connect_stop(void);
|
||||
wifi_connect_status_t wifi_connect_get_status(void);
|
||||
esp_err_t wifi_connect_get_config(wifi_connect_config_t *config);
|
||||
esp_err_t wifi_connect_clear_config(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
1263
components/wifi-connect/wifi-connect.c
Normal file
1263
components/wifi-connect/wifi-connect.c
Normal file
File diff suppressed because it is too large
Load Diff
101
dependencies.lock
Normal file
101
dependencies.lock
Normal file
@@ -0,0 +1,101 @@
|
||||
dependencies:
|
||||
espressif/bh1750:
|
||||
component_hash: e898130f6b2fc4bc0d6022a2e431752bae808b9c94d4cc91596e36ecaf4cb7c6
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 2.0.0
|
||||
espressif/cjson:
|
||||
component_hash: 002c6d1872ee4c97d333938ebe107a29841cc847f9de89e676714bd2844057ea
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.7.19~1
|
||||
espressif/console_simple_init:
|
||||
component_hash: b488b12318f3cb6e0b55b034bd12956926d45f0e1396442e820f8ece4776c306
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.1.0
|
||||
espressif/esp_lvgl_port:
|
||||
component_hash: b6360960f47b6776462e7092861b3ea66477ffb762a01baa0aecbb3d74cd50f4
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.1'
|
||||
- name: lvgl/lvgl
|
||||
registry_url: https://components.espressif.com
|
||||
require: public
|
||||
version: '>=8,<10'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 2.7.2
|
||||
espressif/mqtt:
|
||||
component_hash: ffdad5659706b4dc14bc63f8eb73ef765efa015bf7e9adf71c813d52a2dc9342
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>=5.3'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.0.0
|
||||
idf:
|
||||
source:
|
||||
type: idf
|
||||
version: 5.5.2
|
||||
k0i05/esp_ahtxx:
|
||||
component_hash: 34ecd4cc05b54a8ee64a813f80cf2b8efea6f22ecdbf7244640fc29627416fed
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>5.3.0'
|
||||
- name: k0i05/esp_type_utils
|
||||
registry_url: https://components.espressif.com
|
||||
require: private
|
||||
version: '>=1.0.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com/
|
||||
type: service
|
||||
version: 1.2.7
|
||||
k0i05/esp_type_utils:
|
||||
component_hash: 95d8ec40268e045f7e264d8035f451e53844b4a2f6d5f112ece6645c5effd639
|
||||
dependencies:
|
||||
- name: idf
|
||||
require: private
|
||||
version: '>5.3.0'
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 1.2.7
|
||||
lvgl/lvgl:
|
||||
component_hash: 184e532558c1c45fefed631f3e235423d22582aafb4630f3e8885c35281a49ae
|
||||
dependencies: []
|
||||
source:
|
||||
registry_url: https://components.espressif.com
|
||||
type: service
|
||||
version: 9.5.0
|
||||
direct_dependencies:
|
||||
- espressif/bh1750
|
||||
- espressif/cjson
|
||||
- espressif/console_simple_init
|
||||
- espressif/esp_lvgl_port
|
||||
- espressif/mqtt
|
||||
- idf
|
||||
- k0i05/esp_ahtxx
|
||||
manifest_hash: 718977b7c70d2e199530b4f98a537ecc03c07999f59c844987823a832f51b9b0
|
||||
target: esp32c3
|
||||
version: 2.0.0
|
||||
4
main/CMakeLists.txt
Executable file
4
main/CMakeLists.txt
Executable file
@@ -0,0 +1,4 @@
|
||||
idf_component_register(SRCS "main.c" "auto_ctrl_thresholds.c" "auto_alerts.c" "status_web.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES wifi-connect mqtt_control esp_lvgl_port lvgl_st7735s_use i2c_master_messager io_device_control console_simple_init console console_user_cmds capactive_soil_moisture_sensor_V2.0 ui esp_app_format
|
||||
)
|
||||
188
main/auto_alerts.c
Normal file
188
main/auto_alerts.c
Normal file
@@ -0,0 +1,188 @@
|
||||
#include "auto_alerts.h"
|
||||
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
static const char *TAG = "auto_alerts"; // 日志标签
|
||||
|
||||
// 用于保护全局状态的自旋锁(临界区)
|
||||
static portMUX_TYPE s_alerts_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
// 用户注册的回调函数
|
||||
static auto_alert_callback_t s_callback = NULL;
|
||||
// 回调函数的用户上下文指针
|
||||
static void *s_user_ctx = NULL;
|
||||
|
||||
// 土壤湿度告警是否已激活
|
||||
static bool s_soil_alarm_active = false;
|
||||
// 光照强度告警是否已激活
|
||||
static bool s_light_alarm_active = false;
|
||||
|
||||
/**
|
||||
* @brief 发送自动告警事件
|
||||
*
|
||||
* @param metric 告警指标类型(如土壤湿度、光照强度)
|
||||
* @param state 告警状态(告警或恢复正常)
|
||||
* @param value 当前测量值
|
||||
* @param threshold 触发告警的阈值
|
||||
*/
|
||||
static void auto_alerts_emit(auto_alert_metric_t metric,
|
||||
auto_alert_state_t state,
|
||||
float value,
|
||||
float threshold)
|
||||
{
|
||||
auto_alert_event_t event = {
|
||||
.metric = metric,
|
||||
.state = state,
|
||||
.value = value,
|
||||
.threshold = threshold,
|
||||
.timestamp_ms = esp_timer_get_time() / 1000, // 转换为毫秒时间戳
|
||||
};
|
||||
|
||||
auto_alert_callback_t callback = NULL;
|
||||
void *user_ctx = NULL;
|
||||
|
||||
// 进入临界区,安全读取回调和上下文
|
||||
taskENTER_CRITICAL(&s_alerts_lock);
|
||||
callback = s_callback;
|
||||
user_ctx = s_user_ctx;
|
||||
taskEXIT_CRITICAL(&s_alerts_lock);
|
||||
|
||||
if (callback != NULL)
|
||||
{
|
||||
callback(&event, user_ctx); // 调用用户注册的回调函数
|
||||
}
|
||||
|
||||
// 打印日志信息
|
||||
ESP_LOGI(TAG,
|
||||
"alert metric=%d state=%d value=%.1f threshold=%.1f",
|
||||
(int)event.metric,
|
||||
(int)event.state,
|
||||
event.value,
|
||||
event.threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化自动告警模块
|
||||
*
|
||||
* 将所有告警状态重置为未激活。
|
||||
*/
|
||||
void auto_alerts_init(void)
|
||||
{
|
||||
taskENTER_CRITICAL(&s_alerts_lock);
|
||||
s_soil_alarm_active = false;
|
||||
s_light_alarm_active = false;
|
||||
taskEXIT_CRITICAL(&s_alerts_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 注册自动告警回调函数
|
||||
*
|
||||
* @param callback 用户定义的回调函数
|
||||
* @param user_ctx 用户上下文指针
|
||||
* @return esp_err_t 总是返回 ESP_OK
|
||||
*/
|
||||
esp_err_t auto_alerts_register_callback(auto_alert_callback_t callback, void *user_ctx)
|
||||
{
|
||||
taskENTER_CRITICAL(&s_alerts_lock);
|
||||
s_callback = callback;
|
||||
s_user_ctx = user_ctx;
|
||||
taskEXIT_CRITICAL(&s_alerts_lock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据当前传感器数据和阈值评估是否触发或解除告警
|
||||
*
|
||||
* @param soil_valid 土壤湿度数据是否有效
|
||||
* @param soil_moisture_pct 当前土壤湿度百分比
|
||||
* @param light_valid 光照数据是否有效
|
||||
* @param light_lux 当前光照强度(单位:lux)
|
||||
* @param thresholds 自动控制阈值配置结构体指针
|
||||
*/
|
||||
void auto_alerts_evaluate(bool soil_valid,
|
||||
float soil_moisture_pct,
|
||||
bool light_valid,
|
||||
float light_lux,
|
||||
const auto_ctrl_thresholds_t *thresholds)
|
||||
{
|
||||
if (thresholds == NULL)
|
||||
{
|
||||
return; // 阈值为空,直接返回
|
||||
}
|
||||
|
||||
// 处理土壤湿度告警逻辑
|
||||
if (soil_valid)
|
||||
{
|
||||
bool emit_alarm = false; // 是否需要触发告警
|
||||
bool emit_recover = false; // 是否需要恢复通知
|
||||
|
||||
taskENTER_CRITICAL(&s_alerts_lock);
|
||||
// 如果当前未告警,且土壤湿度低于启动水泵的阈值,则触发告警
|
||||
if (!s_soil_alarm_active && soil_moisture_pct < thresholds->pump_on_soil_below_pct)
|
||||
{
|
||||
s_soil_alarm_active = true;
|
||||
emit_alarm = true;
|
||||
}
|
||||
// 如果当前处于告警状态,且土壤湿度高于关闭水泵的阈值,则恢复
|
||||
else if (s_soil_alarm_active && soil_moisture_pct > thresholds->pump_off_soil_above_pct)
|
||||
{
|
||||
s_soil_alarm_active = false;
|
||||
emit_recover = true;
|
||||
}
|
||||
taskEXIT_CRITICAL(&s_alerts_lock);
|
||||
|
||||
if (emit_alarm)
|
||||
{
|
||||
auto_alerts_emit(AUTO_ALERT_METRIC_SOIL_MOISTURE,
|
||||
AUTO_ALERT_STATE_ALARM,
|
||||
soil_moisture_pct,
|
||||
thresholds->pump_on_soil_below_pct);
|
||||
}
|
||||
if (emit_recover)
|
||||
{
|
||||
auto_alerts_emit(AUTO_ALERT_METRIC_SOIL_MOISTURE,
|
||||
AUTO_ALERT_STATE_NORMAL,
|
||||
soil_moisture_pct,
|
||||
thresholds->pump_off_soil_above_pct);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理光照强度告警逻辑
|
||||
if (light_valid)
|
||||
{
|
||||
bool emit_alarm = false; // 是否需要触发告警
|
||||
bool emit_recover = false; // 是否需要恢复通知
|
||||
|
||||
taskENTER_CRITICAL(&s_alerts_lock);
|
||||
// 如果当前未告警,且光照强度低于开启补光灯的阈值,则触发告警
|
||||
if (!s_light_alarm_active && light_lux < thresholds->light_on_lux_below)
|
||||
{
|
||||
s_light_alarm_active = true;
|
||||
emit_alarm = true;
|
||||
}
|
||||
// 如果当前处于告警状态,且光照强度高于关闭补光灯的阈值,则恢复
|
||||
else if (s_light_alarm_active && light_lux > thresholds->light_off_lux_above)
|
||||
{
|
||||
s_light_alarm_active = false;
|
||||
emit_recover = true;
|
||||
}
|
||||
taskEXIT_CRITICAL(&s_alerts_lock);
|
||||
|
||||
if (emit_alarm)
|
||||
{
|
||||
auto_alerts_emit(AUTO_ALERT_METRIC_LIGHT_INTENSITY,
|
||||
AUTO_ALERT_STATE_ALARM,
|
||||
light_lux,
|
||||
thresholds->light_on_lux_below);
|
||||
}
|
||||
if (emit_recover)
|
||||
{
|
||||
auto_alerts_emit(AUTO_ALERT_METRIC_LIGHT_INTENSITY,
|
||||
AUTO_ALERT_STATE_NORMAL,
|
||||
light_lux,
|
||||
thresholds->light_off_lux_above);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
main/auto_alerts.h
Normal file
48
main/auto_alerts.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "auto_ctrl_thresholds.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
AUTO_ALERT_METRIC_SOIL_MOISTURE = 1,
|
||||
AUTO_ALERT_METRIC_LIGHT_INTENSITY = 2,
|
||||
} auto_alert_metric_t;
|
||||
|
||||
typedef enum {
|
||||
AUTO_ALERT_STATE_NORMAL = 0,
|
||||
AUTO_ALERT_STATE_ALARM = 1,
|
||||
} auto_alert_state_t;
|
||||
|
||||
typedef struct {
|
||||
auto_alert_metric_t metric;
|
||||
auto_alert_state_t state;
|
||||
float value;
|
||||
float threshold;
|
||||
int64_t timestamp_ms;
|
||||
} auto_alert_event_t;
|
||||
|
||||
typedef void (*auto_alert_callback_t)(const auto_alert_event_t *event, void *user_ctx);
|
||||
|
||||
// Reset internal state at boot.
|
||||
void auto_alerts_init(void);
|
||||
|
||||
// Register callback sink (e.g. MQTT publisher). Passing NULL clears callback.
|
||||
esp_err_t auto_alerts_register_callback(auto_alert_callback_t callback, void *user_ctx);
|
||||
|
||||
// Evaluate current sensor values and emit edge-triggered alert events.
|
||||
void auto_alerts_evaluate(bool soil_valid,
|
||||
float soil_moisture_pct,
|
||||
bool light_valid,
|
||||
float light_lux,
|
||||
const auto_ctrl_thresholds_t *thresholds);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
146
main/auto_ctrl_thresholds.c
Normal file
146
main/auto_ctrl_thresholds.c
Normal file
@@ -0,0 +1,146 @@
|
||||
#include "auto_ctrl_thresholds.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_check.h"
|
||||
|
||||
// 默认土壤湿度低于此百分比时启动水泵(单位:%)
|
||||
#define DEFAULT_PUMP_ON_SOIL_BELOW_PCT 35.0f
|
||||
// 默认土壤湿度高于此百分比时关闭水泵(单位:%)
|
||||
#define DEFAULT_PUMP_OFF_SOIL_ABOVE_PCT 45.0f
|
||||
// 默认光照强度低于此值时开启补光灯(单位:lux)
|
||||
#define DEFAULT_LIGHT_ON_LUX_BELOW 200.0f
|
||||
// 默认光照强度高于此值时关闭补光灯(单位:lux)
|
||||
#define DEFAULT_LIGHT_OFF_LUX_ABOVE 350.0f
|
||||
|
||||
// 用于保护阈值数据的自旋锁(临界区)
|
||||
static portMUX_TYPE s_thresholds_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
// 全局阈值配置结构体,初始化为默认值
|
||||
static auto_ctrl_thresholds_t s_thresholds = {
|
||||
.pump_on_soil_below_pct = DEFAULT_PUMP_ON_SOIL_BELOW_PCT,
|
||||
.pump_off_soil_above_pct = DEFAULT_PUMP_OFF_SOIL_ABOVE_PCT,
|
||||
.light_on_lux_below = DEFAULT_LIGHT_ON_LUX_BELOW,
|
||||
.light_off_lux_above = DEFAULT_LIGHT_OFF_LUX_ABOVE,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 验证自动控制阈值配置的有效性
|
||||
*
|
||||
* 检查指针非空、数值范围合法、启停阈值满足 on < off 等条件。
|
||||
*
|
||||
* @param cfg 待验证的阈值配置指针
|
||||
* @return esp_err_t 验证结果,ESP_OK 表示有效
|
||||
*/
|
||||
static esp_err_t auto_ctrl_thresholds_validate(const auto_ctrl_thresholds_t *cfg)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(cfg != NULL, ESP_ERR_INVALID_ARG, "auto_ctrl_thresholds", "cfg is null");
|
||||
|
||||
ESP_RETURN_ON_FALSE(cfg->pump_on_soil_below_pct >= 0.0f && cfg->pump_on_soil_below_pct <= 100.0f,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
"auto_ctrl_thresholds",
|
||||
"pump_on_soil_below_pct out of range");
|
||||
ESP_RETURN_ON_FALSE(cfg->pump_off_soil_above_pct >= 0.0f && cfg->pump_off_soil_above_pct <= 100.0f,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
"auto_ctrl_thresholds",
|
||||
"pump_off_soil_above_pct out of range");
|
||||
ESP_RETURN_ON_FALSE(cfg->pump_on_soil_below_pct < cfg->pump_off_soil_above_pct,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
"auto_ctrl_thresholds",
|
||||
"pump thresholds must satisfy on < off");
|
||||
|
||||
ESP_RETURN_ON_FALSE(cfg->light_on_lux_below >= 0.0f,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
"auto_ctrl_thresholds",
|
||||
"light_on_lux_below out of range");
|
||||
ESP_RETURN_ON_FALSE(cfg->light_off_lux_above >= 0.0f,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
"auto_ctrl_thresholds",
|
||||
"light_off_lux_above out of range");
|
||||
ESP_RETURN_ON_FALSE(cfg->light_on_lux_below < cfg->light_off_lux_above,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
"auto_ctrl_thresholds",
|
||||
"light thresholds must satisfy on < off");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化阈值为默认值
|
||||
*
|
||||
* 将全局阈值结构体重置为预设的默认配置。
|
||||
*/
|
||||
void auto_ctrl_thresholds_init_defaults(void)
|
||||
{
|
||||
const auto_ctrl_thresholds_t defaults = {
|
||||
.pump_on_soil_below_pct = DEFAULT_PUMP_ON_SOIL_BELOW_PCT,
|
||||
.pump_off_soil_above_pct = DEFAULT_PUMP_OFF_SOIL_ABOVE_PCT,
|
||||
.light_on_lux_below = DEFAULT_LIGHT_ON_LUX_BELOW,
|
||||
.light_off_lux_above = DEFAULT_LIGHT_OFF_LUX_ABOVE,
|
||||
};
|
||||
|
||||
taskENTER_CRITICAL(&s_thresholds_lock);
|
||||
s_thresholds = defaults;
|
||||
taskEXIT_CRITICAL(&s_thresholds_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取当前阈值配置
|
||||
*
|
||||
* 安全地复制当前阈值到输出参数中。
|
||||
*
|
||||
* @param out 输出参数,指向接收阈值的结构体
|
||||
*/
|
||||
void auto_ctrl_thresholds_get(auto_ctrl_thresholds_t *out)
|
||||
{
|
||||
if (out == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
taskENTER_CRITICAL(&s_thresholds_lock);
|
||||
*out = s_thresholds;
|
||||
taskEXIT_CRITICAL(&s_thresholds_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置新的阈值配置
|
||||
*
|
||||
* 验证输入配置有效性后,安全更新全局阈值。
|
||||
*
|
||||
* @param cfg 新的阈值配置指针
|
||||
* @return esp_err_t 设置结果,ESP_OK 表示成功
|
||||
*/
|
||||
esp_err_t auto_ctrl_thresholds_set(const auto_ctrl_thresholds_t *cfg)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(auto_ctrl_thresholds_validate(cfg), "auto_ctrl_thresholds", "invalid thresholds");
|
||||
|
||||
taskENTER_CRITICAL(&s_thresholds_lock);
|
||||
s_thresholds = *cfg;
|
||||
taskEXIT_CRITICAL(&s_thresholds_lock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 通过独立参数设置阈值
|
||||
*
|
||||
* 提供一种更便捷的阈值设置方式,内部封装为结构体后调用 set 接口。
|
||||
*
|
||||
* @param pump_on_soil_below_pct 水泵启动土壤湿度阈值(%)
|
||||
* @param pump_off_soil_above_pct 水泵关闭土壤湿度阈值(%)
|
||||
* @param light_on_lux_below 补光灯开启光照阈值(lux)
|
||||
* @param light_off_lux_above 补光灯关闭光照阈值(lux)
|
||||
* @return esp_err_t 设置结果
|
||||
*/
|
||||
esp_err_t auto_ctrl_thresholds_set_values(float pump_on_soil_below_pct,
|
||||
float pump_off_soil_above_pct,
|
||||
float light_on_lux_below,
|
||||
float light_off_lux_above)
|
||||
{
|
||||
const auto_ctrl_thresholds_t cfg = {
|
||||
.pump_on_soil_below_pct = pump_on_soil_below_pct,
|
||||
.pump_off_soil_above_pct = pump_off_soil_above_pct,
|
||||
.light_on_lux_below = light_on_lux_below,
|
||||
.light_off_lux_above = light_off_lux_above,
|
||||
};
|
||||
|
||||
return auto_ctrl_thresholds_set(&cfg);
|
||||
}
|
||||
33
main/auto_ctrl_thresholds.h
Normal file
33
main/auto_ctrl_thresholds.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
float pump_on_soil_below_pct;
|
||||
float pump_off_soil_above_pct;
|
||||
float light_on_lux_below;
|
||||
float light_off_lux_above;
|
||||
} auto_ctrl_thresholds_t;
|
||||
|
||||
// Initializes default thresholds once at boot.
|
||||
void auto_ctrl_thresholds_init_defaults(void);
|
||||
|
||||
// Thread-safe snapshot read, intended for control loop usage.
|
||||
void auto_ctrl_thresholds_get(auto_ctrl_thresholds_t *out);
|
||||
|
||||
// Thread-safe full update with range/order validation.
|
||||
esp_err_t auto_ctrl_thresholds_set(const auto_ctrl_thresholds_t *cfg);
|
||||
|
||||
// Convenience API for MQTT callback usage.
|
||||
esp_err_t auto_ctrl_thresholds_set_values(float pump_on_soil_below_pct,
|
||||
float pump_off_soil_above_pct,
|
||||
float light_on_lux_below,
|
||||
float light_off_lux_above);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
23
main/idf_component.yml
Normal file
23
main/idf_component.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: '>=4.1.0'
|
||||
# # Put list of dependencies here
|
||||
# # For components maintained by Espressif:
|
||||
# component: "~1.0.0"
|
||||
# # For 3rd party components:
|
||||
# username/component: ">=1.0.0,<2.0.0"
|
||||
# username2/component2:
|
||||
# version: "~1.0.0"
|
||||
# # For transient dependencies `public` flag can be set.
|
||||
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||
# # All dependencies of `main` are public by default.
|
||||
# public: true
|
||||
espressif/esp_lvgl_port: ^2.7.2
|
||||
espressif/bh1750: ^2.0.0
|
||||
k0i05/esp_ahtxx: ^1.2.7
|
||||
espressif/console_simple_init: ^1.1.0
|
||||
|
||||
espressif/mqtt: ^1.0.0
|
||||
espressif/cjson: ^1.7.19
|
||||
670
main/main.c
Executable file
670
main/main.c
Executable file
@@ -0,0 +1,670 @@
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "wifi-connect.h"
|
||||
#include "lvgl_st7735s_use.h"
|
||||
#include "i2c_master_messager.h"
|
||||
#include "io_device_control.h"
|
||||
#include "console_simple_init.h" // 提供 console_cmd_user_register 和 console_cmd_all_register
|
||||
#include "console_user_cmds.h"
|
||||
#include "capactive_soil_moisture_sensor_V2.0.h"
|
||||
#include "ui.h" // 使用EEZStudio提供的ui组件,便于后续扩展
|
||||
#include "esp_lvgl_port.h"
|
||||
#include "vars.h" // 定义全局变量接口
|
||||
#include "auto_ctrl_thresholds.h"
|
||||
#include "auto_alerts.h"
|
||||
#include "mqtt_control.h" // MQTT 控制接口
|
||||
#include "status_web.h"
|
||||
|
||||
// 配置宏定义:BH1750 光照传感器是否启用(默认禁用)
|
||||
#ifndef CONFIG_I2C_MASTER_MESSAGER_BH1750_ENABLE
|
||||
#define CONFIG_I2C_MASTER_MESSAGER_BH1750_ENABLE 0
|
||||
#endif
|
||||
|
||||
// 配置宏定义:AHT30 温湿度传感器是否启用(默认禁用)
|
||||
#ifndef CONFIG_I2C_MASTER_MESSAGER_AHT30_ENABLE
|
||||
#define CONFIG_I2C_MASTER_MESSAGER_AHT30_ENABLE 0
|
||||
#endif
|
||||
|
||||
// 配置宏定义:BH1750 读取周期(毫秒,默认500ms)
|
||||
#ifndef CONFIG_I2C_MASTER_MESSAGER_BH1750_READ_PERIOD_MS
|
||||
#define CONFIG_I2C_MASTER_MESSAGER_BH1750_READ_PERIOD_MS 500
|
||||
#endif
|
||||
|
||||
// 配置宏定义:AHT30 读取周期(毫秒,默认2000ms)
|
||||
#ifndef CONFIG_I2C_MASTER_MESSAGER_AHT30_READ_PERIOD_MS
|
||||
#define CONFIG_I2C_MASTER_MESSAGER_AHT30_READ_PERIOD_MS 2000
|
||||
#endif
|
||||
|
||||
// 配置宏定义:I2C 是否启用内部上拉电阻(默认启用)
|
||||
#ifndef CONFIG_I2C_MASTER_MESSAGER_ENABLE_INTERNAL_PULLUP
|
||||
#define CONFIG_I2C_MASTER_MESSAGER_ENABLE_INTERNAL_PULLUP 1
|
||||
#endif
|
||||
|
||||
// I2C 端口配置
|
||||
#define BOTANY_I2C_PORT I2C_NUM_0
|
||||
// I2C SCL 引脚
|
||||
#define BOTANY_I2C_SCL_GPIO GPIO_NUM_5
|
||||
// I2C SDA 引脚
|
||||
#define BOTANY_I2C_SDA_GPIO GPIO_NUM_4
|
||||
// BH1750 使能标志
|
||||
#define BOTANY_BH1750_ENABLE CONFIG_I2C_MASTER_MESSAGER_BH1750_ENABLE
|
||||
// AHT30 使能标志
|
||||
#define BOTANY_AHT30_ENABLE CONFIG_I2C_MASTER_MESSAGER_AHT30_ENABLE
|
||||
// BH1750 读取周期
|
||||
#define BOTANY_BH1750_PERIOD_MS CONFIG_I2C_MASTER_MESSAGER_BH1750_READ_PERIOD_MS
|
||||
// AHT30 读取周期
|
||||
#define BOTANY_AHT30_PERIOD_MS CONFIG_I2C_MASTER_MESSAGER_AHT30_READ_PERIOD_MS
|
||||
// I2C 内部上拉使能
|
||||
#define BOTANY_I2C_INTERNAL_PULLUP CONFIG_I2C_MASTER_MESSAGER_ENABLE_INTERNAL_PULLUP
|
||||
// MQTT 告警主题
|
||||
#define BOTANY_MQTT_ALERT_TOPIC "topic/alert/esp32_iothome_001"
|
||||
// MQTT 遥测数据上报周期(毫秒)
|
||||
#define BOTANY_MQTT_TELEMETRY_PERIOD_MS 5000
|
||||
#define BOTANY_STATUS_WEB_PORT 8080
|
||||
|
||||
// 日志标签
|
||||
static const char *TAG = "main";
|
||||
|
||||
// 全局变量:存储空气温度字符串
|
||||
static char s_air_temp[16];
|
||||
// 全局变量:存储空气湿度字符串
|
||||
static char s_air_hum[16];
|
||||
// 全局变量:存储土壤湿度字符串
|
||||
static char s_soil[16];
|
||||
// 全局变量:存储光照强度字符串
|
||||
static char s_lux[16];
|
||||
// 全局变量:水泵状态(true=开启,false=关闭)
|
||||
static bool s_pump_on = false;
|
||||
// 全局变量:补光灯状态(true=开启,false=关闭)
|
||||
static bool s_light_on = false;
|
||||
// 全局变量:自动控制模式使能(true=自动,false=手动)
|
||||
static bool s_auto_control_enabled = true;
|
||||
static bool s_i2c_ready = false;
|
||||
static bool s_soil_sensor_ready = false;
|
||||
static uint32_t s_main_loop_counter = 0;
|
||||
|
||||
/**
|
||||
* @brief 发布当前完整状态快照(含阈值)到传感器主题
|
||||
*/
|
||||
static esp_err_t publish_telemetry_snapshot(void)
|
||||
{
|
||||
if (!mqtt_control_is_connected())
|
||||
{
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
auto_ctrl_thresholds_t thresholds = {0};
|
||||
auto_ctrl_thresholds_get(&thresholds);
|
||||
|
||||
char telemetry_payload[256] = {0};
|
||||
int len = snprintf(telemetry_payload,
|
||||
sizeof(telemetry_payload),
|
||||
"{\"temp\":\"%s\",\"hum\":\"%s\",\"soil\":\"%s\",\"lux\":\"%s\",\"pump\":\"%s\",\"light\":\"%s\",\"mode\":\"%s\",\"soil_on\":%.1f,\"soil_off\":%.1f,\"light_on\":%.1f,\"light_off\":%.1f}",
|
||||
s_air_temp,
|
||||
s_air_hum,
|
||||
s_soil,
|
||||
s_lux,
|
||||
s_pump_on ? "on" : "off",
|
||||
s_light_on ? "on" : "off",
|
||||
s_auto_control_enabled ? "auto" : "manual",
|
||||
thresholds.pump_on_soil_below_pct,
|
||||
thresholds.pump_off_soil_above_pct,
|
||||
thresholds.light_on_lux_below,
|
||||
thresholds.light_off_lux_above);
|
||||
if (len <= 0 || len >= (int)sizeof(telemetry_payload))
|
||||
{
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
return mqtt_control_publish_sensor(telemetry_payload, 0, 0);
|
||||
}
|
||||
|
||||
static void update_status_web_snapshot(void)
|
||||
{
|
||||
status_web_snapshot_t snap = {0};
|
||||
snprintf(snap.temp, sizeof(snap.temp), "%s", s_air_temp[0] ? s_air_temp : "--");
|
||||
snprintf(snap.hum, sizeof(snap.hum), "%s", s_air_hum[0] ? s_air_hum : "--");
|
||||
snprintf(snap.soil, sizeof(snap.soil), "%s", s_soil[0] ? s_soil : "--");
|
||||
snprintf(snap.lux, sizeof(snap.lux), "%s", s_lux[0] ? s_lux : "--");
|
||||
snap.pump_on = s_pump_on;
|
||||
snap.light_on = s_light_on;
|
||||
snap.auto_mode = s_auto_control_enabled;
|
||||
|
||||
auto_ctrl_thresholds_t thresholds = {0};
|
||||
auto_ctrl_thresholds_get(&thresholds);
|
||||
snap.soil_on_threshold = thresholds.pump_on_soil_below_pct;
|
||||
snap.soil_off_threshold = thresholds.pump_off_soil_above_pct;
|
||||
snap.light_on_threshold = thresholds.light_on_lux_below;
|
||||
snap.light_off_threshold = thresholds.light_off_lux_above;
|
||||
snap.i2c_ready = s_i2c_ready;
|
||||
snap.soil_sensor_ready = s_soil_sensor_ready;
|
||||
snap.loop_counter = s_main_loop_counter;
|
||||
|
||||
esp_err_t ret = status_web_update(&snap);
|
||||
if (ret != ESP_OK && ret != ESP_ERR_INVALID_STATE)
|
||||
{
|
||||
ESP_LOGW(TAG, "status web update failed: %s", esp_err_to_name(ret));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MQTT 控制命令处理函数
|
||||
*
|
||||
* 处理来自 MQTT 的控制命令,包括模式切换、阈值更新、水泵和补光灯控制。
|
||||
*
|
||||
* @param cmd 指向 MQTT 控制命令结构体的指针
|
||||
* @param user_ctx 用户上下文(未使用)
|
||||
* @return esp_err_t 处理结果
|
||||
*/
|
||||
static esp_err_t mqtt_control_command_handler(const mqtt_control_command_t *cmd, void *user_ctx)
|
||||
{
|
||||
(void)user_ctx;
|
||||
ESP_RETURN_ON_FALSE(cmd != NULL, ESP_ERR_INVALID_ARG, TAG, "cmd is null");
|
||||
esp_err_t final_ret = ESP_OK;
|
||||
bool has_any_control = cmd->has_mode || cmd->has_thresholds || cmd->has_pump || cmd->has_light;
|
||||
|
||||
// 处理模式切换命令
|
||||
if (cmd->has_mode)
|
||||
{
|
||||
s_auto_control_enabled = cmd->auto_mode;
|
||||
ESP_LOGI(TAG, "MQTT 控制模式切换: %s", s_auto_control_enabled ? "auto" : "manual");
|
||||
}
|
||||
|
||||
// 处理阈值更新命令
|
||||
if (cmd->has_thresholds)
|
||||
{
|
||||
esp_err_t ret = auto_ctrl_thresholds_set_values(cmd->soil_on_pct,
|
||||
cmd->soil_off_pct,
|
||||
cmd->light_on_lux,
|
||||
cmd->light_off_lux);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
ESP_LOGI(TAG,
|
||||
"MQTT 更新阈值: soil_on=%.1f soil_off=%.1f light_on=%.1f light_off=%.1f",
|
||||
cmd->soil_on_pct,
|
||||
cmd->soil_off_pct,
|
||||
cmd->light_on_lux,
|
||||
cmd->light_off_lux);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "设置阈值失败: %s", esp_err_to_name(ret));
|
||||
final_ret = ret;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理水泵控制命令
|
||||
if (cmd->has_pump)
|
||||
{
|
||||
esp_err_t ret = io_device_control_set_pump(cmd->pump_on);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
s_pump_on = cmd->pump_on;
|
||||
ESP_LOGI(TAG, "MQTT 控制水泵: %s", cmd->pump_on ? "on" : "off");
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "MQTT 控制水泵失败: %s", esp_err_to_name(ret));
|
||||
final_ret = ret;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理补光灯控制命令
|
||||
if (cmd->has_light)
|
||||
{
|
||||
esp_err_t ret = io_device_control_set_light(cmd->light_on);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
s_light_on = cmd->light_on;
|
||||
ESP_LOGI(TAG, "MQTT 控制补光灯: %s", cmd->light_on ? "on" : "off");
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "MQTT 控制补光灯失败: %s", esp_err_to_name(ret));
|
||||
final_ret = ret;
|
||||
}
|
||||
}
|
||||
|
||||
// 任何控制指令处理后都立即上报最新状态(含阈值)作为回复。
|
||||
if (has_any_control)
|
||||
{
|
||||
esp_err_t pub_ret = publish_telemetry_snapshot();
|
||||
if (pub_ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGW(TAG, "控制后立即上报失败: %s", esp_err_to_name(pub_ret));
|
||||
if (final_ret == ESP_OK)
|
||||
{
|
||||
final_ret = pub_ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return final_ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将告警指标类型转换为字符串
|
||||
*
|
||||
* @param metric 告警指标类型
|
||||
* @return const char* 对应的字符串表示
|
||||
*/
|
||||
static const char *alert_metric_text(auto_alert_metric_t metric)
|
||||
{
|
||||
switch (metric)
|
||||
{
|
||||
case AUTO_ALERT_METRIC_SOIL_MOISTURE:
|
||||
return "soil";
|
||||
case AUTO_ALERT_METRIC_LIGHT_INTENSITY:
|
||||
return "light";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将告警状态转换为字符串
|
||||
*
|
||||
* @param state 告警状态
|
||||
* @return const char* 对应的字符串表示
|
||||
*/
|
||||
static const char *alert_state_text(auto_alert_state_t state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case AUTO_ALERT_STATE_NORMAL:
|
||||
return "normal";
|
||||
case AUTO_ALERT_STATE_ALARM:
|
||||
return "alarm";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 自动告警 MQTT 回调函数
|
||||
*
|
||||
* 当自动告警模块触发事件时,通过此函数将告警信息以 JSON 格式发布到 MQTT。
|
||||
*
|
||||
* @param event 指向告警事件结构体的指针
|
||||
* @param user_ctx 用户上下文(未使用)
|
||||
*/
|
||||
static void auto_alert_mqtt_callback(const auto_alert_event_t *event, void *user_ctx)
|
||||
{
|
||||
(void)user_ctx;
|
||||
if (event == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用明文发送报警简单的 JSON 字符串,格式示例:{"metric":"soil","state":"alarm"}
|
||||
char payload[64] = {0};
|
||||
int len = snprintf(payload,
|
||||
sizeof(payload),
|
||||
"{\"metric\":\"%s\",\"state\":\"%s\"}",
|
||||
alert_metric_text(event->metric),
|
||||
alert_state_text(event->state));
|
||||
if (len <= 0 || len >= (int)sizeof(payload))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mqtt_control_is_connected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
esp_err_t ret = mqtt_control_publish(BOTANY_MQTT_ALERT_TOPIC, payload, 1, 0);
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "告警 MQTT 发布失败: %s", esp_err_to_name(ret));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 自动控制逻辑更新函数
|
||||
*
|
||||
* 根据当前传感器数据和阈值,决定是否需要开启或关闭水泵和补光灯。
|
||||
*
|
||||
* @param soil_valid 土壤湿度数据是否有效
|
||||
* @param soil_moisture_pct 当前土壤湿度百分比
|
||||
* @param light_valid 光照数据是否有效
|
||||
* @param light_lux 当前光照强度(lux)
|
||||
* @param thresholds 指向阈值配置结构体的指针
|
||||
* @param pump_on 指向当前水泵状态的指针(输入/输出)
|
||||
* @param light_on 指向当前补光灯状态的指针(输入/输出)
|
||||
*/
|
||||
static void auto_control_update(bool soil_valid,
|
||||
float soil_moisture_pct,
|
||||
bool light_valid,
|
||||
float light_lux,
|
||||
const auto_ctrl_thresholds_t *thresholds,
|
||||
bool *pump_on,
|
||||
bool *light_on)
|
||||
{
|
||||
bool desired_pump = *pump_on;
|
||||
bool desired_light = *light_on;
|
||||
|
||||
// 根据土壤湿度决定水泵状态
|
||||
if (soil_valid)
|
||||
{
|
||||
if (!desired_pump && soil_moisture_pct < thresholds->pump_on_soil_below_pct)
|
||||
{
|
||||
desired_pump = true;
|
||||
}
|
||||
else if (desired_pump && soil_moisture_pct > thresholds->pump_off_soil_above_pct)
|
||||
{
|
||||
desired_pump = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据光照强度决定补光灯状态
|
||||
if (light_valid)
|
||||
{
|
||||
if (!desired_light && light_lux < thresholds->light_on_lux_below)
|
||||
{
|
||||
desired_light = true;
|
||||
}
|
||||
else if (desired_light && light_lux > thresholds->light_off_lux_above)
|
||||
{
|
||||
desired_light = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果水泵状态需要改变,则执行控制
|
||||
if (desired_pump != *pump_on)
|
||||
{
|
||||
esp_err_t ret = io_device_control_set_pump(desired_pump);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
*pump_on = desired_pump;
|
||||
ESP_LOGI(TAG,
|
||||
"自动控制: 水泵%s (土壤湿度=%.1f%%)",
|
||||
desired_pump ? "开启" : "关闭",
|
||||
soil_moisture_pct);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "自动控制: 水泵控制失败: %s", esp_err_to_name(ret));
|
||||
}
|
||||
}
|
||||
|
||||
// 如果补光灯状态需要改变,则执行控制
|
||||
if (desired_light != *light_on)
|
||||
{
|
||||
esp_err_t ret = io_device_control_set_light(desired_light);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
*light_on = desired_light;
|
||||
ESP_LOGI(TAG,
|
||||
"自动控制: 补光灯%s (光照=%.1f lux)",
|
||||
desired_light ? "开启" : "关闭",
|
||||
light_lux);
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOGE(TAG, "自动控制: 补光灯控制失败: %s", esp_err_to_name(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UI 任务函数
|
||||
*
|
||||
* 负责定期切换显示页面(每3秒切换一次)。
|
||||
*
|
||||
* @param arg 任务参数(未使用)
|
||||
*/
|
||||
static void ui_task(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
uint32_t elapsed_ms = 0;
|
||||
enum ScreensEnum current = SCREEN_ID_TEMPERATURE;
|
||||
const uint32_t switch_period_ms = 3000; // 每3秒切一次
|
||||
|
||||
for (;;)
|
||||
{
|
||||
lvgl_port_lock(0);
|
||||
ui_tick();
|
||||
|
||||
elapsed_ms += 20;
|
||||
if (elapsed_ms >= switch_period_ms) {
|
||||
elapsed_ms = 0;
|
||||
|
||||
// 下一个页面:1->2->3->4->1
|
||||
if (current >= _SCREEN_ID_LAST) {
|
||||
current = _SCREEN_ID_FIRST;
|
||||
} else {
|
||||
current = (enum ScreensEnum)(current + 1);
|
||||
}
|
||||
|
||||
loadScreen(current);
|
||||
}
|
||||
|
||||
lvgl_port_unlock();
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 等待 Wi-Fi 连接成功
|
||||
*
|
||||
* 在初始化 console 之前,确保 Wi-Fi 已连接成功,最多等待120秒。
|
||||
*/
|
||||
static void wait_for_wifi_connected(void)
|
||||
{
|
||||
const uint32_t timeout_s = 120;
|
||||
uint32_t elapsed_half_s = 0;
|
||||
|
||||
ESP_LOGI(TAG, "等待 Wi-Fi 连接成功后再初始化 console...");
|
||||
while (wifi_connect_get_status() != WIFI_CONNECT_STATUS_CONNECTED)
|
||||
{
|
||||
if (elapsed_half_s >= (timeout_s * 2))
|
||||
{
|
||||
ESP_LOGW(TAG, "等待 Wi-Fi 超时(%" PRIu32 "s),继续初始化 console", timeout_s);
|
||||
return;
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
elapsed_half_s++;
|
||||
|
||||
// 每 5 秒打印一次等待状态,避免日志刷屏。
|
||||
if ((elapsed_half_s % 10) == 0)
|
||||
{
|
||||
ESP_LOGI(TAG, "仍在等待 Wi-Fi 连接(%" PRIu32 "s)", elapsed_half_s / 2);
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Wi-Fi 已连接,开始初始化 console");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 主函数
|
||||
*
|
||||
* 系统启动入口,初始化所有组件并进入主循环。
|
||||
*/
|
||||
void app_main(void)
|
||||
{
|
||||
// 初始化 Wi-Fi 配网组件,支持长按按键进入配网
|
||||
ESP_ERROR_CHECK(wifi_connect_init());
|
||||
printf("设备启动完成:长按按键进入配网模式,手机连接 ESP32-* 后访问 http://192.168.4.1\n");
|
||||
|
||||
// 启动 LVGL 演示程序,显示简单的界面
|
||||
ESP_ERROR_CHECK(start_lvgl_demo());
|
||||
|
||||
// 初始化 UI 组件(需在 LVGL 锁内进行对象创建)
|
||||
lvgl_port_lock(0);
|
||||
ui_init();
|
||||
lvgl_port_unlock();
|
||||
|
||||
BaseType_t ui_task_ok = xTaskCreate(ui_task, "ui_task", 4096, NULL, 5, NULL);
|
||||
ESP_ERROR_CHECK(ui_task_ok == pdPASS ? ESP_OK : ESP_FAIL);
|
||||
|
||||
// 初始化 IO 设备控制组件(GPIO1 水泵,GPIO10 光照,高电平有效)
|
||||
ESP_ERROR_CHECK(io_device_control_init());
|
||||
|
||||
i2c_master_messager_config_t i2c_cfg = {
|
||||
.i2c_port = BOTANY_I2C_PORT,
|
||||
.scl_io_num = BOTANY_I2C_SCL_GPIO,
|
||||
.sda_io_num = BOTANY_I2C_SDA_GPIO,
|
||||
.i2c_enable_internal_pullup = BOTANY_I2C_INTERNAL_PULLUP,
|
||||
.bh1750_enable = BOTANY_BH1750_ENABLE,
|
||||
.aht30_enable = BOTANY_AHT30_ENABLE,
|
||||
.bh1750_read_period_ms = BOTANY_BH1750_PERIOD_MS,
|
||||
.aht30_read_period_ms = BOTANY_AHT30_PERIOD_MS,
|
||||
.bh1750_mode = BH1750_CONTINUE_1LX_RES,
|
||||
|
||||
};
|
||||
|
||||
bool i2c_ready = false;
|
||||
esp_err_t ret = i2c_master_messager_init(&i2c_cfg);
|
||||
if (ret == ESP_OK)
|
||||
{
|
||||
ret = i2c_master_messager_start();
|
||||
}
|
||||
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "I2C 传感器管理启动失败: %s", esp_err_to_name(ret));
|
||||
ESP_LOGW(TAG, "请检查 I2C 引脚/上拉电阻/端口占用情况,系统将继续运行但不采集传感器");
|
||||
ESP_ERROR_CHECK(lvgl_st7735s_set_center_text("I2C init failed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_ready = true;
|
||||
s_i2c_ready = true;
|
||||
}
|
||||
|
||||
// 初始化电容式土壤湿度传感器(GPIO0 / ADC1_CH0)。
|
||||
bool soil_ready = false;
|
||||
cap_soil_sensor_config_t soil_cfg = {
|
||||
.unit = CAP_SOIL_SENSOR_DEFAULT_UNIT,
|
||||
.channel = CAP_SOIL_SENSOR_DEFAULT_CHANNEL,
|
||||
.atten = ADC_ATTEN_DB_12,
|
||||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||
// 标定值来自当前实测:空气中约 3824,水中约 1463。
|
||||
.air_raw = 3824,
|
||||
.water_raw = 1463,
|
||||
};
|
||||
ret = cap_soil_sensor_init(&soil_cfg);
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "土壤湿度传感器初始化失败: %s", esp_err_to_name(ret));
|
||||
}
|
||||
else
|
||||
{
|
||||
soil_ready = true;
|
||||
s_soil_sensor_ready = true;
|
||||
}
|
||||
|
||||
// 按需求:仅在 Wi-Fi 确认连通后再初始化 MQTT和console。
|
||||
wait_for_wifi_connected();
|
||||
|
||||
// 独立状态网页(端口 8080),与配网页面(端口 80)互不干扰。
|
||||
ESP_ERROR_CHECK(status_web_start(BOTANY_STATUS_WEB_PORT));
|
||||
|
||||
ESP_ERROR_CHECK(mqtt_control_register_command_handler(mqtt_control_command_handler, NULL));
|
||||
ESP_ERROR_CHECK(mqtt_control_start()); // 启动 MQTT 客户端
|
||||
|
||||
ESP_ERROR_CHECK(console_cmd_init());
|
||||
ESP_ERROR_CHECK(console_user_cmds_register());
|
||||
ESP_ERROR_CHECK(console_cmd_all_register()); // 可选:自动注册插件命令
|
||||
ESP_ERROR_CHECK(console_cmd_start());
|
||||
|
||||
auto_ctrl_thresholds_init_defaults();
|
||||
auto_alerts_init();
|
||||
ESP_ERROR_CHECK(auto_alerts_register_callback(auto_alert_mqtt_callback, NULL));
|
||||
auto_ctrl_thresholds_t thresholds = {0};
|
||||
auto_ctrl_thresholds_get(&thresholds);
|
||||
|
||||
uint32_t telemetry_elapsed_ms = 0;
|
||||
ESP_LOGI(TAG,
|
||||
"自动控制阈值: pump_on<%.1f%%, pump_off>%.1f%%, light_on<%.1flux, light_off>%.1flux",
|
||||
thresholds.pump_on_soil_below_pct,
|
||||
thresholds.pump_off_soil_above_pct,
|
||||
thresholds.light_on_lux_below,
|
||||
thresholds.light_off_lux_above);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
s_main_loop_counter++;
|
||||
|
||||
// 预留给 MQTT 回调动态更新阈值:每个周期读取最新配置。
|
||||
auto_ctrl_thresholds_get(&thresholds);
|
||||
|
||||
bool soil_valid = false;
|
||||
float soil_moisture_pct = 0.0f;
|
||||
|
||||
cap_soil_sensor_data_t soil_data = {0};
|
||||
if (soil_ready && cap_soil_sensor_read(&soil_data) == ESP_OK)
|
||||
{
|
||||
// 读取成功
|
||||
soil_valid = true;
|
||||
soil_moisture_pct = soil_data.moisture_percent;
|
||||
snprintf(s_soil, sizeof(s_soil), "%.0f", soil_data.moisture_percent);
|
||||
set_var_soil_moisture(s_soil);
|
||||
}
|
||||
|
||||
bool light_valid = false;
|
||||
float light_lux = 0.0f;
|
||||
|
||||
i2c_master_messager_data_t sensor_data = {0};
|
||||
if (i2c_ready && i2c_master_messager_get_data(&sensor_data) == ESP_OK)
|
||||
{
|
||||
// 读取成功
|
||||
if (sensor_data.aht30.valid)
|
||||
{
|
||||
snprintf(s_air_temp, sizeof(s_air_temp), "%.1f", sensor_data.aht30.temperature_c);
|
||||
set_var_air_temperature(s_air_temp);
|
||||
|
||||
snprintf(s_air_hum, sizeof(s_air_hum), "%.1f", sensor_data.aht30.humidity_rh);
|
||||
set_var_air_humidity(s_air_hum);
|
||||
}
|
||||
if (sensor_data.bh1750.valid)
|
||||
{
|
||||
light_valid = true;
|
||||
light_lux = sensor_data.bh1750.lux;
|
||||
snprintf(s_lux, sizeof(s_lux), "%.0f", sensor_data.bh1750.lux);
|
||||
set_var_light_intensity(s_lux);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_auto_control_enabled)
|
||||
{
|
||||
auto_control_update(soil_valid,
|
||||
soil_moisture_pct,
|
||||
light_valid,
|
||||
light_lux,
|
||||
&thresholds,
|
||||
&s_pump_on,
|
||||
&s_light_on);
|
||||
}
|
||||
|
||||
// 预留给 MQTT:回调注册后可在此处收到边沿告警事件并发布。
|
||||
auto_alerts_evaluate(soil_valid,
|
||||
soil_moisture_pct,
|
||||
light_valid,
|
||||
light_lux,
|
||||
&thresholds);
|
||||
|
||||
update_status_web_snapshot();
|
||||
|
||||
telemetry_elapsed_ms += 1000;
|
||||
if (telemetry_elapsed_ms >= BOTANY_MQTT_TELEMETRY_PERIOD_MS)
|
||||
{
|
||||
telemetry_elapsed_ms = 0;
|
||||
esp_err_t pub_ret = publish_telemetry_snapshot();
|
||||
if (pub_ret != ESP_OK && pub_ret != ESP_ERR_INVALID_STATE)
|
||||
{
|
||||
ESP_LOGW(TAG, "周期状态上报失败: %s", esp_err_to_name(pub_ret));
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
256
main/status_web.c
Normal file
256
main/status_web.c
Normal file
@@ -0,0 +1,256 @@
|
||||
#include "status_web.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_app_desc.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_http_server.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_netif_ip_addr.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "mqtt_control.h"
|
||||
#include "wifi-connect.h"
|
||||
|
||||
static const char *TAG = "status_web";
|
||||
|
||||
static httpd_handle_t s_server = NULL;
|
||||
static SemaphoreHandle_t s_lock = NULL;
|
||||
static uint64_t s_snapshot_update_ms = 0;
|
||||
static uint32_t s_snapshot_update_count = 0;
|
||||
static status_web_snapshot_t s_snapshot = {
|
||||
.temp = "--",
|
||||
.hum = "--",
|
||||
.soil = "--",
|
||||
.lux = "--",
|
||||
.pump_on = false,
|
||||
.light_on = false,
|
||||
.auto_mode = true,
|
||||
.soil_on_threshold = 35.0f,
|
||||
.soil_off_threshold = 45.0f,
|
||||
.light_on_threshold = 100.0f,
|
||||
.light_off_threshold = 350.0f,
|
||||
.i2c_ready = false,
|
||||
.soil_sensor_ready = false,
|
||||
.loop_counter = 0,
|
||||
};
|
||||
|
||||
static const char *wifi_status_text(wifi_connect_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case WIFI_CONNECT_STATUS_IDLE: return "idle";
|
||||
case WIFI_CONNECT_STATUS_PROVISIONING: return "provisioning";
|
||||
case WIFI_CONNECT_STATUS_CONNECTING: return "connecting";
|
||||
case WIFI_CONNECT_STATUS_CONNECTED: return "connected";
|
||||
case WIFI_CONNECT_STATUS_FAILED: return "failed";
|
||||
case WIFI_CONNECT_STATUS_TIMEOUT: return "timeout";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void get_sta_ip_text(char *out, size_t out_size)
|
||||
{
|
||||
if (out == NULL || out_size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(out, out_size, "--");
|
||||
esp_netif_t *sta = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
|
||||
if (sta == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
esp_netif_ip_info_t ip_info;
|
||||
if (esp_netif_get_ip_info(sta, &ip_info) == ESP_OK) {
|
||||
snprintf(out,
|
||||
out_size,
|
||||
IPSTR,
|
||||
IP2STR(&ip_info.ip));
|
||||
}
|
||||
}
|
||||
|
||||
static const char *s_page_html =
|
||||
"<!doctype html><html><head><meta charset='utf-8'/>"
|
||||
"<meta name='viewport' content='width=device-width, initial-scale=1'/>"
|
||||
"<title>BotanicalBuddy Status</title>"
|
||||
"<style>"
|
||||
"body{font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:#eef2f7;margin:0;padding:14px;color:#111827;}"
|
||||
".wrap{max-width:1080px;margin:0 auto;background:#fff;border-radius:14px;padding:14px;box-shadow:0 8px 24px rgba(0,0,0,.08);}"
|
||||
"h1{font-size:20px;margin:0 0 10px;}"
|
||||
".meta{font-size:12px;color:#6b7280;margin-bottom:10px;}"
|
||||
".sec{margin-top:10px;}"
|
||||
".sec h2{font-size:14px;margin:0 0 6px;color:#374151;}"
|
||||
".grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;}"
|
||||
"@media(max-width:900px){.grid{grid-template-columns:1fr 1fr;}}"
|
||||
"@media(max-width:560px){.grid{grid-template-columns:1fr;}}"
|
||||
".card{padding:10px;border:1px solid #e5e7eb;border-radius:10px;background:#fafafa;}"
|
||||
".k{font-size:12px;color:#6b7280;}"
|
||||
".v{font-size:17px;font-weight:600;margin-top:2px;word-break:break-all;}"
|
||||
"#raw{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:12px;background:#0f172a;color:#e2e8f0;padding:10px;border-radius:10px;overflow:auto;max-height:260px;}"
|
||||
"button{margin-top:10px;border:none;border-radius:8px;background:#1d4ed8;color:#fff;padding:8px 12px;cursor:pointer;}"
|
||||
"</style></head><body><div class='wrap'>"
|
||||
"<h1>BotanicalBuddy 设备状态总览</h1>"
|
||||
"<div class='meta'>独立状态服务(port 8080),每2秒自动刷新</div>"
|
||||
"<div class='sec'><h2>传感与控制</h2><div class='grid'>"
|
||||
"<div class='card'><div class='k'>空气温度</div><div id='temp' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>空气湿度</div><div id='hum' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>土壤湿度</div><div id='soil' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>光照强度</div><div id='lux' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>水泵</div><div id='pump' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>补光灯</div><div id='light' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>控制模式</div><div id='mode' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>soil_on/off</div><div id='soil_th' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>light_on/off</div><div id='light_th' class='v'>--</div></div>"
|
||||
"</div></div>"
|
||||
"<div class='sec'><h2>连接与系统</h2><div class='grid'>"
|
||||
"<div class='card'><div class='k'>Wi-Fi 状态</div><div id='wifi' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>STA IP</div><div id='ip' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>MQTT 连接</div><div id='mqtt' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>I2C Ready</div><div id='i2c' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>Soil Sensor Ready</div><div id='soil_ready' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>主循环计数</div><div id='loop' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>运行时长</div><div id='uptime' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>空闲堆/最小堆</div><div id='heap' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>固件版本</div><div id='ver' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>快照更新时间</div><div id='snap' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>快照序号</div><div id='seq' class='v'>--</div></div>"
|
||||
"<div class='card'><div class='k'>快照年龄</div><div id='age' class='v'>--</div></div>"
|
||||
"</div></div>"
|
||||
"<div class='sec'><h2>原始 JSON</h2><pre id='raw'>{}</pre></div>"
|
||||
"<button onclick='loadStatus()'>立即刷新</button>"
|
||||
"</div><script>"
|
||||
"function onoff(v){return v?'on':'off';}"
|
||||
"function yn(v){return v?'yes':'no';}"
|
||||
"function fmtMs(ms){if(ms<1000)return ms+' ms';const s=Math.floor(ms/1000);if(s<60)return s+' s';const m=Math.floor(s/60);const rs=s%60;if(m<60)return m+'m '+rs+'s';const h=Math.floor(m/60);return h+'h '+(m%60)+'m';}"
|
||||
"async function loadStatus(){try{const r=await fetch('/api/status');const d=await r.json();"
|
||||
"temp.textContent=d.temp;hum.textContent=d.hum;soil.textContent=d.soil;lux.textContent=d.lux;"
|
||||
"pump.textContent=d.pump;light.textContent=d.light;mode.textContent=d.mode;"
|
||||
"soil_th.textContent=`${d.soil_on}/${d.soil_off}`;light_th.textContent=`${d.light_on}/${d.light_off}`;"
|
||||
"wifi.textContent=d.wifi_status;ip.textContent=d.sta_ip;mqtt.textContent=onoff(d.mqtt_connected);"
|
||||
"i2c.textContent=yn(d.i2c_ready);soil_ready.textContent=yn(d.soil_sensor_ready);"
|
||||
"loop.textContent=d.loop_counter;uptime.textContent=fmtMs(d.uptime_ms);"
|
||||
"heap.textContent=`${d.free_heap}/${d.min_free_heap}`;ver.textContent=d.app_version;"
|
||||
"snap.textContent=d.snapshot_update_ms;seq.textContent=d.snapshot_update_count;age.textContent=fmtMs(d.snapshot_age_ms);"
|
||||
"raw.textContent=JSON.stringify(d,null,2);"
|
||||
"}catch(e){raw.textContent='读取失败: '+e;}}"
|
||||
"setInterval(loadStatus,2000);loadStatus();"
|
||||
"</script></body></html>";
|
||||
|
||||
static esp_err_t status_root_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "text/html");
|
||||
return httpd_resp_send(req, s_page_html, HTTPD_RESP_USE_STRLEN);
|
||||
}
|
||||
|
||||
static esp_err_t status_api_handler(httpd_req_t *req)
|
||||
{
|
||||
status_web_snapshot_t snap;
|
||||
uint64_t snapshot_update_ms = 0;
|
||||
uint32_t snapshot_update_count = 0;
|
||||
xSemaphoreTake(s_lock, portMAX_DELAY);
|
||||
snap = s_snapshot;
|
||||
snapshot_update_ms = s_snapshot_update_ms;
|
||||
snapshot_update_count = s_snapshot_update_count;
|
||||
xSemaphoreGive(s_lock);
|
||||
|
||||
const esp_app_desc_t *app_desc = esp_app_get_description();
|
||||
uint64_t now_ms = (uint64_t)(esp_timer_get_time() / 1000);
|
||||
uint64_t snapshot_age_ms = (snapshot_update_ms > 0 && now_ms >= snapshot_update_ms) ? (now_ms - snapshot_update_ms) : 0;
|
||||
const uint32_t free_heap = esp_get_free_heap_size();
|
||||
const uint32_t min_free_heap = esp_get_minimum_free_heap_size();
|
||||
const uint32_t largest_block = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
|
||||
const bool mqtt_connected = mqtt_control_is_connected();
|
||||
const wifi_connect_status_t wifi_status = wifi_connect_get_status();
|
||||
char ip_text[16] = {0};
|
||||
get_sta_ip_text(ip_text, sizeof(ip_text));
|
||||
|
||||
char json[640];
|
||||
int len = snprintf(json,
|
||||
sizeof(json),
|
||||
"{\"temp\":\"%s\",\"hum\":\"%s\",\"soil\":\"%s\",\"lux\":\"%s\",\"pump\":\"%s\",\"light\":\"%s\",\"mode\":\"%s\",\"soil_on\":%.1f,\"soil_off\":%.1f,\"light_on\":%.1f,\"light_off\":%.1f,\"wifi_status\":\"%s\",\"sta_ip\":\"%s\",\"mqtt_connected\":%s,\"i2c_ready\":%s,\"soil_sensor_ready\":%s,\"loop_counter\":%lu,\"uptime_ms\":%llu,\"free_heap\":%lu,\"min_free_heap\":%lu,\"largest_block\":%lu,\"app_version\":\"%s\",\"snapshot_update_ms\":%llu,\"snapshot_update_count\":%lu,\"snapshot_age_ms\":%llu}",
|
||||
snap.temp,
|
||||
snap.hum,
|
||||
snap.soil,
|
||||
snap.lux,
|
||||
snap.pump_on ? "on" : "off",
|
||||
snap.light_on ? "on" : "off",
|
||||
snap.auto_mode ? "auto" : "manual",
|
||||
snap.soil_on_threshold,
|
||||
snap.soil_off_threshold,
|
||||
snap.light_on_threshold,
|
||||
snap.light_off_threshold,
|
||||
wifi_status_text(wifi_status),
|
||||
ip_text,
|
||||
mqtt_connected ? "true" : "false",
|
||||
snap.i2c_ready ? "true" : "false",
|
||||
snap.soil_sensor_ready ? "true" : "false",
|
||||
(unsigned long)snap.loop_counter,
|
||||
(unsigned long long)now_ms,
|
||||
(unsigned long)free_heap,
|
||||
(unsigned long)min_free_heap,
|
||||
(unsigned long)largest_block,
|
||||
app_desc ? app_desc->version : "unknown",
|
||||
(unsigned long long)snapshot_update_ms,
|
||||
(unsigned long)snapshot_update_count,
|
||||
(unsigned long long)snapshot_age_ms);
|
||||
if (len <= 0 || len >= (int)sizeof(json)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
return httpd_resp_sendstr(req, json);
|
||||
}
|
||||
|
||||
esp_err_t status_web_start(uint16_t port)
|
||||
{
|
||||
if (s_server != NULL) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (s_lock == NULL) {
|
||||
s_lock = xSemaphoreCreateMutex();
|
||||
ESP_RETURN_ON_FALSE(s_lock != NULL, ESP_ERR_NO_MEM, TAG, "create mutex failed");
|
||||
}
|
||||
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
config.server_port = port;
|
||||
config.ctrl_port = (uint16_t)(port + 1);
|
||||
|
||||
ESP_RETURN_ON_ERROR(httpd_start(&s_server, &config), TAG, "httpd_start failed");
|
||||
|
||||
const httpd_uri_t root = {
|
||||
.uri = "/",
|
||||
.method = HTTP_GET,
|
||||
.handler = status_root_handler,
|
||||
.user_ctx = NULL,
|
||||
};
|
||||
const httpd_uri_t api = {
|
||||
.uri = "/api/status",
|
||||
.method = HTTP_GET,
|
||||
.handler = status_api_handler,
|
||||
.user_ctx = NULL,
|
||||
};
|
||||
|
||||
ESP_RETURN_ON_ERROR(httpd_register_uri_handler(s_server, &root), TAG, "register root failed");
|
||||
ESP_RETURN_ON_ERROR(httpd_register_uri_handler(s_server, &api), TAG, "register api failed");
|
||||
|
||||
ESP_LOGI(TAG, "status web started at port %u", (unsigned)port);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t status_web_update(const status_web_snapshot_t *snapshot)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(snapshot != NULL, ESP_ERR_INVALID_ARG, TAG, "snapshot is null");
|
||||
ESP_RETURN_ON_FALSE(s_lock != NULL, ESP_ERR_INVALID_STATE, TAG, "status web not started");
|
||||
|
||||
xSemaphoreTake(s_lock, portMAX_DELAY);
|
||||
s_snapshot = *snapshot;
|
||||
s_snapshot_update_ms = (uint64_t)(esp_timer_get_time() / 1000);
|
||||
s_snapshot_update_count++;
|
||||
xSemaphoreGive(s_lock);
|
||||
return ESP_OK;
|
||||
}
|
||||
34
main/status_web.h
Normal file
34
main/status_web.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char temp[16];
|
||||
char hum[16];
|
||||
char soil[16];
|
||||
char lux[16];
|
||||
bool pump_on;
|
||||
bool light_on;
|
||||
bool auto_mode;
|
||||
float soil_on_threshold;
|
||||
float soil_off_threshold;
|
||||
float light_on_threshold;
|
||||
float light_off_threshold;
|
||||
bool i2c_ready;
|
||||
bool soil_sensor_ready;
|
||||
uint32_t loop_counter;
|
||||
} status_web_snapshot_t;
|
||||
|
||||
esp_err_t status_web_start(uint16_t port);
|
||||
esp_err_t status_web_update(const status_web_snapshot_t *snapshot);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
4
partitions.csv
Normal file
4
partitions.csv
Normal file
@@ -0,0 +1,4 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
factory, app, factory, 0x10000, 0x200000,
|
||||
|
Reference in New Issue
Block a user