本帖最后由 HonestQiao 于 2024-1-9 00:36 编辑
近期刚好上手了一块 Pervasive Displays 的电子墨水屏,显示的效果非常好,结合手头的树莓派Pico,制作了一款老黄历。
一、项目介绍:
这个项目,使用树莓派Pico做为主控,使用Pervasive Displays的红白黑三色电子墨水屏进行显示,并使用采集的老黄历数据,进行老黄历的呈现。
目前版本的效果:
二、项目设计:
要实现这个项目,需要依次实现以下:
1. 寻找老黄历数据和模版
2. 驱动EPD屏幕
3. 在EPD屏幕上显示中文
4. 老黄历界面设计
5. 代码编写
6. 整体优化
三、硬件:
1. 树莓派Pico
2. Pervasive Displays墨水屏+转接板
3. 实物连接
四、寻找老黄历数据和模版
讲过多番查找,最终使用 https://www.ibazi.cn/huangli 的信息,做为老黄历的数据和呈现模版。
五、驱动EPD屏幕
树莓派Pico可以在Arduino IDE环境开发,而Pervasive Displays又为 EPD提供了Arduino环境的Lib,所以就直接使用Arduino IDE开发了。
安装PDLS_EXT3_Basic_GLobal即可:
然后参考实例,了解具体的用法:
六. 在EPD屏幕上显示中文
PDLS_EXT3_Basic_GLobal默认只提供了英文字符字库,没有中文字库的接口。
经过相关官方了解,只有商业用户,才提供支持用户字库的版本,非商业用户只能自己研究。
经过一番探究,确定PDLS_EXT3_Basic_GLobal中显示字符,就使用的画点。
既然画点,那就好办了,弄一个汉字的点阵数据就可以。
参考其自带的Terminal8x12e.h,复制了一份Terminal8x16e.h。
再访问 https://www.23bei.com/tool/216.html 生成所需显示内容的字形数据:
上面的数据,拷贝到上述字形数据文件中,替换原有的一部分:
再代码中,使用如下代码即可显示:
- myScreen.selectFont(Font_Terminal8x16);
- myScreen.gText(76, 329, "LMNOPQ", myColours.red);
复制代码
当然,这只是一个简单的替换显示。
复杂一点的,还可以做一个转换函数,方便快捷进行调用。
七. 在EPD屏幕上呈现老黄历界面
要想在EPD上面,显示老黄历界面,是最麻烦的一步。
我的具体做法如下:
1. 在图形软件中,新建一个和屏幕像素同等大小的图像
2. 然后截图老黄历界面并调整到实际大小
3. 在界面上拉线,获取每个位置的坐标
最终,得到一系列坐标定义:
- 顶部:
- 方块:
- 5,4 83,64 淡红
- 字:
- 95,11 今天 黑色
- 95,35 农历 淡红
- 95,54 葵卯年 黑色
-
- 37,25 7 白色
-
- 线框:灰色
- x=70,170
- y=77,96,158
- 0,77,w=240-1,h=158-77 黑色
- 70,77,w=100,h=158-77 黑色
-
-
- 中间两边:
- 圆:
- 37,110,r=10 红色
- 204,110.r=10 灰色
-
- 字:
- 37,110 宜 白色
- 204,110 忌 白色
-
- 37,82 无节日 黑色
- 204,82 无节气 黑色
-
- 字:
- 37,126 祭祀 黑色
- 204,126 畋猎 黑色
- 37,141 嫁娶 黑色
- 204,141 求医 黑色
-
- 中间中间:
- 圆:
- 117,120,r=30 灰色
- 117,120,r=20 暗红
- 117,120,r=20 灰色
- 117,120,r=10 白色
-
- 线:
- 117,120-5 - 117,120+5 红色
-
- 字:
- 70,77 喜 白色
- 170,77 贵 白色
- 70,158 财 白色
- 170,158 生 白色
-
- 块:
- 70,77-76,83 喜 暗红
- 170,77-176,83 贵 红色
- 70,158-76,164 财 淡红
- 170,158-176,164 生 灰色
-
- 字:
- 80,77 西北 黑色
- 180,77 东北 黑色
- 80,158 正东 黑色
- 180,158 东南 黑色
-
-
-
- 下中:
- 框
- 0,158 - 0,181, w=240,h=181-158 灰色
- 0,181 - 0,210, w=240,h=210-181 灰色
- 0,210 - 0,270, w=240, h=270-181 灰色
- 70,181, 170,210, w=100,h=270-181 灰色
- 70,254, 170,210, w=100,h=270-210 灰色
-
- 字:
- 54,166 年 红色
- 99,166 月 红色
- 146,166 日 红色
-
- 9,185 冲 红色
- 102,185 煞 红色
- 176,185 天干 红色
-
- 14,213 今日胎神 红色
- 98,213 今日吉时
- 182.213 今日八字
-
- 74,257 十二神 红色
- 124,257 二八宿 红色
复制代码
八、代码编写
上一步得到了坐标数据,下面就是实际的代码编写了:
- // Screen
- #include "PDLS_EXT3_Basic_Global.h"
-
- // SDK
- // #include <Arduino.h>
- #include "hV_HAL_Peripherals.h"
-
- // Include application, user and local libraries
- // #include <SPI.h>
-
- // Configuration
- #include "hV_Configuration.h"
-
- // Set parameters
-
- // Define structures and classes
-
- // Define variables and constants
- Screen_EPD_EXT3 myScreen(eScreen_EPD_EXT3_370, boardRaspberryPiPico_RP2040);
-
- // Prototypes
-
- // Utilities
- ///
- /// @brief Wait with countdown
- /// @param second duration, s
- ///
- void wait(uint8_t second)
- {
- for (uint8_t i = second; i > 0; i--)
- {
- Serial.print(formatString(" > %i \r", i));
- delay(1000);
- }
- Serial.print(" \r");
- }
-
- // Functions
- ///
- /// @brief DisplayLHL
- ///
- void DisplayLHL()
- {
- myScreen.setOrientation(2);
-
- myScreen.setPenSolid(true);
- myScreen.dRectangle(5, 4, 83-5, 64-4, myColours.lightRed);
-
- myScreen.selectFont(Font_Terminal16x24);
- myScreen.gText(37, 25, "7", myColours.white);
-
- myScreen.selectFont(Font_Terminal8x12);
- myScreen.gText(95, 11, "Today, 2024-1, Sunday", myColours.black);
- myScreen.gText(95, 35, "NongLi 11-26", myColours.red);
- myScreen.gText(95, 54, "Tu Yi-Chou Geng-Wu", myColours.black);
-
- myScreen.setPenSolid(false);
- myScreen.dRectangle(0, 77, 240-1, 158-77, myColours.grey);
- myScreen.dRectangle(70, 77, 170-70, 158-77, myColours.grey);
-
- myScreen.setPenSolid(true);
- myScreen.circle(37, 110, 10, myColours.red);
- myScreen.circle(204, 110, 10, myColours.grey);
-
- myScreen.gText(37-4, 110-4, "Y", myColours.white);
- myScreen.gText(204-4, 110-4, "N", myColours.white);
-
- myScreen.gText(37-20, 82, "No Jie", myColours.black);
- myScreen.gText(204-20, 82, "No Qi", myColours.black);
-
- myScreen.gText(37-20-8, 126, "Ji-Shi", myColours.black);
- myScreen.gText(204-20-8, 126, "Lie-Shou", myColours.black);
- myScreen.gText(37-20-8, 141, "Jia-Qu", myColours.black);
- myScreen.gText(204-20-8, 141, "Qiu-Yi", myColours.black);
-
- myScreen.circle(117, 120, 30, myColours.grey);
- myScreen.circle(117, 120, 25, myColours.darkRed);
- myScreen.circle(117, 120, 20, myColours.grey);
- myScreen.circle(117, 120, 10, myColours.white);
-
- myScreen.circle(117, 120, 2, myColours.darkRed);
- myScreen.dLine(117, 120-10, 0, 10, myColours.black);
- myScreen.dLine(117, 120, 0, 10, myColours.red);
-
- myScreen.dRectangle(70, 77, 16, 16, myColours.red);
- myScreen.dRectangle(170-16, 77, 16, 16, myColours.darkRed);
- myScreen.dRectangle(70, 158-16, 16, 16, myColours.lightRed);
- myScreen.dRectangle(170-16, 158-16, 16, 16, myColours.grey);
-
- myScreen.gText(70+4, 77+4, "J", myColours.white);
- myScreen.gText(170-16+4, 77+4, "E", myColours.white);
- myScreen.gText(70+4, 158-16+4, "P", myColours.black);
- myScreen.gText(170-16+4, 158-16+4, "L", myColours.black);
-
- myScreen.gText(80+8, 77+2, "WN", myColours.black);
- myScreen.gText(180-8-32-8, 77+2, "EN", myColours.black);
- myScreen.gText(80+8, 158-8-4, "CE", myColours.black);
- myScreen.gText(180-8-32-8, 158-8-4, "ES", myColours.black);
-
-
- myScreen.setPenSolid(false);
- myScreen.dRectangle(0, 158, 240-1, 181-158, myColours.grey);
- myScreen.dRectangle(0, 181, 240-1, 210-181, myColours.grey);
- myScreen.dRectangle(0, 210, 240-1, 270-210, myColours.grey);
- myScreen.dRectangle(70, 181, 170-70, 270-181, myColours.grey);
- myScreen.dRectangle(70, 254, 170-70, 270-254, myColours.grey);
-
- myScreen.setPenSolid(true);
- myScreen.gText(54, 166, "Y:", myColours.red);
- myScreen.gText(99, 166, "M:", myColours.red);
- myScreen.gText(146, 166, "D:", myColours.red);
-
- myScreen.gText(9, 185, "Chong:", myColours.red);
- myScreen.gText(102, 185, "Sha:", myColours.red);
- myScreen.gText(176, 185, "Tian:", myColours.red);
-
- myScreen.gText(14-8, 213, "Today-B:", myColours.red);
- myScreen.gText(98-16, 213, "Today-T:", myColours.red);
- myScreen.gText(182-8, 213, "Today-8:", myColours.red);
-
- myScreen.selectFont(Font_Terminal6x8);
- myScreen.gText(74, 257, "12:", myColours.red);
- myScreen.gText(124, 257, "28:", myColours.red);
-
-
- myScreen.selectFont(Font_Terminal8x16);
- myScreen.gText(76, 329, "LMNOPQ", myColours.red);
-
- myScreen.flush();
- }
-
- // Add setup code
- ///
- /// @brief Setup
- ///
- void setup()
- {
- // Start
- Serial.begin(115200);
- delay(2000);
-
- Serial.println("begin... ");
- myScreen.begin();
- Serial.println(formatString("%s %ix%i", myScreen.WhoAmI().c_str(), myScreen.screenSizeX(), myScreen.screenSizeY()));
-
- Serial.println("Colours... ");
- myScreen.clear();
- DisplayLHL();
- wait(8);
-
- Serial.println("=== ");
- Serial.println();
- }
-
- // Add loop code
- ///
- /// @brief Loop, empty
- ///
- void loop()
- {
- delay(1000);
- }
复制代码
上述代码,就是使用了画线、画圆、画方块、画方框、显示文字、设置字体等调用,来进行具体的实现。
九、实现效果
上面的代码编译执行后,效果如下:
因为最近比较忙,显示的还只是英文字符,还没有完全换为中文字符。
另外,老黄历的数据是采集的,不能公开,所以数据还在整合中,将尽快整合完成。
十、整体优化
之前的版本,还是显示的英文字符,而且内容,都还是在代码里面写死的。
每一次修改,都需要重新编译,然后下载,然后启动运行,耗时耗力不好调整。
那么这一版本,就做了整体优化。
具体的优化细节如下:
1. 要显示的信息,提取为json文件,要改变现实效果,只需要修改json配置即可
2. json配置文件,通过web提供
3. PicoW添加了联网读取解析json的功能,并根据json的数据,进行实际的显示绘制操作
4. PicoW添加了按BOOTSEL按键,重新读取json的功能
1. json配置文件如下:
- {
- "name": "laohuangli",
- "orientation": 2,
- "version": 1.0,
- "offset" : [0, 0],
- "data_demo" :[
- {"type": "comment", "value":"这是一行注释"},
- {"type": "setOrientation", "value":2},
- {"type": "setOffset", "x":0, "y":0},
- {"type": "setPenSolid", "value":true},
-
- {"type": "selectFont", "value":"16x24"},
- {"type": "setFontSolid", "value":true},
- {"type": "gText", "x":37, "y":25, "text":"7", "color":"white"},
-
- {"type": "point", "x":5, "y":4, "color":"white"},
- {"type": "line", "x":5, "y":4, "x1":5, "y1":4, "color":"white"},
- {"type": "rectangle", "x":5, "y":4, "x1":5, "y1":4, "color":"white"},
- {"type": "circle", "x":5, "y":4, "r":10, "color":"white"},
- {"type": "triangle", "x":5, "y":4, "x1":5, "y1":4, "x2":5, "y2":4, "color":"white"},
-
- {"type": "dLine", "x":5, "y":4, "w":78, "h":60, "color":"white"},
- {"type": "dRectangle", "x":5, "y":4, "w":78, "h":60, "color":"white"}
- ],
- "data" :[
- {"type":"comment", "value":"设置方向"},
- {"type": "setOrientation", "value":2},
-
- {"type":"comment", "value":"设置笔触"},
- {"type": "setPenSolid", "value":true},
- {"type": "setFontSolid", "value":false},
-
- {"type":"comment", "value":"标题"},
- {"type": "selectFont", "value":"8x16"},
- {"type": "gText", "x":96, "y":5, "text":"老黄历", "color":"red"},
-
- {"type": "dLine", "x":0, "y":30, "w":240, "h":0, "color":"grey"},
-
- {"type": "setOffset", "x":0, "y":35},
-
- {"type":"comment", "value":"当日日期"},
- {"type": "dRectangle", "x":5, "y":4, "w":78, "h":70, "color":"lightRed"},
- {"type": "selectFont", "value":"16x24"},
- {"type": "gText", "x":37, "y":30, "text":"8", "color":"white"},
-
- {"type":"comment", "value":"当日日历信息"},
- {"type": "selectFont", "value":"8x16"},
- {"type": "gText", "x":95, "y":10, "text":"2024年1月 星期一", "color":"black"},
- {"type": "gText", "x":95, "y":25, "text":"农历十一月廿七", "color":"black"},
- {"type": "gText", "x":95, "y":40, "text":"癸卯年 兔年", "color":"black"},
- {"type": "gText", "x":95, "y":55, "text":"乙丑月 辛未日", "color":"black"},
-
- {"type": "setOffset", "x":0, "y":50},
-
- {"type":"comment", "value":"中间方框"},
- {"type": "setPenSolid", "value":false},
- {"type": "dRectangle", "x":0, "y":77, "w":239, "h":81, "color":"grey"},
- {"type": "dRectangle", "x":70, "y":77, "w":100, "h":81, "color":"grey"},
-
- {"type":"comment", "value":"中间方框内两边圆形"},
- {"type": "setPenSolid", "value":true},
- {"type": "circle", "x":37, "y":110, "r":10, "color":"red"},
- {"type": "circle", "x":204, "y":110, "r":10, "color":"grey"},
- {"type": "selectFont", "value":"8x16"},
- {"type": "gText", "x":31, "y":103, "text":"宜", "color":"white"},
- {"type": "gText", "x":198, "y":103, "text":"忌", "color":"black"},
-
- {"type":"comment", "value":"中间方框内上部文字"},
- {"type": "gText", "x":17, "y":82, "text":"无节日", "color":"black"},
- {"type": "gText", "x":184, "y":82, "text":"无节气", "color":"black"},
-
- {"type":"comment", "value":"中间方框内下部文字"},
- {"type": "gText", "x":9, "y":126, "text":"祭祀 解除", "color":"black"},
- {"type": "gText", "x":176, "y":126, "text":"祈福 冠带", "color":"black"},
- {"type": "gText", "x":9, "y":141, "text":"破屋坏垣", "color":"black"},
- {"type": "gText", "x":176, "y":141, "text":"嫁娶 进人口", "color":"black"},
-
-
- {"type":"comment", "value":"中间方框内中部圆盘"},
- {"type": "circle", "x":117, "y":120, "r":30, "color":"grey"},
- {"type": "circle", "x":117, "y":120, "r":25, "color":"darkRed"},
- {"type": "circle", "x":117, "y":120, "r":20, "color":"grey"},
- {"type": "circle", "x":117, "y":120, "r":10, "color":"white"},
-
- {"type":"comment", "value":"中间方框内中部圆盘内部指南针"},
- {"type": "circle", "x":117, "y":120, "r":2, "color":"darkRed"},
- {"type": "dLine", "x":117, "y":110, "w":0, "h":10, "color":"black"},
- {"type": "dLine", "x":117, "y":120, "w":0, "h":10, "color":"red"},
-
- {"type":"comment", "value":"中间方框内中部圆盘四边方框和文字"},
- {"type": "dRectangle", "x":70, "y":77, "w":16, "h":16, "color":"red"},
- {"type": "dRectangle", "x":154, "y":77, "w":16, "h":16, "color":"darkRed"},
- {"type": "dRectangle", "x":70, "y":142, "w":16, "h":16, "color":"lightRed"},
- {"type": "dRectangle", "x":154, "y":142, "w":16, "h":16, "color":"grey"},
- {"type": "gText", "x":72, "y":77, "text":"喜", "color":"white"},
- {"type": "gText", "x":156, "y":77, "text":"贵", "color":"white"},
- {"type": "gText", "x":72, "y":142, "text":"财", "color":"black"},
- {"type": "gText", "x":156, "y":142, "text":"生", "color":"black"},
-
- {"type":"comment", "value":"中间方框内中部圆盘四边方框旁边文字"},
- {"type": "gText", "x":88, "y":77, "text":"西南", "color":"black"},
- {"type": "gText", "x":130, "y":77, "text":"东北", "color":"black"},
- {"type": "gText", "x":88, "y":142, "text":"正东", "color":"black"},
- {"type": "gText", "x":130, "y":142, "text":"东南", "color":"black"},
-
- {"type": "setOffset", "x":0, "y":65},
-
- {"type":"comment", "value":"下部方框"},
- {"type": "setPenSolid", "value":false},
- {"type": "dRectangle", "x":0, "y":158, "w":239, "h":23, "color":"grey"},
- {"type": "dRectangle", "x":0, "y":181, "w":239, "h":49, "color":"grey"},
- {"type": "dRectangle", "x":0, "y":230, "w":239, "h":90, "color":"grey"},
- {"type": "dRectangle", "x":70, "y":181, "w":100, "h":139, "color":"grey"},
- {"type": "dRectangle", "x":70, "y":284, "w":100, "h":36, "color":"grey"},
-
- {"type":"comment", "value":"下部方框文字:红色"},
- {"type":"comment", "value":"下部方框顶部文字"},
- {"type": "gText", "x":54, "y":162, "text":"年", "color":"red"},
- {"type": "gText", "x":99, "y":162, "text":"月", "color":"red"},
- {"type": "gText", "x":146, "y":162, "text":"日", "color":"red"},
-
- {"type":"comment", "value":"下部方框中间文字"},
- {"type": "gText", "x":9, "y":185, "text":"冲", "color":"red"},
- {"type": "gText", "x":9, "y":205, "text":"肖", "color":"red"},
- {"type": "gText", "x":95, "y":200, "text":"煞", "color":"red"},
- {"type": "gText", "x":176, "y":185, "text":"天干", "color":"red"},
- {"type": "gText", "x":176, "y":205, "text":"地支", "color":"red"},
-
- {"type":"comment", "value":"下部方框下部文字"},
- {"type": "gText", "x":6, "y":233, "text":"今日胎神", "color":"red"},
- {"type": "gText", "x":82, "y":233, "text":"今日吉时", "color":"red"},
- {"type": "gText", "x":174, "y":233, "text":"今日八字", "color":"red"},
-
- {"type":"comment", "value":"下部方框下部中间文字"},
- {"type": "gText", "x":74, "y":287, "text":"十二神", "color":"red"},
- {"type": "gText", "x":124, "y":287, "text":"二八宿", "color":"red"},
-
- {"type":"comment", "value":"下部方框文字:黑色"},
- {"type":"comment", "value":"下部方框顶部文字"},
- {"type": "gText", "x":70, "y":162, "text":"金箔", "color":"black"},
- {"type": "gText", "x":115, "y":162, "text":"海中", "color":"black"},
- {"type": "gText", "x":162, "y":162, "text":"路旁", "color":"black"},
-
- {"type":"comment", "value":"下部方框中间文字"},
- {"type": "gText", "x":24, "y":190, "text":"羊日冲牛", "color":"black"},
- {"type": "gText", "x":24, "y":210, "text":"乙丑", "color":"black"},
- {"type": "gText", "x":120, "y":200, "text":"煞西", "color":"black"},
- {"type": "gText", "x":201, "y":190, "text":"辛金", "color":"black"},
- {"type": "gText", "x":201, "y":210, "text":"未土", "color":"black"},
-
- {"type":"comment", "value":"下部方框下部文字"},
- {"type": "gText", "x":6, "y":253, "text":"厨灶厕外", "color":"black"},
- {"type": "gText", "x":6, "y":273, "text":"西南", "color":"black"},
-
- {"type": "gText", "x":82, "y":253, "text":"庚寅辛卯癸巳", "color":"black"},
- {"type": "gText", "x":82, "y":269, "text":"丙申戊戌己亥 ", "color":"black"},
-
- {"type": "gText", "x":174, "y":253, "text":"癸卯乙丑", "color":"black"},
- {"type": "gText", "x":174, "y":273, "text":"辛未戊子", "color":"black"},
-
- {"type":"comment", "value":"下部方框下部中间文字"},
- {"type": "gText", "x":95, "y":301, "text":"破", "color":"black"},
- {"type": "gText", "x":145, "y":301, "text":"张", "color":"black"}
- ]
- }
复制代码
在上述文件中,定义了在老黄历界面中,所有需要的调用操作,data_demo中给出了所有可用的定义。
上面这个json文件,也可以用程序来自动生成,这样子每次访问网址的时候,可以根据当前日期,自动选择对应日期的数据输出json给PicoW使用。
2. json配置文件,通过web提供
在这里,使用了python提供简单web服务:
- python -m http.server 9080
复制代码
3. arduino中PicoW的代码:
- // #include <WiFi.h>
- // #include <HTTPClient.h>
-
- // Screen
- #include "PDLS_EXT3_Basic_Global.h"
-
- // SDK
- // #include <Arduino.h>
- #include "hV_HAL_Peripherals.h"
-
- // Include application, user and local libraries
- // #include <SPI.h>
-
- // Configuration
- #include "hV_Configuration.h"
-
- #include <Arduino.h>
- #include <WiFi.h>
- #include <HTTPClient.h>
- #include <ArduinoJson.h>
-
- // Define structures and classes
-
- // Define variables and constants
- Screen_EPD_EXT3 myScreen(eScreen_EPD_EXT3_370, boardRaspberryPiPico_RP2040);
-
- bool status = false;
-
- // Prototypes
-
- // Utilities
- ///
- /// @brief Wait with countdown
- /// @param second duration, s
- ///
- void wait(uint8_t second) {
- for (uint8_t i = second; i > 0; i--) {
- Serial.print(formatString(" > %i \r", i));
- delay(1000);
- }
- Serial.print(" \r");
- }
-
- #ifndef STASSID
- #define STASSID "********"
- #define STAPSK "********"
- #endif
-
- const char *ssid = STASSID;
- const char *pass = STAPSK;
-
- WiFiMulti WiFiMulti;
-
- uint8_t get_font(String font_name) {
- if (font_name == "6x8") {
- return Font_Terminal6x8;
- } else if (font_name == "8x12") {
- return Font_Terminal8x12;
- } else if (font_name == "8x16") {
- return Font_Terminal8x16;
- } else if (font_name == "12x16") {
- return Font_Terminal12x16;
- } else if (font_name == "16x24") {
- return Font_Terminal16x24;
- } else {
- Serial.println(formatString("font_name is invalid: %s", font_name));
- return Font_Terminal6x8;
- }
- }
-
- uint16_t get_color(String color_name) {
- if (color_name == "black") {
- return myColours.black;
- } else if (color_name == "white") {
- return myColours.white;
- } else if (color_name == "grey") {
- return myColours.grey;
- } else if (color_name == "red") {
- return myColours.red;
- } else if (color_name == "lightRed") {
- return myColours.lightRed;
- } else if (color_name == "darkRed") {
- return myColours.darkRed;
- } else {
- Serial.println(formatString("color_name is invalid: %s", color_name));
- return myColours.black;
- }
- }
-
- void request_json_and_display() {
- // wait for WiFi connection
- if ((WiFiMulti.run() == WL_CONNECTED)) {
-
- HTTPClient http;
-
- Serial.print("[HTTP] begin...\n");
- if (http.begin("http://192.168.1.15:9080/laohuangli.json")) { // HTTP
- Serial.print("[HTTP] GET...\n");
- // start connection and send HTTP header
- int httpCode = http.GET();
-
- // httpCode will be negative on error
- if (httpCode > 0) {
- // HTTP header has been send and Server response header has been handled
- Serial.printf("[HTTP] GET... code: %d\n", httpCode);
-
- // file found at server
- if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
- String payload = http.getString();
- Serial.println(payload);
-
- // Allocate the JSON document
- JsonDocument doc;
-
- // Parse JSON object
- DeserializationError error = deserializeJson(doc, payload);
- if (error) {
- Serial.print(F("deserializeJson() failed: "));
- Serial.println(error.f_str());
- return;
- } else {
- // 解析数据
- int x_offset = 0;
- int y_offset = 0;
- int orientation = 2;
-
- x_offset = doc["offset"][0].as<long>();
- y_offset = doc["offset"][1].as<long>();
- orientation = doc["orientation"].as<long>();
-
- Serial.println(F("Response:"));
- Serial.println(formatString("name: %s", doc["name"].as<const char *>()));
- Serial.println(formatString("orientation: %d", orientation));
- Serial.println(formatString("offset: (%d,%d)", x_offset, y_offset));
- Serial.println(formatString("version: %0.2f", doc["version"].as<float>()));
- Serial.println(formatString("data size: %d", doc["data"].size()));
-
- // 设置默认方向
- myScreen.setOrientation(orientation);
-
- for (int i = 0; i < doc["data"].size(); i++) {
- String type = doc["data"][i]["type"];
- if (type == "comment") {
- // 注释
- String comment = doc["data"][i]["value"];
- Serial.println(formatString("comment: %s", comment.c_str()));
- } else if (type == "setOrientation") {
- // 设置方向
- int value = doc["data"][i]["value"].as<long>();
- Serial.println(formatString("setOrientation: %d", value));
- myScreen.setOrientation(value);
- } else if (type == "setOffset") {
- // 设置方向
- x_offset = doc["data"][i]["x"].as<long>();
- y_offset = doc["data"][i]["y"].as<long>();
- Serial.println(formatString("setOffset: (x, y)=(%d, %d)", x_offset, y_offset));
- } else if (type == "setPenSolid") {
- // 设置落笔抬笔
- int value = doc["data"][i]["value"].as<bool>();
- Serial.println(formatString("setPenSolid: %d", value));
- myScreen.setPenSolid(value);
- } else if (type == "selectFont") {
- // 设置字体
- String font_name = doc["data"][i]["value"];
- Serial.println(formatString("selectFont: %s", font_name.c_str()));
- uint8_t font = get_font(font_name);
- myScreen.selectFont(font);
- } else if (type == "setFontSolid") {
- // 设置字体落笔抬笔
- int value = doc["data"][i]["value"].as<bool>();
- Serial.println(formatString("setFontSolid: %d", value));
- myScreen.setFontSolid(value);
- } else if (type == "gText") {
- // 显示文本
- int x = doc["data"][i]["x"].as<long>();
- int y = doc["data"][i]["y"].as<long>();
- String text = doc["data"][i]["text"];
- String color_name = doc["data"][i]["color"];
- Serial.println(formatString("gText: (x,y)=(%d,%d) text=%s color=%s", x, y, text.c_str(), color_name.c_str()));
- uint16_t color = get_color(color_name);
- myScreen.gText(x + x_offset, y + y_offset, text, color);
- } else if (type == "point") {
- // 画点
- int x = doc["data"][i]["x"].as<long>();
- int y = doc["data"][i]["y"].as<long>();
- String color_name = doc["data"][i]["color"];
- Serial.println(formatString("point: (x,y)=(%d,%d) color=%s", x, y, color_name.c_str()));
- uint16_t color = get_color(color_name);
- myScreen.point(x + x_offset, y + y_offset, color);
- } else if (type == "line") {
- // 画线
- int x = doc["data"][i]["x"].as<long>();
- int y = doc["data"][i]["y"].as<long>();
- int x1 = doc["data"][i]["x1"].as<long>();
- int y1 = doc["data"][i]["y1"].as<long>();
- String color_name = doc["data"][i]["color"];
- Serial.println(formatString("line: (x,y)=(%d,%d) (x1,y1)=(%d,%d) color=%s", x, y, x1, y1, color_name.c_str()));
- uint16_t color = get_color(color_name);
- myScreen.line(x + x_offset, y + y_offset, x1+ x_offset, y1 + y_offset, color);
- } else if (type == "rectangle") {
- // 画矩形
- int x = doc["data"][i]["x"].as<long>();
- int y = doc["data"][i]["y"].as<long>();
- int x1 = doc["data"][i]["x1"].as<long>();
- int y1 = doc["data"][i]["y1"].as<long>();
- String color_name = doc["data"][i]["color"];
- Serial.println(formatString("rectangle: (x,y)=(%d,%d) (x1,y1)=(%d,%d) color=%s", x, y, x1, y1, color_name.c_str()));
- uint16_t color = get_color(color_name);
- myScreen.rectangle(x + x_offset, y + y_offset, x1 + x_offset, y1 + y_offset, color);
- } else if (type == "circle") {
- // 画圆
- int x = doc["data"][i]["x"].as<long>();
- int y = doc["data"][i]["y"].as<long>();
- int r = doc["data"][i]["r"].as<long>();
- String color_name = doc["data"][i]["color"];
- Serial.println(formatString("circle: (x,y)=(%d,%d) r=%d color=%s", x, y, r, color_name.c_str()));
- uint16_t color = get_color(color_name);
- myScreen.circle(x + x_offset, y + y_offset, r, color);
- } else if (type == "triangle") {
- // 画三角形
- int x = doc["data"][i]["x"].as<long>();
- int y = doc["data"][i]["y"].as<long>();
- int x1 = doc["data"][i]["x1"].as<long>();
- int y1 = doc["data"][i]["y1"].as<long>();
- int x2 = doc["data"][i]["x2"].as<long>();
- int y2 = doc["data"][i]["y2"].as<long>();
- String color_name = doc["data"][i]["color"];
- Serial.println(formatString("triangle: (x,y)=(%d,%d) (x1,y1)=(%d,%d) (x2,y2)=(%d,%d) color=%s", x, y, x1, y1, x2, y2, color_name.c_str()));
- uint16_t color = get_color(color_name);
- myScreen.triangle(x + x_offset, y + y_offset, x1 + x_offset, y1 + y_offset, x2 + x_offset, y2 + y_offset, color);
- } else if (type == "dLine") {
- // 画线(向量)
- int x = doc["data"][i]["x"].as<long>();
- int y = doc["data"][i]["y"].as<long>();
- int w = doc["data"][i]["w"].as<long>();
- int h = doc["data"][i]["h"].as<long>();
- String color_name = doc["data"][i]["color"];
- Serial.println(formatString("dLine: (x,y)=(%d,%d) (w,h)=(%d,%d) color=%s", x, y, w, h, color_name.c_str()));
- uint16_t color = get_color(color_name);
- myScreen.dLine(x + x_offset, y + y_offset, w, h, color);
- } else if (type == "dRectangle") {
- // 画矩形(向量)
- int x = doc["data"][i]["x"].as<long>();
- int y = doc["data"][i]["y"].as<long>();
- int w = doc["data"][i]["w"].as<long>();
- int h = doc["data"][i]["h"].as<long>();
- String color_name = doc["data"][i]["color"];
- Serial.println(formatString("dRectangle: (x,y)=(%d,%d) (w,h)=(%d,%d) color=%s", x, y, w, h, color_name.c_str()));
- uint16_t color = get_color(color_name);
- myScreen.dRectangle(x + x_offset, y + y_offset, w, h, color);
- } else {
- Serial.println(formatString("type: %s", type));
- }
- }
- myScreen.flush();
- }
- }
- } else {
- Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
- }
-
- http.end();
- } else {
- Serial.println("[HTTP} Unable to connect");
- }
- }
- }
-
- void setup() {
- pinMode(LED_BUILTIN, OUTPUT);
- Serial.begin(115200);
- // Serial.setDebugOutput(true);
-
- Serial.println();
- Serial.println();
- Serial.println();
-
- for (uint8_t t = 4; t > 0; t--) {
- Serial.printf("[SETUP] WAIT %d...\n", t);
- Serial.flush();
- delay(1000);
- }
-
- status = true;
- digitalWrite(LED_BUILTIN, status);
- WiFiMulti.addAP(ssid, pass);
- Serial.print("WiFi is connecting: ");
- while ((WiFiMulti.run() != WL_CONNECTED)) {
- Serial.print(".");
- Serial.flush();
- delay(100);
- digitalWrite(LED_BUILTIN, status);
- status = !status;
- }
- Serial.println(" OK!");
- status = false;
- digitalWrite(LED_BUILTIN, status);
-
- Serial.println("begin... ");
- myScreen.begin();
- Serial.println(formatString("%s %ix%i", myScreen.WhoAmI().c_str(), myScreen.screenSizeX(), myScreen.screenSizeY()));
-
- Serial.println("request json and display... ");
- status = true;
- digitalWrite(LED_BUILTIN, status);
- myScreen.clear();
- request_json_and_display();
- status = false;
- digitalWrite(LED_BUILTIN, status);
-
- Serial.println("=== ");
- Serial.println();
- }
-
- void loop() {
- if (BOOTSEL) {
- status = true;
- digitalWrite(LED_BUILTIN, status);
-
- Serial.printf("\a\aYou pressed BOOTSEL!\n");
- // Wait for BOOTSEL to be released
- while (BOOTSEL) {
- delay(1);
- }
- status = false;
- digitalWrite(LED_BUILTIN, status);
- delay(500);
-
- status = true;
- digitalWrite(LED_BUILTIN, status);
- myScreen.clear();
- request_json_and_display();
- status = false;
- digitalWrite(LED_BUILTIN, status);
- }
- delay(1000);
- }
复制代码
4. 最终效果:
如果觉得显示的效果不好,例如位置不对等,可以在json配置文件中修改,然后按一下BOOTSEL按键,就能自动调用最新版本,然后刷新显示了。
十一、后续优化
后续的工作,就要简单多了,主要是如下的工作:
1. 睡眠模式:显示完成后,直接进入睡眠模式,定时唤醒。因为使用的是电子墨水屏,不供电也能继续显示,所以显示完,就可以睡眠了。
2. python服务端提供每日老黄历json文件
|