kann mir jemand verraten, wie schwer es ist einen String der über die USB Schnittstelle kommt in 2 Teile zu zerlegen. Als Trennzeichen würde ich vermutlich einfach ein "|" - Zeihen nehmen. Also den Senkrechten Strich bei < >.
Der erste Teil des Strings wird eine Zahl sein, welche zwischen 1 und 4 ist. Das was danach kommt soll einfach auf das LCD - Modul ausgegeben werden.
Also z.B. es kommt folgender String "2|test", damit wird "test" in die zweite Zeile des LCD Moduls geschrieben.
Am Ende soll das Arduinoboard mit einem Raspberry Pi verbunden werden, der via Python mit dem Arduino kommuniziert. Das ist aber ein anderes Thema.
Um C strings zu zerlegen gibt es strtok(). String Tokenizer:
Das ersetzt dir automatisch die Delimter durch NULL damit die Teil-Strings korrekt terminiert sind.
Man kann auch nach chars mit strchr() suchen:
Damit könntest du nach dem Delimter suchen, diesen per Hand durch NULL ersetzen (für den ersten Teil-String) und dann von dem Index des Delimters + 1 den zweiten String ausgeben. strtrok() ist da aber etwas handlicher bei vielen Teil-Strings. Wenn es nur einmal Trennen ist tut es auch strchr().
Wenn du nur den zweiten Teil-String willst brauchst du auch den Delimiter nicht mit NULL zu überschreiben.
Das bezieht sich auf NULL-terminierte char Arrays. Nicht die Arduino String Objekte. Du kannst aber mit toCharArray (?) daraus auch einen C-String machen.
Ich denke die Lösung mit "strtok" ist schon ein guter Anfang.
Also nur im Groben zur Verständlichkeit, ist nur Schematik kein Code:
#String definieren
String = "2|TesT"
#Ersten Teil vom String in Variable
zeile = strtok(String, "|")
#Zeile des Displays festlegen
LCD(1, zeile)
#Zweiten Teil vom String in Variable
ausgabe = strtok(String, "|")
#Text auf Display ausgeben
LCD Ausgabe(ausgabe)
Wäre das so im Groben was zum Ziel führen würde? Mir ist klar, dass ich das noch in einem Quellcode packen muss, aber sonst? Und wenn ich mit Abstand von 1 Sekunde Informationen so an den Arduino schicke, schafft er diese alle zu verabeiten oder?
Am besten du steigst gleich voll auf C-Strings um. Das sind nur char Arrays:
Du musst halt einmal einen Puffer anlegen der groß genug für deinen maximalen String + 1 ist. z.B.:
const int BUFFER_SIZE = 31;
char buffer[30];
Dann kannst du einen Index mitzählen und sowas machen:
buffer[index++] = Serial.read();
Bedenke da dass wenn du alles eingelesen hast (also z.B. ein LF oder CR kommt, je nachdem was du im Serial Monitor eingestellt hast), du den letzten char auf NULL setzten musst. mit buffer[index] = '\0';
Oder du setzt VOR dem Einlesen den gesamten Puffer mit memset() auf NULL: http://www.cplusplus.com/reference/cstring/memset/
strtok() ist etwas komplizierter als das. Schau dir das Beispiel genau an. Der erste Aufruf gibt dir einen Zeiger auf den ersten Teil-String. Dann musst du die Funktion in zweites mal aufrufen (und dann mit NULL als Parameter) um an den zweiten Teilstring zu kommen. Siehe auch hier: http://www.cplusplus.com/reference/cstring/strtok/
strtok() verwaltet intern mit einer static Variablen einen Zeiger auf den Delimeter. Dieser Zeiger wird mit dem ersten Aufruf initialisiert, der den String als Parameter hat. Alle weiteren Aufrufe haben NULL als Parameter und arbeiten dann auf dem String der im ersten Aufruf übergeben wurde.
Es gibt da auch mit strtok_r() (für "reentrant) noch eine Version die den Zeiger extern verwaltet, da ist aber auch nicht viel anders.
Ansonsten, ja. So geht es Und 1 Sekunde ist lange. Serial ist recht langsam (im ms Bereich), aber der Arduino hat einen Takt von 62.5 ns.
Man legt einen Puffer für den String an und beschreibt dann den String. Hier haben wir eine Dezimal-Zahl %d, gefolgt von einem Strich und der Rest ist ein String %s
snprintf() und sccanf() fressen viel Speicher, aber sind sehr praktisch wenn man sich immer wiederholenden, kurze Strings hat. Vor allem kann man da Teile von Strings gleich in Zahlen wandeln.
Jurs hatte da übrigens mal eine fertige Routine für Serial Einlesen gepostet:
har* receiveBuffer()
#define ZEILENTRENNZEICHEN 13 // 13 ist Steuerzeichen CR (Carriage Return)
{
static char lineBuffer[63]; // Maximale Zeilenlänge festlegen
static byte counter=0;
char c;
if (Serial.available()==0) return NULL; // Nullpointer zurück
if (counter==0) memset(lineBuffer,0,sizeof(lineBuffer));// Puffer vor Benutzung löschen
c=Serial.read();
if (c==ZEILENTRENNZEICHEN)
{
counter=0;
return lineBuffer;
}
else if (c>=32) // kein Steuerzeichen?
{
lineBuffer[counter]=c; // Zeichen im Zeilenpuffer einfügen
if (counter<sizeof(lineBuffer)-2) counter++;
}
return NULL;
}
void loop()
{
char* text = receiveBuffer()
if(text != NULL)
{
//Auswertung hier
}
}
Da siehst du wie das gemeint war. Terminiert in diesem Fall bei einem CR am Ende
Habe oben auch noch mal eine Alternative zu strtok() geschrieben, die vor allem bei so kurzen Sachen schön ist.
Ansonsten, wenn deine Zahl immer nur eine Stelle hat kannst du auch einfach in den dritten Index greifen
So ähnlich:
Serial.println(buffer + 2);
Gibt da viele Optionen, je nachdem wie das genau aussieht und was man da genau mit den Strings machen will. Manchmal muss gar nicht die großen Funktionen rausholen.
Es geht eher darum wie dein String genau aussieht. Wenn du am Anfang nur eine einstellige Zahl hast (und nie zwei-stellig). Dann geht auch sowas in der Art:
EDIT: sehe jetzt das du geschrieben hast, dass es nur von 1-4 gehen soll
Da wäre nur die Sache, wie bekomme ich bei der Buffer - Lösung die Zeilenzahl raus?
Weil an sich gefällt die mir sogar noch viel besser, da einfacher
Und zum String, das werden nur einfache Informationen wie Titel, Interpret, eine Zeitangabe also Min:Sec und in der dritten Zeile kommt eine Temperaturanzeige hin.
Wobei ich aber vermutlich auch nur folgende Informationen an das Board übergebe: Titel, Interpret und Spieldauer eines Titels. Den die Fortlaufenden Sekunden kann ich ja mit dem Arduino auch allein hinbekommen denke ich oder? wobei es dann nur ein Problem gibt, wenn der Player gestoppt wird, also von daher werde ich wohl doch die Spieldauer und Spielzeit übergeben lassen. 8)
Wird offensichtlich wenn du dir mal die ASCII Tabelle ansiehst und merkst dass die 0 den ASCII Code 0x30 hat.
EDIT: Natürlich 0x30. 0x20 ist das Leerzeichen. Es wird spät
Wobei du dir das mit der Zeilen Nummer auch eventuell sparen könntest. Wenn du weist welcher Teil des Strings wo im Display steht, kannst du auch alles auf einmal schicken. Dann bist du aber wieder bei strtok(), da dann alles in einem String steht. Ist dann Geschmackssache.
Der Hacken wäre nur, wenn ich alles auf einmal schicke, dass ich den gesamten Display jede Secunde neu beschreibe oder macht es ihm nichts aus?
Den dann könnte man auch über eine "Fortschrittsleiste" nachdenken. Wie erstellt man eigentlich eigene Symbole für die LCD Methode? Also in Bascom gibt es einen Editor, mit dem man einzelne Pixel aktivieren kann auf der Matrix eines Kästchens. Und wenn ich das noch richtig im Kopf habe, hat jedes "Kästchen" 5 oder 6 Spalten. Also man könnte den Fortschrittsbalken dann Detailierter darstellen lassen. Die Rechenarbeit übernimmt die Datenquelle und würde dann nur einen Prozentwert übermitteln, mit dem dann der Balken gefüllt wird.
Aber wenn das jede Sekunde beschreiben dem Bildschirm nichts aus macht, wäre das auch eine interessante Möglichkeit.
Ob man das Display komplett jede Sekunde beschreiben kann, kannst du einfach mal ausprobieren. Kann ich jetzt so nicht sagen. Man sollte es nicht dauernd beschreiben, da die Displays träge sind. Aber damit sind alle paar ms gemeint. Jede Sekunde könnte gehen.
Wobei du schon recht hast, das das trotzdem irgendwie nicht toll ist. Auch wenn es geht.
Dabei immer eine Zeilennummer voranzustellen ist eine normale Lösung, die nicht schlechter ist.
Solche Fortschrittsbalken findest du glaube ich auch fertig im Internet.
Und auch generell in den Beispielen die mit bestimmten LCD Libs kommt. Das LCD hat einen bestimmten Bereich im RAM wo die drin stehen. Dann gibt es einen Befehl mit denen man genau den Bereich beschreibt.
Font Editoren für 5x7 gibt es z.B. hier:
Da sieht du schon die Balken drin.
Oder nach "LCD font generator suchen". Das oben ist ein Online Editor. Da gibt es aber auch viele Programme zum runterladen.