项目设想
因为我住的宿舍楼光线较差,尤其是一到晚上,楼道里漆黑一片,虽然楼道内装了声控灯,但总觉得发出声音有些不好意思,因此晚上总是摸黑前行。于是有一次我十分尴尬的走错了寝室,这让我下定决心给我们的宿舍门做一些装饰:光感应灯。
我打算用3个LED(红、黄、绿各一个)结合Pico和光感应模块将门牌“511”照亮。
参考资料
材料清单及成本
树莓派Pico(以下简称:Pico)
https://3.cn/24w1Y-gh ¥16.8
2节5号电池盒
https://m.tb.cn/h.gMC3Lv3?tk=n7Lh3gOjHF2 ¥3.52/5 = ¥0.704
光感应模块
https://m.tb.cn/h.golCN8X?tk=5p9M3gOlumG ¥2.95
2节5号碱性电池
https://3.cn/24w3-aLa ¥8.8/5 = ¥1.76
3个LED
成本忽略不计
小电线
成本忽略不计
电路连接
Pico引脚分布图
Pico GPIO Layout.png
将LED与Pico连接
按照上面的引脚分布图,将红、黄、绿的LED分别与GP2、GP12、GP15连接。
连接光传感器
传感器模块的VCC脚接树莓派Pico的3V3
传感器模块的GND脚接树莓派Pic 的GND
传感器模块的AO脚接树莓派Pico的GP28
传感器模块的 DO 脚接树莓派Pico的GP27
代码实现
导入所需库并定义LED
1 2 3 4 5 6 import machineimport utimeledG = machine.Pin(15 , machine.Pin.OUT) ledY = machine.Pin(12 , machine.Pin.OUT) ledR = machine.Pin(2 , machine.Pin.OUT)
定义开灯/关灯函数
1 2 3 4 5 6 7 8 9 def lightOn (): ledG.on() ledY.on() ledR.on() def lightOff (): ledG.off() ledY.off() ledR.off()
定义光传感器(模拟信号、数字信号)
1 2 sensor_analog = machine.ADC(28 ) sensor_digital = machine.Pin(27 , machine.Pin.IN)
先编写如下程序进行测试:
1 2 3 4 5 6 7 8 9 import machineimport utime sensor_analog = machine.ADC(28 ) sensor_digital = machine.Pin(27 , machine.Pin.IN) while True : print ('Analog value: %d, Digital value: %d.' % (65535 - sensor_analog.read_u16(), 1 - sensor_digital.value())) utime.sleep(0.5 )
如下是开启我桌上台灯前后的输出结果。
1 2 3 4 5 6 7 8 9 Analog value: 41786, Digital value: 1. Analog value: 41930, Digital value: 1. Analog value: 41674, Digital value: 1. Analog value: 41706, Digital value: 1. Analog value: 47035, Digital value: 1. Analog value: 57454, Digital value: 1. Analog value: 57422, Digital value: 1. Analog value: 57454, Digital value: 1. Analog value: 57358, Digital value: 1.
定义阈值并编写测量函数
如上所示,将测试用阈值暂定为50000,即模拟信号值大于50000时,开启LED;反之,则不开启。
1 2 3 4 5 6 7 8 9 10 11 12 threshold = 50000 def testing (threshold ): sensor_analog = machine.ADC(28 ) sensor_digital = machine.Pin(27 , machine.Pin.IN) print ('Analog value: %d, Digital value: %d.' % (65535 - sensor_analog.read_u16(), 1 - sensor_digital.value())) if 65535 - sensor_analog.read_u16() >= threshold: return True else : return False
开/关灯逻辑实现
1 2 3 4 5 6 while True : utime.sleep(0.1 ) if testing(threshold): lightOff() else : lightOn()
实地测量获取数据
如上的阈值是用于桌上判断台灯开启与否的,与实际需求(见“项目设想”)必然存在一定差异,因此我们必须再做更多实地测量获取可用的阈值。
但把电脑搬到外面去似乎不太合适(主要也是不方便),于是我们需要自动启动程序并将测量值记录下来。
编写测量程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import machineimport utime sensor_analog = machine.ADC(28 ) sensor_digital = machine.Pin(27 , machine.Pin.IN) with open ('dataLogger.txt' , 'a' ) as f: f.write('\n' ) while True : with open ('dataLogger.txt' , 'a' ) as f: f.write('Analog value: %d, Digital value: %d.\n' % (65535 - sensor_analog.read_u16(), 1 - sensor_digital.value())) utime.sleep(0.5 )
Pico自动运行程序
将如上程序保存为main.py。按下CTRL +D ,这样Thonny 就能将Pico激活。
这样,就可以带上充电宝(和USB A2B数据线),来到宿舍门外试验啦!
测量日志:
2024/9/4
14:35(这时天很亮,楼道里也能勉强看清)宿舍门前的声控灯开启与否的阈值约为30000。
2024/9/4 21:21 阈值约为18000。
综上,我决定采用18000作为最终阈值。
附:记录日志
14:35
23:21
完整代码
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 import machineimport utimeportG = 15 portY = 12 portR = 2 ledG = machine.Pin(portG, machine.Pin.OUT) ledY = machine.Pin(portY, machine.Pin.OUT) ledR = machine.Pin(portR, machine.Pin.OUT) threshold = 18000 def lightOn (): ledG.on() ledY.on() ledR.on() def lightOff (): ledG.off() ledY.off() ledR.off() def testing (threshold ): sensor_analog = machine.ADC(28 ) sensor_digital = machine.Pin(27 , machine.Pin.IN) print ('Analog value: %d, Digital value: %d.' % (65535 - sensor_analog.read_u16(), 1 - sensor_digital.value())) if 65535 - sensor_analog.read_u16() >= threshold: return True else : return False while True : utime.sleep(0.1 ) if testing(threshold): lightOff() else : lightOn()
记得将上述代码保存为main.py!
使用电池供电
目前为止,我们都是采用Pico上的micro
USB接口为其供电。但我们不可能专门为这个光感应灯配备一个充电宝,这样成本太高了,因此最佳方案是使用干电池为其供电。(当然也可以选用带micro
USB口的电池盒,但这个方案被pass掉的原因同样是成本较高)
根据树莓派官网的信息,Pico的安全供电电压介于1.8V和5.5V之间,因此我们选用2节干电池,提供3V的工作电压。
将电池盒的正、负极分别接在Pico的VSYS口、GND口。
形成产品
为了能让我们的光感应灯长久的贴于寝室门上,我们需要一个外壳。我手头刚好有一个惠普鼠标的纸壳,便用它作为产品外壳。
首先大致测量数字5 1
1之间的长度,以确定LED的位置,随后,用小刀之类的工具在其上钻三个孔用于将灯泡置于壳外。
接着,在纸壳的下部,钻一个方形的孔,用于放置光感应模块。
实物图:
实物图2.jpg
实物图1.jpg