分类目录动手就动手

ps2摇杆传感器控制舵机实验

    ps2摇杆传感器组合PCF8591数模转换模块,从而获取方向信息,然后通过PCA9685驱动板,驱动两个方向的舵机进行转动。
组合效果如图:
组装示例

如图所示,需要用到的模块有:

模块数量
ps2摇杆传感器1
PCF8591数模转换模块1
树莓派Zero1
PCA9685舵机驱动板1
MG966R舵机3
电源(此处是充电宝)1
特别说明:

1、由于ps2摇杆和PCA9685都需要用到SCL和SDA引脚,所以需要提前焊接PCA9685舵机驱动板尾部串联引脚。(可参考文章:https://www.shumeijiang.com/2021/08/29/多个pca9685舵机驱动板一起执行实验(含地址修改).html)。

2、实验前需要手工打开树莓派I2c协议支持(可参考文章:https://www.shumeijiang.com/2019/12/08/基于命令行打开i2c协议支持.html)。

接线说明:

引脚连接引脚
摇杆GND树莓派GND
摇杆+5V树莓派5V
摇杆VRXPCF8591的AIN0
摇杆VRYPCF8591的AIN1
摇杆SWPCF8591的AIN2
PCF8591的SDAPCA9685的SDA
PCF8591的SCLPCA9685的SCL
PCF8591的VCCPCA9685的VCC
PCF8591的GNDPCA9685的GND
PCA9685的SCL树莓派SCL
PCA9685的SDA树莓派SDA
PCA9685的VCC树莓派5V
PCA9685的GND树莓派GND
视频效果:
关键代码:

#coding:utf-8

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

import time
from board import SCL, SDA
import busio
from PCF8591 import getDirection #引入读取ps2摇杆数据

from adafruit_pca9685 import PCA9685 #引入舵机控制
from adafruit_motor import servo

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

#控制第一块板子
pca = PCA9685(i2c, address=0x40)  #地址可以修改  默认0x40
pca.frequency = 50

#初始化两个舵机驱动
servo_x = servo.Servo(pca.channels[0])
servo_y = servo.Servo(pca.channels[1])

#设置脉冲宽度 500到2500是正常的 这个可以自己调整 不设置默认只到135度
servo_x.set_pulse_width_range(min_pulse=500, max_pulse=2500)
servo_y.set_pulse_width_range(min_pulse=500, max_pulse=2500)

#获取摇杆数据
try:
    while True:
        xN = getDirection('x')
        yN = getDirection('y')
        print(xN)
        print(yN)

        #control x
        if xN == '向前':
            servo_x.angle = 60
        elif xN == '向后':
            servo_x.angle = 140
        else:
            servo_x.angle = 100

        #control y
        if yN == '向左':
            servo_y.angle = 40
        elif yN == '向右':
            servo_y.angle = 140
        else:
            servo_y.angle = 90

        time.sleep(0.2)

except KeyboardInterrupt:
    print('stop')

pca.deinit()
其他参考:
1、PCF8591数模转换实验参考文章:https://www.shumeijiang.com/2022/10/30/pcf8591-da数模转换实验.html

自制防止电脑掉线小工具

     最近家里新添加了一位吃奶小战士,所以事情比较多;经常会被打断去忙别的事情;导致电脑长时间没有动静从而出现微信等工具掉线情况;所以自制了一个小工具,在忙别的事情的时候能保证电脑不会掉链子。
     下面将通过树莓派Zero、PCA9685舵机驱动、MG996舵机组合实现鼠标的定期或随机移动,组合如下图:
组合效果
实现原理:
    树莓派连接PCA9685舵机驱动板,驱动板连接MG996舵机;舵机转轴连接一个驱动臂;将鼠标用胶带跟驱动臂连接起来;接下来写程序,让舵机每隔一段时间执行转动-复位动作,然后驱动臂顺带带动鼠标移动一下;从而实现,电脑检测鼠标在使用的情况,从而防止电脑程序不掉线的目的。
视频效果如下:
实现代码如下:

#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)

#控制第一块板子
pca = PCA9685(i2c, address=0x40)  #地址可以修改  默认0x40
pca.frequency = 50

default_angle = {0:113, 1:0, 2:80}

#开始执行
while True:
    i = 2
    servo_o = servo.Servo(pca.channels[i]) #i是舵机在pca9685上的编号

    #设置脉冲宽度 500到2500是正常的 这个可以自己调整 不设置默认只到135度
    servo_o.set_pulse_width_range(min_pulse=500, max_pulse=2500)

    #初始化度数
    servo_o.angle = default_angle[i]
    time.sleep(1)

    #再执行移动
    servo_o.angle = 65
    time.sleep(1)

    #再恢复
    servo_o.angle = default_angle[i]  
    time.sleep(60) #一分钟执行一次  可随机数

pca.deinit()
舵机驱动部分参考文章:https://www.shumeijiang.com/2021/08/29/舵机的新驱动方式.html

陀螺仪平衡小车实验

    之前曾尝试如何获取陀螺仪的数据,文章地址:https://www.shumeijiang.com/2021/11/09/陀螺仪模块实验-获取欧拉角.html;今天则尝试给陀螺仪加上两个轮子组装成一个二轮小车;然后利用陀螺仪数据使之保持平衡。组装小车中使用到树莓派Zero,直流电机驱动板L298N,以及可显降压升高模块。
接线示例:
实现原理:
1、获取陀螺仪Roll数据(根据陀螺仪安装方向而定);
2、定义一个平衡区间,然后对比陀螺仪的值是否在区间内;
3、当数值小于左侧边界时,小车向左移动来保持平衡;
4、当数值大于右侧边界时,小车向右移动来保持平衡;
5、当在区间内时,小车停止驱动。
代码示例:

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

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

from mpu6050 import mpu6050
#import threading
import time
import MPU6050filter
import RPi.GPIO as GPIO ##引入GPIO模块

motorA1 = 17   ##定义电机A的IN1引脚
motorA2 = 18   ##定义电机A的IN2引脚
enA = 21 #引脚21接ENA,调速电机A

GPIO.setmode(GPIO.BCM)  ##此处采用BCM编码
GPIO.setup(motorA1, GPIO.OUT)  ##设置引脚为输出模式
GPIO.setup(motorA2, GPIO.OUT)
GPIO.setup(enA, GPIO.OUT)

#初始化PWM
pwm = GPIO.PWM(enA, 40)
pwm.start(60)  ##初始化占空比

#陀螺仪数据获取
def get_mpu6050():
    sensor = mpu6050(address=0x68)
    sensor.set_gyro_range(mpu6050.ACCEL_RANGE_16G)
    sensor.set_accel_range(mpu6050.GYRO_RANGE_2000DEG)
    time.sleep(0.02)

    accel_data = sensor.get_accel_data()
    gyro_data = sensor.get_gyro_data()
    rotation = MPU6050filter.IMUupdate(accel_data['x'], accel_data['y'], accel_data['z'], gyro_data['x'], gyro_data['y'], gyro_data['z'])

    return rotation

#设置正反方向
def get_direction(direction):
        if direction == 1:
            GPIO.output(motorA1, GPIO.LOW)
            GPIO.output(motorA2, GPIO.HIGH)
        else:
            GPIO.output(motorA1, GPIO.HIGH) ##设置A1 引脚为高电平
            GPIO.output(motorA2, GPIO.LOW)  ##设置A2 引脚为低电平 如此可控制电机A正转,反之电机A反转

#根据幅度决定速度
def get_duty_cycle(val, n=1):
    val = abs(val)
    if val>10:
        val = 10
    return n*(val*6+40)

def main():
    middle = -3
    left_board = -9
    right_board = 6
    while True:
        time.sleep(0.05)
        rotation = get_mpu6050()
        roll = rotation[1]
        val = roll-middle
        print("roll is", roll)

        duty = get_duty_cycle(val, 0.6)
        if val > right_board:
            get_direction(2)
            pwm.ChangeDutyCycle(duty)
        elif val < left_board:
            get_direction(1)
            pwm.ChangeDutyCycle(duty)
        else:
            #安全区域
            pwm.ChangeDutyCycle(0)

if __name__ == '__main__':
    main()
平衡效果:
实验效果:
1、执行命令 Python jiujiang.py;
2、当小车中心失衡时,出现向左向右行走以保持平衡;
3、不过也有很多问题,当偏恒幅度过大时,小车容易出现无法保持平衡的情况;
4、由于没有经过滤波,所以小车很容易出现抖动。
视频效果:
另一个视角:

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

    前几天实验了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
    然后点击轻触开关传感器,就像拍照时按下快门,可见终端提示“已拍照”,然后同目录文件夹下可见生成一张图片;如此,多次点击可见多次拍照,生成多个照片。
 视频效果如下:

手柄遥控四驱小车实验

    前面曾实验过四驱小车,以及如何获取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,如果发现探测不灵或者过度灵敏,可以旋转声音探测传感器灵敏度调节按钮。

手机连接树莓派实验

    平时都是通过电脑ssh连接树莓派,这次尝试通过手机登录树莓派然后进行命令行输入以及文件查看;当然前提是树莓派设置好静态IP。
示例app
   这次用的是Terminal & SSH和PiHelper两个手机app,都是从Apple手机的App Store下载;下面分别测试如何使用两个APP。
1、Terminal & SSH
打开app后,首先配置登录信息,点击右上角的+号,然后弹层输入配置信息,如下图:
    其中Name为自定义名称,用于区分登录信息,Host是登录树莓派的静态IP地址,Port是默认端口22,Username是登录名称,这边是pi,密码如果没有修改过是raspberry,Use SFTP(Secure File Transfer Protocol)默认打开,表示是否可以传输文件;Path是登录后默认进入的路径地址。
登录效果
命令行界面
    文件下载部分,点击文件可以看到文件下载,然后查看最底部导航栏的Documents按钮,可以看到已下载文件。
2、PiHelper
点击进入APP,然后点击+新建连接;弹出新页面输入如下图配置,同上面:
    配置好后,测试连接,成功后保存配置;保存后跳转首页,然后点击配置好的连接项,效果如下图:其中GPIO为GPIO口注解,TERM为命令行页面,SFTP为文件列表;
点击TERM后,进入命令行界面,如下图:
点击SFTP,进入文件列表页面: