v1.0.2; change file structure

This commit is contained in:
fsender
2023-09-24 16:59:01 +08:00
parent 5f91e9a9a5
commit 765c433e53
59 changed files with 9077 additions and 632 deletions

View File

@@ -1,3 +1,27 @@
# 敬请期待: Coming soon:
1. -可-以-配-网-了- -也-可-以-在-线-更-新-固-件-了-.- -注-意-在-2-M-B- -f-l-a-s-h-的-项-目-上-是-无-法-通-过-在-线-更-新-固-件-的-. 现在还需要你通过示例来进行配网!
### Release 1.0.2 - 2023/09/24
1. 进行了ESP32C3, ESP32S3和ESP32S2的功能测试.
2. 修复了一些bug, 包括可能会让一部分内存被两个任务连续释放导致ESP32触发assert的问题.
3. 更新了一些示例.
### Release 1.0.1 - 2023/09/23
1. 更改文件结构 (Git:我谢谢你). 现在可以像arduino库一样使用readguy了.
2. 优化platformio.ini的描述, 现在对新人开发者来说结构更清晰了.
3. 合并了 2.66英寸(Vusion价签屏) 和2.13英寸B型(红黑白三色屏和部分价签屏) 的驱动程序.
4. 现在支持使用arduino IDE进行项目开发.
5. 修复了若干bug
# Release 1.0.0 - 2023/09/18
可以通过WiFi进行配置显示屏和SD卡设置. 目前支持 1.54, 2.13, 2.66, 2.9, 3.7, 4.2 英寸的10种屏幕

116
README.md
View File

@@ -1,26 +1,34 @@
# readguy 自由的墨水屏阅读器驱动库
版本1.0正式发布欢迎分享、star和fork~
<img src="extra/artset/readguy_theme3.png" width="30%" height="auto">
**版本1.0正式发布欢迎分享、star和fork~** 上面的图是项目看板娘, 盖. 可爱的盖姐在等你哟~
欢迎克隆, 项目交流QQ群: 926824162 (萌新可以进来问问题的哟), 项目的 Bilibili 主页:
依赖的库: [LovyanGFX](https://github.com/lovyan03/LovyanGFX)
注意, 有问题一定要先加群问, 先不要提issue, 提了小影 *(也就是作者FriendshipEnder)* 也不会看的.
依赖的环境: Arduino-ESP8266 或者 Arduino-ESP32.
**依赖的库: [LovyanGFX](https://github.com/lovyan03/LovyanGFX)**
*依赖的环境: Arduino-ESP8266 或者 Arduino-ESP32.*
## 在**所有**受支持屏幕上都显示**16级灰度**内容!
### 目前支持ESP芯片平台、多种屏幕型号、13个按钮操控、SD卡、前置光亮度控制
### 一次编译即可使程序兼容多种屏幕!
### 固件在同芯片平台下完全兼容不同硬件设计!
<img src="extra/artset/readguy_girl.png" width="25%" height="auto">
### 可以在内存极少的情况下以抖动方式或者16级灰度方式渲染主流格式图片
<img src="extra/artset/view.jpg" width="auto" height="auto">
### *由于内存过低ESP8266上暂不支持PNG格式显示。*
#### 目前支持ESP芯片平台、多种屏幕型号、13个按钮操控、SD卡、前置光亮度控制
### 可以使用wifi配网来配置硬件信息。
#### 固件在同芯片平台下完全兼容不同硬件设计!
#### 可以在内存极少的情况下以抖动方式或者16级灰度方式渲染主流格式图片
#### *由于内存过低ESP8266上暂不支持PNG格式显示。*
#### 可以使用wifi配网来配置硬件信息。
----
@@ -32,6 +40,20 @@ Supported chips: esp8266/esp32/esp32s3/esp32s2/esp32c3
Supported displays: 1.54-inch, 2.13-inch, 2.66-inch, 2.9-inch, 4.2-inch.
| # |屏幕名称 | 驱动 | 分辨率 | 灰度 |连续灰度刷新|慢刷时间|快刷时间|
|:-:|:----------------:|:-------:|:-----:|:----:|:---------:|:----:|:-----:|
| 1 |1.54寸标准 |原创自研 |200*200| 16阶 | 不支持 | 1.3s | 0.35s |
| 2 |1.54寸Lilygo |原创自研 |200*200| 16阶 | 支持 | 2.3s | 0.6s |
| 3 |2.13寸汉朔价签 |原创自研 |122*250| 16阶 | 不支持 | 1.6s | 0.31s |
| 4 |2.13寸三色 |原创自研 |104*212| 16阶 | 支持 | 2s | 0.2s |
| 5 |2.66寸Vusion价签 |和4号相同|152*296| 16阶 | 支持 | 2s | 0.2s |
| 6 |2.7寸佳显触摸屏 |和2号相同|176*264| 16阶 | 支持 | 2.3s | 0.6s |
| 7 |2.9寸A01 |和1号相同|128*296| 16阶 | 不支持 | 1.8s | 0.55s |
| 8 |2.9寸T94背光 |和2号相同|128*296| 16阶 | 支持 | 2.3s | 0.6s |
| 9 |3.7寸高dpi墨水屏 |原创自研 |280*480| 16阶 | 不支持 | 1.3s | 0.5s |
|10 |4.2寸HINK黑白价签 |原创自研 |400*300| 16阶 | 支持 | 1.72s | 0.38s |
|11 |4.2寸WF丝印 |原创自研 |400*300| 16阶 | 不支持 | 3.6s | 0.8s |
可以自己在代码中加入你想要的屏幕型号
You can add the screen model you want in the code.
@@ -76,7 +98,7 @@ Light-brightness-control is optional.
2. 连接此wifi之后访问192.168.4.1之后就可以对其中的初始设定项目更改。
3. 尽情使用
3. 根据网页内容设置引脚之后就可以尽情使用!
4. 单按键操作说明
@@ -126,6 +148,80 @@ Light-brightness-control is optional.
6. 设备最好都要支持littlefs来存放书籍文件
## ESP32 串口固件烧录方法:
1. 在压缩包内准备好以下三个文件:
如果压缩包内没有, 请浏览群文件内更大的压缩包, 其中应当右这些文件
```
bootloader.bin
partitions.bin
ota_data_initial.bin
firmware.bin
```
2. 打开烧录软件 flash_download_tool_3.9.2.exe 烧录选项: flash 80MHz, DIO模式
```
bootloader.bin 0x1000
partitions.bin 0x8000
ota_data_initial.bin 0xe000
firmware.bin 0x10000
```
3. 等待烧录完成
## 项目编译注意事项
文件结构更改, 现在它更像一个 "库文件夹" 而不是一个 "项目文件夹". 因此使用时请按照以下说明, 自己编写程序
### 对于使用platformIO的用户:
1. 新建一个`PlatformIO`项目, 克隆`readguy`并放置于`lib`文件夹(用户库文件夹), 并在lib文件夹下额外克隆[`LovyanGFX`](https://github.com/lovyan03/LovyanGFX)库.(`LovyanGFX`库也需要放到`lib`文件夹内), *详见下图**下**方红框*.
2. 将库的`platformio.ini`(位于项目的`extra/platformio/platformio.ini`)替换掉新建项目内的`platformio.ini`. 默认编译的是`ESP8266`平台. *其实这一步可有可无, 只是这里提供了一种编译一定能成功的示例*
3. 如果编译目标是`ESP32`, 则需要更改`platformio.ini`内的 `[default_envs]` (在`PlatformIO.ini`文件内有说明), 而且还需要额外增加一个`components`文件夹 *(文件结构直接看图吧)*.
4. 注意编译目标是`ESP32`时, 此文件内的默认的ESP32环境并非纯arduino, 而是`ESP-IDF arduino component`. *此处`platformio.ini`里的framework是`espidf,arduino`, 这说明正在使用`ESP-IDF arduino component`. 这样可玩性更高涅!*
**如果想要使用纯arduino环境, 需要更改platformio.ini, 并将framework更改为`arduino`. 此时可以跳过 5~6 步骤**.
5. 编译目标是`ESP32`时, 需要单独安装[`LittleFS`](https://github.com/joltwallet/esp_littlefs)库来实现相关功能. 在项目内新建文件夹`components`, 在`components`文件夹内放入刚刚克隆的`LittleFS`库. *详见下图**上**方红框*. (使用纯arduino时跳过此步骤)
<img src="extra/artset/build_dir_structure.png" width="20%" height="auto">
6.`readguy``extra`文件夹内的`platformio`文件夹内所有文件都放在当前目录. 这些文件包含推荐的ESP32 sdkconfig, flash分区表等文件. 使用`pio run -t menuconfig`可以更改项目的menuconfig数据. (使用纯arduino时跳过此步骤)
7. 打开`examples`, 找到示例程序, 然后将源代码文件拷贝到项目的`src`文件夹内即可. *可以根据需要自己编写程序*.(***这不是废话??! \<憨色声线\>***)
8. 爽快的编译上传吧! 祝你 `0 error(s), 0 warning(s)`,加油~
### 对于使用 arduinoIDE 的用户:
1. 克隆项目之后, **首先你刚克隆完可能文件名是readguy-main.zip, 你需要把克隆好的文件重命名为readguy.zip** 再通过Arduino IDE添加到库, 或者解压拷贝到arduino IDE的libraries(arduino IDE的默认第三方库位置是C:\\Users\\$你的用户名$\\OneDrive\\documents\\Arduino\\libraries)文件夹内.
2. 现在打开arduino IDE, 找到examples, 选择需要的示例进行运行.
3. 打开库管理器, 找到[`LovyanGFX`](https://github.com/lovyan03/LovyanGFX)库并安装. 安装不了的用上述的1~2步骤克隆`LovyanGFX`并安装到`arduino IDE `内.
4. 爽快的编译上传吧! 祝你 `0 error(s), 0 warning(s)`,加油~
### 如何自定义功能
此库可以选择将一些功能关闭来减少flash的消耗.
其中的WiFi功能, 其实是可以禁掉的. 只要你提前配置成功, 那么就可以摆脱WiFi配网配引脚功能.
使用方法: 打开文件[guy_driver_config.h](src/guy_driver_config.h), 随后便根据注释来选择性的开启或关闭一些系统功能.
**不推荐的做法!**: 其中有些屏幕用不到, 也可以通过`guy_epaper_config`来配置.
使用方法: 打开文件[guy_epaper_config.h](src/guy_epaper/guy_epaper_config.h), 随后便可以设置不加载哪些屏幕的驱动程序.
此操作可以节约flash和RAM消耗, **但是实际上此操作并不能节省太多的flash.** 为确保编译获得的程序兼容性, 应尽量不要更改这个文件.
---
Copyright © 2022-2023 FriendshipEnder. All Rights reserved.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 KiB

View File

@@ -0,0 +1,90 @@
/******************** F r i e n d s h i p E n d e r ********************
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
*
* @file ex01_helloWorld.ino
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @version 1.0
* @date 2023-09-19
* @brief ReadGuy最基础的HelloWorld显示.
*
* @note 食用方法:
* 首先, 你需要有一颗ESP8266或者ESP32开发板, 一个墨水屏, 以及1~3个按钮.
* 如果有一张SD卡或者是屏幕前置光, 那就更好啦, 哈哈哈哈~
* 不过如果你有一个成品阅读器, 那你可以社牛的问一下硬件的作者(一般在oshwhub能找到)
* 问到哪个引脚对应哪个GPIO.
* 其实看原理图就可以知道哪个GPIO连接到哪个外设了.
*
* 其次, 你需要把开发板连接到电脑, 烧录这个程序. 克隆这个项目之后, 在platformIO里打开,
* 直接编译! 上传! (用arduino IDE的, 把lib文件夹内的三个子文件夹拷贝到你的arduino库
* 目录里, 一般在C:\Users\$username$\OneDrive\文档\Arduino\libraries)
* 不成功的和不会的, 建议再看一遍ESP8266和ESP32项目的构建流程.
*
* 烧录完成之后, 用手机连接设备的WiFi网络 "readguy". 密码12345678.
* 连接上之后访问 http://192.168.4.1 最后根据网页的提示操作就可以
* 你需要知道你的哪个引脚对应哪个GPIO, 才能使用这个库 (带来的不便请谅解nia~)
* 配置好了, 代码就开始正常运行了.
*
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
* Apache License, Version 2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//在这里包含程序需要用到的库函数
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
#include "readguy.h" //包含readguy_driver 基础驱动库
readguy_driver guy;//新建一个readguy对象, 用于显示驱动.
void drawLines(); //声明一个函数, 用于显示一些线条. 此函数在后面的程序中会用到的
void setup(){
// --------------------- 1 - 初始化和启动ReadGuy -------<
Serial.begin(115200); //初始化串口
//注意: 首次烧录此程序时, 这一步需要你打开手机联esp8266/32的 WiFi, 用于配网.
//名称是 readguy 密码 12345678. 连接后访问 192.168.4.1 再在网页中完成后续步骤
//后续启动就可以不用这个配置了
guy.init(); //初始化readguy_driver 基础驱动库.
//首次初始化完成之后, 以后再初始化就不需要配网了, 除非你抹除了芯片的flash
//完成之后会全屏刷新一次
guy.setFont(&FreeMonoBold9pt7b); //设置显示的字体
guy.setTextColor(0,1); //设置显示的颜色. 0代表黑色, 1代表白色
guy.drawString("Hello Readguy!",10,10); //用此函数将字符串显示到屏幕缓存内
//guy.setCursor(10,10); //设置显示的坐标
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
guy.display(true); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
//guy.display(false); // 慢速刷新.
//想知道更多内容, 欢迎移步到其他示例.
}
void loop(){
//什么也不做, 毕竟刷新墨水屏要消耗墨水屏的阳寿.
//盖姐说它们也是有阳寿的. 刷多了会老化.
}/* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -4,7 +4,7 @@
* QQ群: 926824162 ()
* : .
*
* @file oldDemo.cpp
* @file ex02_demo.ino
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @version 1.0
* @date 2023-09-19
@@ -49,7 +49,7 @@
//在这里包含程序需要用到的库函数
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
#include "guy_driver.h" //包含readguy_driver 基础驱动库
#include "readguy.h" //包含readguy_driver 基础驱动库
readguy_driver guy;//新建一个readguy对象, 用于显示驱动.
@@ -89,11 +89,8 @@ void setup(){
guy.drawString(guy.SDinside()?"SD card OK.":"No SD card!",10,50); //检查readguy是否插入了SD卡
#ifdef ESP8266
guy.drawString("with ESP8266.",10,70); //检查readguy运行在ESP8266上还是ESP32上.
#else
guy.drawString("with ESP32.",10,70);
#endif
guy.drawString("with " _READGUY_PLATFORM ".",10,70); //检查readguy运行在ESP8266上还是ESP32上.
guy.display(); //不带参数时, 默认使用快速刷新

View File

@@ -0,0 +1,80 @@
/******************** F r i e n d s h i p E n d e r ********************
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
*
* @file ex03_1_u8g2font.ino
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @version 1.0
* @date 2023-09-19
* @brief ReadGuy功能演示.
* 将根目录下的data文件夹 上传到LittleFS之后运行效果更佳
* 或者可以准备一张SD卡,并准备在卡的根目录下放置data文件夹内的文件.
* 用于演示BMP格式图片灰度显示.
*
* @note 食用方法:
* 首先, 你需要有一颗ESP8266或者ESP32开发板, 一个墨水屏, 以及1~3个按钮.
* 如果有一张SD卡或者是屏幕前置光, 那就更好啦, 哈哈哈哈~
* 不过如果你有一个成品阅读器, 那你可以社牛的问一下硬件的作者(一般在oshwhub能找到)
* 问到哪个引脚对应哪个GPIO.
* 其实看原理图就可以知道哪个GPIO连接到哪个外设了.
*
* 其次, 你需要把开发板连接到电脑, 烧录这个程序. 克隆这个项目之后, 在platformIO里打开,
* 直接编译! 上传! (用arduino IDE的, 把lib文件夹内的三个子文件夹拷贝到你的arduino库
* 目录里, 一般在C:\Users\$username$\OneDrive\文档\Arduino\libraries)
* 不成功的和不会的, 建议再看一遍ESP8266和ESP32项目的构建流程.
*
* 烧录完成之后, 用手机连接设备的WiFi网络 "readguy". 密码12345678.
* 连接上之后访问 http://192.168.4.1 最后根据网页的提示操作就可以
* 你需要知道你的哪个引脚对应哪个GPIO, 才能使用这个库 (带来的不便请谅解nia~)
*
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
* Apache License, Version 2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//在这里包含程序需要用到的库函数
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
#include "readguy.h" //包含readguy_driver 基础驱动库
#include "ctg_u8g2_wqy12.h" //中文字体库
readguy_driver guy;//新建一个readguy对象, 用于显示驱动.
extern const uint8_t ctg_wqy9pt_chinese1[]; //声明中文字体文件
const lgfx::U8g2font cn_font(ctg_wqy9pt_chinese1); //U8G2格式中文字体转化为LGFX格式字体
void setup(){
Serial.begin(115200); //初始化串口
guy.init();
guy.setFont(&cn_font);
guy.setCursor(10,10);
guy.print("中文");
guy.display();
}
void loop(){
}/* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
extra/artset/reward.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
extra/artset/test.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 578 KiB

After

Width:  |  Height:  |  Size: 578 KiB

View File

Before

Width:  |  Height:  |  Size: 600 KiB

After

Width:  |  Height:  |  Size: 600 KiB

BIN
extra/artset/view.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

View File

@@ -1,18 +0,0 @@
/**
* @file main.cpp
* @author ex01_helloWorld
* @brief 基础的实例. 同时注入了少许功能性驱动代码.
* http://www.lilygo.cn/prod_view.aspx?TypeId=50036&Id=1318
* 项目基于 TTGO T-block Ep-bk (带有背光功能的ESP32电子墨水屏模块)
*
* 注意屏幕所用的 EPD_RESET 其实是接在 GPIO38 上面, 手册写的 GPIO34 是错误的
* GPIO38 为 SENSOR_CAPN 引脚(可能是供内部使用),
* 在标准的 ESP32-WROOM 和 WROVER 模组上未引出此 GPIO.
* 可能影响一部分功能的正常使用. 不过无伤大雅
*
* @version 0.1
* @date 2022-11-23
*
* @copyright Copyright (c) 2022
*
*/

View File

@@ -1,143 +0,0 @@
/******************** F r i e n d s h i p E n d e r ********************
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
*
* @file oldDemo/main.cpp
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @version 1.0
* @date 2023-09-19
* @brief 旧版的功能演示.
* 将根目录下的data文件夹 上传到LittleFS之后运行效果更佳
* 或者可以准备一张SD卡,并准备在卡的根目录下放置data文件夹内的文件.
* 用于演示BMP格式图片灰度显示.
*
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
* Apache License, Version 2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <Arduino.h>
#include "guy_driver.h"
const char HelloArduino[] = "Hello Arduino!";
const char HelloEpaper[] = "Hello E-Paper!";
readguy_driver guy;
void helloWorld(int i,int j)
{
bool full=1;
if(i>=1000){
i-=1000;
full=0;
}
Serial.printf("[%lu] helloWorld: %d, %d\n",millis(),i,j);
guy.setFont(&FreeMonoBold9pt7b);
guy.setTextColor(0,1);
//display.fillScreen(GxEPD_WHITE);
guy.setCursor(i,j);
guy.print("Hello");
if(!full) guy.print("Full");
//guy.g().drawString(HelloWorld,i,j);
guy.display(full); // full update
Serial.printf("[%lu] helloWorld done\n",millis());
}
//TaskHandle_t press2reset_h=nullptr;
void press2reset_f(void *pv){
pinMode(36,INPUT_PULLUP);
for(;;){
if(!digitalRead(36)) ESP.restart();
delay(10);
}
}
void setup()
{
Serial.begin(115200);
Serial.println("setup");
//xTaskCreate(press2reset_f,"press2reset",1024,nullptr,1,&press2reset_h);
guy.init();
//pinMode(32,INPUT);
delay(100);
// first update should be full refresh
helloWorld(10,10);
helloWorld(10,30);
LGFX_Sprite sp(&guy);
sp.createFromBmpFile(guy.guyFS(),"/test.bmp");
Serial.printf("sp.w: %d, h: %d, res: %d.\n",sp.width(),sp.height(),ESP.getFreeHeap());
guy.drawImage(sp,30,10);
Serial.printf("drawn dithering bmp.\n");
delay(2500);
guy.draw16grey(sp,30,10);
Serial.printf("drawn.\n");
delay(5000);
guy.fillScreen(1);
helloWorld(1010,50);
helloWorld(10,70);
guy.fillScreen(1);
helloWorld(10,90);
guy.fillScreen(1);
helloWorld(10,140);
guy.fillScreen(1);
guy.drawChar(10,40,'a',true,false,2);
helloWorld(10,160);
helloWorld(1010,10);
helloWorld(1040,30);
guy.sleepEPD();
delay(2000);
helloWorld(1010,50);
helloWorld(20,70);
helloWorld(30,90);
guy.fillScreen(1);
helloWorld(40,110);
guy.setDepth(10); //设置颜色深度
helloWorld(38,126);
guy.setDepth(6);
helloWorld(36,142);
guy.setDepth(2);
helloWorld(38,158);
guy.setDepth(0); //恢复正常颜色深度
guy.fillScreen(1);
guy.display(0); //慢刷清屏
guy.setFont(&fonts::Font0);
for(int i=1;i<16;i++){
guy.setDepth(i); //灰度测试
guy.fillRect(10,i*10,20,10,0);
guy.setCursor(32,i*10);
guy.printf("Grey%d",i);
guy.display();
}
delay(3000);
guy.fillScreen(0);
guy.display();
guy.drawLine(0,0,guy.width(),guy.height(),1);
guy.display();
Serial.println("Reading touch sensor...");
//guy.ap_setup();
//guy.server_setup();
}
int bright=128;
void loop(){
//guy.server_loop();
delay(10);
if(bright%7==0){
Serial.printf("getBtn: %d\n",guy.getBtn());
}
if(bright==511) bright=0;
else bright++;
guy.setBright(bright>=256?511-bright:bright);
}

View File

@@ -0,0 +1,158 @@
;/******************** F r i e n d s h i p E n d e r ********************
; * 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
; * 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
; * 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
; * 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
; *
; * @file platformio.ini
; * @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
; * @version 1.0
; * @date 2023-09-18
; * @brief platformIO项目基础控制文件.
; *
; * @attention
; * Copyright (c) 2022-2023 FriendshipEnder
; *
; * Apache License, Version 2.0
; *
; * Licensed under the Apache License, Version 2.0 (the "License");
; * you may not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * http://www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an "AS IS" BASIS,
; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
;*/
;更改此处来实现ESP32和ESP8266两个版本的编译
;default_envs = esp32dev - ESP32环境
;default_envs = nodemcuv2 - esp8266环境
;default_envs = esp32s3_2m - ESP32S3 2MB PSRAM环境
;default_envs = esp32s3_8m - ESP32S3 8MB PSRAM环境
;default_envs = esp32c3_luatos - ESP32C3环境
;default_envs = esp32s2_dev - ESP32S2环境(我这边只有ESP32S2-Solo, 测试可以编译)
[platformio]
default_envs = nodemcuv2
;lib_deps =
;lovyan03/LovyanGFX
[env]
board_build.filesystem = littlefs ; SPIFFS mode
upload_speed = 921600 ; If using USB-JTAG, this selection is dummy
monitor_speed = 115200
build_flags =
-Wall
-Wextra
[env:esp32dev] ; 适用于ESP32的项目配置方案 注意是经典的ESP32...
platform = espressif32
board = esp32dev
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = dio
board_build.partitions = readguy_4MB.csv ; defined
framework = espidf, arduino
monitor_filters = esp32_exception_decoder
;build_type = debug
build_flags =
; -DCORE_DEBUG_LEVEL=4
[env:nodemcuv2] ; 适用于ESP8266的项目配置方案
platform = espressif8266
board = nodemcuv2
framework = arduino
board_build.f_cpu = 160000000L
board_build.ldscript = eagle.flash.4m2m.ld
monitor_filters = esp8266_exception_decoder
;build_type = debug
build_flags =
; -DNON32XFER_HANDLER ;不需要PROGMEM保留字也可以访问flash中的内容
; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;增大可用的HEAP内存
; -fstack-protector ;打开栈溢出保护器
[env:esp32s3_2m] ;适用于ESP32S3:2MB PSRAM 的项目配置方案. for ESP32S3 NxR2 series
; 圆屏, 适用于 flash 任意, PSRAM 2MB 的场景. 范例用的分区表是4M 的
; PSRAM 必须在menuconfig 里改
platform = espressif32
board = esp32-s3-devkitc-1
framework = espidf, arduino
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = dio ; Running flash config is QIO
board_build.partitions = readguy_4MB.csv ; defined
monitor_filters = esp32_exception_decoder
;build_type = debug
build_flags =
;-DARDUINO_USB_MODE=1
;-DARDUINO_USB_CDC_ON_BOOT=1 ; 是否需要使用USB串口调试如果需要调试则打开否则禁用
; 如果打开了这个选项但是不连接串口在有串口输出的地方会卡顿1秒左右
-DBOARD_HAS_PSRAM=1 ;是否使用PSRAM
-DPSRAM_SIZE_KB=2048
; -DARDUINO_RUNNING_CORE=1
; -DARDUINO_EVENT_RUNNING_CORE=1
; -Werror
;lib_deps_builtin =
; SPI
; littlefs
; SD_MMC
[env:esp32s3_8m] ;适用于ESP32S3:8MB PSRAM 的项目配置方案. for ESP32S3 NxR8 series
; 方屏, 适用于 flash 任意, PSRAM 8MB 的场景. 范例用的分区表是 8M 的
; PSRAM 必须在menuconfig 里改
platform = espressif32
board = lolin_s3
framework = espidf, arduino
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = dio
board_build.partitions = readguy_16MB.csv
monitor_filters = esp32_exception_decoder
build_flags =
;-DARDUINO_USB_MODE=1
;-DARDUINO_USB_CDC_ON_BOOT=1 ; 是否需要使用USB串口调试如果需要调试则打开否则禁用
; 如果打开了这个选项但是不连接串口在有串口输出的地方会卡顿1秒左右
-DBOARD_HAS_PSRAM=1 ;是否使用PSRAM
-DPSRAM_SIZE_KB=8192
; -DARDUINO_RUNNING_CORE=1
; -DARDUINO_EVENT_RUNNING_CORE=1
;lib_deps_builtin =
; SPI
; littlefs
; SD_MMC
[env:esp32c3_luatos] ;适用于ESP32C3 的项目配置方案.
platform = espressif32 ;注意在使用不带串口芯片的ESP32C3时, 尽量不要使用引脚18和19.
board = esp32-c3-devkitm-1 ;那俩是连接的板载USB串口 (USB-CDC, 可以下载程序或是当免驱串口)
framework = espidf, arduino ;合宙你真该死啊出这种没串口芯片的ESP32C3 甚至旧版本arduino无法编程!
board_build.f_cpu = 160000000L ;芯片速率默认160MHz, 不支持高频240MHz.
;board_build.flash_size=2MB ;2MB的芯片就选readguy_2MB_noOTA.csv
board_build.flash_size=4MB ;根据你自己的改, 不得小于4MB. 2MB的芯片就选readguy_2MB_noOTA.csv
board_build.f_flash = 80000000L
board_build.flash_mode = dio
board_build.partitions = readguy_4MB.csv ; 2MB的芯片就选readguy_2MB_noOTA.csv
build_flags =
-DCORE_DEBUG_LEVEL=1 ; None 0, Error 1, Warn 2, Info 3, Debug 4, Verbose 5
[env:esp32s2_dev] ;适用于ESP32S2 的项目配置方案.
platform = espressif32
board = nodemcu-32s2
framework = espidf, arduino
board_build.f_cpu = 240000000L
board_build.flash_size=4MB ;根据你自己的改, 不得小于4MB
board_build.f_flash = 80000000L
board_build.flash_mode = dio
board_build.partitions = readguy_4MB.csv ; defined
build_flags =
-DCORE_DEBUG_LEVEL=1 ; None 0, Error 1, Warn 2, Info 3, Debug 4, Verbose 5

View File

@@ -0,0 +1,7 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x640000,
app1, app, ota_1, 0x650000,0x640000,
spiffs, data, spiffs, 0xc90000,0x360000,
coredump, data, coredump,0xFF0000,0x10000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x640000
5 app1 app ota_1 0x650000 0x640000
6 spiffs data spiffs 0xc90000 0x360000
7 coredump data coredump 0xFF0000 0x10000

View File

@@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
spiffs, data, spiffs, 0x150000,0xA0000,
coredump, data, coredump,0x1F0000,0x10000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x140000
5 spiffs data spiffs 0x150000 0xA0000
6 coredump data coredump 0x1F0000 0x10000

View File

@@ -0,0 +1,7 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, 0x150000,0x140000,
spiffs, data, spiffs, 0x290000,0x160000,
coredump, data, coredump,0x3F0000,0x10000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x140000
5 app1 app ota_1 0x150000 0x140000
6 spiffs data spiffs 0x290000 0x160000
7 coredump data coredump 0x3F0000 0x10000

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

41
extra/tools/file2bin.c Normal file
View File

@@ -0,0 +1,41 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
int main(int argc,char ** argv)
{
FILE *fp=NULL;
FILE *fw=NULL;
if(argc>1){
fp=fopen(argv[1],"rb");
fw=fopen("result.h","wb");
}
if(fp==NULL) return 1;
printf("\n//File name : ");
puts(argv[1]);
printf("\nconst uint8_t val [] PROGMEM = {\n ");
fprintf(fw,"#ifndef _RESULT_H_\n");
fprintf(fw,"#define _RESULT_H_\n");
fprintf(fw,"\nconst uint8_t val [] = {\n ");
int hadread=0;
while(1){
//if(feof(fp)) break;
int f_justread=fgetc(fp);
if(f_justread==EOF) break;
fprintf(fw,"0x%02x,",f_justread);
hadread++;
if((hadread & 1023) ==0){
printf(" // %d KB converted.\n",(hadread>>10));
fprintf(fw,"// %d KB converted.",(hadread>>10));
}
if((hadread & 31) ==0){
fprintf(fw,"\n ");
}
}
fprintf(fw,"\n};\n//Total File size is %d bytes.\n",hadread);
fprintf(fw,"\n#endif\n");
fclose(fp);
fclose(fw);
printf("\n};\nTotal File size is %d bytes.\n",hadread);
return 0;
}

BIN
extra/tools/file2bin.exe Normal file

Binary file not shown.

View File

@@ -1,222 +0,0 @@
/******************** F r i e n d s h i p E n d e r ********************
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
* @file guy_213b.cpp
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @brief 2.13英寸B型墨水屏 驱动库函数
* @version 1.0
* @date 2023-09-21
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
* Apache License, Version 2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include "guy_213b.h"
#ifdef READGUY_DEV_213B
//#define MEPD_DEBUG_WAVE
namespace guydev_213B{
//以下代码均为我 FriendshipEnder 原创, 呵呵哒~~
static const PROGMEM unsigned char lutSlow_vcom0[] ={
0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
0x60, 0x28, 0x28, 0x00, 0x00, 0x01,
0x00, 0x0c, 0x00, 0x00, 0x00, 0x01,
0x00, 0x28, 0x00, 0x00, 0x00, 0x01
};
static const PROGMEM unsigned char lutSlow_w_w[] ={
0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
0x40, 0x0c, 0x00, 0x00, 0x00, 0x01,
0x80, 0x20, 0x00, 0x00, 0x00, 0x01
};
static const PROGMEM unsigned char lutSlow_b_w[] ={
0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
0x40, 0x0c, 0x00, 0x00, 0x00, 0x02,
0x80, 0x28, 0x00, 0x00, 0x00, 0x01
};
static const PROGMEM unsigned char lutSlow_w_b[] ={
0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
0x80, 0x0c, 0x00, 0x00, 0x00, 0x01,
0x50, 0x28, 0x00, 0x00, 0x00, 0x01
};
static const PROGMEM unsigned char lutSlow_b_b[] ={
0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
0x80, 0x0c, 0x00, 0x00, 0x00, 0x01,
0x50, 0x28, 0x00, 0x00, 0x00, 0x01
};
//partial screen update LUT
//#define Fx19 0x19 // original value is 25 (phase length)
#define Fx19 40 // new value for test is 40 (phase length) //Me:60
static const PROGMEM unsigned char lutFast_vcomDC[] ={
0x00, Fx19, 0x01, 0x00, 0x00, 0x01 };
static const PROGMEM unsigned char lutFast_w_w[] ={
0x00, Fx19, 0x01, 0x00, 0x00, 0x01 };
static const PROGMEM unsigned char lutFast_b_w[] ={
0x80, 0x1c, 0x01, 0x00, 0x00, 0x01 };
static const PROGMEM unsigned char lutFast_w_b[] ={
0x40, Fx19, 0x01, 0x00, 0x00, 0x01 };
static const PROGMEM unsigned char lutFast_b_b[] ={
0x00, Fx19, 0x01, 0x00, 0x00, 0x01 };
drv::drv(){
guy_lutArray[0] = lutSlow_vcom0;
guy_lutArray[1] = lutSlow_w_w;
guy_lutArray[2] = lutSlow_b_w;
guy_lutArray[3] = lutSlow_w_b;
guy_lutArray[4] = lutSlow_b_b;
guy_lutArray[5] = lutFast_vcomDC;
guy_lutArray[6] = lutFast_w_w;
guy_lutArray[7] = lutFast_b_w;
guy_lutArray[8] = lutFast_w_b;
guy_lutArray[9] = lutFast_b_b;
}
void drv::InitDisplay(){
guy_epdCmd(0x01);
guy_epdParam(0x03);
guy_epdParam(0x00);
guy_epdParam(0x2b);
guy_epdParam(0x2b);
guy_epdParam(0x03);
guy_epdCmd(0x06);
guy_epdParam(0x17);
guy_epdParam(0x17);
guy_epdParam(0x17);
guy_epdCmd(0x00);
guy_epdParam(0xbf);
guy_epdParam(0x0d);
guy_epdCmd(0x30);
guy_epdParam(0x3a);
guy_epdCmd(0x61);
guy_epdParam(0x68);
guy_epdParam(0x00);
guy_epdParam(0xd4);
guy_epdCmd(0x82);
guy_epdParam(0x08);
guy_epdCmd(0x50);
}
void drv::epd_Init(uint8_t lastCmd){
if(!epd_PowerOn) Reset(); //存疑的选项
guy_epdCmd(0x91);
guy_epdCmd(0x90);
guy_epdParam(0x00);
guy_epdParam(0x67);
guy_epdParam(0x00);
guy_epdParam(0x00);
guy_epdParam(0x00);
guy_epdParam(0xd3);
guy_epdParam(0x01);
guy_epdCmd(lastCmd);
}
void drv::SendLuts(bool part){
if(!epd_PowerOn) part=false; //形参嘛
for(uint8_t i=0;i<5;i++){
guy_epdCmd(i+0x20);
for(int j=0;j<(i==0?44:42);j++){
if(part){
if(j==1) guy_epdParam(i==2?pgm_read_byte(lutFast_b_w+1):iLutFx19);
else guy_epdParam(j<6?pgm_read_byte(guy_lutArray[i+5]+j):0);
}
else {
guy_epdParam(j<24?pgm_read_byte(guy_lutArray[i]+j):0x00);
}
}
}
if(!epd_PowerOn){
guy_epdCmd(0x04);
epd_PowerOn=1;
}
}
void drv::post(){
guy_epdCmd(0x92); //数据发送完毕了
if(epdFull) { //慢刷
InitDisplay();
guy_epdParam(0x97);
SendLuts();
//write lut here...
guy_epdCmd(0x12);
EndTransfer();
guy_epdBusy(-2800); //慢刷等待
}
else{ //快刷
InitDisplay();
guy_epdParam(0x17);
SendLuts(1); //快刷
epd_Init();
guy_epdCmd(0x12);
EndTransfer();
guy_epdBusy(-700);
}
//guy_epdCmd(0x92); //end refreshing
}
void drv::drv_init(){ //初始化屏幕
epdFull = 1;
drv_color(0xff);
}
void drv::drv_fullpart(bool part){ //初始化慢刷功能
//if(part==epdFull) return;
if(!part) iLutFx19=Fx19; //恢复默认的灰度模式
epdFull = !part;
//epd_Init();
}
/* for (int j = 0; j < GUY_D_HEIGHT*GUY_D_WIDTH/8; j++)
guy_epdParam(d[j]); //按照给定的RAM写入数据 */
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
BeginTransfer();
epd_Init();
//for (int j = 0; j < GUY_D_HEIGHT*GUY_D_WIDTH/8; j++)
// guy_epdParam(c); //按照给定的RAM写入数据
for (int j = 0; j < GUY_D_HEIGHT*GUY_D_WIDTH/8; j++)
guy_epdParam(f(j)); //按照给定的RAM写入数据
post();
}
void drv::drv_sleep() { //开始屏幕睡眠
if(RST_PIN>=0){; //未定义RST_PIN时无法唤醒
BeginTransfer();
guy_epdCmd(0x02); //powerOff
guy_epdBusy(-250);
guy_epdCmd(0x07); //enter deep sleep
guy_epdParam(0xa5);
EndTransfer();
DelayMs(200);
epd_PowerOn=false;
epdFull=1;
iLutFx19=Fx19;
}
}
void drv::drv_setDepth(uint8_t i){ //设置显示颜色深度
static const uint8_t strength[14]={
2,4,6,8,10,12,15,18,21,24,28,32,37,42
};
if(i) iLutFx19 = i>=15?Fx19:strength[i-1];
else iLutFx19=Fx19;
epdFull=0;
}
}
#endif /* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */

View File

@@ -1,65 +0,0 @@
/******************** F r i e n d s h i p E n d e r ********************
* 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
* 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
* 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
* 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
* @file guy_213b.h
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @brief 2.13英寸B型墨水屏 驱动库函数 头文件
* @version 1.0
* @date 2023-09-21
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
* Apache License, Version 2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "../guy_epdbase.h"
#if (!defined(_GUY_EPD213B_H_FILE) && (defined(READGUY_DEV_213B)))
#define _GUY_EPD213B_H_FILE
namespace guydev_213B{
constexpr int GUY_D_WIDTH =104;
constexpr int GUY_D_HEIGHT =212;
class drv : public readguyEpdBase {
public:
drv();
int drv_ID() const { return READGUY_DEV_213B; }
void drv_init(); //初始化屏幕
void drv_fullpart(bool part); //切换慢刷/快刷功能
void drv_dispWriter(std::function<uint8_t(int)> f); //按照函数刷新
void drv_sleep() ; //开始屏幕睡眠
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
void drv_setDepth(uint8_t i); //设置显示颜色深度
int drv_supportGreyscaling() const { return 16; }
private:
uint8_t epdFull = 0; //是partical模式/快速刷新模式 0快刷, 1慢刷
uint8_t epd_PowerOn = 0; //是否上电
uint8_t iLutFx19 = 40;
void epd_Init(uint8_t lastCmd=0x13);
void InitDisplay(void);
void SendLuts(bool part = 0);
void post(void);
const uint8_t *guy_lutArray[10];
//uint16_t dat_combo = 0; //dc引脚状态 0 command, 1 data
// uint8_t _ed_lut_full[40];
// uint8_t _ed_lut_part[40];
};
}
#endif /* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */

View File

@@ -1,72 +0,0 @@
;/******************** F r i e n d s h i p E n d e r ********************
; * 本程序隶属于 Readguy 开源项目, 请尊重开源开发者, 也就是我FriendshipEnder.
; * 如果有条件请到 extra/artset/reward 中扫描打赏,否则请在 Bilibili 上支持我.
; * 项目交流QQ群: 926824162 (萌新可以进来问问题的哟)
; * 郑重声明: 未经授权还请不要商用本开源项目编译出的程序.
; *
; * @file platformio.ini
; * @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
; * @version 1.0
; * @date 2023-09-18
; * @brief platformIO项目基础控制文件.
; *
; * @attention
; * Copyright (c) 2022-2023 FriendshipEnder
; *
; * Apache License, Version 2.0
; *
; * Licensed under the Apache License, Version 2.0 (the "License");
; * you may not use this file except in compliance with the License.
; * You may obtain a copy of the License at
; *
; * http://www.apache.org/licenses/LICENSE-2.0
; *
; * Unless required by applicable law or agreed to in writing, software
; * distributed under the License is distributed on an "AS IS" BASIS,
; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; * See the License for the specific language governing permissions and
; * limitations under the License.
;*/
;更改此处来实现ESP32和ESP8266两个版本的编译
;default_envs = esp32dev - ESP32环境
;default_envs = nodemcuv2 - esp8266环境
[platformio]
default_envs = nodemcuv2
;lib_deps =
;lovyan03/LovyanGFX
[env:esp32dev]
platform = espressif32
board = esp32dev
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.filesystem = littlefs
framework = arduino
upload_speed = 1500000
monitor_speed = 115200
monitor_filters = esp32_exception_decoder
build_flags =
-Wall
; -DCORE_DEBUG_LEVEL=4
[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2
framework = arduino
upload_speed = 921600
monitor_speed = 115200
board_build.f_cpu = 160000000L
board_build.ldscript = eagle.flash.4m2m.ld
board_build.filesystem = littlefs
monitor_filters = esp8266_exception_decoder
;build_type = debug
build_flags =
-Wall
-Werror
; -DNON32XFER_HANDLER ;不需要PROGMEM保留字也可以访问flash中的内容
; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;增大可用的HEAP内存
; -fstack-protector ;打开栈溢出保护器

View File

@@ -62,8 +62,6 @@ SOFTWARE.
// initalize static counter
int guy_button::_nextID = 0;
guy_button::guy_button() {
//pin = UNDEFINED_PIN;
//id = _nextID++;
@@ -78,15 +76,16 @@ void guy_button::begin(uint8_t _pin, std_U8_function_U8 f, bool activeLow /* = t
get_state_cb = f;
pin = _pin;
state = get_state_cb(pin);
lk=0;
min_debounce =25; //去抖时间
long_press_ms =300; //长按持续时间+双击识别间隔最大时间
long_repeat_ms =150; //长按连按间隔时间
multibtn =0;
lk=0;
}
uint8_t guy_button::read() { //注意ticker不能在此触发
while(lk); //等待数据读完
int mi=millis();
while(lk) if(millis()-mi>GUYBTN_READ_TIMEOUT) return 0; //等待数据读完
lk=2;
unsigned long n = millis();
if(state == _pressedState && n - down_ms>= long_press_ms && long_clicked < n){
@@ -103,7 +102,8 @@ uint8_t guy_button::read() { //注意ticker不能在此触发
void guy_button::loop() {
if(get_state_cb==NULL || lk==255) return;
while(lk); //等待数据读完
int mi=millis();
while(lk) if(millis()-mi>GUYBTN_LOOP_TIMEOUT) return; //等待数据读完
lk=1;
unsigned long now = millis();
prev_state = state;

View File

@@ -76,11 +76,11 @@ SOFTWARE.
#define GUYBUTTON_double_click 2
#define GUYBUTTON_triple_click 3
#define GUYBUTTON_long_click 4
#define GUYBTN_READ_TIMEOUT 100
#define GUYBTN_LOOP_TIMEOUT 10
class guy_button{
protected:
static int _nextID;
uint16_t min_debounce ; //去抖时间
uint16_t long_press_ms ; //长按持续时间+双击识别间隔最大时间
uint16_t long_repeat_ms ; //长按连按间隔时间

View File

@@ -63,7 +63,7 @@
#define DYNAMIC_PIN_SETTINGS //使用静态的数据 !!!注意:注释此选项编写的程序是不支持跨平台运行的!!!
#define READGUY_ENABLE_WIFI //启用WIFI配网功能.必须先启用 #define DYNAMIC_PIN_SETTINGS
#define READGUY_USE_LITTLEFS 1 //取消注释以使用LittleFS,注释则用SPIFFS
#define BTN_LOOPTASK_STACK 768 //ESP32按键服务任务的栈空间大小
#define BTN_LOOPTASK_STACK 1024 //ESP32按键服务任务的栈空间大小
#define BTN_LOOPTASK_CORE_ID 0 //ESP32按键服务任务运行在哪个核心
#define BTN_LOOPTASK_PRIORITY 4 //ESP32按键服务任务的优先级
#define BTN_LOOPTASK_DELAY 10 //按键任务间隔多久调用一次,单位毫秒

View File

@@ -3,9 +3,9 @@
* extra/artset/reward , Bilibili .
* QQ群: 926824162 ()
* : .
* @file guy_266a.cpp
* @file guy_213b_266a.cpp
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @brief 2.66
* @brief 2.13B型墨水屏和 2.66
* @version 1.0
* @date 2023-09-21
@@ -28,10 +28,10 @@
*/
#include <stdlib.h>
#include "guy_266a.h"
#include "guy_213b_266a.h"
// #define MEPD_DEBUG_WAVE
#ifdef READGUY_DEV_266A
namespace guydev_266A{
namespace guydev_213B_266A{
static const PROGMEM unsigned char lutSlow_vcom0[] ={
0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
0x60, 0x28, 0x28, 0x00, 0x00, 0x01,
@@ -68,7 +68,7 @@ static const PROGMEM unsigned char lutSlow_b_b[] ={
static const PROGMEM unsigned char lutFast_[]={
0x00,0x18,0x5a,0xa5,0x24
};
drv::drv(){
drv_base::drv_base(){
guy_lutArray[0] = lutSlow_vcom0;
guy_lutArray[1] = lutSlow_w_w;
guy_lutArray[2] = lutSlow_b_w;
@@ -76,12 +76,12 @@ drv::drv(){
guy_lutArray[4] = lutSlow_b_b;
guy_lutArray[5] = lutFast_;
}
void drv::pre(){
void drv_base::pre(){
guy_epdCmd(0x91);
send_zoneInfo();
guy_epdCmd(0x13);
}
void drv::epd_init(){
void drv_base::epd_init(){
if(!Power_is_on) Reset();
guy_epdCmd(0x01);
guy_epdParam(0x03);
@@ -107,7 +107,7 @@ void drv::epd_init(){
guy_epdCmd(0x50);
guy_epdParam(0x17);
}
void drv::send_zoneInfo(){
void drv_base::send_zoneInfo(){
guy_epdCmd(0x90);
guy_epdParam(0x00);
guy_epdParam(0x97);
@@ -117,7 +117,7 @@ void drv::send_zoneInfo(){
guy_epdParam(0x27);
guy_epdParam(0x00);
}
void drv::SendLuts(bool part_lut){
void drv_base::SendLuts(bool part_lut){
if(!Power_is_on) part_lut=false; //形参嘛
for(uint8_t i=0;i<5;i++){
guy_epdCmd(i+0x20);
@@ -140,29 +140,29 @@ void drv::SendLuts(bool part_lut){
Power_is_on = 1;
}
}
void drv::drv_init(){
void drv_base::drv_init(){
part_mode=0;
drv_color(0xff);
}
void drv::drv_fullpart(bool part){ //切换慢刷/快刷功能
void drv_base::drv_fullpart(bool part){ //切换慢刷/快刷功能
if(!part) greyLut=15; //恢复默认的灰度模式
part_mode = part;
}
void drv::drv_setDepth(uint8_t i){
void drv_base::drv_setDepth(uint8_t i){
part_mode=1;
greyLut = i?(i>15?15:i):15;
BeginTransfer();
SendLuts(1);
EndTransfer();
}
void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
void drv_base::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
BeginTransfer();
pre();
//send pixel data -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
//Total 5624 data written.
//for(int i=0;i<GUY_D_WIDTH*GUY_D_HEIGHT/8;i++)
// guy_epdParam(c);
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
for (int i = 0; i < epdHeight*epdWidth/8; i++)
guy_epdParam(f(i)); //按照给定的RAM写入数据
guy_epdCmd(0x92);
@@ -200,7 +200,7 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
pre();
//send image data -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
//Total 5624 data written.
for (int i = 0; i < GUY_D_HEIGHT*GUY_D_WIDTH/8; i++)
for (int i = 0; i < epdHeight*epdWidth/8; i++)
guy_epdParam(f(i)); //按照给定的RAM写入数据
guy_epdCmd(0x92);
EndTransfer();
@@ -210,7 +210,7 @@ void drv::drv_dispWriter(std::function<uint8_t(int)> f){ //单色刷新
//guy_epdBusy(-20);
}
}
void drv::drv_sleep() { //开始屏幕睡眠
void drv_base::drv_sleep() { //开始屏幕睡眠
if(RST_PIN>=0) { //未定义RST_PIN时无法唤醒
part_mode = 0;
BeginTransfer();
@@ -223,7 +223,7 @@ void drv::drv_sleep() { //开始屏幕睡眠
}
}
void drv::drv_draw16grey_step(std::function<uint8_t(int)> f, int step){
void drv_base::drv_draw16grey_step(std::function<uint8_t(int)> f, int step){
if(_quality) return readguyEpdBase::drv_draw16grey_step(f,step);
if(step==1){
greyHQ=3;

View File

@@ -3,9 +3,9 @@
* extra/artset/reward , Bilibili .
* QQ群: 926824162 ()
* : .
* @file guy_266a.h
* @file guy_213b_266a.h
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @brief 2.66
* @brief 2.13B型墨水屏和 2.66
* @version 1.0
* @date 2023-09-21
@@ -28,26 +28,27 @@
*/
#include "../guy_epdbase.h"
#if (!defined(_GUY_EPD266A_H_FILE) && (defined(READGUY_DEV_266A)))
#define _GUY_EPD266A_H_FILE
#if (!defined(_GUY_EPD213B_266A_H_FILE) && \
(defined(READGUY_DEV_266A) || defined(READGUY_DEV_213B)))
#define _GUY_EPD213B_266A_H_FILE
namespace guydev_266A{
constexpr int GUY_D_WIDTH =152;
constexpr int GUY_D_HEIGHT =296;
class drv : public readguyEpdBase {
namespace guydev_213B_266A{
class drv_base : public readguyEpdBase {
public:
drv();
int drv_ID() const { return READGUY_DEV_266A; }
drv_base();
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_sleep() ; //开始屏幕睡眠
int drv_width() const { return GUY_D_WIDTH; }; //返回显示区域宽度
int drv_height() const{ return GUY_D_HEIGHT; }; //返回显示区域高度
int drv_width() const { return epdWidth; }; //返回显示区域宽度
int drv_height() const{ return epdHeight; }; //返回显示区域高度
void drv_setDepth(uint8_t i); //设置显示颜色深度
int drv_supportGreyscaling() const { return _quality?16:-16; }
void drv_draw16grey_step(std::function<uint8_t(int)> f, int step);
protected:
int epdWidth;
int epdHeight;
private:
void pre();
void epd_init();
@@ -59,6 +60,20 @@ private:
uint8_t greyHQ=4; // greyHQ==3 时 为高品质刷新灰度 否则为常规方式刷新灰度
const uint8_t *guy_lutArray[6];
};
#ifdef READGUY_DEV_213B
class dev213B : public drv_base {
public:
dev213B(){ epdWidth=104; epdHeight=212; }
int drv_ID() const { return READGUY_DEV_213B; }
};
#endif
#ifdef READGUY_DEV_266A
class dev266A : public drv_base {
public:
dev266A(){ epdWidth=152; epdHeight=296; }
int drv_ID() const { return READGUY_DEV_266A; }
};
#endif
}
#endif /* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */

View File

@@ -31,7 +31,7 @@
#define _GUY_E_PAPER_CONFIG_H_FILE
//#define MEPD_DEBUG_WAVE 16 //取消此行注释来监视SPI的通信数据 (用于debug), 可以查看主控和屏幕的通信数据
#define MEPD_DEBUG_WAITTIME //显示墨水屏的刷新时间, 单位是毫秒
//#define MEPD_DEBUG_WAITTIME //显示墨水屏的刷新时间, 单位是毫秒
#define FLOYD_STEINBERG_DITHERING //默认使用性能更好的floyd steinberg抖动算法, 取消注释则使用bayer图案抖动算法
// ***********************************************************************

View File

@@ -48,14 +48,18 @@ void readguyEpdBase::DelayMs(unsigned int delaytime) {
delay(delaytime);
}
void readguyEpdBase::BeginTransfer(){
if(spi_tr_press!=nullptr) spi_tr_press();
if(!in_trans && CS_PIN>=0) digitalWrite(CS_PIN, LOW);
if(!in_trans && CS_PIN>=0) {
digitalWrite(CS_PIN, LOW);
if(spi_tr_press!=nullptr) spi_tr_press();
}
in_trans++;
}
void readguyEpdBase::EndTransfer(){
if(in_trans) in_trans--;
if(!in_trans && CS_PIN>=0) digitalWrite(CS_PIN, HIGH);
if(spi_tr_release!=nullptr) spi_tr_release();
if(!in_trans && CS_PIN>=0) {
digitalWrite(CS_PIN, HIGH);
if(spi_tr_release!=nullptr) spi_tr_release();
}
}
void readguyEpdBase::SpiTransfer(unsigned char data) {
if(in_trans) {

View File

@@ -32,6 +32,7 @@
#include <Arduino.h>
#include <SPI.h>
#include <FS.h>
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include "guy_epaper_config.h"

View File

@@ -121,7 +121,11 @@ public:
{ // 设置总线控制。- SPI, I2C, I2S, FSMC, etc.
auto cfg = _bus_instance.config(); // 获取总线配置的结构。
#ifndef ESP8266
cfg.spi_host = VSPI_HOST; // 选择要使用的 SPI (VSPI_HOST or HSPI_HOST)
#ifdef CONFIG_IDF_TARGET_ESP32
cfg.spi_host = SPI3_HOST; // 选择要使用的 SPI (VSPI_HOST or HSPI_HOST)
#else
cfg.spi_host = SPI1_HOST; // 选择要使用的 SPI (VSPI_HOST or HSPI_HOST)
#endif
cfg.use_lock = true; // 使用锁时设置为 True
cfg.dma_channel = SPI_DMA_CH_AUTO; // Set the DMA channel (1 or 2. 0=disable) 设置要打开的 DMA 通道 (0=DMA关闭)
#endif

View File

@@ -32,9 +32,9 @@
#define READGUY_V_MAJOR 1
#define READGUY_V_MINOR 0
#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 "1.0.0"
#define READGUY_VERSION "1.0.2"
#ifdef ESP8266
#define _READGUY_PLATFORM "ESP8266"

View File

@@ -27,7 +27,7 @@
* limitations under the License.
*/
#include "guy_driver.h"
#include "readguy.h"
static const PROGMEM char NOT_SUPPORTED[] = "(不支持此屏幕)";
static const PROGMEM char header_html[] = "text/html";
@@ -65,7 +65,7 @@ void readguy_driver::server_setup(const serveFunc *serveFuncs, int funcs){
sv.on("/final", HTTP_POST, std::bind(&readguy_driver::handleFinalPost,this)); //此时验证已经正确
sv.on("/wifi", HTTP_POST, std::bind(&readguy_driver::handleWiFiPost ,this)); //此时验证已经正确
for(int i=0;i<funcs;i++){
sv.on(serveFuncs[i].event,serveFuncs[i].method,serveFuncs[i].func);
sv.on(serveFuncs[i].event,HTTPMethod(serveFuncs[i].method),serveFuncs[i].func);
}
FSBrowser_setup(); //set-up for fs-browser. 第三方库内容, 初始化后即可使用
/*sv.on("/favicon.ico", HTTP_GET, [&](){
@@ -134,7 +134,6 @@ void readguy_driver::handleInitPost(){
btnTask.detach();
#else
SD.end();//关闭SD卡
Serial.printf("sd_spi at: 0x%p; epd_spi at: 0x%p.\n",sd_spi,epd_spi);
if(sd_spi != epd_spi) { //共线时, 不要删除SD
delete sd_spi;
sd_spi=nullptr;
@@ -164,21 +163,25 @@ void readguy_driver::handleInitPost(){
}
else {
Serial.write('\n');
if(i==0) config_data[1] = 0; //有的html响应是没有的
if(i==0) READGUY_shareSpi = 0; //有的html响应是没有的.共享SPI默认值为true.
else if(i<12) config_data[i+1] = -1;//这12个引脚是不可以重复的, 如果有重复, config_data[0]设为0
}
}
//尝试初始化各个硬件, 可能失败, 然后显示一些东西
#ifdef ESP8266
config_data[10] = config_data[3];
config_data[11] = config_data[4];
#if (defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3))
if(config_data[3]==-1) config_data[3] = config_data[10];
else config_data[10] = config_data[3];
if(config_data[4]==-1) config_data[4] = config_data[11];
else config_data[11] = config_data[4];
READGUY_shareSpi = true;
#else
if(config_data[10] == config_data[3] && config_data[11] == config_data[4]) //检测到SPI共线
READGUY_shareSpi = true;
else if(READGUY_shareSpi){
config_data[10] = config_data[3];
config_data[11] = config_data[4];
if(config_data[3]==-1) config_data[3] = config_data[10];
else config_data[10] = config_data[3];
if(config_data[4]==-1) config_data[4] = config_data[11];
else config_data[11] = config_data[4];
}
#endif
uint8_t ck=checkEpdDriver();
@@ -223,8 +226,10 @@ void readguy_driver::handleInitPost(){
//drawChar((width()>>1)-46+48,(height()>>1)-14,randomch[2],true,false,4);
drawRect((width()>>1)-46+72,(height()>>1)-14,20,28,0);
//drawChar((width()>>1)-46+72,(height()>>1)-14,randomch[3],true,false,4);
spibz++;
guy_dev->drv_fullpart(1);
guy_dev->_display((const uint8_t*)getBuffer());
spibz--;
Serial.println(F("Display done!"));
READGUY_cali=1; //显示初始化完成
}
@@ -255,9 +260,11 @@ void readguy_driver::handlePinSetup(){
s += String(index_cn_html8); s += (READGUY_cali?(int)READGUY_sd_mosi :-1);
s += String(index_cn_html9); s += (READGUY_cali?(int)READGUY_sd_sclk :-1);
s += String(index_cn_html10); s += (READGUY_cali?(int)READGUY_sd_cs :-1);*/
#ifdef ESP8266
#if defined(ESP8266)
for(int i=2;i<10;i++){
if(i>=6 && i<=8) continue;
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
for(int i=2;i<10;i++){
#else
for(int i=0;i<10;i++){
#endif
@@ -485,8 +492,11 @@ const PROGMEM char readguy_driver::index_cn_html[] = // then write EpdMOSI pin
"置</title></head><body><h1>readguy 设置页面</h1><p>感谢您使用ReadGuy. 现在将引脚配置输"
"入到框内, 即可成功点亮屏幕.<br />点击<a href=\"/wifi\">配置WiFi</a>"
"<br/>点击<a href=\"/api\">配置聚合数据API密钥</a><br/></p><form name=\"input\" action"
"=\"/verify\" method=\"POST\"><h2>引脚定义设定</h2><input type=\"checkbox\" name=\"sha"
"re\" value=\"1\">墨水屏和SD卡共享SPI<br/>E-paper 型号<select name=\"epdtype\">";
"=\"/verify\" method=\"POST\"><h2>引脚定义设定</h2>"
#if (!defined(ESP8266) && !defined(CONFIG_IDF_TARGET_ESP32C3))
"<input type=\"checkbox\" name=\"share\" value=\"1\">墨水屏和SD卡共享SPI<br/>"
#endif
"E-paper 型号<select name=\"epdtype\">";
/* "<option value=\"0\">EPD2_154</option>"
"<option value=\"1\">EPD2_154_D67</option>"

View File

@@ -27,7 +27,7 @@
* limitations under the License.
*/
#include "guy_driver.h"
#include "readguy.h"
#if (!defined(INPUT_PULLDOWN))
#define INPUT_PULLDOWN INPUT
#endif
@@ -41,6 +41,7 @@ volatile uint8_t readguy_driver::spibz=0;
#ifndef ESP8266
SPIClass *readguy_driver::sd_spi =nullptr;
SPIClass *readguy_driver::epd_spi=nullptr;
TaskHandle_t readguy_driver::btn_handle;
#endif
readguy_driver::readguy_driver(){
@@ -76,9 +77,9 @@ uint8_t readguy_driver::init(){
#if (!defined(INDEV_DEBUG))
}
else{ //看来NVS有数据, //从NVS加载数据, 哪怕前面的数据刚刚写入, 还没读取
for(unsigned int i=0;i<sizeof(config_data);i++){
Serial.printf_P(PSTR("data %u: %d\n"),i,config_data[i]);
}
//for(unsigned int i=0;i<sizeof(config_data);i++){
// Serial.printf_P(PSTR("data %u: %d\n"),i,config_data[i]);
//}
if(checkEpdDriver()!=127) setEpdDriver(); //初始化屏幕
else for(;;); //此处可能添加程序rollback等功能操作(比如返回加载上一个程序)
setSDcardDriver();
@@ -124,10 +125,10 @@ uint8_t readguy_driver::checkEpdDriver(){
case READGUY_DEV_213A: guy_dev = new guydev_213A ::drv; break;
#endif
#ifdef READGUY_DEV_266A
case READGUY_DEV_266A: guy_dev = new guydev_266A ::drv; break;
case READGUY_DEV_266A: guy_dev = new guydev_213B_266A ::dev266A; break;
#endif
#ifdef READGUY_DEV_213B
case READGUY_DEV_213B: guy_dev = new guydev_213B ::drv; break;
case READGUY_DEV_213B: guy_dev = new guydev_213B_266A ::dev213B; break;
#endif
#ifdef READGUY_DEV_290A
case READGUY_DEV_290A: guy_dev = new guydev_154A_290A ::dev290A; break;
@@ -160,11 +161,16 @@ uint8_t readguy_driver::checkEpdDriver(){
SPI.setFrequency(ESP8266_SPI_FREQUENCY); ///< 1MHz
guy_dev->IfInit(SPI, READGUY_epd_cs, READGUY_epd_dc, READGUY_epd_rst, READGUY_epd_busy);
#else
if(epd_spi == nullptr) epd_spi = new SPIClass(VSPI);
epd_spi ->setFrequency(ESP32_DISP_FREQUENCY);
if(epd_spi == nullptr) epd_spi = &SPI; //ESP32S2和S3和C3 不支持VSPI, C3只支持HSPI. 使用SPI库默认提供的HSPI.
else epd_spi->end();
//epd_spi ->setFrequency(ESP32_DISP_FREQUENCY);
//Serial.println("deleting guy_dev");
epd_spi->begin(READGUY_epd_sclk,READGUY_shareSpi?READGUY_sd_miso:-1,READGUY_epd_mosi);
if(READGUY_shareSpi) sd_spi = epd_spi;
else {
if(sd_spi!=nullptr && sd_spi!=&SPI) { sd_spi->end(); delete sd_spi; } //防止SPI被delete掉
sd_spi=nullptr;
}
epd_spi->begin(READGUY_epd_sclk,READGUY_shareSpi?READGUY_sd_miso:-1,READGUY_epd_mosi);
guy_dev->IfInit(*epd_spi, READGUY_epd_cs, READGUY_epd_dc, READGUY_epd_rst, READGUY_epd_busy);
#endif
Serial.println(F("IfInit OK"));
@@ -200,22 +206,22 @@ bool readguy_driver::setSDcardDriver(){
&& READGUY_sd_mosi!=READGUY_sd_cs && READGUY_sd_sclk!=READGUY_sd_cs && READGUY_sd_miso>=0 && READGUY_sd_mosi>=0 && READGUY_sd_sclk>=0
#endif
&& READGUY_sd_cs!=READGUY_epd_cs && READGUY_sd_cs!=READGUY_epd_dc && READGUY_sd_cs!=READGUY_epd_rst && READGUY_sd_cs!=READGUY_epd_busy
&& READGUY_sd_cs!=READGUY_btn1 && READGUY_sd_cs!=READGUY_btn2 && READGUY_sd_cs!=READGUY_btn3 && READGUY_sd_cs!=READGUY_bl_pin
){
){ //SD卡的CS检测程序和按键检测程序冲突, 故删掉 (可能引发引脚无冲突但是显示冲突的bug)
#if defined(ESP8266)
//Esp8266无视SPI的设定, 固定为唯一的硬件SPI (D5=SCK, D6=MISO, D7=MOSI)
SDFS.setConfig(SDFSConfig(READGUY_sd_cs));
READGUY_sd_ok = SDFS.begin();
#else
if(sd_spi == nullptr) {
sd_spi = new SPIClass(HSPI);
//sd_spi = new SPIClass(HSPI);
#if (defined(CONFIG_IDF_TARGET_ESP32))
sd_spi = new SPIClass(VSPI);
#else
sd_spi = new SPIClass(FSPI); //ESP32S2和S3和C3 不支持VSPI, C3不支持FSPI
#endif
sd_spi->begin(READGUY_sd_sclk,READGUY_sd_miso,READGUY_sd_mosi); //初始化SPI
}
READGUY_sd_ok = SD.begin(READGUY_sd_cs,*sd_spi,ESP32_SD_SPI_FREQUENCY); //初始化频率为20MHz
if(!READGUY_sd_ok && sd_spi != epd_spi) { //共线时, 不要删除SD
delete sd_spi;
sd_spi=nullptr;
}
#endif
}
else READGUY_sd_ok=0; //引脚不符合规则,或冲突或不可用

View File

@@ -3,7 +3,7 @@
* extra/artset/reward , Bilibili .
* QQ群: 926824162 ()
* : .
* @file guy_driver.h
* @file readguy.h
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @brief readguy .
* @version 1.0
@@ -40,33 +40,30 @@
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include "guy_epdbase.h"
#include "guy_epaper/guy_epdbase.h"
#if (defined(READGUY_DEV_154A) || defined(READGUY_DEV_290A))
#include "guy_154a_290a/guy_154a_290a.h"
#include "guy_epaper/guy_154a_290a/guy_154a_290a.h"
#endif
#if (defined(READGUY_DEV_154B) || defined(READGUY_DEV_270B) || defined(READGUY_DEV_290B))
#include "guy_154b_270b_290b/guy_154b_270b_290b.h"
#include "guy_epaper/guy_154b_270b_290b/guy_154b_270b_290b.h"
#endif
#ifdef READGUY_DEV_213A
#include "guy_213a/guy_213a.h"
#include "guy_epaper/guy_213a/guy_213a.h"
#endif
#ifdef READGUY_DEV_213B
#include "guy_213b/guy_213b.h"
#endif
#ifdef READGUY_DEV_266A
#include "guy_266a/guy_266a.h"
#if (defined(READGUY_DEV_213B) || defined(READGUY_DEV_266A))
#include "guy_epaper/guy_213b_266a/guy_213b_266a.h"
#endif
#ifdef READGUY_DEV_370A
#include "guy_370a/guy_370a.h"
#include "guy_epaper/guy_370a/guy_370a.h"
#endif
#ifdef READGUY_DEV_420A
#include "guy_420a/guy_420a.h"
#include "guy_epaper/guy_420a/guy_420a.h"
#endif
#ifdef READGUY_DEV_420B
#include "guy_420b/guy_420b.h"
#include "guy_epaper/guy_420b/guy_420b.h"
#endif
#ifdef MEPD_DEBUG_DISPLAY
#include "lcdDebug/lcdDebug.h"
#include "guy_epaper/lcdDebug/lcdDebug.h"
#endif
#include "guy_button.h" //改自Button2精简而来
@@ -122,7 +119,7 @@
#define READGUY_sd_miso (config_data[9]) // 目标sd卡的 MISO 引脚, sd_share_spi == 1 时无效
#define READGUY_sd_mosi (config_data[10])// 目标sd卡的 MOSI 引脚, sd_share_spi == 1 时无效
#define READGUY_sd_sclk (config_data[11])// 目标sd卡的 SCLK 引脚, sd_share_spi == 1 时无效
#define READGUY_sd_cs (config_data[12])// 目标sd卡的 CS 引脚
#define READGUY_sd_cs (config_data[12])// 目标sd卡的 CS 引脚.
//按键驱动部分, 为负代表高触发, 否则低触发,
//注意, 这里的io编号是加1的, 即 1或-1 代表 gpio0 的低触发/高触发
#define READGUY_btn1 (config_data[13])
@@ -189,18 +186,25 @@ class readguy_driver: public LGFX_Sprite{ // readguy 基础类
/// @brief 进入EPD的低功耗模式
void sleepEPD(void);
/// @brief ap配网设置页面
typedef struct {
String event;
int method; //其实这里的method的类型应当为HTTPMethod, 但是为了兼容无wifi的功能, 使用了int格式
std::function<void()> func;
} serveFunc;
#ifdef READGUY_ESP_ENABLE_WIFI
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
void ap_setup();
typedef struct {
String event;
HTTPMethod method;
std::function<void()> func;
} serveFunc;
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
void server_setup(const serveFunc *serveFuncs = nullptr, int funcs = 0);
bool server_loop();
void server_end() { sv.stop(); MDNS.end(); }
#else
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
void ap_setup(){}
/// @brief 初始化WiFi AP模式, 用于将来的连接WiFi 处于已连接状态下会断开原本的连接
void server_setup(const serveFunc *serveFuncs = nullptr, int funcs = 0){}
bool server_loop(){ return true; }
void server_end(){}
#endif
/// @brief 检查初始化屏幕硬件, 若检查失败返回0,否则返回硬件代号
uint8_t checkEpdDriver();
@@ -270,7 +274,7 @@ class readguy_driver: public LGFX_Sprite{ // readguy 基础类
#endif
static SPIClass *sd_spi;
static SPIClass *epd_spi;
TaskHandle_t btn_handle;
static TaskHandle_t btn_handle;
#endif
#ifdef READGUY_ESP_ENABLE_WIFI
void handleInit(); //服务器初始化系统(初次访问时, 跳转至引脚设定函数)