2017-08-18 4 views
0

Ma fonction suivante lit à partir d'un port série, traite les données et affiche les informations à l'utilisateur. la chose intéressante est que cela semble ne fonctionner que lorsqu'il est appelé sur des instances impaires. Sur les lectures paires, le cas de dépassement de délai se produit.La fonction fonctionne à chaque fois qu'elle est appelée

Cette fonction est appelée toutes les 10 secondes ou plus tôt si elle est appelée par l'utilisateur. Peu importe à quelle fréquence ça s'appelle, ça marchera toutes les deux fois.

CODE:

bool SR(bool echo, int&value) 
{ 
    bool valid; 
    byte buf [2]; 

sur les appels même red retours 0

byte red = Serial2.readBytes(buf,2); 
    if(red>0) 
    { 

Voici la "bonne données" cas SvAdd me donne l'adresse de l'expéditeur en FCode donne le type de message envoyé (il sont 8 types de messages, mais nous n'utilisons que les types 3 et 6)

valid=true; 
    byte SvAdd = buf[0]; 
    byte FCode = buf[1]; 
    int Read; 
    byte registerL; 
    switch (FCode) 
    { 
     case 3: 

données pour le cas 3 (lecture seule) apparaît comme indiqué dans ce tableau: Case 3 Data

 Serial2.readBytes(buf,1); 
     registerL = buf[0]; 
     for (byte i=(registerL/2); i>0 ; i--) 
     { 
      Serial2.readBytes(buf,2); 
      Read = buf[1] | buf[0] << 8; 
     } 

Pour l'instant, registerLdevrait cependant toujours 2 j'ai ajouté la boucle juste au cas où

 value=Read; 
     break; 
     case 6: 
Les données du cas 6 (écriture puis lecture) apparaissent comme indiqué dans ce tableau: case 6 Write -> read
 Serial2.readBytes(buf,2); 
     Read = buf[1] | buf[0] << 8; 
     Serial2.readBytes(buf,2); 
     Read = buf[1] | buf[0] << 8; 
     value=Read; 

Je sais l'adresse si je lis passé et ne regarde les bits de données afin de vérifier la fonction correcte a été écrit

 break; 
    } 

Aquire les deux derniers octets CRC de la fonction (pour effacer la mémoire tampon)

Serial2.readBytes(buf,2); 
    int CRC = buf[1] | buf[0] << 8; 
    if (echo) 
    { 
     Serial.println(SvAdd); 
     Serial.println(FCode); 
     switch (FCode) 
     { 
     case 3: 
      Serial.println(registerL); 
      Serial.println(Read); //Last Value read 
      break; 
     case 6: 
      Serial.println(Read); //Value 
      break; 
     } 
     Serial.println(CRC); 
    } 
    return valid; 
    } 

est ici le cas où red=0

else 
    { 
    valid=false; 
    Serial.println("timeout"); 
    return valid; 
    } 
} 

EDIT (code contigu)

bool SR(bool echo, int&value) 
{ 
    bool valid; 
    byte buf [2]; 
    byte red = Serial2.readBytes(buf,2); 
    if(red>0) 
    { 
    valid=true; 
    byte SvAdd = buf[0]; 
    byte FCode = buf[1]; 
    int Read; 
    byte registerL; 
    switch (FCode) 
    { 
     case 3: 
     Serial2.readBytes(buf,1); 
     registerL = buf[0]; 
     for (byte i=(registerL/2); i>0 ; i--) 
     { 
      Serial2.readBytes(buf,2); 
      Read = buf[1] | buf[0] << 8; 
     } 
     value=Read; 
     break; 
     case 6: 
     Serial2.readBytes(buf,2); 
     Read = buf[1] | buf[0] << 8; 
     Serial2.readBytes(buf,2); 
     Read = buf[1] | buf[0] << 8; 
     value=Read; 
     break; 
    } 
    Serial2.readBytes(buf,2); 
    int CRC = buf[1] | buf[0] << 8; 
    if (echo) 
    { 
     Serial.println(SvAdd); 
     Serial.println(FCode); 
     switch (FCode) 
     { 
     case 3: 
      Serial.println(registerL); 
      Serial.println(Read); //Last Value read 
      break; 
     case 6: 
      Serial.println(Read); //Value 
      break; 
     } 
     Serial.println(CRC); 
    } 
    return valid; 
    } 
    else 
    { 
    valid=false; 
    Serial.println("timeout"); 
    return valid; 
    } 
} 
+0

Il serait beaucoup plus facile d'examiner votre code s'il était posté comme un seul bloc contigu, au lieu de morceaux. – TomServo

+0

Désolé, éditer maintenant –

+0

@TomServo Bloc contigu créé et ajouté à la fin –

Répondre

1

Une chose que je vois est que Read est défini comme int dire signé int. Je me demande si vous obtiendriez de meilleurs résultats, puisque vous le créez par décalage, si vous le définissez comme unsigned int. Si vous déplacez un 1 dans cette position MSB, tout d'un coup (int) Read est un nombre négatif.

suivant:

Read = buf[1] | buf[0] << 8; 
Serial2.readBytes(buf,2); 
Read = buf[1] | buf[0] << 8; 
value=Read; 

Vous vous rendez compte que Read est assignée deux fois de suite, non? Donc, il ne conservera que la dernière valeur. Ce n'est pas grave si vous voulez rejeter l'adresse transmise. Mais il ne semble pas comme vous le faites, à cause de cela:

Serial.println(Read); //Addr 
Serial.println(Read); //Value 

Read n'est pas l'adresse et la valeur.

Je vous suggère de regarder ces deux éléments de poisson en premier. Je ne peux pas exécuter votre code maintenant, mais un examen plus approfondi de ces éléments pourrait éclairer votre problème.

Enfin, votre fonction elle-même appel, si vous voulez passer un pointeur, lire:

bool SR(bool echo, unsigned int * value) 

Mais la ligne de fond est que si vous obtenez « délai » tous les temps, il est parce que red n'est pas> 0 et l'instruction readBytes ci-dessus n'a pas fonctionné.

+0

Je réalise l'affectation consécutive, car pour le moment je ne me soucie pas de l'adresse transmise. (J'y ai manqué) J'ai deux questions: 1) Je travaille avec des nombres négatifs reçus par l'appareil, si je fais 'Read' non signé comment j'obtiendrais l'int non signé en retour à un int (puis-je juste' (int) Lisez-le?) 2) N'importe quelle idée pourquoi 'rouge = 0' à chaque fois que la fonction est appelée? il devrait y avoir des données en série car il se produit seulement après une écriture –