ESP32にはWi-FiやBluetoothを使った無線通信機能があります。
しかし、ESP32同士でちょっとしたデータをやり取りしたいだけなら、
「Wi-Fiルーターに接続する必要があるの?」
「アクセスポイントやサーバーを用意しないと通信できないの?」
と思うかもしれません。
そんなときに利用できるのがESP-NOWです。
ESP-NOWを使うと、Wi-Fiルーターを経由せず、ESP32同士で直接無線通信できます。
この記事では、
- ESP-NOWとは何か
- Wi-Fi通信との違い
- ESP-NOWでできること
- MACアドレスとは何か
- 送信側と受信側の考え方
- ESP32同士で実際にデータを送受信する方法
を初心者向けに解説します。
ESP-NOWとは?
ESP-NOWは、Espressifが提供しているESP32シリーズ向けの無線通信方式です。
ESP32に搭載されている無線機能を利用して、対応デバイス同士で直接データをやり取りできます。
大きな特徴は、一般的なWi-Fi通信のようにWi-Fiルーターへ接続しなくてもESP32同士で通信できることです。
イメージすると、
一般的なWi-Fi通信
ESP32
↓
Wi-Fiルーター
↓
ESP32
に対して、ESP-NOWでは、
ESP-NOW
ESP32 ─────→ ESP32
という形で直接通信できます。
そのため、ESP32同士でセンサーデータや操作情報などの小さなデータをやり取りしたい用途に便利です。
ESP-NOWでは何ができる?
ESP-NOWを使うと、離れたESP32へさまざまなデータを送信できます。
たとえば、
- ボタンが押されたことを送る
- センサーの測定値を送る
- LEDを点灯する指示を送る
- モーターの操作情報を送る
- 別のESP32へ状態を通知する
といった使い方ができます。
たとえば送信側のESP32にボタンを接続して、
ボタンを押す
↓
ESP-NOWで「前進」というデータを送る
↓
受信側ESP32がデータを受信する
↓
モーターを回す
とすれば、無線リモコンのようなものも作れます。
また、センサーの値を送れば、
センサー
↓
ESP32
↓ ESP-NOW
ESP32
↓
表示・記録・制御
といったシステムも作れます。
ESP-NOWとWi-Fi通信は何が違う?
ESP32には通常のWi-Fi通信機能もあります。
たとえばESP32を自宅のWi-Fiルーターへ接続し、インターネット上のサーバーへデータを送信することができます。
一方、ESP-NOWはESP32同士の直接通信に向いています。
大まかに分けると、
| ESP-NOW | 一般的なWi-Fi通信 | |
|---|---|---|
| Wi-Fiルーター | 不要 | 基本的に使用 |
| インターネット | 不要 | 利用可能 |
| ESP32同士の直接通信 | 得意 | 構成による |
| 小さなデータの送受信 | 得意 | 可能 |
| Webアクセス | 不向き | 得意 |
という違いがあります。
「インターネットへ接続したい」のであれば通常のWi-Fi通信が適しています。
一方、
「ESP32から別のESP32へデータを送りたい」
という用途なら、ESP-NOWは有力な選択肢になります。
ESP-NOWではMACアドレスを使う
ESP-NOWを使うときに重要なのがMACアドレスです。
MACアドレスは、ネットワーク機器を識別するためのアドレスです。
たとえば、
24:6F:28:AA:BB:CC
のような形式で表されます。
ESP-NOWで特定のESP32へデータを送信する場合、基本的には送信先ESP32のMACアドレスを指定します。
イメージとしては、
送信側ESP32
「このMACアドレスのESP32へ送信」
↓
ESP-NOW
↓
受信側ESP32
という関係です。
そのため、ESP-NOWを試すときは最初に受信側ESP32のMACアドレスを確認しておくと分かりやすいです。
ESP32のMACアドレスを確認する
Arduino環境では、ESP32のMACアドレスをプログラムから確認できます。
たとえば次のようなプログラムです。
#include <WiFi.h>
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
Serial.print("MAC Address: ");
Serial.println(WiFi.macAddress());
}
void loop() {
}
プログラムを書き込み、シリアルモニターを開くとMACアドレスが表示されます。
表示されたMACアドレスは、後ほど送信側のプログラムで使用します。
ESP-NOW通信の流れ
今回はESP32を2台使います。
役割を、
ESP32①:送信側
ESP32②:受信側
とします。
最初は複雑なデータを送るのではなく、整数値を1つ送ってみましょう。
たとえば、
123
という値を送信側から送ります。
受信側では、
受信データ:123
とシリアルモニターへ表示します。
まずはこの最小構成でESP-NOW通信ができることを確認します。
受信側ESP32のプログラム
まず受信側を作ります。
Arduino環境で次のようなプログラムを書き込みます。
#include <WiFi.h>
#include <esp_now.h>
void onDataRecv(const esp_now_recv_info_t *info,
const uint8_t *incomingData,
int len) {
int receivedValue;
memcpy(&receivedValue, incomingData, sizeof(receivedValue));
Serial.print("受信データ: ");
Serial.println(receivedValue);
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOWの初期化に失敗しました");
return;
}
esp_now_register_recv_cb(onDataRecv);
Serial.println("ESP-NOW受信待機中");
}
void loop() {
}
ESP-NOWでは、データを受信すると登録したコールバック関数が呼び出されます。
今回の場合は、
onDataRecv()
が呼び出されます。
受信したデータをmemcpy()で整数型の変数へコピーし、シリアルモニターへ表示しています。
送信側ESP32のプログラム
次に送信側を作ります。
送信側では、先ほど確認した受信側ESP32のMACアドレスを指定します。
たとえば受信側のMACアドレスが、
24:6F:28:AA:BB:CC
だったとします。
プログラムでは次のように記述します。
#include <WiFi.h>
#include <esp_now.h>
// 受信側ESP32のMACアドレスに変更してください
uint8_t receiverAddress[] = {
0x24, 0x6F, 0x28, 0xAA, 0xBB, 0xCC
};
esp_now_peer_info_t peerInfo = {};
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("ESP-NOWの初期化に失敗しました");
return;
}
memcpy(peerInfo.peer_addr,
receiverAddress,
6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("送信先の登録に失敗しました");
return;
}
Serial.println("ESP-NOW送信開始");
}
void loop() {
int sendValue = 123;
esp_err_t result = esp_now_send(
receiverAddress,
(uint8_t *)&sendValue,
sizeof(sendValue)
);
if (result == ESP_OK) {
Serial.println("送信しました");
} else {
Serial.println("送信に失敗しました");
}
delay(1000);
}
このプログラムでは、1秒ごとに整数値123を送信しています。
ESP-NOWで通信してみよう
2台のESP32へそれぞれプログラムを書き込んだら、受信側のシリアルモニターを開きます。
通信できていれば、
ESP-NOW受信待機中
受信データ: 123
受信データ: 123
受信データ: 123
のように表示されます。
これで、
送信側ESP32
↓
ESP-NOW
↓
受信側ESP32
という基本的な無線通信ができました。
Wi-Fiルーターを用意しなくても、ESP32同士でデータを送受信できることが分かります。
数値だけでなく複数のデータも送れる
実際の電子工作では、整数値1つだけでなく複数の情報をまとめて送りたいことがあります。
たとえば、
- X方向の値
- Y方向の値
- ボタンの状態
などです。
このような場合は構造体を使ってデータをまとめると扱いやすくなります。
たとえば、
typedef struct {
int x;
int y;
bool button;
} ControlData;
のような構造体を作ります。
送信側と受信側で同じ構造を使用すれば、
x = 100
y = -50
button = true
といった複数の値をまとめて送ることができます。
この方法を使うと、リモコンやセンサーなどの情報を別のESP32へ送信しやすくなります。
ESP-NOWを使うと何が作れる?
ESP-NOWの基本は非常にシンプルです。
データを作る
↓
送信する
↓
別のESP32が受信する
↓
受信したデータに応じて処理する
という流れです。
この「受信したデータに応じて処理する」の部分を変えることで、さまざまな電子工作へ発展できます。
たとえば、
無線スイッチ
送信側のボタンを押すと、離れたESP32のLEDが点灯する。
無線センサー
温度や明るさなどの測定値を別のESP32へ送る。
無線リモコン
ボタン操作を送信して、別のESP32に接続されたモーターを動かす。
モーターカー
前進・後退・左右旋回の指示をESP-NOWで送り、離れた場所から操作する。
などです。
KUMITATE-C3を2台使って無線通信にも発展できる
KUMITATE-C3にはESP32-C3を搭載しているため、ESP-NOWを利用した無線通信にも発展できます。
たとえばKUMITATE-C3を2台用意して、
KUMITATE-C3
送信側
│
│ ESP-NOW
▼
KUMITATE-C3
受信側
という構成にできます。
送信側のボタン操作を受信側へ送ったり、センサーで取得した値を別のKUMITATE-C3へ送ったりできます。
ここまでできると、単体のマイコンだけではなく、複数のマイコンが無線で連携するシステムを作れるようになります。
次はESP-NOWでモーターカーを操作してみよう
ESP-NOWの基本的な送受信ができたら、次は実際の制御へ発展させてみましょう。
次の記事ではKUMITATE-C3を2台使用します。
【リモコン側】
KUMITATE-C3
4つのボタン
│
│ ESP-NOW
▼
【モーターカー側】
KUMITATE-C3
│
KUMITATE-MOTOR
│
左右DCモーター
リモコン側の4つのボタンを、
- 前進
- 後退
- 左
- 右
に割り当てます。
ボタンが押されたらESP-NOWで操作情報を送信し、受信側のKUMITATE-C3がKUMITATE-MOTORを制御します。
これによって、Wi-Fiルーターを使わずにESP32同士で通信する無線モーターカーを作ることができます。
さらに加速度センサーを利用すれば、ボタンではなくコントローラーを傾けてモーターカーを操作するといった発展も可能です。
参考)
まとめ
今回はESP-NOWの基本と、ESP32同士でデータを送受信する方法を紹介しました。
ポイントは、
- ESP-NOWはESP32シリーズで利用できる無線通信方式
- Wi-Fiルーターを経由せず対応デバイス同士で通信できる
- 送信先を識別するためにMACアドレスを使用できる
- 数値などの小さなデータを送受信できる
- 構造体を使えば複数の値をまとめて送信できる
- ボタン、センサー、モーターなどと組み合わせられる
というところです。
まずはESP32を2台使って、単純な数値を送受信するところから試してみましょう。
ESP-NOWによる通信ができれば、その先は**「受信したデータで何を動かすか」**によってさまざまな電子工作へ発展できます。

