Je travail actuellement sur un projet de tracker GPS avec une Arduino UNO R3 , un Shield LoRa LA66 et un module GPS Neo7M.
J'ai un blocage au niveau de mon code sur le format de mes cordonnées gps à envoyer dans le payload pour le recevoir sur TTN , mes payload sont vide sur TTN mais je vois bien les trames. Quelqu'un qui à déjà eu un projet similaire ou alors qui connait bien le Shield LA66 pourrait m'aider à avancer svp ?
Code:
#include <SoftwareSerial.h>
#include <VMA430_GPS.h> // Inclue la librairie associé au module gps
#include <SoftwareSerial.h>
/*
*/
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
long old_time=millis();
long new_time;
long uplink_interval=30000; //ms
bool time_to_at_recvb=false;
bool get_LA66_data_status=false;
bool network_joined_status=false;
SoftwareSerial ss(10, 11); // Arduino RX, TX ,
SoftwareSerial sa(12, 13);
VMA430_GPS gps(&sa);
char rxbuff[128];
uint8_t rxbuff_index=0;
void setup() {
// initialize serial
Serial.begin(9600);
Serial.println("hello");
gps.begin(9600); // Sets up the GPS module to communicate with the Arduino over serial at 9600 baud
gps.setUBXNav(); // Enable the UBX mavigation messages to be sent from the GPS module
ss.begin(9600);
ss.listen();
sa.begin(9600);
sa.listen();
// reserve 200 bytes for the inputString:
inputString.reserve(200);
ss.println("ATZ");//reset LA66
sa.println("ATZ");//reset LA66
}
void loop() {
new_time = millis();
if((new_time-old_time>=uplink_interval)&&(network_joined_status==1)){
old_time = new_time;
get_LA66_data_status=false;
}
if (gps.getUBX_packet()) // If a valid GPS UBX data packet is received...
{
gps.parse_ubx_data(); // Parse the new data
if (gps.utc_time.valid) // If the utc_time passed from the GPS is valid...
{
Serial.println();
Serial.print("UTC time: ");
Serial.print(gps.utc_time.hour);
Serial.print(":");
Serial.print(gps.utc_time.minute);
Serial.print(":");
Serial.print(gps.utc_time.second);
Serial.println();
}
// Print location (latitude/longitude)
Serial.println();
Serial.print("location: ");
Serial.print("Lat: ");
Serial.print(gps.location.latitude, 8); // to 8 decimals
Serial.print(" Long: ");
Serial.print(gps.location.longitude, 8); // to 8 decimals
delay(7200);
char compilation[128]="\0";
//confirm status,Fport,payload length,payload(HEX)
snprintf(compilation,128,"AT+SENDB=%d,%d,%d,%02X%02X%02X%02X",0,2,4,(short)(gps.location.latitude*100)>>8 & 0xFF,(short)(gps.location.latitude*100) & 0xFF,(short)(gps.location.longitude*10)>>8 & 0xFF,(short)(gps.location.longitude*10) & 0xFF);
ss.println(compilation);
}
if(time_to_at_recvb==true){
time_to_at_recvb=false;
get_LA66_data_status=true;
delay(1000);
ss.println("AT+CFG");
}
while ( ss.available()) {
// get the new byte:
char inChar = (char) ss.read();
// add it to the inputString:
inputString += inChar;
rxbuff[rxbuff_index++]=inChar;
if(rxbuff_index>128)
break;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n' || inChar == '\r') {
stringComplete = true;
rxbuff[rxbuff_index]='\0';
if(strncmp(rxbuff,"JOINED",6)==0){
network_joined_status=1;
}
if(strncmp(rxbuff,"Dragino LA66 Device",19)==0){
network_joined_status=0;
}
if(strncmp(rxbuff,"Run AT+RECVB=? to see detail",28)==0){
time_to_at_recvb=true;
stringComplete=false;
inputString = "\0";
}
if(strncmp(rxbuff,"AT+RECVB=",9)==0){
stringComplete=false;
inputString = "\0";
Serial.print("\r\nGet downlink data(FPort & Payload) ");
Serial.println(&rxbuff[9]);
}
rxbuff_index=0;
if(get_LA66_data_status==true){
stringComplete=false;
inputString = "\0";
}
}
}
while ( Serial.available()) {
// get the new byte:
char inChar = (char) Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n' || inChar == '\r') {
ss.print(inputString);
inputString = "\0";
}
}
// print the string when a newline arrives:
if (stringComplete) {
Serial.print(inputString);
// clear the string:
inputString = "\0";
stringComplete = false;
}
}
je ne connais pas du tout le LA66 mais utilise LoRaWAN avec diverses autres solutions... (et avec des trames plus courtes et plus simple que la tienne)
tu dis que tu 'vois tes trames' : où et comment ? En hexadécimal dans le 'live data' de ton 'device' ?
As tu créé un 'Payload Formatter' (en javascript) pour que le serveur LoRaWAN puisse reconstituer les données à partir du 'paquet d'octets' de la trame qu'il reçoit ?
Je vois les trames dans le live data de mon decive , mais dans la partie payload c'est vide , mon prof me dit que c'est à cause du format mais ne veut pas plus m'aider.
Non je n'ai pas fait de payload formatter parceque le payload est vide donc il peut pas reconstituer les données pour l'instant non ? Je pense que quoi qu'il arrive je devrais en crée un plus tard mais je voulais plutot crée un noeud node red ensuite qui reconvertie les données qui sont en héxa
mon prof me dit que c'est à cause du format mais ne veut pas plus m'aider.
Suis les conseils de ton prof
il te dit quoi travailler , je respecte sa démarche
trois conseils :
-Révises attentivement la syntaxe de la commande AT+SENDB de ton module LA66 DRAGINO
Souvent , pas toujours, les commandes AT d'envoi de trames par des 'modems' LoRaWAN comportent la longeur de la trame en complément du contenu de celle çi.... patrfois elels deamndent d'autres paramètres.....
Vois aussi de près quel type de données fournir à SENDB pour envoi.
-Avant de balancer une longue trame , commences par des trames plus courtes, plus simples pour bien 'apprivoiser' les choses
Souhaitable : Bien vérifier dans le code que ton LA66 te réponde qu'il est OK pour la commande AT+SENDB reçue (j'ai lu ton code en diagonale et ne suis pas certain que tu analyses la réponse du LA66 à cette commande d'envoi de trame)
Avec la commande c'est uniquement de l'héxa et ducoup c'est sur sa que je bloque depuis 3 semaine.
J'ai essayé d'envoyer des trames plus courtes mais j'ai pas constaté de changement dans le payload sur TTN
Il me répond que tout est ok dans le serial monitor de l'ide arduino donc je pense que c'est bon juste qu'il doit envoyer du vent vu que mes données ne doivent pas être au bon format pour l'envoi.
Exemple de trame sur ttn (la partie metadata c'est la passerelle ducoup c'est pas ce qu'on veut ) :
rien d'autre en complément ? J'en serai convaincu quand tu montreras la partie de la liste des commandes AT de ton module qui traite de la commande AT+SENDB
Exemple de trame sur ttn (la partie metadata c'est la passerelle ducoup c'est pas ce qu'on veut )
Ce que tu vois à ce niveau est le 'payload brut' , payload crypté, c'est dans l'ordre des choses de ne pas en voir plus au niveau d'une passerelle LoRAWAN, que tu le veuilles ou non
Aucune passerelle LoRaWAN ne décrypte les trames pour voir leur contenu (travail exclusif du serveur LoRaWAN qui seul sait accèder au contenu 'en clair' de la payload puis d'en extraire les divers données.
Je n'ai pas bien compris ton explication au niveau du payload brut et crypté , j'avais déjà réalisé un projet avec un capteur d'humidité mais avec un autre shield sans les commandes at et je me souviens pas avoir décrypté la payload , j'avais directement la variable humidité de visible que je pouvais utiliser sur node red.
Ps: il y a bien d'autres paramètres à la commande comme tu disais j'avais pas compris du premier coup le message , normalement tout est bon au niveau de la taille du payload , du port , et du "confirm status" , je pense que c'est ma façon de convertir l'héxa dans mon code qui doit être mauvaise
normalement tout est bon au niveau de la taille du payload , du port , et du "confirm status"
regardes bien....
le 4 envoyé après 0 et 2 représente le nombre d'octets à émettre par AT+SENDB
C'est bien 4 dans l'exemple proposé dans la doc (message #7) : 0x11, 0x22, 0x33 et 0x44 mais ce n'est pas toujours le cas
Au cas où plus tard j'ai la flemme de tout retaper,
je pourrais faire un copié/collé :
function Decoder(bytes, port) {
// Vérifiez que la longueur du payload est correcte
if (bites.length !== 4) {
return {
error: "Invalid payload length"
};
}
// Récupération des octets
let lat_msb = bytes[0];
let lat_lsb = bytes[1];
let lon_msb = bytes[2];
let lon_lsb = bytes[3];
// Reconstruction des valeurs de latitude et longitude
let latitude = ((lat_msb << 8) | lat_lsb) / 100;
let longitude = ((lon_msb << 8) | lon_lsb) / 10;
return {
latitude: latitude,
longitude: longitude
};
}