树莓派模拟照相机拍照实验

    前几天实验了OpenCV的安装,今天尝试组合轻触开关传感器加上摄像头模拟照相机进行拍照实验;其中参考文章:
(1)轻触开关传感器实验:https://www.shumeijiang.com/2019/11/10/轻触开关传感器实验.html;
(2)OpenCV安装:https://www.shumeijiang.com/2021/12/12/树莓派安装opencv-python.html;
(3)由于在vnc里执行,参考vnc安装:https://www.shumeijiang.com/2021/05/06/树莓派安装vnc.html
组装效果:
    由上图可见,我们将树莓派放进盒子里面,然后轻触开关粘在盒子顶部,摄像头粘贴在盒子表面;当需要拍照时,只需要按压一次轻触开关即可。盒子里面如下图:
实验代码:

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

'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''

import cv2
import numpy as np
import RPi.GPIO as GPIO
import time
import random

#轻触开关
touchPin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(touchPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#注册事件
GPIO.add_event_detect(touchPin, GPIO.FALLING)

#开始
cap = cv2.VideoCapture(0)
try:
    while True:
        # get a frame
        ret, frame = cap.read()
        cv2.imshow("capture", frame)

        #拍照
        if GPIO.event_detected(touchPin):
            i = random.randint(0,100)
            name = 'sample'+str(i)+'.jpg'
            cv2.imwrite(name, frame)
            print('已拍照')
            continue

        time.sleep(0.5)
except KeyboardInterrupt:
    print('拍照结束')

cap.release()
cv2.destroyAllWindows()
    我们打开VNC然后进入树莓派桌面,打开自带的Linux终端,然后找到我们的代码,执行命令:

python jiujiang.py
    然后点击轻触开关传感器,就像拍照时按下快门,可见终端提示“已拍照”,然后同目录文件夹下可见生成一张图片;如此,多次点击可见多次拍照,生成多个照片。
 视频效果如下:

树莓派自制散热装置

    树莓派长时间启动运行时,会发现发热很严重;尤其是单板子放在桌子或其他物品上时,经常因为紧挨物品而无法很好散热;所以想了下自己弄了一个较好的散热装置用作参考。
    用到的物品如下:
材料:
(1)树莓派3b+;
(2)散热小风扇;
(3)散热铜柱10个(数量可自己调整);
(4)M3螺帽8个;
(5)M3*20螺丝两个;
(6)长度65雪糕片一个;
组装过程:
(1)两个铜柱组合,组个四组,目的提高离地间隙(根据自己需要);
(2)用螺丝组合雪糕片和散热小风扇;
(3)树莓派四个小孔扩大,此处用的直径4mm的钻头;
(4)组合好的铜柱分别安装到树莓派的四个孔,用作支撑角;效果如下:
(5)将组合好的散热小风扇,安装到树莓派尾部(TF卡端);
(6)小风扇的电源线连接树莓派,黑线接GND,红线接5V;
(7)树莓派开机,可见散热小风扇开始转动,给树莓派降温;
(8)组装完成,效果如下:
组装效果

树莓派安装OpenCV-Python

    OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上,包含树莓派基于Linux为内核的Debian系统。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
    其中OpenCV-Python是用于OpenCV的Python API,它是解决计算机视觉问题的Python专用库;接下来就尝试如何安装这个库。
    其中这次采用apt-get安装预构建安装包安装;首先确定要安装的Python版本,如果是Python2,则执行:

sudo apt-get install python-opencv
如果是Python3,则执行:

sudo apt-get install python3-opencv
执行过程如下图,可见会自动安装一系列依赖包,以及升级和建议安装:
执行成功后,执行:

import cv2
print(cv2.__version__)
如果没有报错,则表示安装成功:

键盘控制云台方向实验

    摄像头云台买了很久,今天才想起来尝试一下;时间有限,初步尝试用键盘操作一下云台四个方向操作;其中ad控制左右转动,ws控制前后转动;驱动板用的是pca9685。
    其中舵机驱动采用的是adafruit-circuitpython-pca9685,可以参考以前的文章:https://www.shumeijiang.com/2021/08/29/舵机的新驱动方式
组合效果:
代码示例:

#coding:utf-8

'''
from JiuJiang
树莓酱的操作实例
https:://www.shumeijiang.com
'''

import time
from board import SCL, SDA
import busio

from adafruit_pca9685 import PCA9685
from adafruit_motor import servo

#引入i2c
i2c = busio.I2C(SCL, SDA)

#实例化 此处是0x41 驱动板地址修改过导致
pca = PCA9685(i2c, address=0x40)  #地址可以修改  默认0x40
pca.frequency = 40

#左右
servo_0 = servo.Servo(pca.channels[0])
servo_0.set_pulse_width_range(min_pulse=500, max_pulse=2500)
base_0 = 60

#前后
servo_1 = servo.Servo(pca.channels[1])
servo_1.set_pulse_width_range(min_pulse=500, max_pulse=2500)
base_1 = 80

while True:
    code = input('方向是?')
    angle_n = 10
    if base_0+angle_n >= 180:
        continue
    if base_1+angle_n >= 180:
        continue
    if base_0 <= angle_n:
        continue
    if base_1 <= angle_n:
        continue

    if code == 'a':
        base_0 = base_0 - angle_n
    elif code == 'd':
        base_0 = base_0 + angle_n
    elif code == 'w':
        base_1 = base_1 + angle_n
    elif code == 's':
        base_1 = base_1 - angle_n

    servo_0.angle = base_0
    servo_1.angle = base_1
    time.sleep(0.2)
pca.deinit()
执行效果:

手柄遥控四驱小车实验

    前面曾实验过四驱小车,以及如何获取ps4手柄数据,今天想想如何尝试两者结合起来,用ps4手柄操作四驱小车实现四向行走;以前文章参考:
1、ps4手柄蓝牙连接树莓派:https://www.shumeijiang.com/2021/08/04/树莓派和手柄-蓝牙连接;
2、ps4手柄数据获取:https://www.shumeijiang.com/2021/08/04/树莓派和手柄-数据获取;
3、四驱小车驱动封装:https://www.shumeijiang.com/2021/09/23/四驱小车循迹实验-直流电机驱动封装
组装效果:
    其中将手柄数据获取部分做了简化,然后检测手柄的右侧摇杆数据;当Axis等于2时,表示左右动作,当Axis等于5时,表示前后动作;具体如下表格:
摇杆含义
Axis2大于0向右
Axis2小于0向左
Axis5大于0后退
Axis5小于0前进
代码示例:

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

'''
from JiuJiang
树莓酱的操作实例
https:://www.shumeijiang.com
'''

#import RPi.GPIO as GPIO ##引入GPIO模块
import time    ##引入time库
import pygame

#引入驱动类
from baseAct import baseAct
#实例化驱动类并赋值四个电机所占引脚值
act = baseAct(17, 16, 13, 12, 19, 18, 21, 20)
done = False

#手柄获取初始化
pygame.init()
pygame.joystick.init()

try:
    while not done:
        #检测手柄状态 手柄关闭则检测关闭
        for event in pygame.event.get():
            if event.type == pygame.QUIT:  #是否关闭
                done = True

        #获取摇杆数量
        joystick_count = pygame.joystick.get_count()
        for i in range(joystick_count):
            joystick = pygame.joystick.Joystick(i) #挨个创建摇杆对象
            joystick.init() #摇杆初始化
            axes = joystick.get_numaxes() #获取摇杆轴数

            #挨个获取轴的数据
            for n in range(axes):
                axis = joystick.get_axis(n) #获取指定轴的位置 数字表示
                if axis == 0.0:
                    continue

                #数据收集
                if n == 2:  #左右
                    if axis > 0:
                        act.turn_right(0.5, 50, 50, True)
                    else:
                        act.turn_left(0.5, 50, 50, True)
                elif n == 5: #前后
                    if axis > 0:
                        act.act_backward(0.5, 50, 50)
                    else:
                        act.act_forward(0.5, 50, 50, True)

                time.sleep(0.2)

except KeyboardInterrupt:
    print('停止检测')
执行效果:
    不过实验还是存在一些问题,比如力矩体现,连贯性体现等还是不够完美;后续会实验小车安装摄像头然后实现手机远程视频功能。

红外感应灯实验

    家里曾经买过一种灯,放在门口门厅的位置;尤其是晚上当感应到人的时候会自动亮灯,从而方便找到物品或者电灯开关的位置;好像也叫红外感应灯;由于手里有继电器,红外感应传感器以及七彩LED灯(此处用于替代灯泡的作用),所以尝试模仿制作一个红外感应灯。
感应灯
先看自己的效果:
    从上面的动图可以看到,当手放在红外传感器的前面就会自动触发七彩LED灯点亮;此处可以理解为将灯泡点亮。
具体接线可以参考文章:
继电器部分:https://www.shumeijiang.com/2019/11/23/继电器实验;
红外传感器部分:https://www.shumeijiang.com/2019/12/28/人体红外传感器探测实验
代码示例:

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

'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''

import RPi.GPIO as GPIO  ##引入GPIO模块
import time              ##引入time库

ledPin = 18  ##继电器控制
detectPin = 17  ##人体红外传感器检测

GPIO.setmode(GPIO.BCM)  ##此处采用的BCM编码
GPIO.setup(ledPin, GPIO.OUT)  ##设置继电器为输出模式
GPIO.setup(detectPin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) ##设置人体红外传感器为输入模式 并初始化拉低电平

GPIO.output(ledPin, GPIO.LOW)  ##初始化继电器为低电平

##定义七彩LED灯预警闪烁方法
def startWarning():
    GPIO.output(ledPin, GPIO.HIGH)  ##高电平闪烁
    time.sleep(8)  ##闪烁8秒
    GPIO.output(ledPin, GPIO.LOW)  ##低电平熄灭

GPIO.add_event_detect(detectPin, GPIO.RISING)   ##添加一个边沿检测事件 检测电压升高
GPIO.add_event_callback(detectPin, startWarning)  ##同时添加一个回调动作

try:
    while True:
        if GPIO.event_detected(detectPin):  ##检测是否触发事件 电压升高触发
            print "触发预警"
        else:
            pass

        time.sleep(1)  ##检测频率为1秒/次  可自定义
except KeyboardInterrupt:
    print('预警结束')

GPIO.cleanup()
由上面代码可看到:
1、定义LED灯为输出模式;
2、定义人体红外传感器为输入模式,并初试化拉低电压;
3、添加边沿加测事件,由于人体红外传感器高电平触发,因此定义一个电压升高事件,RISING事件;
4、添加一个回调函数,函数定义七彩LED亮灯动作;
5、遍历检测人体红外是否触发电压升高事件,如果触发则回调七彩LED亮灯函数;
6、定义检测频率,每秒检测一次,这个可自定义。

声控亮灯实验

    生活中经常能看到声控灯,只要有声音,灯变会亮起来;然后没有声音灯又会灭掉;这篇实验将通过一个声音探测传感器加上一个双色LED灯,来尝试模拟声控灯效果;感觉还是蛮好玩;对了,实验用的树莓派zero,可以更好的封装起来。
先看效果:
从上动图可见,当手指弹出声音时,LED灯亮起,然后等待0.5s后熄灭;具体接线图下图:
接线示例
其中声音探测传感器使用可参考文章:https://www.shumeijiang.com/2019/12/28/声音探测传感器实验;
双色LED灯使用可参考文章:https://www.shumeijiang.com/2019/10/27/双色led变化实验
具体实现代码如下:

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

'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''

import RPi.GPIO as GPIO  ##引入GPIO模块
import time              ##引入time库

#声音探测
detectPin = 27

GPIO.setmode(GPIO.BCM)   ##此处采用的BCM编码
GPIO.setup(detectPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) ##初始化高电平

#注册声音探测事件
GPIO.add_event_detect(detectPin, GPIO.FALLING, bouncetime=600)

ledOne = 17
ledTwo = 18
GPIO.setup(ledOne, GPIO.OUT)
GPIO.setup(ledTwo, GPIO.OUT)

try:
    while True:
        #检测是否发现声音
        status = GPIO.event_detected(detectPin)

        if status:
            print('亮灯')
            GPIO.output(ledOne, True)
            time.sleep(0.5) #亮灯持续时间
            GPIO.output(ledOne, False)
        else:
            pass

        time.sleep(0.5) #检测间隔

except KeyboardInterrupt:
    print('停止检测')

GPIO.cleanup()
保存代码为jiujiang.py,然后执行python jiujiang.py,如果发现探测不灵或者过度灵敏,可以旋转声音探测传感器灵敏度调节按钮。

旋转编码传感器实验

    旋转编码传感器是一种速度位移检测传感器;用来检测位置的变化以及位置的偏移变化量;它可以向左转动也可以向右转动,同时还可以按压进行复位这个三个动作方向。
其中传感器有五个引脚,功能分别如下:
引脚功能
CLK判断是否旋转 0是 1否
DT判断旋转方向,1变0顺时针,0变1逆时针
SW复位
+VCC,接5V
GND接GND
接线示例:
接线示例
检测原理:
(1)CLK口注册一个边缘检测事件,检测FALLING事件;
(2)当CLK事件命中时,表示旋转事件发生,这个时间检测旋转方向;
(3)检测DT引脚状态,当状态由1变0时为顺时针旋转,0变1时为逆时针旋转;
(4)检测SW引脚状态,默认为高电平,当为低电平时表示按钮按下,表示计数复位;
代码示例

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

'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''

import RPi.GPIO as GPIO  ##引入GPIO模块
import time              ##引入time库

clkPin = 17
dtPin = 18
swPin = 27

GPIO.setmode(GPIO.BCM)   ##此处采用的BCM编码
GPIO.setup(clkPin, GPIO.IN) ##设置为输入模式
GPIO.setup(dtPin, GPIO.IN)
GPIO.setup(swPin, GPIO.IN)

##定义变量初始值
start = False
reset = False
counter = 0

#检测旋转事件 电压下降为触发条件
GPIO.add_event_detect(clkPin, GPIO.FALLING, bouncetime=600)

try:
    while True:
        ##检测是否触发旋转动作
        clkStatus = GPIO.event_detected(clkPin)
        dtOldStatus = GPIO.input(dtPin)
        swStatus = GPIO.input(swPin)

        #开始旋转
        if clkStatus:
            print('start')
            dtNewStatus = GPIO.input(dtPin)
            start = True

        ##动作开始
        if start:
            ##1变0 顺时针旋转
            if dtOldStatus == 1 and dtNewStatus == 0:
                counter += 1
                print('顺时针旋转')

            ##0变1 逆时针旋转
            if dtOldStatus == 0 and dtNewStatus == 1:
                counter -= 1
                print('逆时针旋转')

        ##检测是否按下 重置数值
        if swStatus == 0:
            reset = True

        #重置
        if reset:
            counter = 0

        #步进数量
        print('步数:%d'%counter)
        time.sleep(0.2)
except KeyboardInterrupt:
    print('停止检测');

GPIO.cleanup()
实验效果: