Go Down

Topic: Sämtliche Zeichen eines Arrays um eine Stelle verschieben (Read 3411 times) previous topic - next topic

Chris72622

Arduino erklärt nicht den gesamten Befehlsatz/ Funktionen.


Danke. Das macht es am Anfang wirklich sehr schwierig, wenn man ausschließlich mit Arduino und passend darauf zugeschnittener Lektüre ins Thema Programmieren startet.

Gruß Chris
https://github.com/jeffThompson/DarkArduinoTheme

jurs


Mich verwirrt, dass viele "Befehle" in einer Programmiersprache geschrieben sind, die ich nicht in Einklang bringen kann mit dem, was ich in den Büchern über reine Arduinoprogrammierung bisher gelernt habe (z.B. "memset" oder "strstr").


Deine Bücher "über reine Arduinoprogrammierung" sind nicht das allein Seeligmachende für die C-Programmierung von AVR-Mikrocontrollern.

Arduino ist in erster Linie eine GCC-Entwicklungsumgebung mit vollständigen AVR-libc Libraries, die vollständig vorinstalliert sind. Plus einen kleinen Fliegenschiss an Arduino-spezifischen Erweiterungen bei Preprocessing und Arduino-Libraryerweiterungen.

Zum Programmieren unter Arduino steht Dir die gesamte AVR libc zur Verfügung:
http://www.nongnu.org/avr-libc/

Library Reference: http://www.nongnu.org/avr-libc/user-manual/modules.html

Mit allen Stringbearbeitungsfunktionen: http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html

Die Links poste ich mal, falls Du nachschlagen möchtest, welche Befehle Dir zum Programmieren zur Verfügung stehen. Wie Du die verwendest, kannst Du auch auf anderen Seiten über C und C++ Programmierung googeln, wenn sie Dir nichts sagen.

Im Gegensatz dazu, dass manche meinen, Arduino wäre ein Mikrocontrollersystem, das sich an Leute mit null Vorkenntnissen wendet, ist Arduino tatsächlich ein Mikrocontrollersystem, das sich zuerst an C/C++-Programmier mit soliden Programmierkenntnissen wendet.


Da ich ohne delay() arbeiten möchte, da ich noch anderen Code abzuarbeiten habe, wäre mir die "Funktionsvariante" viel lieber, doch mit dem Umbauen haperts ganz gewaltig. :(


Das sind Beispiele mit wenigen Codezeilen für interaktive Programme. Die darin enthaltenen 100ms Delay liegen unterhalb der Reaktionszeiten eines Menschen. Wenn Du nicht-interaktive Programme machst, die in den 100ms, die der Beispielcode wartet, noch tausend andere Dinge erledigen müssen, kannst Du die Kommandos natürlich auch ohne Delay einsammeln, dann wird der Code und die Programmlogik ein paar Zeilen länger.


In meinem Fall würde es aureichen auf Zeichenfolgen zu prüfen (wie "CONNECT" bei dem Kollegen, bloß inkl. Leerzeichen- z.B. "Z 3 0 1").


Also eine loop die gleichzeitig kurze Kommandos von der seriellen Schnittstelle sammelt und ohne delay andere Dinge erledigen kann während die seriellen Zeichen eintrudeln. Da würde ich mir keine grossen Gedanken über einen eigenen Empfangs-Ringpuffer machen, das ist vergebliche Mühe, denn der serielle Empfangspuffer beim Arduino ist ja bereits vorhanden, ich glaube mit 64 Bytes Pufferspeicher. Da braucht man die Zeichen nur rausziehen und auf die Kommandos abscannen, genau wie in den zwei von mir geposteten Beispielen. Bzw. mit den ganzen Zahlen als Modifikator eines Kommandos dann das zweite Beispiel mit der "CONNECT" Auswertung.


Das sich aus meiner Sicht bei Beiden von Dir verlinkten Codeschnipseln der Buffer innerhalb der setup loop() befindet, kann ich das Ganze nun leider nicht in Einklang mit bisher von Dir "vorgeschlagenen" Funktionsvariante bringen.


Da schaue bitte nochmal genau hin!
Im CONNECT-Beispiel http://arduino.cc/forum/index.php/topic,137669.0.html wird in setup() nur die serielle Schnittstelle initialisiert, es gibt eine saugeniale Funktion getIntFromString zum Rausziehen von Zahlenwerten aus einem String, die von überall im Sketch verwendet werden kann, und es gibt eine loop(), in der Kommandos laufend ausgewertet werden und die darauf reagiert, dass bestimmte Kommandos kommen.

Das ist der Ansatz als Vorlage, wo Du nur noch das delay() durch eine andere Programmlogik ersetzen müßtest, und dann könntest Du auch Kommandos wie  z.B. "Z 3 0 1" damit erkennen und darauf reagieren.

Chris72622

#17
Jan 15, 2013, 11:38 am Last Edit: Jan 15, 2013, 12:33 pm by Chris72622 Reason: 1
1000 Dank für den ganzen Content!!

Werde mir alles zu Gemüte führen!

Spricht was gegen diese Lösung (Textsendefenster muss CR mitschicken):

Code: [Select]
boolean x=0;

void setup()
{

Serial.begin(9600);
 
}

void loop()
{

 x=Serial.findUntil("Z 3 0 1","\r");
 Serial.println(x);
 delay(100);
}


Wunder mich, warum es keine Bufferprobleme zu geben scheint. Ist der Arduino-Eingangsbuffer somit ein Ringbuffer und überschreibt automatisch die letzten Zeichen?

Gruß Chris
https://github.com/jeffThompson/DarkArduinoTheme

jurs


Spricht was gegen diese Lösung (Textsendefenster muss CR mitschicken):
...
 x=Serial.findUntil("Z 3 0 1","\r");


???

Gestern noch schriebst Du was davon, dass 100 ms delay für Dein Programm nicht OK sind:
> "Da ich ohne delay() arbeiten möchte, da ich noch anderen Code abzuarbeiten habe"
Und heute möchtest Du eine Funktion aufrufen, die sämliche Codeverarbeitung bis ins unendliche blockieren kann, jedenfalls so lange bis entweder der Suchstring oder der terminierende String gefunden wird?

Kapiere ich nicht.

Das mußt Du doch selber wissen, wie lange Dein Programm maximal zwischendurch warten darf bis wieder Code ausgeführt wird. Entweder gar nicht, dann mußt Du Dir noch was einfallen lassen. Oder 100 ms (wobei das ggf. auch herabgesetzt werden kann) mit der von mir geposteten Lösung. Oder bis zu unendlich lange bis entweder der gesuchte String oder ein Zeilenende von der seriellen Schnittstelle reinkommt mit "findUntil".


Wunder mich, warum es keine Bufferprobleme zu geben scheint. Ist der Arduino-Eingangsbuffer somit ein Ringbuffer und überschreibt automatisch die letzten Zeichen?


Solange in den seriellen Eingangspuffer nicht mehr Zeichen reingeschrieben werden als es der Puffergröße entspricht, ohne zwischendurch Zeichen wieder auszulesen, wird gar nichts überschrieben, sondern nur zwischengepuffert.

Chris72622

Das mit den 100ms im letzten Codefetzen war nur fürs Debugging.

Gruß Chris
https://github.com/jeffThompson/DarkArduinoTheme

jurs


Das mit den 100ms im letzten Codefetzen war nur fürs Debugging.


Die 100 ms explizites delay meine ich gar nicht.

Aber was ist mit dem quasi "eingebauten delay" beim Aufrunf von findUntil?
Die findUntil-Funktion macht doch "busy waiting" und verzögert die weitere Programmausführung, während es damit beschäftigt ist, auf das Eintreten der Abbruchbedingung zu warten.

Ich habe die Funktion gerade mal getestet, eine Zeile wie
x=Serial.findUntil("Z 3 0 1","\r");
dauert in der Ausführung zwar im Extremfall nicht unendlich lange (entsprechend der Dokumentation auf den Arduino-Seiten), sondern "nur" bis zu 1 Sekunde (=1000 ms), offenbar gibt es ein nicht dokumentiertes Timeout.

Stört das weiter nicht, wenn Deine Programmausführung für anderen Code bis zu einer Sekunde aussetzt?

Denn die Funktion findUntil blockiert doch die Programmausführung, und zwar bis
- entweder der Suchstring gefunden wird (z.B. "Z 3 0 1")
- oder der terminierende String gefunden wird (z.B. "\r")
- oder das Timeout von einer Sekunde abgelaufen ist

Das war meine Frage, ob diese blockierende Eigenschaft der Funktion findUntil für Dein Programm unbedenklich ist?

Z.B. weil (was Du nicht geschrieben hast) an der seriellen Schnittstelle zwischen den Kommandos, die Du abgreifen möchtest, sowieso immer laufend "\r" gesendet wird und im Eingangspuffer landet, bei dessen Empfang Deine findUntil-Aufrufe ja jedesmal abbrechen?





Chris72622

#21
Jan 16, 2013, 01:07 pm Last Edit: Jan 16, 2013, 06:23 pm by Chris72622 Reason: 1
Ich habe das Timeout auf 0 gesetzt und frag 100ms nach Knopfdruck ab.

Dokumentiert ist es hier:

http://arduino.cc/en/Serial/SetTimeout

Das passt in meinem Fall wirklich super. :)

Es lassen sich bei mehreren seriellen Anschlüssen sogar unterschiedliche Timeouts (jedezeit neu) setzen.

Gruß Chris
https://github.com/jeffThompson/DarkArduinoTheme

Go Up