杰瑞科技汇

Arduino与Python如何驱动点阵屏?

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

Arduino与Python如何驱动点阵屏?-图1
(图片来源网络,侵删)

项目概述

我们将使用:

  • 硬件:
    • 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 引脚)

接线图:

Arduino与Python如何驱动点阵屏?-图2
(图片来源网络,侵删)
      [ 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 的编程。

  1. 安装 LedControl 库:

    • 打开 Arduino IDE。
    • 点击 项目 -> 加载库 -> 管理库...
    • 在搜索框中输入 LedControl
    • 找到 LedControl by Eberhard Fahle,点击安装。
  2. 编写 Arduino 代码:

    Arduino与Python如何驱动点阵屏?-图3
    (图片来源网络,侵删)

    这段代码会初始化 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]);
        }
      }
    }
  3. 上传代码:

    • 在 Arduino IDE 中选择正确的开发板和端口。
    • 点击“上传”按钮。

上传成功后,打开串口监视器(工具 -> 串口监视器),你应该会看到 "MAX7219 is ready!" 的消息,此时点阵是熄灭的。


第三步:Python 端编程 (控制端)

Python 将负责生成要显示的内容(比如文字、时间),然后通过串口发送给 Arduino。

  1. 安装 pyserial 库:

    • 打开终端或命令提示符,运行:
      pip install pyserial
  2. 编写 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()
  3. 运行 Python 脚本:

    • 最重要的一步: 修改代码中的 ARDUINO_PORT,使其与你电脑上的 Arduino 串口号一致。
    • 在终端或命令提示符中,导航到你保存 Python 脚本的目录。
    • 运行脚本:
      python your_script_name.py

预期效果:

  • 点阵会先显示 "HELLO" 5 秒钟。
  • 然后开始显示当前时间(12:34),并且每秒钟更新一次。

进阶玩法与扩展

  1. 级联多个点阵:

    • 你可以将多个 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
  2. 显示滚动文字:

    在 Python 端,你可以创建一个长条形的点阵数据,然后通过不断向左或向右移动数据并发送给 Arduino,来实现滚动效果。

  3. 更复杂的图形和动画:

    你可以定义各种图形(如心形、箭头)的帧数据,然后在 Python 中按顺序发送这些帧,实现动画效果。

  4. 使用其他库:

    • 对于 Python,还有更高级的库如 luma.led_matrix,它提供了更丰富的 API,可以简化图形绘制和动画的实现,但底层依然依赖于 pyserial 与 Arduino 通信。

这个项目为你提供了一个坚实的基础,你可以在此基础上发挥创意,实现更多有趣的功能!

分享:
扫描分享到社交APP
上一篇
下一篇