gelöst: Daten empfangen und weiterverarbeiten

Hallo zusammen

Nachdem sehr vieles sehr gut funktioniert hat, bin ich nun auf ein Problem gestossen, für das ich keine logische Erklärung finde und demnach auch keinen Lösungsansatz. Ich hoffe, ihr könnt mir helfen!

Es geht um zwei Geräte. Das eine ist ein Eingabegerät und besteht unter anderem aus 8 Tastern und einem analog-Joystick. Bei jeder Änderung der Tasten oder des Joysticks werden die Daten über deren Zustände über einen XBee an das zweite Gerät gesendet. Dieses besteht im Wesentlichen aus einem Arduino micro und einem zweiten XBee. Der Micro soll die Daten empfangen und damit verschiedene Dinge anstellen, wie z.B. die Tastatur und die Maus zu steuern.

Das Auswerten der Tastendaten hat bisher auch soweit geklappt und es konnten Tastaturausgaben gemacht werden. Als ich aber die Daten des Joysticks weiterverarbeiten wollte, stiess ich auf das Problem! Auf der Suche nach dem Fehler, habe ich so viel wie möglich auskommentiert, was stören könnte. So ist nun auch alles was mit der Keyboard und Mouse library zu tun hat weg. Nun macht der Micro eigentlich nichts anderes mehr, als die Funktion auszuführen, die die Daten empfängt und in ein Array speichert und eine andere Funktion, die die Inhalte dieses Arrays per Serial.print ausgibt. Komischerweise sind die Ausgaben der zweiten Funktion völlig falsch. Gebe ich allerdings die Daten über die selben Serial.print befehle in der Empfangsfunktion aus, wie ich es während des Testens der Datenübertragung jeweils gemacht habe, ist alles korrekt. Was könnte da in der Zwischenzeit mit den Daten passieren?

Anbei die relevanten Teile des Sketches:

Deklarieren der globalen Variablen, setup und loop mit den besagten Funktionen:

char datastart = 1; //daten start
char txt = 2; //text start
char separator = 29; //daten separator
char endoftransmission = 10; //ende

char message[32];
unsigned int values[5] = {255,547,538,0}; // 0 = buttons, 1 = x joy, 2 = y joy, 3 = poti
unsigned long presstime;

void setup() {
  Serial.begin(57600);
  Serial1.begin(57600);
}

void loop() {

// serialRelay();          // empfängt Text an Serial und übergibt sie gemäss Protokoll an Serial1

 getValues();            // empfängt Daten an Serial1 und speichert sie in das array values

 computerTakeover();   // manipuliert Maus und Keyobard entsprechend values

}

Funktion getValues()

void getValues() {
  static int dataBuffer;
  static int dataIndex;
  static boolean data;
  if (Serial1.available()) {
      byte ch = Serial1.read();
      if (ch == endoftransmission) {
            values[dataIndex++] = dataBuffer;
            dataBuffer = 0;
            dataIndex = 0;
            data = false;
        /*Serial.print(values[0], BIN);             //wird dieser Kommentar aufgehoben, sind die Ausgaben korrekt. c.f. Beispiel unten
            Serial.print("/");
            Serial.print(values[1]);
            Serial.print("/");
            Serial.print(values[2]);
            Serial.print("/");
            Serial.println(values[3]); */

      }
      else if (ch == separator) {
            values[dataIndex++] = dataBuffer;
            dataBuffer = 0;
      }
      else if (data) {
          dataBuffer = (dataBuffer * 10) + (ch - 48);
      }
      
      else if (ch == datastart) {
            dataIndex = 0;
            dataBuffer = 0;
            data = true;
      }

  }
}

korrekte Ausgaben wenn in getValues() serial.print aktiviert. Einige Taster werden gedrückt (Nullen im ersten binären Byte), Veränderung der Joystick position x und y in der zweiten und dritten Zahl. Letzte Zahl unwichtig.

10010110/293/538/17
10010110/277/538/16
10010110/261/538/16
10010110/245/538/16
10010110/229/538/16
10010110/213/538/19
10010110/197/538/16
10010110/183/538/16
10010110/174/538/16
10010110/185/538/16
11011111/191/538/16
11011111/191/538/16
11011111/191/538/16
11011111/191/538/16
11011111/198/538/16
11011111/206/538/17
11011111/214/538/15

inkorrekte Ausgaben, wenn genau die selben serial.print angaben in der Funktion takeoverComputer() ausgeführt werden

11111111/547/538/0
11111111/547/538/0
11111111/547/538/0
11111111/547/538/0
11111111/547/538/0
11111111/547/538/0
11111111/547/538/0
11111111/547/538/0
11111111/547/538/0
11111111/547/538/0               //bis hier keine Bewegung am Stick
10/965/59365/19560         //danach Bewegung des Sticks, sämtliche Daten nehmen Werte an, die gar nicht möglich sind
10/965/59365/19560
10/965/59365/19560
10/965/59365/19560
10/965/59365/19560
10/965/59365/19560
10/965/59365/19560
10/965/59365/19560
10/965/59365/19560
10/965/59365/19560
110011110000100/965/59365/19560       // auch das Byte für die Buttons, obwohl sie gar nicht verändert werden
110011110000100/965/59365/19560
110011110000100/965/59365/19560
110011110000100/66/59365/19560
110011110000100/66/59365/19560
110011110000100/66/59365/19560
110011110000100/66/59365/19560
110011110000100/66/59365/19560

Was ist da los? Helft mir bitte, ich bin am verzweifeln :(

Gruss

Hitsuji

Versuch mal jedesmal wenn Du values[dataIndex++] machst Dir den Wert von dataIndex ausgeben zu lassen und kontrollier ob er kleiner gleich 4 ist. Grüße Uwe

habs mal so bei "else if (ch == separator)" hinzugefügt, dass er nach dem Hochzählen den Index ausgibt.

Beim ersten Testdurchgang habe ich die Funktion "computerTakeover", die den Fehler verursacht auskommentiert. Da gibt der Serial Monitor bei jedem Tastendruck den Index 1,2,3 aus. Genau so ist es, wenn ich den Joystick bewege.

Beim zweiten Durchgang habe ich die Funktion wieder entkommentiert. Wenn ich Tasten drücke, zeigt der Index ebenfalls 1,2,3 an, nie 4 oder höher und die Werte sind korrekt. Sobald ich aber den Joystick bewege, erscheinen plötzlich nurnoch 1 und 2, danach beginnts natürlich mit den falschen Werten und später sind Indexe bis zu 8 hoch zu sehen...

Du scheinst mich der Sache näher gebracht zu haben! :) Doch was verursacht den Fehler? Könnte es sein, dass er sich bei zu schnellem Senden von Datenpaketen selbst unterbricht? Müsste man den Fehler demnach auf der Senderseite suchen? Könnte man dem vielleicht durch einige Serial.flush() befehle am richtigen Ort entgegenwirken? Wieso funktioniert es dann allerdings bei der Ausgabe am einen Ort und nicht mehr, sobald die Ausgabe in der anderen Funktion getätigt wird?

Oder empfängt er zu viele Daten beim Bewegen des Sticks, so dass er hereinkommende Zeichen verpasst, sobald er andere Dinge auch noch machen muss?

Da gibt der Serial Monitor bei jedem Tastendruck den Index 1,2,3 aus. Genau so ist es, wenn ich den Joystick bewege.

Was passiert denn mit dem Index 0 ? Das ist nämlich der Erste, nicht 1

Der Befehl Serial.print folgt erst nach dem Inkrementieren.

Okay. Hab die Funktion getValues boolsch gemacht und zwar so, dass sie erst true zurück gibt, wenn sie einen vollständigen datensatz empfangen und abgelegt hat und rufe sie nun nicht mehr in der loop auf, sondern mache dasda:

   if (getValues()) {
            Serial.print(values[0], BIN);
            Serial.print("/");
            Serial.print(values[1]);
            Serial.print("/");
            Serial.print(values[2]);
            Serial.print("/");
            Serial.println(values[3]);
   }

Scheint vorerst zu funktionieren. Muss nun allerdings noch kucken, obs auch noch funktioniert, wenns öfters abgefragt wird…

ja, Deine Funktion kann mehrfach die Daten auswerten wenn ein vollständiger Datensatz beim ersten Lesen noch nicht vollständig angekommen ist. Wie in Deinem Lösungsweg kannst Du schauen ob das Abschlußbyte angekommen ist und erst dann, einmal, die Auswertung machen.

Grüße Uwe

Voilà! Mittlerweile steht die Funktion, die die Daten auswertet und in Keystrokes und Mausbewegungen umwandelt und funktioniert wunderprächtig mit der boolschen Methode (solange nirgends ein delay eingesetzt wird). Ausserdem hat sich herausgestellt, dass dies gleichzeitig die bequemste Methode ist, um weitere fehlerkorrigierende Massnahmen einzubauen, wie eben das Überprüfen des Empfangs eines Abschlussbytes, das Durchzählen der empfangenen Bytes oder die Kontrolle einer Prüfsumme, was ich eventuell noch einbauen werde, allerdings erst am Schluss, um zu sehen, wie viel eigentlich fehlerhaft übertragen wird, was im Moment allerdings gegen 0 geht. Ich danke herzlichst Uwe, der mich kurz und klar auf die richtige Bahn gebracht hat und Arty fürs Mitdenken. Ausserdem hat mir jemand wies aussieht ein zweites Karma spendiert :D wofür auch immer, ich freu mich darüber ;)

Und wär ich jetzt nicht zu blöd dafür, den Thread umzubenennen in "gelöst: blabla..." würd ich das glatt machen ;)

bitte 8) 8)

Hitsuji: ... Und wär ich jetzt nicht zu blöd dafür, den Thread umzubenennen in "gelöst: blabla..." würd ich das glatt machen ;)

Deinen ersten Beitrag mit "Modify" aufmachen und Titel ergänzen. dann abspeichern. Grüße Uwe