mirror of
https://github.com/fsender/readguy.git
synced 2025-12-10 20:18:14 +08:00
update to 1.3.1 ver
This commit is contained in:
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,3 +1,23 @@
|
||||
## 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
|
||||
|
||||
1. 增加了真.保姆级的教程 (详细到注释比代码多很多倍)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<img src="extra/artset/readguy_theme3.png" width="30%" height="auto">
|
||||
|
||||
**版本1.3.0正式发布!欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~
|
||||
**版本1.3.1正式发布!欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~
|
||||
|
||||
欢迎克隆, 项目交流QQ群: 926824162 (萌新可以进来问问题的哟), 项目的 Bilibili 主页: [BV1f94y187wz](https://www.bilibili.com/video/BV1f94y187wz/) 记得三连+关注我这个宝藏up主哦~
|
||||
|
||||
|
||||
@@ -157,8 +157,8 @@ void setup(){ //Arduino的setup函数. 这个函数在上电之后仅执行一
|
||||
//guy.setCursor(10,10); //设置显示的坐标
|
||||
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
|
||||
|
||||
guy.display(true); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上. 可简写为 guy.display(), 效果一样.
|
||||
//guy.display(false); // 慢速刷新.
|
||||
guy.display(READGUY_FAST); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上. 可简写为 guy.display(), 效果一样.
|
||||
//guy.display(READGUY_SLOW); // 慢速刷新.
|
||||
|
||||
//想知道更多内容, 欢迎移步到其他示例.
|
||||
}
|
||||
|
||||
@@ -11,6 +11,25 @@
|
||||
* @brief ReadGuy功能演示.
|
||||
* 将根目录下的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都要用这种方法.
|
||||
*
|
||||
* 用于演示BMP格式图片灰度显示.
|
||||
*
|
||||
* @note 食用方法:
|
||||
@@ -76,14 +95,14 @@ void setup(){
|
||||
guy.drawString("Hello Readguy!",10,10); //用此函数将字符串显示到屏幕缓存内
|
||||
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
|
||||
|
||||
guy.display(true); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
|
||||
//guy.display(false); // 慢速刷新.
|
||||
guy.display(READGUY_FAST); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
|
||||
//guy.display(READGUY_SLOW); // 慢速刷新.
|
||||
|
||||
guy.setCursor(10,30); //设置显示的坐标
|
||||
|
||||
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卡
|
||||
@@ -134,7 +153,7 @@ void setup(){
|
||||
|
||||
guy.fillScreen(1);
|
||||
|
||||
guy.display(false); // 慢速刷新. 慢刷的对比度显著高于快速刷新, 而且可以消除残影
|
||||
guy.display(READGUY_SLOW); // 慢速刷新. 慢刷的对比度显著高于快速刷新, 而且可以消除残影
|
||||
|
||||
for(int i=1;i<16;i++){ //灰度测试, 循环设置不同灰度
|
||||
|
||||
@@ -203,7 +222,7 @@ void setup(){
|
||||
guy.setFont(&FreeMonoBold9pt7b); //设置文本字体
|
||||
guy.setTextColor(0); //设置文本颜色
|
||||
guy.fillScreen(1); //用白色清屏.
|
||||
guy.display(false); //慢刷. 注意, 进行慢刷操作之后, 所有之前显示的灰度内容均会被重新刷成纯黑色
|
||||
guy.display(READGUY_SLOW); //慢刷. 注意, 进行慢刷操作之后, 所有之前显示的灰度内容均会被重新刷成纯黑色
|
||||
//不管是浅灰色还是深灰色, 进行慢刷之后只有黑白色. 原来的非白色像素(浅灰色,深灰色和黑色等) 会全刷成白色.
|
||||
|
||||
guy.drawString("Rotation 0",10,12); //默认旋转方向为0. 实际的默认方向取决于屏幕IC. 大多数屏幕IC是竖屏.
|
||||
@@ -239,13 +258,13 @@ void setup(){
|
||||
guy.setTextColor(1); //设置文本颜色为白色,因为被反色的屏幕的当前像素颜色以黑色像素为主
|
||||
guy.drawString("Wake Up! ~\\(^_^)/~",10,50); //退出睡眠状态
|
||||
|
||||
guy.display(false); //使用慢刷 来唤醒处于低功耗状态下的屏幕.
|
||||
guy.display(READGUY_SLOW); //使用慢刷 来唤醒处于低功耗状态下的屏幕.
|
||||
|
||||
// ------------------ 6 - 可以利用灰度来达到的一些显示效果 --<<<<<<
|
||||
|
||||
guy.fillScreen(1); //清屏
|
||||
|
||||
guy.display(FILL_WHITE,false); //慢刷清屏. 左侧的FILL_WHITE表示 不写入屏幕缓存, 直接刷全白
|
||||
guy.display(FILL_WHITE,READGUY_SLOW); //慢刷清屏. 左侧的FILL_WHITE表示 不写入屏幕缓存, 直接刷全白
|
||||
//可以改为FILL_BLACK来设置写入缓存全黑.
|
||||
//以上的方式均不会修改屏幕缓存中的内容. 右侧的false表示全屏慢刷.
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ void setup(){
|
||||
//guy.setCursor(10,10); //设置显示的坐标
|
||||
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
|
||||
|
||||
guy.display(true); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
|
||||
//guy.display(false); // 慢速刷新.
|
||||
guy.display(READGUY_FAST); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
|
||||
//guy.display(READGUY_SLOW); // 慢速刷新.
|
||||
|
||||
//想知道更多内容, 欢迎移步到其他示例.
|
||||
}
|
||||
|
||||
@@ -15,6 +15,29 @@
|
||||
* - 运行的会很缓慢, 因为示例的图片文件比较大.
|
||||
* 1. 在运行过ex01或者ex02的开发板上 编译烧录本程序.
|
||||
* 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} 代码食用注意事项:
|
||||
* 这一部分的代码很难读, 或者按维莫斯小姐的说法, 很 "抽象" .
|
||||
@@ -174,13 +197,13 @@ void setup(){
|
||||
delay(2000);
|
||||
|
||||
|
||||
guy.display(FILL_WHITE,true); //在保持屏幕缓存不变的时候快速刷新白屏.
|
||||
guy.display(FILL_WHITE,READGUY_FAST); //在保持屏幕缓存不变的时候快速刷新白屏.
|
||||
guy.drawImage(sp,0,0,guy.width(),guy.height()); //绘画的画布可以被放大或者缩小到任意宽度和高度.
|
||||
//此处的参数调用表示将会在屏幕坐标(0,0)开始显示, 显示的画布宽度缩放到屏幕宽度, 画布高度缩放到屏幕高度.
|
||||
guy.display(); //调用display函数刷屏.
|
||||
delay(2000);
|
||||
|
||||
guy.display(FILL_WHITE,true); //在保持屏幕缓存不变的时候快速刷新白屏
|
||||
guy.display(FILL_WHITE,READGUY_FAST); //在保持屏幕缓存不变的时候快速刷新白屏
|
||||
guy.fillScreen(1); //白屏清屏(清屏幕缓存)
|
||||
guy.drawImage(sp,10,10,65,50); //缩放: 缩小到65X50
|
||||
guy.display(); //调用display函数刷屏.
|
||||
@@ -244,7 +267,7 @@ void setup(){
|
||||
|
||||
im.filename=BMP_FILE; //在此直接设置文件路径和文件名.
|
||||
|
||||
guy.display(FILL_WHITE,false); //将屏幕全刷成白屏. 为了即将的图片刷新.
|
||||
guy.display(FILL_WHITE,READGUY_SLOW); //将屏幕全刷成白屏. 为了即将的图片刷新.
|
||||
//建议在使用drawImageFile函数之前, 使用慢刷刷白屏, 可以保证显示效果清晰可见.
|
||||
|
||||
im.drawImageFile(); //显示BMP格式.图片. im会自动识别文件扩展名并绘制.
|
||||
@@ -265,7 +288,7 @@ void setup(){
|
||||
|
||||
im.background=0; //设置背景颜色, 0黑1白, 此处设为背景色为黑色.
|
||||
|
||||
guy.display(FILL_WHITE,false); //将屏幕全刷成白屏. 为了即将的图片刷新.
|
||||
guy.display(FILL_WHITE,READGUY_SLOW); //将屏幕全刷成白屏. 为了即将的图片刷新.
|
||||
|
||||
im.drawImageFile(); //显示JPG格式.图片. im会自动识别文件扩展名并绘制.
|
||||
delay(2000);
|
||||
@@ -279,7 +302,7 @@ void setup(){
|
||||
im.scalex=400.0f/1280.0f;
|
||||
im.scaley=300.0f/576.0f;
|
||||
|
||||
guy.display(FILL_WHITE, false);//显示. 此处的功能就是将显示缓存输出到屏幕上
|
||||
guy.display(FILL_WHITE, READGUY_SLOW);//显示. 此处的功能就是将显示缓存输出到屏幕上
|
||||
|
||||
im.drawImageFile(); //显示PNG格式.图片. ESP8266可能不会绘制.
|
||||
delay(2000);
|
||||
@@ -308,7 +331,7 @@ void setup(){
|
||||
im.exPoolSize=MEM_POOL; //设置外部缓存内存大小
|
||||
|
||||
guy.setGreyQuality(1); //设置灰度模式为默认灰度显示模式
|
||||
guy.display(FILL_WHITE,false); //将屏幕全刷成白屏. 为了即将显示灰度图.
|
||||
guy.display(FILL_WHITE,READGUY_SLOW); //将屏幕全刷成白屏. 为了即将显示灰度图.
|
||||
|
||||
im.enableFloyd=0; //禁用掉抖动算法.
|
||||
|
||||
@@ -316,7 +339,7 @@ void setup(){
|
||||
|
||||
delay(2000);
|
||||
|
||||
guy.display(FILL_WHITE,false); //将屏幕全刷成白屏. 为了即将显示灰度图.
|
||||
guy.display(FILL_WHITE,READGUY_SLOW); //将屏幕全刷成白屏. 为了即将显示灰度图.
|
||||
|
||||
im.enableFloyd=1; // 重新启用抖动算法.
|
||||
|
||||
@@ -351,7 +374,7 @@ void setup(){
|
||||
}
|
||||
guy.drawLine(guy.width(),0,0,guy.height(),0);
|
||||
|
||||
guy.display(false); //刷新屏幕, 显示绘画的线段
|
||||
guy.display(READGUY_SLOW); //刷新屏幕, 显示绘画的线段
|
||||
|
||||
//im.baseFs=&guy.guyFS(); //直接更改im内的数据即可设置绘制参数. 在此处就是设置文件系统.
|
||||
im.filename=BMP_FILE; //在此直接设置文件路径和文件名.
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/fsender/readguy"
|
||||
},
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"frameworks": "arduino",
|
||||
"platforms": ["espressif32", "espressif8266"],
|
||||
"headers": "readguy.h",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name=readguy
|
||||
version=1.3.0
|
||||
version=1.3.1
|
||||
author=fsender <f_ender@163.com>
|
||||
maintainer=fsender <f_ender@163.com>
|
||||
sentence=A free E-paper display driver library supports 16-level greyscale.
|
||||
|
||||
@@ -110,7 +110,9 @@ void drvBase::drv_fullpart(bool part){ //切换慢刷/快刷功能
|
||||
if(!part) iLut=15; //恢复默认的灰度模式
|
||||
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);
|
||||
BeginTransfer();
|
||||
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(0xff);
|
||||
EndTransfer();
|
||||
guy_epdBusy((this->lut == (const uint8_t*)lut_fast)?idleFastRf:idleSlowRf);
|
||||
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();
|
||||
lastRefresh=millis();
|
||||
}
|
||||
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
uint32_t u=(this->lut == (const uint8_t*)lut_fast)?idleFastRf:idleSlowRf;
|
||||
if(ms<u) guy_epdBusy(u-ms);
|
||||
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() { //开始屏幕睡眠
|
||||
if(RST_PIN>=0) { //未定义RST_PIN时无法唤醒
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
virtual int drv_ID() const=0;
|
||||
void drv_init(); //初始化屏幕
|
||||
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() ; //开始屏幕睡眠
|
||||
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
||||
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
||||
|
||||
@@ -148,7 +148,9 @@ void drvSSD168x::drv_fullpart(bool part){ //切换慢刷/快刷功能
|
||||
if(!part) { iLut=15; greyScaling=0; }
|
||||
_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();
|
||||
if(_part){
|
||||
//Reset();
|
||||
@@ -196,7 +198,15 @@ void drvSSD168x::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
guy_epdParam(_part?0x0f:0xc7);
|
||||
guy_epdCmd(0x20);
|
||||
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() { //开始屏幕睡眠
|
||||
if(RST_PIN>=0){ //无法唤醒
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
virtual int drv_ID() const =0;
|
||||
void drv_init(); //初始化屏幕
|
||||
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() ; //开始屏幕睡眠
|
||||
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
||||
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
||||
|
||||
@@ -119,7 +119,9 @@ void drv::drv_fullpart(bool part){ //初始化慢刷功能
|
||||
epdFull = !part;
|
||||
//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();
|
||||
if(epdFull) { //当刷新模式从快刷切换为慢刷时, 需要发送一次init
|
||||
epdFull=0;
|
||||
@@ -143,7 +145,15 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
guy_epdParam(epdFull?0xc4:0x04);
|
||||
guy_epdCmd(0x20);
|
||||
EndTransfer();
|
||||
guy_epdBusy(epdFull?1600:310);
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
lastRefresh=0;
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
uint32_t u=epdFull?1600:310;
|
||||
if(ms<u) guy_epdBusy(u-ms);
|
||||
}
|
||||
//guy_epdBusy(epdFull?1600:310);
|
||||
}
|
||||
void drv::drv_sleep() { //开始屏幕睡眠
|
||||
if(RST_PIN>=0){ //RST_PIN<0 无法唤醒
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
int drv_ID() const { return READGUY_DEV_213A; }
|
||||
void drv_init(); //初始化屏幕
|
||||
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() ; //开始屏幕睡眠
|
||||
int drv_width() const { return EPD_REAL_WIDTH; }; //返回显示区域宽度
|
||||
//int drv_panelwidth() const { return GUY_D_WIDTH; }; //返回缓存的数据宽度
|
||||
|
||||
@@ -152,7 +152,9 @@ void drv_base::drv_setDepth(uint8_t i){
|
||||
SendLuts(1);
|
||||
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();
|
||||
epd_init();
|
||||
SendLuts(part_mode);
|
||||
@@ -169,17 +171,29 @@ void drv_base::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
send_zoneInfo();
|
||||
guy_epdCmd(0x12);
|
||||
EndTransfer();
|
||||
guy_epdBusy(-200);
|
||||
}
|
||||
else{
|
||||
guy_epdCmd(0x12);
|
||||
EndTransfer();
|
||||
guy_epdBusy(-2000);
|
||||
BeginTransfer();
|
||||
epd_init();
|
||||
SendLuts(1);
|
||||
guy_epdCmd(0x92);
|
||||
EndTransfer();
|
||||
}
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
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() { //开始屏幕睡眠
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
virtual int drv_ID() const=0;
|
||||
void drv_init(); //初始化屏幕
|
||||
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() ; //开始屏幕睡眠
|
||||
int drv_width() const { return epdWidth; }; //返回显示区域宽度
|
||||
int drv_height() const{ return epdHeight; }; //返回显示区域高度
|
||||
|
||||
@@ -120,7 +120,9 @@ void drv::drv_fullpart(bool 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();
|
||||
BeginTransfer();
|
||||
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);
|
||||
guy_epdCmd(0x20);
|
||||
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() { //开始屏幕睡眠
|
||||
if(RST_PIN>=0){
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
int drv_ID() const { return READGUY_DEV_370A; }
|
||||
void drv_init(); //初始化屏幕
|
||||
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() ; //开始屏幕睡眠
|
||||
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
||||
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) 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();
|
||||
epd_Init();
|
||||
SetMemory();
|
||||
@@ -211,9 +213,7 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
SetLut(lut_213_B72_Full);
|
||||
guy_epdCmd(0x22);
|
||||
guy_epdParam(0xc4);
|
||||
guy_epdCmd(0x20);
|
||||
EndTransfer();
|
||||
guy_epdBusy(1600); //等待刷完
|
||||
//guy_epdBusy(1600); //等待刷完
|
||||
}
|
||||
else{ //快刷
|
||||
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);
|
||||
guy_epdCmd(0x22);
|
||||
guy_epdParam(0x04);
|
||||
guy_epdCmd(0x20);
|
||||
EndTransfer();
|
||||
guy_epdBusy(260); //等待屏幕刷新完成
|
||||
}
|
||||
BeginTransfer(); //write again
|
||||
SetMemory();
|
||||
guy_epdCmd(0x26);
|
||||
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
|
||||
SpiTransfer(f(i)); //按照给定的RAM写入数据
|
||||
guy_epdCmd(0x20);
|
||||
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){
|
||||
if(_quality&1) return readguyEpdBase::drv_draw16grey_step(f,step);
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
int drv_ID() const { return READGUY_DEV_420A; }
|
||||
void drv_init(); //初始化屏幕
|
||||
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() ; //开始屏幕睡眠
|
||||
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
||||
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_b_b[] ={ 0x01,2,0,48,0,1 };
|
||||
//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();
|
||||
Init(part_mode);
|
||||
if(part_mode){
|
||||
@@ -181,7 +183,13 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
}
|
||||
guy_epdCmd(0x12);
|
||||
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();
|
||||
if(part_mode){
|
||||
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++)
|
||||
SpiTransfer(f(i));
|
||||
guy_epdCmd(0x92);
|
||||
EndTransfer();
|
||||
}
|
||||
else{
|
||||
Init(2);
|
||||
@@ -199,6 +206,7 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
SpiTransfer(f(i));
|
||||
guy_epdCmd(0x92);
|
||||
guy_epdCmd(0x02);
|
||||
}
|
||||
EndTransfer();
|
||||
guy_epdBusy(-20);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
void drv_init(); //初始化屏幕
|
||||
//void drv_draw16grey(uint8_t *d16bit);
|
||||
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() ; //开始屏幕睡眠
|
||||
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
|
||||
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);
|
||||
if(BUSY_PIN>=0) pinMode(BUSY_PIN, INPUT);
|
||||
_spi = &c;
|
||||
lastRefresh=0;
|
||||
|
||||
//_spi->begin();
|
||||
//_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,
|
||||
uint16_t fw, uint16_t fh){
|
||||
#ifndef FLOYD_STEINBERG_DITHERING
|
||||
static const uint8_t bayer_tab [64]={
|
||||
static const PROGMEM uint8_t bayer_tab [64]={
|
||||
0, 32, 8, 40, 2, 34, 10, 42,
|
||||
48, 16, 56, 24, 50, 18, 58, 26,
|
||||
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,
|
||||
63, 31, 55, 23, 61, 29, 53, 21
|
||||
};
|
||||
#endif
|
||||
if(!fw) fw=spr.width();
|
||||
if(!fh) fh=spr.height();
|
||||
if((!fw) || (!fh)) return;
|
||||
if(o==0 || o==1){
|
||||
readBuff = new uint16_t[spr.width()];
|
||||
#ifdef FLOYD_STEINBERG_DITHERING
|
||||
floyd_tab[0] = 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; }
|
||||
#endif
|
||||
writeBuff = new uint8_t[(fw+7)>>3];
|
||||
}
|
||||
sprbase.fillRect(x,y,fw,fh,1);
|
||||
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;
|
||||
spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
|
||||
if(_quality&2){
|
||||
for(int32_t j=0;j<fw;j++){
|
||||
int gv=greysc(readBuff[j*spr.width()/fw]);
|
||||
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; }
|
||||
}
|
||||
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);
|
||||
}
|
||||
//_display((const uint8_t*)sprbase.getBuffer()); //显示
|
||||
if(o==0 || o==3){
|
||||
delete []readBuff;
|
||||
delete []writeBuff;
|
||||
#ifdef FLOYD_STEINBERG_DITHERING
|
||||
delete [] floyd_tab[0] ;
|
||||
delete [] floyd_tab[1] ;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//不支持的话使用单色抖动刷屏
|
||||
@@ -247,10 +244,8 @@ void readguyEpdBase::drv_draw16grey(LGFX_Sprite &sprbase,LGFX_Sprite &spr,uint16
|
||||
if((!fw) || (!fh)) return;
|
||||
readBuff = new uint16_t[spr.width()];
|
||||
if(_quality&2){
|
||||
#ifdef FLOYD_DITHERING_16GREY
|
||||
floyd_tab[0] = new int16_t [fw];
|
||||
floyd_tab[1] = new int16_t [fw];
|
||||
#endif
|
||||
}
|
||||
writeBuff = new uint8_t[(fw+7)>>3];
|
||||
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_fullpart(1);
|
||||
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; }
|
||||
#endif
|
||||
for(int i=y;i<(int32_t)fh+y;i++){
|
||||
uint_fast8_t buff8bit=0;
|
||||
spr.readRect(0,(i-y)*spr.height()/fh,spr.width(),1,readBuff);
|
||||
for(int32_t j=0;j<fw;j++){
|
||||
//for(uint_fast8_t b=0;b<8;b++){
|
||||
#ifdef FLOYD_DITHERING_16GREY
|
||||
uint_fast8_t cg=0;
|
||||
if(_quality&2){
|
||||
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; }
|
||||
}
|
||||
else{ cg=greysc(readBuff[j*spr.width()/fw])>>4; }
|
||||
#else
|
||||
uint_fast8_t cg=greysc(readBuff[j*spr.width()/fw])>>4;
|
||||
#endif
|
||||
//uint_fast8_t cg=greysc(readBuff[j*spr.width()/fw])>>4;
|
||||
if(negativeOrder)
|
||||
buff8bit |= (cg<k)<<((~j)&7);
|
||||
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));
|
||||
}
|
||||
#ifdef FLOYD_DITHERING_16GREY
|
||||
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);
|
||||
}
|
||||
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 []writeBuff;
|
||||
if(_quality&2){
|
||||
#ifdef FLOYD_DITHERING_16GREY
|
||||
delete [] floyd_tab[0] ;
|
||||
delete [] floyd_tab[1] ;
|
||||
#endif
|
||||
}
|
||||
} /* END OF FILE. ReadGuy project.
|
||||
Copyright (C) 2023 FriendshipEnder. */
|
||||
@@ -55,9 +55,8 @@ protected:
|
||||
#endif
|
||||
uint16_t *readBuff;// = new uint16_t[spr.width()];
|
||||
uint8_t *writeBuff;// = new uint8_t[w];
|
||||
#if (defined(FLOYD_DITHERING_16GREY) || defined(FLOYD_STEINBERG_DITHERING))
|
||||
int16_t *floyd_tab[2];
|
||||
#endif
|
||||
uint32_t lastRefresh;
|
||||
|
||||
public:
|
||||
readguyEpdBase(void);
|
||||
@@ -82,9 +81,9 @@ public:
|
||||
virtual int drv_ID() const =0; //返回驱动代号
|
||||
virtual void drv_init()=0; //初始化屏幕
|
||||
virtual void drv_fullpart(bool part)=0; //初始化慢刷功能
|
||||
void _display(const uint8_t *d){ drv_dispWriter([&](int n)->uint8_t{return d[n];}); }
|
||||
virtual void drv_dispWriter(std::function<uint8_t(int)>)=0; //按照显示函数刷新
|
||||
void drv_color(uint8_t c){ drv_dispWriter([=](int)->uint8_t{return c;}); } //单色刷新
|
||||
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)>,uint8_t m=3)=0; //按照显示函数刷新
|
||||
void drv_color(uint8_t c,uint8_t m=3){ drv_dispWriter([=](int)->uint8_t{return c;},m); } //单色刷新
|
||||
virtual void drv_sleep() =0; //开始屏幕睡眠
|
||||
virtual int drv_width() const=0; //返回显示区域宽度, 即使旋转了也不能影响此函数输出
|
||||
virtual int drv_height()const=0; //返回显示区域高度, 即使旋转了也不能影响此函数输出
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
//#define _DEFINA_SD_CS_PIN 0
|
||||
|
||||
// * for NodeMcu ctg stack LCF board
|
||||
#define WHITE_GAP 8
|
||||
#define WHITE_GAP 2
|
||||
|
||||
#ifdef ESP8266
|
||||
#define DISPLAY_TYPE_ST7789_240320 //2.0寸的ST7789 IPS TFT模块
|
||||
|
||||
@@ -40,7 +40,9 @@ void drv::drv_init(){
|
||||
void drv::drv_fullpart(bool 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){//stage 1
|
||||
if(lastRefresh) drv_dispWriter(f,2);
|
||||
uint16_t dat[8];
|
||||
unsigned short xbits=(drv_width()+7)/8;
|
||||
if(partMode==0){
|
||||
@@ -79,7 +81,13 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
|
||||
}
|
||||
}
|
||||
}
|
||||
yield();
|
||||
}
|
||||
lastRefresh=millis();
|
||||
}
|
||||
if(m&2){//stage 2
|
||||
uint32_t ms=millis()-lastRefresh;
|
||||
if(ms<150) DelayMs(150-ms);
|
||||
lastRefresh=0;
|
||||
}
|
||||
}
|
||||
void drv::drv_sleep() {}
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
int drv_ID() const { return MEPD_DEBUG_DISPLAY; }
|
||||
void drv_init(); //初始化屏幕
|
||||
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() ; //开始屏幕睡眠
|
||||
int drv_width() const { return ips.width()-2*WHITE_GAP; } //返回显示区域宽度
|
||||
int drv_height() const{ return ips.height()-2*WHITE_GAP; } //返回显示区域高度
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
//另外, 在提交新版本之前, 不要忘记在github上创建release, 否则Arduino IDE会读不到
|
||||
#define READGUY_V_MAJOR 1
|
||||
#define READGUY_V_MINOR 3
|
||||
#define READGUY_V_PATCH 0
|
||||
#define READGUY_V_PATCH 1
|
||||
#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.1"
|
||||
|
||||
#ifdef ESP8266
|
||||
#define _READGUY_PLATFORM "ESP8266"
|
||||
|
||||
@@ -191,7 +191,7 @@ bool ReadguyDriver::server_loop(){ //此时等待网页操作完成响应...
|
||||
}
|
||||
if(refFlag!=127) {
|
||||
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->_display((const uint8_t*)getBuffer());
|
||||
}
|
||||
@@ -311,13 +311,14 @@ void ReadguyDriver::handleInitPost(){
|
||||
setEpdDriver(); //尝试初始化屏幕
|
||||
Serial.println(F("[Guy] Init details..."));
|
||||
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(); //初始化按钮..
|
||||
//} //尝试初始化按键, 调用后, 若SD卡初始化成功, READGUY_sd_ok的值会变成1
|
||||
drawRect((width()>>1)-46 ,(height()>>1)-14,20,28,0);
|
||||
drawRect((width()>>1)-46+24,(height()>>1)-14,20,28,0);
|
||||
drawRect((width()>>1)-46+48,(height()>>1)-14,20,28,0);
|
||||
drawRect((width()>>1)-46+72,(height()>>1)-14,20,28,0);
|
||||
drawRect((guy_dev->drv_width()>>1)-46 ,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||
drawRect((guy_dev->drv_width()>>1)-46+24,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||
drawRect((guy_dev->drv_width()>>1)-46+48,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||
drawRect((guy_dev->drv_width()>>1)-46+72,(guy_dev->drv_height()>>1)-14,20,28,0);
|
||||
spibz++;
|
||||
guy_dev->drv_fullpart(1);
|
||||
guy_dev->_display((const uint8_t*)getBuffer());
|
||||
|
||||
@@ -180,11 +180,10 @@ void ReadguyDriver::setEpdDriver(bool initepd/* ,int g_width,int g_height */){
|
||||
//else guy_width = guy_dev->drv_width(); //宽度必须是8的倍数, 但这个可以由GFX自动计算
|
||||
//if(g_height) guy_height = g_height;
|
||||
//else guy_height = guy_dev->drv_height();
|
||||
Serial.println(F("[Guy EPD] EPD init OK"));
|
||||
//以下依赖于你的图形驱动
|
||||
setColorDepth(1); //单色模式
|
||||
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的特性, 如果以前有画布会自动重新生成新画布
|
||||
//此外, 即使画布宽度不是8的倍数(如2.13寸单色),也支持自动补全8的倍数 ( 250x122 => 250x128 )
|
||||
//为了保证图片显示功能的正常使用, 高度也必须是8的倍数.
|
||||
@@ -370,32 +369,41 @@ void ReadguyDriver::setBright(int d){
|
||||
digitalWrite(READGUY_bl_pin,d?HIGH:LOW);
|
||||
}
|
||||
}
|
||||
void ReadguyDriver::display(bool part){
|
||||
void ReadguyDriver::display(uint8_t part){
|
||||
//真的是我c++的盲区了啊....搜索了半天才找到可以这么玩的
|
||||
//......可惜'dynamic_cast' not permitted with -fno-rtti
|
||||
// static bool _part = 0; 记忆上次到底是full还是part, 注意启动时默认为full
|
||||
if(READGUY_cali==127){
|
||||
//in_press(); //暂停, 然后读取按键状态 spibz
|
||||
guy_dev->drv_fullpart(part);
|
||||
guy_dev->_display((const uint8_t*)getBuffer());
|
||||
guy_dev->drv_fullpart(part&1);
|
||||
guy_dev->_display((const uint8_t*)getBuffer(),((part>>1)?part>>1:3));
|
||||
//in_release(); //恢复
|
||||
}
|
||||
}
|
||||
void ReadguyDriver::display(std::function<uint8_t(int)> f, bool part){
|
||||
void ReadguyDriver::display(const uint8_t *buf, uint8_t part){
|
||||
if(READGUY_cali==127){
|
||||
//in_press(); //暂停, 然后读取按键状态 spibz
|
||||
guy_dev->drv_fullpart(part);
|
||||
guy_dev->drv_dispWriter(f);
|
||||
guy_dev->drv_fullpart(part&1);
|
||||
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(); //恢复
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
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){
|
||||
if(READGUY_cali==127 && guy_dev->drv_supportGreyscaling()) guy_dev->drv_setDepth(d);
|
||||
|
||||
@@ -132,6 +132,13 @@
|
||||
#define READGUY_buttons (config_data[21]) //按钮个数, 0-3都有可能
|
||||
#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 基础类
|
||||
public:
|
||||
#ifdef READGUY_ESP_ENABLE_WIFI
|
||||
@@ -155,7 +162,9 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
||||
/// @brief 返回显示亮度
|
||||
int getBright() const { return currentBright; }
|
||||
/// @brief 刷新显示到屏幕上
|
||||
void display(bool part = true);
|
||||
void display(uint8_t part = READGUY_FAST);
|
||||
/// @brief 刷新显示到屏幕上
|
||||
void display(const uint8_t *buf, uint8_t part = READGUY_FAST);
|
||||
/** @brief 刷新显示到屏幕上, 可以自定义读取指定位置像素的函数
|
||||
* @param f 自定义的函数. 此函数将在读取像素并输出到墨水屏时被调用.
|
||||
* 每次调用需要返回 "参数对应位置" 的8个像素的颜色信息(凑成一字节). 其中左侧应在高位,右侧应在低位.
|
||||
@@ -170,7 +179,7 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
||||
* @endcode
|
||||
* 该函数会将参数从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 = READGUY_FAST);
|
||||
/// @brief 显示图片, 使用抖动算法. 可以用省内存的方法显示, 可以缩放到指定的宽度和高度
|
||||
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);
|
||||
@@ -368,14 +377,16 @@ class ReadguyDriver: public LGFX_Sprite{ // readguy 基础类
|
||||
//constexpr int memHeight () const { return guy_height ; } //返回显存高度(不是画幅高度),不会随着画布旋转改变
|
||||
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 width () const { return READGUY_cali==127?((getRotation()&1)?drvHeight():drvWidth()):0; }
|
||||
int height() const { return READGUY_cali==127?((getRotation()&1)?drvWidth():drvHeight()):0; }
|
||||
int width () const { return (getRotation()&1)?drvHeight():drvWidth(); }
|
||||
int height() const { return (getRotation()&1)?drvWidth():drvHeight(); }
|
||||
// private:
|
||||
void implBeginTransfer() { guy_dev->BeginTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!
|
||||
void implEndTransfer() { guy_dev->EndTransfer(); } //此函数用于开启SPI传输, 只能在自定义刷屏函数中使用!!
|
||||
/// @brief 分阶段显示图片, 使用抖动算法. 更加的省内存.目前函数
|
||||
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.
|
||||
Copyright (C) 2023 FriendshipEnder. */
|
||||
Reference in New Issue
Block a user