2017-08-18 3 views
0

Meine folgende Funktion liest von einer seriellen Schnittstelle, verarbeitet die Daten und zeigt Informationen für den Benutzer an. Das Interessante ist, dass es nur funktioniert, wenn es an ungeraden Instanzen aufgerufen wird. Bei geraden Lesevorgängen tritt der Timeout-Fall auf.Funktion funktioniert jedes Mal, wenn es aufgerufen wird

Diese Funktion wird alle 10 Sekunden oder früher aufgerufen, wenn sie vom Benutzer aufgerufen wird. Egal wie oft es heißt, es wird jedes andere Mal funktionieren.

Code:

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

auf einmal ruft red kehrt 0

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

Hier ist die „gute Daten“ Fall SvAdd gibt mir die Absenderadresse während FCode die Art der Nachricht dorthin geschickt gibt (sind 8 Arten von Nachrichten, aber wir verwenden nur die Typen 3 und 6)

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

Daten für Fall 3 (read-only) erscheint in dieser Tabelle gezeigt: 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; 
     } 

Vorerst registerLsollte immer 2 sein aber habe ich die Schleife nur für den Fall

 value=Read; 
     break; 
     case 6: 

Daten für Fall 6 (schreiben, dann lesen) erscheint wie in dieser Tabelle gezeigt: 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; 

Ich kenne die Adresse an, damit ich an ihn gelesen und nur an den Datenbits sehen die korrekte Funktion zu überprüfen

 break; 
    } 

Aquire die letzten zwei CRC-Bytes aus der Funktion geschrieben wurde (löschen den Puffer)

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; 
    } 

Hier ist der Fall, wenn red=0

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

EDIT (zusammenhängenden Code)

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

Es wäre viel einfacher, Ihren Code zu untersuchen, wenn er als einzelner zusammenhängender Block anstelle von Stücken gepostet würde. – TomServo

+0

Entschuldigung, Bearbeitung jetzt –

+0

@TomServo Zusammenhängender Block erstellt und am Ende hinzugefügt –

Antwort

1

Was ich sehe ist, dass Read definiert als int d.h. int signiert. Ich frage mich, ob Sie bessere Ergebnisse erzielen würden, da Sie es durch Bit-Shifting erstellen, wenn Sie es als unsigned int definieren. Wenn Sie eine 1 in diese MSB-Position verschieben, ist plötzlich (als int) Read eine negative Zahl.

Next:

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

Sie erkennen, dass Read zweimal hintereinander zugewiesen wird, nicht wahr? So behält es nur den letzten Wert. Das ist in Ordnung, wenn Sie die übertragene Adresse verwerfen möchten. Aber es sieht nicht wie Sie das tun, weil dieser:

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

Read ist nicht sowohl die Adresse und den Wert.

Ich schlage vor, dass Sie zuerst in diese zwei fischigen Gegenstände schauen. Ich kann Ihren Code derzeit nicht ausführen, aber ein genauerer Blick auf diese Artikel könnte Ihr Problem beleuchten.

Schließlich Ihre Funktion selbst nennen, wenn Sie in einen Zeiger übergeben wollen sollten, lesen Sie:

bool SR(bool echo, unsigned int * value) 

Aber das Endergebnis ist, dass, wenn Sie „Timeout“ jede andere Zeit bekommen, es ist, weil red ist NICHT> 0, und die obige readBytes Anweisung hat nicht funktioniert.

+0

Ich erkenne die fortlaufende Zuweisung, denn im Moment ist mir die übertragene Adresse egal. (Hoppla, das habe ich verpasst) Ich habe zwei Fragen: 1) Ich arbeite mit negativen Zahlen, die vom Gerät empfangen werden, wenn ich 'Read' ohne Vorzeichen mache, wie würde ich das unsigned Int wieder zu einem int bekommen (kann ich einfach' (int) Lies 'es?) 2) Irgendeine Idee warum' rot = 0 'jedes Mal, wenn die Funktion aufgerufen wird? Dort sollte es serielle Daten geben, da es erst nach einem Schreibvorgang auftritt –

Verwandte Themen