Sur mon NodeMCU V3, j'obtiens une chaîne de caractères, la convertis en deux longs, un int et deux octets, les enregistre dans une union et envoie la totalité de l'union à un Arduino Mega, qui est censé le lire dans une union égale. Lorsque le NodeMCU imprime les octets sur le moniteur série de mon ordinateur portable, il affiche leur valeur exacte, mais après leur envoi, je reçois juste deux 0. Pourtant, je pense qu'il a quelque chose à voir avec la conversion des octets, mais ne peut pas comprendre quoi.Pourquoi une Union ne fonctionne-t-elle pas pour envoyer des octets convertis à partir d'une chaîne via Serial?
J'ai essayé:
- En utilisant
atol
au lieu destrtol
pour convertir la chaîne, mais qui mis au rebut après avoir lu les inconvénients. atol() v/s. strtol()
Cela n'a pas fonctionné de toute façon. - J'ai essayé de convertir les octets avec
lowByte((int) int1)
.
Voici la partie pertinente de mon code. J'ai inventé une chaîne, au lieu d'en recevoir une à des fins de test.
#include <ESP8266WiFi.h>
union Serial { //Union to place the numbers in.
byte by[12];
struct {
long vsollneu;
long ssollneu;
int phisollneu;
byte priosollneu;
byte typsollneu;
} Befehlssammlung;
} Befehle;
long a1,pr1,ty1;
char str[]="2049714 -1927461000 17 80 4"; //String to be seperated
void convert(char*);
void setup(){
Serial.begin(9600);
}
void loop(){
convert(str);
//Serial.write(Befehle.by,12); //Send the Bytes of the Union to the Arduino MEGA
delay(5555);
}
void convert(char* str){ //Converting the String with strtol
char* ende;
Befehle.Befehlssammlung.vsollneu =strtol(str,&ende,10);
Befehle.Befehlssammlung.ssollneu =strtol(ende,&ende,10);
a1 = strtol(ende,&ende,10);
pr1= strtol(ende,&ende,10);
ty1= strtol(ende,NULL,10);
Befehle.Befehlssammlung.phisollneu=(int) a1; //Converting the long to an int
Befehle.Befehlssammlung.priosollneu=(byte) pr1; //Probably that's somehow wrong???
Befehle.Befehlssammlung.typsollneu=(byte) ty1;
// Serial.println(Befehle.Befehlssammlung.vsollneu);
// Serial.println(Befehle.Befehlssammlung.ssollneu);
// Serial.println(Befehle.Befehlssammlung.phisollneu);
// Serial.println(Befehle.Befehlssammlung.priosollneu);
// Serial.println(Befehle.Befehlssammlung.typsollneu);
}
Voici la partie de l'Arduino Mega recevoir:
union IZweiCkontainer {
byte by[12];
struct {
long vsollneu;
long ssollneu ;
int phisollneu;
byte priosollneu;
byte typsollneu;
} Befehlssammlung;
} Befehle;
void setup(){
Serial.begin(115200); //Serial for debugging
Serial3.begin(9600); //Serial for conncetion the the Mcu
}
void loop(){
if(Serial3.available()>0){
while(Serial3.available()){
Serial3.readBytes(Befehle.by,12); //receiving the Bytes and writing them in the "same" union
}
}
Serial.println(Befehle.Befehlssammlung.vsollneu);
Serial.println(Befehle.Befehlssammlung.ssollneu);
Serial.println(Befehle.Befehlssammlung.phisollneu);
Serial.println(Befehle.Befehlssammlung.priosollneu);
Serial.println(Befehle.Befehlssammlung.typsollneu);
}
Que bucks moi est que tout va bien sur le NodeMCU, mais après l'envoi, je reçois la sortie suivante de l'Arduino Mega:
2049714
-1927461000
17
0
0
Vous devriez vérifier, dans 'Serial3.readBytes (Befehle.by, 12)', le nombre d'octets réellement lus. Le délai d'attente par défaut pour lire (ils disent) est 1 seconde, mais ... mieux vérifier. – linuxfan
Vous n'utilisez pas seulement des structures sur des domaines de compilation, mais une union. et s'attendre à ce que cela fonctionne? Est ce que vous dites? Faisable mais ne vaut généralement pas l'effort et le coût de l'entretien régulier. rapide et sale vérifier vos longueurs sur les deux extrémités, avec des réponses codées en dur, si la longueur ne correspond pas à la valeur codée en dur puis caution/échouer sur les données (et revenir en mode de maintenance). –
@linuxfan Merci, pour l'idée. Malheureusement 'Serial.readBytes (Befehl.by, 12)' renvoie 12, donc cela semble bien. – DeniseBryson