Bonjour, dans le cadre de mon stage je cherche a creer un reseau LoRa fermé qui a pour but de recuperer la temperature et l 'humidite dans un local et en fonction de celle-ci allumer ou non le chauffage. Pour cela j'utilise des Arduino MKR1310. Dans le systeme, il y en a une (ou plus potentielleemnt) comme emettrice qui va envoyer la temperature et l'humidite et l autre comme receptrice.
La communication se fait comme suit:
E: envoie la temperature et l humidite et attend une reponse
R: Recoit le paquet puis renvoie celui ci comme reponse
R: Transmet via le port serie les donnees a un script python
Le script python analyse les donnees et renvoie une commande ON/OFF
R: Renvoi la commande
E: La recupere et active ou non l'actionneur (dans le code juste une led pour l'instant)
Toute cette partie fonctionnait très bien quand je n'avais pas encore implenté le cryptage.
Après j'ai via la bibliotheque AESLib crypter toutes les communications LoRa et cela fonctionne bien dans l'ensemble à un détail qui me fait m'arracher les cheveux depuis une semaine: au bout d'un certains temps la boucle de l'un des deux codes s'arrete. Parfois c'est l'emetteur et parfois le recepteur, ça prend parfois des dizaines d'iterations et parfois des centaines mais ça le fait à chaque fois. De plus j'ai placé plusieurs print dans le programme pour savoir ou est ce qu'il s'arrete mais ce n'est pas toujours la meme chose. De ce que j'ai compris ce genre d'erreur peuvent etre dues a des depassements de memoire, des boucles infines (probablement pas le cas ici) ou peut etre un probleme au niveau de la librairie (A noter que j'ai supprimer une ligne du fichier AESlib.h qui contenait une fonction qui bloqué la compilation c'est peut etre stupide mais c'est le seul moyen que j'ai trouvé pour pouvoir compiler).Merci d'avance pour votre aide !
// --- Emetteur LoRa ---
#include <SPI.h>
#include <LoRa.h>
#include "DHT.h"
#include <AESLib.h>
AESLib aesLib;
byte aes_key[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81
};
byte aes_iv[] = {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F
};
// Fonction pour ajouter du padding pour le cryptage
int addPadding(byte *data, int len) {
int padLen = 16 - (len % 16);
for (int i = 0; i < padLen; i++) {
data[len + i] = padLen;
}
return len + padLen;
}
// Fonction pour retirer le padding apres le decryptage
int removePadding(byte* data, int len) {
int padLen = data[len - 1];
return len - padLen;
}
#define LED_Chauffage 6
#define LORA_BAND 868E6 // Frequenza LoRa
#define SYSTEM_ID 1234 // ID del sistema impostato dall'utente
#define NUM 2 // Numero of the Node
int counter = 0;
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
int compt=0;
void setup() {
Serial.begin(115200);
dht.begin();
//while (!Serial);
pinMode(LED_Chauffage, OUTPUT);
Serial.println("LoRa Sender");
Serial.println("0");
if (!LoRa.begin(LORA_BAND)) {
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
LoRa.flush(); // vider le buffer Lora
Serial.println("0");
//lire la temperature et l'humidite du capteur DHT
int h = dht.readHumidity();
Serial.println("01");
int t = dht.readTemperature();
Serial.println("02");
bool ackReceived = false;
String expectedResponse = String(SYSTEM_ID) + "," + String(t)+ "," + String(h)+"," + String(NUM);
Serial.println(compt);
compt++;
Serial.println("03");
while (!ackReceived) {
Serial.println("02");
Serial.print("Valore trasmesso: ");
Serial.print(t);
Serial.print(",");
Serial.print(h);
Serial.print(",");
Serial.println(NUM);
//Recuperation des donnees sous forme de char, puis on place cette chaine de caractere dans un tableau de Byte
String capteur=expectedResponse;
byte capteur_plain[64];
byte capteur_encrypted[64];
Serial.println("erreur2");
int msgLen = capteur.length();
memcpy(capteur_plain, capteur.c_str(), msgLen);
// On ajoute du padding au cas ou la chaine de caractere n'a pas une longueur multiple de 16
//puis on crypte le message avant de l'envoyer en lora
int paddedLen = addPadding(capteur_plain, msgLen);
aesLib.encrypt(capteur_plain, paddedLen,capteur_encrypted, aes_key, 128, aes_iv);
LoRa.beginPacket();
LoRa.write(capteur_encrypted, paddedLen);
LoRa.endPacket();
Serial.println("Pacchetto inviato, in attesa di conferma...");
Serial.println("erreur3");
// Une fois envoye on attend la reponse du receiver
LoRa.receive();
long startWait = millis();
String receivedData = "";
Serial.println("erreur4");
// On attend la reponse pdt 2 secondes et on decrypte le message de la meme maniere que poiur l encryption
//Si la reponse est equivalente a ce qu'on a envoye on peut passer au renvoi de la commande
while (millis() - startWait < 2000) { // Timeout de 2 secondes
int packetSize = LoRa.parsePacket();
if (packetSize) {
Serial.println("erreur6");
byte rep_encrypted[64];
byte rep_decrypted[64];
int len = 0;
while (LoRa.available() && len < 64) {
rep_encrypted[len++] = LoRa.read();
}
aesLib.decrypt(rep_encrypted, len, rep_decrypted, aes_key, 128, aes_iv);
int realLen = removePadding(rep_decrypted, len);
rep_decrypted[realLen] = '\0'; // Fin de chaîne
Serial.print("Risposta ricevuta: ");
Serial.println("erreur7");
Serial.println((char*)rep_decrypted);
receivedData = String((char*)rep_decrypted);
if (receivedData == expectedResponse) {
Serial.println("Conferma ricevuta!");
ackReceived = true;
break;
} else {
Serial.println("Errore! Ritrasmissione...");
break;
}
}
}
}
//On passe en mode reception pour recuperer la commande
Serial.println("04");
LoRa.flush();
Serial.println("erreur8");
long startWait = millis();
String command="";
while (millis() - startWait < 2000) {
int packetSize = LoRa.parsePacket();
if (packetSize) {
byte command_encrypted[64];
byte command_decrypted[64];
int len = 0;
Serial.println("erreur9");
while (LoRa.available() && len < 64) {
command_encrypted[len++] = LoRa.read();
}
Serial.println("erreur10");
aesLib.decrypt(command_encrypted, len, command_decrypted, aes_key, 128, aes_iv);
int realLen = removePadding(command_decrypted, len);
command_decrypted[realLen] = '\0'; // Fin de chaîne
command = String((char*)command_decrypted);
Serial.print("Message reçu (déchiffré) : ");
Serial.println(command);
Serial.println("erreur11");
// on recupere chaque element de la commnde separement
// Si "l etat" de la commande est sur ON la led s'allume sinon elle s'eteint
int commaIndex = command.indexOf(',');
int commaIndex2 = command.indexOf(',',commaIndex+1);
if (commaIndex != -1) {
Serial.println("erreur12");
int Com_ID = command.substring(0, commaIndex).toInt();
String Com_state = command.substring(commaIndex + 1,commaIndex2);
int Com_Num = command.substring(commaIndex2+1).toInt();
Serial.println("erreur121");
if(Com_state=="ON" && Com_Num==NUM && Com_ID==SYSTEM_ID){
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("LIGHT ON");
}
else if(Com_state=="OFF"){
Serial.println("erreur123");
digitalWrite(LED_BUILTIN, LOW);
Serial.println("Light OFF");
}
else{
Serial.println("erreur122");
digitalWrite(LED_BUILTIN, LOW);
Serial.println("Error command");
}
}
}
}
Serial.println("erreur13");
delay(7000);
}
// --- Recepteur LoRa ---
#include <SPI.h>
#include <LoRa.h>
#include <AESLib.h>
#define LORA_BAND 868E6 // Frequenza LoRa
#define SYSTEM_ID 1234 // ID del sistema impostato dall'utente
#define NUM 1
AESLib aesLib;
byte aes_key[] = {
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81
};
byte aes_iv[] = {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F
};
int removePadding(byte* data, int len) {
int padLen = data[len - 1];
return len - padLen;
}
int addPadding(byte *data, int len) {
int padLen = 16 - (len % 16);
for (int i = 0; i < padLen; i++) {
data[len + i] = padLen;
}
return len + padLen;
}
int counter = 0;
void setup() {
Serial.begin(115200);
// while (!Serial);
//Serial.println("LoRa Receiver");
if (!LoRa.begin(LORA_BAND)) {
//Serial.println("Starting LoRa failed!");
while (1);
}
LoRa.receive(); // Mette subito il ricevitore in ascolto
}
void loop() {
LoRa.flush();
int packetSize = LoRa.parsePacket();
if (packetSize) {
byte receivedData_encrypted[64];
byte receivedData_decrypted[64];
int len = 0;
String receivedData = "";
while (LoRa.available() && len < 64) {
receivedData_encrypted[len++] = LoRa.read();
}
aesLib.decrypt(receivedData_encrypted, len, receivedData_decrypted, aes_key, 128, aes_iv);
int realLen = removePadding(receivedData_decrypted, len);
receivedData_decrypted[realLen] = '\0'; // Fin de chaîne
receivedData = String((char*)receivedData_decrypted);
//Serial.println("données reçues: ");
// Parsing ID e valore
int commaIndex = receivedData.indexOf(',');
int commaIndex2 = receivedData.indexOf(',',commaIndex+1);
int commaIndex3 = receivedData.indexOf(',',commaIndex2+1);
if (commaIndex != -1) {
int receivedID = receivedData.substring(0, commaIndex).toInt();
int receivedValueTemp = receivedData.substring(commaIndex + 1,commaIndex2).toInt();
int receivedValueHum = receivedData.substring(commaIndex2+1,commaIndex3).toInt();
int receivedNum = receivedData.substring(commaIndex3+1).toInt();
//Serial.print(receivedID);
//Serial.print("Valeur T: ");
//Serial.print(receivedValueTemp);
//Serial.print("Valeur Humidity: ");
//Serial.print(receivedValueHum);
//Serial.print("Numero sender: ");
//Serial.println(receivedNum);
if (receivedID == SYSTEM_ID) {
Serial.println(counter);
counter++;
Serial.println(receivedData);
//Serial.print("Valore valido ricevuto: ");
//Serial.println(receivedValue);
// Ritenta l'invio della risposta fino a conferma
bool responseSent = false;
for (int i = 0; i < 3 && !responseSent; i++) { // Fino a 3 tentativi
String reponse=String(SYSTEM_ID)+","+String(receivedValueTemp)+","+String(receivedValueHum)+","+String(receivedNum);
byte plain[64];
byte reponse_encrypted[64];
int msgLen = reponse.length();
memcpy(plain, reponse.c_str(), msgLen);
int paddedLen = addPadding(plain, msgLen);
aesLib.encrypt(plain, paddedLen, reponse_encrypted, aes_key, 128, aes_iv);
//Serial.print("Reponse envoyée: ");
//Serial.println(reponse);
delay(200); // Attende prima di rispondere
LoRa.beginPacket();
LoRa.write(reponse_encrypted, paddedLen);
LoRa.endPacket();
//Serial.println("Risposta inviata");
responseSent = true;
}
LoRa.receive();
delay(1000);
String command="";
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
Serial.print("je le recois");
byte command_plain[64];
byte command_encrypted[64];
int msgLen = command.length();
memcpy(command_plain, command.c_str(), msgLen);
int paddedLen = addPadding(command_plain, msgLen);
aesLib.encrypt(command_plain, paddedLen, command_encrypted, aes_key, 128, aes_iv);
LoRa.beginPacket();
LoRa.write(command_encrypted, paddedLen);
LoRa.endPacket();
Serial.println("message envoyé");
}
else{
LoRa.beginPacket();
LoRa.print("ERROR_COMMAND");
LoRa.endPacket();
delay(10);
}
}
}
LoRa.receive();
//else {
//Serial.println("ID errato, pacchetto ignorato");
//}
}
}