diff --git a/platformio.ini b/platformio.ini index 78e5a59..433639d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -22,4 +22,12 @@ lib_deps = siara-cc/Sqlite3Esp32 @ ~2.4 # The exact version - siara-cc/Sqlite3Esp32 @ 2.4 \ No newline at end of file + siara-cc/Sqlite3Esp32 @ 2.4 + olikraus/U8g2 @ ^2.35.17 + +# Accept only backwards compatible bug fixes +# (any version with the same major and minor versions, and an equal or greater patch version) + olikraus/U8g2 @ ~2.35.17 + +# The exact version + olikraus/U8g2 @ 2.35.17 \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 990f5cd..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - This example opens Sqlite3 databases from SD Card and - retrieves data from them. - Before running please copy following files to SD Card: - examples/sqlite3_sdmmc/data/mdr512.db - examples/sqlite3_sdmmc/data/census2000names.db - Connections: - * SD Card | ESP32 - * DAT2 - - * DAT3 SS (D5) - * CMD MOSI (D23) - * VSS GND - * VDD 3.3V - * CLK SCK (D18) - * DAT0 MISO (D19) - * DAT1 - -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "SD.h" -//配置数据结构 -using namespace std; -int OutPutTimes; - -String OutPutString = ""; -int keySize; - -struct key { - String user; - String password; -}; - -const char* data = "Callback function called"; -static int callback(void *data, int argc, char **argv, char **azColName){ - int i; - Serial.printf("%s: ", (const char*)data); - OutPutTimes++; - - Serial.println("----------------------"); - for (i = 0; i( "%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); - - // Serial.printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); -// 现在OutPutString包含了格式化后的字符串 - - } - - Serial.printf("\n"); - return 0; -} - -int openDb(const char *filename, sqlite3 **db) { - int rc = sqlite3_open(filename, db); - if (rc) { - Serial.printf("Can't open database: %s\n", sqlite3_errmsg(*db)); - return rc; - } else { - Serial.printf("Opened database successfully\n"); - } - return rc; -} - -char *zErrMsg = 0; -int db_exec(sqlite3 *db, const char *sql) { - Serial.println(sql); - long start = micros(); - int rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg); - if (rc != SQLITE_OK) { - Serial.printf("SQL error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); - } else { - Serial.printf("Operation done successfully\n"); - } - Serial.print(F("Time taken:")); - Serial.println(micros()-start); - - return rc; -} -void removeDuplicates(String arr[], int& n) {//此函数提供方法删除数组内重复的值 - for (int i = 0; i < n; i++) { - for (int j = i + 1; j < n;) { - if (arr[i] == arr[j]) { - for (int k = j; k < n - 1; k++) { - arr[k] = arr[k + 1]; - } - n--; - } else { - j++; - } - } - } -} -void addSiteDataToArr() {//此函数提供方法使其全部网站保存在数组中,界面分类用 - sqlite3 *db1; - - char *zErrMsg = 0; - int rc; - - SPI.begin(); - SD.begin(); - - sqlite3_initialize(); - - // Open database 1 - if (openDb("/sd/key.db", &db1)) - return; - rc = db_exec(db1, "SELECT * FROM site"); - if (rc != SQLITE_OK) { - sqlite3_close(db1); - - return; - } - Serial.println(OutPutString); - - Serial.println("All Have Data Times:"); - const int SiteSize = OutPutTimes; - - String Site[SiteSize];//根据数据长度确认数组长度 - // std::string OutPutString = "id = 1\nsite = example_site_2\nuser = user1\npassword = password1\nid = 2\nsite = example_site_1\nuser = user3\npassword = password1\nid = 3\nsite = example.com\nuser = john_doe\npassword = password123"; - String inputString = OutPutString; // 输入的字符串 - int startIndex = 0; - int endIndex = 0; - - for(int i=0;i= 'a' && name[index] <= 'z')//小写字母 + { + if (name[index] == 'a') + { + name[index] = ' '; + } + else + { + name[index] -= 1; + } + } + else + { + name[index] = 'Z'; + } + } + else + { + if (name[index] >= 'A' && name[index] <= 'Z')//大写字母 + { + if (name[index] == 'Z') + { + name[index] = ' '; + } + else + { + name[index] += 1; + } + } + else if (name[index] >= 'a' && name[index] <= 'z')//小写字母 + { + if (name[index] == 'z') + { + name[index] = 'A'; + } + else + { + name[index] += 1; + } + } + else + { + name[index] = 'a'; + } + } +} + +//消失函数 +void disappear() +{ + switch (disappear_step) + { + case 1: + for (uint16_t i = 0; i < buf_len; ++i) + { + if (i % 2 == 0) buf_ptr[i] = buf_ptr[i] & 0x55; + } + break; + case 2: + for (uint16_t i = 0; i < buf_len; ++i) + { + if (i % 2 != 0) buf_ptr[i] = buf_ptr[i] & 0xAA; + } + break; + case 3: + for (uint16_t i = 0; i < buf_len; ++i) + { + if (i % 2 == 0) buf_ptr[i] = buf_ptr[i] & 0x00; + } + break; + case 4: + for (uint16_t i = 0; i < buf_len; ++i) + { + if (i % 2 != 0) buf_ptr[i] = buf_ptr[i] & 0x00; + } + break; + default: + ui_state = S_NONE; + disappear_step = 0; + break; + } + disappear_step++; +} + + + +/**************************界面显示*******************************/ + +void logo_ui_show()//显示logo +{ + u8g2.drawXBMP(0, 0, 128, 64, LOGO); + + // for(uint16_t i=0;i 0) Kpid[pid_select] -= 0.01; + break; + case 1: + if (Kpid[pid_select] < PID_MAX) Kpid[pid_select] += 0.01; + break; + case 2: + ui_index = M_PID; + break; + default: + break; + } + } + pid_ui_show(); + for (uint16_t i = 0; i < buf_len; ++i) + { + buf_ptr[i] = buf_ptr[i] & (i % 2 == 0 ? 0x55 : 0xAA); + } + pid_edit_ui_show(); +} + +void pid_proc()//pid界面处理函数 +{ + pid_ui_show(); + if (key_msg.pressed) + { + key_msg.pressed = false; + switch (key_msg.id) + { + case 0: + if (pid_select != 0) + { + pid_select -= 1; + pid_line_y_trg -= 15; + pid_box_y_trg -= 16; + break; + } + else + { + break; + } + case 1: + if (pid_select != 3) + { + pid_select += 1; + pid_line_y_trg += 15; + pid_box_y_trg += 16; + } + else + { + break; + } + break; + case 2: + if (pid_select == 3) + { + ui_index = M_SELECT; + ui_state = S_DISAPPEAR; + pid_select = 0; + pid_line_y = pid_line_y_trg = 1; + pid_box_y = pid_box_y_trg = 0; + pid_box_width = pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2; + } + else + { + ui_index = M_PID_EDIT; + } + break; + default: + break; + } + pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2; + } +} + +void select_proc(void)//选择界面处理重要的 +{ + if (key_msg.pressed) + { + key_msg.pressed = false; + switch (key_msg.id) + { + case 0: + if (ui_select < 1) break; + ui_select -= 1; + line_y_trg -= single_line_length; + if (ui_select < -(y / 16)) + { + y_trg += 16; + } + else + { + box_y_trg -= 16; + } + + break; + case 1: + if ((ui_select + 2) > list_num) break;//变更菜单数组个数3 + ui_select += 1; + line_y_trg += single_line_length; + if ((ui_select + 1) > (4 - y / 16)) + { + y_trg -= 16; + } + else + { + box_y_trg += 16; + } + + break; + case 2: + switch (ui_select) + { + case 0: //return + ui_state = S_DISAPPEAR; //S_DISAPPEAR; + ui_index = M_LOGO;//M_LOGO; + break; + case 1: //pid + ui_state = S_DISAPPEAR; + ui_index = M_PID; + break; + case 2: //icon + ui_state = S_DISAPPEAR; + ui_index = M_ICON; + break; + case 3: //chart + ui_state = S_DISAPPEAR; + ui_index = M_CHART; + break; + case 4: //textedit + ui_state = S_DISAPPEAR; + ui_index = M_TEXT_EDIT; + break; + case 6: //about + ui_state = S_DISAPPEAR; + ui_index = M_ABOUT; + break; + case 7: //about + ui_state = S_DISAPPEAR; + ui_index = M_ABOUT; + break; + case 8: //about + ui_state = S_DISAPPEAR; + ui_index = M_ABOUT; + break; + default: + break; + } + //Serial.println("Btn2"); + default: + break; + } + //Serial.println(ui_select); + box_width_trg = u8g2.getStrWidth(list[ui_select].select) + x * 2; + } + select_ui_show(); +} + +void icon_proc(void)//icon界面处理 +{ + icon_ui_show(); + if (key_msg.pressed) + { + key_msg.pressed = false; + switch (key_msg.id) + { + case 1: + if (icon_select != (icon_num - 1)) + { + icon_select += 1; + app_y_trg += 16; + icon_x_trg -= ICON_SPACE; + } + break; + case 0: + + if (icon_select != 0) + { + icon_select -= 1; + app_y_trg -= 16; + icon_x_trg += ICON_SPACE; + } + break; + case 2://2代表按下Mid按键 + + + switch (icon_select) { + case 0: ui_state = S_DISAPPEAR; + ui_index = M_LOGO; + break; + case 1:ui_state = S_DISAPPEAR; + ui_index = M_SELECT; + break; + case 2:ui_state = S_DISAPPEAR; + ui_index = M_PID; + break; + } + Serial.println("button press"); + Serial.println(icon_select); + Serial.println(icon_x); + Serial.println( app_y); + Serial.println("num to zero"); + icon_select = 0; + icon_x = icon_x_trg = 0; + app_y = app_y_trg = 0; + + + break; + default: + break; + } + } +} + +void chart_proc()//chart界面处理函数 +{ + chart_ui_show(); + if (key_msg.pressed) + { + key_msg.pressed = false; + ui_state = S_DISAPPEAR; + ui_index = M_SELECT; + frame_is_drawed = false;//退出后框架为未画状态 + chart_x = 0; + } +} + +void text_edit_proc() +{ + text_edit_ui_show(); + if (key_msg.pressed) + { + key_msg.pressed = false; + switch (key_msg.id) + { + case 0: + if (edit_flag) + { + //编辑 + text_edit(false, edit_index); + } + else + { + if (edit_index == 0) + { + edit_index = name_len; + } + else + { + edit_index -= 1; + } + } + break; + case 1: + if (edit_flag) + { + //编辑 + text_edit(true, edit_index); + } + else + { + if (edit_index == name_len) + { + edit_index = 0; + } + else + { + edit_index += 1; + } + } + break; + case 2: + if (edit_index == name_len) + { + ui_state = S_DISAPPEAR; + ui_index = M_SELECT; + edit_index = 0; + } + else + { + edit_flag = !edit_flag; + } + break; + default: + break; + } + } +} + +void about_proc()//about界面处理函数 +{ + if (key_msg.pressed) + { + key_msg.pressed = false; + ui_state = S_DISAPPEAR; + ui_index = M_SELECT; + } + about_ui_show(); +} +/********************************总的UI显示************************************/ + +void ui_proc()//总的UI进程 +{ + switch (ui_state) + { + case S_NONE: + if (ui_index != M_CHART) u8g2.clearBuffer(); + switch (ui_index) + { + case M_LOGO: + logo_proc(); + break; + case M_SELECT: + select_proc(); + break; + case M_PID: + pid_proc(); + break; + case M_ICON: + icon_proc(); + break; + case M_CHART: + chart_proc(); + break; + case M_TEXT_EDIT: + text_edit_proc(); + break; + case M_PID_EDIT: + pid_edit_proc(); + break; + case M_ABOUT: + about_proc(); + break; + default: + break; + } + break; + case S_DISAPPEAR: + disappear(); + break; + default: + break; + } + u8g2.sendBuffer(); +} + +int listSize = 4; +int pidSize = 4; + + +static int callback(void *data, int argc, char **argv, char **azColName){ + int i; + Serial.printf("%s: ", (const char*)data); + OutPutTimes++; + + Serial.println("----------------------"); + for (i = 0; i( "%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); + + // Serial.printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); +// 现在OutPutString包含了格式化后的字符串 + + } + + Serial.printf("\n"); + return 0; +} + +int openDb(const char *filename, sqlite3 **db) { + int rc = sqlite3_open(filename, db); + if (rc) { + Serial.printf("Can't open database: %s\n", sqlite3_errmsg(*db)); + return rc; + } else { + Serial.printf("Opened database successfully\n"); + } + return rc; +} + +char *zErrMsg = 0; +int db_exec(sqlite3 *db, const char *sql) { + Serial.println(sql); + long start = micros(); + int rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg); + if (rc != SQLITE_OK) { + Serial.printf("SQL error: %s\n", zErrMsg); + sqlite3_free(zErrMsg); + } else { + Serial.printf("Operation done successfully\n"); + } + Serial.print(F("Time taken:")); + Serial.println(micros()-start); + + return rc; +} +void addUser(){ + sqlite3 *db1; + + char *zErrMsg = 0; + int rc; + + SPI.begin(); + SD.begin(); + + sqlite3_initialize(); + + // Open database 1 + if (openDb("/sd/key.db", &db1)) + return; + + rc = db_exec(db1, "SELECT user FROM key WHERE site = 'example.com';"); + if (rc != SQLITE_OK) { + sqlite3_close(db1); + + return; + } + Serial.println(OutPutString); + + Serial.println("All Have Data Times:"); + const int SiteSize = OutPutTimes; + char* Site[SiteSize]; // Change the array type to char* + + // String OutPutString = "id = 1\nsite = example_site_2\nuser = user1\npassword = password1\nid = 2\nsite = example_site_1\nuser = user3\npassword = password1\nid = 3\nsite = example.com\nuser = john_doe\npassword = password123"; + String inputString = OutPutString; // Declare and initialize inputString + int startIndex = 0; + int endIndex = 0; + + for (int i = 0; i < OutPutTimes; i++) { + startIndex = inputString.indexOf("=", endIndex); + if (startIndex == -1) { + break; // If the equal sign is not found, exit the loop + } + + endIndex = inputString.indexOf("\n", startIndex); // Find the position of the newline character + + if (endIndex == -1) { + endIndex = inputString.length(); // If the newline character is not found, use the end of the string as the endpoint + } + + String value = inputString.substring(startIndex + 2, endIndex); // Extract the content after the equal sign, including spaces + + Serial.println(value); + // Convert String to char* and store in Site + Site[i] = strdup(value.c_str()); // Use strdup to allocate memory for the new string + + // Release memory after usage if needed + // free(Site[i]); + } + + Serial.println("--------test-----------"); + for (int i = 0; i < OutPutTimes; i++) { + Serial.println(Site[i]); + } + Serial.println("--------over-----------"); + + pid = (SELECT_LIST*)malloc(pidSize * sizeof(SELECT_LIST)); + + if (pid != NULL) { + // 添加值到结构体数组 + + // 打印数组中的值 + + for (int i = 0; i < pidSize; i++) { + pid[i].select = strdup(Site[i]); // 使用strdup创建分配的字符串副本 + } + + + } + + Serial.println(OutPutTimes); + //初始化 + OutPutString = ""; + OutPutTimes = 0; + sqlite3_close(db1); + +} +void sqlAPI(){ + sqlite3 *db1; + + char *zErrMsg = 0; + int rc; + + SPI.begin(); + SD.begin(); + + sqlite3_initialize(); + + // Open database 1 + if (openDb("/sd/key.db", &db1)) + return; + + rc = db_exec(db1, "SELECT * FROM key;"); + if (rc != SQLITE_OK) { + sqlite3_close(db1); + + return; + } + Serial.println(OutPutString); + OutPutString=""; + Serial.println("All Have Data Times2:"); + Serial.println(OutPutTimes); + sqlite3_close(db1); + +} +void addSiteDataToArr() {//此函数提供方法使其全部网站保存在数组中,界面分类用 + sqlite3 *db1; + + char *zErrMsg = 0; + int rc; + + SPI.begin(); + SD.begin(); + + sqlite3_initialize(); + + // Open database 1 + if (openDb("/sd/key.db", &db1)) + return; + rc = db_exec(db1, "SELECT DISTINCT site FROM key;"); + if (rc != SQLITE_OK) { + sqlite3_close(db1); + + return; + } + Serial.println(OutPutString); + + Serial.println("All Have Data Times:"); + const int SiteSize = OutPutTimes; + char* Site[SiteSize]; // Change the array type to char* + + // String OutPutString = "id = 1\nsite = example_site_2\nuser = user1\npassword = password1\nid = 2\nsite = example_site_1\nuser = user3\npassword = password1\nid = 3\nsite = example.com\nuser = john_doe\npassword = password123"; + String inputString = OutPutString; // Declare and initialize inputString + int startIndex = 0; + int endIndex = 0; + + for (int i = 0; i < OutPutTimes; i++) { + startIndex = inputString.indexOf("=", endIndex); + if (startIndex == -1) { + break; // If the equal sign is not found, exit the loop + } + + endIndex = inputString.indexOf("\n", startIndex); // Find the position of the newline character + + if (endIndex == -1) { + endIndex = inputString.length(); // If the newline character is not found, use the end of the string as the endpoint + } + + String value = inputString.substring(startIndex + 2, endIndex); // Extract the content after the equal sign, including spaces + + Serial.println(value); + // Convert String to char* and store in Site + Site[i] = strdup(value.c_str()); // Use strdup to allocate memory for the new string + + // Release memory after usage if needed + // free(Site[i]); + } + + Serial.println("--------test-----------"); + for (int i = 0; i < OutPutTimes; i++) { + Serial.println(Site[i]); + } + Serial.println("--------over-----------"); + + list = (SELECT_LIST*)malloc(listSize * sizeof(SELECT_LIST)); + + if (list != NULL) { + // 添加值到结构体数组 + + // 打印数组中的值 + + for (int i = 0; i < listSize; i++) { + list[i].select = strdup(Site[i]); // 使用strdup创建分配的字符串副本 + } + + + } + + + // OutPutString. +// +// char *token; +// +// token = strtok( OutPutString, "\n"); +// for (int i = 0; i < OutPutTimes; i++) { +// char *value = strchr(token, '='); +// +// if (value != NULL) { +// value++; // 移动到等号后面的值 +// Site[i] = value; +// } +// +// token = strtok(NULL, "\n"); +// } + + + + + Serial.println(OutPutTimes); + //初始化 + OutPutString = ""; + OutPutTimes = 0; + sqlite3_close(db1); +} +void setup() { + Serial.begin(115200); + addSiteDataToArr(); + addUser(); + // 动态分配内存以存储结构体数组 + + + //Wire.begin(21,22,400000); + pinMode(BTN0, INPUT_PULLUP); + pinMode(BTN1, INPUT_PULLUP); + pinMode(BTN2, INPUT_PULLUP); + key_init(); + + u8g2.setBusClock(800000); + u8g2.begin(); + u8g2.setFont(u8g2_font_wqy12_t_chinese1); + //u8g2.setContrast(10); + + buf_ptr = u8g2.getBufferPtr();//拿到buffer首地址 + buf_len = 8 * u8g2.getBufferTileHeight() * u8g2.getBufferTileWidth(); + + x = 4; + y = y_trg = 0; + line_y = line_y_trg = 1; + pid_line_y = pid_line_y_trg = 1; + ui_select = pid_select = icon_select = 0; + icon_x = icon_x_trg = 0; + app_y = app_y_trg = 0; + + box_width = box_width_trg = u8g2.getStrWidth(list[ui_select].select) + x * 2;//两边各多2 + pid_box_width = pid_box_width_trg = u8g2.getStrWidth(pid[pid_select].select) + x * 2;//两边各多2 + + ui_index = M_LOGO; + //ui_index=M_TEXT_EDIT; + ui_state = S_NONE; + +} + +void loop() { + key_scan(); + ui_proc(); +} \ No newline at end of file