What I can do to make the slave receive the second datapackage using the ESP_NOW?
Posted: Tue Oct 01, 2024 2:43 pm
I Have an issue that drives me crazy .....I try to operate an agility light project with 4 pieces usin esp8266 ...one master and 3 slaves .... that if your get you hand close to the sensor then interruption will occurs and the ws2812b on the other .....without much details there are 2 data packets the first data packets (packetsettings) is sent sucessfuly but the second datapacket(datapacketalone) didnot sent even the call back function activated in the slave piece (as I serial.print the recieving mac addreess ) but the data sent didnt copied in the address directed to even the data length are the same
I tried using several techniques .....I thought first it a hardware issue I put capacitors ,logic converter,....changed the power source
but then after learning and make logging I found it is software and I donnot know what it is ....I searced alot and tried several solutions like
1.using delay
2.using ack system
3.change wifi mode
4.wifi.setsleep (false)
5.change wifi channel
nothing solved I thought I should change the communication protocol but I found the best one is esp-now
so What I should do if the receiver didnot not receive the second data package even the code is fine
Master Code
[Codebox][/Codebox]
Slave Code
that is the main code if you want to have alook Ecu1 is the master and Ecu2,3,4 are the slaves
https://github.com/projectswithalex/Rea ... ing-Module
I tried using several techniques .....I thought first it a hardware issue I put capacitors ,logic converter,....changed the power source
but then after learning and make logging I found it is software and I donnot know what it is ....I searced alot and tried several solutions like
1.using delay
2.using ack system
3.change wifi mode
4.wifi.setsleep (false)
5.change wifi channel
nothing solved I thought I should change the communication protocol but I found the best one is esp-now
so What I should do if the receiver didnot not receive the second data package even the code is fine
Master Code
[Codebox]
Code: Select all
uint8_t receiverAddress1[] = { 0x40,0x91,0x51,0x4E,0x10,0x31 };
// /*replaceValueHere*/ uint8_t receiverAddress1[] = { 0xF4, 0xCF, 0xA2, 0x5D, 0x75, 0x28 }; // this ECU MAC address ,only for example purposes
/*replaceValueHere*/ uint8_t receiverAddress2[] = {
0xAC,0x0B,0xFB,0xDA,0xE0,0x11};
uint8_t receiverECU_Address[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //Placeholder for the receiver address
uint8_t receiverArray[MAXAVAILABLEECU][MACADDRESSSIZE];
#define MAXAVAILABLEECU 10
dataPacketSettings packetSettings = { 0 };
struct __attribute__((packed)) dataPacketSettings {
uint8_t training_NrOfEcus;
uint8_t training_trainingType;
uint8_t training_nrOfColors;
uint8_t training_counterValStop;
uint16_t training_stopTimeDuration;
uint8_t training_partnerMode_P1Color;
uint8_t training_partnerMode_P2Color;
uint32_t training_maxIntervalTime;
uint32_t training_minIntervalTime;
uint8_t winnerPartner;
};
struct __attribute__((packed)) dataPacketAlone {
uint8_t LED_Token; // Token for activating ECUs
uint8_t counterExerciseData;
};
dataPacketAlone packetAlone = { 1, 0 };
void initReceiverAddress(void) {
// memcpy(&receiverArray[0], NOECU, 6); //no ECU is allowed to be on 0 position
// memcpy(&receiverArray[1], receiverAddress1, 6); //This is my ECU position doesn't need to be filed.
switch (training_SelectNrOfECUs) {
case 1:
memcpy(&receiverArray[2], receiverAddress2, 6);
esp_now_add_peer(receiverAddress2, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
break;
case 2:
memcpy(&receiverArray[2], receiverAddress2, 6);
memcpy(&receiverArray[3], receiverAddress3, 6);
esp_now_add_peer(receiverAddress2, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress3, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
break;
case 3:
memcpy(&receiverArray[2], receiverAddress2, 6);
memcpy(&receiverArray[3], receiverAddress3, 6);
memcpy(&receiverArray[4], receiverAddress4, 6);
esp_now_add_peer(receiverAddress2, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress3, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress4, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
break;
case 4:
memcpy(&receiverArray[2], receiverAddress2, 6);
memcpy(&receiverArray[3], receiverAddress3, 6);
memcpy(&receiverArray[4], receiverAddress4, 6);
//to add
esp_now_add_peer(receiverAddress2, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress3, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress4, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
//to add
break;
}
//.......
//and so on until MAXAVAILABLEECU
}
void initESPNOWcomm(void) {
WiFi.mode(WIFI_STA);
WiFi.disconnect(); // we do not want to connect to a WiFi network
if (esp_now_init() != 0) {
Serial.println("ESP-NOW initialization failed");
return;
}
Serial.print("ESP Board MAC Address: ");
Serial.println(WiFi.macAddress());
esp_now_set_self_role(MY_ROLE);
esp_now_register_send_cb(transmissionComplete); // this function will get called once all data is sent
esp_now_register_recv_cb(dataReceived); // this function will get called whenever we receive data
/*replaceValueHere*/ //add peers here or modify the reciverAddress to the right ECUS
esp_now_add_peer(receiverAddress1, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0); // this is the master and we need to add it before everyone else because the commands come from it.
memcpy(&receiverArray[1], receiverAddress1, 6);
Serial.println("initESPNOWcomm");
}
uint8_t randomECUselect(void) {
randomSeed(millis());
uint8_t returnValue = 0;
uint8_t randomNumber = 0;
while (returnValue == 0) {
randomNumber = random(0, training_NrOfEcus + 2); //we have +2 because 1 is master and the function is exclusive
if ((randomNumber != MY_ECU) && (randomNumber != NO_ECU)) {
returnValue = randomNumber;
}
}
Serial.println("randomECUselect");
delay(500);
return returnValue;
}
void selectECU_number(uint8_t ECU) {
memcpy(&receiverECU_Address, receiverArray[ECU], MACADDRESSSIZE);
packetAlone.LED_Token = ECU;
TransmisionStatus = SENDDATA_en;
Serial.print("selectECU_number");
delay(500);
}
randomECUSelection = randomECUselect();
selectECU_number(randomECUSelection);
esp_now_send(receiverECU_Address, (uint8_t *)&packetAlone, sizeof(packetAlone));
Slave Code
Code: Select all
[Codebox]uint8_t receiverAddress1[] = { 0x40,0x91,0x51,0x4E,0x10,0x31 };
// /*replaceValueHere*/ uint8_t receiverAddress1[] = { 0xF4, 0xCF, 0xA2, 0x5D, 0x75, 0x28 }; // this ECU MAC address ,only for example purposes
/*replaceValueHere*/ uint8_t receiverAddress2[] = {
0xAC,0x0B,0xFB,0xDA,0xE0,0x11};
uint8_t receiverECU_Address[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //Placeholder for the receiver address
uint8_t receiverArray[MAXAVAILABLEECU][MACADDRESSSIZE];
#define MAXAVAILABLEECU 10
struct __attribute__((packed)) dataPacketAlone {
uint8_t LED_Token; // Token for activating ECUs
uint8_t counterExerciseData;
};
dataPacketAlone packetAlone = { 1, 0 };
dataPacketSettings packetSettings = { 0 };
struct __attribute__((packed)) dataPacketSettings {
uint8_t training_NrOfEcus;
uint8_t training_trainingType;
uint8_t training_nrOfColors;
uint8_t training_counterValStop;
uint16_t training_stopTimeDuration;
uint8_t training_partnerMode_P1Color;
uint8_t training_partnerMode_P2Color;
uint32_t training_maxIntervalTime;
uint32_t training_minIntervalTime;
uint8_t winnerPartner;
};
void initReceiverAddress(void) {
switch (packetSettings.training_NrOfEcus) {
case 2:
memcpy(&receiverArray[1], receiverAddress1, 6);
esp_now_add_peer(receiverAddress1, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
break;
case 3:
memcpy(&receiverArray[3], receiverAddress3, 6);
memcpy(&receiverArray[1], receiverAddress1, 6);
esp_now_add_peer(receiverAddress3, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress1, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
break;
case 4:
memcpy(&receiverArray[1], receiverAddress1, 6);
memcpy(&receiverArray[3], receiverAddress3, 6);
memcpy(&receiverArray[4], receiverAddress4, 6);
//to add 5
esp_now_add_peer(receiverAddress3, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress4, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress1, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
//to add 5
break;
}
//and so on until MAXAVAILABLEECU
}
void initESPNOWcomm(void) {
WiFi.mode(WIFI_STA);
WiFi.disconnect(); // we do not want to connect to a WiFi network
if (esp_now_init() != 0) {
Serial.println("ESP-NOW initialization failed");
return;
}
Serial.print("ESP Board MAC Address: ");
Serial.println(WiFi.macAddress());
esp_now_set_self_role(MY_ROLE);
esp_now_register_send_cb(transmissionComplete); // this function will get called once all data is sent
esp_now_register_recv_cb(dataReceived); // this function will get called whenever we receive data
/*replaceValueHere*/ //add peers here or modify the reciverAddress to the right ECUS
esp_now_add_peer(receiverAddress1, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress2, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0);
esp_now_add_peer(receiverAddress4, RECEIVER_ROLE, WIFI_CHANNEL, NULL, 0); // this is the master and we need to add it before everyone else because the commands come from it.
memcpy(&receiverArray[1], receiverAddress1, 6);
memcpy(&receiverArray[2], receiverAddress2, 6);
memcpy(&receiverArray[4], receiverAddress4, 6);
}
void dataReceived(uint8_t *senderMac, uint8_t *data, uint8_t dataLength) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", senderMac[0], senderMac[1], senderMac[2], senderMac[3], senderMac[4], senderMac[5]);
Serial.println();
Serial.print("Received data from: ");
Serial.println(macStr);
switch (dataLength) {
case 2:
Serial.println(" case 2 ");
memcpy(&packetAlone, data, sizeof(packetAlone));
if(packetSettings.training_trainingType==TRAINING_TIMERMODE && packetAlone.LED_Token==MY_ECU) {
timer1_write(randomTimerInterval());
}
Serial.print(packetAlone.counterExerciseData);
Serial.print(packetAlone.LED_Token);
break;
case 3:
Serial.println("local");
memcpy(&partnerLocal, data, sizeof(partnerLocal));
break;
case 17:
Serial.println(" case 8");
memcpy(&packetSettings, data, sizeof(packetSettings));
settingsReceivedFlag = false;
break;
}
TransmisionStatus = DATARECEIVED_en;
}[/Codebox]
https://github.com/projectswithalex/Rea ... ing-Module