M5NanoC6、加速度センサー(ADXL345)を無線電送して遊ぶ。(ESP-NOW)


参考

https://qiita.com/caa45040/items/75c2cda3e2c3b6bc2452


x 過去ログを見よ!!
x USBシリアルがかけるが気にするな!
x パケロスするが気にするな!!
x ブロードキャストがわかる人
x 積極的に書かなかったが、なぜか受信の割り込み関数でメモリを食う
処理ゃ時間の掛る処理をするとなぜかセグメントエラーで落ちる


転送データの形式(固定長)

-00.00,-00.00,-00.00[0x00]

ex 

004.00,000.01,-09.80[0x00]
-09.80,000.03,000.10[0x00]


結果


![o_coq647.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9568c1f4-d876-c51d-1eca-cedfa0100e08.jpeg)

![o_coq648.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8c7a5ea5-ee71-7181-fbc9-f8f1f75ecf33.jpeg)


![o_coq649.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1a85f23c-30ce-9f4a-2847-c137fbf43c41.jpeg)

![o_coq650.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9bcbe269-f20a-fd8e-dba5-2baf7cd67219.jpeg)



プログラム

ホスト NanoC6 加速度センサー


```c++




//ESP32_NOW_m_ADXL345_M5NanoC6_1
//1対1に改造する　対応
//ブロードキャスト


//インクルド
//加速度センサー
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
//ESP-NOW
#include "ESP32_NOW.h"
#include "WiFi.h"
#include <esp_mac.h>  // For the MAC2STR and MACSTR macros


//定義
//加速度センサー
/* Assign a unique ID to this sensor at the same time */

Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

/* Definitions */
//WiFiチャンネルの指定
#define ESPNOW_WIFI_CHANNEL 1

//クラス
/* Classes */

// Creating a new class that inherits from the ESP_NOW_Peer class is required.

class ESP_NOW_Broadcast_Peer : public ESP_NOW_Peer {
  public:
    // Constructor of the class using the broadcast address
    ESP_NOW_Broadcast_Peer(const uint8_t *mac_addr, uint8_t channel, wifi_interface_t iface, const uint8_t *lmk) : ESP_NOW_Peer(mac_addr, channel, iface, lmk) {}

    // Destructor of the class
    ~ESP_NOW_Broadcast_Peer() {
      remove();
    }

    // Function to properly initialize the ESP-NOW and register the broadcast peer
    bool begin() {
      if (!ESP_NOW.begin() || !add()) {
        log_e("Failed to initialize ESP-NOW or register the broadcast peer");
        return false;
      }
      return true;
    }

    // Function to send a message to all devices within the network
    bool send_message(const uint8_t *data, size_t len) {
      if (!send(data, len)) {
        log_e("Failed to broadcast message");
        return false;
      }
      return true;
    }
};

/* Global Variables */

//ブロードキャスト オブジェクトの定義
// Create a broadcast peer object
ESP_NOW_Broadcast_Peer broadcast_peer(ESP_NOW.BROADCAST_ADDR, ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);

//const MacAddress peer_mac({0x48, 0x27, 0xe2, 0xe3, 0xbd, 0x50});
//ESP_NOW_Broadcast_Peer broadcast_peer(  peer_mac  , ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);

/* Main */

#define CP (uint8_t *)

//浮動小数点-12.34を文字列の"-12.34"に変換
void ch_conv(char *buf,float f){
    
    int n; //変換元
    int a; //一時変数
    
    n = (int)(f * 100);

    // 0123456
    // -12.34_

    buf[0]='0';
    buf[3]='.';
    buf[6]=0;

    //符号を外す
    if(n < 0) {n = 0 - n;buf[0]='-';}

    a = (n * 52429) >> 19; // n / 10;
    buf[5] = '0' + n - (a * 10);
    n = a;

    a = (n * 52429) >> 19; // n / 10;
    buf[4] = '0' + n - (a * 10);
    n = a;

    a = (n * 52429) >> 19; // n / 10;
    buf[2] = '0' + n - (a * 10);
    n = a;

    a = (n * 52429) >> 19; // n / 10;
    buf[1] = '0' + n - (a * 10);
    //n = a;

}//ch_conv


//初期化
void setup() {

  //WiFiの初期化
  // Initialize the Wi-Fi module
  WiFi.mode(WIFI_STA);
  WiFi.setChannel(ESPNOW_WIFI_CHANNEL);
  delay(3000);//決め打ちなので、おかしかったら調整してね!

  //ブロードキャストの初期化
  // Register the broadcast peer
  if (!broadcast_peer.begin()) {
    delay(5000); //瞬リセット防止用
    ESP.restart(); //リセット
  }//endif

  //テストメッセージを送る debug
  //         012345678901234567890
  char pp[]="000.00,000.00,-09.80";
  delay(5);
  broadcast_peer.send_message(CP(pp), 19+1);
  delay(5);
  broadcast_peer.send_message(CP(pp), 19+1);
  delay(5);
  broadcast_peer.send_message(CP(pp), 19+1);
  delay(5);

  /* Initialise the sensor */
  if(!accel.begin()){ //失敗
    /* There was a problem detecting the ADXL345 ... check your connections */

    while(1){delay(1);};//無限ループ
  }//endif

  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);

}//setup


//            012345678901234567890
char hhh[] = "000.00,000.00,-09.80";

//メインループ
void loop() {

  /* Get a new sensor event */ 
  sensors_event_t event; 
  accel.getEvent(&event);

  // メッセージの変換
  ch_conv(&hhh[0],(float)(event.acceleration.x));

  // メッセージの変換
  ch_conv(&hhh[7],(float)(event.acceleration.y));

  // メッセージの変換
  ch_conv(&hhh[14],(float)(event.acceleration.z));

  //            012345678901234567890
  //           "000.00,000.00,-09.80"
  hhh[6]  = ',';
  hhh[13] = ',';
  hhh[20] = 0;

  broadcast_peer.send_message(CP(hhh), 19+1);delay(5);
  delay(1000);

}//loop


```

スレーブ　StampS3 シリアル出力

```c++



//ESP32_NOW_s_print_M5StampS3_1
//1対1に改造する　対応
//ブロードキャスト


/*
    ESP-NOW Broadcast Slave
    Lucas Saavedra Vaz - 2024

    This sketch demonstrates how to receive broadcast messages from a master device using the ESP-NOW protocol.

    The master device will broadcast a message every 5 seconds to all devices within the network.

    The slave devices will receive the broadcasted messages. If they are not from a known master, they will be registered as a new master
    using a callback function.
*/


//インクルド
#include <Arduino.h>

#include "ESP32_NOW.h"
#include "WiFi.h"

#include <esp_mac.h>  // For the MAC2STR and MACSTR macros

#include <vector>

#include "MacAddress.h"


//定義
/* Definitions */

#define ESPNOW_WIFI_CHANNEL 1

//クラス
/* Classes */

// Creating a new class that inherits from the ESP_NOW_Peer class is required.

class ESP_NOW_Peer_Class : public ESP_NOW_Peer {
public:
  // Constructor of the class
  ESP_NOW_Peer_Class(const uint8_t *mac_addr, uint8_t channel, wifi_interface_t iface, const uint8_t *lmk) : ESP_NOW_Peer(mac_addr, channel, iface, lmk) {}

  // Destructor of the class
  ~ESP_NOW_Peer_Class() {}

  // Function to register the master peer
  bool add_peer() {
    if (!add()) {
      log_e("Failed to register the broadcast peer");
      return false;
    }
    return true;
  }

  // Function to print the received messages from the master
  void onReceive(const uint8_t *data, size_t len, bool broadcast) {
    
    Serial.printf("Received a message from master " MACSTR " (%s)\n", MAC2STR(addr()), broadcast ? "broadcast" : "unicast");
    Serial.printf("  Message: %s\n", (char *)data);
  }
};

/* Global Variables */

// List of all the masters. It will be populated when a new master is registered
std::vector<ESP_NOW_Peer_Class> masters;

/* Callbacks */

// Callback called when an unknown peer sends a message
void register_new_master(const esp_now_recv_info_t *info, const uint8_t *data, int len, void *arg) {

//自分
const MacAddress peer_mac1({0x48, 0x27, 0xe2, 0xe3, 0xbd, 0x50});
unsigned char a_add[6] ={0x48, 0x27, 0xe2, 0xe3, 0xbd, 0x50};
//相手
const MacAddress peer_mac2({0x40, 0x4c, 0xca, 0x5a, 0xe3, 0x1c});

  if (memcmp(info->des_addr, ESP_NOW.BROADCAST_ADDR, 6) == 0) {
  //if (memcmp(info->des_addr, a_add, 6) == 0) {
    Serial.printf("Unknown peer " MACSTR " sent a broadcast message\n", MAC2STR(info->src_addr));
    Serial.println("Registering the peer as a master");



    ESP_NOW_Peer_Class new_master(info->src_addr, ESPNOW_WIFI_CHANNEL, WIFI_IF_STA, NULL);

    masters.push_back(new_master);
    if (!masters.back().add_peer()) {
      Serial.println("Failed to register the new master");
      return;
    }
  } else {
    // The slave will only receive broadcast messages
    log_v("Received a unicast message from " MACSTR, MAC2STR(info->src_addr));
    log_v("Igorning the message");
  }
}


/* Main */

//初期化
void setup() {

  //WiFiの初期化
  // Initialize the Wi-Fi module
  WiFi.mode(WIFI_STA);
  WiFi.setChannel(ESPNOW_WIFI_CHANNEL);

  Serial.begin(115200); //シリアルポート
  for(int i=0;i<9;i++){
    Serial.print(".");
    delay(500);//接続待ち
  }//for
  Serial.println();

  while (!WiFi.STA.started()) {
    delay(500);//接続待ち
  }

  //アドレスとWiFiチャンネルの表示
  Serial.println("ESP-NOW Example - Broadcast Slave");
  Serial.println("Wi-Fi parameters:");
  Serial.println("  Mode: STA");
  Serial.println("  MAC Address: " + WiFi.macAddress());
  Serial.printf("  Channel: %d\n", ESPNOW_WIFI_CHANNEL);

  //ブロードキャストの初期化
  // Initialize the ESP-NOW protocol
  if (!ESP_NOW.begin()) {
    Serial.println("Failed to initialize ESP-NOW");
    Serial.println("Reeboting in 5 seconds...");
    delay(5000); //瞬リセット防止用
    ESP.restart(); //リセット
  }//endif

  //ESP-NOWのコールバック
  // Register the new peer callback
  ESP_NOW.onNewPeer(register_new_master, NULL);

  Serial.println("Setup complete. Waiting for a master to broadcast a message...");

}//setup


//メインループ
void loop() {

    delay(300);//ダミー
   
}//loop


```