树莓派驱动4位数码管

听歌:宇宙を見上げて (动画《比宇宙更远的地方》插入曲)

经过上个周末以及元旦一天的努力,手里的web项目也过半了,于是陆续准备了许多材料打算开始做基于树莓派和OpenCV的自主寻迹小车。正好今天周六数码显示管到了,于是想先摸索着点亮看看,之前也没搞过。往上资料不是很详细,花了两三个小时才搞明白,记录一下备忘。


硬件

  • 树莓派(3b+)
  • 4位数码显示管
  • T型扩展板(非必需)
  • 12根母对母杜邦线

原理

树莓派控制3641BS数码管显示数字

元件电路图:

4位数码管电路原理图

我自己买的共阴极的。

引脚:

引脚图

引脚编号从下往上,从左往右然后再从右往左。

其中 12 号引脚控制第一个数字的显示,然后 9 -> 2,8 -> 3,6 -> 4。

接线

在接线这儿犹豫了一会儿,因为担心接线接错了可能会直接烧毁数码显示器和树莓派,往上也没有找到详细的线路图。后来看了电路图后直接将所有引脚用母对母杜邦线接到了GPIO口。接完了了之后只测试了一个数字的显示,确认显示正常值后才开始写代码。

在我的3b+ T型扩展板上(用的BCM编码方式),连线是这样的:

树莓派引脚(BCM) 数码显示器引脚
G18 11
G19 7
G20 4
G21 2
G22 1
G23 10
G24 5
G25 3
G13 12
G16 9
G17 8
G26 6

显示当前时间的代码

代码是从这里搬过来的,但是我把时间改成了小时+分钟的形式,然后这段代码有些bug,做了一些修改。

树莓派控制3641BS数码管显示数字

最后修正后的代码如下,将高电位和低电位进行了反转;在Ln157到Ln176行增加了显示1, 2, 3, 4其中一个数字的时候,将其他三个数字选择置于高电平,是高电位哦;在程序退出时增加了RPi.GPIO.cleanup(),避免程序退出数码管依然显示。

# !/usr/bin/bin/env python
# coding:utf-8


import RPi.GPIO as GPIO
import time


# mapping LED to GPIO
LED_A = 18 # 11
LED_B = 19 # 7
LED_C = 20 # 4
LED_D = 21 # 2
LED_E = 22 # 1
LED_F = 23 # 10
LED_G = 24 # 5
LED_DP = 25 # 3
 
# mapping public GPIO
DIGIT1 = 13 # 12
DIGIT2 = 16 # 9
DIGIT3 = 17 # 8
DIGIT4 = 26 # 6
 
#sleep time - loop displey
t=0.001
 
GPIO.setmode(GPIO.BCM)
 
GPIO.setup(LED_A, GPIO.OUT)
GPIO.setup(LED_B, GPIO.OUT)
GPIO.setup(LED_C, GPIO.OUT)
GPIO.setup(LED_D, GPIO.OUT)
GPIO.setup(LED_E, GPIO.OUT)
GPIO.setup(LED_F, GPIO.OUT)
GPIO.setup(LED_G, GPIO.OUT)
GPIO.setup(LED_DP, GPIO.OUT)
GPIO.setup(DIGIT1, GPIO.OUT)
GPIO.setup(DIGIT2, GPIO.OUT)
GPIO.setup(DIGIT3, GPIO.OUT)
GPIO.setup(DIGIT4, GPIO.OUT)
 
GPIO.output(DIGIT1, True)
GPIO.output(DIGIT2, True)
GPIO.output(DIGIT3, True)
GPIO.output(DIGIT4, True)
 
 
def showDigit(no, num, showDotPoint=False):

    GPIO.setup(LED_A, False)
    GPIO.setup(LED_B, False)
    GPIO.setup(LED_C, False)
    GPIO.setup(LED_D, False)
    GPIO.setup(LED_E, False)
    GPIO.setup(LED_F, False)
    GPIO.setup(LED_G, False)
    GPIO.setup(LED_DP, False)


    GPIO.output(DIGIT1, False)
    GPIO.output(DIGIT2, False)
    GPIO.output(DIGIT3, False)
    GPIO.output(DIGIT4, False)
 
    if (num == 0) :
        GPIO.output(LED_A, True)
        GPIO.output(LED_B, True)
        GPIO.output(LED_C, True)
        GPIO.output(LED_D, True)
        GPIO.output(LED_E, True)
        GPIO.output(LED_F, True)
        GPIO.output(LED_G, False)
        GPIO.output(LED_DP, showDotPoint)
    elif (num == 1) :
        GPIO.output(LED_A, False)
        GPIO.output(LED_B, True)
        GPIO.output(LED_C, True)
        GPIO.output(LED_D, False)
        GPIO.output(LED_E, False)
        GPIO.output(LED_F, False)
        GPIO.output(LED_G, False)
        GPIO.output(LED_DP, showDotPoint)
    elif (num == 2) :
        GPIO.output(LED_A, True)
        GPIO.output(LED_B, True)
        GPIO.output(LED_C, False)
        GPIO.output(LED_D, True)
        GPIO.output(LED_E, True)
        GPIO.output(LED_F, False)
        GPIO.output(LED_G, True)
        GPIO.output(LED_DP, showDotPoint)
    elif (num == 3) :
        GPIO.output(LED_A, True)
        GPIO.output(LED_B, True)
        GPIO.output(LED_C, True)
        GPIO.output(LED_D, True)
        GPIO.output(LED_E, False)
        GPIO.output(LED_F, False)
        GPIO.output(LED_G, True)
        GPIO.output(LED_DP, showDotPoint)
    elif (num == 4) :
        GPIO.output(LED_A, False)
        GPIO.output(LED_B, True)
        GPIO.output(LED_C, True)
        GPIO.output(LED_D, False)
        GPIO.output(LED_E, False)
        GPIO.output(LED_F, True)
        GPIO.output(LED_G, True)
        GPIO.output(LED_DP, showDotPoint)
    elif (num == 5) :
        GPIO.output(LED_A, True)
        GPIO.output(LED_B, False)
        GPIO.output(LED_C, True)
        GPIO.output(LED_D, True)
        GPIO.output(LED_E, False)
        GPIO.output(LED_F, True)
        GPIO.output(LED_G, True)
        GPIO.output(LED_DP, showDotPoint)
    elif (num == 6) :
        GPIO.output(LED_A, True)
        GPIO.output(LED_B, False)
        GPIO.output(LED_C, True)
        GPIO.output(LED_D, True)
        GPIO.output(LED_E, True)
        GPIO.output(LED_F, True)
        GPIO.output(LED_G, True)
        GPIO.output(LED_DP, showDotPoint)
    elif (num == 7) :
        GPIO.output(LED_A, True)
        GPIO.output(LED_B, True)
        GPIO.output(LED_C, True)
        GPIO.output(LED_D, False)
        GPIO.output(LED_E, False)
        GPIO.output(LED_F, False)
        GPIO.output(LED_G, False)
        GPIO.output(LED_DP, showDotPoint)
    elif (num == 8) :
        GPIO.output(LED_A, True)
        GPIO.output(LED_B, True)
        GPIO.output(LED_C, True)
        GPIO.output(LED_D, True)
        GPIO.output(LED_E, True)
        GPIO.output(LED_F, True)
        GPIO.output(LED_G, True)
        GPIO.output(LED_DP, showDotPoint)
    elif (num == 9) :
        GPIO.output(LED_A, True)
        GPIO.output(LED_B, True)
        GPIO.output(LED_C, True)
        GPIO.output(LED_D, True)
        GPIO.output(LED_E, False)
        GPIO.output(LED_F, True)
        GPIO.output(LED_G, True)
        GPIO.output(LED_DP, showDotPoint)
 
    if (no == 1) :
        GPIO.output(DIGIT1, False)
        GPIO.output(DIGIT2, True)
        GPIO.output(DIGIT3, True)
        GPIO.output(DIGIT4, True)
    elif (no == 2) :
        GPIO.output(DIGIT1, True)
        GPIO.output(DIGIT2, False)
        GPIO.output(DIGIT3, True)
        GPIO.output(DIGIT4, True)
    elif (no == 3) :
        GPIO.output(DIGIT1, True)
        GPIO.output(DIGIT2, True)
        GPIO.output(DIGIT3, False)
        GPIO.output(DIGIT4, True)
    else :
        GPIO.output(DIGIT1, True)
        GPIO.output(DIGIT2, True)
        GPIO.output(DIGIT3, True)
        GPIO.output(DIGIT4, False)
 
def display_time():
    while True:
        now = time.localtime(time.time())
        time.sleep(t)
        showDigit(1, int(time.strftime("%H", now)) / 10, False)
        time.sleep(t)
        showDigit(2, int(time.strftime("%H", now)) % 10, True)
        time.sleep(t)
        showDigit(3, int(time.strftime("%M", now)) / 10, False)
        time.sleep(t)
        showDigit(4, int(time.strftime("%M", now)) % 10, False)
try:
    display_time()
finally:
    GPIO.cleanup()

运行结果

效果如下:

效果图

可能是二极管余辉的原因?每个数字显示得都很不纯净,暂时先这样吧。