Windmesser auslesen

molli76:
Ein Beispiel-Code wäre total cool. Wenn Du das auf die Schnelle machen könntest, wäre ich Dir unsagbar dankbar.

Du möchtest das aber nicht bereits für ein Oster-Sportfest am Laufen haben, oder?

Ich weiß auch nicht ganz genau, was Du genau machen möchtest und wie die Daten dann weiterverarbeitet werden sollen.

Ich habe auf die schnelle was zusammenkopiert und geschrieben, das wie folgt arbeitet:

LED als "Bereitschaftsanzeige":
Wenn der Sketch bereit ist zur Messung, wird die Board LED an Pin-13 eingeschaltet.
Während eine Messung läuft, ist die Board LED an Pin-13 ausgeschaltet

Der Sketch versucht, immer die beiden Werte aus je 3 Zeilen auszulesen und gibt im Erfolgsfall aus:

  • Zeitstempel beim Empfang von Wert-1
  • Wert-1 als String, so wie er empfangen wurde
  • Wert-1 umgewandelt in eine numerische Gleitkommavariable
  • Wert-2 als String, so wie er empfangen wurde
  • Wert-2 umgewandelt in eine numerische Gleitkommavariable
  • Zeitstempel beim Empfang von Wert-2

Der numerische Wert weicht vom tatsächlichen Wert mindestens in dem Fall ab, dass "--.-" empfangen wird, dann ist der empfangene Wert "--.-" und der numerische Wert "0.0".

Die Zeitstempel stammen hier einfach vom Stand des millis() Timers (Zeit seit Controller-Reset), könnte man bei Bedarf aber auch aus einer Echtzeituhr ziehen.

Falls eine Messung begonnen wurde, aber während einer bestimmten Timeout-Dauer keine weiteren Zeichen empfangen wurden, erfolgt ein Fallback in Messbereitschaft und das Programm wartet auf eine neue Messung. Diese Timeout-Zeit habe ich mal auf 60 Sekunden eingestellt.

Wenn die Messwerte irgendwo in einem seriellen Terminalprogramm mitgeloggt werden sollen, kann man das wohl so ungefähr machen. Aber falls die Daten irgendwie weiter verarbeitet werden sollen, müßte man an der Struktur vielleicht irgendwas ändern.

Probiers mal aus.

#define LED 13  // Pin für LED "Bereitschaftsanzeige"
#define TIMEOUTLIMIT 60000L // Maximaldauer für eine Messung in Millisekunden

char* SerialStringRead(char EOLchar)
{
  // Parameter EOLchar: welches Zeichen als "Zeilenende" interpretiert werden soll
  // Rückgabewert: Wenn keine Zeile gelesen wurde NULL, sonst String-Pointer
  static char text[25]; // Stringpuffer für maximale Zeilenlänge + 1
  static byte charcount=0; // Zeichenzähler
  if (!Serial.available()) return NULL; // kein Zeichen im seriellen Eingangspuffer
  if (charcount==0) memset(text,0,sizeof(text)); // Stringpuffer löschen
  char c=Serial.read(); // ein Zeichen aus dem seriellen Eingangspuffer lesen
  if (c>32 && charcount<sizeof(text)-1) // Steuerzeichen und Leerzeichen überlesen
  {
    text[charcount]=c; // ASCII-Zeichen > 32 behalten
    charcount++;
  }
  else if (c==EOLchar) 
  {
    charcount=0;
    return text;
  }
  return NULL;
}

boolean timeoutErkennung(boolean doReset)
{
  static unsigned long lastCharReceived=0;
  if (doReset)  // Timeout resetten
    lastCharReceived=millis();
  else  // Timeout prüfen
  {
    if (millis()-lastCharReceived>TIMEOUTLIMIT) return true;
  }
  return false;
}




void setup() {
  Serial.begin(9600);
  pinMode(LED,OUTPUT);
  Serial.println("Alge-Timing Windmesser WS2 auswerten by 'jurs' for German Arduino Forum");
  Serial.println();
  Serial.println("Zeit  \tWert-1\tW1 num\tWert-2\tW2 num\tZeit  ");
  Serial.println("------\t------\t------\t------\t------\t------");
}


byte linecount=0;
float wert1,wert2;

void loop()
{
  char* strPtr;
  if (Serial.available())
  {
    timeoutErkennung(true); // Timeout resetten
    strPtr=SerialStringRead(13); // Zeichen auslesen
  }
  else strPtr=NULL;
  if (strPtr!=NULL && strcmp(strPtr,"")==0)
  {// Auf Leerzeile synchronisieren, normalerweise die dritte Zeile nach zwei Datenwerten
    Serial.println();
    linecount=0; 
  }
  else if (strPtr!=NULL)
  {
    linecount++;
    switch (linecount)
    {
      case 1:
        Serial.print(millis()/1000.0,1); // Zeit für den ersten Wert
        Serial.print('\t');
        Serial.print(strPtr); // Erster Wert als String
        Serial.print('\t');
        wert1=atof(strPtr);   // Erster Wert numerisch
        Serial.print(wert1);
        Serial.print('\t');
        break;
      case 2: 
        Serial.print(strPtr);  // Zweiter Wert als String
        Serial.print('\t');
        wert2=atof(strPtr);
        Serial.print(wert2);   // Zweiter Wert numerisch
        Serial.print('\t');
        Serial.print(millis()/1000.0,1); // Zeit für den zweiten Wert
        break;
    }
  }
  if (linecount==0) digitalWrite(LED,HIGH); // in Bereitschaft auf Messung warten, Bereitschaftsanzeige an
  else  // wir sind mitten in einer Messung
  {
    digitalWrite(LED,LOW);  // Bereitschaftsanzeige aus
    if (timeoutErkennung(false)) // Auf Timeout prüfen, falls Timeout wieder in Bereitschaft gehen
    { 
      Serial.println();
      Serial.println("Timeout - warten auf neue Messung");
      linecount=0; 
    }
  }
}