0%

树莓派开发智能小车

小车的配件

  1. 底盘
  2. 4个轮子和4个减速电机
  3. 双路L298N一个
  4. 电池盒(最好要5号8节电池)
  5. 树莓派
  6. 若干的跳线和杜邦线(最好是母对母的)

小车代码,使用的Python的Web异步框架(tornado)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import tornado.ioloop
import tornado.web
import RPi.GPIO as GPIO
import time

IN1=11
IN2=12
IN3=13
IN4=15

def init():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(IN1,GPIO.OUT)
GPIO.setup(IN2,GPIO.OUT)
GPIO.setup(IN3,GPIO.OUT)
GPIO.setup(IN4,GPIO.OUT)

def goLeft():
init()
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.HIGH)
GPIO.output(IN3,False)
GPIO.output(IN4,False)
time.sleep(0.3)
GPIO.cleanup()

def goRight():
init()
GPIO.output(IN1,False)
GPIO.output(IN2,False)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.HIGH)
time.sleep(0.3)
GPIO.cleanup()

def goForward():
init()
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.HIGH)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.HIGH)
time.sleep(0.3)
GPIO.cleanup()

def goBack():
init()
GPIO.output(IN1,GPIO.HIGH)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.HIGH)
GPIO.output(IN4,GPIO.LOW)
time.sleep(0.3)
GPIO.cleanup()

def parkRight():
init()
GPIO.output(IN1,GPIO.HIGH)
GPIO.output(IN2,GPIO.LOW)
GPIO.output(IN3,GPIO.LOW)
GPIO.output(IN4,GPIO.HIGH)
time.sleep(0.3)
GPIO.cleanup()

def parkLeft():
init()
GPIO.output(IN1,GPIO.LOW)
GPIO.output(IN2,GPIO.HIGH)
GPIO.output(IN3,GPIO.HIGH)
GPIO.output(IN4,GPIO.LOW)
time.sleep(0.3)
GPIO.cleanup()

class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
def post(self):
print(self.get_argument('key'))
arg = self.get_argument('key')
if(arg == 'a'):
goLeft()
if(arg == 'd'):
goRight()
if(arg == 'w'):
goForward()
if(arg == 's'):
goBack()
if(arg == 'pr'):
parkRight()
if(arg == 'pl'):
parkLeft()
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])

if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()

安卓手机APP的程序代码(安卓初学,求放过)

  1. 界面布局

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.daniel.controlcar.MainActivity"
    android:background="#fff">
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:layout_marginTop="128px">
    <Button
    android:id="@+id/go_a"
    android:layout_width="256px"
    android:layout_height="256px"
    android:background="@mipmap/left"
    />
    </LinearLayout>
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center">
    <Button
    android:id="@+id/go_s"
    android:layout_width="256px"
    android:layout_height="256px"
    android:background="@mipmap/down"
    />
    <Button
    android:id="@+id/go_w"
    android:layout_width="256px"
    android:layout_height="256px"
    android:background="@mipmap/up"
    android:layout_marginLeft="256px"
    />
    </LinearLayout>
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center">
    <Button
    android:id="@+id/go_d"
    android:layout_width="256px"
    android:layout_height="256px"
    android:background="@mipmap/right"
    />
    </LinearLayout>
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <Button
    android:id="@+id/p_left"
    android:layout_width="256px"
    android:layout_height="256px"
    android:background="@mipmap/p_left"
    />
    <Button
    android:id="@+id/p_right"
    android:layout_width="256px"
    android:layout_height="256px"
    android:background="@mipmap/p_right"
    />
    </LinearLayout>
    </LinearLayout>


    </android.support.constraint.ConstraintLayout>

  2. 后台代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    package com.example.daniel.controlcar;

    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.Button;

    import com.example.daniel.common.HttpUtil;

    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;

    public class MainActivity extends Activity implements View.OnTouchListener {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button goWBtn = (Button) findViewById(R.id.go_w);
    goWBtn.setOnTouchListener(this);
    Button goABtn = (Button) findViewById(R.id.go_a);
    goABtn.setOnTouchListener(this);
    Button goSBtn = (Button) findViewById(R.id.go_s);
    goSBtn.setOnTouchListener(this);
    Button goDBtn = (Button) findViewById(R.id.go_d);
    goDBtn.setOnTouchListener(this);
    Button goPLeftBtn = (Button) findViewById(R.id.p_left);
    goPLeftBtn.setOnTouchListener(this);
    Button goPRightBtn = (Button) findViewById(R.id.p_right);
    goPRightBtn.setOnTouchListener(this);
    }


    public void sendPost(final String key) {

    new Thread(new Runnable() {
    @Override
    public void run() {
    HttpUtil httpUtil = new HttpUtil();
    String response = httpUtil.doPost("http://192.168.31.242:8888?key=" + key, "{}");
    Log.d("returnValue", response);
    }
    }).start();
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
    action(view);
    } else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
    stop();
    }
    return false;
    }

    private ScheduledExecutorService scheduledExecutor;

    /**
    * 开始计划任务,定时每100ms执行一次
    * @param view
    */
    private void action(final View view){
    stop();//首先把已有的定时任务关闭
    scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
    scheduledExecutor.scheduleWithFixedDelay(new Runnable() {
    @Override
    public void run() {
    switch (view.getId()) {
    case R.id.go_w:
    sendPost("w");
    break;
    case R.id.go_a:
    sendPost("a");
    break;
    case R.id.go_s:
    sendPost("s");
    break;
    case R.id.go_d:
    sendPost("d");
    break;
    case R.id.p_left:
    sendPost("pl");
    break;
    case R.id.p_right:
    sendPost("pr");
    break;
    }
    }
    }, 0, 300, TimeUnit.MILLISECONDS); //每间隔100ms发送Message
    }

    /**
    * 停止计划任务
    */
    private void stop() {
    if (scheduledExecutor != null) {
    scheduledExecutor.shutdownNow();
    scheduledExecutor = null;
    }
    }

    }

  3. 配置文件AndroidManifest.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.daniel.controlcar">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />

    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    </activity>

    </application>

    </manifest>
  4. HttpUtil

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    package com.example.daniel.common;

    import java.io.IOException;

    import okhttp3.MediaType;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.RequestBody;
    import okhttp3.Response;

    /**
    * Created by Daniel on 2018/6/20.
    */

    public class HttpUtil {
    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    OkHttpClient client = new OkHttpClient();

    String post(String url, String json) throws IOException {
    RequestBody body = RequestBody.create(JSON, json);
    Request request = new Request.Builder()
    .url(url)
    .post(body)
    .build();
    try (Response response = client.newCall(request).execute()) {
    return response.body().string();
    }
    }



    public String doPost(String url,String paramJson){
    HttpUtil httpUtil = new HttpUtil();
    String responseStr = "";
    try {
    responseStr = httpUtil.post(url,paramJson);
    } catch (IOException e) {
    e.printStackTrace();
    }
    return responseStr;
    }
    }