工作电压:3.3V
- 按钮:2个
按钮A,占用树莓派的GPIO29和P40
按钮B,占用树莓派的GPIO28和P38
分辨率:250x122 (逻辑分辨率 250x128)
通信接口:SPI
显示颜色:黑白
灰度等级:2
刷新方式:完全刷新和部分刷新
刷新时间:全刷新需要3秒,部分刷新需要0.5秒
可视角度:>170°


树莓派5设置由于电子墨水屏通信方式为 SPI,所以树莓派5 需要使能SPI。
输入命令 sudo raspi-config 打开树莓派设置界面,进入选项 3 Interface Options,使能SPI。



(.venv) lintex9527@pi:~/workspace/eepw/elem_rpi5_contest/DFRobot_RPi_Eink_Display/examples $ python3 display_bitmap.py Traceback (most recent call last): File "/home/lintex9527/workspace/eepw/elem_rpi5_contest/DFRobot_RPi_Eink_Display/examples/display_bitmap.py", line 21, in <module> from DFRobot_RPi_Eink_Display import DFRobot_RPi_Eink_Display, THIS_BOARD_TYPE File "/home/lintex9527/workspace/eepw/elem_rpi5_contest/DFRobot_RPi_Eink_Display/DFRobot_RPi_Eink_Display.py", line 32, in <module> import RPi.GPIO as RPIGPIO ModuleNotFoundError: No module named 'RPi'
替代方案是使用 gpiozero 或者 lgpio。这里我选择了用 lgpio。
RPi.GPIO 报错的代码如下,在判定当前开发板为树莓派是,引入 RPi.GPIO 库,否则引入 mraa 库。




GPIO.__init__() 方法用 lgpio 重新实现




def bitmap_file(self, x, y, path):
"""!
@brief Draw a bitmap
@param x Starting x-coordinate of the bitmap
@param y Starting y-coordinate of the bitmap
@param path Bitmap file path
"""
try:
f = open(path, "rb")
except:
print("open file error")
return
c = bytearray(f.read())
f.close()
# 确定是否是有效的BMP文件(包含 'BM')
if c[0] != 0x42 and c[1] != 0x4d:
print("file error")
print(c[0])
print(c[1])
return
dib_offset = self._bytes_to_number(c[10:14])
width = self._bytes_to_number(c[18:22])
height = self._bytes_to_number(c[22:26])
color_bits = self._bytes_to_number(c[28:30])
compression = self._bytes_to_number(c[30:32])
# print("w: %d, h: %d, color_bits: %d" %(width, height, color_bits))
if color_bits == 24:
width3 = width * 3
for i in range(height):
self.start_draw_bitmap_file(x, y + height - i)
buf = []
left = dib_offset + i * width3
i = 0
while i < width3:
buf.append(c[left + i + 2])
buf.append(c[left + i + 1])
buf.append(c[left + i + 0])
i += 3
self.bitmap_file_helper(buf)
self.end_draw_bitmap_file()
elif color_bits == 1:
quads = self._get_quads(c, 2)
addr = dib_offset
if compression == self.BITMAP_COMPRESSION_NO:
addr_count_complement = (width // 8 + 1) % 4
if addr_count_complement != 0:
addr_count_complement = 4 - addr_count_complement
for i in range(height):
w = width
addr_count = 0
self.start_draw_bitmap_file(x, y + height - i - 1)
buf = []
while w > 0:
d = c[addr + addr_count]
addr_count = addr_count + 1
j = 8
while w > 0 and j > 0:
j -= 1
quad = d & (0x01 << j)
if quad > 0:
quad = 1
buf.append(quads[quad][2])
buf.append(quads[quad][1])
buf.append(quads[quad][0])
w -= 1
self.bitmap_file_helper(buf)
addr_count += addr_count_complement
addr += addr_count
self.end_draw_bitmap_file()
else:
print("dont support this bitmap file format yet") def bitmap_file(self, x, y, path):
"""!
@brief Draw a bitmap
@param x Starting x-coordinate of the bitmap
@param y Starting y-coordinate of the bitmap
@param path Bitmap file path
"""
try:
f = open(path, "rb")
except:
print("open file error")
return
c = bytearray(f.read())
f.close()
# 检查BMP文件签名
if c[0] != 0x42 or c[1] != 0x4d:
print("Not a valid BMP file")
return
# 读取BMP头信息
dib_offset = self._bytes_to_number(c[10:14])
width = self._bytes_to_number(c[18:22])
height = self._bytes_to_number(c[22:26])
color_bits = self._bytes_to_number(c[28:30])
compression = self._bytes_to_number(c[30:34])
if color_bits == 24:
self._draw_24bit_bmp(x, y, c, dib_offset, width, height)
# self._draw_24bit_bmp_optimized(x, y, c, dib_offset, width, height)
elif color_bits == 1:
self._draw_1bit_bmp(x, y, c, dib_offset, width, height, compression)
else:
print(f"Unsupported BMP format: {color_bits}-bit")
def _draw_24bit_bmp(self, x, y, file_data, data_offset, width, height):
"""处理24位BMP文件"""
# 计算每行的字节数(4字节对齐)
row_size = (width * 3 + 3) & ~3 # 对齐到4字节
self.start_draw_bitmap_file(x, y)
# BMP是从下到上存储的,需要反转
for row in range(height):
# 计算当前行在文件中的位置
row_pos = data_offset + (height - 1 - row) * row_size
buf = []
for col in range(width):
# 读取BGR像素
pixel_pos = row_pos + col * 3
blue = file_data[pixel_pos]
green = file_data[pixel_pos + 1]
red = file_data[pixel_pos + 2]
# 转换为灰度值来判断黑白
# 使用常见的灰度转换公式: 0.299*R + 0.587*G + 0.114*B
gray = int(0.299 * red + 0.587 * green + 0.114 * blue)
# 根据灰度值决定显示黑色还是白色
# 阈值可以调整,这里使用128作为中间值
if gray < 128:
buf.extend([0, 0, 0]) # 黑色
else:
buf.extend([255, 255, 255]) # 白色
self.bitmap_file_helper(buf)
self._bitmap_file_start_y += 1
self.end_draw_bitmap_file()
def _draw_1bit_bmp(self, x, y, file_data, data_offset, width, height, compression):
"""处理1位BMP文件(原有的逻辑)"""
quads = self._get_quads(file_data, 2)
addr = data_offset
if compression == self.BITMAP_COMPRESSION_NO:
row_size = ((width + 31) // 32) * 4 # 1位BMP的行对齐计算
for i in range(height):
w = width
self.start_draw_bitmap_file(x, y + height - i - 1)
buf = []
for byte_pos in range(row_size):
if w <= 0:
break
d = file_data[addr + byte_pos]
bits_remaining = min(8, w)
for bit in range(bits_remaining):
quad_index = (d >> (7 - bit)) & 0x01
buf.extend(quads[quad_index][:3]) # 只取RGB部分
w -= 1
self.bitmap_file_helper(buf)
addr += row_size
self.end_draw_bitmap_file()把任意一种图片转换为 24bit 深度的 BMP 图片就可以在电子墨水屏上显示,如下图所示:


我要赚赏金
