树莓派驱动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(),避免程序退出数码管依然显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# !/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()

运行结果

效果如下:

效果图

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