Go Down

Topic: Zeichenkette von Windowsprogramm an Arduino übergeben und auswerten (Read 2177 times) previous topic - next topic

Thyrie

Hallo Zusammen,

ich denke ihr könnt mir bei meinem Problem sicherlich weiterhelfen.

Ich habe mir ein Programm in Visual Basic geschrieben mit welchen ich 3 Werte über eine Serielle Schnittstelle
zu meinem Arduino übergeben möchte.
Die Zeile in welchen die Werte stehen sieht wie folgt aus: 500;500;500
Diese wird alle 5 Sekunden vom Windowsprogramm übertragen.
Die einzelnen Werte können aber von 0-1000 variieren.

Nun mein eigentliches Problem, wie lese ich nun diese Zeichenkette seriell mit meinem Arduino ein und weise
diese wiederum 3 verschiedenen Variablen zu?

Gruß
Thyrie


sschultewolter

#1
Jul 10, 2014, 07:39 pm Last Edit: Jul 10, 2014, 07:41 pm by sschultewolter Reason: 1
Du solltest mit jeder Nachricht aus Visual Basic daran denken, das NewLine Zeichen mitzusenden!

Code: [Select]
const int NUMBER_OF_FIELDS = 3; // Wie viele kommaseparierte Felder erwarten wir?
int fieldIndex = 0; // Das aktuell empfangene Feld
int values[NUMBER_OF_FIELDS]; // Array mit den Werten aller Felder
void setup()
{
 Serial.begin(9600); // Serieller Port sendet und empfaengt mit 9600 Baud
}
void loop()
{
 if( Serial.available())
 {
   char ch = Serial.read();
   if(ch >= '0' && ch <= '9') // ASCII-Zeichen zwischen 0 und 9?
   {
     // Ja, Wert akkumulieren, solange fieldIndex gueltig ist
     //U¨berza¨hlige Felder werden nicht gespeichert
     if(fieldIndex < NUMBER_OF_FIELDS) {
       values[fieldIndex] = (values[fieldIndex] * 10) + (ch - '0');
     }
   }
   else if (ch == ';') // Komma ist unser Trennzeichen, also weiter zum naechsten Feld
   {
     fieldIndex++; // Feldindex inkrementieren
   }
   else
   {
     // Jedes Zeichen außer Ziffern und Semikolon beendet das Einlesen der Felder.
     // In diesem Beispiel ist dies das vom seriellen Monitor gesendete Newline-Zeichen
     // Alle gespeicheren Felder ausgeben
     for(int i=0; i < min(NUMBER_OF_FIELDS, fieldIndex+1); i++)
     {
       Serial.println(values[i]);
       values[i] = 0; // Werte fuer naechste Nachricht auf 0 zuruecksetzen
     }
     fieldIndex = 0; // Index fuer Neustart vorbereiten
   }
 }
}
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

Serenifly

http://www.gammon.com.au/forum/?id=11425

Am Ende ist eine Variante wie man einfach Zahlen einlesen kann ohne den String vorher abzuspeichern. Also einlesen + konvertieren auf einmal.

Man kann aber auch den String erst mal in einen Puffer einlesen und danach mit strtok() splitten und atoi() in Integer konvertieren. Das kostet aber etwas mehr RAM.

k-b-l

schau mal nach einer for schleife, die dir alle empfangene Bytes in ein array schreibt.

wegen deinen Werten sende das doch einfach mit einer 0 vorweg

1000:0699:0069:0009

so ist deine Zeichenkette immer gleich lang

Serenifly

#4
Jul 10, 2014, 07:44 pm Last Edit: Jul 10, 2014, 07:46 pm by Serenifly Reason: 1

schau mal nach einer for schleife, die dir alle empfangene Bytes in ein array schreibt.

Da Serial so langsam ist, braucht man dazu ein Delay nach dem ersten Zeichen, damit man wartet bis alles wirklich da ist. Es gibt Anwendungen bei denen das vertretbar ist, aber statt das Programm zu blockieren ist es wesentlich besser man fragt ständig ab ob Daten da sind und liest dann nur aus wenn etwas da ist. Wenn keine Daten da sind, kann man zwischendurch andere Dinge erledigen.

Wobei es in diesem speziellen Fall wohl sogar geht wenn man mit Serial.available() abfragt ob alle Zeichen da sind. Aber das ist ein Sonderfall. Am besten man lernt gleich wie es allgemein geht. Dann ist es vollkommen egal wie viele Zahlen man sendet oder wie lang diese sind.

sschultewolter


Am besten man lernt gleich wie es allgemein geht. Dann ist es vollkommen egal wie viele Zahlen man sendet oder wie lang diese sind.


Das könnte man zB mit dem Sketch oben machen. Müsste dann NUMBER_OF_FIELDS auf einen beliebigen Wert hochsetzen. Das wichtige ist halt vorallem ein Newline, damit er überhaupt mitbekommt, dass ein Datensatz komplett gesendet wurde.
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

michael_x

Quote
Da Serial so langsam ist, braucht man dazu ein Delay nach dem ersten Zeichen, damit man wartet bis alles wirklich da ist.

Ja, man kann generell davon ausgehen, dass in jedem loop - Durchlauf 0 , 1, oder einige mehr Zeichen kommen.
Bei jedem Trennzeichen kann man eine Zahl fertig bearbeiten, beim Endezeichen '\n' das machen was zu tun ist, wenn alle Daten da sind.
Wem das zu kompliziert ist, der liest in jedem loop Durchlauf nur max 1 Zeichen, und macht nichts, wenn Serial zu langsam war.

Quote
wartet bis alles wirklich da ist. Es gibt Anwendungen bei denen das vertretbar ist

Problem bei variablen Längen, wo man erst an den Daten erkennt, wann alles da ist.
Kann auch immer mal ein Zeichen verstümmelt werden.
Quote
Das wichtige ist halt vorallem ein Newline, damit er überhaupt mitbekommt, dass ein Datensatz komplett gesendet wurde.
Genau !



Serenifly


Problem bei variablen Längen, wo man erst an den Daten erkennt, wann alles da ist.

Das ist klar. Deshalb habe ich gesagt, dass es ein Sonderfall ist :)

Wenn man weiß dass man immer 4 Zahlen bekommt oder diese konstant 4 Ziffern breit formatiert, kennt man die Anzahl der zu erwartend Zeichen. Wenn man dann annimmt, dass nie Zeichen komplett verschluckt werden (was ich eigentlich noch nie hatte), geht das theoretisch. Ich würde es aber trotzdem nicht empfehlen.

combie

Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Go Up