我们将分步进行,从硬件连接到 Python 代码,并实现一个实时显示电脑时间的功能。

项目概述
我们将使用:
- 硬件:
- Arduino (如 Arduino Uno)
- MAX7219 驱动芯片(这是关键,因为它能简化控制,并支持级联)
- 8x8 LED 点阵模块
- 杜邦线若干
- 软件:
- Arduino IDE
- Python 3
- Python 库:
pyserial(用于 Arduino 通信),pyserial的安装命令是pip install pyserial。
第一步:硬件连接
MAX7219 芯片通过 SPI 协议与 Arduino 通信,只需要 4 根线,非常方便。
点阵模块引脚 -> Arduino 引脚:
- VCC -> 5V
- GND -> GND
- DIN (Data In) -> D11 (Arduino 的 MOSI 引脚)
- CS (Load) -> D10 (Arduino 的 SS/CS 引脚)
- CLK (Clock) -> D13 (Arduino 的 SCK 引脚)
接线图:

[ 8x8 点阵模块 ]
VCC -----> Arduino 5V
GND -----> Arduino GND
DIN -----> Arduino D11 (MOSI)
CS -----> Arduino D10 (SS/CS)
CLK -----> Arduino D13 (SCK)
连接好后,将 Arduino 通过 USB 线连接到电脑。
第二步:Arduino 端编程 (固件)
Arduino 的任务是接收来自 Python 的指令,并将其显示在点阵上,我们将使用一个流行的库 LedControl 来简化 MAX7219 的编程。
-
安装 LedControl 库:
- 打开 Arduino IDE。
- 点击
项目->加载库->管理库...。 - 在搜索框中输入
LedControl。 - 找到
LedControl by Eberhard Fahle,点击安装。
-
编写 Arduino 代码:
(图片来源网络,侵删)这段代码会初始化 MAX7219,然后通过串口不断接收数据,Python 会发送一个 8 字节的数据,每个字节代表点阵的一行。
// 引入 LedControl 库 #include <LedControl.h> // 定义引脚 // Din = 数据引脚, Clk = 时钟引脚, Cs = 片选引脚 #define DIN 11 #define CLK 13 #define CS 10 // 创建 LedControl 对象 // 我们只控制一个点阵模块,所以参数是 1 // 参数分别是: 数据引脚, 时钟引脚, 片选引脚, 模块数量 LedControl lc = LedControl(DIN, CLK, CS, 1); void setup() { // 初始化串口通信,波特率必须与 Python 端一致 Serial.begin(9600); // MAX7219 初始化 // lc.shutdown(0, false); // 0 表示第一个模块,false 表示正常工作模式(非省电) // lc.setIntensity(0, 8); // 设置亮度 (0-15) // lc.clearDisplay(0); // 清空显示 // 更简洁的初始化方式 lc.shutdown(0, false); // 启动设备 lc.setIntensity(0, 8); // 设置亮度 (0-15) lc.clearDisplay(0); // 清空显示 Serial.println("MAX7219 is ready!"); } void loop() { // 检查串口是否有数据 if (Serial.available() >= 8) { // 创建一个 8 字节的数组来存储接收到的数据 byte rows[8]; // 读取 8 个字节 for (int i = 0; i < 8; i++) { rows[i] = Serial.read(); } // 将接收到的数据写入点阵的每一行 for (int i = 0; i < 8; i++) { lc.setRow(0, i, rows[i]); } } } -
上传代码:
- 在 Arduino IDE 中选择正确的开发板和端口。
- 点击“上传”按钮。
上传成功后,打开串口监视器(工具 -> 串口监视器),你应该会看到 "MAX7219 is ready!" 的消息,此时点阵是熄灭的。
第三步:Python 端编程 (控制端)
Python 将负责生成要显示的内容(比如文字、时间),然后通过串口发送给 Arduino。
-
安装
pyserial库:- 打开终端或命令提示符,运行:
pip install pyserial
- 打开终端或命令提示符,运行:
-
编写 Python 代码:
我们将创建一个脚本来显示 "HELLO" 和当前时间。
import serial import time import datetime # --- 配置 --- # 找到你的 Arduino 的串口 # 在 Windows 上可能是 'COM3', 'COM4' 等 # 在 macOS 或 Linux 上可能是 '/dev/tty.usbserial-XXXX' 或 '/dev/ttyACM0' # 你可以在 Arduino IDE 的串口监视器中查看 ARDUINO_PORT = 'COM3' # !!! 请务必修改成你的端口 !!! BAUD_RATE = 9600 # --- 定义字符 --- # 这是一个简单的 8x8 字符集 (0=灭, 1=亮) # 每个字符由 8 个字节组成,每个字节代表一行 CHAR_MAP = { 'H': [ 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b11111111, 0b00100000, 0b00100000, 0b00100000, ], 'E': [ 0b11111111, 0b00100000, 0b00100000, 0b11111111, 0b11111111, 0b00100000, 0b00100000, 0b11111111, ], 'L': [ 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b00100000, 0b11111111, ], 'O': [ 0b00111100, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b00111100, ], # 添加更多字符... } def text_to_matrix(text): """将文本转换为点阵数据""" matrix = [] for char in text: if char in CHAR_MAP: matrix.extend(CHAR_MAP[char]) else: # 如果字符未定义,用空格代替 matrix.extend([0b00000000] * 8) return matrix def time_to_matrix(): """将当前时间 (HH:MM) 转换为点阵数据""" now = datetime.datetime.now() time_str = now.strftime("%H:%M") # 定义数字 0-9 的点阵 DIGIT_MAP = { '0': [0b00111100, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b00111100], '1': [0b00001000, 0b00011000, 0b00001000, 0b00001000, 0b00001000, 0b00001000, 0b00001000, 0b00111110], '2': [0b00111100, 0b01000010, 0b00000010, 0b00001100, 0b00110000, 0b01100000, 0b01000000, 0b01111110], '3': [0b00111100, 0b01000010, 0b00000010, 0b00001100, 0b00000010, 0b00000010, 0b01000010, 0b00111100], '4': [0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01111110, 0b00000010, 0b00000010, 0b00000010], '5': [0b01111110, 0b01000000, 0b01111110, 0b00000010, 0b00000010, 0b00000010, 0b01000010, 0b00111100], '6': [0b00111100, 0b01000000, 0b01111110, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b00111100], '7': [0b01111110, 0b00000010, 0b00000100, 0b00001000, 0b00010000, 0b00010000, 0b00010000, 0b00010000], '8': [0b00111100, 0b01000010, 0b01000010, 0b00111100, 0b01000010, 0b01000010, 0b01000010, 0b00111100], '9': [0b00111100, 0b01000010, 0b01000010, 0b00111110, 0b00000010, 0b00000010, 0b01000010, 0b00111100], ':': [0b00000000, 0b01000010, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b01000010, 0b00000000], } matrix = [] for char in time_str: if char in DIGIT_MAP: matrix.extend(DIGIT_MAP[char]) return matrix def main(): try: # 连接 Arduino ser = serial.Serial(ARDUINO_PORT, BAUD_RATE, timeout=1) print(f"成功连接到 {ARDUINO_PORT}") time.sleep(2) # 等待 Arduino 初始化 # 先显示 "HELLO" print("显示 'HELLO'...") hello_matrix = text_to_matrix("HELLO") ser.write(hello_matrix) time.sleep(5) # 循环显示时间 print("开始显示当前时间...") while True: time_matrix = time_to_matrix() ser.write(time_matrix) time.sleep(1) # 每秒更新一次 except serial.SerialException as e: print(f"无法连接到串口: {e}") print("请检查端口是否正确,以及 Arduino 是否已连接。") except KeyboardInterrupt: print("\n程序被用户中断。") finally: if 'ser' in locals() and ser.is_open: ser.close() print("串口已关闭。") if __name__ == "__main__": main() -
运行 Python 脚本:
- 最重要的一步: 修改代码中的
ARDUINO_PORT,使其与你电脑上的 Arduino 串口号一致。 - 在终端或命令提示符中,导航到你保存 Python 脚本的目录。
- 运行脚本:
python your_script_name.py
- 最重要的一步: 修改代码中的
预期效果:
- 点阵会先显示 "HELLO" 5 秒钟。
- 然后开始显示当前时间(
12:34),并且每秒钟更新一次。
进阶玩法与扩展
-
级联多个点阵:
- 你可以将多个 8x8 点阵模块连接在一起,形成一个更长的显示屏。
- 硬件连接: 将前一个模块的
DOUT(Data Out) 引脚连接到下一个模块的DIN(Data In) 引脚,其他引脚 (CS,CLK) 并联到 Arduino。 - Arduino 代码: 在
LedControl初始化时,将模块数量改为n(lc = LedControl(..., 3);表示3个模块),发送数据时,你需要发送8 * n个字节,lc.setRow()的第一个参数指定要操作的是第几个模块 (0, 1, 2...)。 - Python 代码: 生成矩阵数据时,要确保总长度是
8 * n。
-
显示滚动文字:
在 Python 端,你可以创建一个长条形的点阵数据,然后通过不断向左或向右移动数据并发送给 Arduino,来实现滚动效果。
-
更复杂的图形和动画:
你可以定义各种图形(如心形、箭头)的帧数据,然后在 Python 中按顺序发送这些帧,实现动画效果。
-
使用其他库:
- 对于 Python,还有更高级的库如
luma.led_matrix,它提供了更丰富的 API,可以简化图形绘制和动画的实现,但底层依然依赖于pyserial与 Arduino 通信。
- 对于 Python,还有更高级的库如
这个项目为你提供了一个坚实的基础,你可以在此基础上发挥创意,实现更多有趣的功能!
