ArduinoとラズパイでMQTTラジコンカー




# MQTTラジコンカー
最初にどのようなものを作ったのかを紹介します
こちらはMQTTを利用したラジコンカーとなっておりインターネット経由で動かしているのでネット環境があれば様々な場所から操作することができます
<img src="https://user-images.githubusercontent.com/62089701/97300100-53355880-1899-11eb-9d9f-6b44d4c939e0.gif" width=80%>


# 使用した環境
・windows10
・ubuntu18.04
・AWS

windows10でarduinoのプログラムスケッチ、書き込みを行う
ubuntuでラズパイとssh接続し、ラズパイを操作
AWSをMQTTブローカーとして使用



## 使用したもの
・Arduino
・Raspberry Pi 3 Model B
・usbケーブル(AruinoとRaspiをシリアル通信させるために使用)
・モバイルバッテリー、usbケーブル(ラズパイに電源供給するために使用)
・[電池ボックス](https://www.amazon.co.jp/uxcell-%E9%9B%BB%E6%B1%A0%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9-%E9%9B%BB%E6%B1%A0%E3%83%9B%E3%83%AB%E3%83%80%E3%83%BC-1-5V%E5%8D%98%E4%B8%89%E9%9B%BB%E6%B1%A0-%E5%8D%983%E9%9B%BB%E6%B1%A0%E3%82%B1%E3%83%BC%E3%82%B9/dp/B01HUX8YDY/ref=sr_1_6?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E9%9B%BB%E6%B1%A0%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9&qid=1603765741&sr=8-6)(アマゾンで購入)
・[モータードライバ](https://www.switch-science.com/catalog/5522/)（スイッチサイエンスで購入）
・[タミヤ楽しい工作シリーズダブルギヤボックス](https://www.amazon.co.jp/%E3%82%BF%E3%83%9F%E3%83%A4-%E6%A5%BD%E3%81%97%E3%81%84%E5%B7%A5%E4%BD%9C%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-No-168-%E3%83%80%E3%83%96%E3%83%AB%E3%82%AE%E3%83%A4%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9-%E5%B7%A6%E5%8F%B3%E7%8B%AC%E7%AB%8B4%E9%80%9F%E3%82%BF%E3%82%A4%E3%83%97/dp/B001Q13BIU/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E3%82%BF%E3%83%9F%E3%83%A4+%E3%83%80%E3%83%96%E3%83%AB%E3%82%AE%E3%83%A4%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9&qid=1603764617&sr=8-1)(アマゾンで購入)
・[タミヤ楽しい工作シリーズナロータイヤセット58mm](https://www.amazon.co.jp/%E3%82%BF%E3%83%9F%E3%83%A4-%E6%A5%BD%E3%81%97%E3%81%84%E5%B7%A5%E4%BD%9C%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-No-145-%E3%83%8A%E3%83%AD%E3%83%BC%E3%82%BF%E3%82%A4%E3%83%A4%E3%82%BB%E3%83%83%E3%83%88-58mm%E5%BE%84/dp/B001VZJDZ6/ref=pd_all_pref_10?pd_rd_w=LumaR&pf_rd_p=4f969a54-b46f-456c-b77f-72ed974b654e&pf_rd_r=ZNSFZS63R7790S957Y6W&pd_rd_r=5a95b0cc-6bdb-48e0-8afa-73690040d578&pd_rd_wg=liiX2&pd_rd_i=B001VZJDZ6)(アマゾンで購入)

## ハードウェアの準備
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823157/7a65fed9-9c0e-fcb3-5ca3-31063634ab98.jpeg" width=40%>

・アマゾンで届いた段ボールを適当な大きさに切ってモーターと電池ボックスを置き、モータの上にはモータードライバを両面テープで固定。さらにその上にarduinoとラズパイ、モバイルバッテリーをマスキングテープで固定。

・とりあえず動けばいいという考えで作ってます。

## ソフトウェアの準備

### MQTTのパラメータ
| topic  |
|:---------:|
|  mqtt_RC  |

|message |  動作　  |
|:---------|-------:|
|   　　w    | 　 前進　  |
|   　　a    | 　左旋回　 |
|   　　d    | 　右旋回　 |
|   　　s    |  　停止　  |
|   　　b    |  　後進　  |
|   　　f    |    終了　  |

### Arduinoのプログラム
arduinoはラズパイからシリアル通信で送られてくる信号に応じてモーターを制御する。

```ruby:mqtt_RC_arduino.ino


const int MA1 = 10;
const int MA2 = 11;
const int MB1 = 12;
const int MB2 = 13;

int com = 0;

void setup() {

  Serial.begin(9600);
  
  pinMode(MA1,OUTPUT);
  pinMode(MA2,OUTPUT);
  pinMode(MB1,OUTPUT);  
  pinMode(MB2,OUTPUT);  

}

void loop() {
    while(true){

      if(Serial.available() > 0){
        com = Serial.read();
        Serial.println(com);
      }
      if(com == 'w'){
        motor_forward();
        delay(1000);
      }  
      else if(com =='d'){
        motor_righit();
        delay(1000);
      }
      else if(com =='a'){
        motor_left();
        delay(1000);
      }
      else if(com =='s'){
        motor_stop();
        delay(1000);
      }
      else if(com =='b'){
        motor_back();
        delay(1000);
        }
      else if(com =='f'){
        break;
      }
  }
}

void motor_forward(){
      digitalWrite(MA1,HIGH);
      digitalWrite(MA2,LOW);
      digitalWrite(MB1,HIGH);
      digitalWrite(MB2,LOW);
      Serial.println("forward");
}

void motor_back(){
      digitalWrite(MA1,LOW);
      digitalWrite(MA2,HIGH);
      digitalWrite(MB1,LOW);
      digitalWrite(MB2,HIGH);   
      Serial.println("back");   
}

void motor_stop(){
      digitalWrite(MA1,LOW);
      digitalWrite(MA2,LOW);
      digitalWrite(MB1,LOW);
      digitalWrite(MB2,LOW);  
      Serial.println("stop");
}

void motor_righit(){
      digitalWrite(MA1,HIGH);
      digitalWrite(MA2,LOW);
      digitalWrite(MB1,LOW);
      digitalWrite(MB2,LOW);  
      Serial.println("righit"); 
}

void motor_left(){
      digitalWrite(MA1,LOW);
      digitalWrite(MA2,LOW);
      digitalWrite(MB1,HIGH);
      digitalWrite(MB2,LOW);
      Serial.println("left");
}
```

### ラズパイのプログラム
ラズパイはmqtt通信でpubliserから送られてくるメッセージを受信しそれをシリアル通信でarduinoに送る。
シリアル通信でarduinoと接続するラズパイのポートと、mqttブローカーのアドレスは自分で確認して入力する。

```ruby:mqtt_RC_raspi.py
import  sys
from time import sleep
import paho.mqtt.client as mqtt
import serial
# ------------------------------------------------------------------
sys.stderr.write("*** 通信開始 ***\n")


ser = serial.Serial('接続するarduinoのポートを入力',9600)

host = 'ブローカーのアドレスを入力'
port = 1883
topic = 'mqtt_RC'


def on_connect(client, userdata, flags, respons_code):
    print('status {0}'.format(respons_code))

    client.subscribe(topic)

def on_message(client, userdata, msg):
    st = str(msg.payload,'utf-8')
    print(st)

    if st == "w":
        print("go_straight")
        ser.write(b'w')

    elif st == "s":
        print("stop")
        ser.write(b's')

    elif st == "d":
        ser.write(b'd')
        print("turn_righit")

    elif st == "a":
        ser.write(b'a')
        print("turn_left")

    elif st == "b":
        ser.write(b'b')
        print("go_back")

    elif st =="f":
        print("fin")
        client.disconnect()

if __name__ == '__main__':

    client = mqtt.Client(protocol=mqtt.MQTTv311)
    client.on_connect = on_connect
    client.on_message = on_message

    client.connect(host, port=port, keepalive=60)

    client.loop_forever()

sys.stderr.write("*** 終了 ***\n")

```

### MQTTのpublisherについて

メッセージの送信はスマホにmqtt通信でpublishやsubsclibeできるアプリがあるのでそれを使用してpublishすれば制御することができます。今回はパソコンでpublisihするプログラムを作成し、パソコンをコントローラとて動作させました