ESP-NOWはESP系マイコン同士の通信方法で,MACアドレスを使って1対1、1対多などの無線通信ができます。

ESP系マイコン同士のお手軽な無線通信ESP-NOWを試してみた

今回はESP-NOWをESP32C3の1対1通信で使い,実際にDCモータやR/Cサーボをリモートコントロールしてみました。


試作のシステムです。
送受信ともにXIAO ESP32C3 を使っています。





送信側の装置です。

・MCU:Seeed Studio XIAO ESP32-C3
・アナログ・デジタル入力
 A0, A1:DCモータ値 アナログ入力(12bit)
 A2:R/Cサーボ値 アナログ入力(12bit)
 D8, D9, D10:タクトスイッチ値 デジタル入力





受信側の装置です。

・MCU:Seeed Studio XIAO ESP32-C3
・DC ギアードモータ
 D0, D1:モータ1 ドライバを介しての pwm 制御
 D2, D3:モータ2 ドライバを介しての pwm 制御
・R/Cサーボ
 I2Cによるサーボドライバ(自作ATtiny1604)を介しての 制御
・LED
 D8, D9, D10:デジタル出力





実際の動作の短い(^^;;;動画です。





思ったより機敏に動いてくれて,内心満足しています(^^)。

今回は小さいMCUに主に入出力ともに直付けでコントロールの種類が少ないですね。これはI2Cとか使えば拡張できますし,ま,素直に入出力ピン数の多いMCUを使うというのもアリですね。



せっかく動いたので送受信のプログラムもメモしておきます。

送信側のプログラムです。


/* XIAO_ESP32C3 ESP-NOW Sender Code test1 */

#include <WiFi.h>
#include <esp_now.h>

// Set Receiver_Address (MAC Address)
uint8_t Receiver_Address[] = {0x58, 0x8c, 0x81, 0x--, 0x--, 0x--};


// Create a struct_message called myData
typedef struct {
   int m1;
   int m2;
   int s1;
   byte red;
   byte green;
   byte blue;
} struct_message;

struct_message myData;


// create peer_info
esp_now_peer_info_t peerInfo;


// callback function will be executed when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
   Serial.print("\r\nLast Packet Send Status:\t");
   Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}


void setup() {

 pinMode(8, INPUT);
 pinMode(9, INPUT);
 pinMode(10,INPUT);

   
   // Initialize Serial
   Serial.begin(115200);

   // Set device as Wi-Fi Station mode
   WiFi.mode(WIFI_STA);

   // Init ESP-NOW
   if (esp_now_init() != ESP_OK) {
       Serial.println("Error initializing ESP-NOW");
       return;
   }

   // Set a callback_function that will be executed when data is sent
   esp_now_register_send_cb(OnDataSent);

   // Set peer_Info
   memcpy(peerInfo.peer_addr, Receiver_Address, 6); // Set receiver address
   peerInfo.channel = 0;       // Set channel 0
   peerInfo.encrypt = false;   // No encryption
   
   if (esp_now_add_peer(&peerInfo) != ESP_OK){  // add peer node and Error check
       Serial.println("Failed to add peer");
       return;
   }

} // setup end


void loop() {

   // Insert test_data into myData
   // Read Analog data (12bit) and Button switch
   myData.m1 = analogRead(A0);
   myData.m2 = analogRead(A1);
   myData.s1 = analogRead(A2);
   myData.red = digitalRead(8);
   myData.green = digitalRead(9);
   myData.blue = digitalRead(10);
  
   // Send data
   esp_now_send(Receiver_Address, (uint8_t *) &myData, sizeof(myData));
   
   delay(100);

} // loop end





受信側のプログラムです。


/* XIAO_ESP32C3 Receiver Code test1 */

// ESP-NOW
#include <WiFi.h>
#include <esp_now.h>

// I2C Target Slave_Address 6 for R/C servo
#include <Wire.h>
#define slave_Address 6

//#include <ESP32PWM.h>
//ESP32PWM pwm;

// Create a struct_message called myData
typedef struct {
   int m1;
   int m2;
   int s1;
   byte red;
   byte green;
   byte blue;
} struct_message;

struct_message myData;


// callback function will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
 memcpy(&myData, incomingData, sizeof(myData));
 Serial.print("Bytes received: ");
 Serial.println(len);
 Serial.print("m1m2s1: ");
 Serial.print(myData.m1);
 Serial.print(", ");
 Serial.print(myData.m2);
 Serial.print(", ");
 Serial.println(myData.s1);
 Serial.print (myData.red);
 Serial.print (myData.green);
 Serial.println (myData.blue);
 
 // DC motor1
 int mv=map(myData.m1, 0, 4095, -255, 255);
 if (mv < 0){
   analogWrite(2, 0);
   analogWrite(3, (byte)-mv);
 }else{
   analogWrite(2, (byte)mv);
   analogWrite(3, 0);
 }

 // DC motor2
 mv=map(myData.m2, 0, 4095, -255, 255);
 if (mv < 0){
   analogWrite(4, 0);
   analogWrite(5, (byte)-mv);
 }else{
   analogWrite(4, (byte)mv);
   analogWrite(5, 0);
 }

 // R/C Servo (via I2C driver)
 Wire.beginTransmission(slave_Address);
   Wire.write(1);                    // servo number
   Wire.write((byte)(myData.s1 & 0x00FF));  // Low byte
   Wire.write((byte)(myData.s1 >> 8));      // High byte
 Wire.endTransmission();
 delay(20);

 // Color LED
 digitalWrite(8,myData.red);
 digitalWrite(9,myData.green);
 digitalWrite(10,myData.blue);

}

void setup() {
 // Initialize Serial
 Serial.begin(115200);

 // Initialize I2C
 Wire.begin();

// Initialize  output_Pin
 for (byte i = 2; i <6; i++){  // pwm
   pinMode(i, OUTPUT);
}
 for (byte i = 8; i <11; i++){ // LED
   pinMode(i, OUTPUT);
}

 // Set device as Wi-Fi Station mode
 WiFi.mode(WIFI_STA);

 // Init ESP-NOW
 if (esp_now_init() != ESP_OK) {
   Serial.println("Error initializing ESP-NOW");
   return;
 }
 
 // Set a callback_function that will be executed when data is received
 esp_now_register_recv_cb(OnDataRecv);

} // setup end


void loop() {

} // loop end