180 lines
4.6 KiB
C++
180 lines
4.6 KiB
C++
#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;
|
|
}
|
|
|
|
}
|