, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
KeyBox-ESP32C3电子钥匙
3 |
4 |
5 | 
6 | 
7 | 
8 |
9 | [](https://discord.com/invite/az3ceRmgVe)
10 |
11 | 
12 |
13 | 这是一项基于C语言的电子密钥存储器
14 |
15 |
16 |
17 |
18 | ## 演示视频
19 |
20 | [](https://youtu.be/kEUG0me2HfA "KeyBox")
21 |
22 | [无法播放请点此使用BiliBili](https://www.bilibili.com/video/BV1NATFeLE5D/)
23 | ## 功能
24 | - ✅支持从浏览器导入网站密钥
25 | - ✅支持 TOTP 2FA实时验证码绑定
26 | - ✅支持蓝牙模拟输入HID
27 | - ✅支持 WIFI NTP 校时
28 | - ✅支持设置设备6位密码
29 | - ✅支持息屏
30 | - ✅支持屏幕亮度调节。
31 | ## 计划
32 | - [ ] 接入IOT万物互联客户端
33 | - [ ] 天气、时间、新闻、电量显示
34 |
35 | ## 开源协议
36 | 本项目遵循CC BY-NC-SA 4.0开源协议,使用本程序时请注明出处并进行版权声明
37 | 本项目仅供学习研究与学习,严禁非授权的商业获利,
38 | 如果您有更好的建议,欢迎PR
39 |
40 |
41 | 如遇问题,请向我提出issues
42 | ## 喜欢这个项目,请为我点个Star ⭐
43 |
44 | [](https://star-history.com/#star-history/star-history&Date)
45 | ## 实物图
46 |
47 | | 1 | 2 |
48 | | --- | --- |
49 | |||
50 | ||
51 | |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/include/README:
--------------------------------------------------------------------------------
1 |
2 | This directory is intended for project header files.
3 |
4 | A header file is a file containing C declarations and macro definitions
5 | to be shared between several project source files. You request the use of a
6 | header file in your project source file (C, C++, etc) located in `src` folder
7 | by including it, with the C preprocessing directive `#include'.
8 |
9 | ```src/main.c
10 |
11 | #include "header.h"
12 |
13 | int main (void)
14 | {
15 | ...
16 | }
17 | ```
18 |
19 | Including a header file produces the same results as copying the header file
20 | into each source file that needs it. Such copying would be time-consuming
21 | and error-prone. With a header file, the related declarations appear
22 | in only one place. If they need to be changed, they can be changed in one
23 | place, and programs that include the header file will automatically use the
24 | new version when next recompiled. The header file eliminates the labor of
25 | finding and changing all the copies as well as the risk that a failure to
26 | find one copy will result in inconsistencies within a program.
27 |
28 | In C, the usual convention is to give header files names that end with `.h'.
29 | It is most portable to use only letters, digits, dashes, and underscores in
30 | header file names, and at most one dot.
31 |
32 | Read more about using header files in official GCC documentation:
33 |
34 | * Include Syntax
35 | * Include Operation
36 | * Once-Only Headers
37 | * Computed Includes
38 |
39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
40 |
--------------------------------------------------------------------------------
/lib/README:
--------------------------------------------------------------------------------
1 |
2 | This directory is intended for project specific (private) libraries.
3 | PlatformIO will compile them to static libraries and link into executable file.
4 |
5 | The source code of each library should be placed in an own separate directory
6 | ("lib/your_library_name/[here are source files]").
7 |
8 | For example, see a structure of the following two libraries `Foo` and `Bar`:
9 |
10 | |--lib
11 | | |
12 | | |--Bar
13 | | | |--docs
14 | | | |--examples
15 | | | |--src
16 | | | |- Bar.c
17 | | | |- Bar.h
18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
19 | | |
20 | | |--Foo
21 | | | |- Foo.c
22 | | | |- Foo.h
23 | | |
24 | | |- README --> THIS FILE
25 | |
26 | |- platformio.ini
27 | |--src
28 | |- main.c
29 |
30 | and a contents of `src/main.c`:
31 | ```
32 | #include
33 | #include
34 |
35 | int main (void)
36 | {
37 | ...
38 | }
39 |
40 | ```
41 |
42 | PlatformIO Library Dependency Finder will find automatically dependent
43 | libraries scanning project source files.
44 |
45 | More information about PlatformIO Library Dependency Finder
46 | - https://docs.platformio.org/page/librarymanager/ldf.html
47 |
--------------------------------------------------------------------------------
/platformio.ini:
--------------------------------------------------------------------------------
1 | ; PlatformIO Project Configuration File
2 | ;
3 | ; Build options: build flags, source filter
4 | ; Upload options: custom upload port, speed and extra flags
5 | ; Library options: dependencies, extra library storages
6 | ; Advanced options: extra scripting
7 | ;
8 | ; Please visit documentation for the other options and examples
9 | ; https://docs.platformio.org/page/projectconf.html
10 |
11 | [env:airm2m_core_esp32c3]
12 | platform = espressif32
13 | board = airm2m_core_esp32c3
14 | framework = arduino
15 | board_build.partitions = tinyuf2-partitions-4MB.csv
16 | ;将CPU频率设置为240MHz
17 | board_build.f_cpu = 130000000L
18 | board_build.f_flash = 80000000L
19 | lib_deps =
20 |
21 | olikraus/U8g2 @ ^2.35.17
22 |
23 | # Accept only backwards compatible bug fixes
24 | # (any version with the same major and minor versions, and an equal or greater patch version)
25 | olikraus/U8g2 @ ~2.35.17
26 |
27 | # The exact version
28 | olikraus/U8g2 @ 2.35.17
29 | # RECOMMENDED
30 | # Accept new functionality in a backwards compatible manner and patches
31 | bblanchon/ArduinoJson @ ^7.0.4
32 |
33 | # Accept only backwards compatible bug fixes
34 | # (any version with the same major and minor versions, and an equal or greater patch version)
35 | bblanchon/ArduinoJson @ ~7.0.4
36 |
37 | # The exact version
38 | bblanchon/ArduinoJson @ 7.0.4
39 |
40 | # RECOMMENDED
41 | # Accept new functionality in a backwards compatible manner and patches
42 | polygontechmx/TOTP++ @ ^1.0.1
43 |
44 | # Accept only backwards compatible bug fixes
45 | # (any version with the same major and minor versions, and an equal or greater patch version)
46 | polygontechmx/TOTP++ @ ~1.0.1
47 |
48 | # The exact version
49 | polygontechmx/TOTP++ @ 1.0.1
50 |
51 | arduino-libraries/NTPClient @ ^3.2.1
52 |
53 | # Accept only backwards compatible bug fixes
54 | # (any version with the same major and minor versions, and an equal or greater patch version)
55 | arduino-libraries/NTPClient @ ~3.2.1
56 |
57 | # The exact version
58 | arduino-libraries/NTPClient @ 3.2.1
59 | t-vk/ESP32 BLE Keyboard @ ^0.3.2
60 |
61 | # Accept only backwards compatible bug fixes
62 | # (any version with the same major and minor versions, and an equal or greater patch version)
63 | t-vk/ESP32 BLE Keyboard @ ~0.3.2
64 |
65 | # The exact version
66 | t-vk/ESP32 BLE Keyboard @ 0.3.2
--------------------------------------------------------------------------------
/src/main.ino:
--------------------------------------------------------------------------------
1 | /*
2 | This example opens Sqlite3 databases from SD Card and
3 | retrieves data from them.
4 | Before running please copy following files to SD Card:
5 | examples/sqlite3_sdmmc/data/mdr512.db
6 | examples/sqlite3_sdmmc/data/census2000names.db
7 | Connections:
8 | * SD Card | ESP32
9 | * DAT2 -
10 | * DAT3 SS (D5)
11 | * CMD MOSI (D23)
12 | * VSS GND
13 | * VDD 3.3V
14 | * CLK SCK (D18)
15 | * DAT0 MISO (D19)
16 | * DAT1 -
17 | */
18 | #include "TOTP++.h"
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include "SD.h"
24 | #include
25 | #include
26 |
27 | BleKeyboard bleKeyboard;
28 |
29 | using namespace std;
30 |
31 | // WiFi credentials
32 | const char *ssid = "Hello-World 2.4G";
33 | const char *password = "Qwe200477";
34 | //const long utcOffsetInSeconds = 3600;//用于NTPClient timeClient,看定义
35 |
36 | WiFiUDP ntpUDP;
37 | NTPClient timeClient(ntpUDP, "pool.ntp.org");
38 |
39 |
40 |
41 | // TOTP CONFIG
42 |
43 |
44 |
45 |
46 | int OutPutTimes;
47 | int modelchooese=0;//0:JSON,1:TXT,2:SET,3.TOTp,4.Displaytime,5.Back Light,6.BLE MODE
48 | String OutPutString = "";
49 | int keySize;
50 | char* passwordIn;
51 | struct key {
52 | String user;
53 | String password;
54 | };
55 | int passwordst=0;
56 | const char* data = "Callback function called";
57 | //#include
58 | #include
59 | #include
60 |
61 | // #define ESP32 0
62 | // #define MEGA2560 1
63 |
64 | // #define MCU 1
65 |
66 | #define SPEED 4//16的因数
67 | #define ICON_SPEED 12
68 | #define ICON_SPACE 48//图标间隔,speed倍数
69 |
70 | // #define READ A0
71 | // #define BTN0 5
72 | // #define BTN1 6
73 | // #define BTN2 7
74 |
75 | #define BTN0 12
76 | #define BTN1 1
77 | #define BTN2 0
78 |
79 | U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* clock=*/ 9, /* data=*/ 8); // ESP32 Thing, pure SW emulated I2C
80 |
81 | PROGMEM const uint8_t icon_pic[][200]
82 | {
83 | {
84 |
85 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x80,0x3F,0x00,0x00,0x00,0xE0,0x79,0x00,0x00,0x00,0x70,0xE0,0x00,0x00,0x00,0x38,0xC0,0x03,0x00,0x00,0x1E,0x80,0x07,0x00,0x00,0x0F,0x00,0x0E,0x00,0x80,0x03,0x00,0x1C,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0xC0,0x3F,0x30,0x00,0xC0,0xC0,0x3F,0x30,0x00,0xC0,0xC0,0x30,0x30,0x00,0xC0,0xC0,0x30,0x30,0x00,0xC0,0xC0,0x30,0x30,0x00,0xC0,0xC0,0x30,
86 | 0x30,0x00,0xC0,0xC0,0x30,0x30,0x00,0xC0,0xC0,0x30,0x30,0x00,0xC0,0xC0,0x30,0x30,0x00,0xC0,0xFF,0xF0,0x3F,0x00,0x80,0xFF,0xF0,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"C:\Users\qw200\Desktop\home_40dp_FILL0_wght400_GRAD0_opsz40.bmp",0*/
87 | },
88 | {
89 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x80,0x7F,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x70,0xC0,0x01,0x00,0x00,0x38,0x00,0x03,0x00,0x00,0x18,0x00,0xFF,0xFF,0x00,0x0C,0x00,0xFE,0xFF,0x01,0x0C,0x0E,0x00,0x80,0x03,0x0C,0x1F,0x00,0x00,0x07,0x0C,0x1F,0x00,0x00,0x0E,0x0C,0x0E,0x00,0x04,0x07,0x0C,0x00,0x3E,0x8E,0x01,0x18,0x00,0x7F,0xFF,0x00,0x18,0x00,0xE3,0x71,0x00,0x70,0x80,0x81,0x20,0x00,0xE0,0xE0,0x00,0x00,0x00,0xC0,0x7F,0x00,
90 | 0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"C:\Users\qw200\Desktop\key_40dp_FILL0_wght400_GRAD0_opsz40 (1).bmp",0*/
91 |
92 | /* (36 X 37 )*/
93 | },
94 | {
95 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0xE0,0x79,0x00,0x00,0x00,0x7C,0xE0,0x03,0x00,0x80,0x0F,0x00,0x1F,0x00,0x80,0x03,0x00,0x38,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x0F,0x30,0x00,0xC0,0x00,0x0F,0x30,0x00,0xC0,0x00,0x0F,0x30,0x00,0xC0,0x00,0x0F,0x30,0x00,0xC0,0x00,0x06,0x30,0x00,0xC0,0x00,0x06,0x30,0x00,0xC0,0x01,0x06,0x30,0x00,0x80,0x01,0x06,0x38,0x00,0x80,0x01,0x0E,0x18,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x03,0x00,0x0C,0x00,0x00,0x03,0x00,0x0C,0x00,0x00,0x06,0x00,
96 | 0x06,0x00,0x00,0x0C,0x00,0x07,0x00,0x00,0x1C,0x00,0x03,0x00,0x00,0x38,0xC0,0x01,0x00,0x00,0x70,0xE0,0x00,0x00,0x00,0xC0,0x79,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"C:\Users\qw200\Desktop\encrypted_40dp_FILL0_wght400_GRAD0_opsz40.bmp",0*/
97 |
98 | },
99 |
100 | {
101 |
102 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x1F,0x00,0x00,0x80,0xFF,0x7F,0x00,0x00,0xC0,0x00,0xE0,0x00,0x00,0xC0,0x00,0xE0,0x00,0x00,0xC0,0x00,0xE0,0x01,0x00,0xC0,0x00,0xE0,0x07,0x00,0xC0,0x00,0xE0,0x0F,0x00,0xC0,0x00,0xE0,0x1F,0x00,0xC0,0x00,0xE0,0x1F,0x00,0xC0,0x00,0x20,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0xE0,0x7F,0x30,0x00,0xC0,0xF0,0xFF,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0xF0,0xFF,
103 | 0x30,0x00,0xC0,0xE0,0x7E,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0xC0,0x00,0x00,0x30,0x00,0x80,0xFF,0xFF,0x3F,0x00,0x80,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"C:\Users\qw200\Desktop\description_40dp_FILL0_wght400_GRAD0_opsz40.bmp",0*/
104 |
105 |
106 | },
107 | {
108 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x80,0x3F,0x00,0x00,0x00,0x80,0x30,0x00,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0xC0,0x30,0x00,0x00,0x80,0xE1,0x70,0x30,0x00,0xC0,0x77,0xE0,0x3F,0x00,0x60,0x1E,0x80,0x67,0x00,0x60,0x08,0x00,0x61,0x00,0x30,0x00,0x00,0xC0,0x00,0x30,0x00,0x06,0xC0,0x00,0xE0,0x80,0x1F,0xE0,0x00,0xC0,0xC1,0x3F,0x38,0x00,0x80,0xC1,0x7F,0x18,0x00,0x80,0xC1,0x7F,0x18,0x00,0x80,0xE1,0x7F,0x18,0x00,0x80,0xC1,0x7F,0x18,0x00,0xC0,0xC1,0x3F,0x38,0x00,0xE0,0x80,0x1F,0x70,0x00,0x30,0x00,0x0F,0xC0,0x00,0x30,0x00,0x00,0xC0,0x00,0x60,0x00,0x00,0xE0,0x00,0x60,0x1E,0x80,
109 | 0x67,0x00,0xC0,0x7F,0xE0,0x3F,0x00,0xC0,0xE1,0xF0,0x38,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0x80,0x30,0x00,0x00,0x00,0x80,0x3F,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"C:\Users\qw200\Desktop\settings_40dp_FILL0_wght400_GRAD0_opsz40.bmp",0*/
110 | },
111 | {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x00,0x00,0x00,0xC0,0x3F,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x70,0xE0,0x00,0x00,0x00,0x38,0xC0,0x01,0x00,0x00,0x18,0x80,0x01,0x00,0x00,0x18,0x80,0x01,0x00,0x00,0x18,0x80,0x01,0x00,0x00,0x18,0x80,0x01,0x00,0x00,0x18,0x80,0x01,0x00,0x00,0xFE,0xFF,0x07,0x00,0x80,0xFF,0xFF,0x1F,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0x01,0x0F,0x38,0x00,0xC0,0x81,0x1F,0x38,0x00,0xC0,0x81,0x1F,0x38,0x00,0xC0,0x81,0x1F,0x38,0x00,0xC0,0x01,0x0F,0x38,0x00,0xC0,0x01,0x00,
112 | 0x38,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0x01,0x00,0x38,0x00,0xC0,0xFF,0xFF,0x3F,0x00,0x80,0xFF,0xFF,0x1F,0x00,0x00,0xFE,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"C:\Users\qw200\Desktop\lock_24dp_FILL0_wght400_GRAD0_opsz24.bmp",0*/},
113 | };
114 |
115 | uint8_t icon_width[] = { 36,36,36,36,36 ,36};
116 |
117 | //main界面图片
118 | PROGMEM const uint8_t LOGO[] =
119 | {
120 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
121 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
123 | 0x00,0x00,0x00,0x00,0xEF,0x0F,0x70,0x00,0x00,0x00,0x00,0x00,0xE0,0xD8,0x87,0x3F,
124 | 0x00,0x00,0x00,0x80,0xEF,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0xE0,0xDC,0x8F,0x3F,
125 | 0x98,0xFF,0x7F,0xBF,0x0F,0x8F,0xFF,0xFF,0x03,0x00,0x00,0x00,0xE0,0x1D,0x8F,0x07,
126 | 0x98,0xE1,0xFF,0x3F,0x87,0x87,0x73,0x77,0x03,0x00,0x00,0x00,0xC0,0x9F,0x87,0x1F,
127 | 0x98,0xFD,0xF7,0x3B,0x87,0x83,0x7F,0xF7,0x07,0x00,0x00,0x00,0xC0,0xCF,0x03,0x3C,
128 | 0xB0,0xF7,0xF7,0x3F,0xC7,0x73,0x7E,0x7F,0x00,0x00,0x00,0x00,0xC0,0xE7,0xB7,0x3F,
129 | 0xF0,0xFE,0xF7,0x3F,0xE7,0xF1,0x7F,0xFF,0x03,0x00,0x00,0x00,0x80,0xE7,0xB7,0x1F,
130 | 0xF0,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131 | 0x70,0x00,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132 | 0x7C,0x00,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135 | 0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,
136 | 0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,
137 | 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,
138 | 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,
139 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,
140 | 0xFF,0xFF,0x83,0xFF,0xF0,0x01,0x00,0x8F,0xFF,0x1E,0x00,0x7E,0x80,0x0F,0x7F,0xFE,
141 | 0xFF,0xFF,0x83,0x7F,0xF0,0x01,0x00,0x0F,0x7F,0x1E,0x7F,0x3C,0x00,0x0F,0x3E,0xFE,
142 | 0xFF,0xFF,0xC1,0x1F,0xF8,0xF1,0xFF,0x1F,0x7E,0x1E,0x7F,0x1C,0x00,0x3E,0x3C,0xFE,
143 | 0xFF,0xFF,0xC1,0x07,0xFE,0xF1,0xFF,0x3F,0x3C,0x1F,0x3F,0x1C,0x3C,0x7C,0x18,0xFE,
144 | 0xFF,0xFF,0xC0,0x81,0xFF,0xF1,0xFF,0xFF,0x98,0x1F,0x0F,0x1C,0x7E,0xFC,0x08,0xFF,
145 | 0xFF,0xFF,0x00,0xF0,0xFF,0xF1,0xFF,0xFF,0xC8,0x1F,0x00,0x1F,0x7F,0xFC,0x81,0xFF,
146 | 0xFF,0xFF,0x00,0xFC,0xFF,0x01,0xC0,0xFF,0xC9,0x1F,0xF0,0x1F,0x7F,0xFC,0xC1,0xFF,
147 | 0xFF,0xFF,0x00,0xFE,0xFF,0x01,0xC0,0xFF,0xE3,0x1F,0x80,0x1F,0x7F,0xFC,0xC0,0xFF,
148 | 0xFF,0x7F,0x00,0xF8,0xFF,0x01,0x80,0xFF,0xF3,0x1F,0x00,0x1C,0x7F,0x7C,0xC0,0xFF,
149 | 0xFF,0x7F,0xF0,0xF8,0xFF,0xF9,0xFF,0xFF,0xF3,0x1F,0x1F,0x18,0x7F,0x7C,0x88,0xFF,
150 | 0xFF,0x7F,0xF8,0xF0,0xFF,0xF8,0xFF,0xFF,0xF3,0x9F,0x3F,0x18,0x7F,0x3C,0x0C,0xFF,
151 | 0xFF,0x3F,0xF8,0xE1,0xFF,0xF8,0xFF,0xFF,0xF3,0x9F,0x3F,0x18,0x7F,0x3C,0x1E,0xFE,
152 | 0xFF,0x3F,0xF8,0xC3,0x7F,0xFC,0xFF,0xFF,0xF3,0x9F,0x3F,0x18,0x7F,0x3C,0x1F,0xFE,
153 | 0xFF,0x1F,0xFC,0x87,0x3F,0xFC,0xFF,0xFF,0xF3,0x9F,0x1F,0x18,0x3F,0x1C,0x3F,0xFC,
154 | 0xFF,0x1F,0xFC,0x0F,0x3F,0x00,0xE0,0xFF,0xF3,0x1F,0x00,0x1C,0x00,0x1C,0x3F,0xF8,
155 | 0xFF,0x1F,0xFC,0x0F,0x3E,0x00,0xE0,0xFF,0xF3,0x1F,0x00,0x7F,0x00,0xBC,0x7F,0xF8,
156 | 0xFF,0x0F,0xFE,0x1F,0x3E,0x00,0xF0,0xFF,0xF3,0x1F,0xF0,0xFF,0x03,0xFF,0x7F,0xFC,
157 | 0xFF,0xFF,0xFF,0x3F,0xFE,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
158 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
159 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
160 | 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,
161 | 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,
162 | 0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,
163 | 0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,
164 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
165 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
166 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
167 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
169 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
171 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
172 | 0x00,0x00,0x00,0x00,0x00,0x38,0x9E,0xDF,0xDF,0xF3,0x30,0xCF,0x73,0x7F,0xDE,0x1F,
173 | 0x00,0x00,0x00,0x00,0x00,0x38,0x9F,0xFF,0xFF,0xF7,0x99,0xDF,0xF7,0x7F,0xDF,0x1F,
174 | 0x00,0x00,0x00,0x00,0x00,0xB8,0xBB,0xE7,0xFD,0xF7,0x9F,0xD9,0xF7,0x07,0x1F,0x0E,
175 | 0x00,0x00,0x00,0x00,0x00,0xB8,0x31,0xFF,0xF8,0x7F,0xCF,0xD9,0xFD,0x7B,0x0E,0x0F,
176 | 0x00,0x00,0x00,0x00,0x00,0xFC,0x3F,0xFE,0xFC,0x7C,0xC7,0xFF,0xFD,0x7B,0x8E,0x07,
177 | 0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x7C,0xE7,0xFF,0xFD,0x7F,0x8E,0x07,
178 | 0x00,0x00,0x00,0x00,0x00,0xFF,0xF1,0xCF,0xDF,0x3C,0xF7,0xF9,0x3D,0x7F,0xCE,0x03,
179 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
180 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
181 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
182 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
183 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"C:\Users\qw200\Desktop\indexa.bmp",0*/
184 | };
185 |
186 | const float PID_MAX = 10.00;//PID最大允许值
187 | //PID变量
188 | float Kpid[3] = { 9.97,0.2,0.01 };//Kp,Ki,Kd
189 | // float Kp=8.96;
190 | // float Ki=0.2;
191 | // float Kd=0.01;
192 |
193 | #define MAX_CHARS_PER_LINE 20 // 每行最大字符数
194 | #define MAX_LINES_PER_PAGE 5 // 每页最大行数
195 |
196 | #define BUTTON_PIN 1
197 | #define DISPLAY_ROWS 6
198 | #define CHARACTERS_PER_LINE 22
199 |
200 | //U8G2_SH1106_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
201 |
202 |
203 | String textContent;
204 | int currentPage = 0;
205 | int totalPages = 0;
206 | uint8_t disappear_step = 1;
207 |
208 |
209 | float angle, angle_last;
210 | //实时坐标
211 | uint8_t chart_x;
212 | bool frame_is_drawed = false;
213 |
214 | //指向buf首地址的指针
215 | uint8_t* buf_ptr;
216 | uint16_t buf_len;
217 |
218 | //选择界面变量
219 | uint8_t x;
220 | int16_t y, y_trg;//目标和当前
221 | uint8_t line_y, line_y_trg;//线的位置
222 | uint8_t box_width, box_width_trg;//框的宽度
223 | int16_t box_y, box_y_trg;//框的当前值和目标值
224 | int8_t ui_select;//当前选中那一栏
225 |
226 | //pid界面变量
227 | //pid界面变量
228 | int8_t pid_x;
229 | int16_t pid_y,pid_y_trg;
230 | uint8_t pid_line_y, pid_line_y_trg;//线的位置
231 | uint8_t pid_box_width, pid_box_width_trg;//框的宽度
232 | int16_t pid_box_y, pid_box_y_trg;//框的当前值和目标值
233 | int8_t pid_select;//当前选中那一栏
234 |
235 | //icon界面变量
236 | int16_t icon_x, icon_x_trg;
237 | int16_t app_y, app_y_trg;
238 |
239 | int8_t icon_select;
240 |
241 | uint8_t ui_index, ui_state;
242 |
243 |
244 | enum//ui_index
245 | {
246 | M_LOGO,//开始界面
247 | M_SELECT,//选择界面
248 | M_PID,//PID界面
249 | M_PID_EDIT,//pid编辑
250 | M_ICON,//icon界面
251 | M_CHART,//图表
252 | M_TEXT_EDIT,//文字编辑
253 | M_VIDEO,//视频显示
254 | M_ABOUT,//关于本机
255 | M_ABOUT_pass,
256 | M_IMPORT,
257 | M_TXTREAD,
258 | M_ABOUTDEV,
259 | M_SET,
260 | M_TOTF,
261 | M_BLACK
262 | };
263 |
264 |
265 | enum//ui_state
266 | {
267 | S_NONE,
268 | S_DISAPPEAR,
269 | S_SWITCH,
270 | S_MENU_TO_MENU,
271 | S_MENU_TO_PIC,
272 | S_PIC_TO_MENU,
273 | };
274 |
275 | //const char* text="This is a text Hello world ! follow up one two three four may jun july";
276 |
277 | //菜单结构体
278 | typedef struct
279 | {
280 | char* select;
281 | } SELECT_LIST;
282 |
283 | SELECT_LIST* list = NULL; // (主要的菜单结构,用于展示站点和文本)初始化结构体数组指针
284 |
285 | SELECT_LIST* pid = NULL; // (二级菜单结构,用于展示站点的多个用户)初始化结构体数组指针
286 |
287 |
288 |
289 |
290 | //SELECT_LIST list[]
291 | //{
292 | // {"MainUI"},
293 | // {"+PID Editor"},
294 | // {"-Icon Test"},
295 | // {"-Chart Test"},
296 | // {"-Text Edit"},
297 | // {"-Play Video"},
298 | // {"{ About }"},
299 | // {"{ About }"},
300 | // {"{ About }"},
301 | //};
302 | int listSize = 7;//选择界面菜单个数
303 | int pidSize = 6;
304 | uint8_t pid_single_line_length = 63 /pidSize;
305 | uint8_t pid_total_line_length = pid_single_line_length * pidSize + 1;
306 | uint8_t single_line_length = 63 / listSize;
307 | uint8_t total_line_length = single_line_length * listSize + 1;
308 |
309 | SELECT_LIST icon[]
310 | {
311 | {"HOME"},
312 | {"WEB KEY"},
313 | {"2FA KEY"},
314 | {"TXT"},
315 | {"SET"},
316 | {"LOCK"},
317 | };
318 |
319 | //设备名称
320 | char name[] = "";
321 | char Passwordis[]="";
322 | int display_time=0;
323 | //允许名字的最大长度
324 | const uint8_t name_len = 6;//0-11for name 12 for return
325 | char title[] = "Password";
326 | char bt[] = "sure";
327 |
328 | uint8_t edit_index = 0;
329 | bool edit_flag = false;//默认不在编辑
330 | uint8_t blink_flag;//默认高亮
331 | const uint8_t BLINK_SPEED = 16;//2的倍数
332 |
333 | uint8_t icon_num = sizeof(icon) / sizeof(SELECT_LIST);
334 |
335 | //按键变量
336 | typedef struct
337 | {
338 | bool val;
339 | bool last_val;
340 | }KEY;
341 |
342 | KEY key[3] = { false };
343 |
344 | //按键信息
345 | typedef struct
346 | {
347 | uint8_t id;
348 | bool pressed;
349 | }KEY_MSG;
350 |
351 | KEY_MSG key_msg = { 0 };
352 |
353 | void createJson(String fileName, String key, String value) {
354 | StaticJsonDocument<200> doc; //JSON document size
355 |
356 | doc[key] = value;
357 |
358 | delay(500); // 添加延时以确保前一个文件句柄已被释放
359 |
360 | File jsonFile = SD.open("/"+fileName, FILE_WRITE); // 定义并初始化File对象
361 |
362 | delay(100); // 添加另一个延时
363 |
364 | if (jsonFile) {
365 | serializeJson(doc, jsonFile);
366 | jsonFile.close();
367 | } else {
368 | Serial.println("Error opening file for writing!");
369 | }
370 | }
371 | void updateJson(String fileName, String key, String value) {
372 | File jsonFile = SD.open("/"+fileName, FILE_READ);
373 |
374 | DynamicJsonDocument doc(1024);
375 |
376 | DeserializationError error = deserializeJson(doc, jsonFile);
377 |
378 | jsonFile.close();
379 |
380 | if (error) {
381 | Serial.println("Error deserializing JSON file!");
382 | return;
383 | }
384 |
385 | doc[key] = value;
386 |
387 | delay(100); // 添加延时以确保前一个文件句柄已被释放
388 |
389 | jsonFile = SD.open("/"+fileName, FILE_WRITE);
390 |
391 | if (jsonFile) {
392 | serializeJson(doc, jsonFile);
393 | jsonFile.close();
394 | } else {
395 | Serial.println("Error opening222 file for writing!");
396 | }
397 | }
398 | void writeCSV(){
399 |
400 | // 打开CSV文件
401 | File csvFile = SD.open("/data.csv");
402 |
403 | // 跳过第一行
404 | if (csvFile) {
405 | csvFile.readStringUntil('\n'); // 跳过第一行
406 | } else {
407 | Serial.println("Error opening CSV file!");
408 | return;
409 | }
410 |
411 | // 读取CSV文件内容并创建/更新JSON文件
412 | while (csvFile.available()) {
413 | String data = csvFile.readStringUntil('\n'); // 读取一行数据
414 | if (data == "") {
415 | break; // 结束循环,文件已读取完整
416 | }
417 |
418 | String ip = data.substring(0, data.indexOf(","));
419 | int firstCommaIndex = data.indexOf(",");
420 | int secondCommaIndex = data.indexOf(",", firstCommaIndex + 1);
421 | int thirdCommaIndex = data.indexOf(",", secondCommaIndex + 1);
422 | int fourthCommaIndex = data.indexOf(",", thirdCommaIndex + 1);
423 | int fourth2CommaIndex = data.indexOf(",", fourthCommaIndex + 1);
424 | String key = data.substring(thirdCommaIndex + 1, fourthCommaIndex);
425 | String value = data.substring(fourthCommaIndex + 1, fourth2CommaIndex);
426 | Serial.println(ip);
427 | Serial.println(key);
428 | Serial.println(value);
429 | Serial.println("----------------------------------");
430 | String fileName = ip + ".web";
431 |
432 | if (SD.exists("/" + fileName)) {
433 | // 文件已存在,更新JSON文件中的键值对
434 | updateJson(fileName, key, value);
435 | } else {
436 | // 文件不存在,创建新的JSON文件
437 | createJson(fileName, key, value);
438 | }
439 | }
440 |
441 | csvFile.close(); // 关闭CSV文件
442 | // 关闭CSV文件
443 |
444 | }
445 | bool get_key_val(uint8_t ch)
446 | {
447 | switch (ch)
448 | {
449 | case 0:
450 | return digitalRead(BTN0);
451 | break;
452 | case 1:
453 | return digitalRead(BTN1);
454 | break;
455 | case 2:
456 | return digitalRead(BTN2);
457 | break;
458 | default:
459 | break;
460 | }
461 | }
462 |
463 | void key_init()
464 | {
465 | for (uint8_t i = 0; i < (sizeof(key) / sizeof(KEY)); ++i)
466 | {
467 | key[i].val = key[i].last_val = get_key_val(i);
468 | }
469 | }
470 |
471 | void key_scan()
472 | {
473 | for (uint8_t i = 0; i < (sizeof(key) / sizeof(KEY)); ++i)
474 | {
475 | key[i].val = get_key_val(i);//获取键值
476 | if (key[i].last_val != key[i].val)//发生改变
477 | {
478 | key[i].last_val = key[i].val;//更新状态
479 | if (key[i].val == LOW)
480 | {
481 | key_msg.id = i;
482 | key_msg.pressed = true;
483 | }
484 | }
485 | }
486 | }
487 |
488 | //移动函数
489 | bool move(int16_t* a, int16_t* a_trg)
490 | {
491 | if (*a < *a_trg)
492 | {
493 | *a += SPEED;
494 | if (*a > *a_trg) *a = *a_trg;//加完超过
495 | }
496 | else if (*a > *a_trg)
497 | {
498 | *a -= SPEED;
499 | if (*a < *a_trg) *a = *a_trg;//减完不足
500 | }
501 | else
502 | {
503 | return true;//到达目标
504 | }
505 | return false;//未到达
506 | }
507 |
508 | //移动函数
509 | bool move_icon(int16_t* a, int16_t* a_trg)
510 | {
511 | if (*a < *a_trg)
512 | {
513 | *a += ICON_SPEED;
514 | if (*a > *a_trg) *a = *a_trg;//加完超过
515 | }
516 | else if (*a > *a_trg)
517 | {
518 | *a -= ICON_SPEED;
519 | if (*a < *a_trg) *a = *a_trg;//减完不足
520 | }
521 | else
522 | {
523 | return true;//到达目标
524 | }
525 | return false;//未到达
526 | }
527 |
528 | //宽度移动函数
529 | bool move_width(uint8_t* a, uint8_t* a_trg, uint8_t select, uint8_t id)
530 | {
531 | if (*a < *a_trg)
532 | {
533 | uint8_t step = 16 / SPEED;//判断步数
534 | uint8_t len;
535 | if (ui_index == M_SELECT)
536 | {
537 | len = abs(u8g2.getStrWidth(list[select].select) - u8g2.getStrWidth(list[id == 0 ? select + 1 : select - 1].select));
538 | }
539 | else if (ui_index == M_PID)
540 | {
541 | len = abs(u8g2.getStrWidth(pid[select].select) - u8g2.getStrWidth(pid[id == 0 ? select + 1 : select - 1].select));
542 | }
543 | uint8_t width_speed = ((len % step) == 0 ? (len / step) : (len / step + 1)); //计算步长
544 | *a += width_speed;
545 | if (*a > *a_trg) *a = *a_trg;//
546 | }
547 | else if (*a > *a_trg)
548 | {
549 | uint8_t step = 16 / SPEED;//判断步数
550 | uint8_t len;
551 | if (ui_index == M_SELECT)
552 | {
553 | len = abs(u8g2.getStrWidth(list[select].select) - u8g2.getStrWidth(list[id == 0 ? select + 1 : select - 1].select));
554 | }
555 | else if (ui_index == M_PID)
556 | {
557 | len = abs(u8g2.getStrWidth(pid[select].select) - u8g2.getStrWidth(pid[id == 0 ? select + 1 : select - 1].select));
558 | }
559 | uint8_t width_speed = ((len % step) == 0 ? (len / step) : (len / step + 1)); //计算步长
560 | *a -= width_speed;
561 | if (*a < *a_trg) *a = *a_trg;
562 | }
563 | else
564 | {
565 | return true;//到达目标
566 | }
567 | return false;//未到达
568 | }
569 |
570 | //进度条移动函数
571 | bool move_bar(uint8_t* a, uint8_t* a_trg)
572 | {
573 | if (*a < *a_trg)
574 | {
575 | uint8_t step = 16 / SPEED;//判断步数
576 | uint8_t width_speed = ((single_line_length % step) == 0 ? (single_line_length / step) : (single_line_length / step + 1)); //计算步长
577 | *a += width_speed;
578 | if (*a > *a_trg) *a = *a_trg;//
579 | }
580 | else if (*a > *a_trg)
581 | {
582 | uint8_t step = 16 / SPEED;//判断步数
583 | uint8_t width_speed = ((single_line_length % step) == 0 ? (single_line_length / step) : (single_line_length / step + 1)); //计算步长
584 | *a -= width_speed;
585 | if (*a < *a_trg) *a = *a_trg;
586 | }
587 | else
588 | {
589 | return true;//到达目标
590 | }
591 | return false;//未到达
592 | }
593 |
594 | //文字编辑函数
595 | void text_edit(bool dir, uint8_t index)
596 | {
597 | if (!dir)
598 | {
599 | if (name[index] >= 'A' && name[index] <= 'Z')//大写字母
600 | {
601 | if (name[index] == 'A')
602 | {
603 | name[index] = 'z';
604 | }
605 | else
606 | {
607 | name[index] -= 1;
608 | }
609 | }
610 | else if (name[index] >= 'a' && name[index] <= 'z')//小写字母
611 | {
612 | if (name[index] == 'a')
613 | {
614 | name[index] = ' ';
615 | }
616 | else
617 | {
618 | name[index] -= 1;
619 | }
620 | }
621 | else
622 | {
623 | name[index] = 'Z';
624 | }
625 | }
626 | else
627 | {
628 | if (name[index] >= 'A' && name[index] <= 'Z')//大写字母
629 | {
630 | if (name[index] == 'Z')
631 | {
632 | name[index] = ' ';
633 | }
634 | else
635 | {
636 | name[index] += 1;
637 | }
638 | }
639 | else if (name[index] >= 'a' && name[index] <= 'z')//小写字母
640 | {
641 | if (name[index] == 'z')
642 | {
643 | name[index] = 'A';
644 | }
645 | else
646 | {
647 | name[index] += 1;
648 | }
649 | }
650 | else
651 | {
652 | name[index] = 'a';
653 | }
654 | }
655 | Serial.println("NOW IS");
656 | Serial.println(name);
657 | }
658 |
659 | //消失函数
660 | void disappear()
661 | {
662 | switch (disappear_step)
663 | {
664 | case 1:
665 | for (uint16_t i = 0; i < buf_len; ++i)
666 | {
667 | if (i % 2 == 0) buf_ptr[i] = buf_ptr[i] & 0x55;
668 | }
669 | break;
670 | case 2:
671 | for (uint16_t i = 0; i < buf_len; ++i)
672 | {
673 | if (i % 2 != 0) buf_ptr[i] = buf_ptr[i] & 0xAA;
674 | }
675 | break;
676 | case 3:
677 | for (uint16_t i = 0; i < buf_len; ++i)
678 | {
679 | if (i % 2 == 0) buf_ptr[i] = buf_ptr[i] & 0x00;
680 | }
681 | break;
682 | case 4:
683 | for (uint16_t i = 0; i < buf_len; ++i)
684 | {
685 | if (i % 2 != 0) buf_ptr[i] = buf_ptr[i] & 0x00;
686 | }
687 | break;
688 | default:
689 | ui_state = S_NONE;
690 | disappear_step = 0;
691 | break;
692 | }
693 | disappear_step++;
694 | }
695 |
696 | int compare(const void *a, const void *b) {
697 | return strcmp(((SELECT_LIST*)a)->select, ((SELECT_LIST*)b)->select);
698 | }
699 | int compare2(const void *elem1, const void *elem2) {
700 | SELECT_LIST* item1 = (SELECT_LIST*)elem1;
701 | SELECT_LIST* item2 = (SELECT_LIST*)elem2;
702 |
703 | // 判断如果元素为最后一个元素,则不进行排序
704 | if (item1 == &pid[pidSize-1] || item2 == &pid[pidSize-1]) {
705 | return 0; // 返回0表示两个元素相等
706 | }
707 |
708 | return strcmp(item1->select, item2->select);
709 | }
710 |
711 | void drawPage(int page) {
712 | u8g2.firstPage();
713 | do {
714 | u8g2.setFont(u8g2_font_ncenB08_tr);
715 | for (int i = 0; i < DISPLAY_ROWS; i++) {
716 | int startIdx = page * DISPLAY_ROWS * CHARACTERS_PER_LINE + i * CHARACTERS_PER_LINE;
717 | int endIdx = startIdx + CHARACTERS_PER_LINE;
718 | if (endIdx > textContent.length()) endIdx = textContent.length();
719 | if (startIdx < textContent.length()) {
720 | u8g2.setCursor(0, 10 + i * 10);
721 | u8g2.print(textContent.substring(startIdx, endIdx));
722 | }
723 | }
724 | } while (u8g2.nextPage());
725 | }
726 |
727 | /**************************界面显示*******************************/
728 |
729 | void logo_ui_show()//显示logo
730 | {
731 | if (!SD.begin(7)) {
732 | Serial.println("SD 卡初始化失败!");
733 | u8g2.firstPage();
734 | do {
735 | u8g2.drawStr(0, 10, "No Find TF card !");
736 | u8g2.drawStr(0, 23, "Please check it");
737 | u8g2.drawStr(0, 36, "And restart...");
738 | u8g2.drawStr(0, 49, "More see at yang17.site");
739 | u8g2.drawStr(0, 62," ---KeyBox");
740 | } while (u8g2.nextPage());
741 |
742 | }else {
743 | u8g2.drawXBMP(0, 0, 128, 64, LOGO);
744 | }
745 | // for(uint16_t i=0;i 0) Kpid[pid_select] -= 0.01;
1024 | break;
1025 | case 1:
1026 | if (Kpid[pid_select] < PID_MAX) Kpid[pid_select] += 0.01;
1027 | break;
1028 | case 2:
1029 | ui_index = M_PID;
1030 | break;
1031 | default:
1032 | break;
1033 | }
1034 | }
1035 | pid_ui_show();
1036 | for (uint16_t i = 0; i < buf_len; ++i)
1037 | {
1038 | buf_ptr[i] = buf_ptr[i] & (i % 2 == 0 ? 0x55 : 0xAA);
1039 | }
1040 | pid_edit_ui_show();
1041 | }
1042 | void addPassword(char* mainsite,char* mainuser);
1043 | void pid_proc()//pid界面处理函数
1044 | {
1045 |
1046 | pid_ui_show();
1047 |
1048 | if (key_msg.pressed)
1049 | {
1050 | key_msg.pressed = false;
1051 | Serial.println("-------------------");
1052 | Serial.println(pid_select);
1053 | Serial.println(pidSize);
1054 |
1055 | switch (key_msg.id)
1056 | {
1057 |
1058 | // Serial.println(pid_select);
1059 | case 0:
1060 | // Serial.println("=============");
1061 | // Serial.println(pid_select);
1062 | if (pid_select < 1) break;
1063 | pid_select -= 1;
1064 | pid_line_y_trg -= pid_single_line_length;
1065 | if (pid_select < -(pid_y / 16))
1066 | {
1067 | pid_y_trg += 16;
1068 | }
1069 | else
1070 | {
1071 | pid_box_y_trg -= 16;
1072 | }
1073 | break;
1074 |
1075 |
1076 | case 1:
1077 |
1078 | if ((pid_select + 2) > pidSize) break;
1079 | pid_select += 1;
1080 | pid_line_y_trg += pid_single_line_length;
1081 | if ((pid_select + 1) > (4 - pid_y / 16))
1082 | {
1083 | pid_y_trg -= 16;
1084 | }
1085 | else
1086 | {
1087 | pid_box_y_trg += 16;
1088 | }
1089 |
1090 |
1091 | break;
1092 | case 2:
1093 | if (pid_select == pidSize-1)
1094 | {
1095 | if(modelchooese==5||modelchooese==4||modelchooese==6){
1096 | modelchooese = 2;
1097 | }
1098 |
1099 | ui_index = M_SELECT;
1100 | ui_state = S_DISAPPEAR;
1101 | pid_x = 4;
1102 | pid_y = pid_y_trg = 0;
1103 | pid_select = 0;
1104 | pid_line_y = pid_line_y_trg = 1;
1105 | pid_box_y = pid_box_y_trg = 0;
1106 | pid_box_width = pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2;
1107 | }
1108 | else if(modelchooese==0){
1109 |
1110 | //json
1111 | Serial.println("json in");
1112 | UserIn = pid[pid_select].select;
1113 | addPassword(SiteIn, UserIn);
1114 | ui_index = M_ABOUT;
1115 |
1116 | } else if(modelchooese==3){
1117 |
1118 | //json
1119 | Serial.println("totp in");
1120 | UserIn = pid[pid_select].select;
1121 | addPassword(SiteIn, UserIn);
1122 | ui_index = M_ABOUT;
1123 |
1124 | }else if (modelchooese == 4) {
1125 | Serial.println("at seting--------------------------------------------!!!!!!!!!!!!!!");
1126 | Serial.println(pid_select);
1127 | switch (pid_select) {
1128 | case 0:
1129 | display_time=60000;
1130 | modelchooese = 2;
1131 | ui_state = S_DISAPPEAR;
1132 | ui_index = M_SELECT;
1133 | break;
1134 | case 1:
1135 | display_time=300000;
1136 | modelchooese = 2;
1137 | ui_state = S_DISAPPEAR;
1138 | ui_index = M_SELECT;
1139 | break;
1140 | case 2:
1141 | display_time=0;
1142 | modelchooese = 2;
1143 | ui_state = S_DISAPPEAR;
1144 | ui_index = M_SELECT;
1145 | break;
1146 | // u8g2.setContrast(50);
1147 | }
1148 | }else if (modelchooese == 5) {
1149 | Serial.println("at seting--------------------------------------------!!!!!!!!!!!!!!");
1150 | Serial.println(pid_select);
1151 | switch (pid_select) {
1152 | case 0:
1153 | u8g2.setContrast(0);
1154 | modelchooese = 2;
1155 | ui_state = S_DISAPPEAR;
1156 | ui_index = M_SELECT;
1157 |
1158 |
1159 | break;
1160 |
1161 | case 1:
1162 | u8g2.setContrast(100);
1163 | modelchooese = 2;
1164 | ui_state = S_DISAPPEAR;
1165 | ui_index = M_SELECT;
1166 | break;
1167 |
1168 | case 2:
1169 | u8g2.setContrast(200);
1170 | modelchooese = 2;
1171 | ui_state = S_DISAPPEAR;
1172 | ui_index = M_SELECT;
1173 | break;
1174 |
1175 | }
1176 | }else if (modelchooese == 6) {
1177 | Serial.println("at seting--------------------------------------------!!!!!!!!!!!!!!");
1178 | Serial.println(pid_select);
1179 | switch (pid_select) {
1180 | case 0:
1181 | bleKeyboard.begin();
1182 | modelchooese = 2;
1183 | ui_state = S_DISAPPEAR;
1184 | ui_index = M_SELECT;
1185 |
1186 |
1187 | break;
1188 |
1189 | case 1:
1190 | bleKeyboard.end();
1191 | modelchooese = 2;
1192 | ui_state = S_DISAPPEAR;
1193 | ui_index = M_SELECT;
1194 | break;
1195 |
1196 |
1197 |
1198 | }
1199 | }
1200 | break;
1201 | default:
1202 | break;
1203 | }
1204 | pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2;
1205 | }
1206 | }
1207 | // 函数原型声明
1208 | void addUser(char* mainnowdisplay);
1209 | int justonece=0;
1210 | void select_proc(void)//选择界面处理重要的
1211 | {
1212 | if (key_msg.pressed)
1213 | {
1214 | key_msg.pressed = false;
1215 | switch (key_msg.id)
1216 | {
1217 | case 0:
1218 | if (ui_select < 1) break;
1219 | ui_select -= 1;
1220 | line_y_trg -= single_line_length;
1221 | if (ui_select < -(y / 16))
1222 | {
1223 | y_trg += 16;
1224 | }
1225 | else
1226 | {
1227 | box_y_trg -= 16;
1228 | }
1229 |
1230 | break;
1231 | case 1:
1232 | if ((ui_select + 2) > listSize) break;//变更菜单数组个数3
1233 | ui_select += 1;
1234 | line_y_trg += single_line_length;
1235 | if ((ui_select + 1) > (4 - y / 16))
1236 | {
1237 | y_trg -= 16;
1238 | }
1239 | else
1240 | {
1241 | box_y_trg += 16;
1242 | }
1243 |
1244 | break;
1245 | case 2:
1246 | Serial.println("ui_select");
1247 | switch (ui_select)
1248 | {
1249 | case 0: //return
1250 | ui_state = S_DISAPPEAR; //S_DISAPPEAR;
1251 | ui_index = M_ICON;//M_LOGO;
1252 | break;
1253 | // case 1: //pid
1254 | // addUser(list[ui_select].select);
1255 | // ui_state = S_DISAPPEAR;
1256 | // ui_index = M_PID;
1257 | // break;
1258 | // case 2: //icon
1259 | // ui_state = S_DISAPPEAR;
1260 | // ui_index = M_ICON;
1261 | // break;
1262 | // case 3: //chart
1263 | // ui_state = S_DISAPPEAR;
1264 | // ui_index = M_CHART;
1265 | // break;
1266 | // case 4: //textedit
1267 | // ui_state = S_DISAPPEAR;
1268 | // ui_index = M_TEXT_EDIT;
1269 | // break;
1270 | // case 6: //about
1271 | // ui_state = S_DISAPPEAR;
1272 | // ui_index = M_ABOUT;
1273 | // break;
1274 | // case 7: //about
1275 | // ui_state = S_DISAPPEAR;
1276 | // ui_index = M_ABOUT;
1277 | // break;
1278 | // case 8: //about
1279 | // ui_state = S_DISAPPEAR;
1280 | // ui_index = M_ABOUT;
1281 | // break;
1282 | default: {
1283 | Serial.println("modelchooese");
1284 | Serial.println(modelchooese);
1285 | if (modelchooese == 0) {
1286 | SiteIn = list[ui_select].select;
1287 | // if(justonece==0) {//防止重复向数组写入导致内存浪费溢出
1288 | addUser(list[ui_select].select);
1289 | // justonece+=1;
1290 | // }
1291 | pid_box_width = pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2;//两边各多2
1292 | ui_state = S_DISAPPEAR;
1293 | ui_index = M_PID;
1294 | break;
1295 | } else if (modelchooese == 1){
1296 | // list[ui_select].select
1297 | //txt
1298 | ui_state = S_DISAPPEAR;
1299 | File file = SD.open("/"+(String)list[ui_select].select+".txt");
1300 | if (file) {
1301 | while (file.available()) {
1302 | textContent += (char)file.read();
1303 | }
1304 | file.close();
1305 | } else {
1306 | Serial.println("无法打开文件");
1307 | }
1308 |
1309 | // 计算总页数
1310 | totalPages = ceil((float)textContent.length() / (DISPLAY_ROWS * CHARACTERS_PER_LINE));
1311 |
1312 | Serial.println("txt connte");
1313 | Serial.println("txt in");
1314 |
1315 | ui_index = M_TXTREAD;
1316 |
1317 | break;
1318 | } else if (modelchooese == 2) {
1319 |
1320 | Serial.print("NOW:");
1321 | Serial.println(list[ui_select].select);
1322 | ui_state = S_DISAPPEAR;
1323 | ui_index = M_SET;
1324 | }else if (modelchooese == 3) {
1325 | SiteIn = list[ui_select].select;
1326 | // if(justonece==0) {//防止重复向数组写入导致内存浪费溢出
1327 | addUser(list[ui_select].select);
1328 | // justonece+=1;
1329 | // }
1330 | pid_box_width = pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2;//两边各多2
1331 | ui_state = S_DISAPPEAR;
1332 | ui_index = M_PID;
1333 | break;
1334 | // Serial.print("NOW:");
1335 | // Serial.println(list[ui_select].select);
1336 | // ui_state = S_DISAPPEAR;
1337 | // ui_index = M_TOTF;
1338 | }
1339 | }
1340 | }
1341 |
1342 | //Serial.println("Btn2");
1343 | default:
1344 | break;
1345 | }
1346 | Serial.println("ui_select------------------test");
1347 | Serial.println(ui_select);
1348 | Serial.println(list[ui_select].select);
1349 | box_width_trg = u8g2.getStrWidth(list[ui_select].select) + x * 2;
1350 | }
1351 | select_ui_show();
1352 | }
1353 | int WIFIst=0;
1354 |
1355 | long epochTime;
1356 | void setting(int select){
1357 | switch (select) {
1358 | case 1:
1359 | free(pid);
1360 | pid = NULL;
1361 | pidSize=3;//此值自增1才可出返回设置//此值存在问题,需要修复!超出4则UI错误
1362 | modelchooese = 6;
1363 |
1364 |
1365 | pid = (SELECT_LIST*)malloc(pidSize * sizeof(SELECT_LIST));
1366 | pid[0].select =strdup("ON BLE");
1367 | pid[1].select =strdup("OFF BLE");
1368 | pid[2].select =strdup("Back");
1369 | pid_box_width = pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2;//两边各多2
1370 | ui_state = S_DISAPPEAR;
1371 | ui_index = M_PID;
1372 | break;
1373 | case 2://时间同步模式
1374 | // Serial.begin(115200);
1375 | u8g2.drawStr(2, 12, "Wait WIFI CONNECT!");
1376 | if(WIFIst==0) {
1377 | WiFi.begin(ssid, password);
1378 | if (WiFi.status() == WL_CONNECTED) {
1379 | timeClient.forceUpdate();
1380 | epochTime = timeClient.getEpochTime();
1381 | WiFi.disconnect();
1382 | u8g2.drawStr(2, 44, "Can not connect!");
1383 | WIFIst=1;
1384 | }else{
1385 | u8g2.drawStr(2, 44, "Was connect!");
1386 | }
1387 |
1388 | }
1389 | Serial.println("Epoch Time: " + String(epochTime));
1390 |
1391 |
1392 |
1393 | break;
1394 | case 3://密码设置模式
1395 | ui_state = S_DISAPPEAR;
1396 | ui_index = M_TEXT_EDIT;
1397 | break;
1398 | case 4:
1399 | free(pid);
1400 | pid = NULL;
1401 | pidSize=4;//此值自增1才可出返回设置//此值存在问题,需要修复!超出4则UI错误
1402 | modelchooese = 5;
1403 |
1404 |
1405 | pid = (SELECT_LIST*)malloc(pidSize * sizeof(SELECT_LIST));
1406 | pid[0].select =strdup("10%");
1407 |
1408 | // pid[2].select =strdup("10min");//未知,缺少size函数
1409 | pid[1].select =strdup("50%");
1410 |
1411 | pid[2].select =strdup("100%");
1412 | pid[3].select =strdup("Back");
1413 | pid_box_width = pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2;//两边各多2
1414 | ui_state = S_DISAPPEAR;
1415 | ui_index = M_PID;
1416 | break;
1417 |
1418 | case 5://息屏时长设置(该功能有待完善,主要体现在息屏时间判断不完善)
1419 | free(pid);
1420 | pid = NULL;
1421 | pidSize=4;//此值自增1才可出返回设置
1422 |
1423 | modelchooese=4;
1424 |
1425 | pid = (SELECT_LIST*)malloc(pidSize * sizeof(SELECT_LIST));
1426 | pid[0].select =strdup("1min");
1427 | pid[1].select =strdup("5min");
1428 | // pid[2].select =strdup("10min");//未知,缺少size函数
1429 | pid[2].select =strdup("Never");
1430 | pid[3].select =strdup("Back");
1431 | pid_box_width = pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2;//两边各多2
1432 | ui_state = S_DISAPPEAR;
1433 | ui_index = M_PID;
1434 | break;
1435 | case 6://升级功能(待实现)
1436 | // ui_state = S_DISAPPEAR;
1437 | u8g2.drawStr(2,12,"Not Find New DATA !");
1438 | // u8g2.drawStr(2,28,"FLASH : 4MB");
1439 | u8g2.drawStr(2,44,"Press any key go back");
1440 | // u8g2.drawStr(2,60,"Firmware : V3.0");
1441 | break;
1442 | case 7://展示设备信息
1443 | ui_state = S_DISAPPEAR;
1444 | ui_index = M_ABOUTDEV;
1445 | break;
1446 | default:
1447 | Serial.println("now is default");
1448 | break;
1449 | }
1450 |
1451 | }
1452 | void set_proc(){
1453 | setting(ui_select);
1454 | Serial.println("txgog11111111111111ogote");
1455 | if (key_msg.pressed)
1456 | {
1457 | key_msg.pressed = false;
1458 | switch (key_msg.id)
1459 | {
1460 | case 2: {
1461 | //按键操作已经在setting内实现
1462 | // writeCSV();存在危险操作,建议提高延迟,否则易损卡
1463 | }
1464 | default:
1465 | ui_state = S_DISAPPEAR;
1466 | ui_index = M_SELECT;
1467 |
1468 | break;
1469 |
1470 | }
1471 | }
1472 |
1473 | }
1474 | void black_proc(){
1475 |
1476 | // setting(ui_select);
1477 | // Serial.println("txgog11111111111111ogote");
1478 | if (key_msg.pressed)
1479 | {
1480 | key_msg.pressed = false;
1481 | switch (key_msg.id)
1482 | {
1483 | case 2: {
1484 |
1485 | // writeCSV();存在危险操作,建议提高延迟,否则易损卡
1486 | }
1487 | default:
1488 | ui_state = S_DISAPPEAR;
1489 | ui_index = M_LOGO;
1490 |
1491 | break;
1492 |
1493 | }
1494 | }
1495 |
1496 | }
1497 | long GMT;
1498 |
1499 | char code[6];
1500 | void TOTF_proc(char* site, char* totpkey) {
1501 | TOTP totp = TOTP();
1502 | // 调整大小以容纳空终止符
1503 | char *newCode = totp.getCode(totpkey, 30, timeClient.getEpochTime());
1504 |
1505 | // 检查 newCode 是否有效
1506 |
1507 | strcpy(code, newCode);
1508 | Serial.println(GMT);
1509 | Serial.print("---> CODE[");
1510 | Serial.print(code);
1511 |
1512 | int screenWidth = u8g2.getWidth();
1513 | int textWidth = u8g2.getStrWidth(site);
1514 | int x = (screenWidth - textWidth) / 2;
1515 | int y = 20; // 垂直位置
1516 | int textWidth2 = u8g2.getStrWidth(code);
1517 | int x2 = (screenWidth - textWidth2) / 2;
1518 |
1519 | u8g2.drawStr(x, y, site);
1520 | u8g2.drawStr(x2, y + 20, code);
1521 | // bleKeyboard.print(code);
1522 | // 连接到 Wi-Fi
1523 |
1524 | Serial.print("---> CODE[");
1525 |
1526 | }
1527 |
1528 | void allcount();
1529 | void addSiteDataToArr();
1530 | void icon_proc(void)//icon界面处理
1531 | {
1532 | icon_ui_show();
1533 | if (key_msg.pressed)
1534 | {
1535 | key_msg.pressed = false;
1536 | switch (key_msg.id)
1537 | {
1538 | case 1:
1539 | if (icon_select != (icon_num - 1))
1540 | {
1541 | icon_select += 1;
1542 | app_y_trg += 16;
1543 | icon_x_trg -= ICON_SPACE;
1544 | }
1545 | break;
1546 | case 0:
1547 |
1548 | if (icon_select != 0)
1549 | {
1550 | icon_select -= 1;
1551 | app_y_trg -= 16;
1552 | icon_x_trg += ICON_SPACE;
1553 | }
1554 | break;
1555 | case 2://2代表按下Mid按键
1556 |
1557 |
1558 | switch (icon_select) {
1559 | case 0: ui_state = S_DISAPPEAR;//主界面
1560 | ui_index = M_LOGO;
1561 | break;
1562 | case 1: {//密钥模式,用于展示TF卡内的json格式密钥文件
1563 | modelchooese=0;
1564 | allcount();
1565 | addSiteDataToArr();
1566 | list[0].select = strdup("HOME");//插入主界面返回按键,此按键应当固定于数组首位
1567 |
1568 | box_width = box_width_trg = u8g2.getStrWidth(list[ui_select].select) + x * 2;//两边各多2
1569 |
1570 | // pid = (SELECT_LIST*)malloc(pidSize * sizeof(SELECT_LIST));
1571 | // pid[0].select = strdup("main");
1572 | // 动态分配内存以存储结构体数组
1573 |
1574 | qsort(list + 1, listSize - 1, sizeof(SELECT_LIST), compare);
1575 |
1576 | // 在串口上打印按照字母顺序排序后的结果
1577 | for (int i = 0; i < listSize; i++) {
1578 | Serial.println(list[i].select);
1579 | }
1580 | ui_state = S_DISAPPEAR;
1581 | ui_index = M_SELECT;
1582 |
1583 | break;
1584 | }
1585 | case 2://TOTP模式,建议设计参考1,Webkey调用json
1586 | modelchooese=3;
1587 | allcount();
1588 | addSiteDataToArr();
1589 | list[0].select = strdup("HOME");//插入主界面返回按键,此按键应当固定于数组首位
1590 |
1591 | box_width = box_width_trg = u8g2.getStrWidth(list[ui_select].select) + x * 2;//两边各多2
1592 |
1593 | // pid = (SELECT_LIST*)malloc(pidSize * sizeof(SELECT_LIST));
1594 | // pid[0].select = strdup("main");
1595 | // 动态分配内存以存储结构体数组
1596 |
1597 | qsort(list + 1, listSize - 1, sizeof(SELECT_LIST), compare);
1598 |
1599 | // 在串口上打印按照字母顺序排序后的结果
1600 | for (int i = 0; i < listSize; i++) {
1601 | Serial.println(list[i].select);
1602 | }
1603 | ui_state = S_DISAPPEAR;
1604 | ui_index = M_SELECT;
1605 |
1606 | break;
1607 | case 3://文档模式,用于展示TF卡内的TXT文件及内容
1608 | // ui_state = S_DISAPPEAR;
1609 | // ui_index = M_IMPORT;
1610 | modelchooese=1;
1611 | allcount();
1612 | addSiteDataToArr();
1613 | list[0].select = strdup("HOME");//同1
1614 |
1615 | box_width = box_width_trg = u8g2.getStrWidth(list[ui_select].select) + x * 2;//两边各多2
1616 |
1617 | // pid = (SELECT_LIST*)malloc(pidSize * sizeof(SELECT_LIST));
1618 | // pid[0].select = strdup("main");
1619 | // 动态分配内存以存储结构体数组
1620 |
1621 | qsort(list + 1, listSize - 1, sizeof(SELECT_LIST), compare);
1622 |
1623 | // 在串口上打印按照字母顺序排序后的结果
1624 | for (int i = 0; i < listSize; i++) {
1625 | Serial.println(list[i].select);
1626 | }
1627 | ui_state = S_DISAPPEAR;
1628 | ui_index = M_SELECT;
1629 |
1630 | break;
1631 | case 4://设置模式(可进行方法归类)
1632 | // ui_state = S_DISAPPEAR;
1633 | // ui_index = M_IMPORT;
1634 | Serial.println("ui_select11");
1635 | modelchooese=2;
1636 | listSize=8;
1637 | Serial.println("ui_select22");
1638 | free(list);
1639 | list = NULL;
1640 | list = (SELECT_LIST*)malloc(listSize * sizeof(SELECT_LIST));
1641 | list[0].select = strdup("HOME");
1642 | list[1].select = strdup("BLE Connect");
1643 | list[2].select = strdup("Updata Time");
1644 | list[3].select = strdup("Password");//插入功能按键
1645 | list[4].select = strdup("Back light");
1646 | list[5].select = strdup("Display Time");
1647 | list[6].select = strdup("Updata");
1648 | list[7].select = strdup("About");
1649 |
1650 | Serial.println("ui_selectsadad");
1651 | pid_box_width = pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2;//两边各多2
1652 | box_width = box_width_trg = u8g2.getStrWidth(list[ui_select].select) + x * 2;//两边各多2
1653 | Serial.println("ui_select33");
1654 | // pid = (SELECT_LIST*)malloc(pidSize * sizeof(SELECT_LIST));
1655 | // pid[0].select = strdup("main");
1656 | // 动态分配内存以存储结构体数组
1657 |
1658 | // qsort(list + 1, listSize - 1, sizeof(SELECT_LIST), compare);
1659 | Serial.println("ui_select33");
1660 | // 在串口上打印按照字母顺序排序后的结果
1661 | for (int i = 0; i < listSize; i++) {
1662 | Serial.println(list[i].select);
1663 | }
1664 | ui_state = S_DISAPPEAR;
1665 | ui_index = M_SELECT;
1666 | Serial.println("ui_select3366");
1667 | break;
1668 | case 5://锁屏模式
1669 | if(Passwordis[0] != '\0'){//未设置密码时
1670 | passwordst=1;
1671 | }
1672 | ui_state = S_DISAPPEAR;//息屏
1673 | ui_index = M_BLACK;
1674 | break;
1675 | }
1676 | Serial.println("button press");//调试输出
1677 | Serial.println(icon_select);
1678 | Serial.println(icon_x);
1679 | Serial.println( app_y);
1680 | Serial.println("num to zero");
1681 | icon_select = 0;
1682 | icon_x = icon_x_trg = 0;
1683 | app_y = app_y_trg = 0;
1684 |
1685 |
1686 | break;
1687 | default:
1688 | break;
1689 | }
1690 | }
1691 | }
1692 |
1693 | //void chart_proc()//chart界面处理函数
1694 | //{
1695 | // chart_ui_show();
1696 | // if (key_msg.pressed)
1697 | // {
1698 | // key_msg.pressed = false;
1699 | // ui_state = S_DISAPPEAR;
1700 | // ui_index = M_SELECT;
1701 | // frame_is_drawed = false;//退出后框架为未画状态
1702 | // chart_x = 0;
1703 | // }
1704 | //}
1705 | void passwordmode(){
1706 | for (int i = 0; i < 6; i++) {
1707 | if (name[i] != '\0') {//输入不为空
1708 |
1709 |
1710 | if (passwordst == 0) {//未设置密码状态下设置密码
1711 | strcpy(Passwordis, name);//密码等于输入
1712 | passwordst=1;
1713 | ui_state = S_DISAPPEAR;
1714 | ui_index = M_LOGO;
1715 | }else if (passwordst == 1&&strcmp(name, Passwordis) == 0) {//设备解锁,存在密码切密码等于输入
1716 | passwordst=0;
1717 | ui_state = S_DISAPPEAR;
1718 | ui_index = M_ICON;
1719 |
1720 | }else if (passwordst == 1&&strcmp(name, Passwordis) != 0) {//密码错误,设备不解锁,存在密码,密码不等于输入
1721 | ui_state = S_DISAPPEAR;
1722 | ui_index = M_LOGO;
1723 | }
1724 | break;
1725 |
1726 | }else{//输入为空状态下
1727 |
1728 |
1729 | if (passwordst == 0) {//未设置密码
1730 | ui_state = S_DISAPPEAR;
1731 | ui_index = M_LOGO;
1732 | }else{//输入为空且设置密码状态下
1733 | // Passwordis[0]='\0';//首位为空
1734 | memset(name, '\0', sizeof(Passwordis));//密码初始化,取消密码设置
1735 | ui_state = S_DISAPPEAR;
1736 | ui_index = M_LOGO;
1737 | }
1738 |
1739 | }
1740 | }
1741 | }
1742 | void text_edit_proc()
1743 | {
1744 | // memset(name, '\0', sizeof(name));
1745 | text_edit_ui_show();
1746 | if (key_msg.pressed)
1747 | {
1748 | key_msg.pressed = false;
1749 | switch (key_msg.id)
1750 | {
1751 | case 0:
1752 | if (edit_flag)
1753 | {
1754 | //编辑
1755 | text_edit(false, edit_index);
1756 | }
1757 | else
1758 | {
1759 | if (edit_index == 0)
1760 | {
1761 | edit_index = name_len;
1762 | }
1763 | else
1764 | {
1765 | edit_index -= 1;
1766 | }
1767 | }
1768 | break;
1769 | case 1:
1770 | if (edit_flag)
1771 | {
1772 | //编辑
1773 | text_edit(true, edit_index);
1774 | }
1775 | else
1776 | {
1777 | if (edit_index == name_len)
1778 | {
1779 | edit_index = 0;
1780 | }
1781 | else
1782 | {
1783 | edit_index += 1;
1784 | }
1785 | }
1786 | break;
1787 | case 2:
1788 | if (edit_index == name_len) {
1789 |
1790 |
1791 |
1792 | passwordmode();
1793 | edit_index = 0;
1794 | blink_flag = 0;
1795 | memset(name, '\0', 6);
1796 | }
1797 | else
1798 | {
1799 | edit_flag = !edit_flag;
1800 | }
1801 | break;
1802 | default:
1803 |
1804 | break;
1805 | }
1806 | }
1807 | }
1808 | void about_ui_show()//about界面
1809 | {
1810 | if(modelchooese==0) {
1811 | // std::string SiteStr = SiteIn;
1812 | Serial.println("PUSH---------");
1813 | Serial.println(SiteIn);
1814 | Serial.println(UserIn);
1815 | Serial.println(passwordIn);
1816 | std::string SiteStr = SiteIn;
1817 | // Concatenate the strings
1818 | std::string SiteString = "Site: " + SiteStr;
1819 | std::string UserStr = UserIn;
1820 |
1821 | // Concatenate the strings
1822 | std::string UserString = "User: " + UserStr;
1823 |
1824 | u8g2.drawStr(2, 12, SiteString.c_str());
1825 | u8g2.drawStr(2, 28, UserString.c_str());
1826 |
1827 | u8g2.drawStr(2, 60, "---Press to Driver---");
1828 |
1829 | }else if (modelchooese==3){
1830 |
1831 |
1832 | TOTF_proc(SiteIn,passwordIn);
1833 |
1834 | }
1835 |
1836 | // u8g2.drawStr(2,12,"MCU : MEGA2560");
1837 | // u8g2.drawStr(2,28,"FLASH : 256KB");
1838 | // u8g2.drawStr(2,44,"SRAM : 8KB");
1839 | // u8g2.drawStr(2,60,"EEPROM : 4KB");
1840 |
1841 | }
1842 | void about_proc()//about界面处理函数
1843 | {
1844 | if (key_msg.pressed) {
1845 |
1846 | if (modelchooese == 0) {//预留蓝牙输入接口
1847 | if (bleKeyboard.isConnected()) {
1848 | Serial.println("Sending 'Hello world'...");
1849 | bleKeyboard.print(UserIn);
1850 | }
1851 | key_msg.pressed = false;
1852 | ui_state = S_DISAPPEAR;
1853 | ui_index = M_ABOUT_pass;
1854 | } else if (modelchooese == 3) {
1855 | if (bleKeyboard.isConnected()) {
1856 | Serial.println("Sending 'Hello world'...");
1857 | bleKeyboard.print(code);
1858 | }
1859 | key_msg.pressed = false;
1860 |
1861 | modelchooese = 3;
1862 | ui_state = S_DISAPPEAR;
1863 | ui_index = M_SELECT;
1864 |
1865 |
1866 | } else {
1867 | key_msg.pressed = false;
1868 | ui_state = S_DISAPPEAR;
1869 | ui_index = M_SELECT;
1870 | }
1871 | }
1872 | about_ui_show();
1873 | }
1874 | void about_pass_ui_show(){
1875 | std::string PasswordStr = passwordIn;
1876 | // Concatenate the strings
1877 | std::string PasswordString = "Password: " + PasswordStr;
1878 | u8g2.drawStr(2, 44, PasswordString.c_str());
1879 |
1880 | }
1881 | void about_pass_proc(){
1882 | if (key_msg.pressed)
1883 | {
1884 | key_msg.pressed = false;
1885 | switch (key_msg.id)
1886 | {
1887 |
1888 | default:
1889 | if(bleKeyboard.isConnected()) {//预留蓝牙输入接口
1890 | Serial.println("Sending 'Hello world'...");
1891 | bleKeyboard.print(passwordIn);
1892 | }
1893 | ui_state = S_DISAPPEAR;
1894 | ui_index = M_SELECT;
1895 | break;
1896 |
1897 | }
1898 | }
1899 | about_pass_ui_show();
1900 | }
1901 | void aboutdev_proc()//about界面处理函数
1902 | {
1903 | if (key_msg.pressed)
1904 | {
1905 | key_msg.pressed = false;
1906 | ui_state = S_DISAPPEAR;
1907 | ui_index = M_SELECT;
1908 | }
1909 | aboutdev_ui_show();
1910 | }
1911 | void import_proc()//about界面处理函数
1912 | {
1913 | u8g2.setFont(u8g2_font_ncenB08_tr);
1914 | u8g2.setCursor(0, 10);
1915 | u8g2.drawStr(2,12,"PLEASE PUSH");
1916 | u8g2.println("IF YOU ARE RIGHT");
1917 |
1918 | if (key_msg.pressed)
1919 | {
1920 | key_msg.pressed = false;
1921 | switch (key_msg.id)
1922 | {
1923 | case 2: {
1924 | ui_state = S_DISAPPEAR;
1925 |
1926 | u8g2.firstPage();
1927 |
1928 | u8g2.setFont(u8g2_font_ncenB08_tr);
1929 | u8g2.setCursor(0, 10);
1930 | u8g2.println("Now WILL RUN");
1931 |
1932 | delay(5000); // 继续等待5秒
1933 | // writeCSV();存在危险操作,建议提高延迟,否则易损卡
1934 | }
1935 | default:
1936 | ui_state = S_DISAPPEAR;
1937 | ui_index = M_ICON;
1938 | break;
1939 |
1940 | }
1941 | }
1942 | // delay(5000); // 等待5秒
1943 |
1944 |
1945 | }
1946 | void txtred_proc(){
1947 |
1948 |
1949 | Serial.println("txt wait");
1950 | drawPage(currentPage);
1951 | Serial.print("当前页码: ");
1952 | Serial.println(currentPage);
1953 | // delay(200);
1954 | // delay(200);
1955 |
1956 | if (key_msg.pressed)
1957 | {
1958 | key_msg.pressed = false;
1959 | switch (key_msg.id)
1960 | {
1961 | case 0: {
1962 | currentPage--;
1963 | break;
1964 | // writeCSV();存在危险操作,建议提高延迟,否则易损卡
1965 | }
1966 | case 1: {
1967 | currentPage++;
1968 | if (currentPage >= totalPages) {
1969 | currentPage = 0;
1970 | }
1971 | break;
1972 | // writeCSV();存在危险操作,建议提高延迟,否则易损卡
1973 | }
1974 | case 2:
1975 | ui_state = S_DISAPPEAR;
1976 | ui_index = M_SELECT;
1977 | currentPage=0;
1978 | textContent="";
1979 |
1980 | break;
1981 |
1982 | }
1983 | }
1984 |
1985 | }
1986 |
1987 | /********************************总的UI显示************************************/
1988 |
1989 | void ui_proc()//总的UI进程
1990 | {
1991 | switch (ui_state)
1992 | {
1993 | case S_NONE:
1994 | if (ui_index != M_CHART) u8g2.clearBuffer();
1995 | switch (ui_index)
1996 | {
1997 | case M_LOGO:
1998 | logo_proc();
1999 | break;
2000 | case M_SELECT:
2001 | select_proc();
2002 | break;
2003 | case M_PID:
2004 | pid_proc();
2005 | break;
2006 | case M_ICON:
2007 | icon_proc();
2008 | break;
2009 | // case M_CHART:
2010 | // chart_proc();
2011 | // break;
2012 | case M_TEXT_EDIT:
2013 | text_edit_proc();
2014 | break;
2015 | case M_PID_EDIT:
2016 | pid_edit_proc();
2017 | break;
2018 | case M_ABOUT:
2019 |
2020 | about_proc();
2021 | break;
2022 | case M_ABOUT_pass:
2023 |
2024 | about_pass_proc();
2025 | break;
2026 | case M_ABOUTDEV:
2027 |
2028 | aboutdev_proc();
2029 | break;
2030 | case M_IMPORT:
2031 | import_proc();
2032 | break;
2033 | case M_TXTREAD:
2034 | txtred_proc();
2035 | break;
2036 | case M_SET:
2037 | set_proc();
2038 | break;
2039 | case M_BLACK:
2040 | black_proc();
2041 | break;
2042 | // case M_TOTF:
2043 | // TOTF_proc(String site,String totpkey);
2044 | // break;
2045 | default:
2046 | break;
2047 | }
2048 | break;
2049 | case S_DISAPPEAR:
2050 | disappear();
2051 | break;
2052 | default:
2053 | break;
2054 | }
2055 | u8g2.sendBuffer();
2056 | }
2057 |
2058 |
2059 | // 比较函数,用于对字符串进行排序
2060 |
2061 |
2062 | void addUser(char* mainnowdisplay){
2063 | free(pid);
2064 | pid = NULL;
2065 | Serial.println("Btn2----------------------");
2066 | Serial.println(mainnowdisplay);
2067 |
2068 | String filePath;
2069 | if(modelchooese==0){
2070 | filePath = String("/") + String(mainnowdisplay)+String(".web");
2071 | }else if(modelchooese==3){
2072 | filePath = String("/") + String(mainnowdisplay)+String(".totp");
2073 | }
2074 | // 打开 data.json 文件
2075 | File jsonFile = SD.open(filePath);
2076 | if (!jsonFile) {
2077 | Serial.println("无法打开 data.json 文件");
2078 | return;
2079 | }
2080 |
2081 | String jsonStr;
2082 | while (jsonFile.available()) {
2083 | char c = jsonFile.read();
2084 | jsonStr += c;
2085 | }
2086 |
2087 | // 关闭文件
2088 | jsonFile.close();
2089 |
2090 | // 解析JSON数据
2091 | DynamicJsonDocument doc(1024);
2092 | DeserializationError error = deserializeJson(doc, jsonStr);
2093 |
2094 | if (error) {
2095 | Serial.println("解析JSON失败");
2096 | return;
2097 | }
2098 | int numx=0;
2099 | // 仅输出JSON键而不输出值
2100 | for (JsonPair keyValue : doc.as()) {
2101 |
2102 | numx++;
2103 | }
2104 | Serial.print("numx------------xxx: ");
2105 | Serial.println(numx);
2106 |
2107 | pidSize=numx+1;//此值自增1才可出返回设置
2108 |
2109 |
2110 |
2111 | pid = (SELECT_LIST*)malloc(pidSize * sizeof(SELECT_LIST));
2112 |
2113 | int num=0;
2114 | // 仅输出JSON键而不输出值
2115 | for (JsonPair keyValue : doc.as()) {
2116 | Serial.print("键: ");
2117 | Serial.println(keyValue.key().c_str());
2118 | pid[num].select =strdup(keyValue.key().c_str());
2119 | num++;
2120 | }
2121 | pid[num].select =strdup("Back");
2122 | qsort(pid, pidSize, sizeof(SELECT_LIST), compare2);
2123 |
2124 | // 在串口上打印按照字母顺序排序后的结果
2125 | // for (int i = 0; i < pidSize; i++) {
2126 | // Serial.println(pid[i].select);
2127 | // }
2128 |
2129 | // pid[4].select =strdup("keyVal");
2130 | Serial.println( "pid[3].select");
2131 | // Serial.println( pid[2].select);
2132 | // Serial.println( pid[3].select);
2133 |
2134 | }
2135 |
2136 | void addPassword(char* mainsite,char* mainuser){
2137 | String filePath;
2138 | if(modelchooese==0){
2139 | filePath = String("/") + String(mainsite)+String(".web");
2140 | }else if(modelchooese==3){
2141 | filePath = String("/") + String(mainsite)+String(".totp");
2142 | }
2143 | // String filePath = String("/") + String(mainsite)+String(".web");
2144 | // 打开 data.json 文件
2145 | File jsonFile = SD.open(filePath);
2146 |
2147 | if (!jsonFile) {
2148 | Serial.println("无法打开文件");
2149 | return;
2150 | }
2151 |
2152 | // 读取文件内容
2153 | String jsonStr;
2154 | while (jsonFile.available()) {
2155 | char c = jsonFile.read();
2156 | jsonStr += c;
2157 | }
2158 |
2159 | // 关闭文件
2160 | jsonFile.close();
2161 |
2162 | // 解析 JSON 数据
2163 | DynamicJsonDocument doc(1024);
2164 | DeserializationError error = deserializeJson(doc, jsonStr);
2165 |
2166 | if (error) {
2167 | Serial.println("解析 JSON 失败");
2168 | return;
2169 | }
2170 | Serial.println("read----");
2171 | Serial.println(mainuser);
2172 | // 提取并输出 location 字段的值
2173 | const char* location = doc[mainuser];
2174 | Serial.println("read----");
2175 | Serial.println(location);
2176 | // Convert String to char* and store in Site
2177 | passwordIn = strdup(location);
2178 | Serial.println("password--------");
2179 | Serial.println(passwordIn);
2180 | Serial.println("password--------");
2181 |
2182 |
2183 |
2184 | }
2185 |
2186 | void allcount(){
2187 | char* model=".web";
2188 | if(modelchooese==0){
2189 | model=".web";
2190 | }else if(modelchooese==1){
2191 | model=".txt";
2192 | }else if(modelchooese==3){
2193 | model=".totp";
2194 | }
2195 |
2196 | File root = SD.open("/");
2197 | int count=0;
2198 | while (true) {
2199 | File entry = root.openNextFile();
2200 | if (!entry) {
2201 | // 没有更多文件
2202 | break;
2203 | }
2204 |
2205 | if (!entry.isDirectory() && entry.name()[0] != '.') {
2206 | String filename = entry.name();
2207 | if (filename.endsWith( model)) {
2208 | count++;
2209 | }
2210 | }
2211 |
2212 | entry.close();
2213 | }
2214 |
2215 | root.close();
2216 | listSize=count+1;
2217 | }
2218 | void addSiteDataToArr() {//此函数提供方法使其全部网站保存在数组中,界面分类用
2219 | free(list);
2220 | list = NULL;
2221 | char* model=".web";
2222 | if(modelchooese==0){
2223 | model=".web";
2224 | }else if(modelchooese==1){
2225 | model=".txt";
2226 | }else if(modelchooese==3){
2227 | model=".totp";
2228 | }
2229 | Serial.println(model);
2230 | Serial.println("read JSON Start:");
2231 | File root = SD.open("/");
2232 | int index = 0; // 用于追踪数组中的索引位置
2233 |
2234 | list = (SELECT_LIST*)malloc(listSize * sizeof(SELECT_LIST));
2235 | int fileCount = 0;//此值传向list 数组长度
2236 | while (true) {
2237 | File entry = root.openNextFile();
2238 | if (!entry) {
2239 | // 没有更多文件
2240 | Serial.println("entry");
2241 | break;
2242 | }
2243 |
2244 | if (!entry.isDirectory() && entry.name()[0] != '.') {
2245 | const char* filename = entry.name();
2246 | if (strstr(filename, model) != NULL) {
2247 | Serial.println(filename);
2248 | // const char* filename = "example.txt"; // 您的文件名
2249 |
2250 | int length = strlen(filename);
2251 |
2252 |
2253 | char* newFilename = new char[length]; // 创建动态分配的新字符串来存储较短的文件名
2254 | if(modelchooese==0) {
2255 | strncpy(newFilename, filename, length - 4);
2256 | newFilename[length - 4] = '\0'; // 添加字符串终止符
2257 | }else if(modelchooese==1){
2258 | strncpy(newFilename, filename, length - 4);
2259 | newFilename[length - 4] = '\0'; // 添加字符串终止符
2260 | }else if(modelchooese==3){
2261 | strncpy(newFilename, filename, length - 5);
2262 | newFilename[length - 5] = '\0'; // 添加字符串终止符
2263 | }
2264 | list[index+1].select = strdup(newFilename);
2265 | index++;
2266 | }
2267 | }
2268 |
2269 | entry.close();
2270 | }
2271 |
2272 | }
2273 | void setup() {//加大审查,尽量关闭sd卡使用时间延长寿命
2274 | Serial.begin(115200);
2275 | Serial.println("Starting BLE work!");
2276 |
2277 |
2278 |
2279 | // 写入数据到 data.json 文件
2280 | // writeJSONToFile();
2281 |
2282 | // 读取并打印 SD 卡上的所有 JSON 文件
2283 | // readAndPrintAllJSONFiles();
2284 | // readJSONFile() ;
2285 |
2286 | Serial.println("entry");
2287 |
2288 | //Wire.begin(21,22,400000);
2289 | pinMode(BTN0, INPUT_PULLUP);
2290 | pinMode(BTN1, INPUT_PULLUP);
2291 | pinMode(BTN2, INPUT_PULLUP);
2292 | key_init();
2293 |
2294 | u8g2.setBusClock(800000);
2295 | u8g2.begin();
2296 | u8g2.setFont(u8g2_font_unifont_t_chinese1);
2297 | //u8g2.setContrast(10);
2298 |
2299 | buf_ptr = u8g2.getBufferPtr();//拿到buffer首地址
2300 | buf_len = 8 * u8g2.getBufferTileHeight() * u8g2.getBufferTileWidth();
2301 |
2302 | x = 4;
2303 | y = y_trg = 0;
2304 | pid_x = 4;
2305 | pid_y = pid_y_trg = 0;
2306 | line_y = line_y_trg = 1;
2307 | pid_line_y = pid_line_y_trg = 1;
2308 | ui_select = pid_select = icon_select = 0;
2309 | icon_x = icon_x_trg = 0;
2310 | app_y = app_y_trg = 0;
2311 |
2312 | u8g2.setFont(u8g2_font_ncenB08_tr);
2313 | ui_index = M_LOGO;
2314 | // ui_index=M_TEXT_EDIT;
2315 | ui_state = S_NONE;
2316 | Serial.println("entry2");
2317 | }
2318 | unsigned long previousMillis = 0;
2319 | //const long interval = 60000; // 5 minutes in milliseconds
2320 | void loop() {
2321 | // Serial.println("entry3");
2322 | unsigned long currentMillis = millis();
2323 | if(display_time!=0) {
2324 | if (currentMillis - previousMillis >= display_time) {
2325 | // 在这里执行您想要每隔5分钟执行的任务
2326 | // 例如,您可以添加要执行的代码块或调用函数
2327 |
2328 | ui_state = S_DISAPPEAR;
2329 | setting(ui_select);
2330 | Serial.println("txgog11111111111111ogote");
2331 | if (key_msg.pressed) {
2332 | key_msg.pressed = false;
2333 | switch (key_msg.id) {
2334 | case 2: {
2335 | // writeCSV();存在危险操作,建议提高延迟,否则易损卡
2336 | }
2337 | default:
2338 | previousMillis = currentMillis;
2339 | ui_state = S_DISAPPEAR;
2340 | ui_index = M_SELECT;
2341 | break;
2342 | }
2343 | }
2344 | // 更新上一次执行任务的时间戳
2345 | }
2346 | }
2347 | key_scan();
2348 | ui_proc();
2349 | }
--------------------------------------------------------------------------------
/test/README:
--------------------------------------------------------------------------------
1 |
2 | This directory is intended for PlatformIO Test Runner and project tests.
3 |
4 | Unit Testing is a software testing method by which individual units of
5 | source code, sets of one or more MCU program modules together with associated
6 | control data, usage procedures, and operating procedures, are tested to
7 | determine whether they are fit for use. Unit testing finds problems early
8 | in the development cycle.
9 |
10 | More information about PlatformIO Unit Testing:
11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
12 |
--------------------------------------------------------------------------------
/tinyuf2-partitions-4MB.csv:
--------------------------------------------------------------------------------
1 | # Name, Type, SubType, Offset, Size, Flags
2 | nvs, data, nvs, 0x9000, 0x5000,
3 | otadata, data, ota, 0xe000, 0x2000,
4 | app0, app, ota_0, 0x10000, 0x200000,
5 | spiffs, data, spiffs, 0x210000,0x1E0000,
6 | coredump, data, coredump,0x3F0000,0x10000,
--------------------------------------------------------------------------------