szjuliet 发表于 2020-8-24 17:06:39

ESP32电子墨水屏日历

## ESP32电子墨水屏日历


多年来,我一直在尝试打破实体日历和数字日历之间的障碍 - 创建可以挂在客厅/厨房中的美观电子墨水日历。现在这个想法以非常令人满意的方式实现了,我很想分享自己是如何实现它的。

日历能够显示特定用户在选定的Google日历中的前9个事件。我选了我太太、我自己和我们两个共同的家庭日历。除日历外,我还在日历的角上创建了一个微型天气,显示来自OpenWeather Maps的图标以及温度和风速。



该项目使用了7.5 Waveshare电子墨水屏、ESP32微控制器和LIPO电池。采用13x18宜家Ribba像框包装。除了微控制器的Arduino代码外,我还创建了一个脚本来从Google提取日历项。





归功于Git上的ESP32电子墨水气象站项目,在编写该项目时我从中学到了很多。

在此处找到该项目的代码:https://github.com/kristiantm/eink-family-calendar-esp32

感谢(https://www.instructables.com/member/ipsendk/)对instructable和代码进行了对错和完整性检查。

## **耗材:**

+ (https://www.waveshare.com/product/displays/e-paper/epaper-1/7.5inch-e-paper-hat.htm)屏幕(800×600版)〜76欧元。购买链接:(https://www.amazon.de/dp/B079JWLMND/ref=sspa_dk_detail_5?pd_rd_i=B07DFD6NY3&pd_rd_w=B1gEh&pf_rd_p=d3e24f85-c2f2-4959-bef4-3acc5e4e81dc&pd_rd_wg=mAaq5&pf_rd_r=5D2Y3ZPWX2453GGTH4P6&pd_rd_r=04973150-53aa-4f81-8b2c-f3a1a9564a34&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEzVldZVVg2UkkyNFMwJmVuY3J5cHRlZElkPUEwOTE0MjQxQkZMNENRRDAwV1lNJmVuY3J5cHRlZEFkSWQ9QTA4NDk0NzBDTDU5MkhDNkJIQzAmd2lkZ2V0TmFtZT1zcF9kZXRhaWwmYWN0aW9uPWNsaWNrUmVkaXJlY3QmZG9Ob3RMb2dDbGljaz10cnVl&th=1)(链接是黄色(C)的版本,我找不到红色(B)的版本了)
+ 在(https://www.aliexpress.com/item/32883116057.html?spm=2114.12010612.8148356.1.4643667b4ceNYz)上购买(https://docs.wemos.cc/en/latest/d32/d32_pro.html)〜8-9 美元 (我使用的是[老版本](https://www.amazon.de/-/en/gp/product/B07687C66W/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1),不过由于D32或D32 Pro在引脚35上集成了电池电量计,因此也可以用D32或D32 Pro)
+ (https://www.amazon.de/-/en/gp/product/B07R67NQ1N/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)上的1800 mAHLIPO电池 〜 13 欧元
+ IKEA Ribba 13x18框架 〜 3 欧元(宜家)

总费用:〜 100欧元

作为替代方案,(https://www.amazon.de/-/en/dp/B07M5CNP3B/)(可以避免接线)-但LOLIN32没有随附的电池插头,因此必须通过5V移动电源为其供电或自行接线连接到3V和GND连接器上。

## 步骤1 将屏幕连接到ESP32开发板



屏幕随附一根连接器电缆,可以将其直接连接到开发板上。但我发现占用了像框太多空间,决定使用自己的电线连接电路板。

**Waveshare 7.5 ↔LOLIN32**

Vcc ↔3V

GND ↔ GND

DIN ↔ 14

CLK ↔13

CS ↔ 15

DC ↔ 27

RST ↔ 26

BUSY ↔25

可以下载GxEPD2库来测试连接。如果使用的是Visual Studio Code,可以通过PlatformIO获取,也可以通过Arduino的库来获取。



要使用正确的引脚来初始化显示,在库中的示例中使用以下代码:

` GxEPD2_3C display(GxEPD2_750c_Z08(/*CS=*/ 15, /*DC=*/ 27, /*RST=*/ 26, /*BUSY=*/ 25));`

完成示例工作(在显示屏上获取演示文本/图形)后,继续进行下一步。

## 步骤2 从Google日历获取事件

Google的日历难以集成,我不得不通过Google脚本进行变通,使日历条目可访问。

在scripts.google.com上创建一个新的web应用来获得访问权限,然后将下面的代码粘贴到其中。

1. 转到scripts.google.com并选择新项目
2. 将下面代码粘贴到其中
3. 用一个“好”名字来保存
4。 点击“Publish”,然后选择“Anyone, even anonymous”作为安全设置
5. 在项目中根据需要复制链接"https://script.google.com/macros/s//exec"



注:获得链接的任何人都可以获得日历中公开的条目。但链接是唯一的且只有你自己拥有。我也喜欢其他关于集成的想法-但目前这个就可以用了。

将带有UNIQUE CODE的URL粘贴到浏览器中来测试脚本。应该看到用分号分隔的事件列表。在看到此之前,请不要进行下一步。

``` javascript
<p>function doGet(e) {</p><p>var calendars = CalendarApp.getAllCalendars();</p><p>
//var cal = CalendarApp.getCalendarsByName('NAME_OF_CALENDAR'); // 0 is subcalendar ID, mostly "0"
//var cal = CalendarApp.getDefaultCalendar();
var calendars = CalendarApp.getAllCalendars();

if (calendars == undefined) {
    Logger.log("No data");
    return ContentService.createTextOutput("no access to calendar hubba");
}</p><p>var calendars_selected = [];

for (var ii = 0; ii < calendars.length; ii++) {
    if (calendars.isSelected()) {
      calendars_selected.push(calendars);
      Logger.log(calendars.getName());
    }
}

Logger.log("Old: " + calendars.length + " New: " + calendars_selected.length);</p><p>const now = new Date();
var start = new Date(); start.setHours(0, 0, 0);// start at midnight
const oneday = 24*3600000; //
const stop = new Date(start.getTime() + 14 * oneday); //get appointments for the next 14 days

//var events = cal.getEvents(start, stop); //pull start/stop time
var events = mergeCalendarEvents(calendars_selected, start, stop); //pull start/stop time


var str = '';
for (var ii = 0; ii < events.length; ii++) {</p><p>    var event=events;   
    var myStatus = event.getMyStatus();
   
   
    // define valid entryStatus to populate array
    switch(myStatus) {
      case CalendarApp.GuestStatus.OWNER:
      case CalendarApp.GuestStatus.YES:
      case CalendarApp.GuestStatus.NO:
      case CalendarApp.GuestStatus.INVITED:
      case CalendarApp.GuestStatus.MAYBE:
      default:
      break;
    }
   
    // Show just every entry regardless of GuestStatus to also get events from shared calendars where you haven't set up the appointment on your own
    str += event.getStartTime() + ';' +
    //event.isAllDayEvent() + '\t' +
    //event.getPopupReminders() + '\t' +
    event.getTitle() +';' +
    event.isAllDayEvent() + ';';
}

return ContentService.createTextOutput(str);
}</p><p>function mergeCalendarEvents(calendars, startTime, endTime) {</p><p>var params = { start:startTime, end:endTime, uniqueIds:[] };</p><p>return calendars.map(toUniqueEvents_, params)
                  .reduce(toSingleArray_)
                  .sort(byStart_);
}</p><p>function toCalendars_(id) { return CalendarApp.getCalendarById(id); }</p><p>function toUniqueEvents_ (calendar) {
return calendar.getEvents(this.start, this.end)
               .filter(onlyUniqueEvents_, this.uniqueIds);
}</p><p>function onlyUniqueEvents_(event) {
var eventId = event.getId();
var uniqueEvent = this.indexOf(eventId) < 0;
if(uniqueEvent) this.push(eventId);
return uniqueEvent;
}</p><p>function toSingleArray_(a, b) { return a.concat(b) }</p><p>function byStart_(a, b) {
return a.getStartTime().getTime() - b.getStartTime().getTime();
}</p>
```

## 步骤3 配置项目

现在对ESP32开发板进行编程。

为此可以使用Visual Studio Code(带有Platform IO)或Arduino。

对于这两个平台,请下载代码其到自己的项目库中。

代码链接:https://github.com/kristiantm/eink-family-calendar-esp32

### **Platform IO:**

1. 确保已安装Platformio并作为工作区打开项目文件夹
2. 如果配置正确,PlatformIO应该自己获取所需的库。如果没有,则必须转到PlatformIO / Libraries并安装 "GxEPD2" 和 "ArduinoJson"

### **Arduino:**

1. 转到setting,并将"https://dl.espressif.com/dl/package_esp32_index.json" 粘贴到"Additional Boards manager URL"中

(译注:应为首选项Preferences,不是setting)

2. 转到Tools/Boards/Boards Manager(工具/主板/主板管理器)。搜索ESP32并安装开发板套件。
2. 选择WEMOS LOLIN32板(或你自己购买的板型号)
3. 转到库管理器并安装"GxEPD2" 和 "ArduinoJson"

从这里开始,你必须专注于调整credentials.h。

设置wifi上网ssid和密码

``` javascript
<p>// Change to your WiFi credentials<br>const char* ssid1   = "";      // For your network
const char* password1 = "";// For your network</p>
```

注册并获取OpenWeatherMaps.com的API:

``` javascript
// Use your own API key by signing up for a free developer account at <a href="https://openweathermap.org/" rel="nofollow">https://openweathermap.org/<br>String ><br>String OWMapikey       = "";<br>
```

更改你的位置信息来获取当地天气 - 谷歌地图是获取纬度和经度的好伙伴:

``` javascript
String City          = "Copenhagen";                      // Your home city See: <a href="http://bulk.openweathermap.org/sample/" rel="nofollow"> <a href="http://bulk.openweathermap.org/sample/" rel="nofollow"> http://bulk.openweathermap.org/sample/
</a>
</a>
String Lattitude          = "";                      // Your lattitude - use google maps
String Longitude          = "";                      // Your longitude - use google maps
String Country       = "Denmark";                            // Your country
String Language      = "EN";                            // NOTE: Only the weather description (not used) is translated by OWM
```

复制Google的webapp网址,获取你的个人事件:

``` javascript
char calendarServer[] = "script.google.com"; <br>String calendarRequest = "https://script.google.com/macros/s//exec"; // Write the path for your google script to fetch calendar events
```

剩下的部分你可以在第一次让它工作的时候继续。

现在单击compile“编译”,希望不会报任何错误。一切就绪后,使用Microusb线将LOLIN32板连接至计算机,并对板子进行编程。

如果一切顺利,约20秒后看到Waveshare面板刷新,显示接下来14天的活动以及当地天气。如果没有显示,尝试串行连接到LOLIN32板提供的COM端口(通过Windows中的设备管理器识别端口号)。可以使用类似PuTTY的程序连接到串行端口,并观察在什么地方链路断开了。

## 步骤4 启用电池电量测量

为避免电池完全放电,需要启用电池测量仪。

项目中的代码会读取电池的当前电压,并在屏幕上显示电池图标,显示满电量、3/4电量、1/2电量、1/4电量或电量耗尽。电量耗尽后,项目会进入永久性深度睡眠状态,直到再次充电。

如果主板是LOLIN D32,电池测量值已经内置在GPIO35引脚中-只需要在代码"uint8_t batteryPin = 35"中调整该引脚即可。

https://www.bilibili.com/video/av841845310?p=1


如果是普通的ESP32,则需要在电池和选定的模拟IO引脚之间插入一个分压器 - 使电池的3.7电压低于开发板能够测量的3V。

在我的设置中,我使用了30K和100K电阻器设置,并从引脚34读取。

https://v.qq.com/x/page/q314134nr3i.html


设置起来有点复杂,但如果没有设置,在忘记给电池充电时可能会耗尽电量并损坏电池。

## 步骤5 组装家庭日历



现在要做的就是将日历妥妥的组装在新的IKEA像框中。Ribba像框非常适合此类IOT项目,它的屏幕和背板之间有一个很大的封闭空间。



首先将墨水屏放在像框白色垫子的最上方,上下左右调整一下直到满意为止。

把与像框一起的纸放在屏幕的顶部,但引导屏幕连接器滑过像框的一侧。用白色塑料内框将其固定-用宽的一面在屏幕上施加轻微的压力。

将墨水屏连接主板,LOLIN板和电池粘在纸上,使其在连接后自然悬挂。

接通电池后,开发板将启动并刷新屏幕。此时对墨水屏的位置进行最终调整。

关上并固定像框的后盖。考虑加一条短的USB线为像框供电(如图所示,在后盖上切一个小孔)。充电周期为2-3个月。



### **你现在是自己独一无二电子墨水屏家庭日历的骄傲拥有者。**

> 原文链接:https://www.instructables.com/id/E-Ink-Family-Calendar-Using-ESP32/   
> 作者: kristiantm   
> 翻译:szjuliet
>

20060606 发表于 2020-8-26 06:41:54

这个屏幕得挺贵

unQAzcWF 发表于 2020-8-26 09:31:41

很时尚的屏幕,想自己做一个!

发表于 2020-8-26 21:14:22

不错的项目,我也想自己做一个!

DFHJtzlT1q8 发表于 2020-8-28 15:06:48

低调而不失内涵,不错。

gada888 发表于 2020-8-30 15:31:11

这屏很贵的

队长911 发表于 2020-9-9 12:57:43

查了一下造价,相当于人民币800元,就为了显示个日历,有点小贵.{:6_211:}
页: [1]
查看完整版本: ESP32电子墨水屏日历