【SPRESENSE2024】esp32とSpresenseによるモデム機能制御"eNord"の構築
作成者: リナちゃん
はじめに
近年、IoT技術の進展に伴い、さまざまな通信機能を内蔵したデバイスの需要が高まっています。特に、モバイルデバイスやロボットにおいては、低消費電力で高い通信機能を持つモジュールが求められています。本研究では、Sony Spresenseを使用したロボット制御システムにおいて、通信機能を実現するためにESP32-S3を使用し、これをESP-NOWを介した通信に活用する方法 eNordType を提案します。
Spresense本体には、通信機能が搭載されていないため、別途、ESP32-S3を利用してモデム機能を追加し、ESP-NOWプロトコルを活用することで、簡単に通信機能を確保できることを実証しました。また、ESP32-S3を使用することで、複数の通信モジュールを個別に用意する必要がなく、単体での通信機能の実現が可能となります。
システム構成
本研究で構築したシステムは、以下の三つの主要なモジュールから成り立っています:
motorSide
ロボットのモーターを制御する部分。壁センサ(前および右)を使用して障害物の位置を検出し、その情報をspreSideに送信します。
spreSide
ESP32-S3を活用した通信モジュール。motorSideから送信された壁センサ情報を受信し、Spresense本体へ転送する役割を担います。ここでは、ESP-NOWを使用して通信を行います。
spreSense
Sony Spresense本体。この部分では、受信した壁情報を元にマップ情報を計算し、ロボットの移動経路や障害物回避経路を決定します。
通信機能
ESP-NOWによる通信
本システムでは、ESP32-S3に搭載されているESP-NOWを使用して、motorSideとspreSide間のデータ通信を行います。ESP-NOWは、Wi-Fiを介さずにデバイス間で直接通信を行う技術であり、低消費電力かつ高速な通信が可能です。この技術により、通信の遅延を最小限に抑え、リアルタイムで壁センサ情報を送受信することができます。
I2C通信による情報転送
さらに、spreSideは、I2C通信を使用して、motorSideで取得されたセンサーデータをSpresense本体に転送します。I2C通信を使用することで、複数のデバイス間で簡単にデータのやり取りができるため、センサーデータを効率的に処理することが可能となります。
システム動作の詳細
motorSideにおけるデータ取得
motorSideには、壁センサ(前および右)が接続されています。これらのセンサから得られたデータは、瞬時にspreSideに送られます。送信されたデータは、spreSideで受信後、Spresense本体に転送され、さらに高度な処理が行われます。motorSideでは、壁センサを利用して障害物の位置をリアルタイムで把握し、その情報を基にロボットの移動経路を制御することが可能となります。
SpreSenseでの計算と制御
Spresense本体では、受信した壁情報を基に、障害物回避や経路計算を行います。これには、Spresenseの6つのコアをフル活用して計算処理を行うため、リアルタイムでのマップ生成や移動経路の決定が可能となります。この計算結果を元に、spreSideからmotorSideへ指示が送られ、ロボットのモーターを制御することができます。
実験結果
wallセンサーデータの転送
実験では、motorSideで取得された壁情報(前および右のセンサーデータ)は、瞬時にspreSideへ送信され、Spresense本体に転送されました。これにより、Spresenseでは、あたかもその壁情報が直接取得されたかのように動作し、計算を行うことができました。この結果、ロボットは障害物を回避しながら自律的に移動することができました。
マップ情報と移動情報の転送
Spresenseで計算されたマップ情報および移動情報は、spreSideを通じてmotorSideに送信され、その情報に基づいてモーターが駆動されます。この一連の動作により、ロボットは障害物を避けながら目的地に向かって移動することが可能となり、実用的な自律移動システムを構築することができました。
結論
本研究では、SpresenseとESP32-S3を活用した通信機能およびロボット制御システム eNordType を構築しました。ESP32-S3を使用することで、ESP-NOWを介した低消費電力かつ高速な通信を実現し、motorSideからspreSide、そしてSpresense本体へのデータ転送を効率的に行うことができました。さらに、Spresense本体の強力な計算能力を活用することで、リアルタイムでの障害物回避や移動経路の計算を行い、ロボットの自律移動を実現しました。今後は、このシステムをさらに発展させ、より複雑な環境下での自律移動を実現することを目指します。
サンプルコード
※詳細は後日
#include "spreWireLib.hpp"
//===========================
// spreSense.ino
// eNordType
//===========================
void setup() {
setupSpre();
delay( 5000 );
cpuToeNord(STX, 0, 0, 0, ETX);
}
// 5v:7..993 3v3:7..656
void loop() {
uint8_t left, right;
int dt0 = analogRead(A0);
int dt1 = analogRead(A1);
left = map(dt, 7, 656, 0, 255);
right = map(dt, 7, 656, 0, 255);
cpuToeNord(left, right);
dataDump((uint8_t *)eNord, sizeof(eNord));
}
//===========================
// spreSide.ino
// eNordType
//===========================
#define GROVE
#include "esp32S3Lib.hpp"
void setup() {
setupS3(WIRE_SLAVE_ADRS, DEFAULT_BRIGHTNESS);
delay(5000);
setupEspNow();
}
void loop() {
COLOR_T col;
memset(&col, 0x0, sizeof(col));
if (eNord[ENORD_WALL]) col.b = 255;
else col.g = 255;
breathNeo(60, col.r, col.g, col.b);
sendData(100);
dataDump((uint8_t *)eNord, sizeof(eNord));
}
//===========================
// motorSide.ino
// eNordType
//===========================
#define GROVE
#include "esp32S3Lib.hpp"
void setup() {
setupS3(WIRE_MASTER_ADRS, DEFAULT_BRIGHTNESS);
delay(5000);
setupEspNow();
}
void loop() {
breathNeo(60, 0, 255, 0);
int wallStat = getWallStat();
eNord[ENORD_WALL] = wallStat;
sendData(100);
driveMotor();
dataDump((uint8_t *)eNord, sizeof(eNord));
}
参考文献
- 旧バージョン:https://elchika.com/article/752e331b-792c-415d-bbdf-ab2a3a2b82ce/
- Sony Spresense公式サイト: https://developer.sony.com/spresense/development-guides/arduino_developer_guide_ja.html
- ESP32-S3技術仕様: https://www.espressif.com/en/products/socs/esp32-s3
- ESP-NOWの技術仕様と実装方法: https://www.espressif.com/en/products/software/esp-now
投稿者の人気記事
-
chrmlinux03
さんが
2024/12/12
に
編集
をしました。
(メッセージ: 初版)
-
chrmlinux03
さんが
2024/12/12
に
編集
をしました。
(メッセージ: なんとかかんとか追加)
-
chrmlinux03
さんが
2024/12/12
に
編集
をしました。
(メッセージ: とび先が....)
-
chrmlinux03
さんが
2024/12/12
に
編集
をしました。
(メッセージ: mdを直した)
-
chrmlinux03
さんが
2024/12/15
に
編集
をしました。
(メッセージ: eNordタグ追加)
ログインしてコメントを投稿する