Grüezi wohl zusammen. Ich schätze mal, meine Frage bzw mein Anliegen ist bereits bekannt aber leider habe ich keine brauchbare Lösung gefunden. Es geht um folgendes: Ich habe einen Schrittmotor mit dem ich ein Schlitten auf die gewünschte Position fahre. Ich habe bereits eine Funktion: "goTo(int position)" die mir den Schlitten an den gewünschten Ort fährt. Diese Funktion funktioniert problemlos. Nun möchte ich aber über den PC (Serial Monitor) die Position eingeben, wohin der Schlitten soll. Das ist jedoch schwieriger als ich gedacht habe. Kann mir bitte jemand sagen, wie ich eine Funktion z.b "goToSerial()" schreiben kann, damit ich über die Konsole einen Zahlenwert eingeben kann und dieser dann der Funktion "goTo(int position)" übergeben wird? Ich wäre über eure Hilfe sehr Dankbar! Grüsse aus der Schweiz Niiico
Von der Seriellen Schnittstelle kriegst du einen String. Den wandelts du mittels atoi() oder dtostrl() in einen int um und steckst ihn in deine Positionier-Funktion rein. (Komisch: Es gibt Fragen, die tauchen in abgewandelter Form an jedem einzelnen Tag mindestens 5 mal im Forum auf. Und auch komisch: es sind zu 90% Fragen, deren Lösung in jedem auch noch so grindigem Einsteiger-C-Buch zu finden ist. Wenn man nur eines hätte und es auch durchgearbeitet hätte.)
Vielen Dank Karl Heinz Sowas habe ich mir bereits überlegt! Ich versuche noch entwas heraus zu finden. Denn den String muss ich ja elementweise auslesen und anschliessend zusammenführen?
Vielleicht schaust Du einfach mal nach, wie atoi() funktioniert ???
Salut zusammmen. Danke für die Inputs sowie Links! Ich habe es geschafft, die Funktion hinbekommen und die Übertragung klappt wunderbar. Schönes Wochenende und Gruss
Hallo, ich habe das gleiche Problem. Wie hast du es gelöst?? LG Sticky
Meinst du das elementweise Aauslesen des Strings oder das Konvertieren in einen Integer?
Hallo, eigentlich meine ich beides. ich weis wie es ca. aussehen müsste: while (Serial.available() > 0) { for (index = 0; index < 20; index++) { inChar[index] = Serial.read(); index++; // Increment where to write next inChar[index] = '\0'; // 0 for String } incomingByte = atoi(inChar); Das Problem ist, wenn ich den Wert incomingByte an den Steppermotor schicke, macht der Motor garnichts. rotate(incomingByte, .5); Wenn ich aber einen fixen Wert eingebe wie zB: rotate(3000, .5); dann dreht sich der Motor um 3000 steps mit der geschwindigkeit 0.5 Ich habe selber sehr wenig programmiererfahrung und das sind erst meine ersten Schritte. Bin für jede Hilfe oder Hinweis Dankbar. Lg Sicky
Sticky schrieb: > Ich habe selber sehr wenig programmiererfahrung und das sind erst meine > ersten Schritte. > Bin für jede Hilfe oder Hinweis Dankbar. Wert irgendwo ausgeben um zu prüfen das auch das richtige/erwartete ankommt.
Sticky schrieb: > while (Serial.available() > 0) { Nun ja. Ich weiß zwar nicht ganz genau was Serial.available macht, kann es mir aber so ungefährt vorstellen. Und genau das ist der falsche Weg. Ein String ist nicht dadurch zu Ende, dass an der UART keine Zeichen mehr da sind. Denn: Dein µC frägt die Serialle viele Tausend mal in der Sekunde, ob ein Zeichen vorliegt. So schnell kannst du aber gar nicht tippen, bzw können Zeichen gar nicht übertragen werden! D.h. der Sender (ein anderes Programm oder zb auch du vor einem Terminalprogramm) muss mit dem Empfänger ein Zeichen ausmachen, mit dem der Sender dem Empfänger mitteilt: 'Jetzt ist der String zu Ende. Jetzt kommt nichts mehr'. Nur weil der Sender eine gewissen Zeit lang nichts sendet, ist ein String noch lange nicht zu Ende. Dein Benutzer kann vor seinem Terminal sitzen und zb sich einen Kaffee holen, aber deswegen ist die Eingabe, die er gerade macht ja noch lange nicht beendet. Oft wird zb ein Carriage Return ('\n') für diesen Zweck benutzt. Und das macht Sinn. Denn Benutzer, die noch nicht klicki-bunti-verseucht sind, sind daran gewöhnt, dass sie Text tippen können und erst ein Druck auf die große Return Taste, leitet dann alles weitere ein. Sie ist praktisch die 'Ich bin fertig - du bist drann' Taste. > for (index = 0; index < 20; index++) { War nicht davon die Rede, dass man beliebig langen Text (in Grenzen) eingeben können soll. Wo kommen dann die 20 her? Warum 20? Dein Code muss (in Grundzügen so aussehen)
1 | do { |
2 | hole Zeichen von der Uart wenn eines da ist |
3 | |
4 | if( Zeichen != '\n' ) |
5 | hänge Zeichen an den bisherigen Text an |
6 | |
7 | } while( Zeichen != '\n' und das Array noch groß genug so dass |
8 | noch ein Zeichen reinpasst ) |
9 | |
10 | hänge ein \0 Zeichen an den Text hinten drann, damit |
11 | aus dem Zeichenhaufen ein C-String wird |
12 | |
13 | atoi anwenden |
und wie Läubi völlig richtig schon angemerkt hat: Lass dir die Zwischenergebnisse ausgeben. Du willst wissen: * kommt jedes Zeichen auch so an, wie ich mir das vorstelle. * Ist der zusammengebaute String der, den ich erwarte * Kommt bei der Umwandlung mittels atoi das richtige raus. Wenn du nur hinten nach feststellst, dass dein Motor falsch dreht, dann machst du beim Debuggen einen grundsätzlichen Fehler: Du hast viele Stufen, in denen etwas schief gehen kann! Also sieh dir diese Zwischenstufen auch an. Kein Mensch sucht in einer 5-seitigen Berechnung Fehler, indem er sich nur das Endergebnis ansieht und dann hinterher verzweifelt nach Hilfe ruft, sondern er sieht sich jede Zeile der Berechnung an, ob er irgendwo einen Fehler gemacht hat. Und genau dasselbe macht man auch beim Programmieren. Wenn hinten nicht das gewünschte rauskommt, dann muss man sich eben überlegen, welche Zwischenergebnisse man sich ansehen muss, um rauszukriegen was da abgeht. Dein µC hilft dir dabei, indem er brav Zwischenergebnisse über die UART zb wieder auf das Terminal ausgeben kann. Nur reinprogrammieren musst DU derartige Ausgaben! Beim Programm-Entwickeln immer schrittweise vorgehen! Deine Aufgabe lässt sich in mehrere Schritte zerlegen * String empfangen * String in Zahl umwandeln * mit der Zahl den Motor ansteuern Dann entwickle und vor allen Dingen teste das auch in Schritten! Nur dann, wenn ein Schritt funktioniert, wird der nächste Schritt in Angriff genommen. Sonst stehst du am Ende mit einem Haufen ungetesteten Code da, der nicht funktioniert und du hast keine Ahnung, wo du mit der Fehlersuche anfangen sollst, weil in jedem Schritt Fehler sein können und auch sein werden. Es ist ein grundsätzlicher, sehr beliebter Anfängerfehler, anzunehmen man könne ein Programm in einem Schritt fehlerfrei runterprogrammieren. Das kann man nicht. Niemand kann das. Auch die Profis können das nicht. Auch wir arbeiten in Schritten, nur sind unsere Schritte etwas größer. Nichts desto trotz sind sie aber da. Und genauso wie du das auch tun solltest, testen wir jeden Schritt ausgiebig, ehe es zum nächsten Schritt weitergeht.
Vielen Dank an Läubi .. Karl Heinz Buchegger. Vorallem die ausführliche Antwort. Ja, mein Problem ist, ich will alles auf einmal. Schrittweise ist sicherlich der bessere Weg. Die 20 in der for-Schleife war nur irgend ein Wert den ich zum Testen verwendet habe. Danke nochmal für die neuen Denkansätze. Wahrscheinlich werde ich euch noch mit einigen noob-Fragen belästigen. Frohes neues Jahr! Sticky
> Dein Code muss (in Grundzügen so aussehen)
Das muss man übrigens relativieren. Je nachdem was der Code sonst noch
so alles können soll, kann das alles auch ganz anders aussehen.
Hängt halt davon ab, wie die Hauptschleife dann konkret aufgebaut ist
und was sonst noch so alles zu tun ist. Der gezeigte Code geht davon
aus, dass UART Empfang und PWM einstellen alles ist, was es zu tun gibt.
Salut Sticky... Ich habe eine möglichst einfache Lösung gefunden. Sie ist noch provisorisch. Da ich auch noch ein grosser Amateur bin, werde ich mich schon noch darum kümmern. Die Funktion "goToSerial()" liest den Wert über den Serial Monitor ein und übergibt den Wert an die Funktion "goTo(position)".
1 | void goToSerial() |
2 | {
|
3 | int i; |
4 | char X_buffer[4]; //Max. Zahl "9999" |
5 | int incomingpos = 0; |
6 | |
7 | Serial.print("Fahre zur Position: "); |
8 | |
9 | while(incomingpos == 0) |
10 | {
|
11 | if (Serial.available()) |
12 | {
|
13 | Serial.flush(); |
14 | delay(5); |
15 | i=0; |
16 | while(i<5) |
17 | {
|
18 | X_buffer[i] = Serial.read(); |
19 | i++; |
20 | }
|
21 | Serial.flush(); |
22 | incomingpos = atoi(X_buffer); |
23 | Serial.println(incomingpos); |
24 | goTo(incomingpos); |
25 | Serial.println("Position erreicht!"); |
26 | }
|
27 | }
|
28 | incomingpos = 0; |
29 | }
|
Bitte denke daran, es ist nicht ganz sauber programmiert. Es war eine "Notlösung" die innerhalb von einem Tag funktionierten musste. Werde, wenn ich mal Zeit habe, einen sauberen Code schreiben. Ich hoffe, du kannst damit etwas machen. Verschneite Grüsse aus der Schweiz
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.