update to 1.3.0 version

This commit is contained in:
fsender
2023-11-06 15:39:13 +08:00
parent b5d77bc054
commit a8b2540468
31 changed files with 903 additions and 635 deletions

View File

@@ -6,8 +6,9 @@
*
* @file ex01_helloWorld.ino
* @author FriendshipEnder (f_ender@163.com), Bilibili: FriendshipEnder
* @version 1.0
* @date 2023-09-19
* @version 1.1
* @date create: 2023-09-19
* last modify: 2023-11-06
* @brief ReadGuy最基础的HelloWorld显示.
*
* @note 食用方法:
@@ -27,6 +28,79 @@
* 你需要知道你的哪个引脚对应哪个GPIO, 才能使用这个库 (带来的不便请谅解nia~)
* 配置好了, 代码就开始正常运行了.
*
* 以下是看不懂代码的解决方法. 仔细看就行了
* {0} 代码食用注意事项:
* 这一部分的代码很难读, 或者按维莫斯小姐的说法, 很 "抽象" .
* 如果你要开始一行一行读取下去, 不妨先在这里停顿一下, 看一下一些需要你提前知道的东西.
*
* {1} 画布, 或者叫sprite. 是一块专门存储图像的数据结构.
* 画布需要大量的内存来存放图像的像素, 但是你可以对画布进行任何图像操作, 就像是在墨水屏上能进行的操作一样多.
* 画布类型的数据结构至少需要包含3个要素: 宽度, 高度, 每像素需要的字节数.
* 画布需要的内存为 宽度*高度*每像素需要的字节数. (1bit图像需要8分之一字节)
* 在画布上可以进行几乎任何图像操作, 就像是在墨水屏上能进行的操作一样多.
* 而且你还可以获取像素的颜色 (这和你创建的画布的颜色格式有关).
* 画布可以随时被快速的显示到墨水屏上, 显示完了之后再使用display方法, 你刚才创建的画布就显示出来了.
*
* {2} 屏幕缓存. 你就从来没好奇过, 墨水屏上怎么呈现图像的? 我好奇过.
* 我翻看了里面那些错综复杂又是深奥的C++骚操作又是类继承又是虚函数指针...反正就是抽象而且难懂的的源代码,
* 简而言之, 墨水屏显示的原理就是墨水屏驱动里面也有个画布, 不过这个画布是1bit的(每8像素消耗1字节内存).
* 所有对墨水屏进行的操作其实都是对那个内部的画布进行的操作.
* 在你使用墨水屏的display方法时, 呃, 墨水屏的驱动程序可以读取到这个屏幕缓存的所有字节.
* 并且根据驱动手册的方法将这个画布上的字节发送到屏幕上.
* 发送完成之后再通过一些代码, 墨水屏就会刷屏, 将这个屏幕缓存里的内容显示出来了.
* 维莫斯小姐: 苏滴嘶内~
* 下面的库其实用了一些更加骚气的方法, 直接读取了这块画布, 从而能允许你在ESP8266上也可以...显示不小的图片
*
* {3} 灰度显示. ReadGuy这个库的一大特色就是支持灰度显示.
* 欸, 可是屏幕缓存画布只有1bit啊, 怎么显示灰度啊?
* 不用急, 原理也不难.
* 16级灰度颜色的刷屏分为15个步骤. 因为白色不需要刷.
* 在开始刷屏之前, 务必进行一次慢刷, 确保所有的白色像素都足够白.
* 第一次刷屏, 通常会刷最浅的灰色.
* 此时, 首先将屏幕缓存内所有需要显示为这个颜色的像素全写入为黑色(只是名义上的黑色, 实际上是设定的颜色).
* 再初始化墨水屏的刷屏功能.
* - 此处需要额外设定刷屏的颜色的参数. 此参数设定是可以由驱动程序自动完成的, 不过也可以通过你调用函数完成.
* - 用户只需要用简单的setDepth函数设置颜色即可. 用户设定的颜色深度通常用于显示字符串或者形状等GUI控件.
* - 刷图程序的灰度图片刷新功能会自动控制刷屏颜色, 不需要手动调用.
* 最后刷屏. 因为之前刷图程序已经设定过刷的颜色了, 所以此时刷屏呈现的颜色就是之前设定的颜色.
* 第2-15次刷屏原理类似.
* 每次追加黑色像素, 追加的像素就是来显示灰度的像素. 而原本的黑色像素就是之前那些灰度颜色的像素.
*
* \*(^_^)*/ /** 我相信你应该还不懂. 我就举个例子吧.
* 比如要显示一个渐变色, 从左到右为白色→黑色的渐变图.
* 首先进行一次慢刷, 确保要刷图的地方都是纯洁的白色.
* ≡=-(1)-=≡
* 筛选出最浅的灰色设为灰1, (灰X代表灰度颜色, 灰15代表黑色)
* 再把图片内所有颜色和灰1最接近的颜色写入到屏幕缓存内.
* 此时屏幕缓存内的"黑色"部分都是与灰1最接近的颜色, 其他颜色均为"白色"部分.
* 刷好了之后, 进行一次刷屏. (系统自动调用setDepth(1)来保证接下来图片的黑色部分其实是灰1).
* ≡=-(2)-=≡
* 筛选出比最浅的灰色深一点的颜色设为灰2, 把图片内和灰2最接近的颜色写入屏幕缓存, 但保持原本代表灰1的"黑色"不变.
* (也就是说, 把灰2的像素写入之后, 屏幕缓存的黑色像素只多不少. 写入过程中, 只能是白→黑, 不存在黑→白)
* 此时屏幕缓存内的"黑色"部分包含了与灰2最接近的颜色, 和刚才刷完的与灰1最接近的颜色. 其他颜色均为"白色"部分.
* 刷好了之后, 进行一次刷屏. (系统自动调用setDepth(2)来保证接下来图片的黑色部分其实是灰2)
* 注意屏幕显示, 原本的灰1并没有颜色变化, 变化的都是本次追加的"灰2"代表的"黑色".
* 追加的像素会显示为新设定的颜色.
* ≡=-(3)-=≡
* 对于灰3, 和灰2一样, 追加显示到屏幕缓存内.
* (也就是说, 屏幕缓存的黑色像素还是只多不少. 写入过程中, 只能是白→黑, 不存在黑→白)
* 此时屏幕缓存内的"黑色"部分包含了与灰3, 灰2和灰1最接近的颜色. 其他颜色均为"白色"部分.
* 设置颜色深度, 刷屏.
* 对于灰4~灰15, 都这么做
* ≡=-(5)-=≡
* 刷完灰15之后, 灰度图就刷完了.
*
* {4} 自定义刷屏函数. 到底是什么决定了刷屏时的每一像素是什么颜色? 是黑是白?
* 其实刷屏的本质就是通过调用一个外部函数.
* 该函数可以根据输入的像素坐标位置来决定输出的像素颜色.
* 为了简化程序调用过程并提高调用速度, 此处的像素坐标位置参数为一个整数(而不是两个)
* 至于该怎么调用这个函数, 并不是你需要了解的事情.
*
* 关于图形函数:
* 用过 LovyanGFX / Adafruit GFX / GxEPD2 / TFT_eSPI 库的用户, 可以直接套用他们的接口函数
* 用过 U8G2 的用户, 接口函数和U8G2不一样的,
* 请参考上述库的示例程序.
*
* @attention
* Copyright (c) 2022-2023 FriendshipEnder
*
@@ -46,14 +120,17 @@
*/
//在这里包含程序需要用到的库函数
//就像是你在C语言里面总是用的 #include <stdio.h> 一样,
//为了能在这里使用readguy库, 你需要在这里调用 #include "readguy.h" 来包含此库
//在platformio中, 还要额外 #include <Arduino.h> 来确保你用的是Arduino环境.
#include <Arduino.h> //arduino功能基础库. 在platformIO平台上此语句不可或缺
#include "readguy.h" //包含readguy_driver 基础驱动库
#include "readguy.h" //包含readguy_driver 基础驱动库
ReadguyDriver guy;//新建一个readguy对象, 用于显示驱动.
//所有对墨水屏的操作都是对guy这个对象进行的操作.
void drawLines(); //声明一个函数, 用于显示一些线条. 此函数在后面的程序中会用到的
void setup(){
void setup(){ //Arduino的setup函数. 这个函数在上电之后仅执行一次.
// --------------------- 1 - 初始化和启动ReadGuy -------<
Serial.begin(115200); //初始化串口
@@ -64,18 +141,23 @@ void setup(){
guy.init(); //初始化readguy_driver 基础驱动库.
//首次初始化完成之后, 以后再初始化就不需要配网了, 除非你抹除了芯片的flash
//完成之后会全屏刷新一次
//完成之后会让下一次刷屏 全屏慢速刷新一次, 之后的刷屏即可自由定义是全刷还是局刷.
guy.setFont(&FreeMonoBold9pt7b); //设置显示的字体
//字体可以参考LovyanGFX的示例程序.
guy.setTextColor(0,1); //设置显示的颜色. 0代表黑色, 1代表白色
//此函数的作用是设置显示颜色. 左边的0代表前景色(文字颜色: 黑色), 右边的1代表背景色(白色)
//类似于 guy.setTextColor(0) 的用法说明此颜色为透明背景.
guy.drawString("Hello Readguy!",10,10); //用此函数将字符串显示到屏幕缓存内
//调用此函数并不会立即刷屏, 而是会将文本字符串写入到屏幕缓存, 在下一次调用display()函数之后就会显示出来.
//也可以用print函数来显示.
//guy.setCursor(10,10); //设置显示的坐标
//guy.print("Hello Readguy!"); //使用这个函数也能显示出字符串, 但是需要提前使用setCursor确定显示坐标
guy.display(true); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上
guy.display(true); // 快速刷新. 将屏幕缓存内的内容显示到墨水屏幕上. 可简写为 guy.display(), 效果一样.
//guy.display(false); // 慢速刷新.
//想知道更多内容, 欢迎移步到其他示例.
@@ -85,6 +167,7 @@ void loop(){
//什么也不做, 毕竟刷新墨水屏要消耗墨水屏的阳寿.
//盖姐说它们也是有阳寿的. 刷多了会老化.
delay(1);
}/* END OF FILE. ReadGuy project.
Copyright (C) 2023 FriendshipEnder. */