Category Archives: 软硬兼施

Hello World 软硬兼施

使用树莓派驱动超声测距模块

这里用的模块,是SRF04超声测距模块,淘宝上买的,10块钱,加八块运费

测距的时序图如下:

想给触发信号trig一个约10us的高电平,模块会发送测距信号,回响信号echo会输出一个高电平,高电平的次序时间,与检测距离成正比,这就是该模块超声定位的基本原理
先面是相关的pytho代码

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
#srf04.py coding:utf-8 srf04超声测距模块驱动
import RPi.GPIO as GPIO
import time
from time import ctime, sleep
 
__gproTrig = 16    trig
__gproEcho = 12    echo
#初始化输入、输出gpio口
def init():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(__gproTrig, GPIO.OUT)
    GPIO.setup(__gproEcho, GPIO.IN)
 
def measure():
    #确保启动前为低电平
    GPIO.output(__gproTrig, False)
    time.sleep(0.0001)
    #启动测距
    GPIO.output(__gproTrig, True)
    time.sleep(0.00001) #10us
    GPIO.output(__gproTrig, False)
    #开始记时
    start   = 0
    stop    = 0
   #         print("measure--1")
    while start == 0 or stop == 0:
        val     = GPIO.input(__gproEcho)
        if stop == 0 and start == 0 and val == 1:
   #         print("measure--2")
            start = time.time()
        if start > 0 and stop == 0 and val == 0:
      #      print("measure--3")
            stop = time.time()
    #根据驱动公式计算测距结果
    elapsed = stop - start
    distance = (elapsed * 34300)/2
    return distance
 
if __name__ == '__main__':
    init()
    for i in range(300)://五分钟测试
     #   print("srf05-start:", i)
        dis = measure()
        print('--------------dis:', dis)
        sleep(1)

over~
~~~~~~后记
其实这个超声模块已经到手很久了,但是看到驱动要使用10us信号后,就一直纠结怎么来做10us的时钟,测试用python的sleep实现时钟,又特别不精确,那么,就需要100MHz的晶振,可晶振怎么接到树莓派上。。。于是就卡到这里了。
后来偶然搜到了类似模块的驱动方式,才发现其实是我想多了,要什么晶振,sleep足够了~~~嘿嘿,照着这种思路做下去,居然真的成功了
很多事情就是这样:先有一个大概的思路,没有更好地办法的情况下,就先照着这个思路走,大部分时候都能走的过去

——本文为原创,转载请注明出处 昆仑的山头

Hello World 软硬兼施

树莓派GPIO使用练习–点亮LED点阵

这里只是为了练习GPIO的使用,没有加任何的译码设备,也没加任何的放大设备,直接用树莓派的16个gpio引脚,连接一个8*8LED点阵的16个引脚,考虑到树莓派所能提供的电流不能太大,所以统一在点阵的8个阳极各加了一个1kΩ的电阻

8*8电阻的16个引脚,8个阳极,8个阴极,我们可以第一为R1~R8、C1~C8(考虑到点阵是方形的,所以不去区分行列,只区分阴阳,上面的R/C和“阴/阳”的对应关系,请根据实际共阴还是共阳区分清楚)

当我们给R1/C1两个管脚上电时(即在树莓派中,将R1对应的GPIO口拉到高电平,C1拉到低电平),第一行、第一列的这个点就会亮起来,同理,给R3/C5上电,[3, 5]的这个点会连起来

于是,我们可以通过这种方式依次点亮所有的点
。。。

于是,问题来了

如果我想同时点亮[3, 5]/[3, 6]/[4, 6]三个点,就需要同时拉高C3/C4,拉低R5/R6,可是,如果我做了这个操作,[4, 5]这个点也会亮起。。。这怎么办哪?

答案时,依次先点亮[3, 5]/[3, 6],熄灭这两个点,再点亮[4, 6],。。。熄灭[4, 6],点亮[3, 5]/[3, 6],如此往复,当这种切换的频率足够高时,由于认得视觉暂留,看到这三个点就是同时亮起的,也就是说,同一时刻,自会有单独一行、或者一列有点在发光

呵呵,很熟悉吧,电影、大屁股显示器什么的,和这个原理类似

好的,明白了原理,就可以动手写程序吧

这里使用树莓派最主流的编程语言:python,显示的东西,是“Hello word”,左右移动显示

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
import RPi.GPIO as GPIO  #导入必要的python库
import time
 
#Hello World 字模
vhws = [
  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0],
]
 
#左移还是右移
isRig = 1
vhwi = 0
#此函数返回当前时间点当前帧需要显示的8*8数组
def hwv():
  global isRig
  global vhwi
  l = len(vhws[0])
  if isRig > 0:
    vhwi += 1
  else:
    vhwi -= 1
  if vhwi >= (l - 8):
    isRig = 0
  if vhwi  0):
    if timeLine % 10 == 0:
      nowV = hwv()
    #双层循环实现的扫描显示  
    for i in range(0, len(nowV)):
      allOver()
      #拉低所有阴极
      GPIO.output(rs[i], GPIO.LOW)
      for j in range(0, len(nowV[i])):
        if nowV[i][j] > 0:
          GPIO.output(cs[j], GPIO.HIGH) #点亮这个点
        else:
          GPIO.output(cs[j], GPIO.LOW)  #不点亮
        time.sleep(sleepTime)
    timeLine = timeLine - 1
  return
#ledtest 17 27 22 5 6 13 19 26 18 23 24 25 12 16 20 21
#这里是管脚对应关系
rs = [21, 20, 16, 12, 25, 24, 23, 18] #R1:13 R2:3 R3:4 R4:10 R5:6 R6:11 R7:15 R8:16
cs = [26, 19, 13, 6, 5, 22, 27, 17] #C1:5 C2:2 C3:7 C4:1 C5:12 C6:8 C7:14 C8:9
#开始
def startVs():
  GPIO.setmode(GPIO.BCM)
  for i in xrange(8):
    GPIO.setup(cs[i], GPIO.OUT)
    GPIO.setup(rs[i], GPIO.OUT)
  allOver()
  return
#关闭
def stopVs():
  GPIO.cleanup()
  return
#将所有管脚置为反响,即熄灭所有
def allOver():
  for i in xrange(8):
    GPIO.output(cs[i], GPIO.LOW)
    GPIO.output(rs[i], GPIO.HIGH)
  return
 
#timeLine = 1000
frames = 60
#显示一个8*8数组
def viewArr():
  timeLine = 1000
  sleepTime = 0.0001 #1 / (frames * 8)
  while(timeLine > 0):
    if timeLine % 10 == 0:
      nowV = hwv()
    for i in range(0, len(nowV)):
      allOver()#每次点亮前,先熄灭所有
      GPIO.output(rs[i], GPIO.LOW)
      for j in range(0, len(nowV[i])):
        if nowV[i][j] > 0:
          GPIO.output(cs[j], GPIO.HIGH)  #点亮
        else:
          GPIO.output(cs[j], GPIO.LOW)   #不点亮
        time.sleep(sleepTime)  #扫屏的时延
  timeLine = timeLine - 1   #显示时常控制
return
 
if __name__ == '__main__':
  startVs()
  viewArr()
  stopVs()

下面是实际效果的几个截图:

下面两个是线路连接:

转载请注明出处:昆仑的山头