树莓派摄像小车教程

    科技2022-07-15  126

    目 录

    前言一,所需材料二,小车成品图三,小车代码内容四,小车代码操作五,树莓派摄像头的配置六,电脑端网页控制界面七,小车接线八,实现控制与连接app实现思路 总结 录)


    前言

    这是一篇关于摄像小车的教程 本教程是借鉴一位大神的教程点此跳转


    一,所需材料

    其它配件摄像头 (1)充电宝 (1)小车底盘套件L298n电机(1)––杜邦线若干USB充电线(1)

    二,小车成品图

    树莓派简单录像小车

    三,小车代码内容

    (一共有四个代码文件,分别是1:config.ini 2:carCtrl.py 3:server.py 4:control.html)

    config.ini 代码如下:

    [car] IN1 = 17 IN2 = 18 IN3 = 27 IN4 = 22

    carCtrl.py 代码如下:

    import RPi.GPIO as GPIO import time import configparser class CAR(): delay_tl = 0.45 delay_tr = 0.5 delay_30 = 0.4 def __init__(self): config = configparser.ConfigParser() config.read("config.ini") self.IN1=config.getint("car","IN1") self.IN2=config.getint("car","IN2") self.IN3=config.getint("car","IN3") self.IN4=config.getint("car","IN4") GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) #avoid GPIO warning GPIO.setup(self.IN1,GPIO.OUT) GPIO.setup(self.IN2,GPIO.OUT) GPIO.setup(self.IN3,GPIO.OUT) GPIO.setup(self.IN4,GPIO.OUT) self.reset() def reset(self): #Rest all the GPIO as LOW GPIO.output(self.IN1,False) GPIO.output(self.IN2,False) GPIO.output(self.IN3,False) GPIO.output(self.IN4,False) def __forward(self): # self.reset() GPIO.output(self.IN1,True) GPIO.output(self.IN2,False) GPIO.output(self.IN3,True) GPIO.output(self.IN4,False) print("forward") def __backward(self): # self.reset() GPIO.output(self.IN1,False) GPIO.output(self.IN2,True) GPIO.output(self.IN3,False) GPIO.output(self.IN4,True) print ("BACK") def __turnright(self): # self.reset() GPIO.output(self.IN1,True) GPIO.output(self.IN2,False) GPIO.output(self.IN3,False) GPIO.output(self.IN4,True) print("right") def __turnleft(self): # self.reset() GPIO.output(self.IN1,False) GPIO.output(self.IN2,True) GPIO.output(self.IN3,True) GPIO.output(self.IN4,False) print("left") def __stop(self): self.reset() print("stop") def CarMove(self,direction): if direction == 'F': self.__forward() elif direction == 'B': self.__backward() elif direction == 'R': self.__turnright() elif direction == 'L': self.__turnleft() elif direction == 'S': self.__stop() elif direction == 'E': GPIO.cleanup() exit() if __name__ == '__main__': RaspCar=CAR() while(True): direction = input("Please input direction:") print(direction) RaspCar.CarMove(direction,True) time.sleep(0.5) direction = "S" RaspCar.CarMove(direction,True)

    server.py 代码如下:

    from http.server import BaseHTTPRequestHandler,HTTPServer import time import socket import urllib from carCtrl import CAR #from camera_control import Camera from threading import Thread #global loop global direction #loop =True class CarServer(BaseHTTPRequestHandler): carControl = CAR() # cameraControler = Camera() i=0 def get_host_ip(self): try: serverSocket = socket.socket(socket.AF_INET ,socket.SOCK_DGRAM) serverSocket.connect(("192.168.137.75",80)) localIP = serverSocket.getsockname()[0] finally: return localIP def do_GET(self): localIP = CarServer.get_host_ip(self) self.carControl.reset() controlPageFile = open("control.html") controlPageGUI = controlPageFile.read() controlPageFile.close() controlPageGUI = controlPageGUI.replace( "requestAddress","http://"+ localIP +":9090/") controlPageGUI = controlPageGUI.replace( "cameraAddress","http://"+ localIP +":8080/") self.send_response(200) self.send_header("Content-type","text/html") self.end_headers() self.wfile.write(controlPageGUI.encode()) print (controlPageGUI) def do_POST(self): length = int(self.headers['Content-Length']) qs = self.rfile.read(length) global direction direction = 'S' direction = qs.decode() print(direction) self.carControl.CarMove(direction) if __name__ == "__main__": #print () raspCarServer = CarServer hostIP = raspCarServer.get_host_ip(raspCarServer) hostPort = 9090 myServer = HTTPServer((hostIP,hostPort),raspCarServer) print(time.asctime(),"Server Starts - %s:%s" %(hostIP,hostPort)) try: myServer.serve_forever() except KeyboardInterrupt: pass

    control.html 代码如下:

    <html> <script> function directionBtnDown(direction) { var url = "http://你的树莓派IP地址:9090" var request = new XMLHttpRequest(); request.open("POST", url); request.send(direction) } function directionBtnUp() { var url = "http://改成你的树莓派IP地址:9090" var request = new XMLHttpRequest(); request.open("POST", url); request.send("S") } </script> <style type="text/css"> span.car { -webkit-touch-callout:none; /*系统默认菜单被禁用*/ -webkit-user-select:none; /*webkit浏览器*/ -khtml-user-select:none; /*早期浏览器*/ -moz-user-select:none;/*火狐*/ -ms-user-select:none; /*IE10*/ user-select:none; position: absolute; margin-top: 30%; height: 480px; } span.camera { position: absolute; margin-top: 5%; margin-left: 300px; height: 480px; width: 640px; background-color: blue } span.camera_control { position: absolute; margin-top: 30%; margin-left: 950px; height: 480px; background-color: blue } button.top { position: absolute; height: 50px; width: 90px; margin-left: 100px; } button.left { position: absolute; height: 50px; width: 90px; margin-top: 60px; } button.center { position: absolute; height: 50px; width: 90px; margin-top: 60px; margin-left: 100px; } button.right { position: absolute; height: 50px; width: 90px; margin-top: 60px; margin-left: 200px; } button.bottom { position: absolute; height: 50px; width: 90px; margin-top: 120px; margin-left: 100px; } button.bleft { position: absolute; height: 50px; width: 90px; margin-top: 180px; } button.bcenter { position: absolute; height: 50px; width: 90px; margin-top: 180px; margin-left: 100px; } button.bright { position: absolute; height: 50px; width: 90px; margin-top: 180px; margin-left: 200px; } button.bbottom { position: absolute; height: 50px; width: 90px; margin-top: 240px; margin-left: 100px; } </style> <head> <title>control page</title> <meta name="viewport" content=" height = 1080px , width = 1920px , initial-scale =0.5, minimum-scale = 0.5 , maximum-scale = 1.0 , user-scalable = "yes" " /> </head> <body> <span id="car_control" class="car"> <button class="top drectionBtn" id="F" ontouchstart="directionBtnDown('F')" ontouchend="directionBtnUp()"οnmοusedοwn="directionBtnDown('F')" οnmοuseup="directionBtnUp()">F</button> <button class="left drectionBtn" id="L" ontouchstart="directionBtnDown('L')" ontouchend="directionBtnUp()" onmousedown="directionBtnDown('L')" onmouseup="directionBtnUp()">L</button> <button class="right drectionBtn" id="R" ontouchstart="directionBtnDown('R')" ontouchend="directionBtnUp()"οnmοusedοwn="directionBtnDown('R')" οnmοuseup="directionBtnUp()">R</button> <button class="center drectionBtn" id="B" ontouchstart="directionBtnDown('B')" ontouchend="directionBtnUp()"οnmοusedοwn="directionBtnDown('B')" οnmοuseup="directionBtnUp()">B</button> <button class="bleft drectionBtn" id="AUTO" onmousedown="directionBtnDown('Auto')">Auto</button> <button class="bcenter drectionBtn" id="S" onmousedown="directionBtnDown('S')">Stop</button> <button class="bright drectionBtn" id="E" onmousedown="directionBtnDown('E')">exit</button> </span> <span id="camera_view" class="camera"> <img id="view" src="http://改成你的树莓派IP地址:8080/?action=stream" /> </span> </body> </html>

    (注意:body标签中的class = top/right/center drectionBtn 这三行代码要手打,使它们与left 行的代码颜色对应)

    四,小车代码操作

    第一步: 1,在树莓派终端用指令(mkdir camera)创建一个名为camera的文件夹 2,然后进入文件夹(cd camera),用指令(sudo nano 加文件名.后缀)分别创建上述四个代码文件 如:sudo nano server.py 3,然后把代码分别写进去 4,在终端打入python查看python版本。 我这为3.7.3,如果为2.7的,则需要切换到3的版本,具体操作如下:

    切换python3(一般选择0的auto模式)

    五,树莓派摄像头的配置

    1,接线(即排线的蓝色面朝向USB口和摄像头内面) 2,设置摄像头enable 3,查看摄像头是否已成功连接 终端输入(ls -o /dev/) (有 video 0 说明已成功连接)

    4,利用MJPG-streamer实现网络监控 首先 安装依赖,输入命令: 1,sudo apt-get install libjpeg8-dev cmake 然后 下载MJPG-Streamer-Master,输入命令:

    2,wget http://github.com/jacksonliam/mjpg-streamer/archive/master.zip 3,unzip master.zip 然后 对分辨率及帧率进行修改,修改帧率及分辨率如图,输入命令:

    4,cd mjpg-streamer-master/mjpg-streamer-experimental 5,sudo nano plugins/input_raspicam/input_raspicam.c 修改完成后保存退出修改文件(CTRL+O, 回车,CTRL+X),进行编译生成可执行文件,输入命令: 6,make clean all 开启摄像头,输入命令: 7,./mjpg_streamer -i “./input_raspicam.so” -o “./output_http.so -w ./www” 8,可通过在浏览器"http://树莓派ip:8080/?action=stream"进行访问,这样就可 以看到摄像头的实时画面

    六,电脑端网页控制界面

    1,首先要用一个可以制作网页的软件,(如 Visual studio code) 2,在拓展中下载open in browser 3,设置自动保存网页内容

    4,在文件新建一个以.html为后缀的文件,把conctrl.html写进去(注意要改成自己树莓派的IP地址,有三处地方) 5,按快捷键"Alt + B" 可以看到如下画面的话就可以了

    七,小车接线

    1,l298n图

    2,树莓派引脚图 1,(我们定义的是BCM模式,所以L298n的IN1-4 对应树莓派的17,18,27,22引脚) 2,树莓派和L298n要共地 3,可用这样一条线让充电宝给L298n供电

    4,其它可参考 B站详细接线视频

    八,实现控制与连接

    1,在树莓派终端切换到camera 文件夹再执行命令python3 server.py 然后回车 2,再在终端开多一个窗口,切换到 mjpg-streamer-master/mjpg-streamer-experimental文件夹,再执行命令 ./mjpg_streamer -i “./input_raspicam.so” -o “./output_http.so -w ./www” 然后回车,

    3,在电脑visual studio code打开网页 即可控制小车和看到图像

    app实现思路

    (1)方案——AS 使用AS自己写一个,不过可能耗时久一点,可以通过访问控制页面实现,也可以耗点力气,把功能全部集中在APP中,跳过网页进行控制。

    (2)方案——MIT-APP 使用简易创建app的工具,直接嵌入一个浏览器内核,直接访问,在里面将小车的IP写成默认,每次点开即可,无需每次重复输入IP。

    下附MIT-APP的链接

    总结

    这台小车是在树莓派中写入一个能够与网页(conctrl.html)通信的python文件(server.py),从而通过调用python文件(carCtrl.py)控制电机的转动,以达到控制小车的目的。

    Processed: 0.013, SQL: 8