自写app与树莓派制作智能小车

实现的功能有:
1.实现小车的前进,后退,左转,右转。
2.实时视频的传回,查看小车周围的情况。
3.摄像头的上下左右转动,使用舵机云台来实现。

需要的材料:
1.树莓派一个(带有python环境,现在的好像都有自带python环境)。
2.安卓手机一部,用于安装写的APP。
3.杜邦线若干。
4.L298N电机驱动模块(某宝9块钱一个)。
5.舵机云台一个(某宝有卖散件,买来自己装,20几块钱)。
6.车架一个(同样某宝…).
7.充电宝一个,用于树莓派供电,和L298N电机驱动模块供电,虽然L298N标的是12V的电源,但是5V也能使用。
8.电脑一台。


   首先要实现手机app与树莓派的通信,这样才能实现对树莓派小车的控制。首先想到的就是socket通信,简单易懂,但是写的时候还是遇见了很多的问题,下面会说到。
   这篇文章只介绍实现app控制小车的前进后退左转右转。
   整体的思路就是:手机app向树莓派发送不同的指令,树莓派根据不同的指令进行指定的相应,来控制车体的运动。

一、车体的组装以及连线这里就不仔细介绍了,这种东西还是比较简单的。要注意的是将从树莓派引出的GPIO引脚要记好,编程的时候还要用。其中L298N驱动的作用就是来为带动小车运动的电机提供足够的电源。

二、下面就是app进行编程了,这里使用的是Android studio,如何安装,与配置环境百度一下都有,这里就不介绍了。下面拿控制小车前进作为一个例子进行解释一下:

@Override
    public void onClick(View v)
    {
        if (v.getId() == R.id.forward)
        {
                forward.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent)
                {
                    //抬起操作
                    if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                        sendRequestWithHttpURLConnection1();
                    }
                    //按下操作
                    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                        sendRequestWithHttpURLConnection();
                    }
                    //移动操作
                    if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {

                    }
                    return false;
                }
            });
        }
  }
 上面的代码是来监控你在app中按下了那个按键,如果是前进键,按下时调用sendRequestWithHttpURLConnection()函数向树莓派发送指令,抬起按键时向树莓派在此发送指令。
 其中sendRequestWithHttpURLConnection()这个函数很重要,在写时遇到了很多的问题,主要就是在UI线程和通信socket线程的处理上,UI线程中不能使用socket通信必须要重新创建一个线程来进行通信。

重点内容

  private void sendRequestWithHttpURLConnection()
    {
             new Thread(new Runnable()
             {
                @Override
                public void run() {
                    int PORT = 1;
                    InetAddress addr = null;
                    try
                    {
                        addr = InetAddress.getByName("192.168.31.6");//此处是树莓派的IP地址。
                    }
                    catch (UnknownHostException e)
                    {
                        e.printStackTrace();
                    }
                    Socket socket = new Socket();
                    try
                    {

                        socket.connect(new InetSocketAddress(addr, PORT), 30000);
                        socket.setSendBufferSize(100);
                        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                        out.write("forward");
                        out.flush();

                    }
                    catch (SocketException e)
                    {
                        e.printStackTrace();
                    }
                    catch (IOException e)
                    {
                        e.printStackTrace();
                        StringBuilder response = new StringBuilder();
                        String line="Iot";
                        response.append(line);
                        showResponse(response.toString());
                    }
                    finally
                    {
                        try
                        {
                            socket.close();
                        }
                        catch (IOException e)
                        {
                            e.printStackTrace();
                        }
                    }
                }
             }).start();
    }
   上面的代码就是socket编程的关键所在,这只是前进指令的发送代码,还有其他的指令的发送代码,几乎都是相同的,只是把write()括号中的内容改一下就行了。每次按下一个按键,就发送一个指令,使得树莓派的GPIO改变状态。每次抬起按键都发送停止的指令,使得小车停下来。

三、树莓派部分的代码
树莓派的代码使用python写的,它的作用是来对手机发送来的指令进行处理。
分为两部分,一部分是用来封装小车的控制代码,一部分是用来识别接收到的指令,调用第一部分的代码。
第一部分代码:
重点内容

import threading
import RPi.GPIO as GPIO
import time

class Info:
    @staticmethod
    def p(message):
        print 'Info: '+message 

class Wheel:
    pins ={'a':[13,15],'b':[16,18]}
    def __init__(self,name):
        self.name = name
        self.pin = Wheel.pins[self.name]
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(self.pin[0],GPIO.OUT)
        GPIO.setup(self.pin[1],GPIO.OUT)
        self.stop()
    def st(self):
        print 'ss'
    def forward(self):
        Info.p('wheel ' + self.name + ' is forwarding')
        GPIO.output(self.pin[0],GPIO.HIGH)
        GPIO.output(self.pin[1],GPIO.LOW)
    def stop(self):
        GPIO.output(self.pin[0],False)
        GPIO.output(self.pin[1],False)
    def back(self):
        Info.p('wheel ' +self.name + ' is backing')
        GPIO.output(self.pin[0],False)
        GPIO.output(self.pin[1],True)

class Car:
    wheel=[Wheel('a'),Wheel('b'),Wheel('c'),Wheel('d')] 
    @staticmethod
    def init():
        GPIO.setmode(GPIO.BOARD)
        Info.p('initialize the smart car ....')     
        Info.p('Smart car is ready to fly!')
    @staticmethod
    def forward():
        Info.p('go straight forward')
        for wheel in Car.wheel:
            wheel.forward()
    @staticmethod
    def left():
        Info.p('turn left ')
        Car.wheel[0].forward()  
        Car.wheel[1].back()
    @staticmethod
    def right():
        Info.p('turn left ')
        Car.wheel[0].back()
        Car.wheel[1].forward()
    @staticmethod
    def bleft():
        Info.p('turn left ')
        Car.wheel[2].back() 
    @staticmethod
    def stop():
        Info.p('turn left ')
        Car.wheel[0].stop() 
        Car.wheel[1].stop() 
    @staticmethod
    def back():
        Info.p('go straight back')
        for wheel in Car.wheel:
            wheel.back()

    @staticmethod
    def lforward():
        Info.p('go forward and turn left')

    @staticmethod
    def rforward():
        Info.p('go forward and turn right')

    @staticmethod
    def lback():
        Info.p('go back and turn left')

    @staticmethod
    def rback():
        Info.p('go back and turn right')
    @staticmethod
    def stop():
        Info.p('try to stop the car ...')
        for wheel in Car.wheel:
            wheel.stop()    
    @staticmethod
    def bark():
        Info.p('try to slow down the car ...')

    @staticmethod
    def speedup():
        Info.p('try to speed up the car ...')
    if __name__ =='__main__':
       print '....'

第二部分代码:

```python 
from socket import *
import sys
import time
from car import *
def run_raspberry():
    commands ={'forward':Car.forward,'back': Car.back, 'stop': Car.stop,'left':      Car.left,'right': Car.right}
    PORT = 1
    s= socket(AF_INET, SOCK_STREAM)
    s.bind(("", PORT)) #对所有的ip都能接收。
    s.listen(1)
    print ('raspberry pi is listening on port 8888')
    while 1:
        conn, addr = s.accept()
        print ('Connected by:', addr)
        while 1:
                command= conn.recv(1024).replace('\n','')
                if not command or command not in commands:break
                commands[command]()
        conn.close()
    if __name__ == '__main__':
         run_raspberry()
 ```
 只需运行run_raspberry.py这个代码就可以了。
 后续功能的实现,将在后面的博客中更新。

参考了一下这个博客:
http://blog.csdn.net/AMDS123/article/details/70595127?locationNum=2&fps=1

  • 10
    点赞
  • 113
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值