mirror of
https://github.com/fsender/readguy.git
synced 2025-12-10 20:18:14 +08:00
update to 1.1.1 version
This commit is contained in:
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,10 +1,26 @@
|
|||||||
## 即将发布: Release 1.1.0 - 2023/09/25
|
## Release 1.1.1 - 2023/20/20
|
||||||
|
|
||||||
即将发布: 1. 可以配网了 也可以在线更新固件了. 注意在2MB flash的硬件上是无法通过在线更新固件的. 现在还需要你通过示例来进行配网!
|
1. 引脚配置页更新,内置预设开发板的引脚定义。
|
||||||
|
|
||||||
即将发布: 2. 增加了更多示例程序.
|
2. 可以配置wifi和线上固件升级。
|
||||||
|
|
||||||
即将发布: 3. 修复了一些bug
|
3. 支持在库内设置i2c总线。实际i2c功能需要自己编写程序,本库只提供了i2c引脚的定义接口。此次更新之后,设备需要重新配网。
|
||||||
|
|
||||||
|
4. 支持16级灰度的抖动算法,并可在程序内切换渲染方式和算法。
|
||||||
|
|
||||||
|
5. 添加了更多例程,例程注释更简洁易用。比如 WiFi获取时间demo, 按键demo, 图片demo, 文本和字体demo, 使用静态引脚定义的demo.
|
||||||
|
|
||||||
|
6. 修复了一些bug.
|
||||||
|
|
||||||
|
## Release 1.1.0 - 2023/09/25
|
||||||
|
|
||||||
|
1. 可以配网了 也可以在线更新固件了. 注意在2MB flash的硬件上是无法通过在线更新固件的. 现在还需要你通过示例来进行配网!
|
||||||
|
|
||||||
|
2. 增加了更多示例程序.
|
||||||
|
|
||||||
|
3. 修复了一些bug
|
||||||
|
|
||||||
|
4. 适配了16级灰度的floyd steinberg抖动算法, 提升了灰度的画质 (显示灰度渐变色, 则不会产生色块, 而是自然的像素抖动)
|
||||||
|
|
||||||
### Release 1.0.2 - 2023/09/24
|
### Release 1.0.2 - 2023/09/24
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
# readguy 自由的墨水屏阅读器驱动库
|
# readguy 自由的墨水屏阅读器驱动库
|
||||||
|
|
||||||
|
[](https://www.ardu-badge.com/readguy)
|
||||||
|
|
||||||
<img src="extra/artset/readguy_theme3.png" width="30%" height="auto">
|
<img src="extra/artset/readguy_theme3.png" width="30%" height="auto">
|
||||||
|
|
||||||
**版本1.0.2正式发布!欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~
|
**版本1.1.1正式发布!欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~
|
||||||
|
|
||||||
欢迎克隆, 项目交流QQ群: 926824162 (萌新可以进来问问题的哟), 项目的 Bilibili 主页:
|
欢迎克隆, 项目交流QQ群: 926824162 (萌新可以进来问问题的哟), 项目的 Bilibili 主页: [BV1f94y187wz](https://www.bilibili.com/video/BV1f94y187wz/) 记得三连+关注我这个宝藏up主哦~
|
||||||
|
|
||||||
注意, 有问题一定要先加群问, 先不要提issue, 提了小影 *(也就是作者FriendshipEnder)* 也不会看的.
|
注意, 有问题一定要先加群问, 先不要提issue, 提了小影 *(也就是作者FriendshipEnder)* 也不会看的.
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
|
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
|
||||||
#include "readguy.h" //包含readguy_driver 基础驱动库
|
#include "readguy.h" //包含readguy_driver 基础驱动库
|
||||||
|
|
||||||
readguy_driver guy;//新建一个readguy对象, 用于显示驱动.
|
ReadguyDriver guy;//新建一个readguy对象, 用于显示驱动.
|
||||||
|
|
||||||
void drawLines(); //声明一个函数, 用于显示一些线条. 此函数在后面的程序中会用到的
|
void drawLines(); //声明一个函数, 用于显示一些线条. 此函数在后面的程序中会用到的
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
|
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
|
||||||
#include "readguy.h" //包含readguy_driver 基础驱动库
|
#include "readguy.h" //包含readguy_driver 基础驱动库
|
||||||
|
|
||||||
readguy_driver guy;//新建一个readguy对象, 用于显示驱动.
|
ReadguyDriver guy;//新建一个readguy对象, 用于显示驱动.
|
||||||
|
|
||||||
void drawLines(); //声明一个函数, 用于显示一些线条. 此函数在后面的程序中会用到的
|
void drawLines(); //声明一个函数, 用于显示一些线条. 此函数在后面的程序中会用到的
|
||||||
|
|
||||||
|
|||||||
82
examples/ex03_buttons/ex03_buttons.ino
Normal file
82
examples/ex03_buttons/ex03_buttons.ino
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/******************** F r i e n d s h i p E n d e r ********************
|
||||||
|
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
|
||||||
|
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
|
||||||
|
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
|
||||||
|
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
|
||||||
|
*
|
||||||
|
* @file ex03_buttons.ino
|
||||||
|
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-10-20
|
||||||
|
* @brief ReadGuy 按键功能演示. ReadGuy自带的按键驱动程序是非常好用的
|
||||||
|
|
||||||
|
* @attention
|
||||||
|
* Copyright (c) 2022-2023 FriendshipEnder
|
||||||
|
*
|
||||||
|
* Apache License, Version 2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//在这里包含程序需要用到的库函数
|
||||||
|
|
||||||
|
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
|
||||||
|
#include "readguy.h" //包含readguy_driver 基础驱动库
|
||||||
|
|
||||||
|
ReadguyDriver guy;//新建一个readguy对象, 用于显示驱动.
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(115200); //初始化串口
|
||||||
|
guy.init(); //初始化readguy_driver 基础驱动库. 尽管初始化过程会刷屏, 但此示例不会用到屏幕.
|
||||||
|
//if(guy.width()<guy.height()) guy.setRotation(1); //横向
|
||||||
|
|
||||||
|
Serial.println(F("[readguy] Button demo")); //显示文本 默认是不支持中文显示的.
|
||||||
|
guy.println("Button demo"); //显示文本 默认是不支持中文显示的.
|
||||||
|
guy.display();//刷新墨水屏.
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
int val = guy.getBtn(); //此函数用于获取按键状态 没有按键按下时 返回0.
|
||||||
|
//1个按键 返回 1=点按 2=双击 3=长按 4=三击
|
||||||
|
//2个按键 返回 1=左键点按 2=左键长按 3=右键点按 4=右键长按
|
||||||
|
//3个按键 返回 1=左键点按 2=右键点按 3=中键点按 4=中键长按
|
||||||
|
|
||||||
|
if(val>0){
|
||||||
|
int c = guy.getButtonsCount(); //此函数用于返回设备有多少个按键. [最近更新的函数]
|
||||||
|
switch (val){
|
||||||
|
case 1:
|
||||||
|
if(c==1) guy.println("key single clicked!");
|
||||||
|
else if(c==2) guy.println("Left key clicked!");
|
||||||
|
else if(c==3) guy.println("Left key clicked!");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(c==1) guy.println("key double clicked!");
|
||||||
|
else if(c==2) guy.println("Left key long pressed!");
|
||||||
|
else if(c==3) guy.println("Right key clicked!");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if(c==1) guy.println("key long pressed!");
|
||||||
|
else if(c==2) guy.println("Right key clicked!");
|
||||||
|
else if(c==3) guy.println("Centre key clicked!");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if(c==1) guy.println("key triple clicked!");
|
||||||
|
else if(c==2) guy.println("Right key long pressed!");
|
||||||
|
else if(c==3) guy.println("Centre key long pressed!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
guy.display();
|
||||||
|
}
|
||||||
|
delay(10);
|
||||||
|
}/* END OF FILE. ReadGuy project.
|
||||||
|
Copyright (C) 2023 FriendshipEnder. */
|
||||||
88
examples/ex04_wifi/1_wifi_ap_server/1_wifi_ap_server.ino
Normal file
88
examples/ex04_wifi/1_wifi_ap_server/1_wifi_ap_server.ino
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/******************** F r i e n d s h i p E n d e r ********************
|
||||||
|
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
|
||||||
|
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
|
||||||
|
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
|
||||||
|
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
|
||||||
|
*
|
||||||
|
* @file 1_wifi_ap_server.ino
|
||||||
|
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-09-29
|
||||||
|
* @brief ReadGuy配网服务器演示.
|
||||||
|
// 注意, 为了避免此项目占用的flash空间过大, 故库内中不再提供配网的相关功能函数.
|
||||||
|
// 此示例程序提供了配网相关的方法, 在实际程序中, 请自行编写.
|
||||||
|
|
||||||
|
// ******** 在进行此示例之前, 不要将 DYNAMIC_PIN_SETTINGS 和 READGUY_ENABLE_WIFI 注释掉. ********
|
||||||
|
// ******************************** 此示例需要用到 WiFi 的特性. ********************************
|
||||||
|
*
|
||||||
|
* @attention
|
||||||
|
* Copyright (c) 2022-2023 FriendshipEnder
|
||||||
|
*
|
||||||
|
* Apache License, Version 2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//在这里包含程序需要用到的库函数
|
||||||
|
|
||||||
|
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
|
||||||
|
#include "readguy.h" //包含readguy_driver 基础驱动库
|
||||||
|
|
||||||
|
ReadguyDriver guy;//新建一个readguy对象, 用于显示驱动.
|
||||||
|
|
||||||
|
typedef ReadguyDriver::ReadguyWebServer* server_t; //类型名太长太繁琐, 使用typedef减短
|
||||||
|
typedef ReadguyDriver::serveFunc event_t ; //存储一个WiFi功能事件.
|
||||||
|
|
||||||
|
void f1(server_t sv); //服务器响应回调函数. 当启动AP配网服务器时, 这些函数将会被调用
|
||||||
|
void f2(server_t sv);
|
||||||
|
void f3(server_t sv);
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(115200); //初始化串口
|
||||||
|
guy.init(); //初始化readguy_driver 基础驱动库. 尽管初始化过程会刷屏, 但此示例不会用到屏幕.
|
||||||
|
|
||||||
|
event_t server_event[3]={ //设置一个服务器响应回调函数的容器.
|
||||||
|
{"按钮1","/btn1",f1}, //需要向容器的第一个元素中添加链接名称, 链接响应和链接回调函数
|
||||||
|
{"按钮2","/btn2",f2}, //链接响应必须以斜线字符开头
|
||||||
|
{"","/btn3",f3} //将HTML响应的事件名改为空白字符串, 就不会显示进入此链接的按钮, 只能通过其他页面跳转
|
||||||
|
}; //这里不太好理解, 不过看完示例应该就会了
|
||||||
|
|
||||||
|
guy.ap_setup(); //初始化WiFi AP模式 (可以理解为路由器模式)
|
||||||
|
|
||||||
|
guy.server_setup(String(F("配网服务器演示:可以放置自己的链接和回调函数")),server_event,3); //初始化服务器.
|
||||||
|
//这些服务器响应回调函数会打包进入初始化参数列表中.
|
||||||
|
//上方的字符串可以在用户访问主页时, 显示在主页的第二行.(作为通知显示, 但并不是通知)
|
||||||
|
}
|
||||||
|
void loop(){
|
||||||
|
guy.server_loop(); //让服务器一直运行
|
||||||
|
}
|
||||||
|
|
||||||
|
// 以下演示了如何向配网服务器添加回调函数.
|
||||||
|
//其中, sv 参数指向了一个服务器类型的变量. 当有来自客户端的请求时, 需要通过sv来发送响应消息.
|
||||||
|
|
||||||
|
void f1(server_t sv){ //使用PSTR来减少对内存的消耗(不加PSTR()或者F()则字符串会存到.rodata,占用宝贵的内存)
|
||||||
|
sv->send_P(200, PSTR("text/html"), PSTR("<html><body><meta charset=\"utf-8\">按钮1服务函数</body></html>"));
|
||||||
|
} //于此相应, 使用send_P函数而不是send函数来发送数据
|
||||||
|
|
||||||
|
void f2(server_t sv){ //使用 R"EOF()EOF" 括起来的字符串, (不含括号本身) 其中的字符不需要转义, 包括回车换行
|
||||||
|
sv->send_P(200, PSTR("text/html"), PSTR(R"EOF(<html>
|
||||||
|
<body>
|
||||||
|
<meta charset="utf-8">按钮2服务函数 <a href="/btn3">按钮3</a></body></html>)EOF"));
|
||||||
|
} //即使是缩进的空格也会被包含到字符串内, 此外, 引号等符号也不需要转义符.
|
||||||
|
|
||||||
|
void f3(server_t sv){ //此函数不会直接在首页中显示链接, 只能通过btn2中的链接跳转到本页面.
|
||||||
|
sv->send_P(200, PSTR("text/html"), PSTR("<html><body><meta charset=\"utf-8\">按钮3服务函数</body></html>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* END OF FILE. ReadGuy project.
|
||||||
|
Copyright (C) 2023 FriendshipEnder. */
|
||||||
296
examples/ex04_wifi/2_wifi_config/2_wifi_config.ino
Normal file
296
examples/ex04_wifi/2_wifi_config/2_wifi_config.ino
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
/******************** F r i e n d s h i p E n d e r ********************
|
||||||
|
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
|
||||||
|
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
|
||||||
|
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
|
||||||
|
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
|
||||||
|
*
|
||||||
|
* @file 2_wifi_config.ino
|
||||||
|
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-10-14
|
||||||
|
* @brief ReadGuy配网服务器 配置并连接附近的WiFi网络演示程序.
|
||||||
|
编译烧录后, 本程序将使用AP方式配网并在连接到网络时访问NTP服务器来在墨水屏上显示时间.
|
||||||
|
同时开启在STA上的服务器, 供这个WiFi上的用户访问此墨水屏阅读器.
|
||||||
|
|
||||||
|
// 注意, 为了避免此项目占用的flash空间过大, 故库内中不再提供配网的相关功能函数.
|
||||||
|
// 此示例程序提供了配网相关的方法, 在实际程序中, 请自行编写.
|
||||||
|
|
||||||
|
// ******** 在进行此示例之前, 不要将 DYNAMIC_PIN_SETTINGS 和 READGUY_ENABLE_WIFI 注释掉. ********
|
||||||
|
// ******************************** 此示例需要用到 WiFi 的特性. ********************************
|
||||||
|
*
|
||||||
|
* @attention
|
||||||
|
* Copyright (c) 2022-2023 FriendshipEnder
|
||||||
|
*
|
||||||
|
* Apache License, Version 2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//在这里包含程序需要用到的库函数
|
||||||
|
|
||||||
|
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
|
||||||
|
#include "readguy.h" //包含readguy_driver 基础驱动库
|
||||||
|
|
||||||
|
ReadguyDriver guy;//新建一个readguy对象, 用于显示驱动.
|
||||||
|
|
||||||
|
typedef ReadguyDriver::ReadguyWebServer* server_t; //类型名太长太繁琐, 使用typedef减短
|
||||||
|
typedef ReadguyDriver::serveFunc event_t ; //存储一个WiFi功能事件.
|
||||||
|
|
||||||
|
void f1(server_t sv); //服务器响应回调函数. 当启动AP配网服务器时, 这些函数将会被调用
|
||||||
|
void f2(server_t sv);
|
||||||
|
time_t getNTPTime(); //NTP获取时间的函数
|
||||||
|
|
||||||
|
int conf_status = 0; //标记WiFi配网状态: 当此值为1时, 说明配网程序收到了WiFi SSID和密码信息, 尝试连接.
|
||||||
|
//此变量为2 说明配网成功了. 连接到了WiFi并显示当前时间.
|
||||||
|
int scanres = 0; //WiFi扫描结果数量
|
||||||
|
String recv_ssid = "";//接收到的WiFi SSID
|
||||||
|
String recv_psk = ""; //接收到的WiFi 密码
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(115200); //初始化串口
|
||||||
|
guy.init(); //初始化readguy_driver 基础驱动库. 尽管初始化过程会刷屏, 但此示例不会用到屏幕.
|
||||||
|
|
||||||
|
Serial.println(F("[readguy] WiFi Configure demo")); //显示文本 默认是不支持中文显示的.
|
||||||
|
guy.println(F("WiFi Configure demo")); //显示文本 默认是不支持中文显示的.
|
||||||
|
guy.display();//刷新墨水屏.
|
||||||
|
|
||||||
|
event_t server_event[3]={ //设置一个服务器响应回调函数的容器. 使用方法详见wifi_ap_server示例
|
||||||
|
{"配置WiFi","/wificfg",f1}, //配置WiFi的入口链接. 在AP模式下点击此链接将会进入配网功能页面.
|
||||||
|
{"","/wifiok",f2} //收到wifi连接请求后 发送的响应. 此函数调用之后会尝试切换到STA模式, 连接到WiFi.
|
||||||
|
}; //本驱动库不会单独保存用户的WiFi SSID和WiFi密码信息
|
||||||
|
|
||||||
|
WiFi.mode(WIFI_AP_STA); //扫描网络需要切换到STA模式进行扫描. 扫描完成之后将会切换到AP模式
|
||||||
|
|
||||||
|
guy.server_setup(String(F("WiFi配网示例")),server_event,2); //初始化服务器.
|
||||||
|
//这些服务器响应回调函数会打包进入初始化参数列表中.
|
||||||
|
//上方的字符串可以在用户访问主页时, 显示在主页的第二行.(作为通知显示, 但并不是通知)
|
||||||
|
|
||||||
|
do{ //没有连接到目标SSID时 一直循环连接.
|
||||||
|
|
||||||
|
conf_status=0; //重置配置状态变量
|
||||||
|
|
||||||
|
scanres = WiFi.scanNetworks(); //开始扫描网络
|
||||||
|
|
||||||
|
Serial.println("[readguy] WiFi Scan OK."); //关闭服务器, 尝试连接, 连接成功之后将会在屏幕上显示
|
||||||
|
guy.println("WiFi Scan OK."); //连接失败则会重新进入循环
|
||||||
|
guy.display();
|
||||||
|
|
||||||
|
IPAddress local_IP(192,168,4,1); //设置本地AP的IP地址, 网关和子网掩码.
|
||||||
|
IPAddress gateway(192,168,4,1);
|
||||||
|
IPAddress subnet(255,255,255,0);
|
||||||
|
WiFi.softAPConfig(local_IP, gateway, subnet); //注册一个WiFi AP(类比无线路由器), 可以被手机等设备连接
|
||||||
|
WiFi.softAP("readguy","12345678"); //初始化WiFi AP模式 (可以理解为路由器模式)
|
||||||
|
|
||||||
|
while(conf_status==0){
|
||||||
|
guy.server_loop(); //让服务器一直运行 此函数总是返回true. 因此配网何时完成, 应在程序里设定, 适可而止
|
||||||
|
}
|
||||||
|
|
||||||
|
//guy.server_end(); //看来是接收到啊WiFi名称和密码消息了, 现在关闭服务器, 尝试连接到WiFi...
|
||||||
|
|
||||||
|
Serial.println("[readguy] received SSID and PSK info"); //关闭服务器, 尝试连接, 连接成功之后将会在屏幕上显示
|
||||||
|
guy.println("received SSID and PSK info"); //连接失败则会重新进入循环
|
||||||
|
guy.display(); //显示到墨水屏
|
||||||
|
|
||||||
|
WiFi.scanDelete(); //删除WiFi扫描数据
|
||||||
|
scanres = 0; //设置扫描到的网络个数为0
|
||||||
|
|
||||||
|
if(recv_ssid != "-"){ //检测SSID是否为空. 一般的网络SSID应该不会是这个名称吧...
|
||||||
|
//WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.begin(recv_ssid,recv_psk); //启动STA模式, 然后尝试连接网络(当前维WIFI_AP_STA模式, 可以连接到网络)
|
||||||
|
|
||||||
|
for(int i=0;i<1500;i++){ //等待15秒, 没连上就退出.
|
||||||
|
if(WiFi.status() == WL_CONNECTED){ //一旦连接成功就退出循环
|
||||||
|
conf_status=2; //标记为连接成功
|
||||||
|
guy.print("Connected! IP:"); //连接成功! 显示消息然后退出循环
|
||||||
|
guy.println(WiFi.localIP());
|
||||||
|
Serial.print("[readguy] Connected!IP:"); //连接成功! 显示消息然后退出循环
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
guy.display();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(conf_status!=2){ //经过循环之后发现wifi并没连接上 显示连接失败的信息.
|
||||||
|
guy.println("WiFi failed! AP and server restarted."); //连接成功! 显示消息然后退出循环
|
||||||
|
Serial.println("[readguy] WiFi failed! AP and server restarted."); //连接成功! 显示消息然后退出循环
|
||||||
|
guy.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
}while(conf_status!=2); // conf_status==2说明连接上了
|
||||||
|
|
||||||
|
WiFi.mode(WIFI_STA); //从WIFI_AP_STA模式切换到WIFI_STA模式, 不再提供readguy热点.
|
||||||
|
|
||||||
|
guy.println("Getting NTP time..."); //连接成功之后尝试获取NTP时间
|
||||||
|
Serial.println("[readguy] Getting NTP time..."); //连接成功之后尝试获取NTP时间
|
||||||
|
guy.display();
|
||||||
|
|
||||||
|
time_t now = getNTPTime(); //下方的函数演示了如何使用NTP来对时
|
||||||
|
guy.println(ctime(&now));
|
||||||
|
Serial.println(ctime(&now));
|
||||||
|
guy.display();
|
||||||
|
|
||||||
|
guy.server_setup("现在是联网的STA模式."); //如果没有调用server_end函数 连续调用server_setup将自动结束之前的服务器
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
guy.server_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 以下演示了如何向配网服务器添加回调函数.
|
||||||
|
//其中, sv 参数指向了一个服务器类型的变量. 当有来自客户端的请求时, 需要通过sv来发送响应消息.
|
||||||
|
|
||||||
|
void f1(server_t sv){ //使用PSTR来减少对内存的消耗(不加PSTR()或者F()则字符串会存到.rodata,占用宝贵的内存)
|
||||||
|
String webpage_html = F(
|
||||||
|
"<!DOCTYPE html>"
|
||||||
|
"<html lang='zh-cn'>"
|
||||||
|
"<head>"
|
||||||
|
"<meta charset='UTF-8'>"
|
||||||
|
"<title>配置WiFi连接</title>"
|
||||||
|
"</head>"
|
||||||
|
"<body>"
|
||||||
|
"<form name='input' action='/wifiok' method='GET'>"
|
||||||
|
"<h2>wifi配置页面</h2>"
|
||||||
|
"如需刷新WiFi列表, 请选择选项``重新扫描WiFi``并点击保存, 而不是刷新此页, 刷新此页不会刷新WiFi列表<hr/>"
|
||||||
|
"wifi名称:<br/>"
|
||||||
|
// "<input type='text' name='ssid'>"
|
||||||
|
"<select name='ssid'>"
|
||||||
|
// "<option value='0'>测试WiFi名称</option>" //在此放置你扫描到的所有WiFi名称
|
||||||
|
// "<option value='1'>1.54寸Lilygo</option>"
|
||||||
|
);
|
||||||
|
String webpage_html2 = F(
|
||||||
|
"</select>"
|
||||||
|
"<br/>"
|
||||||
|
"wifi密码:<br/>"
|
||||||
|
"<input type='text' name='psk'><br/>"
|
||||||
|
"<input type='submit' value='保存'>"
|
||||||
|
"</form>"
|
||||||
|
"</body>"
|
||||||
|
"</html>");
|
||||||
|
|
||||||
|
for(int i=0;i<=scanres;i++){
|
||||||
|
webpage_html += "<option value='";
|
||||||
|
webpage_html += i;
|
||||||
|
webpage_html += "'>";
|
||||||
|
if(i<scanres) webpage_html += WiFi.SSID(i);
|
||||||
|
else webpage_html += "重新扫描WiFi";
|
||||||
|
webpage_html += "</option>";
|
||||||
|
}
|
||||||
|
sv->send_P(200, PSTR("text/html"), (webpage_html+webpage_html2).c_str());
|
||||||
|
} //于此相应, 使用send_P函数而不是send函数来发送数据
|
||||||
|
|
||||||
|
void f2(server_t sv){
|
||||||
|
if(sv->hasArg("ssid")) {
|
||||||
|
if((sv->arg("ssid")).toInt() == scanres){
|
||||||
|
recv_ssid = "-"; //空白字符串 退出 重新扫描
|
||||||
|
}
|
||||||
|
else recv_ssid=WiFi.SSID((sv->arg("ssid")).toInt());
|
||||||
|
if(sv->hasArg("psk")) {
|
||||||
|
recv_psk=sv->arg("psk");
|
||||||
|
if(recv_ssid!="") conf_status=1; //接收到了WiFi SSID信息和密码信息
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(recv_ssid == "-"){
|
||||||
|
sv->send_P(200, PSTR("text/html"), PSTR("<html><body><meta charset=\"utf-8\" http-equiv=\"refresh\""
|
||||||
|
" content=\"8;url=/wificfg\">正在扫描WiFi, 8秒后自动跳转.</body></html>"));
|
||||||
|
}
|
||||||
|
else if(conf_status>=1){
|
||||||
|
String s=F("<html><body><meta charset=\"utf-8\">配置成功,正在连接...<br/>WiFi名称:");
|
||||||
|
s += recv_ssid;
|
||||||
|
s += F("<br/>WiFi密码:");
|
||||||
|
s += recv_psk;
|
||||||
|
s += F("<br/>连接成功的消息会显示在墨水屏上.</body></html>");
|
||||||
|
sv->send_P(200, PSTR("text/html"), s.c_str());
|
||||||
|
}
|
||||||
|
else sv->send_P(200, PSTR("text/html"), //没有给定SSID, 无法连接到WiFi.
|
||||||
|
PSTR("<html><body><meta charset=\"utf-8\">配置失败,缺少信息</body></html>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------- NTP code ------------------*/
|
||||||
|
WiFiUDP udp;
|
||||||
|
uint8_t packetBuffer[48];
|
||||||
|
const int16_t timeZone = 8; //Beijing
|
||||||
|
const int16_t localPort = 1337;
|
||||||
|
time_t get_ntp_time_impl(uint8_t _server)
|
||||||
|
{
|
||||||
|
const char * ntpServerName[4] = {
|
||||||
|
"ntp1.aliyun.com","time.windows.com","cn.ntp.org.cn","cn.pool.ntp.org"
|
||||||
|
};
|
||||||
|
char ntpHost[32];
|
||||||
|
IPAddress ntpServerIP; // NTP server's ip address
|
||||||
|
|
||||||
|
while (udp.parsePacket() > 0) ; // discard any previously received packets
|
||||||
|
Serial.println(F("Transmit NTP Request"));
|
||||||
|
// get a random server from the pool
|
||||||
|
strncpy_P(ntpHost,ntpServerName[_server],31);
|
||||||
|
ntpHost[31] = '\0';
|
||||||
|
WiFi.hostByName(ntpHost, ntpServerIP);
|
||||||
|
Serial.print(FPSTR(ntpServerName[_server]));
|
||||||
|
Serial.write(':');
|
||||||
|
Serial.println(ntpServerIP);
|
||||||
|
|
||||||
|
// set all bytes in the buffer to 0
|
||||||
|
memset(packetBuffer, 0, 48);
|
||||||
|
// Initialize values needed to form NTP request
|
||||||
|
// (see URL above for details on the packets)
|
||||||
|
packetBuffer[0] = 0b11100011; // LI, Version, Mode
|
||||||
|
packetBuffer[1] = 0; // Stratum, or type of clock
|
||||||
|
packetBuffer[2] = 6; // Polling Interval
|
||||||
|
packetBuffer[3] = 0xEC; // Peer Clock Precision
|
||||||
|
// 8 bytes of zero for Root Delay & Root Dispersion
|
||||||
|
packetBuffer[12] = 49;
|
||||||
|
packetBuffer[13] = 0x4E;
|
||||||
|
packetBuffer[14] = 49;
|
||||||
|
packetBuffer[15] = 52;
|
||||||
|
// all NTP fields have been given values, now
|
||||||
|
// you can send a packet requesting a timestamp:
|
||||||
|
udp.beginPacket(ntpServerIP, 123); //NTP requests are to port 123
|
||||||
|
udp.write(packetBuffer, 48);
|
||||||
|
udp.endPacket();
|
||||||
|
|
||||||
|
uint32_t beginWait = millis();
|
||||||
|
while (millis() - beginWait < 1500) {
|
||||||
|
int size = udp.parsePacket();
|
||||||
|
if (size >= 48) {
|
||||||
|
Serial.println("Receive NTP Response");
|
||||||
|
udp.read(packetBuffer, 48); // read packet into the buffer
|
||||||
|
unsigned long secsSince1900;
|
||||||
|
// convert four bytes starting at location 40 to a long integer
|
||||||
|
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
|
||||||
|
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
|
||||||
|
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
|
||||||
|
secsSince1900 |= (unsigned long)packetBuffer[43];
|
||||||
|
return secsSince1900 - 2208988800UL + timeZone * 3600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Serial.println("No NTP Response :-(");
|
||||||
|
return 0; // return 0 if unable to get the time
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t getNTPTime(){
|
||||||
|
time_t _now = 0;
|
||||||
|
if(!WiFi.isConnected()) return 0;
|
||||||
|
udp.begin(localPort);
|
||||||
|
Serial.print("Local port: ");
|
||||||
|
Serial.println(localPort);
|
||||||
|
for(int i=0;i<4;i++){//最多尝试10次对时请求
|
||||||
|
_now=get_ntp_time_impl(i);
|
||||||
|
if(_now) break; //成功后立即退出
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
return _now;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* END OF FILE. ReadGuy project.
|
||||||
|
Copyright (C) 2023 FriendshipEnder. */
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
|
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
|
||||||
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
|
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
|
||||||
*
|
*
|
||||||
* @file ex03_1_u8g2font.ino
|
* @file 1_u8g2font.ino
|
||||||
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
|
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
* @date 2023-09-19
|
* @date 2023-09-19
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
#include "ctg_u8g2_wqy12.h" //中文字体库
|
#include "ctg_u8g2_wqy12.h" //中文字体库
|
||||||
|
|
||||||
readguy_driver guy;//新建一个readguy对象, 用于显示驱动.
|
ReadguyDriver guy;//新建一个readguy对象, 用于显示驱动.
|
||||||
|
|
||||||
extern const uint8_t ctg_wqy9pt_chinese1[]; //声明中文字体文件
|
extern const uint8_t ctg_wqy9pt_chinese1[]; //声明中文字体文件
|
||||||
|
|
||||||
20064
examples/ex05_multifont/1_u8g2font/ctg_u8g2_wqy12.c
Normal file
20064
examples/ex05_multifont/1_u8g2font/ctg_u8g2_wqy12.c
Normal file
File diff suppressed because it is too large
Load Diff
42
examples/ex05_multifont/1_u8g2font/ctg_u8g2_wqy12.h
Normal file
42
examples/ex05_multifont/1_u8g2font/ctg_u8g2_wqy12.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/******************** F r i e n d s h i p E n d e r ********************
|
||||||
|
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
|
||||||
|
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
|
||||||
|
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
|
||||||
|
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
|
||||||
|
*
|
||||||
|
* @file ctg_u8g2_wqy12.h
|
||||||
|
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
|
||||||
|
* @version 1.0
|
||||||
|
* @date 2023-09-24
|
||||||
|
* @brief ReadGuy示例字体文件
|
||||||
|
* @attention
|
||||||
|
* Copyright (c) 2022-2023 FriendshipEnder
|
||||||
|
*
|
||||||
|
* Apache License, Version 2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef _CTG_U8G2_WQY12_H_FILE
|
||||||
|
#define _CTG_U8G2_WQY12_H_FILE
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <pgmspace.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
extern const uint8_t ctg_u8g2_wqy12_chinese1[14241] ;
|
||||||
|
extern const uint8_t ctg_u8g2_wqy12[626234] ;
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -7,20 +7,21 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1>readguy 欢迎页面</h1>
|
<h1>readguy 欢迎页面</h1>返回<a href="/pinsetup">设置页面</a>
|
||||||
<p>您已完成了初始化工作.现在可以配置WiFi和聚合密钥相关内容.<br />
|
<br />前往<a href="/edit">SD卡文件管理器页面</a><br
|
||||||
</p>返回<a href="/pinsetup">设置页面</a><br />前往<a href="/edit">SD卡文件管理器页面</a>
|
/>SD Card Type: SDSC, SD card size: 997888, used size: 997888KB.<br
|
||||||
<br />SD card size: 2967040KB, used size: 28224KB.<br />
|
/>当前WiFi模式: AP配网模式, IP地址: 0.0.0.0<br
|
||||||
当前WiFi模式: AP配网模式, IP地址: (IP unset)<br />
|
/>芯片型号: ESP32-S2 Rev0, 芯片闪存ID: ffffffffffffffff<br
|
||||||
芯片型号: ESP-12E or 12F, 芯片闪存ID: 0x00000000<br />
|
/>闪存容量: 4096KB, MAC地址: 7C:DF:A1:32:BD:78, 当前可用内存: 105324<br
|
||||||
闪存容量: 4096KB, MAC地址: 48:3F:DA:76:24:46<br />
|
/>ESP-IDF版本: 4.4.5<br /><b>引脚定义:</b><br
|
||||||
<b>引脚定义:</b><br />EpdMOSI:-1EpdSCLK:-1Epd_CS:15Epd_DC:5Epd_RST:-1
|
/>EpdMOSI:3 EpdSCLK:2 Epd_CS:6 Epd_DC:5 Epd_RST:4 EpdBusy:7 SD_MISO:41<br
|
||||||
EpdBusy:0SD_MISO:-1SD_MOSI:-1SD_SCLK:-1SD_CS:0<br />按键定义:btn1:5btn2:12btn3:2<br />
|
/>SD_MOSI:40 SD_SCLK:39 SD_CS:42 I2C_SDA:-1 I2C_SCL:-1 <br
|
||||||
<form action="/wifi" method="POST">WiFi 名称<input type='text' name='ssid' maxlength="31" /><br />WiFi 密码<input
|
/>按键定义:btn1:19 btn2:20 <br />
|
||||||
type='text' name='psk' maxlength="31" /><br />天气所在地<input type='text' name='ssid'
|
<form action="/customName"><input type='submit' value='确定!' /><br /></form><br />
|
||||||
maxlength="31" /><br />聚合数据API密钥<input type='text' name='psk' maxlength="63" /><br /></form><br />
|
<p>ReadGuy on device ESP32S2<br
|
||||||
<p>ReadGuy for device ESP8266<br />Copyright © FriendshipEnder <a href="https://github.com/fsender/readguy">GitHub</a>
|
/>Copyright © FriendshipEnder <a href="https://github.com/fsender/readguy">GitHub</a>
|
||||||
<a href="https://space.bilibili.com/180327370/">Bilibili</a><br />版本: 1.0.0 ,编译日期: Sep 20 202318:17:07</p>
|
<a href="https://space.bilibili.com/180327370">Bilibili</a><br
|
||||||
|
/>版本: 1.0.2 ,编译日期: Sep 27 2023 20:32:42</p>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -8,38 +8,166 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h1>readguy 设置页面</h1>
|
<h1>readguy 设置页面</h1>
|
||||||
<p>感谢您使用ReadGuy. 现在将引脚配置输入到框内, 即可成功点亮屏幕.<br />点击<a href="/wifi">配置WiFi</a><br />点击<a href="/api">配置聚合数据API密钥</a><br /></p>
|
<p>感谢您使用ReadGuy. 现在将引脚配置输入到框内, 即可成功点亮屏幕.<br />点击<a href="/wifi">配置WiFi</a>
|
||||||
|
<br />点击<a href="/api">配置聚合数据API密钥</a><br />
|
||||||
|
</p>
|
||||||
|
<h2>引脚定义设定</h2>
|
||||||
<form name="input" action="/verify" method="POST">
|
<form name="input" action="/verify" method="POST">
|
||||||
<h2>引脚定义设定</h2><input type="checkbox" name="share" value="1">墨水屏和SD卡共享SPI<br />E-paper 型号<select name="epdtype">
|
<script>
|
||||||
<option value="0" selected>1.54寸标准</option>
|
function bt() {
|
||||||
|
var a = document.getElementById("e").value;
|
||||||
|
if (a == 1) {
|
||||||
|
document.getElementById("et").value = 0;
|
||||||
|
document.getElementById("EpdMOSI").value = 23;
|
||||||
|
document.getElementById("EpdSCLK").value = 18;
|
||||||
|
document.getElementById("Epd_CS").value = 19;
|
||||||
|
document.getElementById("Epd_DC").value = 16;
|
||||||
|
document.getElementById("Epd_RST").value = 4;
|
||||||
|
document.getElementById("EpdBusy").value = 13;
|
||||||
|
document.getElementById("SD_MISO").value = 2;
|
||||||
|
document.getElementById("SD_MOSI").value = 15;
|
||||||
|
document.getElementById("SD_SCLK").value = 14;
|
||||||
|
document.getElementById("SD_CS").value = 26;
|
||||||
|
document.getElementById("btn_cnt").value = 3;
|
||||||
|
document.getElementById("btn1").value = 32;
|
||||||
|
document.getElementById("btn2").value = 33;
|
||||||
|
document.getElementById("btn3").value = 25;
|
||||||
|
document.getElementById("bklight").value = -1;
|
||||||
|
document.getElementById("I2C_SDA").value = 21;
|
||||||
|
document.getElementById("I2C_SCL").value = 22;
|
||||||
|
}
|
||||||
|
if (a == 2) {
|
||||||
|
document.getElementById("et").value = 11;
|
||||||
|
document.getElementById("EpdMOSI").value = 23;
|
||||||
|
document.getElementById("EpdSCLK").value = 18;
|
||||||
|
document.getElementById("Epd_CS").value = 14;
|
||||||
|
document.getElementById("Epd_DC").value = 27;
|
||||||
|
document.getElementById("Epd_RST").value = 33;
|
||||||
|
document.getElementById("EpdBusy").value = -1;
|
||||||
|
document.getElementById("SD_MISO").value = 19;
|
||||||
|
document.getElementById("SD_MOSI").value = 23;
|
||||||
|
document.getElementById("SD_SCLK").value = 18;
|
||||||
|
document.getElementById("SD_CS").value = 4;
|
||||||
|
document.getElementById("btn_cnt").value = 3;
|
||||||
|
document.getElementById("btn1").value = 39;
|
||||||
|
document.getElementById("btn2").value = 38;
|
||||||
|
document.getElementById("btn3").value = 37;
|
||||||
|
document.getElementById("bklight").value = 32;
|
||||||
|
document.getElementById("I2C_SDA").value = 21;
|
||||||
|
document.getElementById("I2C_SCL").value = 22;
|
||||||
|
}
|
||||||
|
if (a == 3) {
|
||||||
|
document.getElementById("et").value = 0;
|
||||||
|
document.getElementById("EpdMOSI").value = 14;
|
||||||
|
document.getElementById("EpdSCLK").value = 13;
|
||||||
|
document.getElementById("Epd_CS").value = 15;
|
||||||
|
document.getElementById("Epd_DC").value = 27;
|
||||||
|
document.getElementById("Epd_RST").value = 26;
|
||||||
|
document.getElementById("EpdBusy").value = 25;
|
||||||
|
document.getElementById("SD_MISO").value = -1;
|
||||||
|
document.getElementById("SD_MOSI").value = -1;
|
||||||
|
document.getElementById("SD_SCLK").value = -1;
|
||||||
|
document.getElementById("SD_CS").value = -1;
|
||||||
|
document.getElementById("btn_cnt").value = 1;
|
||||||
|
document.getElementById("btn1").value = 0;
|
||||||
|
document.getElementById("btn2").value = -1;
|
||||||
|
document.getElementById("btn3").value = -1;
|
||||||
|
document.getElementById("bklight").value = -1;
|
||||||
|
document.getElementById("I2C_SDA").value = -1;
|
||||||
|
document.getElementById("I2C_SCL").value = -1;
|
||||||
|
}
|
||||||
|
if (a == 4) {
|
||||||
|
document.getElementById("et").value = 1;
|
||||||
|
document.getElementById("EpdMOSI").value = 23;
|
||||||
|
document.getElementById("EpdSCLK").value = 18;
|
||||||
|
document.getElementById("Epd_CS").value = 5;
|
||||||
|
document.getElementById("Epd_DC").value = 19;
|
||||||
|
document.getElementById("Epd_RST").value = 27;
|
||||||
|
document.getElementById("EpdBusy").value = 38;
|
||||||
|
document.getElementById("SD_MISO").value = 2;
|
||||||
|
document.getElementById("SD_MOSI").value = 15;
|
||||||
|
document.getElementById("SD_SCLK").value = 14;
|
||||||
|
document.getElementById("SD_CS").value = 13;
|
||||||
|
document.getElementById("btn_cnt").value = 2;
|
||||||
|
document.getElementById("btn1").value = 32;
|
||||||
|
document.getElementById("btn2").value = 36;
|
||||||
|
document.getElementById("btn3").value = -1;
|
||||||
|
document.getElementById("bklight").value = 12;
|
||||||
|
document.getElementById("I2C_SDA").value = 25;
|
||||||
|
document.getElementById("I2C_SCL").value = 26;
|
||||||
|
}
|
||||||
|
if (a == 5) {
|
||||||
|
document.getElementById("et").value = 5;
|
||||||
|
document.getElementById("EpdMOSI").value = 23;
|
||||||
|
document.getElementById("EpdSCLK").value = 18;
|
||||||
|
document.getElementById("Epd_CS").value = 5;
|
||||||
|
document.getElementById("Epd_DC").value = 17;
|
||||||
|
document.getElementById("Epd_RST").value = 16;
|
||||||
|
document.getElementById("EpdBusy").value = 4;
|
||||||
|
document.getElementById("SD_MISO").value = 2;
|
||||||
|
document.getElementById("SD_MOSI").value = 15;
|
||||||
|
document.getElementById("SD_SCLK").value = 14;
|
||||||
|
document.getElementById("SD_CS").value = 13;
|
||||||
|
document.getElementById("btn_cnt").value = 3;
|
||||||
|
document.getElementById("btn1").value = 37;
|
||||||
|
document.getElementById("btn2").value = 38;
|
||||||
|
document.getElementById("btn3").value = 39;
|
||||||
|
document.getElementById("bklight").value = -1;
|
||||||
|
document.getElementById("I2C_SDA").value = -1;
|
||||||
|
document.getElementById("I2C_SCL").value = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function ct() {
|
||||||
|
document.getElementById("e").value = 0;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<select id="e" name="epdTemplate" onchange="bt()">
|
||||||
|
<option value="0" selected>自定义线序</option>
|
||||||
|
<option value="1">甘草MP3播放器</option>
|
||||||
|
<option value="2">M5Stack-Core</option>
|
||||||
|
<option value="3">微雪官方开发板</option>
|
||||||
|
<option value="4">LilyGo T-Watch墨水屏</option>
|
||||||
|
<option value="5">LilyGo T5开发板</option>
|
||||||
|
</select><br /><input type="checkbox" name="share" value="1">墨水屏和SD卡共享SPI<br
|
||||||
|
/>E-paper 型号<select id="et" onchange="ct()" name="epdtype">
|
||||||
|
<option value="0">1.54寸标准</option>
|
||||||
<option value="1">1.54寸Lilygo</option>
|
<option value="1">1.54寸Lilygo</option>
|
||||||
<option value="2">2.13寸汉朔价签</option>
|
<option value="2">2.13寸汉朔价签</option>
|
||||||
<option value="3">2.66寸Vusion价签</option>
|
<option value="3">2.13寸三色</option>
|
||||||
<option value="4">2.13寸三色</option>
|
<option value="4">2.66寸Vusion价签</option>
|
||||||
<option value="5">2.9寸A01</option>
|
<option value="5">2.7寸佳显触摸墨水屏</option>
|
||||||
<option value="6">2.9寸T94背光</option>
|
<option value="6">2.9寸A01</option>
|
||||||
<option value="7">4.2寸WF丝印</option>
|
<option value="7">2.9寸T94背光</option>
|
||||||
<option value="8">4.2寸HINK黑白价签</option>
|
<option value="8">3.7寸高DPI墨水屏</option>
|
||||||
<option value="9">3.7寸高DPI墨水屏</option>
|
<option value="9">4.2寸HINK黑白价签</option>
|
||||||
<option value="10">测试用LCD屏 请勿选此项</option>
|
<option value="10">4.2寸WF丝印</option>
|
||||||
<option value="11">2.7寸佳显触摸墨水屏</option>
|
<option value="11">测试用LCD屏 请勿选此项</option>
|
||||||
</select><br />Epd_CS<input type="number" name="Epd_CS" min="-1" max="100" step="1" value="15" /><br />
|
</select><br
|
||||||
Epd_DC<input type="number" name="Epd_DC" min="-1" max="100" step="1" value="5" /><br />
|
/>EpdMOSI<input type="number" id="EpdMOSI" onchange="ct()" name="EpdMOSI" min="-1" max="99" step="1" value="-1" /><br
|
||||||
Epd_RST<input type="number" name="Epd_RST" min="-1" max="100" step="1" value="-1" /><br />
|
/>EpdSCLK<input type="number" id="EpdSCLK" onchange="ct()" name="EpdSCLK" min="-1" max="99" step="1" value="-1" /><br
|
||||||
EpdBusy<input type="number" name="EpdBusy" min="-1" max="100" step="1" value="4" /><br />
|
/>Epd_CS<input type="number" id="Epd_CS" onchange="ct()" name="Epd_CS" min="-1" max="99" step="1" value="-1" /><br
|
||||||
SD_CS<input type="number" name="SD_CS" min="-1" max="100" step="1" value="0" /><br />
|
/>Epd_DC<input type="number" id="Epd_DC" onchange="ct()" name="Epd_DC" min="-1" max="99" step="1" value="-1" /><br
|
||||||
几个按键?<br /><input type="number" name="btn_cnt" min="1" max="3" step="1" value="3" /><br />
|
/>Epd_RST<input type="number" id="Epd_RST" onchange="ct()" name="Epd_RST" min="-1" max="99" step="1" value="-1" /><br
|
||||||
按键 1 引脚<input type="number" name="btn1" min="-1" max="100" step="1" value="5" /><br />
|
/>EpdBusy<input type="number" id="EpdBusy" onchange="ct()" name="EpdBusy" min="-1" max="99" step="1" value="-1" /><br
|
||||||
<input type="checkbox" name="btn1c" value="1">高电平触发<br />
|
/>SD_MISO<input type="number" id="SD_MISO" onchange="ct()" name="SD_MISO" min="-1" max="99" step="1" value="-1" /><br
|
||||||
按键 2 引脚<input type="number" name="btn2" min="-1" max="100" step="1" value="12" /><br />
|
/>SD_MOSI<input type="number" id="SD_MOSI" onchange="ct()" name="SD_MOSI" min="-1" max="99" step="1" value="-1" /><br
|
||||||
<input type="checkbox" name="btn2c" value="1">高电平触发<br />
|
/>SD_SCLK<input type="number" id="SD_SCLK" onchange="ct()" name="SD_SCLK" min="-1" max="99" step="1" value="-1" /><br
|
||||||
按键 3 引脚<input type="number" name="btn3" min="-1" max="100" step="1" value="2" /><br />
|
/>SD_CS<input type="number" id="SD_CS" onchange="ct()" name="SD_CS" min="-1" max="99" step="1" value="-1" /><br
|
||||||
<input type="checkbox" name="btn3c" value="1">高电平触发<br />
|
/>I2C_SDA<input type="number" id="I2C_SDA" onchange="ct()" name="I2C_SDA" min="-1" max="99" step="1" value="-1" /><br
|
||||||
背光 PWM 引脚<input type="number" name="bklight" min="-1" max="100" step="1" value="-1" /><br />
|
/>I2C_SCL<input type="number" id="I2C_SCL" onchange="ct()" name="I2C_SCL" min="-1" max="99" step="1" value="-1" /><br
|
||||||
<input type='submit' value='确定!' /><br />
|
/>几个按键?<input type="number" id="btn_cnt" onchange="ct()" name="btn_cnt" min="1" max="3" step="1" value="1" /><br
|
||||||
|
/>按键 1 引脚<input type="number" id="btn1" onchange="ct()" name="btn1" min="-1" max="99" step="1" value="-1" />
|
||||||
|
<input type="checkbox" onchange="ct()" name="btn1c" value="1">高电平触发<br
|
||||||
|
/>按键 2 引脚<input type="number" id="btn2" onchange="ct()" name="btn2" min="-1" max="99" step="1" value="-1" />
|
||||||
|
<input type="checkbox" onchange="ct()" name="btn2c" value="1">高电平触发<br
|
||||||
|
/>按键 3 引脚<input type="number" id="btn3" onchange="ct()" name="btn3" min="-1" max="99" step="1" value="-1" />
|
||||||
|
<input type="checkbox" onchange="ct()" name="btn3c" value="1">高电平触发<br
|
||||||
|
/>背光 PWM 引脚<input type="number" id="bklight" onchange="ct()" name="bklight" min="-1" max="99" step="1" value="-1" /><br
|
||||||
|
/><input type='submit' value='OK!' /><br />
|
||||||
</form><br />
|
</form><br />
|
||||||
<p>ReadGuy on device ESP8266<br />Copyright © FriendshipEnder <a href="https://github.com/fsender/readguy">GitHub</a>
|
<p>ReadGuy on device ESP32<br />Copyright © FriendshipEnder <a
|
||||||
<a href="https://space.bilibili.com/180327370/">Bilibili</a><br />版本: 1.0.0 ,编译日期: Sep 20 202318:17:07</p>
|
href="https://github.com/fsender/readguy">GitHub</a> <a
|
||||||
|
href="https://space.bilibili.com/180327370">Bilibili</a><br />版本: 1.2.0 ,编译日期: Sep 28 2023 23:37:58</p>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -11,13 +11,15 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/fsender/readguy"
|
"url": "https://github.com/fsender/readguy"
|
||||||
},
|
},
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": ["espressif32", "espressif8266"],
|
"platforms": ["espressif32", "espressif8266"],
|
||||||
"headers": "readguy.h",
|
"headers": "readguy.h",
|
||||||
"build": {
|
"build": {
|
||||||
"libArchive": false
|
"libArchive": false
|
||||||
},
|
},
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"homepage": "b站视频",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"name": "lovyan03/LovyanGFX",
|
"name": "lovyan03/LovyanGFX",
|
||||||
"version": ">=1.1.9"
|
"version": ">=1.1.9"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name=readguy
|
name=readguy
|
||||||
version=1.1.0
|
version=1.1.1
|
||||||
author=fsender <f_ender@163.com>
|
author=fsender <f_ender@163.com>
|
||||||
maintainer=fsender <f_ender@163.com>
|
maintainer=fsender <f_ender@163.com>
|
||||||
sentence=A free E-paper display driver library supports 16-level greyscale.
|
sentence=A free E-paper display driver library supports 16-level greyscale.
|
||||||
|
|||||||
@@ -59,17 +59,42 @@
|
|||||||
|
|
||||||
// ------------------ definations - 定义 -
|
// ------------------ definations - 定义 -
|
||||||
|
|
||||||
//#define INDEV_DEBUG 1 //debug专用, 正常开机从NVS读取引脚配置数据, 取消注释则每次开机需要重新配置
|
/// @brief 使用静态的数据 !!!注意:注释此选项编写的程序是不支持跨平台运行的!!!
|
||||||
#define DYNAMIC_PIN_SETTINGS //使用静态的数据 !!!注意:注释此选项编写的程序是不支持跨平台运行的!!!
|
/// @note 相比于禁用WiFi配网功能, 禁用此功能减少的flash并不多, 为保证程序可在不同屏幕上运行, 请不要注释此选项
|
||||||
#define READGUY_ENABLE_WIFI //启用WIFI配网功能.必须先启用 #define DYNAMIC_PIN_SETTINGS
|
#define DYNAMIC_PIN_SETTINGS
|
||||||
#define READGUY_USE_LITTLEFS 1 //取消注释以使用LittleFS,注释则用SPIFFS
|
|
||||||
#define BTN_LOOPTASK_STACK 1024 //ESP32按键服务任务的栈空间大小
|
/// @brief 启用WIFI配网功能.必须先启用 #define DYNAMIC_PIN_SETTINGS. 此选项对 ESP32xx 会减少大量flash.
|
||||||
#define BTN_LOOPTASK_CORE_ID 0 //ESP32按键服务任务运行在哪个核心
|
#define READGUY_ENABLE_WIFI
|
||||||
#define BTN_LOOPTASK_PRIORITY 4 //ESP32按键服务任务的优先级
|
|
||||||
#define BTN_LOOPTASK_DELAY 10 //按键任务间隔多久调用一次,单位毫秒
|
/// @brief 启用I2C功能. 可用于联网时钟, 温度计, 陀螺仪等外设. 目前暂不支持库内使用类似函数. 仅可以提供引脚定义
|
||||||
#define ESP8266_SPI_FREQUENCY 20000000 //使用ESP8266时, SPI速率
|
#define READGUY_ENABLE_I2C
|
||||||
#define ESP32_DISP_FREQUENCY 20000000 //使用ESP32且屏幕与SD卡用不同的SPI总线时,屏幕速率
|
|
||||||
#define ESP32_SD_SPI_FREQUENCY 20000000 //注意ESP32在与SD卡共享SPI时,屏幕依据SD_SPI的速率
|
/// @brief 使用LittleFS作为片上文件系统, 注释此行则用SPIFFS(功能少, 不好用)
|
||||||
|
#define READGUY_USE_LITTLEFS 1
|
||||||
|
|
||||||
|
/// @brief ESP32按键服务任务的栈空间大小, 不建议普通用户更改. 默认值1024字节. 小于此大小会使程序栈溢出.
|
||||||
|
#define BTN_LOOPTASK_STACK 1024
|
||||||
|
|
||||||
|
/// @brief ESP32按键服务任务运行在哪个核心. 通常运行在核心0上.
|
||||||
|
#define BTN_LOOPTASK_CORE_ID 0
|
||||||
|
|
||||||
|
/// @brief ESP32按键服务任务的优先级. 高于arduino默认任务即可
|
||||||
|
#define BTN_LOOPTASK_PRIORITY 3
|
||||||
|
|
||||||
|
/// @brief 按键任务间隔多久调用一次, 默认为20毫秒. 对于需要精确读取按钮的程序, 请酌情减小此数值
|
||||||
|
#define BTN_LOOPTASK_DELAY 20
|
||||||
|
|
||||||
|
/// @brief 使用ESP8266时, 屏幕和SD卡的SPI速率. 默认为20MHz.
|
||||||
|
#define ESP8266_SPI_FREQUENCY 20000000
|
||||||
|
|
||||||
|
/// @brief 使用ESP32且屏幕与SD卡用不同的SPI总线时, 驱动屏幕的SPI速率
|
||||||
|
#define ESP32_DISP_FREQUENCY 20000000
|
||||||
|
|
||||||
|
/// @brief ESP32驱动SD卡的速率. 当ESP32在与SD卡共享SPI时, 屏幕依据此处的速率.
|
||||||
|
#define ESP32_SD_SPI_FREQUENCY 20000000
|
||||||
|
|
||||||
|
/// @brief debug专用, 请保持处于注释状态. 正常开机从NVS读取引脚配置数据, 取消注释则每次开机需要重新配置
|
||||||
|
//#define INDEV_DEBUG 1
|
||||||
|
|
||||||
#ifndef DYNAMIC_PIN_SETTINGS
|
#ifndef DYNAMIC_PIN_SETTINGS
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@@ -86,8 +111,9 @@
|
|||||||
#define READGUY_sd_miso -1 // 目标sd卡的 MISO 引脚, sd_share_spi == 1 时无效
|
#define READGUY_sd_miso -1 // 目标sd卡的 MISO 引脚, sd_share_spi == 1 时无效
|
||||||
#define READGUY_sd_mosi -1 // 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
|
#define READGUY_sd_mosi -1 // 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
|
||||||
#define READGUY_sd_sclk -1 // 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
|
#define READGUY_sd_sclk -1 // 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
|
||||||
|
|
||||||
#define READGUY_sd_cs 0 // 目标sd卡的 CS 引脚
|
#define READGUY_sd_cs 0 // 目标sd卡的 CS 引脚
|
||||||
|
#define READGUY_i2c_sda -1 // 目标i2c总线的SDA引脚, 当且仅当启用i2c总线时才生效
|
||||||
|
#define READGUY_i2c_scl -1 // 目标i2c总线的SCL引脚, 当且仅当启用i2c总线时才生效
|
||||||
//按键驱动部分, 为负代表高触发, 否则低触发,
|
//按键驱动部分, 为负代表高触发, 否则低触发,
|
||||||
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
|
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
|
||||||
#define READGUY_btn1 ( 5+1) //按键1,注意需要+1,这里示例已经加了 设置为负的来允许高电平触发
|
#define READGUY_btn1 ( 5+1) //按键1,注意需要+1,这里示例已经加了 设置为负的来允许高电平触发
|
||||||
@@ -112,6 +138,8 @@
|
|||||||
#define READGUY_sd_mosi 15 // 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
|
#define READGUY_sd_mosi 15 // 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
|
||||||
#define READGUY_sd_sclk 14 // 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
|
#define READGUY_sd_sclk 14 // 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
|
||||||
#define READGUY_sd_cs 13 // 目标sd卡的 CS 引脚
|
#define READGUY_sd_cs 13 // 目标sd卡的 CS 引脚
|
||||||
|
#define READGUY_i2c_sda -1 // 目标i2c总线的SDA引脚, 当且仅当启用i2c总线时才生效
|
||||||
|
#define READGUY_i2c_scl -1 // 目标i2c总线的SCL引脚, 当且仅当启用i2c总线时才生效
|
||||||
|
|
||||||
//按键驱动部分, 为负代表高触发, 否则低触发,
|
//按键驱动部分, 为负代表高触发, 否则低触发,
|
||||||
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
|
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ void drv_base::drv_draw16grey_step(std::function<uint8_t(int)> f, int step){
|
|||||||
if(step==1){
|
if(step==1){
|
||||||
greyHQ=3;
|
greyHQ=3;
|
||||||
drv_setDepth(3);
|
drv_setDepth(3);
|
||||||
drv_fullpart(1); //开始局刷
|
drv_fullpart(1); //开始快刷
|
||||||
}
|
}
|
||||||
if(step==3) drv_setDepth(2);
|
if(step==3) drv_setDepth(2);
|
||||||
if(step==5) drv_setDepth(1);
|
if(step==5) drv_setDepth(1);
|
||||||
|
|||||||
@@ -32,24 +32,27 @@
|
|||||||
|
|
||||||
//#define MEPD_DEBUG_WAVE 16 //取消此行注释来监视SPI的通信数据 (用于debug), 可以查看主控和屏幕的通信数据
|
//#define MEPD_DEBUG_WAVE 16 //取消此行注释来监视SPI的通信数据 (用于debug), 可以查看主控和屏幕的通信数据
|
||||||
//#define MEPD_DEBUG_WAITTIME //显示墨水屏的刷新时间, 单位是毫秒
|
//#define MEPD_DEBUG_WAITTIME //显示墨水屏的刷新时间, 单位是毫秒
|
||||||
#define FLOYD_STEINBERG_DITHERING //默认使用性能更好的floyd steinberg抖动算法, 取消注释则使用bayer图案抖动算法
|
#define FLOYD_STEINBERG_DITHERING //默认使用更好的floyd steinberg抖动算法,取消注释则用bayer图案抖动算法
|
||||||
|
#define FLOYD_DITHERING_16GREY //使用更好的floyd steinberg抖动算法显示16阶灰度,取消注释则使用阈值填充
|
||||||
|
|
||||||
// ***********************************************************************
|
// ***********************************************************************
|
||||||
|
|
||||||
//设备设置: 取消对应设备就可以直接禁用掉对应设备
|
//设备设置: 取消对应设备就可以直接禁用掉对应设备
|
||||||
//如果程序不想支持此型号(为了节省flash),请注释掉这一行, 实测根本不会节省多少空间
|
//非常不建议用户在应用程序中禁用掉设备. 实测根本不会节省很多的空间. 如果要节省代码占用的flash空间,
|
||||||
#define READGUY_DEV_154A 0
|
//请在字库上下功夫.
|
||||||
#define READGUY_DEV_154B 1
|
//如果程序不想支持此型号(为了节省flash),请注释掉这一行, 实测每个设备只能节省100字节左右的flash空间
|
||||||
#define READGUY_DEV_213A 2
|
#define READGUY_DEV_154A 0 //1.54寸标准, 甘草酸不酸使用的1.54默认屏幕型号. 1.54汉朔价签也选这个
|
||||||
#define READGUY_DEV_213B 3
|
#define READGUY_DEV_154B 1 //1.54寸Lilygo, lilygo的1.54触摸和1.54背光墨水屏. GDEH0154D67
|
||||||
#define READGUY_DEV_266A 4
|
#define READGUY_DEV_213A 2 //2.13寸汉朔价签, 价格便宜, 兼容性好. 夏襄居士单词卡用 GDE0213B1
|
||||||
#define READGUY_DEV_270B 5
|
#define READGUY_DEV_213B 3 //2.13寸三色, 分辨率低212x104, 部分价签也用这个屏 易老化
|
||||||
#define READGUY_DEV_290A 6
|
#define READGUY_DEV_266A 4 //2.66寸Vusion价签, 黑白双色.
|
||||||
#define READGUY_DEV_290B 7
|
#define READGUY_DEV_270B 5 //2.7寸佳显触摸墨水屏, 佳显官方店有售: 2.7寸触摸墨水屏.
|
||||||
#define READGUY_DEV_370A 8
|
#define READGUY_DEV_290A 6 //2.9寸A01, 甘草酸不酸2.9寸A01型号. 显示性能一般
|
||||||
#define READGUY_DEV_420A 9
|
#define READGUY_DEV_290B 7 //2.9寸T94背光, 甘草酸不酸2.9寸T94型号. 显示性能更好, 支持前置光
|
||||||
#define READGUY_DEV_420B 10
|
#define READGUY_DEV_370A 8 //3.7寸高DPI墨水屏, 480x280分辨率, 显示效果非常好
|
||||||
#define MEPD_DEBUG_DISPLAY 11 //使用LCD显示屏幕来debug
|
#define READGUY_DEV_420A 9 //4.2寸HINK黑白价签, 汉朔价签, 汉朔三色价签通用. 速度快, 但效果一般
|
||||||
|
#define READGUY_DEV_420B 10 //4.2寸WF丝印, 部分价签也用此型号屏, 排线有WF开头的丝印
|
||||||
|
#define MEPD_DEBUG_DISPLAY 11 //使用LCD显示屏幕来debug. 前往ctg_stack_c_defines.h修改兼容的屏幕.
|
||||||
|
|
||||||
#endif /* END OF FILE. ReadGuy project.
|
#endif /* END OF FILE. ReadGuy project.
|
||||||
Copyright (C) 2023 FriendshipEnder. */
|
Copyright (C) 2023 FriendshipEnder. */
|
||||||
@@ -178,7 +178,7 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
|
|||||||
63, 31, 55, 23, 61, 29, 53, 21
|
63, 31, 55, 23, 61, 29, 53, 21
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
const uint_fast16_t w = (spr.width()+7)>>3;
|
const uint32_t w = (spr.width()+7)>>3;
|
||||||
if((!w) || (!spr.height())) return;
|
if((!w) || (!spr.height())) return;
|
||||||
uint16_t *readBuff = new uint16_t[spr.width()];
|
uint16_t *readBuff = new uint16_t[spr.width()];
|
||||||
uint8_t *writeBuff = new uint8_t[w];
|
uint8_t *writeBuff = new uint8_t[w];
|
||||||
@@ -189,39 +189,39 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
|
|||||||
for(int j=0;j<spr.width();j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
|
for(int j=0;j<spr.width();j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
|
||||||
#endif
|
#endif
|
||||||
sprbase.fillRect(x,y,spr.width(),spr.height(),1);
|
sprbase.fillRect(x,y,spr.width(),spr.height(),1);
|
||||||
for(int_fast16_t i=0;i<(int_fast16_t)spr.height();i++){
|
for(int32_t i=0;i<(int32_t)spr.height();i++){
|
||||||
spr.readRect(0,i,spr.width(),1,readBuff);
|
spr.readRect(0,i,spr.width(),1,readBuff);
|
||||||
#ifdef FLOYD_STEINBERG_DITHERING
|
#ifdef FLOYD_STEINBERG_DITHERING
|
||||||
uint_fast8_t buff8bit=0;
|
uint_fast8_t buff8bit=0;
|
||||||
for(int_fast16_t j=0;j<(int_fast16_t)spr.width();j++){
|
for(int32_t j=0;j<(int32_t)spr.width();j++){
|
||||||
int_fast16_t flodelta = floyd_tab[i&1][j]+(int_fast16_t)(greysc(readBuff[j])<<4);
|
int32_t flodelta = floyd_tab[i&1][j]+(int32_t)((greysc(readBuff[j])<<8)|greysc(readBuff[j]));
|
||||||
if(flodelta>=2048) {
|
if(flodelta>=0x8000) {
|
||||||
//spr.drawPixel(j,i,1);
|
//spr.drawPixel(j,i,1);
|
||||||
buff8bit |= 1<<((~j)&7);
|
buff8bit |= 1<<((~j)&7);
|
||||||
flodelta -= 4095;
|
flodelta -= 0xffff;
|
||||||
}
|
}
|
||||||
if((j&7)==7 || j==((int_fast16_t)spr.width()-1)){
|
if((j&7)==7 || j==((int32_t)spr.width()-1)){
|
||||||
writeBuff[j>>3]=buff8bit;
|
writeBuff[j>>3]=buff8bit;
|
||||||
buff8bit=0;
|
buff8bit=0;
|
||||||
}
|
}
|
||||||
//计算出读取到的颜色, 然后与128比较, 如果小于128, 显示黑色,否则显示白色
|
//计算出读取到的颜色, 然后与128比较, 如果小于128, 显示黑色,否则显示白色
|
||||||
//else { spr.drawPixel(j,i,0); }
|
//else { spr.drawPixel(j,i,0); }
|
||||||
/*if(j!=(int_fast16_t)spr.width()-1) {
|
/*if(j!=(int32_t)spr.width()-1) {
|
||||||
floyd_tab[ i&1 ][j+1] += (flodelta*7)>>4;
|
floyd_tab[ i&1 ][j+1] += (flodelta*7)>>4;
|
||||||
floyd_tab[!(i&1)][j+1] += (flodelta )>>4;
|
floyd_tab[!(i&1)][j+1] += (flodelta )>>4;
|
||||||
}
|
}
|
||||||
if(j) { floyd_tab[!(i&1)][j-1] += (flodelta*3)>>4; }
|
if(j) { floyd_tab[!(i&1)][j-1] += (flodelta*3)>>4; }
|
||||||
{ floyd_tab[!(i&1)][j ] += (flodelta*5)>>4; }*/
|
{ floyd_tab[!(i&1)][j ] += (flodelta*5)>>4; }*/
|
||||||
if(j!=(int_fast16_t)spr.width()-1)
|
if(j!=(int32_t)spr.width()-1)
|
||||||
{ floyd_tab[i&1] [j+1] += (flodelta*7)>>4; }
|
{ floyd_tab[i&1] [j+1] += (flodelta*7)>>4; }
|
||||||
if(j) { floyd_tab[!(i&1)][j-1] += (flodelta*3)>>4; }
|
if(j) { floyd_tab[!(i&1)][j-1] += (flodelta*3)>>4; }
|
||||||
{ floyd_tab[!(i&1)][j ] += (flodelta*5)>>4; }
|
{ floyd_tab[!(i&1)][j ] += (flodelta*5)>>4; }
|
||||||
if(j!=(int_fast16_t)spr.width()-1)
|
if(j!=(int32_t)spr.width()-1)
|
||||||
{ floyd_tab[!(i&1)][j+1] += (flodelta )>>4; }
|
{ floyd_tab[!(i&1)][j+1] += (flodelta )>>4; }
|
||||||
}
|
}
|
||||||
for(int floi=0;floi<spr.width();floi++) floyd_tab[i&1][floi]=0;
|
for(int floi=0;floi<spr.width();floi++) floyd_tab[i&1][floi]=0;
|
||||||
#else
|
#else
|
||||||
for(int_fast16_t j=0;j<w;j++){
|
for(int32_t j=0;j<w;j++){
|
||||||
uint_fast8_t buff8bit=0;
|
uint_fast8_t buff8bit=0;
|
||||||
for(uint_fast8_t b=0;b<8;b++)
|
for(uint_fast8_t b=0;b<8;b++)
|
||||||
buff8bit |= (bayer_tab[(b<<3)|(i&7)]<(greysc(readBuff[(j<<3)+b])>>2))<<(7-b);
|
buff8bit |= (bayer_tab[(b<<3)|(i&7)]<(greysc(readBuff[(j<<3)+b])>>2))<<(7-b);
|
||||||
@@ -241,23 +241,46 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
|
|||||||
//不支持的话使用单色抖动刷屏
|
//不支持的话使用单色抖动刷屏
|
||||||
void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y){
|
void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y){
|
||||||
//Serial.println("drv_draw16grey fx");
|
//Serial.println("drv_draw16grey fx");
|
||||||
const uint_fast16_t w = (spr.width()+7)>>3;
|
const uint32_t w = (spr.width()+7)>>3;
|
||||||
if((!w) || (!spr.height())) return;
|
if((!w) || (!spr.height())) return;
|
||||||
uint16_t *readBuff = new uint16_t[spr.width()];
|
uint16_t *readBuff = new uint16_t[spr.width()];
|
||||||
uint8_t *writeBuff = new uint8_t[w];
|
uint8_t *writeBuff = new uint8_t[w];
|
||||||
|
#ifdef FLOYD_DITHERING_16GREY
|
||||||
|
int16_t *floyd_tab[2];
|
||||||
|
floyd_tab[0] = new int16_t [spr.width()];
|
||||||
|
floyd_tab[1] = new int16_t [spr.width()];
|
||||||
|
#endif
|
||||||
sprbase.fillRect(x,y,spr.width(),spr.height(),1);
|
sprbase.fillRect(x,y,spr.width(),spr.height(),1);
|
||||||
bool negativeOrder=(drv_supportGreyscaling()==-16);
|
bool negativeOrder=(drv_supportGreyscaling()==-16);
|
||||||
drv_fullpart(0);
|
drv_fullpart(0);
|
||||||
_display((const uint8_t*)sprbase.getBuffer()); //先对区域慢刷白屏确保颜色正确
|
_display((const uint8_t*)sprbase.getBuffer()); //先对区域慢刷白屏确保颜色正确
|
||||||
drv_fullpart(1);
|
drv_fullpart(1);
|
||||||
for(uint_fast8_t k=1;k<16;k++){ //亮度为15的不用绘制,因为本来就是白色
|
for(uint_fast8_t k=1;k<16;k++){ //亮度为15的不用绘制,因为本来就是白色
|
||||||
|
#ifdef FLOYD_DITHERING_16GREY
|
||||||
|
for(int j=0;j<spr.width();j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
|
||||||
|
#endif
|
||||||
for(int i=0;i<spr.height();i++){
|
for(int i=0;i<spr.height();i++){
|
||||||
spr.readRect(0,i,spr.width(),1,readBuff);
|
spr.readRect(0,i,spr.width(),1,readBuff);
|
||||||
for(uint_fast16_t j=0;j<w;j++){
|
for(uint32_t j=0;j<w;j++){
|
||||||
uint_fast8_t buff8bit=0;
|
uint_fast8_t buff8bit=0;
|
||||||
for(uint_fast8_t b=0;b<8;b++){
|
for(uint_fast8_t b=0;b<8;b++){
|
||||||
//uint_fast8_t cg=greysc(readBuff[j*8+b])/16
|
#ifdef FLOYD_DITHERING_16GREY
|
||||||
|
uint_fast8_t cg=0;
|
||||||
|
int32_t fd = floyd_tab[i&1][(j<<3)+b]+(int32_t)((greysc(readBuff[(j<<3)+b])<<8)|greysc(readBuff[(j<<3)+b]));
|
||||||
|
while(fd>=0x800) {
|
||||||
|
cg++;
|
||||||
|
if(fd>=0) fd -= 0x1000;
|
||||||
|
}
|
||||||
|
if(fd<0) fd++;
|
||||||
|
if((j<<3)+b!=(uint32_t)spr.width()-1)
|
||||||
|
{ floyd_tab[i&1] [(j<<3)+b+1] += (fd*7)>>4; }
|
||||||
|
if((j<<3)+b) { floyd_tab[!(i&1)][(j<<3)+b-1] += (fd*3)>>4; }
|
||||||
|
{ floyd_tab[!(i&1)][(j<<3)+b ] += (fd*5)>>4; }
|
||||||
|
if((j<<3)+b!=(uint32_t)spr.width()-1)
|
||||||
|
{ floyd_tab[!(i&1)][(j<<3)+b+1] += (fd )>>4; }
|
||||||
|
#else
|
||||||
uint_fast8_t cg=greysc(readBuff[(j<<3)+b])>>4;
|
uint_fast8_t cg=greysc(readBuff[(j<<3)+b])>>4;
|
||||||
|
#endif
|
||||||
if(negativeOrder)
|
if(negativeOrder)
|
||||||
buff8bit |= (cg<k)<<((~b)&7);
|
buff8bit |= (cg<k)<<((~b)&7);
|
||||||
else{
|
else{
|
||||||
@@ -268,11 +291,18 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
|||||||
//sprbase.drawPixel(x+j,y+i,(greysc(readBuff[j])/16)==(15-k));
|
//sprbase.drawPixel(x+j,y+i,(greysc(readBuff[j])/16)==(15-k));
|
||||||
writeBuff[j]=buff8bit^0xff;
|
writeBuff[j]=buff8bit^0xff;
|
||||||
}
|
}
|
||||||
|
#ifdef FLOYD_DITHERING_16GREY
|
||||||
|
for(int floi=0;floi<spr.width();floi++) floyd_tab[i&1][floi]=0;
|
||||||
|
#endif
|
||||||
sprbase.drawBitmap(x,y+i,writeBuff,spr.width(),1,1,0);
|
sprbase.drawBitmap(x,y+i,writeBuff,spr.width(),1,1,0);
|
||||||
}
|
}
|
||||||
drv_draw16grey_step((const uint8_t*)sprbase.getBuffer(),k); //使用灰度显示函数
|
drv_draw16grey_step((const uint8_t*)sprbase.getBuffer(),k); //使用灰度显示函数
|
||||||
}
|
}
|
||||||
delete []readBuff;
|
delete []readBuff;
|
||||||
delete []writeBuff;
|
delete []writeBuff;
|
||||||
|
#ifdef FLOYD_DITHERING_16GREY
|
||||||
|
delete [] floyd_tab[0] ;
|
||||||
|
delete [] floyd_tab[1] ;
|
||||||
|
#endif
|
||||||
} /* END OF FILE. ReadGuy project.
|
} /* END OF FILE. ReadGuy project.
|
||||||
Copyright (C) 2023 FriendshipEnder. */
|
Copyright (C) 2023 FriendshipEnder. */
|
||||||
@@ -86,7 +86,7 @@ public:
|
|||||||
* @param gamma_on 是否对灰度值进行gamma校正(速度慢)
|
* @param gamma_on 是否对灰度值进行gamma校正(速度慢)
|
||||||
* @return uint32_t 颜色的灰度值
|
* @return uint32_t 颜色的灰度值
|
||||||
*/
|
*/
|
||||||
static int greysc(int got){ return (int)((got&0xf8)*299+(((got>>11)&0x1c)|((got<<5)&0xe0))*587+((got&0x1f00)>>5)*114)/978; }
|
static int greysc(int c){return(((c>>3)&0x1F)*79+(((c<<3)+(c>>13))&0x3F)*76+((c>>8)&0x1F)*30)>>5;}
|
||||||
void drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y); //分步完成灰度刷新
|
void drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y); //分步完成灰度刷新
|
||||||
void drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y);//省内存方式
|
void drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y);//省内存方式
|
||||||
void drv_draw16grey_step(const uint8_t *buf, int step){ //分步完成灰度刷新
|
void drv_draw16grey_step(const uint8_t *buf, int step){ //分步完成灰度刷新
|
||||||
|
|||||||
@@ -78,8 +78,6 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
}
|
}
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
//ips.readPixel(i,j);
|
|
||||||
DelayMs(150);
|
|
||||||
}
|
}
|
||||||
void drv::drv_sleep() {}
|
void drv::drv_sleep() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,10 @@
|
|||||||
#define _READGUY_VERSION_H_FILE
|
#define _READGUY_VERSION_H_FILE
|
||||||
|
|
||||||
#define READGUY_V_MAJOR 1
|
#define READGUY_V_MAJOR 1
|
||||||
#define READGUY_V_MINOR 0
|
#define READGUY_V_MINOR 1
|
||||||
#define READGUY_V_PATCH 2
|
#define READGUY_V_PATCH 1
|
||||||
#define READGUY_VERSION_VAL (READGUY_V_MAJOR*1000+READGUY_V_MINOR*100+READGUY_V_PATCH*10)
|
#define READGUY_VERSION_VAL (READGUY_V_MAJOR*1000+READGUY_V_MINOR*100+READGUY_V_PATCH*10)
|
||||||
#define READGUY_VERSION "1.0.2"
|
#define READGUY_VERSION "1.1.1"
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define _READGUY_PLATFORM "ESP8266"
|
#define _READGUY_PLATFORM "ESP8266"
|
||||||
@@ -52,8 +52,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _GITHUB_LINK "https://github.com/fsender/readguy"
|
#define _GITHUB_LINK "github.com/fsender/readguy"
|
||||||
#define _BILIBILI_LINK "https://space.bilibili.com/180327370"
|
#define _BILIBILI_LINK "www.bilibili.com/video/BV1f94y187wz"
|
||||||
|
|
||||||
|
|
||||||
#endif /* END OF FILE. ReadGuy project.
|
#endif /* END OF FILE. ReadGuy project.
|
||||||
|
|||||||
1003
src/guy_wireless.cpp
1003
src/guy_wireless.cpp
File diff suppressed because it is too large
Load Diff
141
src/readguy.cpp
141
src/readguy.cpp
@@ -32,37 +32,35 @@
|
|||||||
#define INPUT_PULLDOWN INPUT
|
#define INPUT_PULLDOWN INPUT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
guy_button readguy_driver::btn_rd[3];
|
guy_button ReadguyDriver::btn_rd[3];
|
||||||
int8_t readguy_driver::pin_cmx=-1;
|
int8_t ReadguyDriver::pin_cmx=-1;
|
||||||
|
|
||||||
const PROGMEM char readguy_driver::projname[8] = "readguy";
|
const PROGMEM char ReadguyDriver::projname[8] = "readguy";
|
||||||
const PROGMEM char readguy_driver::tagname[9] = "hwconfig";
|
const PROGMEM char ReadguyDriver::tagname[7] = "hwconf";
|
||||||
volatile uint8_t readguy_driver::spibz=0;
|
volatile uint8_t ReadguyDriver::spibz=0;
|
||||||
#ifndef ESP8266
|
#ifndef ESP8266
|
||||||
SPIClass *readguy_driver::sd_spi =nullptr;
|
SPIClass *ReadguyDriver::sd_spi =nullptr;
|
||||||
SPIClass *readguy_driver::epd_spi=nullptr;
|
SPIClass *ReadguyDriver::epd_spi=nullptr;
|
||||||
TaskHandle_t readguy_driver::btn_handle;
|
TaskHandle_t ReadguyDriver::btn_handle;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
readguy_driver::readguy_driver(){
|
ReadguyDriver::ReadguyDriver(){
|
||||||
READGUY_cali = 0; // config_data[0] 的初始值为0
|
READGUY_cali = 0; // config_data[0] 的初始值为0
|
||||||
READGUY_sd_ok = 0; //初始默认SD卡未成功初始化
|
READGUY_sd_ok = 0; //初始默认SD卡未成功初始化
|
||||||
READGUY_buttons = 0; //初始情况下没有按钮
|
READGUY_buttons = 0; //初始情况下没有按钮
|
||||||
}
|
}
|
||||||
uint8_t readguy_driver::init(){
|
uint8_t ReadguyDriver::init(uint8_t WiFiSet){ //WiFiSet: 是否保持AP服务器一直处于打开状态
|
||||||
if(READGUY_cali==127) //已经初始化过了一次了, 为了防止里面一些volatile的东西出现问题....还是退出吧
|
if(READGUY_cali==127) //已经初始化过了一次了, 为了防止里面一些volatile的东西出现问题....还是退出吧
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef DYNAMIC_PIN_SETTINGS
|
#ifdef DYNAMIC_PIN_SETTINGS
|
||||||
//char config_data[18];
|
|
||||||
nvs_init();
|
nvs_init();
|
||||||
#if (!defined(INDEV_DEBUG))
|
#if (!defined(INDEV_DEBUG))
|
||||||
if(!nvs_read()){ //如果NVS没有录入数据, 需要打开WiFiAP模式初始化录入引脚数据
|
if(!nvs_read()){ //如果NVS没有录入数据, 需要打开WiFiAP模式初始化录入引脚数据
|
||||||
#endif
|
#endif
|
||||||
#ifdef READGUY_ESP_ENABLE_WIFI
|
#ifdef READGUY_ESP_ENABLE_WIFI
|
||||||
//开启WiFi和服务器, 然后网页获取数据
|
ap_setup(); //开启WiFi和服务器, 然后网页获取数据. 如果保持WiFi AP模式打开, 则显示此标语.
|
||||||
//以下代码仅供测试
|
if(WiFiSet) server_setup(F("引脚配置完成。请稍后访问<a href=\"/\">此页面</a>浏览更多内容。"));
|
||||||
ap_setup();
|
else server_setup(F("引脚配置完成, WiFi即将关闭。")); //直接进入主页.
|
||||||
server_setup();
|
|
||||||
for(uint32_t i=UINT32_MAX;millis()<i;){
|
for(uint32_t i=UINT32_MAX;millis()<i;){
|
||||||
if(server_loop()){
|
if(server_loop()){
|
||||||
if(i==UINT32_MAX) i=millis()+500;
|
if(i==UINT32_MAX) i=millis()+500;
|
||||||
@@ -71,15 +69,14 @@ uint8_t readguy_driver::init(){
|
|||||||
}
|
}
|
||||||
//delay(300); //等待网页加载完再关掉WiFi. (有没有用存疑)
|
//delay(300); //等待网页加载完再关掉WiFi. (有没有用存疑)
|
||||||
server_end();
|
server_end();
|
||||||
WiFi.mode(WIFI_OFF);
|
if(!WiFiSet) WiFi.mode(WIFI_OFF);
|
||||||
fillScreen(1);
|
fillScreen(1);
|
||||||
#endif
|
#endif
|
||||||
#if (!defined(INDEV_DEBUG))
|
#if (!defined(INDEV_DEBUG))
|
||||||
}
|
}
|
||||||
else{ //看来NVS有数据, //从NVS加载数据, 哪怕前面的数据刚刚写入, 还没读取
|
else{ //看来NVS有数据, //从NVS加载数据, 哪怕前面的数据刚刚写入, 还没读取
|
||||||
//for(unsigned int i=0;i<sizeof(config_data);i++){
|
if(WiFiSet>=2) WiFi.begin(); //连接到上次存储在flash NVS中的WiFi.
|
||||||
// Serial.printf_P(PSTR("data %u: %d\n"),i,config_data[i]);
|
else if(WiFiSet==1) ap_setup();
|
||||||
//}
|
|
||||||
if(checkEpdDriver()!=127) setEpdDriver(); //初始化屏幕
|
if(checkEpdDriver()!=127) setEpdDriver(); //初始化屏幕
|
||||||
else for(;;); //此处可能添加程序rollback等功能操作(比如返回加载上一个程序)
|
else for(;;); //此处可能添加程序rollback等功能操作(比如返回加载上一个程序)
|
||||||
setSDcardDriver();
|
setSDcardDriver();
|
||||||
@@ -97,7 +94,7 @@ uint8_t readguy_driver::init(){
|
|||||||
READGUY_cali=127;
|
READGUY_cali=127;
|
||||||
return READGUY_sd_ok;
|
return READGUY_sd_ok;
|
||||||
}
|
}
|
||||||
uint8_t readguy_driver::checkEpdDriver(){
|
uint8_t ReadguyDriver::checkEpdDriver(){
|
||||||
#ifdef DYNAMIC_PIN_SETTINGS
|
#ifdef DYNAMIC_PIN_SETTINGS
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define TEST_ONLY_VALUE 5
|
#define TEST_ONLY_VALUE 5
|
||||||
@@ -155,7 +152,6 @@ uint8_t readguy_driver::checkEpdDriver(){
|
|||||||
Serial.println(F("[ERR] EPD DRIVER IC NOT SUPPORTED!\n"));
|
Serial.println(F("[ERR] EPD DRIVER IC NOT SUPPORTED!\n"));
|
||||||
return 127;
|
return 127;
|
||||||
}
|
}
|
||||||
// this calls the peripheral hardware interface, see epdif 初始化硬件SPI层(HAL层)
|
|
||||||
#if (defined(ESP8266))
|
#if (defined(ESP8266))
|
||||||
SPI.begin();
|
SPI.begin();
|
||||||
SPI.setFrequency(ESP8266_SPI_FREQUENCY); ///< 1MHz
|
SPI.setFrequency(ESP8266_SPI_FREQUENCY); ///< 1MHz
|
||||||
@@ -176,7 +172,7 @@ uint8_t readguy_driver::checkEpdDriver(){
|
|||||||
Serial.println(F("IfInit OK"));
|
Serial.println(F("IfInit OK"));
|
||||||
return READGUY_epd_type;
|
return READGUY_epd_type;
|
||||||
}
|
}
|
||||||
void readguy_driver::setEpdDriver(){
|
void ReadguyDriver::setEpdDriver(){
|
||||||
guy_dev->spi_tr_release = in_release;
|
guy_dev->spi_tr_release = in_release;
|
||||||
guy_dev->spi_tr_press = in_press;
|
guy_dev->spi_tr_press = in_press;
|
||||||
guy_dev->drv_init(); //初始化epd驱动层
|
guy_dev->drv_init(); //初始化epd驱动层
|
||||||
@@ -195,7 +191,7 @@ void readguy_driver::setEpdDriver(){
|
|||||||
setTextColor(0);
|
setTextColor(0);
|
||||||
fillScreen(1); //开始先全屏白色
|
fillScreen(1); //开始先全屏白色
|
||||||
}
|
}
|
||||||
bool readguy_driver::setSDcardDriver(){
|
bool ReadguyDriver::setSDcardDriver(){
|
||||||
/*重要信息: 有些引脚冲突是难以避免的, 比如8266 尤其需要重写这部分代码
|
/*重要信息: 有些引脚冲突是难以避免的, 比如8266 尤其需要重写这部分代码
|
||||||
对于esp32也要注意这个引脚是否是一个合法的引脚
|
对于esp32也要注意这个引脚是否是一个合法的引脚
|
||||||
对于esp8266真的要重写, 比如esp8266需要允许某些引脚是可以复用的
|
对于esp8266真的要重写, 比如esp8266需要允许某些引脚是可以复用的
|
||||||
@@ -235,7 +231,7 @@ bool readguy_driver::setSDcardDriver(){
|
|||||||
}
|
}
|
||||||
return READGUY_sd_ok;
|
return READGUY_sd_ok;
|
||||||
}
|
}
|
||||||
void readguy_driver::setButtonDriver(){
|
void ReadguyDriver::setButtonDriver(){
|
||||||
if(READGUY_btn1) { //初始化按键. 注意高电平触发的引脚在初始化时要设置为下拉
|
if(READGUY_btn1) { //初始化按键. 注意高电平触发的引脚在初始化时要设置为下拉
|
||||||
int8_t btn_pin=abs(READGUY_btn1)-1;
|
int8_t btn_pin=abs(READGUY_btn1)-1;
|
||||||
#if defined(ESP8266) //只有ESP8266是支持16引脚pulldown功能的, 而不支持pullup
|
#if defined(ESP8266) //只有ESP8266是支持16引脚pulldown功能的, 而不支持pullup
|
||||||
@@ -339,7 +335,7 @@ void readguy_driver::setButtonDriver(){
|
|||||||
}
|
}
|
||||||
} //关于按键策略, 我们在此使用多个Button2的类, 然后在一个task共享变量来确定上一个按键状态
|
} //关于按键策略, 我们在此使用多个Button2的类, 然后在一个task共享变量来确定上一个按键状态
|
||||||
}
|
}
|
||||||
fs::FS &readguy_driver::guyFS(uint8_t initSD){
|
fs::FS &ReadguyDriver::guyFS(uint8_t initSD){
|
||||||
if(initSD==2 || (!READGUY_sd_ok && initSD)) setSDcardDriver();
|
if(initSD==2 || (!READGUY_sd_ok && initSD)) setSDcardDriver();
|
||||||
if(READGUY_sd_ok){
|
if(READGUY_sd_ok){
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@@ -354,7 +350,7 @@ fs::FS &readguy_driver::guyFS(uint8_t initSD){
|
|||||||
return SPIFFS;
|
return SPIFFS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void readguy_driver::setBright(int d){
|
void ReadguyDriver::setBright(int d){
|
||||||
if(currentBright>=0 && d>=0 && d<=255){
|
if(currentBright>=0 && d>=0 && d<=255){
|
||||||
currentBright=d;
|
currentBright=d;
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@@ -368,7 +364,7 @@ void readguy_driver::setBright(int d){
|
|||||||
digitalWrite(READGUY_bl_pin,d?HIGH:LOW);
|
digitalWrite(READGUY_bl_pin,d?HIGH:LOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void readguy_driver::display(bool part){
|
void ReadguyDriver::display(bool part){
|
||||||
//真的是我c++的盲区了啊....搜索了半天才找到可以这么玩的
|
//真的是我c++的盲区了啊....搜索了半天才找到可以这么玩的
|
||||||
//......可惜'dynamic_cast' not permitted with -fno-rtti
|
//......可惜'dynamic_cast' not permitted with -fno-rtti
|
||||||
// static bool _part = 0; 记忆上次到底是full还是part, 注意启动时默认为full
|
// static bool _part = 0; 记忆上次到底是full还是part, 注意启动时默认为full
|
||||||
@@ -379,7 +375,7 @@ void readguy_driver::display(bool part){
|
|||||||
//in_release(); //恢复
|
//in_release(); //恢复
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void readguy_driver::display(std::function<uint8_t(int)> f, bool part){
|
void ReadguyDriver::display(std::function<uint8_t(int)> f, bool part){
|
||||||
if(READGUY_cali==127){
|
if(READGUY_cali==127){
|
||||||
//in_press(); //暂停, 然后读取按键状态 spibz
|
//in_press(); //暂停, 然后读取按键状态 spibz
|
||||||
guy_dev->drv_fullpart(part);
|
guy_dev->drv_fullpart(part);
|
||||||
@@ -387,106 +383,113 @@ void readguy_driver::display(std::function<uint8_t(int)> f, bool part){
|
|||||||
//in_release(); //恢复
|
//in_release(); //恢复
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void readguy_driver::drawImage(LGFX_Sprite &spr,uint16_t x,uint16_t y) {
|
void ReadguyDriver::drawImage(LGFX_Sprite &spr,uint16_t x,uint16_t y) {
|
||||||
if(READGUY_cali==127) guy_dev->drv_drawImage(*this, spr, x, y);
|
if(READGUY_cali==127) guy_dev->drv_drawImage(*this, spr, x, y);
|
||||||
}
|
}
|
||||||
void readguy_driver::setDepth(uint8_t d){
|
void ReadguyDriver::setDepth(uint8_t d){
|
||||||
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling()) guy_dev->drv_setDepth(d);
|
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling()) guy_dev->drv_setDepth(d);
|
||||||
}
|
}
|
||||||
void readguy_driver::draw16grey(LGFX_Sprite &spr,uint16_t x,uint16_t y){
|
void ReadguyDriver::draw16grey(LGFX_Sprite &spr,uint16_t x,uint16_t y){
|
||||||
if(READGUY_cali!=127) return;
|
if(READGUY_cali!=127) return;
|
||||||
if(guy_dev->drv_supportGreyscaling() && (spr.getColorDepth()&0xff)>1)
|
if(guy_dev->drv_supportGreyscaling() && (spr.getColorDepth()&0xff)>1)
|
||||||
return guy_dev->drv_draw16grey(*this,spr,x,y);
|
return guy_dev->drv_draw16grey(*this,spr,x,y);
|
||||||
guy_dev->drv_drawImage(*this, spr, x, y);
|
guy_dev->drv_drawImage(*this, spr, x, y);
|
||||||
}
|
}
|
||||||
void readguy_driver::draw16greyStep(int step){
|
void ReadguyDriver::draw16greyStep(int step){
|
||||||
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling())
|
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling())
|
||||||
return guy_dev->drv_draw16grey_step((const uint8_t *)this->getBuffer(),step);
|
return guy_dev->drv_draw16grey_step((const uint8_t *)this->getBuffer(),step);
|
||||||
}
|
}
|
||||||
void readguy_driver::draw16greyStep(std::function<uint8_t(int)> f, int step){
|
void ReadguyDriver::draw16greyStep(std::function<uint8_t(int)> f, int step){
|
||||||
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling())
|
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling())
|
||||||
return guy_dev->drv_draw16grey_step(f,step);
|
return guy_dev->drv_draw16grey_step(f,step);
|
||||||
}
|
}
|
||||||
void readguy_driver::invertDisplay(){
|
void ReadguyDriver::invertDisplay(){
|
||||||
if(READGUY_cali==127){
|
if(READGUY_cali==127){
|
||||||
const int pixels=((guy_dev->drv_width()+7)>>3)*guy_dev->drv_height();
|
const int pixels=((guy_dev->drv_width()+7)>>3)*guy_dev->drv_height();
|
||||||
for(int i=0;i<pixels;i++)
|
for(int i=0;i<pixels;i++)
|
||||||
((uint8_t*)(getBuffer()))[i]=uint8_t(~(((uint8_t*)(getBuffer()))[i]));
|
((uint8_t*)(getBuffer()))[i]=uint8_t(~(((uint8_t*)(getBuffer()))[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void readguy_driver::sleepEPD(){
|
void ReadguyDriver::sleepEPD(){
|
||||||
if(READGUY_cali==127) guy_dev->drv_sleep();
|
if(READGUY_cali==127) guy_dev->drv_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (!defined(DYNAMIC_PIN_SETTINGS)) //do nothing here.
|
#if (!defined(DYNAMIC_PIN_SETTINGS)) //do nothing here.
|
||||||
#elif (defined(INDEV_DEBUG))
|
#elif (defined(INDEV_DEBUG))
|
||||||
void readguy_driver::nvs_init(){
|
void ReadguyDriver::nvs_init(){
|
||||||
}
|
}
|
||||||
void readguy_driver::nvs_deinit(){
|
void ReadguyDriver::nvs_deinit(){
|
||||||
}
|
}
|
||||||
bool readguy_driver::nvs_read(){
|
bool ReadguyDriver::nvs_read(){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
void readguy_driver::nvs_write(){
|
void ReadguyDriver::nvs_write(){
|
||||||
}
|
}
|
||||||
#elif (defined(ESP8266))
|
#elif (defined(ESP8266))
|
||||||
void readguy_driver::nvs_init(){
|
void ReadguyDriver::nvs_init(){
|
||||||
EEPROM.begin(128);
|
EEPROM.begin(32);
|
||||||
}
|
}
|
||||||
void readguy_driver::nvs_deinit(){
|
void ReadguyDriver::nvs_deinit(){
|
||||||
EEPROM.commit();
|
EEPROM.commit();
|
||||||
EEPROM.end();
|
EEPROM.end();
|
||||||
}
|
}
|
||||||
bool readguy_driver::nvs_read(){
|
bool ReadguyDriver::nvs_read(){
|
||||||
char s[8];
|
char s[8];
|
||||||
for(unsigned int i=0;i<sizeof(config_data)+8;i++){
|
for(unsigned int i=0;i<sizeof(config_data)+8;i++){
|
||||||
int8_t rd=(int8_t)EEPROM.read(100+i);
|
int8_t rd=(int8_t)EEPROM.read(2+i);
|
||||||
if(i>=8) config_data[i-8] = rd;
|
if(i>=8) config_data[i-8] = rd;
|
||||||
else s[i]=(char)rd;
|
else s[i]=(char)rd;
|
||||||
}
|
}
|
||||||
Serial.printf("Get NVS...%d\n", config_data[0]);
|
Serial.printf("Get NVS...%d\n", config_data[0]);
|
||||||
return !(strcmp_P(s,projname));
|
return !(strcmp_P(s,projname));
|
||||||
}
|
}
|
||||||
void readguy_driver::nvs_write(){
|
void ReadguyDriver::nvs_write(){
|
||||||
for(unsigned int i=0;i<sizeof(config_data)+8;i++){
|
for(unsigned int i=0;i<sizeof(config_data)+8;i++){
|
||||||
EEPROM.write(100+i,(uint8_t)(i<8?pgm_read_byte(projname+i):config_data[i-8]));
|
EEPROM.write(2+i,(uint8_t)(i<8?pgm_read_byte(projname+i):config_data[i-8]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void readguy_driver::nvs_init(){
|
void ReadguyDriver::nvs_init(){
|
||||||
nvsData.begin(projname); //初始化NVS
|
nvsData.begin(projname); //初始化NVS
|
||||||
}
|
}
|
||||||
void readguy_driver::nvs_deinit(){
|
void ReadguyDriver::nvs_deinit(){
|
||||||
nvsData.end(); //用完NVS记得关闭, 省内存
|
nvsData.end(); //用完NVS记得关闭, 省内存
|
||||||
}
|
}
|
||||||
bool readguy_driver::nvs_read(){
|
bool ReadguyDriver::nvs_read(){ //此处需要处理一些有关I2C的内容
|
||||||
bool suc = nvsData.isKey(tagname);
|
if(!nvsData.isKey(tagname)) return 0; //没有这个键值
|
||||||
if(suc) nvsData.getBytes(tagname,config_data,sizeof(config_data));
|
size_t len=nvsData.getBytes(tagname,config_data,sizeof(config_data)); //读取的数据长度
|
||||||
return suc;
|
/*if(len<sizeof(config_data)){ //旧版本格式无法获取I2C相关数据, 设置为-1.
|
||||||
|
for(int i=sizeof(config_data)-1;i>=15;i--) //使用新版本格式来存储相关数据
|
||||||
|
config_data[i]=config_data[i-2];
|
||||||
|
READGUY_i2c_sda=-1;
|
||||||
|
READGUY_i2c_scl=-1;
|
||||||
|
nvsData.putBytes(tagname,config_data,sizeof(config_data)); //用新版本格式保存
|
||||||
|
}*/
|
||||||
|
return len==sizeof(config_data);
|
||||||
}
|
}
|
||||||
void readguy_driver::nvs_write(){
|
void ReadguyDriver::nvs_write(){
|
||||||
if(nvsData.isKey(tagname)) nvsData.remove(tagname);
|
if(nvsData.isKey(tagname)) nvsData.remove(tagname);
|
||||||
nvsData.putBytes(tagname,config_data,sizeof(config_data)); //正式写入NVS
|
nvsData.putBytes(tagname,config_data,sizeof(config_data)); //正式写入NVS
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t readguy_driver::getBtn_impl(){ //按钮不可用, 返回0.
|
uint8_t ReadguyDriver::getBtn_impl(){ //按钮不可用, 返回0.
|
||||||
uint8_t res1,res2,res3,res4=0;
|
uint8_t res1,res2,res3,res4=0;
|
||||||
switch(READGUY_buttons){
|
switch(READGUY_buttons){
|
||||||
case 1:
|
case 1:
|
||||||
res1=btn_rd[0].read();
|
res1=btn_rd[0].read();
|
||||||
if(res1 == 1) res4 |= 1;
|
if(res1 == 1) res4 |= 1; //点按
|
||||||
else if(res1 == 2) res4 |= 2;
|
else if(res1 == 2) res4 |= 2; //双击
|
||||||
else if(res1 == 4) res4 |= 4;
|
else if(res1 == 4) res4 |= 4; //长按-确定
|
||||||
else if(res1 == 3) res4 |= 8;
|
else if(res1 == 3) res4 |= 8; //三击-返回
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
res1=btn_rd[0].read();
|
res1=btn_rd[0].read(); //两个按钮引脚都读取
|
||||||
res2=btn_rd[1].read();
|
res2=btn_rd[1].read();
|
||||||
if(res1 == 1) res4 |= 1;
|
if(res1 == 1) res4 |= 1; //左键点按-向下翻页
|
||||||
else if(res1 == 4) res4 |= 2;
|
else if(res1 == 4) res4 |= 2; //左键长按-向上翻页
|
||||||
if(res2 == 1) res4 |= 4;
|
if(res2 == 1) res4 |= 4; //右键点按-确定
|
||||||
else if(res2 == 4) res4 |= 8;
|
else if(res2 == 4) res4 |= 8; //右键长按-返回
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
res1=btn_rd[0].read();
|
res1=btn_rd[0].read();
|
||||||
@@ -500,20 +503,20 @@ uint8_t readguy_driver::getBtn_impl(){ //按钮不可用, 返回0.
|
|||||||
}
|
}
|
||||||
return res4;
|
return res4;
|
||||||
}
|
}
|
||||||
void readguy_driver::looptask(){ //均为类内静态数据
|
void ReadguyDriver::looptask(){ //均为类内静态数据
|
||||||
btn_rd[0].loop();
|
btn_rd[0].loop();
|
||||||
btn_rd[1].loop();
|
btn_rd[1].loop();
|
||||||
btn_rd[2].loop();
|
btn_rd[2].loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t readguy_driver::rd_btn_f(uint8_t btn){
|
uint8_t ReadguyDriver::rd_btn_f(uint8_t btn){
|
||||||
static uint8_t lstate=0; //上次从dc引脚读到的电平
|
static uint8_t lstate=0; //上次从dc引脚读到的电平
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if(btn==readguy_driver::pin_cmx && spibz) return lstate;
|
if(btn==ReadguyDriver::pin_cmx && spibz) return lstate;
|
||||||
if(btn==D5||btn==D6||btn==D7||btn==readguy_driver::pin_cmx)
|
if(btn==D5||btn==D6||btn==D7||btn==ReadguyDriver::pin_cmx)
|
||||||
pinMode(btn,INPUT_PULLUP);//针对那些复用引脚做出的优化
|
pinMode(btn,INPUT_PULLUP);//针对那些复用引脚做出的优化
|
||||||
uint8_t readb = digitalRead(btn);
|
uint8_t readb = digitalRead(btn);
|
||||||
if(btn==readguy_driver::pin_cmx) {
|
if(btn==ReadguyDriver::pin_cmx) {
|
||||||
//Serial.printf("rd D1.. %d\n",spibz);
|
//Serial.printf("rd D1.. %d\n",spibz);
|
||||||
pinMode(btn,OUTPUT); //如果有复用引脚, 它们的一部分默认需要保持输出状态, 比如复用的DC引脚
|
pinMode(btn,OUTPUT); //如果有复用引脚, 它们的一部分默认需要保持输出状态, 比如复用的DC引脚
|
||||||
digitalWrite(btn,HIGH); //这些引脚的默认电平都是高电平
|
digitalWrite(btn,HIGH); //这些引脚的默认电平都是高电平
|
||||||
@@ -522,7 +525,7 @@ uint8_t readguy_driver::rd_btn_f(uint8_t btn){
|
|||||||
else if(btn==D5||btn==D6||btn==D7) pinMode(btn,SPECIAL); //针对SPI引脚进行专门的优化
|
else if(btn==D5||btn==D6||btn==D7) pinMode(btn,SPECIAL); //针对SPI引脚进行专门的优化
|
||||||
return readb;
|
return readb;
|
||||||
#else //ESP32不再允许SPI相关引脚复用
|
#else //ESP32不再允许SPI相关引脚复用
|
||||||
if(btn!=readguy_driver::pin_cmx)
|
if(btn!=ReadguyDriver::pin_cmx)
|
||||||
return digitalRead(btn);
|
return digitalRead(btn);
|
||||||
if(spibz) return lstate;
|
if(spibz) return lstate;
|
||||||
pinMode(btn,INPUT_PULLUP);
|
pinMode(btn,INPUT_PULLUP);
|
||||||
|
|||||||
118
src/readguy.h
118
src/readguy.h
@@ -36,7 +36,6 @@
|
|||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
|
|
||||||
//#include <esp-fs-webserver.h>
|
|
||||||
#define LGFX_USE_V1
|
#define LGFX_USE_V1
|
||||||
#include <LovyanGFX.hpp>
|
#include <LovyanGFX.hpp>
|
||||||
|
|
||||||
@@ -120,25 +119,37 @@
|
|||||||
#define READGUY_sd_mosi (config_data[10])// 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
|
#define READGUY_sd_mosi (config_data[10])// 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
|
||||||
#define READGUY_sd_sclk (config_data[11])// 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
|
#define READGUY_sd_sclk (config_data[11])// 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
|
||||||
#define READGUY_sd_cs (config_data[12])// 目标sd卡的 CS 引脚.
|
#define READGUY_sd_cs (config_data[12])// 目标sd卡的 CS 引脚.
|
||||||
|
#define READGUY_i2c_sda (config_data[13])// 目标i2c总线的SDA引脚, 当且仅当启用i2c总线时才生效
|
||||||
|
#define READGUY_i2c_scl (config_data[14])// 目标i2c总线的SCL引脚, 当且仅当启用i2c总线时才生效
|
||||||
//按键驱动部分, 为负代表高触发, 否则低触发,
|
//按键驱动部分, 为负代表高触发, 否则低触发,
|
||||||
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
|
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
|
||||||
#define READGUY_btn1 (config_data[13])
|
#define READGUY_btn1 (config_data[15])
|
||||||
#define READGUY_btn2 (config_data[14])
|
#define READGUY_btn2 (config_data[16])
|
||||||
#define READGUY_btn3 (config_data[15])
|
#define READGUY_btn3 (config_data[17])
|
||||||
#define READGUY_bl_pin (config_data[16])//前置光接口引脚IO
|
#define READGUY_bl_pin (config_data[18])//前置光接口引脚IO
|
||||||
#define READGUY_rtc_type (config_data[17])//使用的RTC型号(待定, 还没用上)
|
#define READGUY_rtc_type (config_data[19])//使用的RTC型号(待定, 还没用上)
|
||||||
#define READGUY_sd_ok (config_data[18]) //SD卡已经成功初始化
|
#define READGUY_sd_ok (config_data[20]) //SD卡已经成功初始化
|
||||||
#define READGUY_buttons (config_data[19]) //按钮个数, 0-3都有可能
|
#define READGUY_buttons (config_data[21]) //按钮个数, 0-3都有可能
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class readguy_driver: public LGFX_Sprite{ // readguy 基础类
|
class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
||||||
public:
|
public:
|
||||||
readguy_driver();
|
#ifdef READGUY_ESP_ENABLE_WIFI
|
||||||
|
#ifdef ESP8266
|
||||||
|
typedef ESP8266WebServer ReadguyWebServer;
|
||||||
|
typedef ESP8266HTTPUpdateServer ReadguyUpdateServer;
|
||||||
|
#else
|
||||||
|
typedef WebServer ReadguyWebServer;
|
||||||
|
typedef HTTPUpdateServer ReadguyUpdateServer;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
ReadguyDriver();
|
||||||
/** @brief 初始化readguy
|
/** @brief 初始化readguy
|
||||||
|
* @param WiFiSet 是否保持AP模式关闭. 0:配网完成自动关WiFi, 1:需要手动调用 WiFi.mode(WIFI_OFF) 关闭WiFi.
|
||||||
|
* 2:自动连接到已存的WiFi, 但不等待连接成功
|
||||||
* @return SD卡是否就绪
|
* @return SD卡是否就绪
|
||||||
*/
|
*/
|
||||||
uint8_t init();
|
uint8_t init(uint8_t WiFiSet = 0);
|
||||||
//LGFX_Sprite g() const { return gfx; }; //使用 gfx 绘制内容.
|
|
||||||
/// @brief 设置显示亮度
|
/// @brief 设置显示亮度
|
||||||
void setBright(int d);
|
void setBright(int d);
|
||||||
/// @brief 返回显示亮度
|
/// @brief 返回显示亮度
|
||||||
@@ -187,22 +198,22 @@ class readguy_driver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
void sleepEPD(void);
|
void sleepEPD(void);
|
||||||
/// @brief ap配网设置页面
|
/// @brief ap配网设置页面
|
||||||
typedef struct {
|
typedef struct {
|
||||||
String event;
|
String linkname;
|
||||||
int method; //其实这里的method的类型应当为HTTPMethod, 但是为了兼容无wifi的功能, 使用了int格式
|
String event; //链接名称 事件URI
|
||||||
std::function<void()> func;
|
std::function<void(ReadguyWebServer*)> func; //触发时执行的函数
|
||||||
} serveFunc;
|
} serveFunc;
|
||||||
#ifdef READGUY_ESP_ENABLE_WIFI
|
#ifdef READGUY_ESP_ENABLE_WIFI
|
||||||
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
|
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
|
||||||
void ap_setup();
|
void ap_setup();
|
||||||
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
|
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
|
||||||
void server_setup(const serveFunc *serveFuncs = nullptr, int funcs = 0);
|
void server_setup(const String ¬ify=emptyString, const serveFunc *serveFuncs = nullptr, int funcs = 0);
|
||||||
bool server_loop();
|
bool server_loop();
|
||||||
void server_end() { sv.stop(); MDNS.end(); }
|
void server_end();
|
||||||
#else
|
#else
|
||||||
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
|
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
|
||||||
void ap_setup(){}
|
void ap_setup(){}
|
||||||
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
|
/// @brief 初始化服务器模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
|
||||||
void server_setup(const serveFunc *serveFuncs = nullptr, int funcs = 0){}
|
void server_setup(const String ¬ify=emptyString, const serveFunc *serveFuncs = nullptr, int funcs = 0){}
|
||||||
bool server_loop(){ return true; }
|
bool server_loop(){ return true; }
|
||||||
void server_end(){}
|
void server_end(){}
|
||||||
#endif
|
#endif
|
||||||
@@ -229,10 +240,10 @@ class readguy_driver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
//以下是支持的所有屏幕型号 Add devices here!
|
//以下是支持的所有屏幕型号 Add devices here!
|
||||||
//添加屏幕驱动范例: 直接添加对应屏幕的类就可以用了
|
//添加屏幕驱动范例: 直接添加对应屏幕的类就可以用了
|
||||||
static const char projname[8];
|
static const char projname[8];
|
||||||
static const char tagname[9];
|
static const char tagname[7];
|
||||||
//数据是否已经校准
|
//uint8_t config_wifi=0; //是否强行在初始化期间设置WiFi.
|
||||||
#ifdef DYNAMIC_PIN_SETTINGS
|
#ifdef DYNAMIC_PIN_SETTINGS//数据是否已经校准
|
||||||
int8_t config_data[20];
|
int8_t config_data[22];
|
||||||
char randomch[4]; //校验用字符串
|
char randomch[4]; //校验用字符串
|
||||||
void nvs_init(); //初始化持久存储器.
|
void nvs_init(); //初始化持久存储器.
|
||||||
void nvs_deinit();//保存持久存储器的内容
|
void nvs_deinit();//保存持久存储器的内容
|
||||||
@@ -245,7 +256,6 @@ class readguy_driver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
#endif
|
#endif
|
||||||
int epd_OK=0; //墨水屏可用
|
int epd_OK=0; //墨水屏可用
|
||||||
int currentBright = -3; //初始亮度
|
int currentBright = -3; //初始亮度
|
||||||
//.........敬请期待更多屏幕ic...........
|
|
||||||
|
|
||||||
//LGFX_Sprite gfx; // 图形引擎类指针, 可以用这个指针去操作屏幕缓冲区
|
//LGFX_Sprite gfx; // 图形引擎类指针, 可以用这个指针去操作屏幕缓冲区
|
||||||
readguyEpdBase *guy_dev = nullptr;
|
readguyEpdBase *guy_dev = nullptr;
|
||||||
@@ -255,19 +265,9 @@ class readguy_driver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
//template <class T> void t_display(T t);
|
//template <class T> void t_display(T t);
|
||||||
|
|
||||||
#if defined(ESP8266)
|
#if defined(ESP8266)
|
||||||
#ifdef READGUY_ESP_ENABLE_WIFI
|
|
||||||
ESP8266WebServer sv;
|
|
||||||
ESP8266HTTPUpdateServer httpUpdater;
|
|
||||||
String w_ssid;
|
|
||||||
String w_psk;
|
|
||||||
#endif
|
|
||||||
//对于esp8266, 需要注册到ticker
|
//对于esp8266, 需要注册到ticker
|
||||||
Ticker btnTask;
|
Ticker btnTask;
|
||||||
#else
|
#else
|
||||||
#ifdef READGUY_ESP_ENABLE_WIFI
|
|
||||||
WebServer sv;
|
|
||||||
HTTPUpdateServer httpUpdater;
|
|
||||||
#endif
|
|
||||||
#ifdef DYNAMIC_PIN_SETTINGS
|
#ifdef DYNAMIC_PIN_SETTINGS
|
||||||
//NVS数据操作函数, 无NVS的使用EEProm的最后几个字节块
|
//NVS数据操作函数, 无NVS的使用EEProm的最后几个字节块
|
||||||
Preferences nvsData;
|
Preferences nvsData;
|
||||||
@@ -277,12 +277,18 @@ class readguy_driver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
static TaskHandle_t btn_handle;
|
static TaskHandle_t btn_handle;
|
||||||
#endif
|
#endif
|
||||||
#ifdef READGUY_ESP_ENABLE_WIFI
|
#ifdef READGUY_ESP_ENABLE_WIFI
|
||||||
|
ReadguyWebServer sv;
|
||||||
|
ReadguyUpdateServer httpUpdater;
|
||||||
|
String guy_notify=emptyString; //嵌入在网页中的自定义标语
|
||||||
|
int sfuncs=-1;
|
||||||
|
String* sfnames=nullptr;
|
||||||
|
String* sfevents=nullptr;
|
||||||
void handleInit(); //服务器初始化系统(初次访问时, 跳转至引脚设定函数)
|
void handleInit(); //服务器初始化系统(初次访问时, 跳转至引脚设定函数)
|
||||||
void handleInitPost(); //服务器响应初始化请求
|
void handleInitPost(); //服务器响应初始化请求
|
||||||
void handlePinSetup(); //服务器-引脚设定函数
|
void handlePinSetup(); //服务器-引脚设定函数
|
||||||
void handleFinal(); //服务器-校验屏幕是否正常
|
void handleFinal(); //服务器-校验屏幕是否正常
|
||||||
void handleFinalPost(); //服务器-校验屏幕是否正常回调函数
|
void handleFinalPost(); //服务器-校验屏幕是否正常回调函数
|
||||||
void handleWiFiPost(); //服务器-处理WiFi连接相关内容和API接口密钥功能
|
//void handleWiFi();//[已弃用]服务器-处理WiFi连接相关内容和API接口密钥功能
|
||||||
void handleNotFound(); //服务器-404响应
|
void handleNotFound(); //服务器-404响应
|
||||||
#endif
|
#endif
|
||||||
//按键驱动部分
|
//按键驱动部分
|
||||||
@@ -295,28 +301,17 @@ class readguy_driver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
#ifdef READGUY_ESP_ENABLE_WIFI
|
#ifdef READGUY_ESP_ENABLE_WIFI
|
||||||
//static constexpr size_t EPD_DRIVERS_NUM_MAX = READGUY_SUPPORT_DEVICES;
|
//static constexpr size_t EPD_DRIVERS_NUM_MAX = READGUY_SUPPORT_DEVICES;
|
||||||
static const char *epd_drivers_list[EPD_DRIVERS_NUM_MAX];
|
static const char *epd_drivers_list[EPD_DRIVERS_NUM_MAX];
|
||||||
|
static const PROGMEM char html_header[]; //HTML头的数据. 省内存, 能省一点是一点
|
||||||
static const PROGMEM char index_cn_html[];
|
static const PROGMEM char index_cn_html[];
|
||||||
/*static const PROGMEM char index_cn_html1[];
|
|
||||||
static const PROGMEM char index_cn_html2[];
|
static const PROGMEM char index_cn_html2[];
|
||||||
static const PROGMEM char index_cn_html3[];
|
static const PROGMEM char index_cn_html3[];
|
||||||
static const PROGMEM char index_cn_html4[];
|
|
||||||
static const PROGMEM char index_cn_html5[];
|
|
||||||
static const PROGMEM char index_cn_html6[];
|
|
||||||
static const PROGMEM char index_cn_html7[];
|
|
||||||
static const PROGMEM char index_cn_html8[];
|
|
||||||
static const PROGMEM char index_cn_html9[];
|
|
||||||
static const PROGMEM char index_cn_html10[];
|
|
||||||
static const PROGMEM char index_cn_html11[];
|
|
||||||
static const PROGMEM char index_cn_html12[];
|
|
||||||
static const PROGMEM char index_cn_html13[];
|
|
||||||
static const PROGMEM char index_cn_html14[];
|
|
||||||
static const PROGMEM char index_cn_html15[]; */
|
|
||||||
static const PROGMEM char index_cn_html16[];
|
static const PROGMEM char index_cn_html16[];
|
||||||
static const PROGMEM char verify_html[];
|
static const PROGMEM char verify_html[];
|
||||||
static const PROGMEM char verify2_html[];
|
static const PROGMEM char verify2_html[];
|
||||||
static const PROGMEM char verifybtn_html[3][200];
|
static const PROGMEM char verifybtn_html[3][200];
|
||||||
static const PROGMEM char final_html[];
|
static const PROGMEM char final_html[];
|
||||||
static const PROGMEM char final2_html[];
|
static const PROGMEM char afterConfig_html[];
|
||||||
|
static const PROGMEM char home_html[];
|
||||||
static const PROGMEM char end_html[];
|
static const PROGMEM char end_html[];
|
||||||
//static const PROGMEM uint8_t faviconData[1150];
|
//static const PROGMEM uint8_t faviconData[1150];
|
||||||
#endif
|
#endif
|
||||||
@@ -335,6 +330,31 @@ class readguy_driver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
if(!spibz) epd_spi->endTransaction();
|
if(!spibz) epd_spi->endTransaction();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
public: //增加了一些返回系统状态变量的函数, 它们是静态的, 而且不会对程序造成任何影响.
|
||||||
|
constexpr int getReadguyShareSpi() const { return config_data[1]; }
|
||||||
|
constexpr int getReadguyEpdType () const { return config_data[2]; } // 对应的epd驱动程序代号, -1为未指定
|
||||||
|
//显示驱动部分, 显示默认使用vspi (vspi也是默认SPI库的通道)
|
||||||
|
constexpr int getReadguyEpdMosi () const { return config_data[3]; } // 目标显示器的 MOSI 引脚
|
||||||
|
constexpr int getReadguyEpdSclk () const { return config_data[4]; } // 目标显示器的 SCLK 引脚
|
||||||
|
constexpr int getReadguyEpdCs () const { return config_data[5]; } // 目标显示器的 CS 引脚
|
||||||
|
constexpr int getReadguyEpdDc () const { return config_data[6]; } // 目标显示器的 DC 引脚
|
||||||
|
constexpr int getReadguyEpdRst () const { return config_data[7]; } // 目标显示器的 RST 引脚
|
||||||
|
constexpr int getReadguyEpdBusy () const { return config_data[8]; } // 目标显示器的 BUSY 引脚
|
||||||
|
//sd卡驱动部分, 默认使用hspi (sd卡建议用hspi)
|
||||||
|
constexpr int getReadguySdMiso () const { return config_data[9]; } // 目标sd卡的 MISO 引脚, sd_share_spi == 1 时无效
|
||||||
|
constexpr int getReadguySdMosi () const { return config_data[10]; }// 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
|
||||||
|
constexpr int getReadguySdSclk () const { return config_data[11]; }// 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
|
||||||
|
constexpr int getReadguySdCs () const { return config_data[12]; }// 目标sd卡的 CS 引脚.
|
||||||
|
constexpr int getReadguyI2cSda () const { return config_data[13]; }// 目标i2c总线的SDA引脚, 当且仅当启用i2c总线时才生效
|
||||||
|
constexpr int getReadguyI2cScl () const { return config_data[14]; }// 目标i2c总线的SCL引脚, 当且仅当启用i2c总线时才生效
|
||||||
|
//按键驱动部分, 为负代表高触发, 否则低触发,
|
||||||
|
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
|
||||||
|
constexpr int getReadguyBtn1Pin () const { return config_data[15]; }
|
||||||
|
constexpr int getReadguyBtn2Pin () const { return config_data[16]; }
|
||||||
|
constexpr int getReadguyBtn3Pin () const { return config_data[17]; }
|
||||||
|
constexpr int getReadguyBlPin () const { return config_data[18]; }//前置光接口引脚IO
|
||||||
|
constexpr int getReadguyRtcType () const { return config_data[19]; }//使用的RTC型号(待定, 还没用上)
|
||||||
|
constexpr int getButtonsCount () const { return config_data[21]; } //按钮个数, 0-3都有可能
|
||||||
};
|
};
|
||||||
#endif /* END OF FILE. ReadGuy project.
|
#endif /* END OF FILE. ReadGuy project.
|
||||||
Copyright (C) 2023 FriendshipEnder. */
|
Copyright (C) 2023 FriendshipEnder. */
|
||||||
Reference in New Issue
Block a user