2017-05-25 2 views
1

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 de strtol 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 
+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

+0

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). –

+0

@linuxfan Merci, pour l'idée. Malheureusement 'Serial.readBytes (Befehl.by, 12)' renvoie 12, donc cela semble bien. – DeniseBryson

Répondre

1

int s et long s sur un Arduino et ESP8266 ne sont pas la même taille. Utilisez int16_t et int32_t pour vous assurer qu'ils ont la même taille pour différentes architectures.

union { 
    byte by[12];    
    struct {     
    int32_t vsollneu;   
    int32_t ssollneu;   
    int16_t phisollneu;   
    byte priosollneu;  
    byte typsollneu;   
    } Befehlssammlung;   
} Befehle;