update to 1.3.1 ver

This commit is contained in:
fsender
2023-11-07 16:41:37 +08:00
parent a8b2540468
commit 85a785eabd
31 changed files with 272 additions and 128 deletions

View File

@@ -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. 增加了真.保姆级的教程 (详细到注释比代码多很多倍)

View File

@@ -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主哦~

View File

@@ -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); // 慢速刷新.
//想知道更多内容, 欢迎移步到其他示例.
}

View File

@@ -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表示全屏慢刷.

View File

@@ -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); // 慢速刷新.
//想知道更多内容, 欢迎移步到其他示例.
}

View File

@@ -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; //在此直接设置文件路径和文件名.

View 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",

View File

@@ -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.

View File

@@ -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时无法唤醒

View File

@@ -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; }; //返回显示区域高度

View File

@@ -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){ //无法唤醒

View File

@@ -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; }; //返回显示区域高度

View File

@@ -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 无法唤醒

View File

@@ -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; }; //返回缓存的数据宽度

View File

@@ -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() { //开始屏幕睡眠

View File

@@ -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; }; //返回显示区域高度

View File

@@ -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){

View File

@@ -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; }; //返回显示区域高度

View File

@@ -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);

View File

@@ -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; }; //返回显示区域高度

View File

@@ -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);
}

View File

@@ -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; }; //返回显示区域高度

View File

@@ -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. */

View File

@@ -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; //返回显示区域高度, 即使旋转了也不能影响此函数输出

View File

@@ -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模块

View File

@@ -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() {}

View File

@@ -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; } //返回显示区域高度

View File

@@ -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"

View File

@@ -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());

View File

@@ -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);

View File

@@ -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. */