【嵌入式】——Linux驱动程序(PWM接口)与超声波测距
一、基于树莓派的反向代理
1.ssh -p 22 -qngfNTR [你的端口号]:localhost:22 阿里云用户名@阿里云服务器IP
ssh -p 22 -qngfNTR 9621:localhost:22 wanghy@114.55.126.125
查看监听端口ss -ntl,出现以下界面表示树莓派和阿里云已经连上。
2.ssh -p [你绑定的端口号] [树莓派用户]@云服务器地址
ssh -p 9621 pi@114.55.126.125
以上操作是基于已经完成打开阿里云服务器端口且配置好相应ssh服务的步骤上完成的,如果没有完成相应操作,需要查询一下如何打开端口,配置ssh服务后再进行。
二、用python编写PWM呼吸灯
PWM就是通过控制一定时间内的平均电压来调节这段时间LED灯的明暗程度。通过改变占空比来控制一定时间内的平均电压,占空比指电路被接通的时间占整个电路工作周期的百分比。
import RPi.GPIO as GPIO
import time# 设置编码方式和引脚
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.OUT)# 实例化PWM,初始频率为50Hz,占空比为50%
pwm = GPIO.PWM(16, 50)
pwm.start(50)
time.sleep(3)# 修改占空比为100%
pwm.ChangeDutyCycle(100)
time.sleep(3)# 停止PWM,释放引脚资源
pwm.stop()
GPIO.cleanup()
效果如下:
PWM
示波器波形如下所示:
三、完成驱动程序的make编译
mkdir -p drivers/00-hello && cd drivers/00-hello
cd drivers/00-hello
touch hello.c Makefile
hello.c
#include <linux/init.h>
#include <linux/module.h>static int __init hello_init(void)
{printk("hello kernel\n");return 0;
}
module_init(hello_init);static void __exit hello_exit(void)
{printk("bye kernel\n");
}
module_exit(hello_exit);MODULE_LICENSE("GPL v2"); // 开源许可证
MODULE_DESCRIPTION("hello module for RPi 3B+"); // 模块描述
MODULE_ALIAS("Hello"); // 模块别名
MODULE_AUTHOR("Philon"); // 模块作者
安装内核头文件,树莓派上执行
sudo apt update && sudo apt install raspberrypi-kernel-headers
Makefile
obj-m += hello.oall:make -C /lib/modules/$(shell uname -r)/build M\=$(PWD) modulesclean:make -C /lib/modules/$(shell uname -r)/build M\=$(PWD) clean
make
scp hello.ko rpi.local:/home/philon/modules/
#开发板加载hello模块sudo insmod hello.ko
# 卸载内核sudo rmmod hello
# 查看内核打印信息dmesg | tail -5
看到其中的hello kernel、bye kernel等显示,表明内核编译成功。
四、树莓派上实现超声波测距
树莓派引脚图如下:
代码中引脚为GPIO23、24
HC-SR04 的测距过程
树莓派向 Trig 脚发送一个持续 10us 的脉冲信号 HC-SR04 接收到树莓派发送的脉冲信号,开始发送超声波 (start sending ultrasoun),并把 Echo置为高电平。 然后准备接收返回的超声波 当 HC-SR04 接收到返回的超声波 (receive returned ultrasound) 时,把 Echo 置为低电平
完整代码hc.py
#导入 GPIO库
import RPi.GPIO as GPIO
import time#设置 GPIO 模式为 BCM
GPIO.setmode(GPIO.BCM)#定义 GPIO 引脚
GPIO_TRIGGER = 23
GPIO_ECHO = 24#设置 GPIO 的工作方式 (IN / OUT)
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)def distance():# 发送高电平信号到 Trig 引脚GPIO.output(GPIO_TRIGGER, True)# 持续 10 us time.sleep(0.00001)GPIO.output(GPIO_TRIGGER, False)start_time = time.time()stop_time = time.time()# 记录发送超声波的时刻1while GPIO.input(GPIO_ECHO) == 0:start_time = time.time()# 记录接收到返回超声波的时刻2while GPIO.input(GPIO_ECHO) == 1:stop_time = time.time()# 计算超声波的往返时间 = 时刻2 - 时刻1time_elapsed = stop_time - start_time# 声波的速度为 343m/s, 转化为 34300cm/s。distance = (time_elapsed * 34300) / 2return distanceif __name__ == '__main__':try:while True:dist = distance()print("Measured Distance = {:.2f} cm".format(dist))time.sleep(1)# Reset by pressing CTRL + Cexcept KeyboardInterrupt:print("Measurement stopped by User")GPIO.cleanup()