mehrere Variablen gleichzeitig empfangen (Arduino Nano/XBee)

Hi. Bin noch ziemlicher Anfänger im Bereich Arduino.

Für ein kleines Projekt habe ich jetzt 2 Arduino-Nanos, auf jeweils einem Board mit XBee.
Nun möchte ich mehrere Werte (eigentlich erstmal nur zwei) über Funk übertragen. Dabei handelt es sich jeweils um eine gerade Zahl (von 0 - 200).

Mit diesem Code (den ich irgendwo im Netz gefunden habe) klappt es soweit ganz gut. Gesendet wird dabei zb. 10;50*

#include <LiquidCrystal.h>

LiquidCrystal lcd(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3);

char *zT = 0;
int zTb = 0;
char *zS = 0;
int zSb = 0;
char current = 0;
char data[15] = ""; 
int incount = 0;
bool lineComplete = false; 



void setup()
{
    lcd.begin(16, 2);
    lcd.clear();
    Serial.begin(9600);
    
    zT=0;
    zS=0;
}



void loop() {
  while ( (Serial.available()) & (incount < 15) & (!lineComplete) )
  {
    current = Serial.read();
    if (current != 42) 
    {
      data[incount] = current;
      incount++;
    }
    else
    {
      data[incount] = '\0'; 
      lineComplete = true;
    }
  }
  
  if (lineComplete)  
  {    
    lineComplete = false;
    incount = 0;
    daten_auswerten();
  }
  else if (incount >=15)
  {
    incount = 0;
    lineComplete = false;
  }
}
  
  

void daten_auswerten()
{
  zT = strtok (data, ";");
  zS = strtok (NULL, "*");
  


      zTb = atoi (zT);
      zSb = atoi (zS);
      lcd.setCursor(0,0);
      lcd.print("Wert1: ");
      lcd.setCursor(10,0);
      lcd.print(zTb, DEC);
      lcd.setCursor(0,1);
      lcd.print("Wert2: ");
      lcd.setCursor(10,1);
      lcd.print(zSb, DEC);
      

  }

Mein Problem ist jetzt aber, dass sobald ich die Anzeige (also die lcd.print - Befehle) in einen anderen Programmabschnitt auslagere, das Ganze nicht mehr funktioniert.
Das benötige ich aber, da diese Werte nicht immer angezeigt werden sollen. Woran liegt das?

Und gibt es eine bessere/andere Variante mehrere Variablen gleichzeitig zu empfangen?
Hab leider nichts richtiges im Netz dazu gefunden…

Vielen Dank schonmal für eure Antworten.

2 infos bitte:
Wie sieht der Übertragene String aus?
Gibst Du uns ein Beispiel wie es ohne lcd.print nicht funktioniert.
Grüße Uwe

Der übertragene String zb für die Werte 10 und 27 sieht so aus:

10;27*

Und wenn es nicht funktioniert, arbeitet das Ganze wie zeitverzögert.
Also erst 3-4 Übertragungen später kommt der nächste Wert.

Ich habe zum probieren mit einem Taster am Sender eine der beiden Werte hochgezählt, und bei jeder Änderung den String gesendet. Zb bei dem Wert 10 beginnend, kam nach ca 4 mal drücken nicht der Wert 14, sondern 11 am Ende raus. Und wieder paar mal später 12. Usw... Kann ich mir irgendwie nicht erklären. Zumal das mit dem ersteren Code oben funktioniert.

Wenn Du Werte von 0 bis 255 übertragen willst, wieso überträgst Du sie als String nicht als Byte?
Grüße Uwe

Weil ich da leider nicht so recht weiß, wie ich die dann trennen kann, bzw wie ich dem Empfänger mitteile, welcher der beiden Werte jetzt übertragen wird.

Niemand einen Tipp, oder irgendwie ein Tutorial oder so zu dem Thema?

Komm leider nicht so richtig weiter damit.

hmm, so richtig was auffallen tut mir auch nicht. kannst du bitte den code posten, wo du das lcd.print ausgelagert hast - oder ist der obrige code gemeint? dann bitte die variante, wo lcd.print "drin" ist, so dass wir uns die unterschiede angucken können :slight_smile:

Vom Code an sich, würde ich anders vorgehen. Eine Routine, an die du einen kompletten String übergibst, der dann auf dem LCD ausgegeben wird. ist einfacher beim debuggen und universeller einsetzbar :wink:

Apropos Debuggen: Schon mal deine Variablen getraced? ich vermute irgendwo dort verbirgt sich das problem. auch die counter debuggen. da denkt man immer als letztes daran, dabei verbergen sich dort die meisten fehler.

cu markus

So sieht das dann in etwa aus:

#include <LiquidCrystal.h>

LiquidCrystal lcd(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3);

char *zT = 0;
int zTb = 0;
char *zS = 0;
int zSb = 0;
char current = 0;
char data[15] = ""; 
int incount = 0;
bool lineComplete = false; 



void setup()
{
    lcd.begin(16, 2);
    lcd.clear();
    Serial.begin(9600);
    
    zT=0;
    zS=0;
}



void loop() {
  anzeige();
  while ( (Serial.available()) & (incount < 15) & (!lineComplete) )
  {
    current = Serial.read();
    if (current != 42) 
    {
      data[incount] = current;
      incount++;
    }
    else
    {
      data[incount] = '\0'; 
      lineComplete = true;
    }
  }
  
  if (lineComplete)  
  {    
    lineComplete = false;
    incount = 0;
    daten_auswerten();
  }
  else if (incount >=15)
  {
    incount = 0;
    lineComplete = false;
  }
}
  
  

void daten_auswerten()
{
  zT = strtok (data, ";");
  zS = strtok (NULL, "*");
  


      zTb = atoi (zT);
      zSb = atoi (zS);
      
  }

void anzeige(){
      lcd.setCursor(0,0);
      lcd.print("Wert1: ");
      lcd.setCursor(10,0);
      lcd.print(zTb, DEC);
      lcd.setCursor(0,1);
      lcd.print("Wert2: ");
      lcd.setCursor(10,1);
      lcd.print(zSb, DEC);
}

Kompletter String ist halt schlecht, weil man da ja nur auf eine Zeile im LCD Display schreiben kann, oder?
Ich würde aber gern Wert1 auf eine, und Wert2 auf die nächste Zeile schreiben.

Variablen tracen? Sagt mir jetzt leider nix, aber ich werd mal danach googln…

Habs jetzt auch mal versucht mit Bytes übertragen - aber wenn ich da zwei Bytes hintereinander versuche zu senden, kommt leider auch nur Quatsch raus.

Hab es jetzt mal so probiert, dass ich einfach die beiden Werte hintereinander sende.
Der XBee empfängt die alle richtig (mit X-CTU empfangen).

Bei diesem Code:

#include <LiquidCrystal.h>

LiquidCrystal lcd(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3);


int input;
int bufferArray[2];
int d1;
int d2;


void setup()
{
    lcd.begin(16, 2);
    lcd.clear();
    Serial.begin(115200);
    input = 0;
}






void loop() {
  if (Serial.available() > 1)  {    
 
      for (int i=0; i<2; i++) {			
       bufferArray[i] = Serial.read();     	
       input = 1;    			
      } 
  }
  
  
  
  
  if (input != 0)				
{                
 
  
 
  					
   int d1 = bufferArray[0];			
   int d2 = bufferArray[1];			
 
 

 
  input = 0;                
}

      Serial.println(d1);
      Serial.println(d2);
      Serial.println(bufferArray[0]);
      Serial.println(bufferArray[1]);
      
}

bekomm ich zb bei übertragenen Werten 10 und 80 nur das:

0
0
50
53

Hab noch diese Seite dazu gefunden: http://dada.soulwire.co.uk/2009/07/arduino-multi-variable-serial-communication/
Nur leider kommt ich beim Verifizieren mit dem >= nicht weiter, und hab leider auch keine Ahnung, was das so richtig bewirkt.

Hallo X77Z,

das > und das < sind html-tags für “>” und “<”.
Die sind wohl beim erstellen der Seite umgewandelt worden.

Also: for (i=0; i<3; i++) ist eigentlich for(i=0; i<3; i++)

Bis…
Dambo

Vielen Dank für den Hinweis. Da hab ich das ja schon so ziemlich richtig abgeändert.

Aber warum bekomm ich die falschen Werte raus? Falsches Format?
Werden die empfangenen Zahlen als Byte empfangen, und so nicht richtig als Integer gelesen?

Poste doch mal den Code mit dem gesendet wird, oder habe ich den hier übersehen? Evtl. liegt da bereits der Fehler.

Achso. Den hatte ich noch nicht mit hin geschrieben.
Der Sendeteil im Programm sieht so aus:

if(sendStart==1){
  Serial.print((byte)wert1,DEC);
  delay(1);
  Serial.print((byte)wert2,DEC);
  delay(1);
  sendStart=0;
}

Wobei es keinen Unterschied macht, ob ich das so wie oben schreibe, oder nur "Serial.print(wert1);".

Und wie gesagt - wenn ich nur mit dem XBee empfange (per X-CTU), dann bekomm ich beide Werte hintereinander angezeigt, so wie es gesendet wird.

Aber müsste nicht auch der Empfang funktionieren, wenn ich die Werte einfach per Console sende?

Also wenn ich den Sender, und die XBees einfach weglasse, und mit dem Serial Monitor erst einen, dann den anderen sende,
dann müssten die doch folglich genauso empfangen werden.

Das funktioniert aber leider auch nicht. Ich bekomm immer nur Werte zwischen 40 und 60 raus.

Ich glaube Dein Problem ist tatsächlich das Senden.
Der Code

if(sendStart==1){
  Serial.print((byte)wert1,DEC);
  delay(1);
  Serial.print((byte)wert2,DEC);
  delay(1);
  sendStart=0;
}

Wandelt beim Senden die Werte in Text um. Sende das Ganze mal mit Serial.write(), das sendet einzelne Bytes. Siehe auch
http://arduino.cc/en/Serial/Write

???
???
???
???
???
???

Das wars. Man. Sowas “kleines”, und so ein großes Kopfzerbrechen.
Vielen Dank für den Tip.

Musste noch den Dateityp ändern, damit es auf dem LCD-Display richtig ankam, aber so funktionierts jetzt:

#include <LiquidCrystal.h>

LiquidCrystal lcd(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3);


int input;
int bufferArray[2];
byte wert1;
byte wert2;


void setup()
{
    lcd.begin(16, 2);
    lcd.clear();
    Serial.begin(115200);
    input = 0;
}






void loop() {
  if (Serial.available() > 1)  {    
 
      for (int i=0; i<2; i++) {			
       bufferArray[i] = Serial.read();     	
       input = 1;    			
      } 
  }
  
  
  
  
  if (input != 0)				
{                
 
  
 
  					
   wert1 = bufferArray[0];			
   wert2 = bufferArray[1];			
 
 

 
  input = 0;                
}
lcd.setCursor(0,0);
  lcd.print("Wert 1:   ");
  lcd.print((byte)wert1,DEC);
  lcd.print("   ");
  lcd.setCursor(0,1);
  lcd.print("Wert 2:      ");
  lcd.print((byte)wert2,DEC);
  lcd.print("   ");
      
      
}

…und gesendet wird mit Serial.write