mirror of
https://github.com/fsender/readguy.git
synced 2026-03-26 22:19:59 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2aca106448 | ||
|
|
d24639a962 | ||
|
|
85a785eabd |
36
CHANGELOG.md
36
CHANGELOG.md
@@ -1,3 +1,39 @@
|
|||||||
|
## Release 1.3.2 - 2023/11/8
|
||||||
|
|
||||||
|
1. 按键驱动 (guy_button) 获得新操作更新: (New button gesture)
|
||||||
|
|
||||||
|
- 单按键操作更新: 现在双击效果为选择/确定, 三击效果为返回, 长按效果为向上翻页;
|
||||||
|
|
||||||
|
- 单按键新增点按后长按操作;
|
||||||
|
|
||||||
|
- 双按键新增按住按键1点按按键2操作;
|
||||||
|
|
||||||
|
- 三按键新增按住按键1点按按键3操作.
|
||||||
|
|
||||||
|
2. 新增获取系统内存的API函数 getFreeMem().
|
||||||
|
|
||||||
|
3. 修复若干驱动层bug.
|
||||||
|
|
||||||
|
## Release 1.3.1 - 2023/11/7
|
||||||
|
|
||||||
|
1. 增加了分步绘制的支持. 可以使用 READGUY_FAST_START 等绘制选项来控制绘制过程:
|
||||||
|
|
||||||
|
- READGUY_SLOW 慢刷, 完整的进行一次慢刷, 等于连续执行慢刷开始和慢刷结束.
|
||||||
|
|
||||||
|
- READGUY_FAST 快刷, 完整的进行一次快刷, 需要等待刷完才能继续执行代码.
|
||||||
|
|
||||||
|
- READGUY_SLOW_START 慢刷开始, 此过程不会进行等待, 发送完要刷新的缓存之后立刻返回
|
||||||
|
|
||||||
|
- READGUY_FAST_START 快刷开始.
|
||||||
|
|
||||||
|
- READGUY_SLOW_END 慢刷结束, 调用慢刷开始之后才能执行. 会等待到屏幕刷完再执行后续操作.
|
||||||
|
|
||||||
|
- READGUY_FAST_END 快刷结束, 如果两次调用间隔时间屏幕已经刷完, 那么该函数会完成刷屏后续操作之后立刻返回.
|
||||||
|
|
||||||
|
2. 修复了首次配置驱动时, 墨水屏显示页面错位的bug (现在对于新设备, 配置起来会像以前一样丝滑)
|
||||||
|
|
||||||
|
3. 修复若干其他bug
|
||||||
|
|
||||||
## Release 1.3.0 - 2023/11/6
|
## Release 1.3.0 - 2023/11/6
|
||||||
|
|
||||||
1. 增加了真.保姆级的教程 (详细到注释比代码多很多倍)
|
1. 增加了真.保姆级的教程 (详细到注释比代码多很多倍)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<img src="extra/artset/readguy_theme3.png" width="30%" height="auto">
|
<img src="extra/artset/readguy_theme3.png" width="30%" height="auto">
|
||||||
|
|
||||||
**版本1.3.0正式发布!欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~
|
**版本1.3.2正式发布!欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~
|
||||||
|
|
||||||
欢迎克隆, 项目交流QQ群: 926824162 (萌新可以进来问问题的哟), 项目的 Bilibili 主页: [BV1f94y187wz](https://www.bilibili.com/video/BV1f94y187wz/) 记得三连+关注我这个宝藏up主哦~
|
欢迎克隆, 项目交流QQ群: 926824162 (萌新可以进来问问题的哟), 项目的 Bilibili 主页: [BV1f94y187wz](https://www.bilibili.com/video/BV1f94y187wz/) 记得三连+关注我这个宝藏up主哦~
|
||||||
|
|
||||||
|
|||||||
@@ -157,8 +157,8 @@ void setup(){ //Arduino的setup函数. 这个函数在上电之后仅执行一
|
|||||||
//guy.setCursor(10,10); //设置显示的坐标
|
//guy.setCursor(10,10); //设置显示的坐标
|
||||||
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
|
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
|
||||||
|
|
||||||
guy.display(true); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上. 可简写为 guy.display(), 效果一样.
|
guy.display(READGUY_FAST); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上. 可简写为 guy.display(), 效果一样.
|
||||||
//guy.display(false); // 慢速刷新.
|
//guy.display(READGUY_SLOW); // 慢速刷新.
|
||||||
|
|
||||||
//想知道更多内容, 欢迎移步到其他示例.
|
//想知道更多内容, 欢迎移步到其他示例.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,25 @@
|
|||||||
* @brief ReadGuy功能演示.
|
* @brief ReadGuy功能演示.
|
||||||
* 将根目录下的data文件夹 上传到LittleFS之后运行效果更佳
|
* 将根目录下的data文件夹 上传到LittleFS之后运行效果更佳
|
||||||
* 或者可以准备一张SD卡,并准备在卡的根目录下放置data文件夹内的文件.
|
* 或者可以准备一张SD卡,并准备在卡的根目录下放置data文件夹内的文件.
|
||||||
|
* 就是SD卡内放data文件夹内的所有文件, 不能额外套文件夹.
|
||||||
|
* 如果你的SD卡插入电脑上显示为可移动磁盘, 那么双击SD卡目录就要看到这个文件夹里的文件
|
||||||
|
*
|
||||||
|
* 默认的文件系统为SD卡. 当没有插入SD卡时, 会读取LittleFS文件系统.
|
||||||
|
* 没有条件准备SD卡的, 可以烧录LittleFS文件系统.
|
||||||
|
*
|
||||||
|
* 对于ESP8266 Arduino 用户, 在项目草图文件夹内新建一个data文件夹, 并放入文件 (示例已提供data文件夹)
|
||||||
|
* 再在 arduinoIDE 的工具选项里选择 ESP8266 LittleFS Data Upload.
|
||||||
|
* 没有这个选项的需要参考以下文档安装ESP8266 Sketch upload tool
|
||||||
|
* https://randomnerdtutorials.com/install-esp8266-nodemcu-littlefs-arduino/
|
||||||
|
*
|
||||||
|
* 对于ESP32 Arduino 用户, 也要在项目草图文件夹内放一个data文件夹, 并把文件放入其中 (示例已提供data文件夹)
|
||||||
|
* 再在 arduinoIDE 的工具选项里选择 ESP32 Sketch data upload, 最后选择LittleFS.
|
||||||
|
* 没有这个选项的需要参考以下文档安装ESP32 LittleFS upload tool
|
||||||
|
* https://randomnerdtutorials.com/esp32-littlefs-arduino-ide/
|
||||||
|
*
|
||||||
|
* 对于PlatformIO 用户, 需要进入platformIO扩展界面, 选择Upload Filesystem Image, 上传项目文件.
|
||||||
|
* ESP8266和ESP32都要用这种方法.
|
||||||
|
*
|
||||||
* 用于演示BMP格式图片灰度显示.
|
* 用于演示BMP格式图片灰度显示.
|
||||||
*
|
*
|
||||||
* @note 食用方法:
|
* @note 食用方法:
|
||||||
@@ -76,14 +95,14 @@ void setup(){
|
|||||||
guy.drawString("Hello Readguy!",10,10); //用此函数将字符串显示到屏幕缓存内
|
guy.drawString("Hello Readguy!",10,10); //用此函数将字符串显示到屏幕缓存内
|
||||||
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
|
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
|
||||||
|
|
||||||
guy.display(true); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
|
guy.display(READGUY_FAST); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
|
||||||
//guy.display(false); // 慢速刷新.
|
//guy.display(READGUY_SLOW); // 慢速刷新.
|
||||||
|
|
||||||
guy.setCursor(10,30); //设置显示的坐标
|
guy.setCursor(10,30); //设置显示的坐标
|
||||||
|
|
||||||
guy.print("Hello~"); //或者用print函数在屏幕上打印字符串, 数值, 字符等等... 两种函数都行
|
guy.print("Hello~"); //或者用print函数在屏幕上打印字符串, 数值, 字符等等... 两种函数都行
|
||||||
|
|
||||||
guy.display(false); // 慢速刷新. 慢刷的对比度显著高于快速刷新, 而且可以消除残影
|
guy.display(READGUY_SLOW); // 慢速刷新. 慢刷的对比度显著高于快速刷新, 而且可以消除残影
|
||||||
|
|
||||||
|
|
||||||
guy.drawString(guy.SDinside()?"SD card OK.":"No SD card!",10,50); //检查readguy是否插入了SD卡
|
guy.drawString(guy.SDinside()?"SD card OK.":"No SD card!",10,50); //检查readguy是否插入了SD卡
|
||||||
@@ -134,7 +153,7 @@ void setup(){
|
|||||||
|
|
||||||
guy.fillScreen(1);
|
guy.fillScreen(1);
|
||||||
|
|
||||||
guy.display(false); // 慢速刷新. 慢刷的对比度显著高于快速刷新, 而且可以消除残影
|
guy.display(READGUY_SLOW); // 慢速刷新. 慢刷的对比度显著高于快速刷新, 而且可以消除残影
|
||||||
|
|
||||||
for(int i=1;i<16;i++){ //灰度测试, 循环设置不同灰度
|
for(int i=1;i<16;i++){ //灰度测试, 循环设置不同灰度
|
||||||
|
|
||||||
@@ -203,7 +222,7 @@ void setup(){
|
|||||||
guy.setFont(&FreeMonoBold9pt7b); //设置文本字体
|
guy.setFont(&FreeMonoBold9pt7b); //设置文本字体
|
||||||
guy.setTextColor(0); //设置文本颜色
|
guy.setTextColor(0); //设置文本颜色
|
||||||
guy.fillScreen(1); //用白色清屏.
|
guy.fillScreen(1); //用白色清屏.
|
||||||
guy.display(false); //慢刷. 注意, 进行慢刷操作之后, 所有之前显示的灰度内容均会被重新刷成纯黑色
|
guy.display(READGUY_SLOW); //慢刷. 注意, 进行慢刷操作之后, 所有之前显示的灰度内容均会被重新刷成纯黑色
|
||||||
//不管是浅灰色还是深灰色, 进行慢刷之后只有黑白色. 原来的非白色像素(浅灰色,深灰色和黑色等) 会全刷成白色.
|
//不管是浅灰色还是深灰色, 进行慢刷之后只有黑白色. 原来的非白色像素(浅灰色,深灰色和黑色等) 会全刷成白色.
|
||||||
|
|
||||||
guy.drawString("Rotation 0",10,12); //默认旋转方向为0. 实际的默认方向取决于屏幕IC. 大多数屏幕IC是竖屏.
|
guy.drawString("Rotation 0",10,12); //默认旋转方向为0. 实际的默认方向取决于屏幕IC. 大多数屏幕IC是竖屏.
|
||||||
@@ -239,13 +258,13 @@ void setup(){
|
|||||||
guy.setTextColor(1); //设置文本颜色为白色,因为被反色的屏幕的当前像素颜色以黑色像素为主
|
guy.setTextColor(1); //设置文本颜色为白色,因为被反色的屏幕的当前像素颜色以黑色像素为主
|
||||||
guy.drawString("Wake Up! ~\\(^_^)/~",10,50); //退出睡眠状态
|
guy.drawString("Wake Up! ~\\(^_^)/~",10,50); //退出睡眠状态
|
||||||
|
|
||||||
guy.display(false); //使用慢刷 来唤醒处于低功耗状态下的屏幕.
|
guy.display(READGUY_SLOW); //使用慢刷 来唤醒处于低功耗状态下的屏幕.
|
||||||
|
|
||||||
// ------------------ 6 - 可以利用灰度来达到的一些显示效果 --<<<<<<
|
// ------------------ 6 - 可以利用灰度来达到的一些显示效果 --<<<<<<
|
||||||
|
|
||||||
guy.fillScreen(1); //清屏
|
guy.fillScreen(1); //清屏
|
||||||
|
|
||||||
guy.display(FILL_WHITE,false); //慢刷清屏. 左侧的FILL_WHITE表示 不写入屏幕缓存, 直接刷全白
|
guy.display(FILL_WHITE,READGUY_SLOW); //慢刷清屏. 左侧的FILL_WHITE表示 不写入屏幕缓存, 直接刷全白
|
||||||
//可以改为FILL_BLACK来设置写入缓存全黑.
|
//可以改为FILL_BLACK来设置写入缓存全黑.
|
||||||
//以上的方式均不会修改屏幕缓存中的内容. 右侧的false表示全屏慢刷.
|
//以上的方式均不会修改屏幕缓存中的内容. 右侧的false表示全屏慢刷.
|
||||||
|
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ void setup(){
|
|||||||
//guy.setCursor(10,10); //设置显示的坐标
|
//guy.setCursor(10,10); //设置显示的坐标
|
||||||
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
|
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
|
||||||
|
|
||||||
guy.display(true); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
|
guy.display(READGUY_FAST); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
|
||||||
//guy.display(false); // 慢速刷新.
|
//guy.display(READGUY_SLOW); // 慢速刷新.
|
||||||
|
|
||||||
//想知道更多内容, 欢迎移步到其他示例.
|
//想知道更多内容, 欢迎移步到其他示例.
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,29 @@
|
|||||||
* - 运行的会很缓慢, 因为示例的图片文件比较大.
|
* - 运行的会很缓慢, 因为示例的图片文件比较大.
|
||||||
* 1. 在运行过ex01或者ex02的开发板上 编译烧录本程序.
|
* 1. 在运行过ex01或者ex02的开发板上 编译烧录本程序.
|
||||||
* 2. 将该项目data文件夹内的所有文件放置于SD卡的根目录上.
|
* 2. 将该项目data文件夹内的所有文件放置于SD卡的根目录上.
|
||||||
|
* 就是SD卡内放data文件夹内的所有文件, 不能额外套文件夹.
|
||||||
|
* 如果你的SD卡插入电脑上显示为可移动磁盘, 那么双击SD卡目录就要看到这个文件夹里的文件
|
||||||
|
*
|
||||||
|
* 将根目录下的data文件夹 上传到LittleFS之后运行效果更佳
|
||||||
|
* 或者可以准备一张SD卡,并准备在卡的根目录下放置data文件夹内的文件.
|
||||||
|
* 就是SD卡内放data文件夹内的所有文件, 不能额外套文件夹.
|
||||||
|
* 如果你的SD卡插入电脑上显示为可移动磁盘, 那么双击SD卡目录就要看到这个文件夹里的文件
|
||||||
|
*
|
||||||
|
* 默认的文件系统为SD卡. 当没有插入SD卡时, 会读取LittleFS文件系统.
|
||||||
|
* 没有条件准备SD卡的, 可以烧录LittleFS文件系统.
|
||||||
|
*
|
||||||
|
* 对于ESP8266 Arduino 用户, 在项目草图文件夹内新建一个data文件夹, 并放入文件 (示例已提供data文件夹)
|
||||||
|
* 再在 arduinoIDE 的工具选项里选择 ESP8266 LittleFS Data Upload.
|
||||||
|
* 没有这个选项的需要参考以下文档安装ESP8266 Sketch upload tool
|
||||||
|
* https://randomnerdtutorials.com/install-esp8266-nodemcu-littlefs-arduino/
|
||||||
|
*
|
||||||
|
* 对于ESP32 Arduino 用户, 也要在项目草图文件夹内放一个data文件夹, 并把文件放入其中 (示例已提供data文件夹)
|
||||||
|
* 再在 arduinoIDE 的工具选项里选择 ESP32 Sketch data upload, 最后选择LittleFS.
|
||||||
|
* 没有这个选项的需要参考以下文档安装ESP32 LittleFS upload tool
|
||||||
|
* https://randomnerdtutorials.com/esp32-littlefs-arduino-ide/
|
||||||
|
*
|
||||||
|
* 对于PlatformIO 用户, 需要进入platformIO扩展界面, 选择Upload Filesystem Image, 上传项目文件.
|
||||||
|
* ESP8266和ESP32都要用这种方法.
|
||||||
*
|
*
|
||||||
* {0} 代码食用注意事项:
|
* {0} 代码食用注意事项:
|
||||||
* 这一部分的代码很难读, 或者按维莫斯小姐的说法, 很 "抽象" .
|
* 这一部分的代码很难读, 或者按维莫斯小姐的说法, 很 "抽象" .
|
||||||
@@ -174,13 +197,13 @@ void setup(){
|
|||||||
delay(2000);
|
delay(2000);
|
||||||
|
|
||||||
|
|
||||||
guy.display(FILL_WHITE,true); //在保持屏幕缓存不变的时候快速刷新白屏.
|
guy.display(FILL_WHITE,READGUY_FAST); //在保持屏幕缓存不变的时候快速刷新白屏.
|
||||||
guy.drawImage(sp,0,0,guy.width(),guy.height()); //绘画的画布可以被放大或者缩小到任意宽度和高度.
|
guy.drawImage(sp,0,0,guy.width(),guy.height()); //绘画的画布可以被放大或者缩小到任意宽度和高度.
|
||||||
//此处的参数调用表示将会在屏幕坐标(0,0)开始显示, 显示的画布宽度缩放到屏幕宽度, 画布高度缩放到屏幕高度.
|
//此处的参数调用表示将会在屏幕坐标(0,0)开始显示, 显示的画布宽度缩放到屏幕宽度, 画布高度缩放到屏幕高度.
|
||||||
guy.display(); //调用display函数刷屏.
|
guy.display(); //调用display函数刷屏.
|
||||||
delay(2000);
|
delay(2000);
|
||||||
|
|
||||||
guy.display(FILL_WHITE,true); //在保持屏幕缓存不变的时候快速刷新白屏
|
guy.display(FILL_WHITE,READGUY_FAST); //在保持屏幕缓存不变的时候快速刷新白屏
|
||||||
guy.fillScreen(1); //白屏清屏(清屏幕缓存)
|
guy.fillScreen(1); //白屏清屏(清屏幕缓存)
|
||||||
guy.drawImage(sp,10,10,65,50); //缩放: 缩小到65X50
|
guy.drawImage(sp,10,10,65,50); //缩放: 缩小到65X50
|
||||||
guy.display(); //调用display函数刷屏.
|
guy.display(); //调用display函数刷屏.
|
||||||
@@ -244,7 +267,7 @@ void setup(){
|
|||||||
|
|
||||||
im.filename=BMP_FILE; //在此直接设置文件路径和文件名.
|
im.filename=BMP_FILE; //在此直接设置文件路径和文件名.
|
||||||
|
|
||||||
guy.display(FILL_WHITE,false); //将屏幕全刷成白屏. 为了即将的图片刷新.
|
guy.display(FILL_WHITE,READGUY_SLOW); //将屏幕全刷成白屏. 为了即将的图片刷新.
|
||||||
//建议在使用drawImageFile函数之前, 使用慢刷刷白屏, 可以保证显示效果清晰可见.
|
//建议在使用drawImageFile函数之前, 使用慢刷刷白屏, 可以保证显示效果清晰可见.
|
||||||
|
|
||||||
im.drawImageFile(); //显示BMP格式.图片. im会自动识别文件扩展名并绘制.
|
im.drawImageFile(); //显示BMP格式.图片. im会自动识别文件扩展名并绘制.
|
||||||
@@ -265,7 +288,7 @@ void setup(){
|
|||||||
|
|
||||||
im.background=0; //设置背景颜色, 0黑1白, 此处设为背景色为黑色.
|
im.background=0; //设置背景颜色, 0黑1白, 此处设为背景色为黑色.
|
||||||
|
|
||||||
guy.display(FILL_WHITE,false); //将屏幕全刷成白屏. 为了即将的图片刷新.
|
guy.display(FILL_WHITE,READGUY_SLOW); //将屏幕全刷成白屏. 为了即将的图片刷新.
|
||||||
|
|
||||||
im.drawImageFile(); //显示JPG格式.图片. im会自动识别文件扩展名并绘制.
|
im.drawImageFile(); //显示JPG格式.图片. im会自动识别文件扩展名并绘制.
|
||||||
delay(2000);
|
delay(2000);
|
||||||
@@ -279,7 +302,7 @@ void setup(){
|
|||||||
im.scalex=400.0f/1280.0f;
|
im.scalex=400.0f/1280.0f;
|
||||||
im.scaley=300.0f/576.0f;
|
im.scaley=300.0f/576.0f;
|
||||||
|
|
||||||
guy.display(FILL_WHITE, false);//显示. 此处的功能就是将显示缓存输出到屏幕上
|
guy.display(FILL_WHITE, READGUY_SLOW);//显示. 此处的功能就是将显示缓存输出到屏幕上
|
||||||
|
|
||||||
im.drawImageFile(); //显示PNG格式.图片. ESP8266可能不会绘制.
|
im.drawImageFile(); //显示PNG格式.图片. ESP8266可能不会绘制.
|
||||||
delay(2000);
|
delay(2000);
|
||||||
@@ -308,7 +331,7 @@ void setup(){
|
|||||||
im.exPoolSize=MEM_POOL; //设置外部缓存内存大小
|
im.exPoolSize=MEM_POOL; //设置外部缓存内存大小
|
||||||
|
|
||||||
guy.setGreyQuality(1); //设置灰度模式为默认灰度显示模式
|
guy.setGreyQuality(1); //设置灰度模式为默认灰度显示模式
|
||||||
guy.display(FILL_WHITE,false); //将屏幕全刷成白屏. 为了即将显示灰度图.
|
guy.display(FILL_WHITE,READGUY_SLOW); //将屏幕全刷成白屏. 为了即将显示灰度图.
|
||||||
|
|
||||||
im.enableFloyd=0; //禁用掉抖动算法.
|
im.enableFloyd=0; //禁用掉抖动算法.
|
||||||
|
|
||||||
@@ -316,7 +339,7 @@ void setup(){
|
|||||||
|
|
||||||
delay(2000);
|
delay(2000);
|
||||||
|
|
||||||
guy.display(FILL_WHITE,false); //将屏幕全刷成白屏. 为了即将显示灰度图.
|
guy.display(FILL_WHITE,READGUY_SLOW); //将屏幕全刷成白屏. 为了即将显示灰度图.
|
||||||
|
|
||||||
im.enableFloyd=1; // 重新启用抖动算法.
|
im.enableFloyd=1; // 重新启用抖动算法.
|
||||||
|
|
||||||
@@ -351,7 +374,7 @@ void setup(){
|
|||||||
}
|
}
|
||||||
guy.drawLine(guy.width(),0,0,guy.height(),0);
|
guy.drawLine(guy.width(),0,0,guy.height(),0);
|
||||||
|
|
||||||
guy.display(false); //刷新屏幕, 显示绘画的线段
|
guy.display(READGUY_SLOW); //刷新屏幕, 显示绘画的线段
|
||||||
|
|
||||||
//im.baseFs=&guy.guyFS(); //直接更改im内的数据即可设置绘制参数. 在此处就是设置文件系统.
|
//im.baseFs=&guy.guyFS(); //直接更改im内的数据即可设置绘制参数. 在此处就是设置文件系统.
|
||||||
im.filename=BMP_FILE; //在此直接设置文件路径和文件名.
|
im.filename=BMP_FILE; //在此直接设置文件路径和文件名.
|
||||||
|
|||||||
@@ -61,16 +61,16 @@ uint8_t readguyImage::drawImgHandler(int r, LGFX_Sprite *spr){
|
|||||||
//_x=y-r/stage*_h; yd=0;
|
//_x=y-r/stage*_h; yd=0;
|
||||||
//_y=x;//(widthDiv8<<3)-x-1;
|
//_y=x;//(widthDiv8<<3)-x-1;
|
||||||
_x=x-r/stage*_h;
|
_x=x-r/stage*_h;
|
||||||
_y=y; yd=0;
|
_y=y+w-guy->drvWidth(); yd=0;
|
||||||
if(_x<0){ xd=-_x; _x=0; }
|
if(_x<0){ xd=-_x; _x=0; }
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
_x=x; xd=0;
|
_x=x+w-guy->drvWidth(); xd=0;
|
||||||
_y=y-(GUY_STAGES-r/stage-1)*_h;
|
_y=y+(r/stage+1)*_h-h;
|
||||||
if(_y<0){ yd=-_y; _y=0; }
|
if(_y<0){ yd=-_y; _y=0; }
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
_x=x-(GUY_STAGES-r/stage-1)*_h;
|
_x=x+(r/stage+1)*_h-h;
|
||||||
_y=y; yd=0;
|
_y=y; yd=0;
|
||||||
if(_x<0){ xd=-_x; _x=0; }
|
if(_x<0){ xd=-_x; _x=0; }
|
||||||
break;
|
break;
|
||||||
@@ -234,7 +234,7 @@ void readguyImage::drawImageFile(bool use16grey){
|
|||||||
_pool=exPool;
|
_pool=exPool;
|
||||||
}
|
}
|
||||||
if(_pool==nullptr) {
|
if(_pool==nullptr) {
|
||||||
_h=(h+7)>>3; //设置缓存区的高度. 更多内存将可以更快显示
|
_h=h>>3; //设置缓存区的高度. 更多内存将可以更快显示
|
||||||
_pool=(uint8_t *)guy->getBuffer();
|
_pool=(uint8_t *)guy->getBuffer();
|
||||||
}
|
}
|
||||||
//(guy->guyMemoryHeight()+7)>>3 返回高度,并补齐后右移三位 (等效于除以2³, 分成8份)
|
//(guy->guyMemoryHeight()+7)>>3 返回高度,并补齐后右移三位 (等效于除以2³, 分成8份)
|
||||||
@@ -275,7 +275,7 @@ void readguyImage::drawImageFile(bool use16grey){
|
|||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// ************* 提示: 编写此示例时的最新版本LovyanGFX库不提供此函数. 请看ex06_Image.ino文件开头的解决方法!
|
// ************* 提示: 编写此示例时的最新版本LovyanGFX库不提供此函数. 请看ex06_Image.ino文件开头的解决方法!
|
||||||
guy->display(std::bind(&readguyImage::drawImgHandler,this,std::placeholders::_1,&bmpspr));
|
guy->display(std::bind(&readguyImage::drawImgHandler,this,std::placeholders::_1,&bmpspr),READGUY_FAST);
|
||||||
// 此函数过不了编译 需要改库.
|
// 此函数过不了编译 需要改库.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/fsender/readguy"
|
"url": "https://github.com/fsender/readguy"
|
||||||
},
|
},
|
||||||
"version": "1.3.0",
|
"version": "1.3.2",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": ["espressif32", "espressif8266"],
|
"platforms": ["espressif32", "espressif8266"],
|
||||||
"headers": "readguy.h",
|
"headers": "readguy.h",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name=readguy
|
name=readguy
|
||||||
version=1.3.0
|
version=1.3.2
|
||||||
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.
|
||||||
|
|||||||
@@ -78,11 +78,18 @@ void guy_button::begin(uint8_t _pin, std_U8_function_U8 f, bool activeLow /* = t
|
|||||||
state = get_state_cb(pin);
|
state = get_state_cb(pin);
|
||||||
min_debounce =25; //去抖时间
|
min_debounce =25; //去抖时间
|
||||||
long_press_ms =300; //长按持续时间+双击识别间隔最大时间
|
long_press_ms =300; //长按持续时间+双击识别间隔最大时间
|
||||||
long_repeat_ms =150; //长按连按间隔时间
|
long_repeat_ms =200; //长按连按间隔时间
|
||||||
multibtn =0;
|
multibtn =0;
|
||||||
lk=0;
|
lk=0;
|
||||||
}
|
}
|
||||||
|
bool guy_button::isPressedRaw() {
|
||||||
|
int mi=millis();
|
||||||
|
while(lk) if(millis()-mi>GUYBTN_READ_TIMEOUT) return 0; //等待数据读完
|
||||||
|
lk=3;
|
||||||
|
bool willreturn = (get_state_cb(pin) == _pressedState);
|
||||||
|
lk=0;
|
||||||
|
return willreturn;
|
||||||
|
}
|
||||||
uint8_t guy_button::read() { //注意ticker不能在此触发
|
uint8_t guy_button::read() { //注意ticker不能在此触发
|
||||||
int mi=millis();
|
int mi=millis();
|
||||||
while(lk) if(millis()-mi>GUYBTN_READ_TIMEOUT) return 0; //等待数据读完
|
while(lk) if(millis()-mi>GUYBTN_READ_TIMEOUT) return 0; //等待数据读完
|
||||||
@@ -91,13 +98,14 @@ uint8_t guy_button::read() { //注意ticker不能在此触发
|
|||||||
if(state == _pressedState && n - down_ms>= long_press_ms && long_clicked < n){
|
if(state == _pressedState && n - down_ms>= long_press_ms && long_clicked < n){
|
||||||
long_clicked = trig_mode?(n+long_repeat_ms):0xfffffffful;
|
long_clicked = trig_mode?(n+long_repeat_ms):0xfffffffful;
|
||||||
lk=0;
|
lk=0;
|
||||||
return GUYBUTTON_long_click;
|
return (click_count>=3)?GUYBUTTON_xxlong_click:\
|
||||||
|
((click_count==2)?GUYBUTTON_xlong_click:GUYBUTTON_long_click);
|
||||||
}
|
}
|
||||||
uint8_t res = last_click_type;
|
uint8_t res = last_click_type;
|
||||||
last_click_type = GUYBUTTON_empty;
|
last_click_type = GUYBUTTON_empty;
|
||||||
was_pressed = false;
|
was_pressed = false;
|
||||||
lk=0;
|
lk=0;
|
||||||
return (res==GUYBUTTON_long_click)?GUYBUTTON_empty:res;
|
return (res>=GUYBUTTON_long_click)?GUYBUTTON_empty:res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void guy_button::loop() {
|
void guy_button::loop() {
|
||||||
@@ -140,8 +148,9 @@ void guy_button::loop() {
|
|||||||
// was there a longclick?
|
// was there a longclick?
|
||||||
if (longclick_detected) {
|
if (longclick_detected) {
|
||||||
// was it part of a combination?
|
// was it part of a combination?
|
||||||
if (click_count == 1) {
|
if (click_count) {
|
||||||
last_click_type = GUYBUTTON_long_click;
|
last_click_type = (click_count>=3)?GUYBUTTON_xxlong_click:\
|
||||||
|
((click_count==2)?GUYBUTTON_xlong_click:GUYBUTTON_long_click);
|
||||||
was_pressed = true;
|
was_pressed = true;
|
||||||
}
|
}
|
||||||
longclick_detected = false;
|
longclick_detected = false;
|
||||||
|
|||||||
@@ -76,14 +76,17 @@ SOFTWARE.
|
|||||||
#define GUYBUTTON_double_click 2
|
#define GUYBUTTON_double_click 2
|
||||||
#define GUYBUTTON_triple_click 3
|
#define GUYBUTTON_triple_click 3
|
||||||
#define GUYBUTTON_long_click 4
|
#define GUYBUTTON_long_click 4
|
||||||
|
#define GUYBUTTON_xlong_click 5
|
||||||
|
#define GUYBUTTON_xxlong_click 6
|
||||||
#define GUYBTN_READ_TIMEOUT 100
|
#define GUYBTN_READ_TIMEOUT 100
|
||||||
#define GUYBTN_LOOP_TIMEOUT 10
|
#define GUYBTN_LOOP_TIMEOUT 10
|
||||||
|
|
||||||
class guy_button{
|
class guy_button{
|
||||||
protected:
|
public:
|
||||||
uint16_t min_debounce ; //去抖时间
|
uint16_t min_debounce ; //去抖时间
|
||||||
uint16_t long_press_ms ; //长按持续时间+双击识别间隔最大时间
|
uint16_t long_press_ms ; //长按持续时间+双击识别间隔最大时间
|
||||||
uint16_t long_repeat_ms ; //长按连按间隔时间
|
uint16_t long_repeat_ms ; //长按连按间隔时间
|
||||||
|
protected:
|
||||||
uint8_t pin = 255; //未定义引脚
|
uint8_t pin = 255; //未定义引脚
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
uint8_t prev_state;
|
uint8_t prev_state;
|
||||||
@@ -114,16 +117,19 @@ class guy_button{
|
|||||||
void setLongRepeatMode(bool trigMode) { trig_mode = trigMode; }
|
void setLongRepeatMode(bool trigMode) { trig_mode = trigMode; }
|
||||||
unsigned int wasPressedFor() const { return down_time_ms; }
|
unsigned int wasPressedFor() const { return down_time_ms; }
|
||||||
bool isPressed() const { return (state == _pressedState); }
|
bool isPressed() const { return (state == _pressedState); }
|
||||||
bool isPressedRaw() { return (get_state_cb(pin) == _pressedState); }
|
bool isPressedRaw(); // { return (get_state_cb(pin) == _pressedState); }
|
||||||
bool wasPressed(){ if(was_pressed){ was_pressed = false; return true; } return false; }
|
bool wasPressed(){ if(was_pressed){ was_pressed = false; return true; } return false; }
|
||||||
uint8_t getNumberOfClicks() const{ return click_count;}
|
uint8_t getNumberOfClicks() const{ return click_count;}
|
||||||
uint8_t getType() const { return last_click_type; }
|
uint8_t getType() const { return last_click_type; }
|
||||||
uint8_t read();
|
uint8_t read();
|
||||||
void loop();
|
void loop();
|
||||||
void setMultiBtn(uint8_t btns) { multibtn = btns; }
|
void setMultiBtn(uint8_t btns) { multibtn = btns; }
|
||||||
void setMinDebounce(short n) { min_debounce =n;} //去抖时间
|
/* void setMinDebounce(short n) { min_debounce =n;} //去抖时间
|
||||||
void setLongPressMs(short n) { long_press_ms =n;} //长按持续时间+双击识别间隔最大时间
|
void setLongPressMs(short n) { long_press_ms =n;} //长按持续时间+双击识别间隔最大时间
|
||||||
void setLongRepeat(short n) { long_repeat_ms =n;} //长按连按间隔时间
|
void setLongRepeat(short n) { long_repeat_ms =n;} //长按连按间隔时间
|
||||||
|
void getMinDebounce(short n) { min_debounce =n;} //去抖时间
|
||||||
|
void getLongPressMs(short n) { long_press_ms =n;} //长按持续时间+双击识别间隔最大时间
|
||||||
|
void getLongRepeat(short n) { long_repeat_ms =n;} //长按连按间隔时间 */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* END OF FILE. ReadGuy project. */
|
#endif /* END OF FILE. ReadGuy project. */
|
||||||
@@ -110,7 +110,9 @@ void drvBase::drv_fullpart(bool part){ //切换慢刷/快刷功能
|
|||||||
if(!part) iLut=15; //恢复默认的灰度模式
|
if(!part) iLut=15; //恢复默认的灰度模式
|
||||||
Init(part?lut_fast:lut_slow);
|
Init(part?lut_fast:lut_slow);
|
||||||
}*/
|
}*/
|
||||||
void drvBase::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新等功能
|
void drvBase::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新等功能
|
||||||
|
if(m&1){//stage 1
|
||||||
|
if(lastRefresh) drv_dispWriter(f,2);
|
||||||
if(sleeping) Init(lut_slow);
|
if(sleeping) Init(lut_slow);
|
||||||
BeginTransfer();
|
BeginTransfer();
|
||||||
SetMemory(); // bit set = white, bit reset = black
|
SetMemory(); // bit set = white, bit reset = black
|
||||||
@@ -123,14 +125,22 @@ void drvBase::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新等
|
|||||||
guy_epdCmd(0x20);
|
guy_epdCmd(0x20);
|
||||||
guy_epdCmd(0xff);
|
guy_epdCmd(0xff);
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
guy_epdBusy((this->lut == (const uint8_t*)lut_fast)?idleFastRf:idleSlowRf);
|
lastRefresh=millis();
|
||||||
BeginTransfer();
|
}
|
||||||
SetMemory(); // bit set = white, bit reset = black
|
|
||||||
guy_epdBusy(90);
|
if(m&2){//stage 2
|
||||||
guy_epdCmd(0x26); /* will send the color data */
|
uint32_t ms=millis()-lastRefresh;
|
||||||
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
|
uint32_t u=(this->lut == (const uint8_t*)lut_fast)?idleFastRf:idleSlowRf;
|
||||||
SpiTransfer(f(i));
|
if(ms<u) guy_epdBusy(u-ms);
|
||||||
EndTransfer();
|
lastRefresh=0;
|
||||||
|
BeginTransfer();
|
||||||
|
SetMemory(); // bit set = white, bit reset = black
|
||||||
|
guy_epdBusy(90);
|
||||||
|
guy_epdCmd(0x26); /* will send the color data */
|
||||||
|
for (int i = 0; i < epdHeight*epdWidth / 8; i++)
|
||||||
|
SpiTransfer(f(i));
|
||||||
|
EndTransfer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void drvBase::drv_sleep() { //开始屏幕睡眠
|
void drvBase::drv_sleep() { //开始屏幕睡眠
|
||||||
if(RST_PIN>=0) { //未定义RST_PIN时无法唤醒
|
if(RST_PIN>=0) { //未定义RST_PIN时无法唤醒
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public:
|
|||||||
virtual int drv_ID() const=0;
|
virtual int drv_ID() const=0;
|
||||||
void drv_init(); //初始化屏幕
|
void drv_init(); //初始化屏幕
|
||||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||||
void drv_sleep() ; //开始屏幕睡眠
|
void drv_sleep() ; //开始屏幕睡眠
|
||||||
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
||||||
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
||||||
|
|||||||
@@ -148,7 +148,9 @@ void drvSSD168x::drv_fullpart(bool part){ //切换慢刷/快刷功能
|
|||||||
if(!part) { iLut=15; greyScaling=0; }
|
if(!part) { iLut=15; greyScaling=0; }
|
||||||
_part=part;
|
_part=part;
|
||||||
}
|
}
|
||||||
void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||||
|
if(m&1){//stage 1
|
||||||
|
if(lastRefresh) drv_dispWriter(f,2);
|
||||||
BeginTransfer();
|
BeginTransfer();
|
||||||
if(_part){
|
if(_part){
|
||||||
//Reset();
|
//Reset();
|
||||||
@@ -196,7 +198,15 @@ void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
guy_epdParam(_part?0x0f:0xc7);
|
guy_epdParam(_part?0x0f:0xc7);
|
||||||
guy_epdCmd(0x20);
|
guy_epdCmd(0x20);
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
guy_epdBusy(_part?600:2300);
|
lastRefresh=millis();
|
||||||
|
}
|
||||||
|
if(m&2){//stage 2
|
||||||
|
uint32_t ms=millis()-lastRefresh;
|
||||||
|
uint32_t u=_part?600:2300;
|
||||||
|
if(ms<u) guy_epdBusy(u-ms);
|
||||||
|
lastRefresh=0;
|
||||||
|
}
|
||||||
|
//guy_epdBusy(_part?600:2300);
|
||||||
}
|
}
|
||||||
void drvSSD168x::drv_sleep() { //开始屏幕睡眠
|
void drvSSD168x::drv_sleep() { //开始屏幕睡眠
|
||||||
if(RST_PIN>=0){ //无法唤醒
|
if(RST_PIN>=0){ //无法唤醒
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
virtual int drv_ID() const =0;
|
virtual int drv_ID() const =0;
|
||||||
void drv_init(); //初始化屏幕
|
void drv_init(); //初始化屏幕
|
||||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||||
void drv_sleep() ; //开始屏幕睡眠
|
void drv_sleep() ; //开始屏幕睡眠
|
||||||
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
||||||
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
||||||
|
|||||||
@@ -119,7 +119,9 @@ void drv::drv_fullpart(bool part){ //初始化慢刷功能
|
|||||||
epdFull = !part;
|
epdFull = !part;
|
||||||
//epd_Init();
|
//epd_Init();
|
||||||
}
|
}
|
||||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||||
|
if(m&1){//stage 1
|
||||||
|
if(lastRefresh) drv_dispWriter(f,2);
|
||||||
BeginTransfer();
|
BeginTransfer();
|
||||||
if(epdFull) { //当刷新模式从快刷切换为慢刷时, 需要发送一次init
|
if(epdFull) { //当刷新模式从快刷切换为慢刷时, 需要发送一次init
|
||||||
epdFull=0;
|
epdFull=0;
|
||||||
@@ -143,7 +145,15 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
guy_epdParam(epdFull?0xc4:0x04);
|
guy_epdParam(epdFull?0xc4:0x04);
|
||||||
guy_epdCmd(0x20);
|
guy_epdCmd(0x20);
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
guy_epdBusy(epdFull?1600:310);
|
lastRefresh=millis();
|
||||||
|
}
|
||||||
|
if(m&2){//stage 2
|
||||||
|
uint32_t ms=millis()-lastRefresh;
|
||||||
|
uint32_t u=epdFull?1600:310;
|
||||||
|
if(ms<u) guy_epdBusy(u-ms);
|
||||||
|
lastRefresh=0;
|
||||||
|
}
|
||||||
|
//guy_epdBusy(epdFull?1600:310);
|
||||||
}
|
}
|
||||||
void drv::drv_sleep() { //开始屏幕睡眠
|
void drv::drv_sleep() { //开始屏幕睡眠
|
||||||
if(RST_PIN>=0){ //RST_PIN<0 无法唤醒
|
if(RST_PIN>=0){ //RST_PIN<0 无法唤醒
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
int drv_ID() const { return READGUY_DEV_213A; }
|
int drv_ID() const { return READGUY_DEV_213A; }
|
||||||
void drv_init(); //初始化屏幕
|
void drv_init(); //初始化屏幕
|
||||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||||
void drv_sleep() ; //开始屏幕睡眠
|
void drv_sleep() ; //开始屏幕睡眠
|
||||||
int drv_width() const { return EPD_REAL_WIDTH; }; //返回显示区域宽度
|
int drv_width() const { return EPD_REAL_WIDTH; }; //返回显示区域宽度
|
||||||
//int drv_panelwidth() const { return GUY_D_WIDTH; }; //返回缓存的数据宽度
|
//int drv_panelwidth() const { return GUY_D_WIDTH; }; //返回缓存的数据宽度
|
||||||
|
|||||||
@@ -152,7 +152,9 @@ void drv_base::drv_setDepth(uint8_t i){
|
|||||||
SendLuts(1);
|
SendLuts(1);
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
}
|
}
|
||||||
void drv_base::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
void drv_base::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||||
|
if(m&1){//stage 1
|
||||||
|
if(lastRefresh) drv_dispWriter(f,2);
|
||||||
BeginTransfer();
|
BeginTransfer();
|
||||||
epd_init();
|
epd_init();
|
||||||
SendLuts(part_mode);
|
SendLuts(part_mode);
|
||||||
@@ -169,17 +171,29 @@ void drv_base::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
send_zoneInfo();
|
send_zoneInfo();
|
||||||
guy_epdCmd(0x12);
|
guy_epdCmd(0x12);
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
guy_epdBusy(-200);
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
guy_epdCmd(0x12);
|
guy_epdCmd(0x12);
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
guy_epdBusy(-2000);
|
}
|
||||||
BeginTransfer();
|
lastRefresh=millis();
|
||||||
epd_init();
|
}
|
||||||
SendLuts(1);
|
if(m&2){//stage 2
|
||||||
guy_epdCmd(0x92);
|
uint32_t ms=millis()-lastRefresh;
|
||||||
EndTransfer();
|
if(part_mode){
|
||||||
|
if(ms<200) guy_epdBusy(ms-200);
|
||||||
|
//guy_epdBusy(-200);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(ms<2000) guy_epdBusy(ms-2000);
|
||||||
|
//guy_epdBusy(-2000);
|
||||||
|
BeginTransfer();
|
||||||
|
epd_init();
|
||||||
|
SendLuts(1);
|
||||||
|
guy_epdCmd(0x92);
|
||||||
|
EndTransfer();
|
||||||
|
}
|
||||||
|
lastRefresh=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void drv_base::drv_sleep() { //开始屏幕睡眠
|
void drv_base::drv_sleep() { //开始屏幕睡眠
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public:
|
|||||||
virtual int drv_ID() const=0;
|
virtual int drv_ID() const=0;
|
||||||
void drv_init(); //初始化屏幕
|
void drv_init(); //初始化屏幕
|
||||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||||
void drv_sleep() ; //开始屏幕睡眠
|
void drv_sleep() ; //开始屏幕睡眠
|
||||||
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
||||||
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
||||||
|
|||||||
@@ -120,7 +120,9 @@ void drv::drv_fullpart(bool part){ //切换慢刷/快刷功能
|
|||||||
}
|
}
|
||||||
part_mode=part;
|
part_mode=part;
|
||||||
}
|
}
|
||||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||||
|
if(m&1){//stage 1
|
||||||
|
if(lastRefresh) drv_dispWriter(f,2);
|
||||||
if(sleeping) Init();
|
if(sleeping) Init();
|
||||||
BeginTransfer();
|
BeginTransfer();
|
||||||
guy_epdCmd(0x4E); guy_epdParam(0x00); guy_epdParam(0x00);
|
guy_epdCmd(0x4E); guy_epdParam(0x00); guy_epdParam(0x00);
|
||||||
@@ -138,7 +140,15 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
Load_LUT(!part_mode);
|
Load_LUT(!part_mode);
|
||||||
guy_epdCmd(0x20);
|
guy_epdCmd(0x20);
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
guy_epdBusy(part_mode?500:1300);
|
lastRefresh=millis();
|
||||||
|
}
|
||||||
|
if(m&2){//stage 2
|
||||||
|
uint32_t ms=millis()-lastRefresh;
|
||||||
|
uint32_t u=part_mode?500:1300;
|
||||||
|
if(ms<u) guy_epdBusy(u-ms);
|
||||||
|
lastRefresh=0;
|
||||||
|
}
|
||||||
|
//guy_epdBusy(part_mode?500:1300);
|
||||||
}
|
}
|
||||||
void drv::drv_sleep() { //开始屏幕睡眠
|
void drv::drv_sleep() { //开始屏幕睡眠
|
||||||
if(RST_PIN>=0){
|
if(RST_PIN>=0){
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
int drv_ID() const { return READGUY_DEV_370A; }
|
int drv_ID() const { return READGUY_DEV_370A; }
|
||||||
void drv_init(); //初始化屏幕
|
void drv_init(); //初始化屏幕
|
||||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||||
void drv_sleep() ; //开始屏幕睡眠
|
void drv_sleep() ; //开始屏幕睡眠
|
||||||
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
||||||
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
|
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
|
||||||
|
|||||||
@@ -185,7 +185,9 @@ void drv::drv_fullpart(bool part){ //初始化慢刷功能
|
|||||||
if(epdFull<=1) epdFull = !part; //epdFull==2代表睡眠中, 不能快刷
|
if(epdFull<=1) epdFull = !part; //epdFull==2代表睡眠中, 不能快刷
|
||||||
if(epdFull) GreyScaling=0;
|
if(epdFull) GreyScaling=0;
|
||||||
}
|
}
|
||||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||||
|
if(m&1){//stage 1
|
||||||
|
if(lastRefresh) drv_dispWriter(f,2);
|
||||||
BeginTransfer();
|
BeginTransfer();
|
||||||
epd_Init();
|
epd_Init();
|
||||||
SetMemory();
|
SetMemory();
|
||||||
@@ -211,9 +213,7 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
SetLut(lut_213_B72_Full);
|
SetLut(lut_213_B72_Full);
|
||||||
guy_epdCmd(0x22);
|
guy_epdCmd(0x22);
|
||||||
guy_epdParam(0xc4);
|
guy_epdParam(0xc4);
|
||||||
guy_epdCmd(0x20);
|
//guy_epdBusy(1600); //等待刷完
|
||||||
EndTransfer();
|
|
||||||
guy_epdBusy(1600); //等待刷完
|
|
||||||
}
|
}
|
||||||
else{ //快刷
|
else{ //快刷
|
||||||
guy_epdCmd(0x2c); //may a mistake? 此处不需要设置vcom
|
guy_epdCmd(0x2c); //may a mistake? 此处不需要设置vcom
|
||||||
@@ -221,17 +221,24 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
SetLut(GreyScalingHighQuality?lut_213_B72_16grey:lut_213_B72);
|
SetLut(GreyScalingHighQuality?lut_213_B72_16grey:lut_213_B72);
|
||||||
guy_epdCmd(0x22);
|
guy_epdCmd(0x22);
|
||||||
guy_epdParam(0x04);
|
guy_epdParam(0x04);
|
||||||
guy_epdCmd(0x20);
|
|
||||||
EndTransfer();
|
|
||||||
guy_epdBusy(260); //等待屏幕刷新完成
|
|
||||||
}
|
}
|
||||||
BeginTransfer(); //write again
|
guy_epdCmd(0x20);
|
||||||
SetMemory();
|
|
||||||
guy_epdCmd(0x26);
|
|
||||||
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
|
|
||||||
SpiTransfer(f(i)); //按照给定的RAM写入数据
|
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
if(epdFull) power_down();
|
lastRefresh=millis();
|
||||||
|
}
|
||||||
|
if(m&2){//stage 2
|
||||||
|
uint32_t ms=millis()-lastRefresh;
|
||||||
|
uint32_t u=epdFull?1600:260;
|
||||||
|
if(ms<u) guy_epdBusy(u-ms); //等待屏幕刷新完成
|
||||||
|
lastRefresh=0;
|
||||||
|
BeginTransfer(); //write again
|
||||||
|
SetMemory();
|
||||||
|
guy_epdCmd(0x26);
|
||||||
|
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
|
||||||
|
SpiTransfer(f(i)); //按照给定的RAM写入数据
|
||||||
|
EndTransfer();
|
||||||
|
if(epdFull) power_down();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void drv::drv_draw16grey_step(std::function<uint8_t(int)> f, int step){
|
void drv::drv_draw16grey_step(std::function<uint8_t(int)> f, int step){
|
||||||
if(_quality&1) return readguyEpdBase::drv_draw16grey_step(f,step);
|
if(_quality&1) return readguyEpdBase::drv_draw16grey_step(f,step);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
int drv_ID() const { return READGUY_DEV_420A; }
|
int drv_ID() const { return READGUY_DEV_420A; }
|
||||||
void drv_init(); //初始化屏幕
|
void drv_init(); //初始化屏幕
|
||||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||||
void drv_sleep() ; //开始屏幕睡眠
|
void drv_sleep() ; //开始屏幕睡眠
|
||||||
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
||||||
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
|
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
|
||||||
|
|||||||
@@ -147,7 +147,9 @@ const PROGMEM unsigned char drv::lutFast_b_w[] ={ 0x5a,2,0,63,0,1 };
|
|||||||
const PROGMEM unsigned char drv::lutFast_w_b[] ={ 0x84,2,0,48,0,1 };
|
const PROGMEM unsigned char drv::lutFast_w_b[] ={ 0x84,2,0,48,0,1 };
|
||||||
const PROGMEM unsigned char drv::lutFast_b_b[] ={ 0x01,2,0,48,0,1 };
|
const PROGMEM unsigned char drv::lutFast_b_b[] ={ 0x01,2,0,48,0,1 };
|
||||||
//void drv::epd_display(){
|
//void drv::epd_display(){
|
||||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||||
|
if(m&1){//stage 1
|
||||||
|
if(lastRefresh) drv_dispWriter(f,2);
|
||||||
BeginTransfer();
|
BeginTransfer();
|
||||||
Init(part_mode);
|
Init(part_mode);
|
||||||
if(part_mode){
|
if(part_mode){
|
||||||
@@ -181,7 +183,13 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
}
|
}
|
||||||
guy_epdCmd(0x12);
|
guy_epdCmd(0x12);
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
guy_epdBusy(part_mode?-800:-3600);
|
lastRefresh=millis();
|
||||||
|
}
|
||||||
|
if(m&2){//stage 2
|
||||||
|
uint32_t ms=millis()-lastRefresh;
|
||||||
|
uint32_t u=part_mode?800:3600;
|
||||||
|
if(ms<u) guy_epdBusy(ms-u);
|
||||||
|
lastRefresh=0;
|
||||||
BeginTransfer();
|
BeginTransfer();
|
||||||
if(part_mode){
|
if(part_mode){
|
||||||
sendArea();
|
sendArea();
|
||||||
@@ -189,7 +197,6 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
|
for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
|
||||||
SpiTransfer(f(i));
|
SpiTransfer(f(i));
|
||||||
guy_epdCmd(0x92);
|
guy_epdCmd(0x92);
|
||||||
EndTransfer();
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
Init(2);
|
Init(2);
|
||||||
@@ -199,6 +206,7 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
SpiTransfer(f(i));
|
SpiTransfer(f(i));
|
||||||
guy_epdCmd(0x92);
|
guy_epdCmd(0x92);
|
||||||
guy_epdCmd(0x02);
|
guy_epdCmd(0x02);
|
||||||
|
}
|
||||||
EndTransfer();
|
EndTransfer();
|
||||||
guy_epdBusy(-20);
|
guy_epdBusy(-20);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
void drv_init(); //初始化屏幕
|
void drv_init(); //初始化屏幕
|
||||||
//void drv_draw16grey(uint8_t *d16bit);
|
//void drv_draw16grey(uint8_t *d16bit);
|
||||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||||
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
|
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //按照函数刷新
|
||||||
void drv_sleep() ; //开始屏幕睡眠
|
void drv_sleep() ; //开始屏幕睡眠
|
||||||
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
||||||
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
|
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ int readguyEpdBase::IfInit(SPIClass &c,int8_t cs,int8_t dc,int8_t rst,int8_t bus
|
|||||||
DigitalWrite(DC_PIN,HIGH);
|
DigitalWrite(DC_PIN,HIGH);
|
||||||
if(BUSY_PIN>=0) pinMode(BUSY_PIN, INPUT);
|
if(BUSY_PIN>=0) pinMode(BUSY_PIN, INPUT);
|
||||||
_spi = &c;
|
_spi = &c;
|
||||||
|
lastRefresh=0;
|
||||||
|
|
||||||
//_spi->begin();
|
//_spi->begin();
|
||||||
//_spi->beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
|
//_spi->beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
|
||||||
@@ -161,8 +162,7 @@ void readguyEpdBase::Reset(uint32_t minTime)
|
|||||||
|
|
||||||
void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y,int o,
|
void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y,int o,
|
||||||
uint16_t fw, uint16_t fh){
|
uint16_t fw, uint16_t fh){
|
||||||
#ifndef FLOYD_STEINBERG_DITHERING
|
static const PROGMEM uint8_t bayer_tab [64]={
|
||||||
static const uint8_t bayer_tab [64]={
|
|
||||||
0, 32, 8, 40, 2, 34, 10, 42,
|
0, 32, 8, 40, 2, 34, 10, 42,
|
||||||
48, 16, 56, 24, 50, 18, 58, 26,
|
48, 16, 56, 24, 50, 18, 58, 26,
|
||||||
12, 44, 4, 36, 14, 46, 6, 38,
|
12, 44, 4, 36, 14, 46, 6, 38,
|
||||||
@@ -172,24 +172,21 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
|
|||||||
15, 47, 7, 39, 13, 45, 5, 37,
|
15, 47, 7, 39, 13, 45, 5, 37,
|
||||||
63, 31, 55, 23, 61, 29, 53, 21
|
63, 31, 55, 23, 61, 29, 53, 21
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
if(!fw) fw=spr.width();
|
if(!fw) fw=spr.width();
|
||||||
if(!fh) fh=spr.height();
|
if(!fh) fh=spr.height();
|
||||||
if((!fw) || (!fh)) return;
|
if((!fw) || (!fh)) return;
|
||||||
if(o==0 || o==1){
|
if(o==0 || o==1){
|
||||||
readBuff = new uint16_t[spr.width()];
|
readBuff = new uint16_t[spr.width()];
|
||||||
#ifdef FLOYD_STEINBERG_DITHERING
|
|
||||||
floyd_tab[0] = new int16_t [fw];
|
floyd_tab[0] = new int16_t [fw];
|
||||||
floyd_tab[1] = new int16_t [fw];
|
floyd_tab[1] = new int16_t [fw];
|
||||||
for(int j=0;j<fw;j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
|
for(int j=0;j<fw;j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
|
||||||
#endif
|
|
||||||
writeBuff = new uint8_t[(fw+7)>>3];
|
writeBuff = new uint8_t[(fw+7)>>3];
|
||||||
}
|
}
|
||||||
sprbase.fillRect(x,y,fw,fh,1);
|
sprbase.fillRect(x,y,fw,fh,1);
|
||||||
for(int32_t i=y;i<(int32_t)fh+y;i++){
|
for(int32_t i=y;i<(int32_t)fh+y;i++){
|
||||||
spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
|
|
||||||
#ifdef FLOYD_STEINBERG_DITHERING
|
|
||||||
uint_fast8_t buff8bit=0;
|
uint_fast8_t buff8bit=0;
|
||||||
|
spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
|
||||||
|
if(_quality&2){
|
||||||
for(int32_t j=0;j<fw;j++){
|
for(int32_t j=0;j<fw;j++){
|
||||||
int gv=greysc(readBuff[j*spr.width()/fw]);
|
int gv=greysc(readBuff[j*spr.width()/fw]);
|
||||||
int32_t flodelta = floyd_tab[i&1][j]+(int32_t)((gv<<8)|gv);
|
int32_t flodelta = floyd_tab[i&1][j]+(int32_t)((gv<<8)|gv);
|
||||||
@@ -218,24 +215,24 @@ void readguyEpdBase::drv_drawImage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_
|
|||||||
{ floyd_tab[!(i&1)][j+1] += (flodelta )>>4; }
|
{ floyd_tab[!(i&1)][j+1] += (flodelta )>>4; }
|
||||||
}
|
}
|
||||||
for(int floi=0;floi<fw;floi++) floyd_tab[i&1][floi]=0;
|
for(int floi=0;floi<fw;floi++) floyd_tab[i&1][floi]=0;
|
||||||
#else
|
|
||||||
for(int32_t j=0;j<w;j++){
|
|
||||||
uint_fast8_t buff8bit=0;
|
|
||||||
for(uint_fast8_t b=0;b<8;b++)
|
|
||||||
buff8bit |= (bayer_tab[(b<<3)|(i&7)]<(greysc(readBuff[j*spr.width()/fw])>>2))<<(7-b);
|
|
||||||
writeBuff[j]=buff8bit;
|
|
||||||
}
|
}
|
||||||
#endif
|
else{
|
||||||
|
for(int32_t j=0;j<((fw+7)>>3);j++){
|
||||||
|
buff8bit=0;
|
||||||
|
for(uint_fast8_t b=0;b<8;b++)
|
||||||
|
buff8bit |= ((pgm_read_byte(bayer_tab+((b<<3)|(i&7)))<<2)+2
|
||||||
|
<greysc(readBuff[((j<<3)+b)*spr.width()/fw]))<<(7-b);
|
||||||
|
writeBuff[j]=buff8bit;
|
||||||
|
}
|
||||||
|
}
|
||||||
sprbase.drawBitmap(x,i,writeBuff,fw,1,1,0);
|
sprbase.drawBitmap(x,i,writeBuff,fw,1,1,0);
|
||||||
}
|
}
|
||||||
//_display((const uint8_t*)sprbase.getBuffer()); //显示
|
//_display((const uint8_t*)sprbase.getBuffer()); //显示
|
||||||
if(o==0 || o==3){
|
if(o==0 || o==3){
|
||||||
delete []readBuff;
|
delete []readBuff;
|
||||||
delete []writeBuff;
|
delete []writeBuff;
|
||||||
#ifdef FLOYD_STEINBERG_DITHERING
|
|
||||||
delete [] floyd_tab[0] ;
|
delete [] floyd_tab[0] ;
|
||||||
delete [] floyd_tab[1] ;
|
delete [] floyd_tab[1] ;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//不支持的话使用单色抖动刷屏
|
//不支持的话使用单色抖动刷屏
|
||||||
@@ -247,10 +244,8 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
|||||||
if((!fw) || (!fh)) return;
|
if((!fw) || (!fh)) return;
|
||||||
readBuff = new uint16_t[spr.width()];
|
readBuff = new uint16_t[spr.width()];
|
||||||
if(_quality&2){
|
if(_quality&2){
|
||||||
#ifdef FLOYD_DITHERING_16GREY
|
|
||||||
floyd_tab[0] = new int16_t [fw];
|
floyd_tab[0] = new int16_t [fw];
|
||||||
floyd_tab[1] = new int16_t [fw];
|
floyd_tab[1] = new int16_t [fw];
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
writeBuff = new uint8_t[(fw+7)>>3];
|
writeBuff = new uint8_t[(fw+7)>>3];
|
||||||
sprbase.fillRect(x,y,fw,fh,1);
|
sprbase.fillRect(x,y,fw,fh,1);
|
||||||
@@ -260,15 +255,12 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
|||||||
drv_dispWriter(FILL_WHITE);
|
drv_dispWriter(FILL_WHITE);
|
||||||
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
|
|
||||||
if(_quality&2) for(int j=0;j<fw;j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
|
if(_quality&2) for(int j=0;j<fw;j++){ floyd_tab[0][j] = 0; floyd_tab[1][j] = 0; }
|
||||||
#endif
|
|
||||||
for(int i=y;i<(int32_t)fh+y;i++){
|
for(int i=y;i<(int32_t)fh+y;i++){
|
||||||
uint_fast8_t buff8bit=0;
|
uint_fast8_t buff8bit=0;
|
||||||
spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
|
spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
|
||||||
for(int32_t j=0;j<fw;j++){
|
for(int32_t j=0;j<fw;j++){
|
||||||
//for(uint_fast8_t b=0;b<8;b++){
|
//for(uint_fast8_t b=0;b<8;b++){
|
||||||
#ifdef FLOYD_DITHERING_16GREY
|
|
||||||
uint_fast8_t cg=0;
|
uint_fast8_t cg=0;
|
||||||
if(_quality&2){
|
if(_quality&2){
|
||||||
int gv=greysc(readBuff[j*spr.width()/fw]);
|
int gv=greysc(readBuff[j*spr.width()/fw]);
|
||||||
@@ -284,9 +276,7 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
|||||||
if(j!=fw-1) { floyd_tab[!(i&1)][j+1] += (fd )>>4; }
|
if(j!=fw-1) { floyd_tab[!(i&1)][j+1] += (fd )>>4; }
|
||||||
}
|
}
|
||||||
else{ cg=greysc(readBuff[j*spr.width()/fw])>>4; }
|
else{ cg=greysc(readBuff[j*spr.width()/fw])>>4; }
|
||||||
#else
|
//uint_fast8_t cg=greysc(readBuff[j*spr.width()/fw])>>4;
|
||||||
uint_fast8_t cg=greysc(readBuff[j*spr.width()/fw])>>4;
|
|
||||||
#endif
|
|
||||||
if(negativeOrder)
|
if(negativeOrder)
|
||||||
buff8bit |= (cg<k)<<((~j)&7);
|
buff8bit |= (cg<k)<<((~j)&7);
|
||||||
else{
|
else{
|
||||||
@@ -300,9 +290,7 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
|||||||
//}
|
//}
|
||||||
//sprbase.drawPixel(x+j,i,(greysc(readBuff[j*spr.width()/fw])/16)==(15-k));
|
//sprbase.drawPixel(x+j,i,(greysc(readBuff[j*spr.width()/fw])/16)==(15-k));
|
||||||
}
|
}
|
||||||
#ifdef FLOYD_DITHERING_16GREY
|
|
||||||
if(_quality&2) for(int floi=0;floi<fw;floi++) floyd_tab[i&1][floi]=0;
|
if(_quality&2) for(int floi=0;floi<fw;floi++) floyd_tab[i&1][floi]=0;
|
||||||
#endif
|
|
||||||
sprbase.drawBitmap(x,i,writeBuff,fw,1,1,0);
|
sprbase.drawBitmap(x,i,writeBuff,fw,1,1,0);
|
||||||
}
|
}
|
||||||
drv_draw16grey_step((const uint8_t*)sprbase.getBuffer(),k); //使用灰度显示函数
|
drv_draw16grey_step((const uint8_t*)sprbase.getBuffer(),k); //使用灰度显示函数
|
||||||
@@ -310,10 +298,8 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
|||||||
delete []readBuff;
|
delete []readBuff;
|
||||||
delete []writeBuff;
|
delete []writeBuff;
|
||||||
if(_quality&2){
|
if(_quality&2){
|
||||||
#ifdef FLOYD_DITHERING_16GREY
|
|
||||||
delete [] floyd_tab[0] ;
|
delete [] floyd_tab[0] ;
|
||||||
delete [] floyd_tab[1] ;
|
delete [] floyd_tab[1] ;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} /* END OF FILE. ReadGuy project.
|
} /* END OF FILE. ReadGuy project.
|
||||||
Copyright (C) 2023 FriendshipEnder. */
|
Copyright (C) 2023 FriendshipEnder. */
|
||||||
@@ -55,9 +55,8 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
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];
|
||||||
#if (defined(FLOYD_DITHERING_16GREY) || defined(FLOYD_STEINBERG_DITHERING))
|
|
||||||
int16_t *floyd_tab[2];
|
int16_t *floyd_tab[2];
|
||||||
#endif
|
uint32_t lastRefresh;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
readguyEpdBase(void);
|
readguyEpdBase(void);
|
||||||
@@ -82,9 +81,9 @@ public:
|
|||||||
virtual int drv_ID() const =0; //返回驱动代号
|
virtual int drv_ID() const =0; //返回驱动代号
|
||||||
virtual void drv_init()=0; //初始化屏幕
|
virtual void drv_init()=0; //初始化屏幕
|
||||||
virtual void drv_fullpart(bool part)=0; //初始化慢刷功能
|
virtual void drv_fullpart(bool part)=0; //初始化慢刷功能
|
||||||
void _display(const uint8_t *d){ drv_dispWriter([&](int n)->uint8_t{return d[n];}); }
|
void _display(const uint8_t *d,uint8_t m=3){ drv_dispWriter([&](int n)->uint8_t{return d[n];},m); }
|
||||||
virtual void drv_dispWriter(std::function<uint8_t(int)>)=0; //按照显示函数刷新
|
virtual void drv_dispWriter(std::function<uint8_t(int)>,uint8_t m=3)=0; //按照显示函数刷新
|
||||||
void drv_color(uint8_t c){ drv_dispWriter([=](int)->uint8_t{return c;}); } //单色刷新
|
void drv_color(uint8_t c,uint8_t m=3){ drv_dispWriter([=](int)->uint8_t{return c;},m); } //单色刷新
|
||||||
virtual void drv_sleep() =0; //开始屏幕睡眠
|
virtual void drv_sleep() =0; //开始屏幕睡眠
|
||||||
virtual int drv_width() const=0; //返回显示区域宽度, 即使旋转了也不能影响此函数输出
|
virtual int drv_width() const=0; //返回显示区域宽度, 即使旋转了也不能影响此函数输出
|
||||||
virtual int drv_height()const=0; //返回显示区域高度, 即使旋转了也不能影响此函数输出
|
virtual int drv_height()const=0; //返回显示区域高度, 即使旋转了也不能影响此函数输出
|
||||||
|
|||||||
@@ -73,7 +73,7 @@
|
|||||||
//#define _DEFINA_SD_CS_PIN 0
|
//#define _DEFINA_SD_CS_PIN 0
|
||||||
|
|
||||||
// * for NodeMcu ctg stack LCF board
|
// * for NodeMcu ctg stack LCF board
|
||||||
#define WHITE_GAP 8
|
#define WHITE_GAP 2
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define DISPLAY_TYPE_ST7789_240320 //2.0寸的ST7789 IPS TFT模块
|
#define DISPLAY_TYPE_ST7789_240320 //2.0寸的ST7789 IPS TFT模块
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ void drv::drv_init(){
|
|||||||
void drv::drv_fullpart(bool part){
|
void drv::drv_fullpart(bool part){
|
||||||
partMode=part;
|
partMode=part;
|
||||||
}
|
}
|
||||||
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
void drv::drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m){ //单色刷新
|
||||||
|
if(!(m&1)) return; //stage 1
|
||||||
uint16_t dat[8];
|
uint16_t dat[8];
|
||||||
unsigned short xbits=(drv_width()+7)/8;
|
unsigned short xbits=(drv_width()+7)/8;
|
||||||
if(partMode==0){
|
if(partMode==0){
|
||||||
@@ -79,7 +80,6 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void drv::drv_sleep() {}
|
void drv::drv_sleep() {}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
int drv_ID() const { return MEPD_DEBUG_DISPLAY; }
|
int drv_ID() const { return MEPD_DEBUG_DISPLAY; }
|
||||||
void drv_init(); //初始化屏幕
|
void drv_init(); //初始化屏幕
|
||||||
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
void drv_fullpart(bool part); //切换慢刷/快刷功能
|
||||||
void drv_dispWriter(std::function<uint8_t(int)> f); //单色刷新
|
void drv_dispWriter(std::function<uint8_t(int)> f,uint8_t m=3); //单色刷新
|
||||||
void drv_sleep() ; //开始屏幕睡眠
|
void drv_sleep() ; //开始屏幕睡眠
|
||||||
int drv_width() const { return ips.width()-2*WHITE_GAP; } //返回显示区域宽度
|
int drv_width() const { return ips.width()-2*WHITE_GAP; } //返回显示区域宽度
|
||||||
int drv_height() const{ return ips.height()-2*WHITE_GAP; } //返回显示区域高度
|
int drv_height() const{ return ips.height()-2*WHITE_GAP; } //返回显示区域高度
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* @file guy_version.h
|
* @file guy_version.h
|
||||||
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
|
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
|
||||||
* @brief readguy 版本控制文件.
|
* @brief readguy 版本控制文件.
|
||||||
* @version 1.0
|
* @version 1.3.2
|
||||||
* @date 2023-09-21
|
* @date 2023-09-21
|
||||||
|
|
||||||
* @attention
|
* @attention
|
||||||
@@ -41,9 +41,9 @@
|
|||||||
//另外, 在提交新版本之前, 不要忘记在github上创建release, 否则Arduino IDE会读不到
|
//另外, 在提交新版本之前, 不要忘记在github上创建release, 否则Arduino IDE会读不到
|
||||||
#define READGUY_V_MAJOR 1
|
#define READGUY_V_MAJOR 1
|
||||||
#define READGUY_V_MINOR 3
|
#define READGUY_V_MINOR 3
|
||||||
#define READGUY_V_PATCH 0
|
#define READGUY_V_PATCH 2
|
||||||
#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.3.0"
|
#define READGUY_VERSION "1.3.2"
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define _READGUY_PLATFORM "ESP8266"
|
#define _READGUY_PLATFORM "ESP8266"
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ bool ReadguyDriver::server_loop(){ //此时等待网页操作完成响应...
|
|||||||
}
|
}
|
||||||
if(refFlag!=127) {
|
if(refFlag!=127) {
|
||||||
Serial.printf("randch: %d %c\n",randomch[refFlag],(char)(randomch[refFlag]));
|
Serial.printf("randch: %d %c\n",randomch[refFlag],(char)(randomch[refFlag]));
|
||||||
drawChar((width()>>1)-46+refFlag*24,(height()>>1)-14,randomch[refFlag],true,false,4);
|
drawChar((guy_dev->drv_width()>>1)-46+refFlag*24,(guy_dev->drv_height()>>1)-14,randomch[refFlag],true,false,4);
|
||||||
guy_dev->drv_fullpart(1);
|
guy_dev->drv_fullpart(1);
|
||||||
guy_dev->_display((const uint8_t*)getBuffer());
|
guy_dev->_display((const uint8_t*)getBuffer());
|
||||||
}
|
}
|
||||||
@@ -311,13 +311,14 @@ void ReadguyDriver::handleInitPost(){
|
|||||||
setEpdDriver(); //尝试初始化屏幕
|
setEpdDriver(); //尝试初始化屏幕
|
||||||
Serial.println(F("[Guy] Init details..."));
|
Serial.println(F("[Guy] Init details..."));
|
||||||
setTextSize(1);
|
setTextSize(1);
|
||||||
drawCenterString(setSDcardDriver()?"SD Init OK!":"SD Init failed!",width()>>1,(height()>>1)+20);
|
drawCenterString(setSDcardDriver()?"SD Init OK!":"SD Init failed!",
|
||||||
|
guy_dev->drv_width()>>1,(guy_dev->drv_height()>>1)+20);
|
||||||
setButtonDriver(); //初始化按钮..
|
setButtonDriver(); //初始化按钮..
|
||||||
//} //尝试初始化按键, 调用后, 若SD卡初始化成功, READGUY_sd_ok的值会变成1
|
//} //尝试初始化按键, 调用后, 若SD卡初始化成功, READGUY_sd_ok的值会变成1
|
||||||
drawRect((width()>>1)-46 ,(height()>>1)-14,20,28,0);
|
drawRect((guy_dev->drv_width()>>1)-46 ,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||||
drawRect((width()>>1)-46+24,(height()>>1)-14,20,28,0);
|
drawRect((guy_dev->drv_width()>>1)-46+24,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||||
drawRect((width()>>1)-46+48,(height()>>1)-14,20,28,0);
|
drawRect((guy_dev->drv_width()>>1)-46+48,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||||
drawRect((width()>>1)-46+72,(height()>>1)-14,20,28,0);
|
drawRect((guy_dev->drv_width()>>1)-46+72,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||||
spibz++;
|
spibz++;
|
||||||
guy_dev->drv_fullpart(1);
|
guy_dev->drv_fullpart(1);
|
||||||
guy_dev->_display((const uint8_t*)getBuffer());
|
guy_dev->_display((const uint8_t*)getBuffer());
|
||||||
@@ -644,7 +645,7 @@ const PROGMEM char ReadguyDriver::verify2_html[] =
|
|||||||
"al\" method=\"POST\"><input type=\'text\' name=\'t_verify\' maxlength=\"6";
|
"al\" method=\"POST\"><input type=\'text\' name=\'t_verify\' maxlength=\"6";
|
||||||
const PROGMEM char ReadguyDriver::verifybtn_html[3][200] = {
|
const PROGMEM char ReadguyDriver::verifybtn_html[3][200] = {
|
||||||
"一个按键, 操作可能比较繁琐, 但功能还都可以的.<br/>"
|
"一个按键, 操作可能比较繁琐, 但功能还都可以的.<br/>"
|
||||||
"点按: 下一个/向下翻页<br/>双击: 上一个/向上翻页<br/>三连击: 返回/切换输入法<br/>长按: 确定/选择",
|
"点按: 下一个/向下翻页<br/>双击: 确定/选择<br/>三连击: 返回/切换输入法<br/>长按: 上一个/向上翻页",
|
||||||
"两个按键, 操作可以满足需求.<br/>"
|
"两个按键, 操作可以满足需求.<br/>"
|
||||||
"按键1点按: 下一个/向下翻页<br/>按键1长按: 上一个/向上翻页<br/>按键2点按: 确定/选择<br/>按键2长按: 返回/切换输入法",
|
"按键1点按: 下一个/向下翻页<br/>按键1长按: 上一个/向上翻页<br/>按键2点按: 确定/选择<br/>按键2长按: 返回/切换输入法",
|
||||||
"三个按键, 操作非常流畅.<br/>"
|
"三个按键, 操作非常流畅.<br/>"
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ ReadguyDriver::ReadguyDriver(){
|
|||||||
READGUY_sd_ok = 0; //初始默认SD卡未成功初始化
|
READGUY_sd_ok = 0; //初始默认SD卡未成功初始化
|
||||||
READGUY_buttons = 0; //初始情况下没有按钮
|
READGUY_buttons = 0; //初始情况下没有按钮
|
||||||
} //WiFiSet: 是否保持AP服务器一直处于打开状态
|
} //WiFiSet: 是否保持AP服务器一直处于打开状态
|
||||||
uint8_t ReadguyDriver::init(uint8_t WiFiSet,bool initepd/* ,int g_width,int g_height */){
|
uint8_t ReadguyDriver::init(uint8_t WiFiSet, bool initepd){
|
||||||
if(READGUY_cali==127) //已经初始化过了一次了, 为了防止里面一些volatile的东西出现问题....还是退出吧
|
if(READGUY_cali==127) //已经初始化过了一次了, 为了防止里面一些volatile的东西出现问题....还是退出吧
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef DYNAMIC_PIN_SETTINGS
|
#ifdef DYNAMIC_PIN_SETTINGS
|
||||||
@@ -180,15 +180,14 @@ void ReadguyDriver::setEpdDriver(bool initepd/* ,int g_width,int g_height */){
|
|||||||
//else guy_width = guy_dev->drv_width(); //宽度必须是8的倍数, 但这个可以由GFX自动计算
|
//else guy_width = guy_dev->drv_width(); //宽度必须是8的倍数, 但这个可以由GFX自动计算
|
||||||
//if(g_height) guy_height = g_height;
|
//if(g_height) guy_height = g_height;
|
||||||
//else guy_height = guy_dev->drv_height();
|
//else guy_height = guy_dev->drv_height();
|
||||||
Serial.println(F("[Guy EPD] EPD init OK"));
|
|
||||||
//以下依赖于你的图形驱动
|
//以下依赖于你的图形驱动
|
||||||
setColorDepth(1); //单色模式
|
setColorDepth(1); //单色模式
|
||||||
createPalette(); //初始化颜色系统
|
createPalette(); //初始化颜色系统
|
||||||
Serial.printf_P(PSTR("[Guy EPD] mono set: w: %d, h: %d\n"),guy_dev->drv_width(),guy_dev->drv_height());
|
Serial.printf_P(PSTR("[Guy EPD] EPD init OK: w: %d, h: %d\n"),guy_dev->drv_width(),guy_dev->drv_height());
|
||||||
//创建画布. 根据LovyanGFX的特性, 如果以前有画布会自动重新生成新画布
|
//创建画布. 根据LovyanGFX的特性, 如果以前有画布会自动重新生成新画布
|
||||||
//此外, 即使画布宽度不是8的倍数(如2.13寸单色),也支持自动补全8的倍数 ( 250x122 => 250x128 )
|
//此外, 即使画布宽度不是8的倍数(如2.13寸单色),也支持自动补全8的倍数 ( 250x122 => 250x128 )
|
||||||
//为了保证图片显示功能的正常使用, 高度也必须是8的倍数.
|
//为了保证图片显示功能的正常使用, 高度也必须是8的倍数.
|
||||||
createSprite(guy_dev->drv_width(),(guy_dev->drv_height()+7)&0x7ffffff8);
|
createSprite(guy_dev->drv_width(),guy_dev->drv_height());
|
||||||
//这里发现如果用自定义的内存分配方式会更好一些. 不会导致返回的height不对. 但是因为LovyanGFX库未更新 暂时不能这么用.
|
//这里发现如果用自定义的内存分配方式会更好一些. 不会导致返回的height不对. 但是因为LovyanGFX库未更新 暂时不能这么用.
|
||||||
//setRotation(1); //旋转之后操作更方便
|
//setRotation(1); //旋转之后操作更方便
|
||||||
setRotation(0);
|
setRotation(0);
|
||||||
@@ -280,18 +279,21 @@ void ReadguyDriver::setButtonDriver(){
|
|||||||
if(READGUY_btn1) btn_rd[0].begin(abs(READGUY_btn1)-1,rd_btn_f,(READGUY_btn1>0));
|
if(READGUY_btn1) btn_rd[0].begin(abs(READGUY_btn1)-1,rd_btn_f,(READGUY_btn1>0));
|
||||||
if(READGUY_btn2) btn_rd[1].begin(abs(READGUY_btn2)-1,rd_btn_f,(READGUY_btn2>0));
|
if(READGUY_btn2) btn_rd[1].begin(abs(READGUY_btn2)-1,rd_btn_f,(READGUY_btn2>0));
|
||||||
if(READGUY_btn3) btn_rd[2].begin(abs(READGUY_btn3)-1,rd_btn_f,(READGUY_btn3>0));
|
if(READGUY_btn3) btn_rd[2].begin(abs(READGUY_btn3)-1,rd_btn_f,(READGUY_btn3>0));
|
||||||
|
//if(READGUY_buttons==1){
|
||||||
|
btn_rd[0].setLongRepeatMode(1); //允许连按
|
||||||
|
//}
|
||||||
if(READGUY_buttons==2){
|
if(READGUY_buttons==2){
|
||||||
btn_rd[0].setMultiBtn(1); //设置为多个按钮,不识别双击或三击
|
btn_rd[0].setMultiBtn(1); //设置为多个按钮,不识别双击或三击
|
||||||
btn_rd[0].setLongRepeatMode(1);
|
//btn_rd[0].setLongRepeatMode(1);
|
||||||
btn_rd[1].setMultiBtn(1); //设置为多个按钮,不识别双击或三击
|
btn_rd[1].setMultiBtn(1); //设置为多个按钮,不识别双击或三击
|
||||||
btn_rd[1].setLongRepeatMode(0);
|
btn_rd[1].setLongRepeatMode(0);
|
||||||
}
|
}
|
||||||
else if(READGUY_buttons==3){
|
else if(READGUY_buttons==3){
|
||||||
btn_rd[0].setLongPressMs(1); //不识别双击三击, 只有按一下或者长按, 并且开启连按
|
btn_rd[0].long_press_ms = 150; //不识别双击三击, 只有按一下或者长按, 并且开启连按
|
||||||
btn_rd[0].setLongRepeatMode(1);
|
//btn_rd[0].setLongRepeatMode(1);
|
||||||
btn_rd[1].setMultiBtn(1); //设置为多个按钮,不识别双击或三击
|
btn_rd[1].setMultiBtn(1); //设置为多个按钮,不识别双击或三击
|
||||||
btn_rd[1].setLongRepeatMode(0);
|
btn_rd[1].setLongRepeatMode(0);
|
||||||
btn_rd[2].setLongPressMs(1); //不识别双击三击, 只有按一下或者长按, 并且开启连按
|
btn_rd[2].long_press_ms = 1; //不识别双击三击, 只有按一下或者长按, 并且开启连按
|
||||||
btn_rd[2].setLongRepeatMode(1);
|
btn_rd[2].setLongRepeatMode(1);
|
||||||
}
|
}
|
||||||
#ifdef ESP8266 //对于esp8266, 需要注册到ticker. 这是因为没freertos.
|
#ifdef ESP8266 //对于esp8266, 需要注册到ticker. 这是因为没freertos.
|
||||||
@@ -370,32 +372,41 @@ void ReadguyDriver::setBright(int d){
|
|||||||
digitalWrite(READGUY_bl_pin,d?HIGH:LOW);
|
digitalWrite(READGUY_bl_pin,d?HIGH:LOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ReadguyDriver::display(bool part){
|
void ReadguyDriver::display(uint8_t 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
|
||||||
if(READGUY_cali==127){
|
if(READGUY_cali==127){
|
||||||
//in_press(); //暂停, 然后读取按键状态 spibz
|
//in_press(); //暂停, 然后读取按键状态 spibz
|
||||||
guy_dev->drv_fullpart(part);
|
guy_dev->drv_fullpart(part&1);
|
||||||
guy_dev->_display((const uint8_t*)getBuffer());
|
guy_dev->_display((const uint8_t*)getBuffer(),((part>>1)?part>>1:3));
|
||||||
//in_release(); //恢复
|
//in_release(); //恢复
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ReadguyDriver::display(std::function<uint8_t(int)> f, bool part){
|
void ReadguyDriver::displayBuffer(const uint8_t *buf, uint8_t 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&1);
|
||||||
guy_dev->drv_dispWriter(f);
|
guy_dev->_display(buf,((part>>1)?part>>1:3));
|
||||||
|
//in_release(); //恢复
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ReadguyDriver::display(std::function<uint8_t(int)> f, uint8_t part){
|
||||||
|
if(READGUY_cali==127){
|
||||||
|
//in_press(); //暂停, 然后读取按键状态 spibz
|
||||||
|
guy_dev->drv_fullpart(part&1);
|
||||||
|
guy_dev->drv_dispWriter(f,((part>>1)?part>>1:3));
|
||||||
//in_release(); //恢复
|
//in_release(); //恢复
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ReadguyDriver::drawImage(LGFX_Sprite &base, LGFX_Sprite &spr,uint16_t x,uint16_t y,uint16_t zoomw, uint16_t zoomh) {
|
void ReadguyDriver::drawImage(LGFX_Sprite &base, LGFX_Sprite &spr,uint16_t x,uint16_t y,uint16_t zoomw, uint16_t zoomh) {
|
||||||
if(READGUY_cali==127) guy_dev->drv_drawImage(base, spr, x, y, 0, zoomw, zoomh);
|
if(READGUY_cali==127) guy_dev->drv_drawImage(base, spr, x, y, 0, zoomw, zoomh);
|
||||||
}
|
}
|
||||||
void ReadguyDriver::drawImageStage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint8_t stage,
|
void ReadguyDriver::drawImageStage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y,uint8_t stage,
|
||||||
uint8_t totalstage,uint16_t zoomw,uint16_t zoomh) {
|
uint8_t totalstage,uint16_t zoomw,uint16_t zoomh) {
|
||||||
if(READGUY_cali!=127 || stage>=totalstage) return;
|
if(READGUY_cali!=127 || stage>=totalstage) return;
|
||||||
guy_dev->drv_drawImage(*this, spr, x, y, (totalstage<=1)?0:(stage==0?1:(stage==(totalstage-1)?3:2)),zoomw,zoomh);
|
//Serial.printf("stage: %d/%d\n",stage+1,totalstage);
|
||||||
|
guy_dev->drv_drawImage(sprbase, spr, x, y, (totalstage<=1)?0:(stage==0?1:(stage==(totalstage-1)?3:2)),zoomw,zoomh);
|
||||||
}
|
}
|
||||||
void ReadguyDriver::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);
|
||||||
@@ -489,29 +500,47 @@ void ReadguyDriver::nvs_write(){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t ReadguyDriver::getBtn_impl(){ //按钮不可用, 返回0.
|
uint8_t ReadguyDriver::getBtn_impl(){ //按钮不可用, 返回0.
|
||||||
|
static uint32_t last=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 |= 4; //双击-确定
|
||||||
else if(res1 == 4) res4 |= 4; //长按-确定
|
|
||||||
else if(res1 == 3) res4 |= 8; //三击-返回
|
else if(res1 == 3) res4 |= 8; //三击-返回
|
||||||
|
else if(res1 == 4) res4 |= 2; //长按-向上翻页
|
||||||
|
else if(res1 == 5) res4 |= 3; //单击后长按-新增操作(可以连按)
|
||||||
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(millis()-last>500){
|
||||||
else if(res1 == 4) res4 |= 2; //左键长按-向上翻页
|
if(res1 == 1) res4 |= 1; //左键点按-向下翻页
|
||||||
if(res2 == 1) res4 |= 4; //右键点按-确定
|
else if(res1 == 4) {
|
||||||
else if(res2 == 4) res4 |= 8; //右键长按-返回
|
res4 |= 2; //左键长按-向上翻页
|
||||||
|
//if(btn_rd[1].isPressedRaw()) res4 |= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(btn_rd[0].isPressedRaw() && res2){
|
||||||
|
res4 |= 3; //右键点按-确定
|
||||||
|
last=millis();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(res2 == 1) res4 |= 4; //右键点按-确定
|
||||||
|
else if(res2 == 4) res4 |= 8; //右键长按-返回
|
||||||
|
}
|
||||||
|
if(res4==5 || res4==6) res4=3;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
res1=btn_rd[0].read();
|
res1=btn_rd[0].read();
|
||||||
res2=btn_rd[1].read();
|
res2=btn_rd[1].read();
|
||||||
res3=btn_rd[2].read();
|
res3=btn_rd[2].read();
|
||||||
if(res1 == 4) res4 |= 1;
|
if(res1 && millis()-last >= btn_rd[1].long_repeat_ms && (!btn_rd[2].isPressedRaw())) res4 |= 2;
|
||||||
if(res3 == 4) res4 |= 2;
|
if(res3) {
|
||||||
|
res4 |= ((btn_rd[0].isPressedRaw()<<1)|1);
|
||||||
|
last=millis();
|
||||||
|
}
|
||||||
|
//if(res3 && ((millis()-last)<btn_rd[0].long_repeat_ms)) res4 |=3;
|
||||||
if(res2 == 1) res4 |= 4;
|
if(res2 == 1) res4 |= 4;
|
||||||
else if(res2 == 4) res4 |= 8;
|
else if(res2 == 4) res4 |= 8;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -132,6 +132,13 @@
|
|||||||
#define READGUY_buttons (config_data[21]) //按钮个数, 0-3都有可能
|
#define READGUY_buttons (config_data[21]) //按钮个数, 0-3都有可能
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define READGUY_SLOW 0
|
||||||
|
#define READGUY_FAST 1
|
||||||
|
#define READGUY_SLOW_START 2
|
||||||
|
#define READGUY_FAST_START 3
|
||||||
|
#define READGUY_SLOW_END 4
|
||||||
|
#define READGUY_FAST_END 5
|
||||||
|
|
||||||
class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
||||||
public:
|
public:
|
||||||
#ifdef READGUY_ESP_ENABLE_WIFI
|
#ifdef READGUY_ESP_ENABLE_WIFI
|
||||||
@@ -147,15 +154,18 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
/** @brief 初始化readguy
|
/** @brief 初始化readguy
|
||||||
* @param WiFiSet 是否保持AP模式关闭. 0:配网完成自动关WiFi, 1:需要手动调用 WiFi.mode(WIFI_OFF) 关闭WiFi.
|
* @param WiFiSet 是否保持AP模式关闭. 0:配网完成自动关WiFi, 1:需要手动调用 WiFi.mode(WIFI_OFF) 关闭WiFi.
|
||||||
* 2:自动连接到已存的WiFi, 但不等待连接成功
|
* 2:自动连接到已存的WiFi, 但不等待连接成功
|
||||||
|
* @param initepd 是否初始化墨水屏. 初始化后的首次刷屏必为慢刷. 如果是不断电复位, 可以不初始化墨水屏直接刷屏
|
||||||
* @return SD卡是否就绪
|
* @return SD卡是否就绪
|
||||||
*/
|
*/
|
||||||
uint8_t init(uint8_t WiFiSet = 0,bool initepd = 1/* ,int g_width = 0,int g_height = 0 */);
|
uint8_t init(uint8_t WiFiSet = 0, bool initepd = 1);
|
||||||
/// @brief 设置显示亮度
|
/// @brief 设置显示亮度
|
||||||
void setBright(int d);
|
void setBright(int d);
|
||||||
/// @brief 返回显示亮度
|
/// @brief 返回显示亮度
|
||||||
int getBright() const { return currentBright; }
|
int getBright() const { return currentBright; }
|
||||||
/// @brief 刷新显示到屏幕上
|
/// @brief 刷新显示到屏幕上
|
||||||
void display(bool part = true);
|
void display(uint8_t part = READGUY_FAST);
|
||||||
|
/// @brief 刷新显示到屏幕上
|
||||||
|
void displayBuffer(const uint8_t *buf, uint8_t part);
|
||||||
/** @brief 刷新显示到屏幕上, 可以自定义读取指定位置像素的函数
|
/** @brief 刷新显示到屏幕上, 可以自定义读取指定位置像素的函数
|
||||||
* @param f 自定义的函数. 此函数将在读取像素并输出到墨水屏时被调用.
|
* @param f 自定义的函数. 此函数将在读取像素并输出到墨水屏时被调用.
|
||||||
* 每次调用需要返回 "参数对应位置" 的8个像素的颜色信息(凑成一字节). 其中左侧应在高位,右侧应在低位.
|
* 每次调用需要返回 "参数对应位置" 的8个像素的颜色信息(凑成一字节). 其中左侧应在高位,右侧应在低位.
|
||||||
@@ -170,7 +180,7 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
* @endcode
|
* @endcode
|
||||||
* 该函数会将参数从0开始,每次逐渐增加1的顺序来被调用. 即先调用f(0),再f(1),f(2),f(3)... 以此类推.
|
* 该函数会将参数从0开始,每次逐渐增加1的顺序来被调用. 即先调用f(0),再f(1),f(2),f(3)... 以此类推.
|
||||||
*/
|
*/
|
||||||
void display(std::function<uint8_t(int)> f, bool part = true);
|
void display(std::function<uint8_t(int)> f, uint8_t part);
|
||||||
/// @brief 显示图片, 使用抖动算法. 可以用省内存的方法显示, 可以缩放到指定的宽度和高度
|
/// @brief 显示图片, 使用抖动算法. 可以用省内存的方法显示, 可以缩放到指定的宽度和高度
|
||||||
void drawImage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint16_t zoomw=0, uint16_t zoomh=0){
|
void drawImage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint16_t zoomw=0, uint16_t zoomh=0){
|
||||||
if(READGUY_cali==127) drawImage(*this,spr,x,y,zoomw,zoomh);
|
if(READGUY_cali==127) drawImage(*this,spr,x,y,zoomw,zoomh);
|
||||||
@@ -240,6 +250,8 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
bool SDinside(bool check=true) { return check?setSDcardDriver():READGUY_sd_ok; };
|
bool SDinside(bool check=true) { return check?setSDcardDriver():READGUY_sd_ok; };
|
||||||
/// @brief 检查按钮. 当配置未完成时,按钮不可用, 返回0.
|
/// @brief 检查按钮. 当配置未完成时,按钮不可用, 返回0.
|
||||||
uint8_t getBtn() { return (READGUY_cali==127)?getBtn_impl():0; }
|
uint8_t getBtn() { return (READGUY_cali==127)?getBtn_impl():0; }
|
||||||
|
/// @brief 根据按钮ID来检查按钮. 注意这里如果按下返回0, 没按下或者按钮无效返回1
|
||||||
|
//uint8_t getBtn(unsigned int btnID){return btnID<getButtonsCount()?(!(btn_rd[0].isPressedRaw())):1;}
|
||||||
/** @brief 返回可用的文件系统. 当SD卡可用时, 返回SD卡. 否则根据情况返回最近的可用文件系统
|
/** @brief 返回可用的文件系统. 当SD卡可用时, 返回SD卡. 否则根据情况返回最近的可用文件系统
|
||||||
* @param initSD 2:总是重新初始化SD卡; 1:若SD卡不可用则初始化; 0:SD卡不可用则返回LittleFS. */
|
* @param initSD 2:总是重新初始化SD卡; 1:若SD卡不可用则初始化; 0:SD卡不可用则返回LittleFS. */
|
||||||
fs::FS &guyFS(uint8_t initSD = 0);
|
fs::FS &guyFS(uint8_t initSD = 0);
|
||||||
@@ -328,14 +340,18 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
static uint8_t rd_btn_f(uint8_t btn);
|
static uint8_t rd_btn_f(uint8_t btn);
|
||||||
uint8_t getBtn_impl(); //按钮不可用, 返回0.
|
uint8_t getBtn_impl(); //按钮不可用, 返回0.
|
||||||
static void in_press(){ //SPI开始传输屏幕数据
|
static void in_press(){ //SPI开始传输屏幕数据
|
||||||
#ifndef ESP8266
|
#ifdef ESP8266
|
||||||
|
if(!spibz) SPI.beginTransaction(SPISettings(ESP8266_SPI_FREQUENCY, MSBFIRST, SPI_MODE0));
|
||||||
|
#else
|
||||||
if(!spibz) epd_spi->beginTransaction(SPISettings(ESP32_DISP_FREQUENCY, MSBFIRST, SPI_MODE0));
|
if(!spibz) epd_spi->beginTransaction(SPISettings(ESP32_DISP_FREQUENCY, MSBFIRST, SPI_MODE0));
|
||||||
#endif
|
#endif
|
||||||
spibz ++;
|
spibz ++;
|
||||||
}
|
}
|
||||||
static void in_release(){//SPI结束传输屏幕数据
|
static void in_release(){//SPI结束传输屏幕数据
|
||||||
spibz --;
|
spibz --;
|
||||||
#ifndef ESP8266
|
#ifdef ESP8266
|
||||||
|
if(!spibz) SPI.endTransaction();
|
||||||
|
#else
|
||||||
if(!spibz) epd_spi->endTransaction();
|
if(!spibz) epd_spi->endTransaction();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -368,14 +384,23 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
|||||||
//constexpr int memHeight () const { return guy_height ; } //返回显存高度(不是画幅高度),不会随着画布旋转改变
|
//constexpr int memHeight () const { return guy_height ; } //返回显存高度(不是画幅高度),不会随着画布旋转改变
|
||||||
int drvWidth () const { return READGUY_cali==127?guy_dev->drv_width():0; } //返回显示屏硬件宽度(不是画幅宽度)
|
int drvWidth () const { return READGUY_cali==127?guy_dev->drv_width():0; } //返回显示屏硬件宽度(不是画幅宽度)
|
||||||
int drvHeight() const { return READGUY_cali==127?guy_dev->drv_height():0; } //返回显示屏硬件高度(不是画幅高度)
|
int drvHeight() const { return READGUY_cali==127?guy_dev->drv_height():0; } //返回显示屏硬件高度(不是画幅高度)
|
||||||
int width () const { return READGUY_cali==127?((getRotation()&1)?drvHeight():drvWidth()):0; }
|
//int width () const { return (getRotation()&1)?drvHeight():drvWidth(); }
|
||||||
int height() const { return READGUY_cali==127?((getRotation()&1)?drvWidth():drvHeight()):0; }
|
//int height() const { return (getRotation()&1)?drvWidth():drvHeight(); }
|
||||||
|
size_t getFreeMem() const { return
|
||||||
|
#ifdef ESP8266
|
||||||
|
ESP.getFreeHeap();
|
||||||
|
#else
|
||||||
|
esp_get_free_heap_size();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
// private:
|
// private:
|
||||||
void implBeginTransfer() { guy_dev->BeginTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!
|
void implBeginTransfer() { guy_dev->BeginTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!
|
||||||
void implEndTransfer() { guy_dev->EndTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!
|
void implEndTransfer() { guy_dev->EndTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!
|
||||||
/// @brief 分阶段显示图片, 使用抖动算法. 更加的省内存.目前函数
|
/// @brief 分阶段显示图片, 使用抖动算法. 更加的省内存.目前函数
|
||||||
void drawImageStage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint8_t stage,uint8_t totalstage,
|
void drawImageStage(LGFX_Sprite &spr,uint16_t x,uint16_t y,uint8_t stage,uint8_t totalstage,
|
||||||
uint16_t zoomw=0,uint16_t zoomh=0);
|
uint16_t zoomw=0,uint16_t zoomh=0){ drawImageStage(*this,spr,x,y,stage,totalstage,zoomw,zoomh); }
|
||||||
|
void drawImageStage(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16_t x,uint16_t y,
|
||||||
|
uint8_t stage,uint8_t totalstage,uint16_t zoomw=0,uint16_t zoomh=0);
|
||||||
};
|
};
|
||||||
#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