ESP32/8266 を使った WiFi 制御 同軸切替器 4

コントロールソフトをすこし解説。

以前にも書いたように、外にあるスイッチャー本体と室内のコントローラは ESP-NOW という仕組みで通信を行う。この方式は、一度に伝送できるデータ数が 260Byte に限定されるが、SSIDなどの設定が不要で使いやすい。

f:id:PanariLab:20201027161735j:plain

画像のように MACアドレスで識別してやり取りをするものなので、お互いの MAC アドレスを知る必要がある。

ESP32のMACアドレスを表示するスケッチは以下の通りで、リセットするとMACアドレスがシリアルモニタに出力される。


#include "WiFi.h"
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println();
  Serial.print("ESP8266 Board MAC Address:  ");
  Serial.println(WiFi.macAddress());
}

void loop() {
}

室内側のコントローラメインプログラムは以下のとおり。

イニシャライズ後、切替スイッチの情報を取得して、その番号を外側のスイッチャー本体(Sub)に送信する。Sub側から応答がないときには、スイッチ番号の前に「*」を表示して通信が確立していないことを表示する。今回は、128x64 OLED を使ったがシンプルにLEDを点灯させるのも良いと思う。


// Antenna Coaxial SW'er Main Program
// Pins Definition For ESP32
#define SwitchPIN11     19 	   //Switch 1
#define SwitchPIN12     18 	   //Switch 2
#define SwitchPIN13      5 	   //Switch 3
#define SwitchPIN14     17 	   //Switch 4
#define NoSelect 9            // Switch is Not selected
#include "U8x8lib.h"
#include "WiFi.h"
#include "esp_now.h"

// PUBlic variables
  int SetSwitchNo1 ;         // Set Switch Number Main to Switcher
  int SetSwitchNo2 ;         // Set Switch Number Main to Switcher
  int GetSwitchNo ;          // Get Switch Number Switcher to Main
  String AntName;            // Antenna Name

//For ESP-NOW Communication setting
	boolean   RxStatus;   // Receiver Status form Send TASK

//  MAC Address of ESP32 Switcher Receiver
	uint8_t broadcastAddress1[] = {0x30, 0xAE, 0xA4, 0x96, 0x5A, 0xD0};

// Structure to Send/Receive Data Must match the receiver structure
	typedef struct struct_message {
	  int      SwitchNo		  ;		  // 1-4 Antenna Switch No.
	} struct_message;
	
// Create a struct_message to Send & ReceiveData
	struct_message MtoS;
    struct_message StoM;
    
//    Definition For OLED Display
  U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE);

void setup() {
  pinMode(SwitchPIN11, INPUT_PULLUP);
  pinMode(SwitchPIN12, INPUT_PULLUP);
  pinMode(SwitchPIN13, INPUT_PULLUP);
  pinMode(SwitchPIN14, INPUT_PULLUP);
// OLED Library Starts
   u8x8.begin(); 

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

// Initialize ESP-NOW
   if (esp_now_init() != ESP_OK) {
     u8x8.setFont(u8x8_font_8x13_1x2_f); 
     u8x8.setCursor(0,6);
     u8x8.print("ESP-NOW:  NG"); 
    return;}
    else{u8x8.setCursor(0,6);
         u8x8.print("ESP-NOW:  OK");  }
  delay(2000); 
  
// Once ESPNow is successfully Init, we will register for 
// Send CB toget the status of Trasnmitted packet
   esp_now_register_send_cb(OnDataSent);
 
// Register peer
   esp_now_peer_info_t peerInfo;
   peerInfo.channel = 0;  
   peerInfo.encrypt = false;
  
// Add 1st peer
   memcpy(peerInfo.peer_addr, broadcastAddress1, 6);        
   if (esp_now_add_peer(&peerInfo) != ESP_OK){
     u8x8.setFont(u8x8_font_8x13_1x2_f); 
     u8x8.setCursor(0,6);
     u8x8.print("         ");
     u8x8.print("Peer 1: NG");
     delay(2000); 
    return;  }

// Register for a callback function that will be called 
// when data is received
   esp_now_register_recv_cb(OnDataRecv);

// Set up Form Display
  u8x8.setFont(u8x8_font_8x13B_1x2_f);
  u8x8.clear();
  u8x8.setCursor(0,0);
  u8x8.print(" -Ant Switcher-");  
  u8x8.setCursor(0,3);
  u8x8.print(" SW1:");  
} // END Setup()


void loop() {
// Read Switch1 Status and Set Switch Number
 if ( digitalRead(SwitchPIN11) == LOW ) SetSwitchNo1 = 1 ; 
    else if ( digitalRead(SwitchPIN12) == LOW ) SetSwitchNo1 = 2 ;
     else if ( digitalRead(SwitchPIN13) == LOW ) SetSwitchNo1 = 3 ;   
      else if ( digitalRead(SwitchPIN14) == LOW ) SetSwitchNo1 = 4 ;   
        else SetSwitchNo1 = NoSelect ;  
// Send Switch Data message to Switcher Receiver  via ESP-NOW
  MtoS.SwitchNo = SetSwitchNo1 ;     //  Update SW Status      
  esp_now_send(broadcastAddress1, (uint8_t *) &MtoS, sizeof(MtoS));

  delay(100);                 //  100msec Block

// Display Switcher1 Status
  u8x8.setFont(u8x8_font_8x13B_1x2_f);
  u8x8.setCursor(10,3);
  if ( RxStatus )  u8x8.print(" ");  
   else u8x8.print("*");
  u8x8.print(SetSwitchNo1);  
} //End Loop()

//  Communication TASK via ESP NOW 

// Callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) 
 {  if (status ==0)    RxStatus = true;
    else    RxStatus = false; }

// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) 
 { memcpy(&StoM, incomingData, sizeof(StoM));
   GetSwitchNo = StoM.SwitchNo ;            // Data Update
 }


室外のスイッチャー(Sub)のスケッチは以下のとおり。

イニシャライズ後、単純にメインから受信したデータに従って出力ポートに出力するだけのものである。


// 1:4 Switcher Sub Program
// Pins Definition for ESP32 Devkit Switcher Controler

#define SwitchPIN11     15 	   // Switch 1
#define SwitchPIN12     12 	   // Switch 2
#define SwitchPIN13     14 	   // Switch 3
#define SwitchPIN14     27	   // Switch 4
#define NoSelect        9      // Switch is Not selected

#include "WiFi.h"
#include "esp_now.h"

// PUBlic variables
  int SetSwitchNo ;          // Set Switch Number Main to Switcher
  int GetSwitchNo ;          // Get Switch Number Switcher to Main
  
//For ESP-NOW Communication setting
	boolean   RxStatus;   // Receiver Status form Send TASK

//  MAC Address of ESP32 Main Transmitter
  uint8_t broadcastAddress[] = {0xA4, 0xCF, 0x12, 0x96, 0x8E, 0xE8};

// Variable to store if sending data was successful
   String success;

// Structure to Send/Receive Data Must match the receiver structure
	typedef struct struct_message {
	  int      SwitchNo		  ;		  // 1-4 Antenna Switch No.
	} struct_message;
	
// Create a struct_message to Send & ReceiveData
		struct_message MtoS;

void setup() {
  pinMode(SwitchPIN11, OUTPUT);
  pinMode(SwitchPIN12, OUTPUT);
  pinMode(SwitchPIN13, OUTPUT);
  pinMode(SwitchPIN14, OUTPUT);
// All Switch are OFF  
  digitalWrite(SwitchPIN11,LOW);
  digitalWrite(SwitchPIN12,LOW);
  digitalWrite(SwitchPIN13,LOW);
  digitalWrite(SwitchPIN14,LOW); 

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

// Initialize ESP-NOW
   esp_now_init();
   delay(500); 
  
// Once ESPNow is successfully Init, we will register for 
// Send CB to get the status of Trasnmitted packet
   esp_now_register_send_cb(OnDataSent);

// Register peer
   esp_now_peer_info_t peerInfo;
   memcpy(peerInfo.peer_addr, broadcastAddress, 6);
   peerInfo.channel = 0;  
   peerInfo.encrypt = false;
// Add peer        
   esp_now_add_peer(&peerInfo) ;
   delay(500); 
    
// Register for a callback function that will be called when data is received
   esp_now_register_recv_cb(OnDataRecv);

} // END Setup()

void loop() {
// Set Switch Status and Set Switch Number
    switch(SetSwitchNo){
      case 1 :            // Switch 1 ON
       digitalWrite(SwitchPIN11,HIGH);
       digitalWrite(SwitchPIN12,LOW);
       digitalWrite(SwitchPIN13,LOW);
       digitalWrite(SwitchPIN14,LOW); 
       break;
      case 2 :            // Switch 2 ON
       digitalWrite(SwitchPIN12,HIGH);
       digitalWrite(SwitchPIN11,LOW);
       digitalWrite(SwitchPIN13,LOW);
       digitalWrite(SwitchPIN14,LOW); 
       break;
      case 3 :            // Switch 3 ON
       digitalWrite(SwitchPIN13,HIGH);
       digitalWrite(SwitchPIN11,LOW);
       digitalWrite(SwitchPIN12,LOW);
       digitalWrite(SwitchPIN14,LOW); 
       break;
      case 4 :            // Switch 4 ON
       digitalWrite(SwitchPIN14,HIGH);
       digitalWrite(SwitchPIN11,LOW);
       digitalWrite(SwitchPIN12,LOW);
       digitalWrite(SwitchPIN13,LOW);
       break;
      default:            // All Switch OFF
     { digitalWrite(SwitchPIN11,LOW);
       digitalWrite(SwitchPIN12,LOW);
       digitalWrite(SwitchPIN13,LOW);
       digitalWrite(SwitchPIN14,LOW); 
     }  
    }
   delay(200);                 //  200msec Block

} //End Loop()


// Callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) 
 {
  if (status ==0)    RxStatus = true;
    else    RxStatus = false;
 }

// Callback when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) 
 {
  memcpy(&MtoS, incomingData, sizeof(MtoS));
  SetSwitchNo = MtoS.SwitchNo ;         // Switch Data Update
 }