M5NanoC6、チャイムを作って遊ぶ。(ESP-NOW)(ブロードキャスト)


x 過去ログを見よ
x パケットが欠損するが気にするな!!

目的
NanoC6の内蔵ボタンとStampS3とブザーを使ってチャイムを作る

通信方式
ESP-NOW
STAモード
ブロードキャスト
距離　約20mぐらい

よほどの事がないかぎり20m以内に別のESP-NOWが入る事は、ない
WiFi通信の激しい混信は、あるが気にするな(ここは、東京近郊で最強WiFiが10局以上常に入る(速度低下が常に起きる(さらに最強Wifiを導入)))
M5NanoC6の加熱防止の為にキー押すとキー離すのデータ通信になつて
通信が失敗するとなりっぱなしになるが気にするな
(いちおう、タイムアウトで鳴りやむようにする)なしとする


結果

![o_coq541.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/aca78937-dae9-09dd-ef59-0767d160a468.jpeg)

(ホストとスレーブ)

![o_coq542.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/57569370-dffb-521b-e9f8-ef944b261e30.jpeg)


![o_coq543.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ec781a0b-d7f0-d183-d8be-7521cd3a45de.jpeg)



プログラム

(NanoC6(ボタン)　ホスト)


```c++


//ESP32_NOW_m_button1_M5NanoC6


//インクルド
#include <M5NanoC6.h> //SW
#include "ESP32_NOW.h"
#include "WiFi.h"
#include <esp_mac.h>  // For the MAC2STR and MACSTR macros


//定義
/* 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(uint8_t channel, wifi_interface_t iface, const uint8_t *lmk) : ESP_NOW_Peer(ESP_NOW.BROADCAST_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 */

uint32_t msg_count = 0;

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

/* Main */

#define CP (uint8_t *)


//初期化
void setup() {

  NanoC6.begin(); //SW

  //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
  delay(5);
  broadcast_peer.send_message(CP"T", 1+1);
  delay(5);
  broadcast_peer.send_message(CP"T", 1+1);
  delay(5);
  broadcast_peer.send_message(CP"T", 1+1);
  delay(5);

}//setup


//メインループ
void loop() {
  // Broadcast a message to all devices within the network
  static char data[32];

  //ボタンの状態の更新
  delay(5);//連続送信防止用
  NanoC6.update();

  //ボタンを離した時
  if (NanoC6.BtnA.wasReleased()) {
    broadcast_peer.send_message(CP"R", 1+1);
  }//endif

  //ボタンを押し続けた時
  if (NanoC6.BtnA.wasHold()) {
    broadcast_peer.send_message(CP"H", 1+1);
  }//endif

  //ボタンを押した時
  if (NanoC6.BtnA.wasPressed()) {
    broadcast_peer.send_message(CP"P", 1+1);
  }//endif

}//loop


```

(StampS3 スレーブ)

```c++



//ESP32_NOW_Buzzer_1_M5SatmpS3_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>

/* 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) {


    //ブザーの処理
    int a = data[0];
    if(a == 'P'){
      digitalWrite(15, HIGH);
    }else if( a == 'R'){
      digitalWrite(15, LOW);
    }//endif

    
    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) {
  if (memcmp(info->des_addr, ESP_NOW.BROADCAST_ADDR, 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() {

  
  Serial.begin(115200);

  for(int i=0;i<30;i++){
    Serial.println("WiFi");
    delay(1000);
  }//for


  pinMode(15, OUTPUT);//ブザーのポート設定
  digitalWrite(15, LOW);//ブザーのオフ


//  while (!Serial) {
//    delay(10);
//  }

  //WiFiの初期化
  // Initialize the Wi-Fi module
  WiFi.mode(WIFI_STA);
  WiFi.setChannel(ESPNOW_WIFI_CHANNEL);
  while (!WiFi.STA.started()) {
    delay(100);
  }

  //アドレスと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(); //リセット
  }

  //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...");
}

void loop() {
  delay(1000);//ダミー
}


```