效果
1. 墨水屏
型号:微雪 2.9inch e-Paper Module, 带驱动板,8PIN
工作电压:3.3V/5V
通信接口:SPI
分辨率:296 x 128
显示颜色:黑、白
局部刷新:0.3s
全局刷新 :2s
接线表:
墨水屏 8PIN | 树莓派 40PIN 物理序号 | 备注 |
---|---|---|
VCC | 1 | 3.3V |
GND | 6 | GND |
DIN | 19 | |
CLK | 23 | |
CS | 24 | |
DC | 22 | |
RST | 11 | |
BUSY | 18 |
2. 树莓派基本配置
- 详细步骤见帮助文档: https://www.waveshare.net/wiki/2.9inch_e-Paper_Module
- 程序源码在 github 也有: https://github.com/waveshare/e-Paper
- 下载
git clone https://github.com/waveshare/e-Paper.git --depth 1
- 目录如下,有用的文件就几个:
├───Arduino
├───RaspberryPi&JetsonNano
│ ├───c
│ │ └─── ...
│ └───python
│ │ readme_rpi_CN.txt
│ │ setup.py
│ │ ...
│ │
│ ├───examples
│ │ epd_2in9bc_test.py # 测试程序
│ │ ...
│ │
│ ├───lib
│ │ └───waveshare_epd
│ │ epd2in9.py # 主逻辑
│ │ epdconfig.py # 配置文件
│ │ __init__.py
│ │ ...
│ │
│ └───pic
│ 2in9.bmp # 图片
│ Font.ttc # 字体文件,文泉驿,含中文字体
│ ...
└─── ...
- 运行测试程序
cd e-Paper/'RaspberryPi&JetsonNano'/
cd python/examples
sudo python3 epd_2in9bc_test.py
3. 处理 mnist 数据集,提取 index
下载
mnist.npz
https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz我们使用
x_train
的60000个数字,把0-9对应的序号(index),提取出来,保存到mnist_index.json
import numpy as np
import json
img_rows, img_cols = 28, 28
# the data, split between train and test sets
path = 'mnist.npz'
with np.load(path) as f:
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
print('x_train.shape: {}, y_train.shape: {}'.format(x_train.shape, y_train.shape))
print('x_test.shape: {}, y_test.shape: {}'.format(x_test.shape, y_test.shape))
print(x_train[0], y_train[0])
print(x_test[0], y_test[0])
# 创建一个字典,keys 是0-9,values为空的list,后面将序号存进去
idx_dict = {}
for i in range(10):
idx_dict[i] = []
print(idx_dict)
# 将序号存进去
for idx in range(60000):
num = y_train[idx]
idx_dict[num].append(idx)
# if idx == 60: break
# print(idx_dict)
# 转为 json 格式, 保存
idx_json = json.dumps(idx_dict)
# print(idx_json)
with open('mnist_index.json', 'w') as f:
json.dump(idx_dict, f)
# 读取 json 文件
# with open('mnist_index.json', 'r') as f:
# data = json.load(f)
# print(data)
4. 先测试下用 opencv 显示时间
import numpy as np
import json
import random
import cv2
import time
# load mnist dataset
path = 'mnist.npz'
with np.load(path) as f:
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
with open('mnist_index.json', 'r') as f:
idx_dict = json.load(f)
for i in range(10):
print(i, len(idx_dict[str(i)]))
def get_mnist_num(num):
idxs = idx_dict[str(num)]
idx = random.choice(idxs)
return x_train[idx]
gap = np.zeros((28, 10))
for i in [8, 9, 18, 19]:
for j in [4,5,6,]:
gap[i][j] = 255
last_time = [-1, -1, -1, -1, -1, -1]
last_imgs = np.zeros((6, 28, 28))
while True:
now = time.localtime(time.time())
sec, mnt, hour = now.tm_sec, now.tm_min, now.tm_hour
s1, s2 = sec//10, sec%10
m1, m2 = mnt//10, mnt%10
h1, h2 = hour//10, hour%10
now_time = [h1, h2, m1, m2, s1, s2]
print(last_time, now_time)
for i in range(6):
if last_time[i] != now_time[i]:
last_imgs[i] = get_mnist_num(now_time[i])
last_time[i] = now_time[i]
img = np.hstack((last_imgs[0], last_imgs[1], gap,
last_imgs[2], last_imgs[3], gap,
last_imgs[4], last_imgs[5]))
cv2.imshow('num', img)
# cv2.imwrite('mnist-clock.png', img)
cv2.waitKey(100)
5. 在墨水屏显示时间
详见 epd29_mnist_clock.py
# epd29_mnist_clock.py
import sys
import os
import logging
import json
import numpy as np
import random
import time
import traceback
from PIL import Image, ImageDraw, ImageFont
from lib import epd2in9
logging.basicConfig(level=logging.DEBUG)
font = ImageFont.truetype('lib/Font.ttc', 18)
# load mnist dataset
with np.load('mnist.npz') as f:
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
with open('mnist_index.json', 'r') as f:
idx_dict = json.load(f)
gap = np.ones((28, 10)) * 255
for i in [8, 9, 18, 19]:
for j in [4,5,6,]:
gap[i][j] = 0
def get_mnist_num(num):
idxs = idx_dict[str(num)]
idx = random.choice(idxs)
return 255 - x_train[idx]
# === 0. init
logging.info('epd2in9 Demo')
epd = epd2in9.EPD()
logging.info('init and Clear')
epd.init(epd.lut_full_update)
epd.Clear(0xFF)
# === 1. show date & time
logging.info('show date & time')
def YMD(draw, x1=10, y1=5, x2=160, y2=30):
draw.rectangle((x1, y1, x2, y2), fill=255)
draw.text((x1, y1), time.strftime('%Y-%m-%d %a'), font = font, fill=0)
def HMS(draw, x1=180, y1=5, x2=280, y2=30):
draw.rectangle((x1, y1, x2, y2), fill = 255)
draw.text((x1, y1), time.strftime('%H:%M'), font = font, fill=0)
def MNIST(img, draw, mnist_img, x1=8, y1=30, x2=280, y2=120):
draw.rectangle((x1, y1, x2, y2), fill = 255)
mnist_img = Image.fromarray(mnist_img)
mnist_img = mnist_img.resize((38*2*3, 28*3))
img.paste(mnist_img, (x1, y1))
# partial update
time_image = Image.new('1', (epd.height, epd.width), 255)
time_draw = ImageDraw.Draw(time_image)
last_time = [-1, -1, -1, -1]
last_imgs = np.ones((4, 28, 28)) * 255
while (True):
now = time.localtime(time.time())
sec, mnt, hour = now.tm_sec, now.tm_min, now.tm_hour
m1, m2 = mnt//10, mnt%10
h1, h2 = hour//10, hour%10
now_time = [h1, h2, m1, m2]
print(f'{hour}:{mnt}:{sec}', last_time, now_time)
if -1 in last_time or (mnt == 0 and sec < 5) :
logging.info('partial update')
epd.init(epd.lut_full_update)
epd.Clear(0xFF)
time.sleep(1)
logging.info('partial update')
epd.init(epd.lut_partial_update)
epd.Clear(0xFF)
YMD(time_draw)
time.sleep(1)
for i in range(4):
if last_time[i] != now_time[i]:
last_imgs[i] = get_mnist_num(now_time[i])
last_time[i] = now_time[i]
mnist_image = np.hstack((last_imgs[0], last_imgs[1], gap,
last_imgs[2], last_imgs[3]))
HMS(time_draw)
MNIST(time_image, time_draw, mnist_image)
epd.display(epd.getbuffer(time_image))
time.sleep(1)
time.sleep(3)
# Clear
logging.info('Clear...')
epd.init(epd.lut_full_update)
epd.Clear(0xFF)
# Sleep
logging.info('Goto Sleep...')
epd.sleep()
epd.Dev_exit()
所有的文件
把有用的几个文件拉出来放在一个文件夹里。
.
├── cv2_mnist_clock.py # 测试用 opencv 显示时间
├── epd29_mnist_clock.py # 在墨水屏显示时间
├── epd_2in9_test.py
├── lib
│ ├── epd2in9.py
│ ├── epdconfig.py
│ ├── Font.ttc
│ └── __init__.py
├── mnist_index_gen.py # 提取序号(index)
├── mnist_index.json # 保存序号(index),以 json 格式
└── mnist.npz # mnist 原始数据集
完整代码:
https://github.com/shenbo/mnist-clock
灵感
https://github.com/dheera/mnist-clock