上一篇实现了远程监控,但是太不灵活了,如果在摄像头上加上一个舵机云台来实现摄像头的左右上下转动就再好不过了,先来看一下效果吧,这是把前面的都做完之后整体的效果:
材料:
1.舵机云台
某宝上买的20几块钱,不过需要自己组装,如果不想组装可以直接买现成的,不过要贵不少,其实组装也没有太难,关键是上面的两个舵机SG90。
2.arduino开发板
我用的是arduino-Pro-Mini,当然树莓派也可以直接控制舵机,觉着用arduino更好控制一些,网上的树莓派控制舵机的资料也比较少…
3.USB接口用来连接树莓派和arduino开发板,作串口通信:
就需要这些。
步骤:
先来做arduino开发板部分的工作,开发arduino使用的软件是arduino,这个软件十分好用而且自带串口监控工具,整体的思路是给arduino开发板发一个数字,舵机就转相应的度数,关于SG90舵机的使用原理说一下:
https://www.whatled.com/post-1650.html这篇文章介绍的十分详细,介绍了控制舵机的两种方法,我们这里有两个舵机,看懂了原理之后控制两个舵机也不成问题。
再就是树莓派与开发板的串口通信,直接将USB插头插到树莓派的usb接口上,在树莓派上运行:
ls /dev/tty*
可以看到多了一个ttyUSB0这个就是插入的arduino开发板,先写一个程序试一下,用的是python:
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600,timeout=1);
try:
ser.write('5');#writ a string to port
response = ser.readall();#read a string from port
print response;
except:
ser.close()
运行一下舵机会转动到你指定的角度,到这准备工作就做好了。下面使用手机app控制舵机的转动,在之前的文章中有app控制小车运动的方法和代码,这里的原理跟之前的差不多,这里因为是控制两个舵机,做了一个处理,1234等数字表示控制一个舵机,ABCD等字母表示控制另一个舵机,A对应的就是1,但是还有一个问题现在也没有找到为什么,就是ttyUSB0有时会自己变成TTYUSB1,为了解决这个问题做了如下的处理:
if command == '5':
try:
ser = serial.Serial('/dev/ttyUSB0', 9600,timeout=1)
ser.write('5')#writ a string to port
except Exception,ex:
ser = serial.Serial('/dev/ttyUSB1', 9600,timeout=1)
ser.write('5')#writ a string to port
这样不管是ttyUSB0还是ttyUSB1都能正常工作了。
下面就是app了,其实也比较简单,我做了四个按键,来控制两个舵机,实现摄像头的上下左右转动,需要定义一个静态变量,在按下按键时它的值累加,将累加后的值发送到云服务器然后云服务器再将值发送到树莓派,关键的代码如下:
if (v.getId() == R.id.d_forward)
{
d_forward.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
//按下操作
if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
//stop();
}
//抬起操作
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
d_forward();
}
//移动操作
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
}
return false;
}
});
}
private void d_forward()
{
new Thread(new Runnable()
{
@Override
public void run() {
try
{
if(sx>5) {
sx = sx - 1;
}
outputStream = socket.getOutputStream();
String temp;
String kehu = "kehu";
temp = String.valueOf(sx);
// outputStream.write((forward+"\n").getBytes("utf-8"));
// 特别注意:数据的结尾加上换行符才可让服务器端的readline()停止阻塞
// 步骤3:发送数据到服务端
// outputStream.flush();
String jsonStr = "{\"sign\":\"" + kehu + "\"," + " \"account\": \"" + temp + "\"}";
BufferedWriter BW = new BufferedWriter(new OutputStreamWriter(outputStream));
BW.write(jsonStr);
BW.flush();
}
catch (IOException e)
{
}
}
}).start();
}
服务器的代码和具体的一些代码可以去看前面的文章。