ArduinoロボットカーをHC-05 Bluetooth、NRF24L01、HC-12でワイヤレス制御する
このチュートリアルでは、前回作成したArduinoロボットカーをワイヤレスで制御する方法を学びます。HC-05 Bluetoothモジュール、NRF24L01トランシーバーモジュール、HC-12長距離無線モジュールの3つの異なるワイヤレス制御方法、さらにスマートフォンとカスタムメイドAndroidアプリを使用した制御方法を紹介します。詳細については以下の動画をご覧いただくか、書面によるチュートリアルをお読みください。 各モジュールのArduino接続・使用方法については個別のチュートリアルがありますので、詳細は記事下部のリンクをご覧ください。 Bluetooth通信から始めます。HC-05 Bluetoothモジュールを2個用意し、マスターとスレーブデバイスとして設定します。 ATコマンドで簡単に設定可能。ジョイスティックをマスター、Arduinoロボットカーをスレーブに設定しました。この例の完全な回路図: 必要なコンポーネント: 前回のチュートリアル(ジョイスティックで直接制御)のコードをベースに、修正を加えます。 マスターデバイス(ジョイスティック)のコードはシンプル。ジョイスティックのX、Y値(モーター速度を制御)を読み取り、シリアルポート経由でスレーブHC-05に送信。ジョイスティックのアナログ値(0〜1023)を4で割って0〜255に変換し、1バイトで送信しています。これは受信側(Arduinoロボットカー)で受け取りやすくするためです。 受信側では、シリアルで2バイト(XとY)を受信したらSerial.read()で両方を読み取ります。 受信した値を0〜1023の範囲に戻し、モーター制御コード(前回の動画で解説済み)で使用します。 ※コードアップロード時はArduinoのRX/TXピンを外す必要があります。 カスタム構築Androidアプリでロボットカーを制御する方法です。ロボットカーの回路図は前回と同じで、HC-05をスレーブモードに設定。 MIT App Inventorで独自Androidアプリを構築。アプリはジョイスティックをシミュレートし、2つの画像スプライトで外観を構成。 アプリのブロックを見ると、ジョイスティックスプライトをドラッグするとジョイスティックボール画像が指の位置に移動し、同時にX、Y値をBluetooth経由でArduinoカーに送信しています。 これらの値は前回の例と同様にSerial.read関数で受信。 スマートフォンから受信したX、Y値を0〜1023範囲に変換する必要があります。キャンバスサイズにより値が異なり、私のアプリではX、Yともに60〜220の範囲だったため、map()関数で簡単に変換。 アプリブロックでは、イメージスプライトのタッチが離れるとジョイスティックボールがキャンバス中央に戻り、カー停止用の適切な値が送信されます。このアプリとジョイスティック用の2枚の画像はWebサイト記事からダウンロード可能です。 Androidアプリとジョイスティック画像のダウンロード: 次にNRF24L01トランシーバーモジュールを使用したワイヤレス制御です。 回路図。これらのモジュールはSPI通信を使用するため、前回の例と比べてL298NドライバーのEnable A、Enable BピンをArduinoの2番、3番ピンに移動しています。 この例ではRF24ライブラリが必要。前回の例と同様に、ピン定義とモジュールを送信機として設定後、ジョイスティックのX、Y値を読み取り、ロボットカー側のNRF24L01モジュールに送信します。 アナログ読み取り値はString型で、string.toCharArray()で文字配列に格納。radio.write()でその文字配列データを送信。 受信側(ロボットカー)では、モジュールを受信機として設定後、radio.read()でデータ受信。atoi()関数で受信データ(ジョイスティックのX、Y値)を文字配列から整数値に変換し、モーター制御コードで使用。 これだけでシンプルに動作します。モジュールの接続・設定詳細については個別のチュートリアルをご覧ください。 最後の方法はHC-12長距離トランシーバーモジュールを使用。最大1.8kmの通信距離を実現できます。 この例の回路図はHC-05 Bluetoothモジュールの例とほぼ同じで、Arduinoとの通信方法もシリアルポート経由で共通です。 ジョイスティック側のコードはBluetooth通信の例と全く同じ。ジョイスティックのアナログ値を読み取り、Serial.write()で相手モジュールに送信。 受信側ではwhile()ループでデータ到着を待ち、Serial.read()で読み取り、0〜1023範囲に戻してモーター制御コードで使用。 このチュートリアルは以上です。ご質問はコメント欄でお気軽にお尋ねください。HC-05 Bluetoothモジュールを使用した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);
}// Arduinoロボットカーのコードから
// ジョイスティック(マスターBluetoothデバイス)からの着信データ読取
while (Serial.available() >= 2) {
x = Serial.read();
delay(10);
y = Serial.read();
}// Arduinoロボットカーのコードから
// 0-255範囲を0-1023に戻す(モーター制御コード用)
xAxis = x*4;
yAxis = y*4;完全な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アプリからの着信データ読取
while (Serial.available() >= 2) {
x = Serial.read();
delay(10);
y = Serial.read();
}// 正しい値を受信しているか確認
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に変換
}
Arduino_Robot_Car_Joystick_App.apk
1 file(s) 1.62 MB Download
Arduino_Robot_Car_Joystick_App_aia_file
1 file(s) 171.20 KB Download
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トランシーバーモジュールによるワイヤレス制御


ソースコード
送信機コード(ジョイスティック側)
/* 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);
}// 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長距離トランシーバーによるワイヤレス制御

ソースコード
送信機コード(ジョイスティック側)
/* 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);
}受信機コード(ロボットカー側)
/* 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);
}
製造プロセス
- Bluetooth 制御 Raspberry Pi ロボットに音声フィードバックを追加して構築
- Arduinoと1Sheeldで作る万能Androidリモコン──IR制御で家電を一括操作
- Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
- ArduinoでBluetooth経由でLEDを制御 – シンプルDIYガイド
- FirmataとXbox OneコントローラーでArduinoローバーをシームレス操作
- スマート駐車場カウンター:Arduino、Processing、PHPでリアルタイム車両管理
- Arduino IoT CloudとAlexaでテレビを音声操作:ステップバイステップガイド
- Arduino NanoとRDA5807Mで作るコンパクトFMラジオ
- ワイヤレスArduinoプログラミングシールド – HC-05 BluetoothでUSBケーブル不要に
- Arduino UnoとBluetoothでラジコンカーを遠隔操作:ステップバイステップガイド
- ArduinoとPythonでジェスチャー制御PC:ハンズフリー操作を実現