索引
一、硬件连接
二、树莓派Zero配置
三、mjpg-streamer安装调试
四、远程互联网环境搭建
五、增加舵机云台
六、云台及外壳设计制作
七、其他记录
一、硬件连接
硬件概览:树莓派ZeroW、16G存储卡、USB转接头、USB摄像头、2A电源
二、树莓派Zero配置
见:树莓派基础使用-树莓派ZeroW无屏幕烧录系统及配置方式
三、安装mjpg-streamer
官网下载地址:https://github.com/jacksonliam/mjpg-streamer
①.执行以下命令安装必库:
sudo apt-get update sudo apt-get install cmake sudo apt-get install libjpeg9-dev
②.mjpg-streamer项目代码的获取方式
方式一:百度网盘
链接:https://pan.baidu.com/s/1jCqrzse-UQEVEti8M4Iqfg
提取码:mosx
方式二:
##如果直接可以访问github可以安装git直接克隆 sudo apt-get install git sudo git clone https://github.com/jacksonliam/mjpg-streamer.git
③.编译安装:
cd mjpg-streamer/mjpg-streamer-experimental sudo make all sudo make install
④.启动命令:
./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so -w ./www"
如果使用的是CSI摄像头用如下命令:
./mjpg_streamer -i "input_raspicam.so" -o "output_http.so -w ./www"
上述命令启动后,会在控制台输出信息(端口8080),这样就可以通过局域网IP访问了
四、互联网远程环境配置
关于公网访问家庭网,个人总结了几种方式供参考,前两种我都使用过,对个人来讲够用了。
一、家庭宽带有公网IP,或能索要到公网IP
二、无法取得公网IP
三、使用IPv6,这种方式没尝试过,在此就不讨论了。
如何确定你的网是否有公网IP,进入到路由器管理界面,找到WAN界面,查看WAN口IP。然后到百度搜IP,如果两个IP一样就是公网IP,否则就不是;
当前网络服务商可能给公网IP的比较少,我选择宽带商之前确认有公网IP才装的。
这种只需要配置动态域名解析服务就行了,而且带宽就是你宽带上行带宽,不限流量。
如果没有公网IP,目前有些第三方软件,像花生壳等能做内网访问,只需要在路由器或树莓派安装客户端软件,就能实现外网访问。
不过这种方式免费的限流量,不常用的情况下也足够使用了。
除第三方提供的软件外,如果你有自己的云服务器,还可以自己搭建内网代理,我之前用过java开源版的xtunnel。
五、增加舵机云台
上面4步后实现了网络监控,接下来准备作一个云台,通过远程控制摄像头拍摄方向;
这部分利用树莓派的GPIO口控制两路9G舵机,分别沿着水平和垂直两个维度运动。之所以选择9G舵机一个是价格便宜,再一个电路简单不需要外部供电。
树莓派-舵机接线图如下:
云台支架:
1、安装pigpio官方推荐的驱动(
pigpio文档:23. API - Pins — GPIO Zero 1.6.2 Documentation
文档地址:14. API - Output Devices — GPIO Zero 1.6.2 Documentation)
git clone https://github.com/joan2937/pigpio cd pigpio make #编译 sudo make install #安装 sudo ./x_pigpio # 检查完整性 sudo pigpiod # 运行
2、舵机控制程序:
import asyncio import websockets import pigpio import time ## GPIO端口号BCM编码,根据接线修改 PIN_H_SERVO = 17 # 垂直舵机 PIN_V_SERVO = 18 # 水平舵机 PWM_frequency = 50 # Hz # 初始化函数 def init(): # 对舵机控制相关初始化 global pwm_horizontal,pwm_vertical pwm_horizontal = pigpio.pi() pwm_horizontal.set_PWM_range(PIN_H_SERVO, 20000) pwm_horizontal.set_PWM_frequency(PIN_H_SERVO, PWM_frequency) pwm_vertical = pigpio.pi() pwm_vertical.set_PWM_range(PIN_V_SERVO, 20000) pwm_vertical.set_PWM_frequency(PIN_V_SERVO, PWM_frequency) # 水平方向舵机控制 def setHorizontal(x): # 将角度参数转换成pigpio占空比参数 duty = 500 + 11*x pwm_horizontal.set_PWM_dutycycle(PIN_H_SERVO,duty) print("x =", x, "-> duty =", duty) time.sleep(1) # 垂直方向舵机控制 def setVertical(y): # 占空比参数 duty = 500 + 11 * y pwm_vertical.set_PWM_dutycycle(PIN_V_SERVO,duty) print("y =", y, "-> duty =", duty) time.sleep(1) async def handle(websocket, path): async for message in websocket: print("got a command:{}".format(message)) temp = message.split("=") if temp[0] == 'x': setHorizontal(int(temp[1])) if temp[0] == 'y': setVertical(int(temp[1])) print("Done") async def main(): # start a websocket server async with websockets.serve(handle, "0.0.0.0", 8765): await asyncio.Future() # run forever print("starting...") init() asyncio.run(main())
3、修改mjpg-streamer的页面程序,增加控制按钮,通过websockets向树莓派发送舵机指令,实现控制(websockets文档:GitHub - aaugustin/websockets: Library for building WebSocket servers and clients in Python)
Webscoket:是Web浏览器和服务器之间的一种全双工通信协议。
页面中增加一组按钮,代码如下:
<button id="servo_up"><div class="btnface" style="background-image: url('f-up.png');background-size:100% 100%;"></div></button> <button id="servo_down"><div class="btnface" style="background-image: url('f-down.png');background-size:100% 100%;"></div></button> <button id="servo_left"><div class="btnface" style="background-image: url('f-left.png');background-size:100% 100%;"></div></button> <button id="servo_right"><div class="btnface" style="background-image: url('f-right.png');background-size:100% 100%;"></div></button> <button id="servo_auto"><div class="btnface" style="background-image: url('f-auto.png');background-size:100% 100%;"></div></button>
JS写websockets客户端代码:
var x = 90, y = 90; //判断浏览器是否支持WebSocket var supportsWebSockets = 'WebSocket' in window || 'MozWebSocket' in window; if (supportsWebSockets) { var ws = new WebSocket("ws://10.0.0.10:8765"); //连接WebSocket服务端 ws.onopen = function(){ console.log("websocket connect success!"); ws.send("x=90"); // 首次连接后,发送初始化角度命令,水平和垂直舵机都设置成90度 ws.send("y=90"); } ws.onmessage = function(e){ console.log("receive message:" + e.data); } ws.onclose = function(e){ console.log("websocket close!"); } ws.onerror = function(e){ console.log("websocket error:" + e); } //舵机控制函数 $('#servo_up').click(function() { // 垂直 上 y = y + 10; if(y >= 180){ y = 180; } ws.send("y=" + y); }); $('#servo_down').click(function() { // 垂直 下 y = y - 10; if(y <= 0){ y = 0; } ws.send("y=" + y); }); $('#servo_left').click(function() { // 水平 左 x = x + 10; if(x >= 180){ x = 180; } ws.send("x=" + x); }); $('#servo_right').click(function() { // 水平 右 x = x - 10; if(x <= 0){ x = 0; } ws.send("x=" + x); }); }else{ layer.alert("浏览器不支持WebSocket!"); }
六、外壳及支架设计
一共四个部分的3D打印件
七、其他记录
1、舵机抖动问题(发生在启动后,调用sleep过程中或停止时)
一开始我们使用的GPIO库是gpiozero,相关介绍如下:
gpiozero GitHub地址:gpiozero · GitHub
gpiozero 文档地址:gpiozero — GPIO Zero 1.6.2 Documentation
在调试过程中发现,云台在启动后会不停抖动。查询官网文档发现了一个Note提示:
出自地址:14. API - Output Devices — GPIO Zero 1.6.2 Documentation
“为了减少舵机抖动,尽量使用pigpio驱动而不是默认驱动” 原因是:pigpio使用DMA取样使得事件边缘更精确
于是替换了默认库,舵机停止时没有出现抖动现象
2、报错信息如下:sudo: pigpiod: command not found
需要先执行:sudo pigpiod
实测发现,如果通过pip install安装,没有pigpiod命令
==
Copyright © 2015 - 2016 DISPACE.NET | 使用帮助 | 关于我们 | 投诉建议