本人在校生兼职攻城狮,这段时间疫情在家真是憋到慌。每天也就刷刷网课,完成一下作业,再东搞搞西搞搞,没找到那种实验室日夜兼程的感觉,浑身不自在。
所以给自己整点事情玩玩,正巧以前申请的大创项目要结项了,所以买点材料来搞搞,顺便消遣一下时间,顺便检验一下自己“调库”的能力有没有退化了。
历时:一个晚上+一个早上
材料:某宝购买的树莓派+亚克力地盘+电源舵机控制板+摄像头+超声波+DHT11
目标:制作APP端可以控制树莓派小车运动和摄像头的运动,显示视频监控和温湿度超声波测的数据
最终效果视频: 树莓派的室内机器人.zip (6.13 MB, 下载次数: 0)
record如下:
1.收到零件后已经是下午了,吃个晚饭,然后开始琢磨一下这个车。买来都是散件花了一个多小时才装出来个样子。(已经是老司机了,轻车熟路嘿嘿嘿)
2.刷树莓派系统:还是老配方啦 首先安装官方纯净版系统 然后配置摄像头能用 然后安装mpeg_stream+局域网优化 安装一下这个机器人常用的python库,这里主要用到Adafruit_PWM_Servo_Driver库,RPi.GPIO,Adafruit_DHT 上面步骤自行百度安装教程啦,都是老生常谈了。
(额,,,照片歪了,算了不调了麻烦)
3.装完刚刚那些配置环境后,运行MPEG_stream测试一下摄像头能用不。 主要指令如下: - cd mjpg-streamer/mjpg-streamer-experimental
[color=rgb(51, 102, 153) !important]复制代码
[color=rgb(51, 102, 153) !important]复制代码
4.编写机器人的程序 由于我需要用APP来控制机器人,所以需要用到机器人与个人设备的通信。 通信我用TCP/IP协议,主要是基于python的socket类编程。socket是个好东西,通信必备,不懂的建议百度。 然后先基于树莓派环境编写机器人代码,代码主要如下: - #coding:utf-8
- from Adafruit_PWM_Servo_Driver import PWM
- import RPi.GPIO as GPIO
- import socket
- import time
- import sys
- import Adafruit_DHT
- HOST_IP = "10.3.141.1"
- HOST_PORT = 888
- PWMA = 18
- AIN1 = 22
- AIN2 = 27
- PWMB = 23
- BIN1 = 25
- BIN2 = 24
- TRIG = 20
- ECHO = 21
- # Set sensor type : Options are DHT11,dht22 or AM2302
- sensor=Adafruit_DHT.DHT11
- # Set GPIO sensor is connected to
- gpio=16
- s1=90
- ss1=90
- pwm = PWM(0x40,debug = False)
- servoMin = 150 # Min pulse length out of 4096
- servoMax = 600 # Max pulse length out of 4096
- def setServoPulse(channel, pulse):
- pulseLength = 1000000.0 # 1,000,000 us per second
- pulseLength /= 50.0 # 60 Hz
- pulseLength /= 4096.0 # 12 bits of resolution
- pulse *= 1000.0
- pulse /= (pulseLength*1.0)
- pwm.setPWM(channel, 0, int(pulse))
- #Angle to PWM
- def write(servonum,x):
- y=x/90.0+0.5
- y=max(y,0.5)
- y=min(y,2.5)
- setServoPulse(servonum,y)
- pwm.setPWMFreq(50) # Set frequency to 60 Hz
- def t_up(speed,t_time):
- L_Motor.ChangeDutyCycle(speed)
- GPIO.output(AIN2,False)#AIN2
- GPIO.output(AIN1,True) #AIN1
- R_Motor.ChangeDutyCycle(speed)
- GPIO.output(BIN2,False)#BIN2
- GPIO.output(BIN1,True) #BIN1
- time.sleep(t_time)
- def t_stop(t_time):
- L_Motor.ChangeDutyCycle(0)
- GPIO.output(AIN2,False)#AIN2
- GPIO.output(AIN1,False) #AIN1
- R_Motor.ChangeDutyCycle(0)
- GPIO.output(BIN2,False)#BIN2
- GPIO.output(BIN1,False) #BIN1
- time.sleep(t_time)
- def t_down(speed,t_time):
- L_Motor.ChangeDutyCycle(speed)
- GPIO.output(AIN2,True)#AIN2
- GPIO.output(AIN1,False) #AIN1
- R_Motor.ChangeDutyCycle(speed)
- GPIO.output(BIN2,True)#BIN2
- GPIO.output(BIN1,False) #BIN1
- time.sleep(t_time)
- def t_left(speed,t_time):
- L_Motor.ChangeDutyCycle(speed)
- GPIO.output(AIN2,True)#AIN2
- GPIO.output(AIN1,False) #AIN1
- R_Motor.ChangeDutyCycle(speed)
- GPIO.output(BIN2,False)#BIN2
- GPIO.output(BIN1,True) #BIN1
- time.sleep(t_time)
- def t_right(speed,t_time):
- L_Motor.ChangeDutyCycle(speed)
- GPIO.output(AIN2,False)#AIN2
- GPIO.output(AIN1,True) #AIN1
- R_Motor.ChangeDutyCycle(speed)
- GPIO.output(BIN2,True)#BIN2
- GPIO.output(BIN1,False) #BIN1
- time.sleep(t_time)
- GPIO.setwarnings(False)
- GPIO.setmode(GPIO.BCM)
- GPIO.setup(AIN2,GPIO.OUT)
- GPIO.setup(AIN1,GPIO.OUT)
- GPIO.setup(PWMA,GPIO.OUT)
- GPIO.setup(TRIG, GPIO.OUT)
- GPIO.setup(ECHO, GPIO.IN)
- GPIO.setup(BIN1,GPIO.OUT)
- GPIO.setup(BIN2,GPIO.OUT)
- GPIO.setup(PWMB,GPIO.OUT)
- L_Motor= GPIO.PWM(PWMA,100)
- L_Motor.start(0)
- R_Motor = GPIO.PWM(PWMB,100)
- R_Motor.start(0)
- def distance():
- GPIO.output(TRIG, 0)
- time.sleep(0.000002)
- GPIO.output(TRIG, 1)
- time.sleep(0.00001)
- GPIO.output(TRIG, 0)
- while GPIO.input(ECHO) == 0:
- a = 0
- time1 = time.time()
- while GPIO.input(ECHO) == 1:
- a = 1
- time2 = time.time()
- during = time2 - time1
- return during * 340 / 2 * 100
- write(0, 120)
- time.sleep(1)
- write(1, ss1)
- time.sleep(1)
- write(2,s1)
- time.sleep(1)
- '''
- while True:
- dis_f = distance()
- print 'Dis:',dis_f, 'cm'
- humidity, temperature = Adafruit_DHT.read_retry(sensor, gpio)
- IF humidity is not None and temperature is not None:
- print 'Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(temperature, humidity)
- time.sleep(0.5)
- GPIO.cleanup()
- '''
- print("Starting socket: TCP...")
- #1.create socket object:socket=socket.socket(family,type)
- socket_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- print("TCP server listen @ %s:%d!" %(HOST_IP, HOST_PORT) )
- host_addr = (HOST_IP, HOST_PORT)
- #2.bind socket to addr:socket.bind(address)
- socket_tcp.bind(host_addr)
- #3.listen connection request:socket.listen(backlog)
- socket_tcp.listen(1)
- #4.waite for client:connection,address=socket.accept()
- socket_con, (client_ip, client_port) = socket_tcp.accept()
- print("Connection accepted from %s." %client_ip)
- socket_con.send("Welcome to RPi TCP server!")
- print("Receiving package...")
- ###主循环
- while True:
- try:
- data=socket_con.recv(512)
- if(data == b'g'):
- dis_f = distance()
- humidity, temperature = Adafruit_DHT.read_retry(sensor, gpio)
- socket_con.send('Dis={0:0.01f}cm Temp={1:0.1f}*C Humidity={2:0.1f}%'.format(dis_f,temperature, humidity))
- elif(data == b'w'):
- t_up(15,1)
- elif(data == b's'):
- t_stop(3)
- elif(data == b'x'):
- t_down(15,1)
- elif(data == b'a'):
- t_left(30,1)
- elif(data == b'd'):
- t_right(30,1)
- elif(data == b'y'):
- if s1 <180:
- s1 = s1 + 10
- write(1, s1)
- elif(data == b'h'):
- if s1>0:
- s1 = s1 - 10
- write(1, s1)
- elif(data == b'u'):
- if ss1 <180:
- ss1 = ss1 + 10
- write(1, ss1)
- elif(data == b'j'):
- if ss1>0 :
- ss1 = ss1 - 10
- write(1, ss1)
- except Exception:
- socket_tcp.close()
- sys.exit(1)
[color=rgb(51, 102, 153) !important]复制代码
然后在电脑端用网络调试助手发送指令控制小车。 嘿嘿这里的指令主要有 指令 | 功能 | w | 前进 | s | 停车 | x | 后退 | a | 左转 | d | 右转 | y | 摄像头的舵机向上移动 | h | 摄像头的舵机向下移动 | u | 摄像头的舵机向下移动 | j | 摄像头的舵机向上移动 | g | 更新距离和温湿度数据 | 然后测试一下
5.接下来是编写APP程序来代替电脑网络调试助手
APP是基于易安卓开发的,也是顺风顺水,几十分钟内搞定。
文末我会附上这个APP,不喜欢捣鼓的可以直接用,嘿嘿嘿。
6.尾声:历时一个晚上加一个上午终于捣鼓好了。来跑一下
回顾一下我们的功能:制作APP端可以控制树莓派小车运动和摄像头的运动,显示视频监控和温湿度超声波测的数据。
ok收稿,好久没有这么整过了。
附件:功能视频+APP
|