工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

このチュートリアルでは、前回作成したArduinoロボットカーをワイヤレスで制御する方法を学びます。HC-05 Bluetoothモジュール、NRF24L01トランシーバーモジュール、HC-12長距離無線モジュールの3つの異なるワイヤレス制御方法、さらにスマートフォンとカスタムメイドAndroidアプリを使用した制御方法を紹介します。詳細については以下の動画をご覧いただくか、書面によるチュートリアルをお読みください。

各モジュールのArduino接続・使用方法については個別のチュートリアルがありますので、詳細は記事下部のリンクをご覧ください。

HC-05 Bluetoothモジュールを使用したArduinoロボットカー制御

Bluetooth通信から始めます。HC-05 Bluetoothモジュールを2個用意し、マスターとスレーブデバイスとして設定します。

ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

ATコマンドで簡単に設定可能。ジョイスティックをマスター、Arduinoロボットカーをスレーブに設定しました。この例の完全な回路図:

ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

必要なコンポーネント:

  • HC-05 Bluetoothモジュール
  • ジョイスティックモジュール
  • 18650バッテリー
  • 18650バッテリーチャージャー
  • L298Nドライバー
  • 12V高トルクDCモーター
  • Arduinoボード

ソースコード

前回のチュートリアル(ジョイスティックで直接制御)のコードをベースに、修正を加えます。

HC-05 マスターコード(ジョイスティック側)

/* Arduino Robot Car Wireless Control using the HC-05 Bluetooth
   MASTER DEVICE - Joystick
   by Dejan Nedelkovski, www.HowToMechatronics.com */
int xAxis, yAxis;

void setup() {
  Serial.begin(38400); // Bluetoothモジュールのデフォルト通信レート
}

void loop() {
  xAxis = analogRead(A0); // ジョイスティックX軸読取
  yAxis = analogRead(A1); // ジョイスティックY軸読取
  // シリアルポート経由でスレーブHC-05デバイスに値を送信
  Serial.write(xAxis/4); // 0-1023を0-255(1バイト)に変換
  Serial.write(yAxis/4);
  delay(20);
}

マスターデバイス(ジョイスティック)のコードはシンプル。ジョイスティックのX、Y値(モーター速度を制御)を読み取り、シリアルポート経由でスレーブHC-05に送信。ジョイスティックのアナログ値(0〜1023)を4で割って0〜255に変換し、1バイトで送信しています。これは受信側(Arduinoロボットカー)で受け取りやすくするためです。

受信側では、シリアルで2バイト(XとY)を受信したらSerial.read()で両方を読み取ります。

// Arduinoロボットカーのコードから
// ジョイスティック(マスターBluetoothデバイス)からの着信データ読取
while (Serial.available() >= 2) {
  x = Serial.read();
  delay(10);
  y = Serial.read();
}

受信した値を0〜1023の範囲に戻し、モーター制御コード(前回の動画で解説済み)で使用します。

// Arduinoロボットカーのコードから
// 0-255範囲を0-1023に戻す(モーター制御コード用)
xAxis = x*4;
yAxis = y*4;

※コードアップロード時はArduinoのRX/TXピンを外す必要があります。

完全なHC-05 スレーブコード(ロボットカー側)

/* Arduino Robot Car Wireless Control using the HC-05 Bluetooth
   SLAVE DEVICE - Arduino robot car
   by Dejan Nedelkovski, www.HowToMechatronics.com */
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7

int xAxis, yAxis;
unsigned int x = 0, y = 0;
int motorSpeedA = 0, motorSpeedB = 0;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  Serial.begin(38400);
}

void loop() {
  // デフォルト値 - ジョイスティック中央で停止
  x = 510 / 4;
  y = 510 / 4;
  // マスターBluetoothデバイスからの着信データ読取
  while (Serial.available() >= 2) {
    x = Serial.read();
    delay(10);
    y = Serial.read();
  }
  delay(10);
  // 0-255範囲を0-1023に戻す
  xAxis = x*4;
  yAxis = y*4;
  // Y軸:前進/後退制御
  if (yAxis < 470) {
    digitalWrite(in1, HIGH); digitalWrite(in2, LOW);  // モーターA後退
    digitalWrite(in3, HIGH); digitalWrite(in4, LOW);  // モーターB後退
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  } else if (yAxis > 550) {
    digitalWrite(in1, LOW); digitalWrite(in2, HIGH);  // モーターA前進
    digitalWrite(in3, LOW); digitalWrite(in4, HIGH);  // モーターB前進
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  } else {
    motorSpeedA = 0; motorSpeedB = 0;
  }
  // X軸:左/右制御
  if (xAxis < 470) {
    int xMapped = map(xAxis, 470, 0, 0, 255);
    motorSpeedA = motorSpeedA - xMapped; // 左モーター減速
    motorSpeedB = motorSpeedB + xMapped; // 右モーター加速
    if (motorSpeedA < 0) motorSpeedA = 0;
    if (motorSpeedB > 255) motorSpeedB = 255;
  }
  if (xAxis > 550) {
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    if (motorSpeedA > 255) motorSpeedA = 255;
    if (motorSpeedB < 0) motorSpeedB = 0;
  }
  // 低速時のブーン音防止(モーターにより調整。私のモーターはPWM 70未満で動かない)
  if (motorSpeedA < 70) motorSpeedA = 0;
  if (motorSpeedB < 70) motorSpeedB = 0;
  analogWrite(enA, motorSpeedA);
  analogWrite(enB, motorSpeedB);
}

スマートフォンとカスタム構築Androidアプリによる制御

カスタム構築Androidアプリでロボットカーを制御する方法です。ロボットカーの回路図は前回と同じで、HC-05をスレーブモードに設定。

ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

MIT App Inventorで独自Androidアプリを構築。アプリはジョイスティックをシミュレートし、2つの画像スプライトで外観を構成。

ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する
ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

アプリのブロックを見ると、ジョイスティックスプライトをドラッグするとジョイスティックボール画像が指の位置に移動し、同時にX、Y値をBluetooth経由でArduinoカーに送信しています。

これらの値は前回の例と同様にSerial.read関数で受信。

// スマートフォンAndroidアプリからの着信データ読取
while (Serial.available() >= 2) {
  x = Serial.read();
  delay(10);
  y = Serial.read();
}

スマートフォンから受信したX、Y値を0〜1023範囲に変換する必要があります。キャンバスサイズにより値が異なり、私のアプリではX、Yともに60〜220の範囲だったため、map()関数で簡単に変換。

// 正しい値を受信しているか確認
if (x > 60 & x < 220) {
  xAxis = map(x, 220, 60, 1023, 0); // スマホX値を0-1023に変換
}
if (y > 60 & y < 220) {
  yAxis = map(y, 220, 60, 0, 1023); // スマホY値を0-1023に変換
}

アプリブロックでは、イメージスプライトのタッチが離れるとジョイスティックボールがキャンバス中央に戻り、カー停止用の適切な値が送信されます。このアプリとジョイスティック用の2枚の画像はWebサイト記事からダウンロード可能です。

Androidアプリとジョイスティック画像のダウンロード:

ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

Arduino_Robot_Car_Joystick_App.apk

1 file(s) 1.62 MB Download ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

Arduino_Robot_Car_Joystick_App_aia_file

1 file(s) 171.20 KB Download ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

Joystick App Images

1 file(s) 44.36 KB Download

完全なArduinoコード(スマホアプリ制御版)

/* Arduino Robot Car Wireless Control using the HC-05 Bluetooth and custom-build Android app
   SLAVE DEVICE - Arduino robot car
   by Dejan Nedelkovski, www.HowToMechatronics.com */
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7

int xAxis, yAxis;
int x = 0, y = 0;
int motorSpeedA = 0, motorSpeedB = 0;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  Serial.begin(38400);
}

void loop() {
  xAxis = 510; yAxis = 510; // デフォルト値
  while (Serial.available() >= 2) {
    x = Serial.read();
    delay(10);
    y = Serial.read();
  }
  delay(10);
  if (x > 60 & x < 220) {
    xAxis = map(x, 220, 60, 1023, 0);
  }
  if (y > 60 & y < 220) {
    yAxis = map(y, 220, 60, 0, 1023);
  }
  // Y軸:前進/後退
  if (yAxis < 470) {
    digitalWrite(in1, HIGH); digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH); digitalWrite(in4, LOW);
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  } else if (yAxis > 550) {
    digitalWrite(in1, LOW); digitalWrite(in2, HIGH);
    digitalWrite(in3, LOW); digitalWrite(in4, HIGH);
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  } else {
    motorSpeedA = 0; motorSpeedB = 0;
  }
  // X軸:左/右
  if (xAxis < 470) {
    int xMapped = map(xAxis, 470, 0, 0, 255);
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    if (motorSpeedA < 0) motorSpeedA = 0;
    if (motorSpeedB > 255) motorSpeedB = 255;
  }
  if (xAxis > 550) {
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    if (motorSpeedA > 255) motorSpeedA = 255;
    if (motorSpeedB < 0) motorSpeedB = 0;
  }
  // 低速ブーン音防止
  if (motorSpeedA < 70) motorSpeedA = 0;
  if (motorSpeedB < 70) motorSpeedB = 0;
  analogWrite(enA, motorSpeedA);
  analogWrite(enB, motorSpeedB);
}

NRF24L01トランシーバーモジュールによるワイヤレス制御

次にNRF24L01トランシーバーモジュールを使用したワイヤレス制御です。

ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する
ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

回路図。これらのモジュールはSPI通信を使用するため、前回の例と比べてL298NドライバーのEnable A、Enable BピンをArduinoの2番、3番ピンに移動しています。

ソースコード

この例ではRF24ライブラリが必要。前回の例と同様に、ピン定義とモジュールを送信機として設定後、ジョイスティックのX、Y値を読み取り、ロボットカー側のNRF24L01モジュールに送信します。

アナログ読み取り値はString型で、string.toCharArray()で文字配列に格納。radio.write()でその文字配列データを送信。

送信機コード(ジョイスティック側)

/* Arduino Robot Car Wireless Control using the NRF24L01 Transceiver module
   Transmitter - Joystick
   by Dejan Nedelkovski, www.HowToMechatronics.com
   Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(8, 9); // CE, CSN
const byte address[6] = "00001";
char xyData[32] = "";
String xAxis, yAxis;

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}

void loop() {
  xAxis = analogRead(A0);
  yAxis = analogRead(A1);
  // X値
  xAxis.toCharArray(xyData, 5);
  radio.write(&xyData, sizeof(xyData));
  // Y値
  yAxis.toCharArray(xyData, 5);
  radio.write(&xyData, sizeof(xyData));
  delay(20);
}

受信側(ロボットカー)では、モジュールを受信機として設定後、radio.read()でデータ受信。atoi()関数で受信データ(ジョイスティックのX、Y値)を文字配列から整数値に変換し、モーター制御コードで使用。

// Arduinoロボットカーのコード - NRF24L01例
if (radio.available()) {
  radio.read(&receivedData, sizeof(receivedData));
  xAxis = atoi(&receivedData[0]);
  delay(10);
  radio.read(&receivedData, sizeof(receivedData));
  yAxis = atoi(&receivedData[0]);
  delay(10);
}

これだけでシンプルに動作します。モジュールの接続・設定詳細については個別のチュートリアルをご覧ください。

受信機コード(ロボットカー側)

/* Arduino Robot Car Wireless Control using the NRF24L01 Transceiver module
   Receiver - Arduino robot car
   by Dejan Nedelkovski, www.HowToMechatronics.com
   Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define enA 2 // 注意: 前回はピン9(ピン10はNRF24L01のSPI通信で使用)
#define in1 4
#define in2 5
#define enB 3 // 注意: 前回はピン10
#define in3 6
#define in4 7

RF24 radio(8, 9);
const byte address[6] = "00001";
char receivedData[32] = "";
int xAxis, yAxis;
int motorSpeedA = 0, motorSpeedB = 0;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    radio.read(&receivedData, sizeof(receivedData));
    xAxis = atoi(&receivedData[0]);
    delay(10);
    radio.read(&receivedData, sizeof(receivedData));
    yAxis = atoi(&receivedData[0]);
    delay(10);
  }
  // Y軸:前進/後退
  if (yAxis < 470) {
    digitalWrite(in1, HIGH); digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH); digitalWrite(in4, LOW);
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  } else if (yAxis > 550) {
    digitalWrite(in1, LOW); digitalWrite(in2, HIGH);
    digitalWrite(in3, LOW); digitalWrite(in4, HIGH);
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  } else {
    motorSpeedA = 0; motorSpeedB = 0;
  }
  // X軸:左/右
  if (xAxis < 470) {
    int xMapped = map(xAxis, 470, 0, 0, 255);
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    if (motorSpeedA < 0) motorSpeedA = 0;
    if (motorSpeedB > 255) motorSpeedB = 255;
  }
  if (xAxis > 550) {
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    if (motorSpeedA > 255) motorSpeedA = 255;
    if (motorSpeedB < 0) motorSpeedB = 0;
  }
  // 低速ブーン音防止
  if (motorSpeedA < 70) motorSpeedA = 0;
  if (motorSpeedB < 70) motorSpeedB = 0;
  analogWrite(enA, motorSpeedA);
  analogWrite(enB, motorSpeedB);
}

HC-12長距離トランシーバーによるワイヤレス制御

最後の方法はHC-12長距離トランシーバーモジュールを使用。最大1.8kmの通信距離を実現できます。

この例の回路図はHC-05 Bluetoothモジュールの例とほぼ同じで、Arduinoとの通信方法もシリアルポート経由で共通です。

ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する

ソースコード

ジョイスティック側のコードはBluetooth通信の例と全く同じ。ジョイスティックのアナログ値を読み取り、Serial.write()で相手モジュールに送信。

送信機コード(ジョイスティック側)

/* Arduino Robot Car Wireless Control using the HC-12 long range wireless module
   Transmitter - Joystick
   by Dejan Nedelkovski, www.HowToMechatronics.com */
int xAxis, yAxis;

void setup() {
  Serial.begin(9600);
}

void loop() {
  xAxis = analogRead(A0);
  yAxis = analogRead(A1);
  Serial.write(xAxis/4);
  Serial.write(yAxis/4);
  delay(20);
}

受信側ではwhile()ループでデータ到着を待ち、Serial.read()で読み取り、0〜1023範囲に戻してモーター制御コードで使用。

受信機コード(ロボットカー側)

/* Arduino Robot Car Wireless Control using the HC-12 long range wireless module
   Receiver - Arduino robot car
   by Dejan Nedelkovski, www.HowToMechatronics.com */
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7

int xAxis, yAxis;
int x = 0, y = 0;
int motorSpeedA = 0, motorSpeedB = 0;

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  xAxis = 510; yAxis = 510; // デフォルト値
  while (Serial.available() == 0) {}
  x = Serial.read(); delay(10);
  y = Serial.read(); delay(10);
  xAxis = x * 4; yAxis = y * 4;
  // Y軸:前進/後退
  if (yAxis < 470) {
    digitalWrite(in1, HIGH); digitalWrite(in2, LOW);
    digitalWrite(in3, HIGH); digitalWrite(in4, LOW);
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  } else if (yAxis > 550) {
    digitalWrite(in1, LOW); digitalWrite(in2, HIGH);
    digitalWrite(in3, LOW); digitalWrite(in4, HIGH);
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  } else {
    motorSpeedA = 0; motorSpeedB = 0;
  }
  // X軸:左/右
  if (xAxis < 470) {
    int xMapped = map(xAxis, 470, 0, 0, 255);
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    if (motorSpeedA < 0) motorSpeedA = 0;
    if (motorSpeedB > 255) motorSpeedB = 255;
  }
  if (xAxis > 550) {
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    if (motorSpeedA > 255) motorSpeedA = 255;
    if (motorSpeedB < 0) motorSpeedB = 0;
  }
  // 低速ブーン音防止
  if (motorSpeedA < 70) motorSpeedA = 0;
  if (motorSpeedB < 70) motorSpeedB = 0;
  analogWrite(enA, motorSpeedA);
  analogWrite(enB, motorSpeedB);
}

このチュートリアルは以上です。ご質問はコメント欄でお気軽にお尋ねください。

製造プロセス

  1. Bluetooth 制御 Raspberry Pi ロボットに音声フィードバックを追加して構築
  2. Arduinoと1Sheeldで作る万能Androidリモコン──IR制御で家電を一括操作
  3. Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
  4. ArduinoでBluetooth経由でLEDを制御 – シンプルDIYガイド
  5. FirmataとXbox OneコントローラーでArduinoローバーをシームレス操作
  6. スマート駐車場カウンター:Arduino、Processing、PHPでリアルタイム車両管理
  7. Arduino IoT CloudとAlexaでテレビを音声操作:ステップバイステップガイド
  8. Arduino NanoとRDA5807Mで作るコンパクトFMラジオ
  9. ワイヤレスArduinoプログラミングシールド – HC-05 BluetoothでUSBケーブル不要に
  10. Arduino UnoとBluetoothでラジコンカーを遠隔操作:ステップバイステップガイド
  11. ArduinoとPythonでジェスチャー制御PC:ハンズフリー操作を実現