diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dd2acb..fd187b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## Release 1.3.7 - 2024/3/11 + +1. 配网页面, 增加了用户引脚数据 (可以配置其他功能的引脚. 此功能似乎是为了准备给esp32s3用sdmmc库驱动sd卡用的) + +2. 增加 `guy_button` 按键库功能的接口函数 + +3. 修复部分bug + ## Release 1.3.6 - 2024/3/11 1. 按键功能: 正式更新特殊操作按法, 此按法可用于切换输入法或菜单定位等功能. 同时更新ex03演示, 演示更清晰. diff --git a/README.md b/README.md index 121d19f..5407ea0 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ -**版本1.3.6正式发布!欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~ +**版本1.3.7正式发布!欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~ **即将发布7个全新的屏幕驱动: 欢迎支持! (详见后面的驱动表格)** @@ -209,7 +209,7 @@ firmware.bin 0x10000 **如果想要使用纯arduino环境, 需要更改platformio.ini, 并将framework更改为`arduino`. 此时可以跳过 5~6 步骤**. -5. 编译目标是`ESP32`时, 需要单独安装[`LittleFS`](https://github.com/joltwallet/esp_littlefs)库来实现相关功能. 在项目内新建文件夹`components`, 在`components`文件夹内放入刚刚克隆的`LittleFS`库. *详见下图**上**方红框*. (使用纯arduino时跳过此步骤) +5. 编译目标是`ESP32`且使用`ESP-IDF arduino component`时, 需要单独安装[`LittleFS`](https://github.com/joltwallet/esp_littlefs)库来实现相关功能. 在项目内新建文件夹`components`, 在`components`文件夹内放入刚刚克隆的`LittleFS`库. *详见下图**上**方红框*. (使用纯arduino时跳过此步骤) @@ -235,14 +235,32 @@ firmware.bin 0x10000 其中的WiFi功能, 其实是可以禁掉的. 只要你提前配置成功, 那么就可以摆脱WiFi配网配引脚功能. -使用方法: 打开文件[guy_driver_config.h](src/guy_driver_config.h), 随后便根据注释来选择性的开启或关闭一些系统功能. +使用方法: 打开文件[`guy_driver_config.h`](src/guy_driver_config.h), 随后便根据注释来选择性的开启或关闭一些系统功能. **不推荐的做法!**: 其中有些屏幕用不到, 也可以通过`guy_epaper_config`来配置. -使用方法: 打开文件[guy_epaper_config.h](src/guy_epaper/guy_epaper_config.h), 随后便可以设置不加载哪些屏幕的驱动程序. +使用方法: 打开文件[`guy_epaper_config.h`](src/guy_epaper/guy_epaper_config.h), 随后便可以设置不加载哪些屏幕的驱动程序. 此操作可以节约flash和RAM消耗, **但是实际上此操作并不能节省太多的flash.** 为确保编译获得的程序兼容性, 应尽量不要更改这个文件. +- 还有一部分功能可以通过更改这两个文件来进行编辑 (如你想自己实现一个SD卡驱动) + +- 但是如果自己更改了WiFi配置引脚的功能, ***这样编译出的程序就不能实现跨硬件运行了*** + +*有一些宏定义的组合是没有检验是否能够通过编译的. 如果有问题请提issue或者群里反馈* + +## ESP32 项目配置 (使用 PlatformIO + Arduino as ESP-IDF component 环境) + +menuconfig 内容: + +``` +FREERTOS_HZ = 1000 +ESP32_DEFAULT_CPU_FREQ_MHZ = 240 +ESP32_BROWNOUT_DET_LVL = 0 +ESP_PHY_REDUCE_TX_POWER=y +FATFS_API_ENCODING_UTF_8 = true +``` + --- Copyright © 2022-2023 FriendshipEnder. All Rights reserved. diff --git a/examples/ex04_wifi/4_wifi_text_show/4_wifi_text_show.ino b/examples/ex04_wifi/4_wifi_text_show/4_wifi_text_show.ino index cecc01f..115ad25 100644 --- a/examples/ex04_wifi/4_wifi_text_show/4_wifi_text_show.ino +++ b/examples/ex04_wifi/4_wifi_text_show/4_wifi_text_show.ino @@ -88,6 +88,7 @@ void setup(){ //这些服务器响应回调函数会打包进入初始化参数列表中. //上方的字符串可以在用户访问主页时, 显示在主页的第二行.(作为通知显示, 但并不是通知) guy.println("名称:readguy 密码:12345678"); + guy.println("连接后浏览器访问: 192.168.4.1"); guy.display(); } void loop(){ diff --git a/examples/ex05_multifont/1_u8g2font/1_u8g2font.ino b/examples/ex05_multifont/1_u8g2font/1_u8g2font.ino index 7859e2a..061931c 100644 --- a/examples/ex05_multifont/1_u8g2font/1_u8g2font.ino +++ b/examples/ex05_multifont/1_u8g2font/1_u8g2font.ino @@ -55,9 +55,9 @@ ReadguyDriver guy;//新建一个readguy对象, 用于显示驱动. -extern const uint8_t ctg_wqy9pt_chinese1[]; //声明中文字体文件 +extern const uint8_t ctg_u8g2_wqy12_chinese1[]; //声明中文字体文件 -const lgfx::U8g2font cn_font(ctg_wqy9pt_chinese1); //U8G2格式中文字体转化为LGFX格式字体 +const lgfx::U8g2font cn_font(ctg_u8g2_wqy12_chinese1); //U8G2格式中文字体转化为LGFX格式字体 void setup(){ diff --git a/library.json b/library.json index 76f5f10..c23439a 100644 --- a/library.json +++ b/library.json @@ -11,7 +11,7 @@ "type": "git", "url": "https://github.com/fsender/readguy" }, - "version": "1.3.6", + "version": "1.3.7", "frameworks": "arduino", "platforms": ["espressif32", "espressif8266"], "headers": "readguy.h", diff --git a/library.properties b/library.properties index 11eae14..e3f2063 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=readguy -version=1.3.6 +version=1.3.7 author=fsender maintainer=fsender sentence=A free E-paper display driver library supports 16-level greyscale. diff --git a/src/guy_button.cpp b/src/guy_button.cpp index bfbd353..c740288 100644 --- a/src/guy_button.cpp +++ b/src/guy_button.cpp @@ -77,7 +77,8 @@ void guy_button::begin(uint8_t _pin, std_U8_function_U8 f, bool activeLow/*=true pin = _pin; state = get_state_cb(pin); min_debounce =25; //去抖时间 - long_press_ms =300; //长按持续时间+双击识别间隔最大时间 + long_press_ms =300; //长按持续时间 + double_press_ms =300; //双击识别间隔最大时间 long_repeat_ms =200; //长按连按间隔时间 scanDT =1; // =1识别双击或三击, =0则不识别双击或三击等需要延时返回的情况 lk=0; @@ -144,7 +145,7 @@ void guy_button::loop() { longclick_detected = true; } // is the button released and the time has passed for multiple clicks? - } else if (now - click_ms > (scanDT?long_press_ms:min_debounce)) { + } else if (now - click_ms > (scanDT?double_press_ms:min_debounce)) { // was there a longclick? if (longclick_detected) { // was it part of a combination? diff --git a/src/guy_button.h b/src/guy_button.h index d8b6bf1..30fbd6d 100644 --- a/src/guy_button.h +++ b/src/guy_button.h @@ -71,20 +71,21 @@ SOFTWARE. ///////////////////////////////////////////////////////////////// -#define GUYBUTTON_empty 0 -#define GUYBUTTON_single_click 1 -#define GUYBUTTON_double_click 2 -#define GUYBUTTON_triple_click 3 -#define GUYBUTTON_long_click 4 -#define GUYBUTTON_xlong_click 5 -#define GUYBUTTON_xxlong_click 6 -#define GUYBTN_READ_TIMEOUT 100 -#define GUYBTN_LOOP_TIMEOUT 10 +#define GUYBUTTON_empty 0 //没按下 +#define GUYBUTTON_single_click 1 //单击 +#define GUYBUTTON_double_click 2 //双击 +#define GUYBUTTON_triple_click 3 //三击 +#define GUYBUTTON_long_click 4 //长按 +#define GUYBUTTON_xlong_click 5 //点击后接长按 +#define GUYBUTTON_xxlong_click 6 //双击后接长按 +#define GUYBTN_READ_TIMEOUT 100 //读取延时 +#define GUYBTN_LOOP_TIMEOUT 10 //循环扫描延时 class guy_button{ public: uint16_t min_debounce ; //去抖时间 - uint16_t long_press_ms ; //长按持续时间+双击识别间隔最大时间 + uint16_t long_press_ms ; //长按持续时间 + uint16_t double_press_ms ; //双击识别间隔最大时间 uint16_t long_repeat_ms ; //长按连按间隔时间 protected: uint8_t pin = 255; //未定义引脚 @@ -113,16 +114,39 @@ class guy_button{ public: guy_button(); + /// @brief 初始化 + /// @param _pin 引脚ID. 传入的引脚在内部将会使用digitalRead函数实现 + /// @param activeLow 设置为true时, 当读取到低电平视为按下 + void begin(uint8_t _pin, bool activeLow = true){ + begin(_pin,[](uint8_t p)->uint8_t { return digitalRead(p); },activeLow); + } + /// @brief 初始化 + /// @param _pin 引脚ID. 传入的引脚在内部将会使用digitalRead函数实现 + /// @param f 触发函数: 当activeLow为false时, 返回1表示按下, 0表示没按下 为true时相反 + /// @note 默认的 f 是 匿名函数 [](uint8_t p)->uint8_t { return digitalRead(p); } + /// 如果自己指定了函数而且没有用到内置的参数, 那么 _pin 参数可能是没有任何用处的 void begin(uint8_t _pin, std_U8_function_U8 f, bool activeLow = true); + /// @brief 设置长按连按触发模式 + /// @param trigMode 0:单次长按 1:连续长按 void setLongRepeatMode(bool trigMode) { trig_mode = trigMode; } + /// @brief 长按了多久按钮 unsigned int wasPressedFor() const { return down_time_ms; } + /// @brief 返回是否处于被按下的状态 受loop扫描的限制, 如果没loop扫描则可以先手动调用扫描后使用 bool isPressed() const { return (state == _pressedState); } + /// @brief 读取原始的按钮状态 (不去抖动), 此函数不受loop扫描的限制 bool isPressedRaw(); // { return (get_state_cb(pin) == _pressedState); } + /// @brief 曾经按下的状态 是否是点击后立即松开 bool wasPressed(){ if(was_pressed){ was_pressed = false; return true; } return false; } + /// @brief 连击了几下 uint8_t getNumberOfClicks() const{ return click_count;} + /// @brief [已经弃用] 获取上次按钮的按下数据. 返回按钮状态(按钮状态参考read函数的说明) uint8_t getType() const { return last_click_type; } + /// @brief 读取按钮的按下数据. 返回按钮状态 0没按 1单击 2双击 3三击 4长按 5点击后长按 6双击后长按 uint8_t read(); + /// @brief 连续循环扫描按钮. 必须多次反复调用, 最好是单独开一个task来实现 void loop(); + /// @brief 设置是否识别双击 三连击等高级手势 + /// @param scan =1识别双击或三击, =0则不识别双击或三击等需要延时返回的情况 void enScanDT(uint8_t scan) { scanDT = scan; } /* void setMinDebounce(short n) { min_debounce =n;} //去抖时间 void setLongPressMs(short n) { long_press_ms =n;} //长按持续时间+双击识别间隔最大时间 diff --git a/src/guy_driver_config.h b/src/guy_driver_config.h index 0e2b42b..24334a7 100644 --- a/src/guy_driver_config.h +++ b/src/guy_driver_config.h @@ -73,9 +73,10 @@ #define READGUY_ENABLE_WIFI /// @brief 启用I2C功能. 可用于联网时钟, 温度计, 陀螺仪等外设. 目前暂不支持库内使用类似函数. 仅可以提供引脚定义 -#define READGUY_ENABLE_I2C +//#define READGUY_ENABLE_I2C +/// @note 现在库不提供任何I2C驱动, 只提供引脚定义的存储和读取, 这几乎不增加多少代码. 因此本宏不再使用 -/** @brief (即将推出) 启用SD卡功能. 开启此功能将会使用内置SD卡管理功能. 关闭后仅可保存SD卡用到的引脚. +/** @brief 启用SD卡功能. 开启此功能将会使用内置SD卡管理功能. 关闭后仅可保存SD卡用到的引脚. @note 会破坏兼容性. 若没有启用通用的SD卡驱动程序, 那么那些跨屏台编译的程序将无法用guyFS读取到SD卡. 若用户程序希望能从外部加载SD卡, 可以使用getSdMiso()等函数获取SD卡的Miso等引脚, 再由用户程序初始化SD卡. */ #define READGUY_ENABLE_SD @@ -83,9 +84,13 @@ /// @brief 使用LittleFS作为片上文件系统, 注释此行则用SPIFFS(功能少, 不好用) #define READGUY_USE_LITTLEFS 1 +/// @brief 使用esp8266时, EEPROM(类似NVS)的存储位置起点 (从起点开始的40字节被readguy所使用) 可选值: 0~4045 +/// @note 对于单一项目来说, 此选项不建议更改, 请在项目初期就确定此变量的值. +#define READGUY_ESP8266_EEPROM_OFFSET 2 + /// @brief ESP32按键服务任务的栈空间大小, 不建议普通用户更改. 默认值1024字节. 小于此大小会使程序栈溢出. #ifdef CONFIG_IDF_TARGET_ESP32S3 -#define BTN_LOOPTASK_STACK 1280 +#define BTN_LOOPTASK_STACK 1536 #else #define BTN_LOOPTASK_STACK 1024 #endif diff --git a/src/guy_version.h b/src/guy_version.h index d34aaf1..15b39fb 100644 --- a/src/guy_version.h +++ b/src/guy_version.h @@ -41,9 +41,9 @@ //另外, 在提交新版本之前, 不要忘记在github上创建release, 否则Arduino IDE会读不到 #define READGUY_V_MAJOR 1 #define READGUY_V_MINOR 3 -#define READGUY_V_PATCH 6 +#define READGUY_V_PATCH 7 #define READGUY_VERSION_VAL (READGUY_V_MAJOR*1000+READGUY_V_MINOR*100+READGUY_V_PATCH*10) -#define READGUY_VERSION "1.3.6" +#define READGUY_VERSION "1.3.7" #ifdef ESP8266 #define _READGUY_PLATFORM "ESP8266" diff --git a/src/guy_wireless.cpp b/src/guy_wireless.cpp index 8e755d8..8355457 100644 --- a/src/guy_wireless.cpp +++ b/src/guy_wireless.cpp @@ -33,10 +33,10 @@ static const PROGMEM char NOT_SUPPORTED[] = "(不支持此屏幕)"; static const PROGMEM char TEXT_HTML[] = "text/html"; static const PROGMEM char TEXT_PLAIN [] = "text/plain"; -static const PROGMEM char args_name[23][8]={ +static const PROGMEM char args_name[24][8]={ "share","epdtype","EpdMOSI","EpdSCLK","Epd_CS","Epd_DC","Epd_RST","EpdBusy", "SD_MISO","SD_MOSI","SD_SCLK","SD_CS","I2C_SDA","I2C_SCL", - "btn_cnt","btn1","btn1c","btn2","btn2c","btn3","btn3c","bklight","rtc" + "btn_cnt","btn1","btn1c","btn2","btn2c","btn3","btn3c","bklight","rtc","user" }; #ifdef READGUY_DEV_154A static const PROGMEM char NAME_guyDev154[]="1.54寸标准"; @@ -300,12 +300,14 @@ void ReadguyDriver::handleInitPost(){ #endif } config_data[0]=1; //默认只要运行到此处, 就已经初始化好了的 - for(int i=0;i<23;i++){ + for(int i=0;i<33;i++){ Serial.print(F("Argument ")); - Serial.print(FPSTR(args_name[i])); + String a_name = String(FPSTR(args_name[23])) + (i-22); + if(i<=22) a_name = FPSTR(args_name[i]); + Serial.print(a_name); Serial.write(':'); - if(sv.hasArg(FPSTR(args_name[i]))) { - Serial.println(sv.arg(FPSTR(args_name[i]))); + if(sv.hasArg(a_name)) { + Serial.println(sv.arg(a_name)); if(i<14){ //这12个引脚是不可以重复的, 如果有重复, config_data[0]设为0 config_data[i+1] = sv.arg(FPSTR(args_name[i])).toInt(); } @@ -318,6 +320,9 @@ void ReadguyDriver::handleInitPost(){ else if(i==20&&btn_count_>2) config_data[17]=-config_data[17]; else if(i==21) config_data[18] = sv.arg(FPSTR(args_name[21])).toInt(); else if(i==22) config_data[19] = sv.arg(FPSTR(args_name[22])).toInt(); //保留RTC功能 + else if(i>22){ //用户数据 + config_data[i-1] = sv.arg(a_name).toInt(); + } } else { Serial.write('\n'); @@ -535,7 +540,7 @@ void ReadguyDriver::handlePinSetup(){ s += FPSTR(args_name[i+2]); s += FPSTR(index_cn_html3); s += FPSTR(args_name[i+2]); - s += ("\" min=\"-1\" max=\"99\" step=\"1\" value=\""); + s += F("\" min=\"-1\" max=\"99\" step=\"1\" value=\""); s += (READGUY_cali?(int)config_data[i+3] :-1); s += F("\"/>"); } @@ -562,6 +567,17 @@ void ReadguyDriver::handlePinSetup(){ if(i==3) s += (READGUY_cali?(int)READGUY_bl_pin :-1); else s += ((READGUY_cali && config_data[15+i])?(int)abs(config_data[15+i])-1:-1); } + for(int i=0;i<10;i++){ + s += F("\"/>
用户数据 "); + s += (i+1); + s += F("=8) config_data[i-8] = rd; else @@ -613,7 +618,7 @@ bool ReadguyDriver::nvs_read(){ } void ReadguyDriver::nvs_write(){ for(unsigned int i=0;idrv_width():0; } //返回显示屏硬件宽度(不是画幅宽度)