Commit initial du projet

This commit is contained in:
Nelson-gitea 2026-03-05 08:37:38 +01:00
commit a8ed96cb5f
23 changed files with 3037 additions and 0 deletions

View File

@ -0,0 +1,69 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
//Communication avec le module LoRa
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
//Constantes d'état
#define EMISSION 0
#define DELAI 1
uint8_t state; //État courant
uint8_t data[16]; //Buffer d'émission
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("========Emetteur CAP1========");
M5.Lcd.println("========Emetteur CAP1========");
delay(1000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
//Configuration de la radio
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=EMISSION;
}
}
void loop() {
switch(state){
case EMISSION: //Code source à l'état d'émission
Serial.println("EMISSION");
M5.Lcd.println("EMISSION");
data[0]=0xAA;
data[1]=0x55;
data[2]=0x25;
data[3]=0x24;
data[4]=0x98;
rf95.send(data,5); //Envoi des données
rf95.waitPacketSent();
state=DELAI;
break;
case DELAI:
Serial.println("DELAI");
M5.Lcd.println("DELAI");
delay(1000);
state=EMISSION;
break;
default:
break;
}
}

View File

@ -0,0 +1,96 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
//Communication avec le module LoRa
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
//Déclaration des constantes
uint8_t state; //État courant
uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN]; //buffer en reception
uint8_t rxbuflen = sizeof(rxbuf); //taille du buffer en repection
int rxFrames; //Numéro de la trame reçue
//Constantes d'état
#define ECOUTE 1
#define TEST_RX 2 //Les différents états
#define AFFICHAGE 3
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("========Recepteur CAP1========");
M5.Lcd.println("========Recepteur CAP1========");
delay(1000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=ECOUTE;
Serial.println("Boucle principale");
M5.Lcd.println("Boucle principale");
rxFrames = 0;
}
}
void loop() {
switch(state){
case ECOUTE:
Serial.println("ECOUTE");
M5.Lcd.println("ECOUTE");
rf95.setModeRx();
state=TEST_RX;
break;
case TEST_RX:
Serial.println("TEST-RX");
M5.Lcd.println("TEST-RX");
if(rf95.available()){
state=AFFICHAGE;
}
//Ajout d'un delai pour laisser le temps de récupérer et d'afficher le message sur l'écran du M5
delay(2000);
break;
case AFFICHAGE:
if(rf95.recv(rxbuf, &rxbuflen)){
rxFrames+=1;
Serial.println();
M5.Lcd.println();
Serial.printf("AFFICHAGE : Trame[%d] de ", rxFrames);
M5.Lcd.printf("AFFICHAGE : Trame[%d] de ", rxFrames);
Serial.printf("%d octets : |",rxbuflen);
M5.Lcd.printf("%d octets : |",rxbuflen);
for(int j=0;j<rxbuflen;j++){
Serial.printf("%02x|", rxbuf[j]);
M5.Lcd.printf("%02x|", rxbuf[j]);
}
Serial.println("\n");
M5.Lcd.println("\n");
}
state=ECOUTE;
break;
default:
break;
}
}

View File

@ -0,0 +1,136 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; //Buffer d'emission
uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf); //Buffer de reception
uint8_t state, RxSeq, TxSeq, credit;
uint32_t attente;
#define E0 0
#define E1 1
#define E2 2
#define E3 3
#define E4 4
#define E5 5
#define TYPE_DATA 1
#define TYPE_ACK 2
#define TIMEOUT_ACK 40
#define MAX_CREDIT 5
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("====Emetteur CAP2====");
M5.Lcd.println("====Emetteur CAP2====");
delay(3000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
//Configuration de la radio
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=E0;
TxSeq=0;
credit=MAX_CREDIT;
Serial.println("Boucle principale.");
M5.Lcd.println("Boucle principale.");
delay(3000);
}
}
void loop() {
switch(state){
case E0: //Code source à l'état d'émission
Serial.printf("EMISSION %d", TxSeq);
Serial.println();
M5.Lcd.printf("EMISSION %d \n", TxSeq);
Serial.println();
txbuf[0]=TYPE_DATA;
txbuf[1]=TxSeq;
txbuf[2]=0xAA;
txbuf[3]=0x55;
rf95.send(txbuf,4); //Envoi des données
rf95.waitPacketSent();
credit -=1;
state=E1;
break;
case E1:
attente = millis()+TIMEOUT_ACK; //Armement du Chien de Garde
state = E2;
break;
case E2:
rf95.setModeRx();
state=E3;
break;
case E3:
if(millis() > attente){ //Test expiration CdG
Serial.println("CDG expire");
M5.Lcd.println("CDG expire");
state=E5; //Délais expiré
}
else{
if(rf95.recv(rxbuf, &rxbuflen)){
if((rxbuf[0]==TYPE_ACK) && (rxbuf[1]==TxSeq)){ //Reception d'un ACK avec le bon num de séquence
state=E4;
}
else{
state=E2;
}
}
}
break;
case E4:
Serial.printf("ACK_RECU [%d] \n", TxSeq);
M5.Lcd.printf("ACK_RECU [%d] \n", TxSeq);
state=E0, TxSeq+=1, credit=5;
break;
case E5:
Serial.printf("Probleme\n");
M5.Lcd.printf("Probleme\n");
if (credit==0){
Serial.print("ECHEC\n");
M5.Lcd.print("ECHEC\n");
state=E0;
credit=MAX_CREDIT;
TxSeq+=1;
}
else{
Serial.printf("Nouvelle tentative n %d\n", 5-credit);
M5.Lcd.printf("Nouvelle tentative n %d\n", 5-credit);
state=E0;
Serial.println();
M5.Lcd.println();
}
break;
default:
state=E0;
break;
}
}

View File

@ -0,0 +1,114 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
uint8_t state;
uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t rxlen=RH_RF95_MAX_MESSAGE_LEN;
uint8_t RxSeq;
#define E0 0
#define E1 1
#define E2 2
#define E3 3
#define TYPE_DATA 1
#define TYPE_ACK 2
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("====Recepteur CAP2====");
M5.Lcd.println("====Recepteur CAP2====");
delay(3000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=E0;
Serial.println("Boucle principale");
M5.Lcd.println("Boucle principale");
RxSeq=255;
delay(1000);
}
}
void loop() {
switch(state){
case E0:
Serial.println("Mode Reception");
M5.Lcd.println("Mode Reception");
rf95.setModeRx();
state=E1;
break;
case E1:
if(rf95.recv(rxbuf, &rxlen)){
if(rxbuf[0]==TYPE_DATA){
state=E2;
}
else{
state=E0;
}
}
break;
case E2:
if(RxSeq!=rxbuf[1]){
RxSeq=rxbuf[1];
Serial.printf("[%d] ", RxSeq);
M5.Lcd.printf("[%d] ", RxSeq);
Serial.printf("DATA de %d octets :", rxlen);
M5.Lcd.printf("DATA de %d octets :", rxlen);
Serial.println();
M5.Lcd.println();
for(int i=0;i<rxlen;i++){
Serial.printf("%02x|", rxbuf[i]);
M5.Lcd.printf("%02x|", rxbuf[i]);
}
Serial.println();
M5.Lcd.println();
}
else{
Serial.printf("Duplication\n");
M5.Lcd.printf("Duplication\n");
}
state=E3;
break;
case E3:
Serial.println("Envoi ACK");
M5.Lcd.println("Envoi ACK");
txbuf[0]=TYPE_ACK;
txbuf[1]=rxbuf[1];
rf95.send(txbuf,2);
rf95.waitPacketSent();
state=E0;
break;
default:
break;
}
}

View File

@ -0,0 +1,105 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
//Communication avec le module LoRa
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
//Constantes d'état
#define EMISSION 0
#define DELAI 1
//Variables pour l'état et le buffer
uint8_t state; //État courant
uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; //Buffer d'émission
//Variables pour la correction d'erreur
uint16_t S, SP;
//Constantes pour les champs de la trame
#define CHAMP_MIN_PAYLOAD 0
#define CHAMP_MAX_PAYLOAD 19
#define CHAMP_MIN_S 20
#define CHAMP_MIN_SP 22
#define LONGUEUR_TRAME 24
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("===Emetteur CAP3 Corr===");
M5.Lcd.println("===Emetteur CAP3 Corr===");
delay(3000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
//Configuration de la radio
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=EMISSION;
}
}
void loop() {
switch(state){
case EMISSION: //Code source à l'état d'émission
Serial.println("EMISSION"); //Trame de 20 octets de payload et 4 octets RS
M5.Lcd.println("EMISSION");
S=0;SP=0;
for(int i=CHAMP_MIN_PAYLOAD;i<=CHAMP_MAX_PAYLOAD; i++){
txbuf[i] = 255;
S+=txbuf[i];
SP+=txbuf[i]*(i+1);
Serial.printf("|%02X", txbuf[i]);
M5.Lcd.printf("|%02X", txbuf[i]);
}
//Injection des 8 bits de poids faible
//ET logique avec masque (0000 0000 1111 1111)
txbuf[CHAMP_MIN_S] = S & 0x00FF;
//Injection des 8 bits de poids fort
//ET logique avec masque (1111 1111 0000 0000)
//Puis décalage de 8 bits vers la droite pour pouvoir les coder
//sur un octet
txbuf[CHAMP_MIN_S+1] = (S & 0xFF00) >> 8;
Serial.printf("|%02X|%02X", txbuf[CHAMP_MIN_S],txbuf[CHAMP_MIN_S+1]);
M5.Lcd.printf("|%02X|%02X", txbuf[CHAMP_MIN_S],txbuf[CHAMP_MIN_S+1]);
//Même principe que pour S
txbuf[CHAMP_MIN_SP] = SP & 0x00FF;
txbuf[CHAMP_MIN_SP+1] = (SP & 0xFF00) >> 8;
Serial.printf("|%02X|%02X", txbuf[CHAMP_MIN_SP],txbuf[CHAMP_MIN_SP+1]);
M5.Lcd.printf("|%02X|%02X", txbuf[CHAMP_MIN_SP],txbuf[CHAMP_MIN_SP+1]);
Serial.println();
M5.Lcd.println();
rf95.send(txbuf,LONGUEUR_TRAME); //Envoi des données
rf95.waitPacketSent();
state=DELAI;
break;
case DELAI:
Serial.println("DELAI");
M5.Lcd.println("DELAI");
delay(1000);
state=EMISSION;
break;
default:
break;
}
}

View File

@ -0,0 +1,160 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
uint8_t state;
uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf);
int rxFrames;
//Variables pour la correction d'erreur
int erreur, rang;
uint16_t Sr,SPr, Sc, SPc; //Sommes et Sommes pondérées calculées et reçues
//Constantes d'état
#define ECOUTE 1
#define TEST_RX 2
#define AFFICHAGE 3
//Constantes pour les champs de la trame
#define CHAMP_MIN_PAYLOAD 0
#define CHAMP_MAX_PAYLOAD 19
#define CHAMP_MIN_S 20
#define CHAMP_MIN_SP 22
#define LONGUEUR_TRAME 24
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("===Recepteur CAP3 cor===");
M5.Lcd.println("===Recepteur CAP3 cor===");
delay(3000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=ECOUTE;
delay(2000);
Serial.println("Boucle principale");
M5.Lcd.println("Boucle principale");
}
}
void loop() {
switch(state){
case ECOUTE:
Serial.println("ECOUTE");
M5.Lcd.println("ECOUTE");
rf95.setModeRx();
state=TEST_RX;
delay(2000);
break;
case TEST_RX:
Serial.println("TEST-RX");
M5.Lcd.println("TEST-RX");
if(rf95.available()){
state=AFFICHAGE;
}
break;
case AFFICHAGE:
if(rf95.recv(rxbuf, &rxbuflen)){ //récupération de la trame reçue dans rxbuf
//rxbuflen=23; //Simulation d'erreur de longueur
//rxbuf[16] = 21;//Simulation modification de l'octet 17
//rxbuf[2] = 8;
rxFrames+=1;
Serial.printf("[%d] ", rxFrames);
M5.Lcd.printf("[%d] ", rxFrames);
Serial.printf("%d bytes: ", rxbuflen);
M5.Lcd.printf("%d bytes: ", rxbuflen);
for(int j=0;j<rxbuflen;j++){
Serial.printf("%02x|", rxbuf[j]);
M5.Lcd.printf("%02x|", rxbuf[j]);
}
Serial.println();
M5.Lcd.println();
if(rxbuflen != LONGUEUR_TRAME){
Serial.printf("erreur de longueur de trame : %d !", rxbuflen);
M5.Lcd.printf("erreur de longueur de trame : %d !", rxbuflen);
Serial.println();
M5.Lcd.println();
}
else{
Sr = (rxbuf[CHAMP_MIN_S] & 0x00FF) + ((rxbuf[CHAMP_MIN_S+1] & 0x00FF) << 8);
SPr = (rxbuf[CHAMP_MIN_SP] & 0x00FF) + ((rxbuf[CHAMP_MIN_SP+1] & 0x00FF) << 8);
Sc=0;
SPc=0;
for(int i=CHAMP_MIN_PAYLOAD; i<=CHAMP_MAX_PAYLOAD ; i++){
Sc=Sc+rxbuf[i];
SPc=SPc+rxbuf[i]*(i+1);
}
Serial.printf("Sr=%d SPr=%d Sc=%d SPc=%d ", Sr, SPr, Sc, SPc);
M5.Lcd.printf("Sr=%d SPr=%d Sc=%d SPc=%d ", Sr, SPr, Sc, SPc);
Serial.println();
M5.Lcd.println();
if(Sr != Sc){
Serial.println("Une correction est utile ! ");
M5.Lcd.println("Une correction est utile ! ");
erreur=Sc-Sr;
Serial.printf("Valeur erreur = %d", erreur);
M5.Lcd.printf("Valeur erreur = %d", erreur);
Serial.println();
M5.Lcd.println();
rang=(SPc-SPr)/erreur;
Serial.printf("Rang erreur = %d", rang);
M5.Lcd.printf("Rang erreur = %d", rang);
Serial.println();
M5.Lcd.println();
if(rang!=0){
Serial.printf("Correction de %02X en %02X", rxbuf[rang-1], rxbuf[rang-1]-erreur);
M5.Lcd.printf("Correction de %02X en %02X", rxbuf[rang-1], rxbuf[rang-1]-erreur);
Serial.println();
M5.Lcd.println();
}
else{
Serial.println("Erreur sur la redondance et non sur les DATA utiles");
M5.Lcd.println("Erreur sur la redondance et non sur les DATA utiles");
}
}
else{
if(SPr != SPc){
Serial.println("Erreur sur la redondance et non sur les DATA utiles");
M5.Lcd.println("Erreur sur la redondance et non sur les DATA utiles");
}
}
}
}
state=ECOUTE;
break;
default:
break;
}
}

View File

@ -0,0 +1,182 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
//Variables
uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf); //Buffer de reception et longueur
uint8_t state, TxSeq, credit;
uint32_t attente;
uint8_t FCS; //Champ de contrôle
//Constantes d'états
#define E0 0
#define E1 1
#define E2 2
#define E3 3
#define E4 4
#define E5 5
//Constantes de données et d'acquitement
#define TYPE_DATA 1
#define TYPE_ACK 2
#define TIMEOUT_ACK 40
#define MAX_CREDIT 5
//Constantes de champs de trame
#define CHAMP_TYPE 0
#define CHAMP_NUM_SEQ 1
#define CHAMP_MIN_PAYLOAD 2
#define CHAMP_MAX_PAYLOAD 19
#define CHAMP_FCS_DATA 20
#define CHAMP_FCS_ACK 2
int erreur_ack=1;
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("===Emmetteur CAP3 DET===");
M5.Lcd.println("===Emmetteur CAP3 DET===");
delay(3000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
//Configuration de la radio
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=E0;
TxSeq=0;
credit=MAX_CREDIT;
Serial.println("Boucle principale.");
M5.Lcd.println("Boucle principale.");
delay(3000);
}
}
void loop() {
switch(state){
case E0: //Code source à l'état d'émission
Serial.printf("EMISSION %d\n\n", TxSeq);
M5.Lcd.printf("EMISSION %d\n\n", TxSeq);
txbuf[CHAMP_TYPE]=TYPE_DATA;
txbuf[CHAMP_NUM_SEQ]=TxSeq;
//On remplit les 18 octets de payload au max (255)
for (int i=CHAMP_MIN_PAYLOAD;i<=CHAMP_MAX_PAYLOAD;i++){
txbuf[i]=255;
}
//Calcul du FCS : XOR
FCS=0; //Champ sur un octet
for(int i=0;i<=CHAMP_MAX_PAYLOAD;i++){
//XOR des 20 octets de la trame.
FCS=FCS ^ txbuf[i];
}
//On ajoute le FCS calculé à la fin de la trame
txbuf[CHAMP_FCS_DATA] = FCS;
//Affichage pour le debug
for(int i=0; i<21; i++){
Serial.printf("|%02X", txbuf[i]);
M5.Lcd.printf("|%02X", txbuf[i]);
}
Serial.println("|");
M5.Lcd.println("|");
//Envoi des données
rf95.send(txbuf,21);
rf95.waitPacketSent();
credit-=1;
state=E1;
break;
case E1:
attente = millis()+TIMEOUT_ACK; //Armement du Chien de Garde
state = E2;
break;
case E2:
rf95.setModeRx();
state=E3;
break;
case E3:
if(millis() > attente){ //Test expiration CdG
state=E5; //Délais expiré
}
else{
if(rf95.recv(rxbuf, &rxbuflen)){
//Simulation d'erreur
if(erreur_ack%3==0){
rxbuf[CHAMP_FCS_ACK]=rxbuf[CHAMP_FCS_ACK]+1;
}
erreur_ack+=1;
//Reception d'un ACK avec le bon num de séquence
if((rxbuf[CHAMP_TYPE]==TYPE_ACK) && (rxbuf[CHAMP_NUM_SEQ]==TxSeq)){
//Trame reçue sans erreur
if((rxbuf[CHAMP_TYPE] ^ rxbuf[CHAMP_NUM_SEQ])==rxbuf[CHAMP_FCS_ACK]){
//Affichage de la trame reçue
state=E4;
}
else{
//Affichage de l'échec
state=E5;
}
}
else{
//Réécoute
state=E2;
}
}
}
break;
case E4:
Serial.printf("ACK_RECU [%d] \n", TxSeq);
M5.Lcd.printf("ACK_RECU [%d] \n", TxSeq);
state=E0, TxSeq+=1, credit=MAX_CREDIT;
break;
case E5:
Serial.print("E5 ");
M5.Lcd.print("E5 ");
if (credit==0){
Serial.print("ECHEC\n");
M5.Lcd.print("ECHEC\n");
credit=MAX_CREDIT;
TxSeq+=1;
}
else{
Serial.printf("Nouvelle tentative n %d\n", MAX_CREDIT-credit);
M5.Lcd.printf("Nouvelle tentative n %d\n", MAX_CREDIT-credit);
Serial.println();
M5.Lcd.println();
}
state=E0;
break;
default:
state=E0;
break;
}
}

View File

@ -0,0 +1,141 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
//Variables
uint8_t state;
uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf);
uint8_t RxSeq;
uint8_t FCSc, FCSr; //Champs de contrôle d'un octet calculé et reçu
//Constantes d'état
#define E0 0
#define E1 1
#define E2 2
#define E3 3
#define TYPE_DATA 1
#define TYPE_ACK 2
//Constantes de champs de trames
#define CHAMP_TYPE 0
#define CHAMP_NUM_SEQ 1
#define CHAMP_MIN_PAYLOAD 2
#define CHAMP_MAX_PAYLOAD 19
#define CHAMP_FCS_DATA 20
#define CHAMP_FCS_ACK 2
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("===Recepteur CAP3 DET===");
M5.Lcd.println("===Recepteur CAP3 DET===");
delay(3000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=E0;
Serial.println("Boucle principale");
M5.Lcd.println("Boucle principale");
RxSeq=255;
delay(1000);
}
}
void loop() {
switch(state){
case E0: //ECOUTE
Serial.println("E0 : Attente Reception \n");
M5.Lcd.println("E0 : Attente Reception \n");
rf95.setModeRx();
state=E1;
break;
case E1:
if(rf95.recv(rxbuf, &rxbuflen)){
if(rxbuf[CHAMP_TYPE]==TYPE_DATA){
//Test si FCS juste
FCSr=rxbuf[CHAMP_FCS_DATA]; //Champ de contrôle reçu
//Calcul du FCS
FCSc=0;
for(int i=0;i<=CHAMP_MAX_PAYLOAD;i++){
FCSc= FCSc ^ rxbuf[i];
}
//Mêmes FCS : Trame juste
if(FCSr==FCSc){
state=E2;
}
//Sinon trame fausse
else{
Serial.println();
M5.Lcd.println();
Serial.printf("Erreur de Trame, FCSr=%d FCSc=%d", FCSr, FCSc);
M5.Lcd.printf("Erreur de Trame, FCSr=%d FCSc=%d", FCSr, FCSc);
Serial.println();
M5.Lcd.println();
state=E0;
}
}
else{
state=E0;
}
}
break;
case E2:
if(RxSeq!=rxbuf[CHAMP_NUM_SEQ]){
RxSeq=rxbuf[CHAMP_NUM_SEQ];
Serial.printf("Num Seq : [%d] \n", RxSeq);
M5.Lcd.printf("Num Seq : [%d] \n", RxSeq);
Serial.printf("DATA de %d octets :", rxbuflen);
M5.Lcd.printf("DATA de %d octets :", rxbuflen);
Serial.println();
M5.Lcd.println();
for(int j=0;j<rxbuflen;j++){
Serial.printf("%02x|", rxbuf[j]);
M5.Lcd.printf("%02x|", rxbuf[j]);
}
Serial.println();
M5.Lcd.println();
}
else{
Serial.printf("Duplication\n");
M5.Lcd.printf("Duplication\n");
}
state=E3;
break;
case E3:
Serial.println("E3 : Envoi ACK");
M5.Lcd.println("E3 : Envoi ACK");
txbuf[CHAMP_TYPE]=TYPE_ACK;
txbuf[CHAMP_NUM_SEQ]=rxbuf[CHAMP_NUM_SEQ];
//Ajout du FCS du ACK
txbuf[CHAMP_FCS_ACK]=txbuf[CHAMP_TYPE] ^ txbuf[CHAMP_NUM_SEQ];
rf95.send(txbuf,3);
rf95.waitPacketSent();
state=E0;
break;
default:
break;
}
}

View File

@ -0,0 +1,179 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; //Buffer d'emission
uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf); //Buffer de reception
uint8_t state, RxSeq, TxSeq, credit, backoff, NewFrame, EIT;
uint32_t attente;
//Constantes d'état
#define E0 0
#define E1 1
#define E2 2
#define E3 3
#define E4 4
#define E5 5
//Constantes de type
#define TYPE_DATA 1
#define TYPE_ACK 2
#define TIMEOUT_ACK 70
//Constante de crédit
#define MAX_CREDIT 5
//Constante d'adresse
#define LOCAL_ADDR 2
#define SINK_ADDR 0
//Constantes d'infos champ de trame
#define F_S_ADDR 0 //Adresse source
#define F_D_ADDR 1 //Adresse destination
#define F_TYPE 2 //Type
#define F_NUM_SEQ 3 //Numéro de séquence
#define F_MIN_PAYLOAD 4 //Indice du debut de payload
#define F_MAX_PAYLOAD 9 //Indice de fin de payload
#define TAILLE_TRAME 10 //Taille de la trame
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("====Emetteur CAP4====");
M5.Lcd.println("====Emetteur CAP4====");
delay(3000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
//Configuration de la radio
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=E0;
TxSeq=0;
credit=MAX_CREDIT;
Serial.println("Boucle principale.");
M5.Lcd.println("Boucle principale.");
NewFrame=1; //Initialisation drapeau
randomSeed(analogRead(30)); // Initialisation utilisant la broche GPIO39 (VN)
delay(10000);
}
}
void loop() {
switch(state){
case E0: //Code source à l'état d'émission
if(NewFrame==1){
EIT=random(80,120)*random(80,123);
delay(EIT); //attente pour l'envoi de la nouvelle trame
Serial.printf(" EIT : %d ", EIT);
Serial.println();
M5.Lcd.printf(" EIT : %d ", EIT);
M5.Lcd.println();
}
//Formatage des champs de la trame
txbuf[F_S_ADDR]=LOCAL_ADDR;
txbuf[F_D_ADDR]=SINK_ADDR;
txbuf[F_TYPE]=TYPE_DATA;
txbuf[F_NUM_SEQ]=TxSeq;
//Ajout de la payload
for(int i=F_MIN_PAYLOAD; i<=F_MAX_PAYLOAD;i++){
txbuf[i]=random(0, 256);
}
Serial.printf("EMISSION %d", TxSeq);
Serial.println();
M5.Lcd.printf("EMISSION %d \n", TxSeq);
Serial.println();
rf95.send(txbuf,TAILLE_TRAME); //Envoi des données
rf95.waitPacketSent();
credit -=1;
state=E1;
break;
case E1: //CdG
attente = millis()+TIMEOUT_ACK; //Armement du Chien de Garde
state = E2;
break;
case E2: //Mode Réception
rf95.setModeRx();
state=E3;
break;
case E3:
if(millis() > attente){ //Test expiration CdG
Serial.println("===CDG expire===");
M5.Lcd.println("===CDG expire===");
state=E5; //Délais expiré
}
else{
if(rf95.recv(rxbuf, &rxbuflen)){
if((rxbuf[F_TYPE]==TYPE_ACK) && (rxbuf[F_NUM_SEQ]==TxSeq) && (rxbuf[F_D_ADDR]==LOCAL_ADDR)){
//Reception d'un ACK avec le bon num de séquence et la bonne adresse de destination
state=E4;
}
else{
state=E2;
}
}
}
break;
case E4:
Serial.printf("ACK_RECU [%d] \n", TxSeq);
M5.Lcd.printf("ACK_RECU [%d] \n", TxSeq);
state=E0, TxSeq+=1, credit=5;
break;
case E5:
//Serial.printf("Probleme\n");
//M5.Lcd.printf("Probleme\n");
if (credit==0){
Serial.print("ECHEC\n");
M5.Lcd.print("ECHEC\n");
state=E0;
credit=MAX_CREDIT;
TxSeq+=1;
NewFrame=1;
}
else{
Serial.printf("Collision ? Nouvelle tentative n %d\n", MAX_CREDIT-credit);
M5.Lcd.printf("Collision ? Nouvelle tentative n %d\n", MAX_CREDIT-credit);
state=E0;
NewFrame=0; //Toujours la même trame
backoff=random(80,120)*random(80,123);
delay(backoff); //Attente aléatoire ALOHA
Serial.printf(" backoff : [[%d]] ", backoff);
M5.Lcd.printf(" backoff : [[%d]] ", backoff);
Serial.println();
M5.Lcd.println();
}
break;
default:
state=E0;
break;
}
}

View File

@ -0,0 +1,133 @@
#include <SPI.h>
#include <RH_RF95.h>
#include <M5Stack.h>
//Déclaration des constantes
#define RFM95_CS 5 //M5 LoRa
#define RFM95_DIO0 36 //M5 LoRa
RH_RF95 rf95(RFM95_CS, RFM95_DIO0);
uint8_t state;
uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t rxlen=RH_RF95_MAX_MESSAGE_LEN;
uint8_t RxSeq;
//Constantes d'états
#define E0 0
#define E1 1
#define E2 2
#define E3 3
//Constante de type
#define TYPE_DATA 1
#define TYPE_ACK 2
//Constate d'adresse
#define LOCAL_ADDR 0
//Constantes d'infos champ de trame
#define F_S_ADDR 0 //Adresse source
#define F_D_ADDR 1 //Adresse destination
#define F_TYPE 2 //Type
#define F_NUM_SEQ 3 //Numéro de séquence
#define F_MIN_PAYLOAD 4 //Indice du debut de payload
#define F_MAX_PAYLOAD 5 //Indice de fin de payload
#define TAILLE_ACK 4 //Taille de la trame
void setup() {
M5.begin();
M5.Power.begin();
Serial.println("====Recepteur CAP4====");
M5.Lcd.println("====Recepteur CAP4====");
delay(3000);
if(!rf95.init()){
Serial.println("Echec de la mise en place");
M5.Lcd.println("Echec de la mise en place");
}
else{
Serial.println("Mise en place reussie !!!");
M5.Lcd.println("Mise en place reussie !!!");
rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128);
rf95.setFrequency(867.8);
state=E0;
//Serial.println("Boucle principale");
//M5.Lcd.println("Boucle principale");
RxSeq=255;
delay(1000);
}
}
void loop() {
switch(state){
case E0:
//Serial.println("Mode Reception");
//M5.Lcd.println("Mode Reception");
rf95.setModeRx();
state=E1;
break;
case E1:
if(rf95.recv(rxbuf, &rxlen)){
if((rxbuf[F_TYPE]==TYPE_DATA) && (rxbuf[F_D_ADDR]==LOCAL_ADDR)){
//Réception d'un ACK et pour le récepteur
state=E2;
}
else{
state=E0;
}
}
break;
case E2:
if(RxSeq!=rxbuf[F_NUM_SEQ]){
M5.Lcd.printf("===Message Recu===\n");
M5.Lcd.printf("Recu de [%02X]\n",rxbuf[F_S_ADDR]);
RxSeq=rxbuf[F_NUM_SEQ];
Serial.printf("[%d] ", RxSeq);
M5.Lcd.printf("[%d] ", RxSeq);
Serial.printf("DATA de %d octets :", rxlen);
M5.Lcd.printf("DATA de %d octets :", rxlen);
Serial.println();
M5.Lcd.println();
for(int i=0;i<rxlen;i++){
Serial.printf("%02x|", rxbuf[i]);
M5.Lcd.printf("%02x|", rxbuf[i]);
}
Serial.println();
M5.Lcd.println();
}
else{
Serial.printf("===Duplication===\n");
M5.Lcd.printf("===Duplication===\n");
}
state=E3;
break;
case E3:
Serial.println("===Envoi ACK===");
M5.Lcd.println("===Envoi ACK===");
txbuf[F_S_ADDR]=LOCAL_ADDR; //Adresse du sink
txbuf[F_D_ADDR]=rxbuf[F_S_ADDR]; //Émission du ACK vers source DATA
txbuf[F_TYPE]=TYPE_ACK;
txbuf[F_NUM_SEQ]=rxbuf[F_NUM_SEQ];
rf95.send(txbuf,TAILLE_ACK);
rf95.waitPacketSent();
state=E0;
break;
default:
break;
}
}

View File

@ -0,0 +1,87 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0001
#define CANAL 7
//Variables pour le paquet
uint8_t txbuf[40];
uint8_t packetLen;
//Constantes de indices de champs du paquet
#define ADRESSE_MULTICAST 0x7878
#define NB_PAYLOAD 10
//Procédure de formatage
void formaterPaquet(uint8_t* longueur, uint8_t donnees[]){
*longueur=0;
//Ajout En-tete
wino.encodeUi16(ADRESSE_MULTICAST, &donnees[*longueur]);
*longueur +=2;
//Ajout de la payload
for(int i=0; i<NB_PAYLOAD; i++){
donnees[*longueur]=random(0,256);
*longueur+=1;
}
}
void afficherPaquet(uint8_t longueur, uint8_t donnees[]){
for(int i=0; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
int test_envoi=0;
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("====Emetteur sprint 1====");
M5.Lcd.println("====Emetteur sprint 1====");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
//Générateur de payload aléatoire
randomSeed(analogRead(30));
}
void loop() {
wino.process();
if(test_envoi==0){
M5.Lcd.println("====Envoi Paquet====");
Serial.println("====Envoi Paquet====");
formaterPaquet(&packetLen, txbuf);
afficherPaquet(packetLen, txbuf);
wino.send(0xFFFF, txbuf, packetLen);
test_envoi+=1;
}
}

View File

@ -0,0 +1,88 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0003
#define CANAL 7
//Variables pour le paquet
uint8_t rxbuf[40];
uint8_t packetLen=0;
uint8_t indicePaquet;
uint16_t adresseSource;
uint16_t adresseMulticast;
//Constantes de indices de champs du paquet
#define ADRESSE_MULTICAST 0x7878
//Procédure d'affichage de la payload
//À partir de l'indice de début uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Fonction permettant d'extraire l'adresse multicast en gérant
//L'indexation du paquet
uint16_t extraireMulticast(uint8_t* indice, uint8_t donnees[]){
uint16_t adresse;
adresse=wino.decodeUi16(&donnees[*indice]);
*indice+=2;
return adresse;
}
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("====Recepteur sprint 1====");
M5.Lcd.println("====Recepteur sprint 1====");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
}
void loop() {
wino.process();
//Test Reception
if(wino.recv(&adresseSource, rxbuf, &packetLen)){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
M5.Lcd.printf("Noeud Source : %X \n", adresseSource);
Serial.printf("Noeud Source : %X \n", adresseSource);
adresseMulticast=extraireMulticast(&indicePaquet, rxbuf);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
afficherPayload(indicePaquet, packetLen, rxbuf);
indicePaquet=0;
}
}

View File

@ -0,0 +1,140 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0001
#define CANAL 7
//Variables pour le paquet
uint8_t txbuf[40]; //Buffer d'émission
uint8_t rxbuf[40]; //Buffer de réception
uint8_t packetLenTX; //Longueur du paquet émis
uint8_t packetLenRX; //Longueur du paquet reçu
uint8_t indicePaquetRX; //Indice pour le traitement du paquet reçu
uint16_t adresseSource; //Adresse du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
//Constantes de indices de champs du paquet
#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud
#define NB_PAYLOAD 10 //Nombre de données de payload
//Procédure de formatage de l'en tête et de la payload
//du paquet en émission
void formaterPaquet(uint8_t* longueur, uint8_t donnees[]){
*longueur=0;
//Ajout En-tete
wino.encodeUi16(ADRESSE_MULTICAST, &donnees[*longueur]);
*longueur +=2;
//Ajout de la payload
for(int i=0; i<NB_PAYLOAD; i++){
donnees[*longueur]=random(0,256);
*longueur+=1;
}
}
//Affichage du paquet à émettre
void afficherPaquet(uint8_t longueur, uint8_t donnees[]){
for(int i=0; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Fonction permettant d'extraire l'adresse multicast reçu en gérant
//L'indexation du paquet
uint16_t extraireMulticast(uint8_t* indice, uint8_t donnees[]){
uint16_t adresse;
*indice=0;
adresse=wino.decodeUi16(&donnees[*indice]);
*indice+=2;
return adresse;
}
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de la uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Condition pour déclencher le premier envoi
int test_envoi=0;
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("====Emetteur sprint 2====");
M5.Lcd.println("====Emetteur sprint 2====");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
//Générateur de payload aléatoire
randomSeed(analogRead(30));
}
void loop() {
wino.process();
if(test_envoi==0){
M5.Lcd.println("====Envoi Paquet====");
Serial.println("====Envoi Paquet====");
formaterPaquet(&packetLenTX, txbuf);
afficherPaquet(packetLenTX, txbuf);
wino.send(0xFFFF, txbuf, packetLenTX);
test_envoi+=1;
}
//Test Reception
if(wino.recv(&adresseSource, rxbuf, &packetLenRX) && (adresseSource!=3)){
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
M5.Lcd.printf("Noeud Source : %X \n", adresseSource);
Serial.printf("Noeud Source : %X \n", adresseSource);
adresseMulticast=extraireMulticast(&indicePaquetRX, rxbuf);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
afficherPayload(indicePaquetRX, packetLenRX, rxbuf);
//Test même adresse multicast
if(adresseMulticast==ADRESSE_MULTICAST){
M5.Lcd.println("=====Réemission Paquet=====");
Serial.println("=====Réemission Paquet=====");
wino.send(0xFFFF, rxbuf, packetLenRX);
}
}
}

View File

@ -0,0 +1,94 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0003
#define CANAL 7
//Variables pour le paquet
uint8_t rxbuf[40]; //Buffer de reception
uint8_t packetLen; //Longueur du paquet reçu
uint8_t indicePaquet; //Indice pour le traitement du paquet reçu
uint16_t adresseSource; //Adresse du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
//Constantes de indices de champs du paquet
#define ADRESSE_MULTICAST 0x7878
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de payload uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Fonction permettant d'extraire l'adresse multicast reçu en gérant
//L'indexation du paquet
uint16_t extraireMulticast(uint8_t* indice, uint8_t donnees[]){
uint16_t adresse;
*indice=0;
adresse=wino.decodeUi16(&donnees[*indice]);
*indice+=2;
return adresse;
}
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("==Relais sprint 2==");
M5.Lcd.println("==Relais sprint 2===");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
}
void loop() {
wino.process();
//Test Reception
if(wino.recv(&adresseSource, rxbuf, &packetLen) && (adresseSource!=1)){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
M5.Lcd.printf("Noeud Source : %X \n", adresseSource);
Serial.printf("Noeud Source : %X \n", adresseSource);
adresseMulticast=extraireMulticast(&indicePaquet, rxbuf);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
afficherPayload(indicePaquet, packetLen, rxbuf);
//Test même adresse multicast
if(adresseMulticast==ADRESSE_MULTICAST){
M5.Lcd.println("=====Réemission Paquet=====");
Serial.println("=====Réemission Paquet=====");
wino.send(0xFFFF, rxbuf, packetLen);
}
}
}

View File

@ -0,0 +1,147 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0001
#define CANAL 7
//Variables pour le paquet
uint8_t txbuf[40]; //Buffer d'émission
uint8_t rxbuf[40]; //Buffer de réception
uint8_t packetLenTX; //Longueur du paquet émis
uint8_t packetLenRX; //Longueur du paquet reçu
uint16_t adresseSource; //Adresse du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
//Propriétés du paquet
#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud
#define NB_PAYLOAD 10 //Nombre de données de payload
#define TTL_MAX 7 //Time To Live avant expiration
//Indices des champs du paquet
#define CHAMP_ADRESSE 0 //position du champ d'adressage
#define CHAMP_TTL 2 //Position du TTL dans le paquet
#define CHAMP_MIN_PAYLOAD 3 //Position du premier octet de la payload
//Procédure de formatage de l'en tête et de la payload
//du paquet en émission
void formaterPaquet(uint8_t* longueur, uint8_t donnees[]){
*longueur=0;
//Ajout En-tete
wino.encodeUi16(ADRESSE_MULTICAST, &donnees[CHAMP_ADRESSE]);
*longueur +=2;
//Ajout du TTL
donnees[CHAMP_TTL]=0;
*longueur+=1;
//Ajout de la payload
for(int i=0; i<NB_PAYLOAD; i++){
donnees[*longueur]=random(0,256);
*longueur+=1;
}
}
//Affichage du paquet à émettre
void afficherPaquet(uint8_t longueur, uint8_t donnees[]){
for(int i=0; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de la uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Condition pour déclencher le premier envoi
int test_envoi=0;
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("====Emetteur sprint 3====");
M5.Lcd.println("====Emetteur sprint 3====");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
//Générateur de payload aléatoire
randomSeed(analogRead(30));
}
void loop() {
wino.process();
if(test_envoi==0){
M5.Lcd.println("====Envoi Paquet====");
Serial.println("====Envoi Paquet====");
formaterPaquet(&packetLenTX, txbuf);
afficherPaquet(packetLenTX, txbuf);
wino.send(0xFFFF, txbuf, packetLenTX);
test_envoi+=1;
}
//Test Reception
if(wino.recv(&adresseSource, rxbuf, &packetLenRX) && (adresseSource!=3)){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
//Affichage du noeud source
M5.Lcd.printf("Noeud Source : %X \n", adresseSource);
Serial.printf("Noeud Source : %X \n", adresseSource);
//Affichage Adresse Multicast
adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE]);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
//Affichage TTL
M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
//Incrémentation TTL
rxbuf[CHAMP_TTL]+=1;
//Affichage Payload
afficherPayload(CHAMP_MIN_PAYLOAD, packetLenRX, rxbuf);
//Test pour la réemission
//Même adresse multicast et TTL inférieur au max
if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){
M5.Lcd.println("=====Réemission Paquet=====");
Serial.println("=====Réemission Paquet=====");
wino.send(0xFFFF, rxbuf, packetLenRX);
}
}
}

View File

@ -0,0 +1,97 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0003
#define CANAL 7
//Variables pour le paquet
uint8_t rxbuf[40]; //Buffer de reception
uint8_t packetLen; //Longueur du paquet reçu
uint16_t adresseSource; //Adresse du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
//Propriétés du paquet
#define ADRESSE_MULTICAST 0x7878
#define TTL_MAX 7 //Time To Live avant expiration
//Indices des champs du paquet
#define CHAMP_ADRESSE 0 //position du champ d'adressage
#define CHAMP_TTL 2 //Position du TTL dans le paquet
#define CHAMP_MIN_PAYLOAD 3 //Position du premier octet de la payload
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de payload uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("==Relais sprint 3==");
M5.Lcd.println("==Relais sprint 3===");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
}
void loop() {
wino.process();
//Test Reception
if(wino.recv(&adresseSource, rxbuf, &packetLen) && (adresseSource!=1)){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
//Affichage du noeud source
M5.Lcd.printf("Noeud Source : %X \n", adresseSource);
Serial.printf("Noeud Source : %X \n", adresseSource);
//Affichage Adresse Multicast
adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE]);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
//Affichage TTL
M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
//Incrémentation TTL
rxbuf[CHAMP_TTL]+=1;
//Affichage Payload
afficherPayload(CHAMP_MIN_PAYLOAD, packetLen, rxbuf);
//Test pour la réemission
//Même adresse multicast et TTL inférieur au max
if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){
M5.Lcd.println("=====Réemission Paquet=====");
Serial.println("=====Réemission Paquet=====");
wino.send(0xFFFF, rxbuf, packetLen);
}
}
}

View File

@ -0,0 +1,175 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0001
#define CANAL 7
#define DELAI_ENVOI 60000
//Variables pour le paquet
uint8_t txbuf[40]; //Buffer d'émission
uint8_t rxbuf[40]; //Buffer de réception
uint8_t packetLenTX; //Longueur du paquet émis
uint8_t packetLenRX; //Longueur du paquet reçu
uint16_t adresseSource; //Adresse du noeud source
uint16_t adresseDestination; //Adresse du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
uint8_t numSeq=0;
//Propriétés du paquet
#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud
#define NB_PAYLOAD 10 //Nombre de données de payload
#define TTL_MAX 2 //Time To Live avant expiration
//Indices des champs du paquet
#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination
#define CHAMP_TTL 2 //Position du TTL dans le paquet
#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage
#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence
#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload
//Procédure de formatage de l'en tête et de la payload
//du paquet en émission
void formaterPaquet(uint8_t* longueur, uint8_t donnees[], uint8_t nSeq){
*longueur=0;
//Ajout En-tete
//Adresse Destination
wino.encodeUi16(ADRESSE_MULTICAST, &donnees[CHAMP_ADRESSE_DST]);
*longueur +=2;
//Ajout du TTL
donnees[CHAMP_TTL]=0;
*longueur+=1;
//Adresse Source
wino.encodeUi16(ADRESSE_NOEUD, &donnees[CHAMP_ADRESSE_SRC]);
*longueur +=2;
//Numéro de séquence
donnees[CHAMP_NUM_SEQ]=nSeq;
*longueur +=1;
//Ajout de la payload
for(int i=0; i<NB_PAYLOAD; i++){
donnees[*longueur]=random(0,256);
*longueur+=1;
}
}
//Affichage du paquet à émettre
void afficherPaquet(uint8_t longueur, uint8_t donnees[]){
for(int i=0; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de la uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Condition pour déclencher un envoi toute les 20 secondes
uint32_t attente = millis()+DELAI_ENVOI;
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("====Emetteur sprint 4====");
M5.Lcd.println("====Emetteur sprint 4====");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
//Générateur de payload aléatoire
randomSeed(analogRead(30));
}
void loop() {
wino.process();
//Envoi d'un paquet toutes les x secondes
if(millis() > attente){
Serial.println("====Envoi Paquet====");
formaterPaquet(&packetLenTX, txbuf, numSeq);
afficherPaquet(packetLenTX, txbuf);
wino.send(0xFFFF, txbuf, packetLenTX);
numSeq+=1;
attente=millis()+DELAI_ENVOI;
}
//Test Reception
if(wino.recv(&adresseSource, rxbuf, &packetLenRX) && (adresseSource!=3)){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
//Affichage du noeud source
adresseSource=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_SRC]);
M5.Lcd.printf("Noeud Source : %X \n", adresseSource);
Serial.printf("Noeud Source : %X \n", adresseSource);
//Affichage Adresse Multicast
adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_DST]);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
//Affichage TTL
M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
//Incrémentation TTL
rxbuf[CHAMP_TTL]+=1;
//Affichage du numéro de séquence
M5.Lcd.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
Serial.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
//Affichage Payload
afficherPayload(CHAMP_MIN_PAYLOAD, packetLenRX, rxbuf);
//Test pour la réemission
//Paquet non émis par le noeud
if(adresseSource != ADRESSE_NOEUD){
//Même adresse multicast et TTL inférieur au max
if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){
M5.Lcd.println("=====Réemission Paquet=====");
Serial.println("=====Réemission Paquet=====");
wino.send(0xFFFF, rxbuf, packetLenRX);
}
}
else{
M5.Lcd.println("=== Paquet emis par le noeud ===");
Serial.println("=== Paquet emis par le noeud ===");
}
}
}

View File

@ -0,0 +1,111 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0002
#define CANAL 7
//Variables pour le paquet
uint8_t rxbuf[40]; //Buffer de reception
uint8_t packetLen; //Longueur du paquet reçu
uint16_t adresseSource; //Adresse du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
//Propriétés du paquet
#define ADRESSE_MULTICAST 0x7878
#define TTL_MAX 2 //Time To Live avant expiration
//Indices des champs du paquet
#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination
#define CHAMP_TTL 2 //Position du TTL dans le paquet
#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage
#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence
#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de payload uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("==Relais sprint 4==");
M5.Lcd.println("==Relais sprint 4===");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
}
void loop() {
wino.process();
//Test Reception
if(wino.recv(&adresseSource, rxbuf, &packetLen) /*&& (adresseSource!=1)*/){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
//Affichage du noeud source
adresseSource=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_SRC]);
M5.Lcd.printf("Noeud Source : %X \n", adresseSource);
Serial.printf("Noeud Source : %X \n", adresseSource);
//Affichage Adresse Multicast
adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_DST]);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
//Affichage TTL
M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
//Incrémentation TTL
rxbuf[CHAMP_TTL]+=1;
//Affichage du numéro de séquence
M5.Lcd.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
Serial.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
//Affichage Payload
afficherPayload(CHAMP_MIN_PAYLOAD, packetLen, rxbuf);
//Test pour la réemission
//Paquet non émis par le noeud
if(adresseSource != ADRESSE_NOEUD){
//Même adresse multicast et TTL inférieur au max
if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){
M5.Lcd.println("=====Réemission Paquet=====");
M5.Lcd.println("=====Réemission Paquet=====");
wino.send(0xFFFF, rxbuf, packetLen);
}
}
else{
M5.Lcd.println("=== Paquet emis par le noeud ===");
Serial.println("=== Paquet emis par le noeud ===");
}
}
}

View File

@ -0,0 +1,194 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0001
#define CANAL 7
#define DELAI_ENVOI 60000
//Variables pour le paquet
uint8_t txbuf[40]; //Buffer d'émission
uint8_t rxbuf[40]; //Buffer de réception
uint8_t packetLenTX; //Longueur du paquet émis
uint8_t packetLenRX; //Longueur du paquet reçu
uint16_t adresseSource; //Adresse du noeud source
uint16_t adresseDestination; //Adresse du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
uint8_t numSeq=0; //Numéro de séquence incrémenté pour l'envoi
//Variables de mémorisation de l'adresse
//et du numéro de séquence précédent
uint16_t adressePrec=0xFFFF; //Adresse reçue précédement
uint8_t numSeqPrec=255; //Numéro de séquence reçu précédement
//Propriétés du paquet
#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud
#define NB_PAYLOAD 10 //Nombre de données de payload
#define TTL_MAX 7 //Time To Live avant expiration
//Indices des champs du paquet
#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination
#define CHAMP_TTL 2 //Position du TTL dans le paquet
#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage
#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence
#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload
//Procédure de formatage de l'en tête et de la payload
//du paquet en émission
void formaterPaquet(uint8_t* longueur, uint8_t donnees[], uint8_t nSeq){
*longueur=0;
//Ajout En-tete
//Adresse Destination
wino.encodeUi16(ADRESSE_MULTICAST, &donnees[CHAMP_ADRESSE_DST]);
*longueur +=2;
//Ajout du TTL
donnees[CHAMP_TTL]=0;
*longueur+=1;
//Adresse Source
wino.encodeUi16(ADRESSE_NOEUD, &donnees[CHAMP_ADRESSE_SRC]);
*longueur +=2;
//Numéro de séquence
donnees[CHAMP_NUM_SEQ]=nSeq;
*longueur +=1;
//Ajout de la payload
for(int i=0; i<NB_PAYLOAD; i++){
donnees[*longueur]=random(0,256);
*longueur+=1;
}
}
//Affichage du paquet à émettre
void afficherPaquet(uint8_t longueur, uint8_t donnees[]){
for(int i=0; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de la uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Condition pour déclencher un envoi toute les 20 secondes
uint32_t attente = millis()+DELAI_ENVOI;
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("====Emetteur sprint 5====");
M5.Lcd.println("====Emetteur sprint 5====");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
//Générateur de payload aléatoire
randomSeed(analogRead(30));
}
void loop() {
wino.process();
//Envoi d'un paquet toutes les DELAI_ENVOI secondes
if(millis() > attente){
M5.Lcd.println("====Envoi Paquet====");
Serial.println("====Envoi Paquet====");
formaterPaquet(&packetLenTX, txbuf, numSeq);
afficherPaquet(packetLenTX, txbuf);
wino.send(0xFFFF, txbuf, packetLenTX);
numSeq+=1;
attente=millis()+DELAI_ENVOI;
}
//Test Reception
if(wino.recv(&adresseSource, rxbuf, &packetLenRX) && (adresseSource!=3)){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
//Affichage du noeud source
adresseSource=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_SRC]);
M5.Lcd.printf("Noeud Source : %X \n", adresseSource);
Serial.printf("Noeud Source : %X \n", adresseSource);
//Affichage Adresse Multicast
adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_DST]);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
//Affichage TTL
M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
//Incrémentation TTL
rxbuf[CHAMP_TTL]+=1;
//Affichage du numéro de séquence
M5.Lcd.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
Serial.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
//Affichage Payload
afficherPayload(CHAMP_MIN_PAYLOAD, packetLenRX, rxbuf);
//Test pour la réemission
//Le paquet n'a pas été émis par le noeud lui-même
if(adresseSource!=ADRESSE_NOEUD){
//Même adresse multicast et TTL inférieur au max
if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){
//Test si le paquet n'a pas été déjà reçu
if((adressePrec!=adresseSource) || (numSeqPrec!=rxbuf[CHAMP_NUM_SEQ])){
M5.Lcd.println("=====Réemission Paquet=====");
Serial.println("=====Réemission Paquet=====");
adressePrec=adresseSource;
numSeqPrec=rxbuf[CHAMP_NUM_SEQ];
wino.send(0xFFFF, rxbuf, packetLenRX);
}
else{
M5.Lcd.println("===Déjà Reçu===");
Serial.println("===Déjà Reçu===");
}
}
else{
M5.Lcd.println("Adresse multicast incorecte ou TTL dépassé");
Serial.println("Adresse multicast incorecte ou TTL dépassé");
}
}
else{
M5.Lcd.println("===Paquet émis par le noeud===");
Serial.println("===Paquet émis par le noeud===");
}
}
}

View File

@ -0,0 +1,128 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0002
#define CANAL 7
//Variables pour le paquet
uint8_t rxbuf[40]; //Buffer de reception
uint8_t packetLenRX; //Longueur du paquet reçu
uint16_t adresseSource; //Adresse du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
//Variables de mémorisation de l'adresse
//et du numéro de séquence précédent
uint16_t adressePrec=0xFFFF; //Adresse reçue précédement
uint8_t numSeqPrec=255; //Numéro de séquence reçu précédement
//Propriétés du paquet
#define ADRESSE_MULTICAST 0x7878
#define TTL_MAX 7 //Time To Live avant expiration
//Indices des champs du paquet (format paquet)
#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination
#define CHAMP_TTL 2 //Position du TTL dans le paquet
#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage
#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence
#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de payload uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("==Relais sprint 5==");
M5.Lcd.println("==Relais sprint 5===");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
}
void loop() {
wino.process();
//Test Reception
if(wino.recv(&adresseSource, rxbuf, &packetLenRX) /*&& (adresseSource!=1)*/){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
//Affichage du noeud source
adresseSource=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_SRC]);
M5.Lcd.printf("Noeud Source : %X \n", adresseSource);
Serial.printf("Noeud Source : %X \n", adresseSource);
//Affichage Adresse Multicast
adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_DST]);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
//Affichage TTL
M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
//Incrémentation TTL
rxbuf[CHAMP_TTL]+=1;
//Affichage du numéro de séquence
M5.Lcd.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
Serial.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
//Affichage Payload
afficherPayload(CHAMP_MIN_PAYLOAD, packetLenRX, rxbuf);
//Test pour la réemission
//Le paquet n'a pas été émis par le noeud lui-même
if(adresseSource!=ADRESSE_NOEUD){
//Même adresse multicast et TTL inférieur au max
if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){
//Test si le paquet n'a pas été déjà reçu
if((adressePrec!=adresseSource) || (numSeqPrec!=rxbuf[CHAMP_NUM_SEQ])){
M5.Lcd.println("=====Réemission Paquet=====");
Serial.println("=====Réemission Paquet=====");
adressePrec=adresseSource;
numSeqPrec=rxbuf[CHAMP_NUM_SEQ];
wino.send(0xFFFF, rxbuf, packetLenRX);
}
else{
M5.Lcd.println("===Déjà Reçu===");
Serial.println("===Déjà Reçu===");
}
}
else{
M5.Lcd.println("Adresse multicast incorecte ou TTL dépassé");
Serial.println("Adresse multicast incorecte ou TTL dépassé");
}
}
else{
M5.Lcd.println("===Paquet émis par le noeud===");
Serial.println("===Paquet émis par le noeud===");
}
}
}

View File

@ -0,0 +1,264 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0001
#define CANAL 7
#define DELAI_ENVOI 60000
//Variables pour le paquet
uint8_t txbuf[40]; //Buffer d'émission
uint8_t rxbuf[40]; //Buffer de réception
uint8_t packetLenTX; //Longueur du paquet émis
uint8_t packetLenRX; //Longueur du paquet reçu
uint16_t adresseMacSource; //Adresse de couche 2 du noeud source
uint16_t adresseIpSource; //Adresse de couche 3 du noeud source
uint16_t adresseDestination; //Adresse du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
uint8_t numSeq=0; //Numéro de séquence incrémenté pour l'envoi
//Propriétés du paquet
#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud
#define NB_PAYLOAD 10 //Nombre de données de payload
#define TTL_MAX 7 //Time To Live avant expiration
//Indices des champs du paquet
#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination
#define CHAMP_TTL 2 //Position du TTL dans le paquet
#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage
#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence
#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload
//Mémorisation des paquets
//Nombre de paquets maximums mémorisables
#define NB_PAQUET_MEM 10
//Structure pour l'identification
struct identifiant{
uint16_t srcAddr;
uint8_t sqn;
};
typedef struct identifiant IDENTIFIANT;
uint8_t indiceMemId=0; //Indice pour la mise à jour dans le tableau
IDENTIFIANT idRecu; //Identifiant courant du paquet reçu
IDENTIFIANT tabId[NB_PAQUET_MEM]; //Tableau d'identifiants
//Procédures pour la mémorisation
//Initialisation du tableau d'identifiants
void initTabId(IDENTIFIANT tab[]){
for(int i=0; i<NB_PAQUET_MEM; i++){
tab[i].srcAddr=0xFFFF;
tab[i].sqn=255;
}
}
//Affichage des id du tableau
void AfficheId(IDENTIFIANT tab[]){
for(int i=0; i<NB_PAQUET_MEM; i++){
M5.Lcd.printf("{%02X, %02X}", tab[i].srcAddr, tab[i].sqn);
Serial.printf("{%02X, %02X}", tab[i].srcAddr, tab[i].sqn);
}
M5.Lcd.println();
Serial.println();
}
//Ajout d'un nouvel identifiant dans le tableau
//L'indice du tableau suit un modulo pour reboucler dans les mises à jour
//Afin de ne garder que les derniers NB_PAQUET_MEM paquets
void ajoutTabId(IDENTIFIANT id, IDENTIFIANT tab[], uint8_t* indice){
tab[*indice]=id;
*indice=(*indice+1)%NB_PAQUET_MEM;
}
//Fonction vérifiant si l'id du paquet arrivé a déjà été routé
//Si c'est le cas la fonction renvoi 1 (VRAI)
//Sinon, elle renvoi 0 (FAUX)
int PaquetDejaRoute(IDENTIFIANT id, IDENTIFIANT tab[]){
for(int i=0; i<NB_PAQUET_MEM; i++){
//Un élément du tableau correspond
if((tab[i].srcAddr==id.srcAddr) && (tab[i].sqn==id.sqn)){
return 1;
}
}
return 0;
}
//Procédures pour l'envoi
//Procédure de formatage de l'en tête et de la payload
//du paquet en émission
void formaterPaquet(uint8_t* longueur, uint8_t donnees[], uint8_t nSeq){
*longueur=0;
//Ajout En-tete
//Adresse Destination
wino.encodeUi16(ADRESSE_MULTICAST, &donnees[CHAMP_ADRESSE_DST]);
*longueur +=2;
//Ajout du TTL
donnees[CHAMP_TTL]=0;
*longueur+=1;
//Adresse Source
wino.encodeUi16(ADRESSE_NOEUD, &donnees[CHAMP_ADRESSE_SRC]);
*longueur +=2;
//Numéro de séquence
donnees[CHAMP_NUM_SEQ]=nSeq;
*longueur +=1;
//Ajout de la payload
for(int i=0; i<NB_PAYLOAD; i++){
donnees[*longueur]=random(0,256);
*longueur+=1;
}
}
//Affichage du paquet à émettre
void afficherPaquet(uint8_t longueur, uint8_t donnees[]){
for(int i=0; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Procédures pour la réception
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de la uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
//Condition pour déclencher un envoi toute les 20 secondes
uint32_t attente = millis()+DELAI_ENVOI;
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("====Emetteur sprint 5====");
M5.Lcd.println("====Emetteur sprint 5====");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
//Générateur de payload aléatoire
randomSeed(analogRead(30));
//Initialisation du tableau de mémoire des identifiants
initTabId(tabId);
}
void loop() {
wino.process();
//Envoi d'un paquet toutes les DELAI_ENVOI secondes
if(millis() > attente){
M5.Lcd.println("====Envoi Paquet====");
Serial.println("====Envoi Paquet====");
formaterPaquet(&packetLenTX, txbuf, numSeq);
afficherPaquet(packetLenTX, txbuf);
wino.send(0xFFFF, txbuf, packetLenTX);
numSeq+=1;
attente=millis()+DELAI_ENVOI;
}
//Test Reception
if(wino.recv(&adresseMacSource, rxbuf, &packetLenRX) && (adresseMacSource!=3)){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
//Affichage du noeud source
adresseIpSource=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_SRC]);
M5.Lcd.printf("MAC SRC : %X | ", adresseMacSource);
Serial.printf("MAC SRC : %X | ", adresseMacSource);
M5.Lcd.printf("IP SRC : %X \n", adresseIpSource);
Serial.printf("IP SRC : %X \n", adresseIpSource);
//Affichage Adresse Multicast
adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_DST]);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
//Affichage TTL
M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
//Incrémentation TTL
rxbuf[CHAMP_TTL]+=1;
//Affichage du numéro de séquence
M5.Lcd.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
Serial.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
//Affichage Payload
afficherPayload(CHAMP_MIN_PAYLOAD, packetLenRX, rxbuf);
//Test pour la réemission
//Le paquet n'a pas été émis par le noeud lui-même
if(adresseIpSource!=ADRESSE_NOEUD){
//Même adresse multicast et TTL inférieur au max
if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){
//Récupération de l'identifiant du paquet recu
idRecu.srcAddr=adresseIpSource;
idRecu.sqn=rxbuf[CHAMP_NUM_SEQ];
//Test si le paquet n'a pas déjà été reçu
if(!PaquetDejaRoute(idRecu, tabId)){
M5.Lcd.println("=====Reemission Paquet=====");
Serial.println("=====Reemission Paquet=====");
//Ajout du nouvel id dans le tableau
ajoutTabId(idRecu, tabId, &indiceMemId);
//Réemission du paquet
wino.send(0xFFFF, rxbuf, packetLenRX);
//Affichage des id mémorisés
AfficheId(tabId);
}
else{
M5.Lcd.println("===Deja Recu===");
Serial.println("===Deja Recu===");
}
}
else{
M5.Lcd.println("Adresse multicast incorecte ou TTL depasse");
Serial.println("Adresse multicast incorecte ou TTL depasse");
}
}
else{
M5.Lcd.println("===Paquet emis par le noeud===");
Serial.println("===Paquet emis par le noeud===");
}
}
}

View File

@ -0,0 +1,197 @@
#include <Arduino.h>
#include <SPI.h>
#include "SimpleWiNo.h"
#include <M5Stack.h>
//Objet Wino
SimpleWiNo wino;
//Constantes de configuration des noeuds
#define ADRESSE_CLUSTER 0x4A89
#define ADRESSE_NOEUD 0x0002
#define CANAL 7
//Variables pour le paquet
uint8_t rxbuf[40]; //Buffer de reception
uint8_t packetLenRX; //Longueur du paquet reçu
uint16_t adresseMacSource; //Adresse de couche 2 du noeud source
uint16_t adresseIpSource; //Adresse de couche 3 du noeud source
uint16_t adresseMulticast; //Adresse multicast reçue
//Propriétés du paquet
#define ADRESSE_MULTICAST 0x7878
#define TTL_MAX 7 //Time To Live avant expiration
//Indices des champs du paquet (format paquet)
#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination
#define CHAMP_TTL 2 //Position du TTL dans le paquet
#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage
#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence
#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload
//Mémorisation des paquets
//Nombre de paquets maximums mémorisables
#define NB_PAQUET_MEM 10
//Structure pour l'identification
struct identifiant{
uint16_t srcAddr;
uint8_t sqn;
};
typedef struct identifiant IDENTIFIANT;
uint8_t indiceMemId=0; //Indice pour la mise à jour dans le tableau
IDENTIFIANT idRecu; //Identifiant courant du paquet reçu
IDENTIFIANT tabId[NB_PAQUET_MEM]; //Tableau d'identifiants
//Procédures pour la mémorisation
//Initialisation du tableau d'identifiants
void initTabId(IDENTIFIANT tab[]){
for(int i=0; i<NB_PAQUET_MEM; i++){
tab[i].srcAddr=0xFFFF;
tab[i].sqn=255;
}
}
//Affichage des id du tableau
void AfficheId(IDENTIFIANT tab[]){
for(int i=0; i<NB_PAQUET_MEM; i++){
M5.Lcd.printf("{%02X, %02X}", tab[i].srcAddr, tab[i].sqn);
Serial.printf("{%02X, %02X}", tab[i].srcAddr, tab[i].sqn);
}
M5.Lcd.println();
Serial.println();
}
//Ajout d'un nouvel identifiant dans le tableau
//L'indice du tableau suit un modulo pour reboucler dans les mises à jour
//Afin de ne garder que les derniers NB_PAQUET_MEM paquets
void ajoutTabId(IDENTIFIANT id, IDENTIFIANT tab[], uint8_t* indice){
tab[*indice]=id;
*indice=(*indice+1)%NB_PAQUET_MEM;
}
//Fonction vérifiant si l'id du paquet arrivé a déjà été routé
//Si c'est le cas la fonction renvoi 1 (VRAI)
//Sinon, elle renvoi 0 (FAUX)
int PaquetDejaRoute(IDENTIFIANT id, IDENTIFIANT tab[]){
for(int i=0; i<NB_PAQUET_MEM; i++){
//Un élément du tableau correspond
if((tab[i].srcAddr==id.srcAddr) && (tab[i].sqn==id.sqn)){
return 1;
}
}
return 0;
}
//Procédure d'affichage de la payload reçue
//À partir de l'indice de début de payload uniquement
void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){
M5.Lcd.printf("Payload : ");
Serial.printf("Payload : ");
for(int i=indiceDebut; i<longueur; i++){
M5.Lcd.printf("|%02X", donnees[i]);
Serial.printf("|%02X", donnees[i]);
}
M5.Lcd.println("|");
Serial.println("|");
}
void setup() {
//Démarage M5
M5.begin();
M5.Power.begin();
Serial.println("==Relais sprint 5==");
M5.Lcd.println("==Relais sprint 5===");
delay(3000);
//Demarage wino
wino.init();
//Adresse cluster
wino.set(NODE_PANID, ADRESSE_CLUSTER);
//Adresse noeud
wino.set(NODE_SHORT_ADDRESS, ADRESSE_NOEUD);
//Fréquence de travail
wino.set(NODE_CHANNEL, CANAL);
//Initialisation du tableau de mémoire des identifiants
initTabId(tabId);
}
void loop() {
wino.process();
//Test Reception
if(wino.recv(&adresseMacSource, rxbuf, &packetLenRX) /*&& (adresseMacSource!=1)*/){
//Affichage des éléments du paquet reçu
M5.Lcd.println("=====Reception=====");
Serial.println("=====Reception=====");
//Affichage du noeud source
adresseIpSource=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_SRC]);
M5.Lcd.printf("MAC SRC : %X | ", adresseMacSource);
Serial.printf("MAC SRC : %X | ", adresseMacSource);
M5.Lcd.printf("IP SRC : %X \n", adresseIpSource);
Serial.printf("IP SRC : %X \n", adresseIpSource);
//Affichage Adresse Multicast
adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_DST]);
M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast);
Serial.printf("Adresse Multicast : %X \n", adresseMulticast);
//Affichage TTL
M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]);
//Incrémentation TTL
rxbuf[CHAMP_TTL]+=1;
//Affichage du numéro de séquence
M5.Lcd.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
Serial.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]);
//Affichage Payload
afficherPayload(CHAMP_MIN_PAYLOAD, packetLenRX, rxbuf);
//Test pour la réemission
//Le paquet n'a pas été émis par le noeud lui-même
if(adresseIpSource!=ADRESSE_NOEUD){
//Même adresse multicast et TTL inférieur au max
if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){
//Récupération de l'identifiant du paquet recu
idRecu.srcAddr=adresseIpSource;
idRecu.sqn=rxbuf[CHAMP_NUM_SEQ];
//Test si le paquet n'a pas déjà été reçu
if(!PaquetDejaRoute(idRecu, tabId)){
M5.Lcd.println("=====Reemission Paquet=====");
Serial.println("=====Reemission Paquet=====");
//Ajout du nouvel id dans le tableau
ajoutTabId(idRecu, tabId, &indiceMemId);
//Réemission du paquet
wino.send(0xFFFF, rxbuf, packetLenRX);
//Affichage des id mémorisés
AfficheId(tabId);
}
else{
M5.Lcd.println("===Deja Recu===");
Serial.println("===Deja Recu===");
}
}
else{
M5.Lcd.println("Adresse multicast incorecte ou TTL depasse");
Serial.println("Adresse multicast incorecte ou TTL depasse");
}
}
else{
M5.Lcd.println("===Paquet emis par le noeud===");
Serial.println("===Paquet emis par le noeud===");
}
}
}

Binary file not shown.