 
#include <esp_now.h>
#include <WiFi.h>
#include <esp_wifi.h>
#define led1 27
#define led2 5
#define sw1 34
#define sw2 4
#define led_status 2
#define pwm1 14
#define pwm2 12
#define WIFI_CHANNEL 11

int status_loop=0;
void send_data(void);
bool dir;
int  duty;


uint8_t Address_node1[] = {0x00,0x70,0x07,0xa3,0x78,0x78};
uint8_t Address_node2[] = {0x88,0x57,0x21,0xc2,0xc0,0xb4};
uint8_t Address_node3[] = {0x8c,0x94,0xdf,0x61,0xda,0x04};
uint8_t Address_node4[] = {0x88,0x57,0x21,0xb1,0x28,0x2c};
uint8_t Address_node5[] = {0x58,0x2a,0xbd,0x7d,0xbd,0xbc};


// Data structure for receiving and sending.
typedef struct struct_message {
    char text[32];
    int pwm_duty;
    int id;
    bool in1;
    bool in2;
    bool out1;
    bool out2;
} struct_message;

struct_message myData;       // Information to send
struct_message incomingData; // Received information

//esp_now_peer_info_t peerInfo;


  




//The function is called when data is sent.
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  Serial.print("\r\nLatest delivery status: ");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Sent successfully." : "Send failed.");
}

// The function is called when data is submitted.
void OnDataRecv(const esp_now_recv_info *info, const uint8_t *incomingDataRaw, int len) {

const uint8_t *mac = info->src_addr;
//------------------------------------- check data incomming -------------
    Serial.println("\n=== [Received a new data frame.] ===");
    
    // Displays the sender's MAC address.
    Serial.printf("from MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    
    // Check the frame size (Frame Length Verification)
    Serial.printf("Size of data received. (Bytes): %d\n", len);
    Serial.printf("Expected structure dimensions(Bytes): %d\n", sizeof(struct_message));

    if (len != sizeof(struct_message)) {
        Serial.println("ÃƒÆ’Ã‚Â¢Ãƒâ€šÃ‚ÂÃƒâ€¦Ã¢â‚¬â„¢ [Error] Frame Format Incorrect! The data size does not match the structure");
        return;
    }
//-----------------------------------------------------------------------     
  
  
  memcpy(&incomingData, incomingDataRaw, sizeof(incomingData));
//-------------------- text data ---------------  
  Serial.print("---I received the information: ");
  Serial.print(incomingData.text);
//--------------- interger  data--------------  
  Serial.print(" |number: ");
  Serial.print(incomingData.pwm_duty);
  duty=incomingData.pwm_duty;
//-------------bool data-------------------
  Serial.print(" in1: ");
  Serial.print(incomingData.in1);dir=incomingData.in1;
  Serial.print(" in2: ");
  Serial.print(incomingData.in2);

  Serial.print(" out1: ");
  Serial.print(incomingData.out1);digitalWrite(led1, incomingData.out1);
  Serial.print(" out2: ");
  Serial.print(incomingData.out2);digitalWrite(led2, incomingData.out2);
    //--------------- MORTOR DRIVE-----------------------
  if(dir==1){analogWrite(pwm1, 0);analogWrite(pwm2, duty);} 
  if(dir==0){analogWrite(pwm1, duty);analogWrite(pwm2, 0);}
}
 
void setup() {
  WiFi.mode(WIFI_STA);
  esp_wifi_set_channel(WIFI_CHANNEL, WIFI_SECOND_CHAN_NONE); 
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT); pinMode(led_status, OUTPUT);
  
  pinMode(sw1, INPUT_PULLUP);
  pinMode(sw2, INPUT_PULLUP);

   ledcAttach(pwm1,2000,8); ledcAttach(pwm2,2000,8);  
   analogWrite(pwm1, 0);analogWrite(pwm2, 0); // pwm
	
  int a=0;
  while(a<10)
  {
     digitalWrite(led1, !digitalRead(led1));digitalWrite(led2, !digitalRead(led2));
     delay(1000);a++;
  }
digitalWrite(led1,LOW);digitalWrite(led2,LOW);  
	
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);

  // Getting Started with ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("ESP-NOW startup failed.");
    return;
  }
//-----------------------------------------------------------------
  //Register receiver 1.
  esp_now_peer_info_t peerInfo1 = {};
  memcpy(peerInfo1.peer_addr, Address_node1, 6);
  peerInfo1.channel = WIFI_CHANNEL;  
  peerInfo1.encrypt = false;
 

  if (esp_now_add_peer(&peerInfo1) != ESP_OK){
    Serial.println("Adding a peerInfo1 failed.");
    return;
  }

//----------------------------------------------------------
  //Register receiver 3.
  esp_now_peer_info_t peerInfo3 = {};
  memcpy(peerInfo3.peer_addr, Address_node3, 6);
  peerInfo3.channel = WIFI_CHANNEL;
  peerInfo3.encrypt = false;

  if (esp_now_add_peer(&peerInfo3) != ESP_OK){
    Serial.println("Adding a peerInfo3 failed.");
    return;
  }
 //--------------------------------
  //Register receiver 4.
  esp_now_peer_info_t peerInfo4 = {};
  memcpy(peerInfo4.peer_addr, Address_node4, 6);
  peerInfo4.channel = WIFI_CHANNEL;
  peerInfo4.encrypt = false;

  if (esp_now_add_peer(&peerInfo4) != ESP_OK){
    Serial.println("Adding a peerInfo4 failed.");
    return;
  }
  //------------------------------
  //Register receiver 5.
  esp_now_peer_info_t peerInfo5 = {};
  memcpy(peerInfo5.peer_addr, Address_node5, 6);
  peerInfo5.channel = WIFI_CHANNEL;
  peerInfo5.encrypt = false;

  if (esp_now_add_peer(&peerInfo5) != ESP_OK){
    Serial.println("Adding a peerInfo5 failed.");
    return;
  }  


  //------------------------------------
  
  

  // Register the Callback function for both incoming and outgoing calls.

esp_now_register_send_cb((esp_now_send_cb_t)OnDataSent);

  
esp_now_register_recv_cb((esp_now_recv_cb_t)OnDataRecv);  
  
 
}
 
void loop() {status_loop++;
	//----------------- test command on-------------
    if(digitalRead(sw1)==0)
    {
      delay(100);if(digitalRead(sw1)==0)
      {
		strcpy(myData.text, "Greetings from Board 1.");  
		myData.pwm_duty = 50;
		myData.out1=1;
		myData.out2=1;
        send_data();while(digitalRead(sw1)==0);
	 digitalWrite(led1, myData.out1);digitalWrite(led2, myData.out2);
      }
      
    }
    //----------------------test command off------
    if(digitalRead(sw2)==0)
    {
      delay(100);if(digitalRead(sw2)==0)
      {
         strcpy(myData.text, "Greetings from Board 1.");  
         myData.pwm_duty = 0;
         myData.out1=0;
         myData.out2=0;
         send_data();while(digitalRead(sw2)==0);
		  digitalWrite(led1, myData.out1);digitalWrite(led2, myData.out2);
      }
      
    }	
	
if(status_loop>100000){digitalWrite(led_status, !digitalRead(led_status));status_loop=0;}
}

void send_data(void)
{
    
    // Send to everyone (NULL means send to all registered peers)
  esp_err_t result = esp_now_send(0, (uint8_t *) &myData, sizeof(myData));
  if (result != ESP_OK) {
    Serial.println("An error occurred during data transmission.");
}

}
