Système d'alarme viaESP8266 : l'émetteur commande le récepteur le plus proche grâce au RSSI . Sur ESP32 , tout fonctionnait avec ESP-NOW

#include <ESP8266WiFi.h>
#include <espnow.h>
#include <Bounce2.h> // Bibliothèque pour le bouton avec debounce

#define BUTTON_PIN 2

// -------- LED et bâtiments --------
#define BAT_1 4
#define BAT_2 16
#define BAT_3 17
#define BAT_4 5
#define LED_PIN 15

uint8_t tab_led[5] = { BAT_1, BAT_2, BAT_3, BAT_4, LED_PIN };

// -------- Adresses des récepteurs --------
uint8_t macRecv[][6] = {
{ 0x48, 0x55, 0x19, 0x12, 0x70, 0x0F },
{ 0x3C, 0x71, 0xBF, 0x20, 0xF4, 0xDA },
{ 0xA4, 0xF0, 0x0F, 0x72, 0xBE, 0xE4 },
{ 0xA4, 0xF0, 0x0F, 0x26, 0xB7, 0xB3 },
};

uint8_t Stateconnect;
uint8_t numberRecv = 4;
uint8_t Adress;
unsigned long ReponseTime1 = 0;
unsigned long ReponseTime2 = 0;
unsigned long ReponseTime3 = 0;
unsigned long ReponseTime4 = 0;
unsigned long timeout = 1000;
unsigned long lastPing = 0;

// -------- Tableau bâtiments et RSSI --------
uint8_t BATIMENT[4] = { BAT_1, BAT_2, BAT_3, BAT_4 };
uint8_t TIME[4] = { 0, 0, 0, 0 };
int8_t TABRSSI[4] = {};

// -------- Structures --------
typedef struct {
uint8_t type; // 1 = PING, 2 = COMMANDE
int data;
} msg_t;

typedef struct {
signed int rssi;
} rssi_msg_t;

msg_t msg;
rssi_msg_t rssiMsg1 = { -100 };
rssi_msg_t rssiMsg2 = { -100 };
rssi_msg_t rssiMsg3 = { -100 };
rssi_msg_t rssiMsg4 = { -100 };

// -------- Bounce2 pour le bouton --------
Bounce bouton = Bounce();

// -------- Réception ESP-NOW --------
void OnDataRecv(uint8_t *mac, uint8_t *data, uint8_t len) {
if (len == sizeof(rssi_msg_t)) {
rssi_msg_t temp;
memcpy(&temp, data, sizeof(temp));

if (memcmp(mac, macRecv[0], 6) == 0) {
  rssiMsg1 = temp;
  ReponseTime1 = millis();
} else if (memcmp(mac, macRecv[1], 6) == 0) {
  rssiMsg2 = temp;
  ReponseTime2 = millis();
} else if (memcmp(mac, macRecv[2], 6) == 0) {
  rssiMsg3 = temp;
  ReponseTime3 = millis();
} else if (memcmp(mac, macRecv[3], 6) == 0) {
  rssiMsg4 = temp;
  ReponseTime4 = millis();
}

}
}

// -------- Setup --------
void setup() {
Serial.begin(115200);

// Configuration du bouton avec debounce
bouton.attach(BUTTON_PIN, INPUT_PULLUP);
bouton.interval(50);

for (int i = 0; i < 5; i++) pinMode(tab_led[i], OUTPUT);

WiFi.mode(WIFI_STA);
WiFi.setOutputPower(19.5);

if (esp_now_init() != 0) {
Serial.println("Erreur ESP-NOW !");
return;
}

esp_now_register_recv_cb(OnDataRecv);
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);

// Ajout des peers
esp_now_add_peer(macRecv[0], ESP_NOW_ROLE_COMBO, 1, NULL, 0);
esp_now_add_peer(macRecv[1], ESP_NOW_ROLE_COMBO, 1, NULL, 0);
esp_now_add_peer(macRecv[2], ESP_NOW_ROLE_COMBO, 1, NULL, 0);
esp_now_add_peer(macRecv[3], ESP_NOW_ROLE_COMBO, 1, NULL, 0);

Serial.println("Emetteur prêt !");
}

// -------- Loop --------
void loop() {
bouton.update();

TABRSSI[0] = rssiMsg1.rssi;
TABRSSI[1] = rssiMsg2.rssi;
TABRSSI[2] = rssiMsg3.rssi;
TABRSSI[3] = rssiMsg4.rssi;

if (millis() - lastPing > timeout) {
Serial.print("Adresse de l'emetteur: ");
Serial.println(WiFi.macAddress());

PINGSEND();
CONNECTION();
COMMANDE(Stateconnect, macRecv[Adress]);

lastPing = millis();

}
}

// -------- Envoi Ping --------
void PINGSEND() {
msg.type = 1;
msg.data = 0;

esp_now_send(macRecv[0], (uint8_t *)&msg, sizeof(msg));
esp_now_send(macRecv[1], (uint8_t *)&msg, sizeof(msg));
esp_now_send(macRecv[2], (uint8_t *)&msg, sizeof(msg));
esp_now_send(macRecv[3], (uint8_t *)&msg, sizeof(msg));
}

// -------- Commande --------
void COMMANDE(uint8_t Etat, uint8_t *Adresse) {
if (Etat) {
if (bouton.fell()) {
msg.type = 2;
msg.data = 1;
Serial.println(":right_arrow: Commande envoyée au RECEPTEUR");
esp_now_send(Adresse, (uint8_t *)&msg, sizeof(msg));
digitalWrite(BATIMENT[Etat - 1], HIGH);
}

if (bouton.rose()) {
  digitalWrite(BATIMENT[Etat - 1], LOW);
}

}
}

// -------- Connexion et RSSI --------
void CONNECTION() {
TIME[0] = ReponseTime1;
TIME[1] = ReponseTime2;
TIME[2] = ReponseTime3;
TIME[3] = ReponseTime4;

if (millis() - TIME[0] > timeout) rssiMsg1.rssi = -110;
if (millis() - TIME[1] > timeout) rssiMsg2.rssi = -110;
if (millis() - TIME[2] > timeout) rssiMsg3.rssi = -110;
if (millis() - TIME[3] > timeout) rssiMsg4.rssi = -110;

Serial.println("-------------------------");
Serial.print("RSSI Recv1 : "); Serial.println(rssiMsg1.rssi);
Serial.print("RSSI Recv2 : "); Serial.println(rssiMsg2.rssi);
Serial.print("RSSI Recv3 : "); Serial.println(rssiMsg3.rssi);
Serial.print("RSSI Recv4 : "); Serial.println(rssiMsg4.rssi);

if (rssiMsg1.rssi > rssiMsg2.rssi && rssiMsg1.rssi > rssiMsg3.rssi && rssiMsg1.rssi > rssiMsg4.rssi && rssiMsg1.rssi > -90) {
digitalWrite(LED_PIN, HIGH);
Stateconnect = 1;
Adress = 0;
} else if (rssiMsg2.rssi > rssiMsg1.rssi && rssiMsg2.rssi > rssiMsg3.rssi && rssiMsg2.rssi > rssiMsg4.rssi && rssiMsg2.rssi > -90) {
digitalWrite(LED_PIN, HIGH);
Stateconnect = 2;
Adress = 1;
} else if (rssiMsg3.rssi > rssiMsg1.rssi && rssiMsg3.rssi > rssiMsg2.rssi && rssiMsg3.rssi > rssiMsg4.rssi && rssiMsg3.rssi > -90) {
digitalWrite(LED_PIN, HIGH);
Stateconnect = 3;
Adress = 2;
} else if (rssiMsg4.rssi > rssiMsg1.rssi && rssiMsg4.rssi > rssiMsg2.rssi && rssiMsg4.rssi > rssiMsg3.rssi && rssiMsg4.rssi > -90) {
digitalWrite(LED_PIN, HIGH);
Stateconnect = 4;
Adress = 3;
} else {
digitalWrite(LED_PIN, LOW);
Stateconnect = 0;
}
}

recepteur>>>
#include <ESP8266WiFi.h>
#include "user_interface.h"

#define LED_PIN 2

volatile int RSSI_entrant = -127;

// Structure du paquet promiscuous
typedef struct {
signed rssi : 8;
unsigned rate : 5;
unsigned : 3;
unsigned sig_mode : 2;
unsigned : 1;
unsigned mcs : 7;
unsigned cwb : 1;
unsigned : 8;
unsigned smoothing : 1;
unsigned not_sounding : 1;
unsigned : 1;
unsigned aggregation : 1;
unsigned stbc : 2;
unsigned fec_coding : 1;
unsigned sgi : 1;
unsigned noise_floor : 8;
unsigned ampdu_cnt : 8;
unsigned channel : 4;
unsigned : 12;
} wifi_pkt_rx_ctrl_t;

typedef struct {
wifi_pkt_rx_ctrl_t rx_ctrl;
uint8_t payload[0];
} wifi_promiscuous_pkt_t;

typedef struct {
unsigned frame_ctrl : 16;
unsigned duration_id : 16;
uint8_t addr1[6];
uint8_t addr2[6];
uint8_t addr3[6];
unsigned sequence_ctrl : 16;
unsigned category : 8;
uint8_t addr4[6];
} wifi_ieee80211_mac_hdr_t;

typedef struct {
wifi_ieee80211_mac_hdr_t hdr;
uint8_t payload[0];
} wifi_ieee80211_packet_t;

// Structure du message envoyé
typedef struct {
uint8_t type; // 1 = PING, 2 = COMMANDE
int data; // 0 ou 1
} msg_t;

uint8_t ESP_OUI[] = { 0x18, 0xFE, 0x34 };
uint8_t emetteur_A[] = { 0x48, 0x55, 0x19, 0x12, 0x45, 0x86 };

void promiscuous_rx_cb(uint8_t *buf, uint16_t len) {
const wifi_promiscuous_pkt_t *package = (wifi_promiscuous_pkt_t *)buf;
const wifi_ieee80211_packet_t *pk = (wifi_ieee80211_packet_t *)package->payload;
const wifi_ieee80211_mac_hdr_t *hdr = &pk->hdr;

static const uint8_t ACTION_SUBTYPE = 0xd0; // ESP-NOW

// Vérification du type de paquet et OUI
if ((ACTION_SUBTYPE == (hdr->frame_ctrl & 0xFF)) && (memcmp(hdr->addr4, ESP_OUI, 3) == 0)) {

// Chercher l'OUI dans le payload pour trouver le vrai début
int payload_offset = -1;
for (int i = 0; i < len - 3; i++) {
  if (pk->payload[i] == ESP_OUI[0] && pk->payload[i + 1] == ESP_OUI[1] && pk->payload[i + 2] == ESP_OUI[2]) {
    payload_offset = i + 3;
    break;
  }
}

if (payload_offset > 0 && len > payload_offset + sizeof(msg_t)) {
  msg_t msg;
  memcpy(&msg, pk->payload + payload_offset, sizeof(msg));
  RSSI_entrant = package->rx_ctrl.rssi;

  // Afficher MAC émetteur
  Serial.print("MAC émetteur: ");
  for (int i = 0; i < 6; i++) {
    if (i > 0) Serial.print(":");
    Serial.print(hdr->addr2[i], HEX);
  }
  Serial.print(" | RSSI entrant : ");
  Serial.print(RSSI_entrant);
  Serial.print(" | Type: ");
  Serial.print(msg.type);
  Serial.print(" | Data: ");
  Serial.println(msg.data);
  Serial.println("---------------------");
}
// Afficher la trame complète brute
Serial.print("TRAME: ");
for (int i = 0; i < len; i++) {
  if (i > 0) Serial.print(" ");  // espace entre les octets
  Serial.print(buf[i], HEX);
}

}
}

void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
wifi_set_channel(1);
wifi_promiscuous_enable(1);
wifi_set_promiscuous_rx_cb(promiscuous_rx_cb);
}

void loop() {
// Exemple simple de calcul du RSSI moyen
static int somme = 0;
static int compt = 0;
somme += RSSI_entrant;
if (++compt >= 10) {
int RSSI_moyen = somme / compt;
Serial.print("RSSI moyen: ");
Serial.println(RSSI_moyen);
somme = 0;
compt = 0;
}
}

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

Bonjour,

  1. lire les bonnes pratiques du forum comme demandé ci-dessus
  2. Le titre ce n'est pas un résumé du fil de discussion donc mettre un titre plus court mais explicite. Édition en cliquant sur le crayon qui apparait lorsqu'on survole le titre.
  3. Mettre en forme le premier message pour présenter le code correctement comme demandé dans les bonnes pratiques. Édition en cliquant sur le crayon qui apparait sous le message.

Merci d’éditer votre post en utilisant le :pencil2: dans la barre d’outil juste sous votre post et rajoutez les balises de de code (c’est difficilement lisible tel quel) :

  • sélectionner la partie du texte qui correspond au code
  • appuyez sur l’icône <code/> dans la barre d’outils pour indiquer que c’est du code

(Assurez vous aussi d’indenter le code correctement dans l’IDE avant de le copier pour le coller ici. Cela se fait en pressant ctrlT sur PC ou cmdT sur un Mac)

il serait bon de (re)lire les recommandations listées dans « Les bonnes pratiques du Forum Francophone”

mais c'est ce que j'ai fait..
Le code est bien indenté.....

Ben pas trop il y a des zones oubliées comme (ce n'est qu'un extrait) :

void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
wifi_set_channel(1);
wifi_promiscuous_enable(1);
wifi_set_promiscuous_rx_cb(promiscuous_rx_cb);
}
void loop() {
// Exemple simple de calcul du RSSI moyen
static int somme = 0;
static int compt = 0;
somme += RSSI_entrant;
if (++compt >= 10) {
int RSSI_moyen = somme / compt;
Serial.print("RSSI moyen: ");
Serial.println(RSSI_moyen);
somme = 0;
compt = 0;
}
}

Euh… :worried:

Regardez la tête du post

Le code avec des balises ressemble à cela

void setup() {
  serial.begin(115200);
  …
}

void loop() {
  …
  …
}

expliquez moi bien je ne comprends pas....

On te l'as déjà dit, tout est là

En particulier, la mise en forme du code avec des balises en cliquant sur l'icône <code/>