Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Einfache Befehlszeilenschnittstelle

Komponenten und Verbrauchsmaterialien

Arduino UNO
× 1

Über dieses Projekt

Befehlszeile

Es kommt eine Zeit, in der Sie den Wert eines Sensors ermitteln müssen oder Ihrem Roboter sagen möchten, dass er etwas wie "nach links bewegen" tun soll. Vielleicht müssen Sie Ihr Programm nach dem Laufzeitwert einer Variablen fragen oder den Wert eines digitalen Potentiometers einstellen.

Was Sie brauchen, ist eine Befehlszeile. Ja, es ist einfach, Ihren Arduino dazu zu bringen, auf Textbefehle zu reagieren.

Hier ist eine, auf die Sie aufbauen können. Es ist eine einfache, schnelle und sehr speichereffiziente Befehlszeilenschnittstelle (CLI), die Sie in wenigen Minuten ausschneiden und in Ihren eigenen Code einfügen und betriebsbereit sein können. Befehle bestehen aus einem Namen gefolgt von mehreren Argumenten. Es unterstützt sogar die Rücktaste, wenn Sie Ihre Befehle eingeben.  

Kurzübersicht

Jede Skizze hat eine Schleife() Funktion. Ihre könnte so einfach wie die folgende sein. Es ruft zwei Routinen in einem separaten Tab namens CommandLine.h . auf . Ich werde Sie durch diese beiden Dateien führen und Sie können loslegen.

Schleife

Was es tut:  Jedes Mal loop() führt es aus und prüft, ob wir einen Befehl von der seriellen Schnittstelle haben, indem er getCommandLineFromSerialPort() . aufruft . Die Variable CommandLine ist in CommandLine.h declared deklariert aber stilistisch möchten Sie es vielleicht auf den Haupt-Loop-Tab verschieben. Wenn ein vollständiger Befehl an der seriellen Schnittstelle angekommen ist und in den Befehlspuffer kopiert wurde:

        char   commandLine[COMMAND_BUFFER_LENGTH + 1]; 

Dann loop() ruft DoMyCommand() . auf um den richtigen Befehl auszuführen.

Schauen wir uns nun an, was in CommandLine.h steht . Ich sollte darauf hinweisen, dass ich den gesamten Code in CommandLine.h eingefügt habe , denn dann müssen Sie diesen Code nur noch ausschneiden und in eine neue Registerkarte in Ihrer Arduino IDE einfügen (achten Sie darauf, der Registerkarte einen Namen zu geben, der mit ".h . endet.) "). Fügen Sie diese Datei dann in Ihre Hauptdatei ein, d. h.

 #include "CommandLine.h" 

Dies ermöglicht Ihnen, den gesamten Befehlszeilencode auf einer Registerkarte abzulegen und dennoch an anderer Stelle in Ihrem Programm ohne zusätzlichen Code auf seine Routinen zu verweisen.

Suche in CommandLine.h

Die Datei CommandLine.h steht am Ende dieses Beitrags. Innerhalb von CommandLine.h , jede Zeile, die Sie ändern müssen, ist mit dem Kommentar gekennzeichnet, //Hier ändern . Die Datei enthält zwei Beispielbefehle add und sub und zeigt, wie sie innerhalb von DoMyCommand . aufgerufen werden .

Für viele von Ihnen ist das alles, was Sie brauchen. Gehen Sie einfach durch CommandLine.h . Für diejenigen, die einen genaueren Blick wünschen, lesen Sie weiter.

Tiefer schauen

Innerhalb von CommandLine.h Zuerst fügen wir . ein . String.h ist eine C-Standardbibliothek . Wenn Sie noch nie auf C-Bibliotheken gestoßen sind, führen Sie eine schnelle Internetsuche nach "The C Programming Language" durch. Die C-Bibel wurde vor Jahren von Brian Kernigan und Dennis Ritchie geschrieben und wird immer aktuell gehalten. Die meisten Leute besitzen eine Kopie, aber Sie können sie kostenlos online finden.

Wir verwenden nur die strtok() Routine (String zu Token) von . Diese Routine liest ein Token, d. h. ein Wort, das durch bestimmte Zeichen begrenzt ist (der zweite Parameter von strtok ). Es funktioniert so.

  • Wenn Sie es zum ersten Mal aufrufen, übergeben Sie ihm eine Zeichenfolge ptr und es wird das erste Token zurückgeben
  • Bei nachfolgenden Aufrufen (hier kommt der glorreiche Hack-Teil) übergeben Sie es NULL anstelle einer Zeichenfolge ptr und es wird dort weitermachen, wo es mit der Anfangszeichenfolge aufgehört hat, wodurch jeweils ein Token (ungefähr ein Wort) erhalten wird.

Wir fügen auch . hinzu von denen wir nur atoi() . verwenden für die Umwandlung von ASCII in ganze Zahlen. Machen Sie sich keine Sorgen, der Compiler enthält nur diese eine Routine, nicht die gesamte Bibliothek, aber Sie sollten sich die anderen Routinen in diesen Bibliotheken ansehen, da sie nützlich sind.

Als nächstes habe ich ein optionales kleines Makro namens print2: . geschrieben

#define print2(x,y) (Serial.print(x), Serial.println(y) 

Ich möchte immer ein Etikett und eine Zeichenfolge ausdrucken. Sie verwenden es so:

print2("myVar =", myVar); 

Wenn myVar 25 ist, wird dies im seriellen Fenster gedruckt:

myVar =25 

CommandLine.h enthält getCommandLineFromSerialPort() die eine Befehlszeile von der seriellen Schnittstelle zusammenstellt. Bei jedem Aufruf liest es vom seriellen Port und speichert die Eingabe im globalen Eingabepuffer, CommandLine[] . Wenn es eine Rückgabe erreicht Zeichen, das das Ende des Befehls anzeigt, es gibt true . zurück .

Der fertig zusammengestellte Puffer wird nun an DoMyCommand() . übergeben die herausfindet, welche Funktion der Benutzer anfordert und aufruft. Mit einer großen Anzahl von Befehlen können Sie eine ziemlich unhandliche if-the-else-Anweisung erhalten.

Wenn Sie eine wirklich enorme Anzahl von Befehlen haben, gibt es viele Möglichkeiten, dies zu beschleunigen, z. B. die Übernahme einer sogenannten Hashing-Funktion. Alternativ können Sie den Befehlen nur ein Zeichen geben und dieses eine Zeichen dann als Label einer switch-case-Anweisung verwenden. Ich finde keines von beiden ist sehr oft notwendig. Ein Wort ist viel einfacher zu merken als ein einzelnes Zeichen und da dies ein Arduino ist, wie viele Befehle können Sie wirklich haben, bevor der Platz auf dem Chip ausgeht?

Hinzufügen und Abonnieren

Jede Befehlsfunktion ist dafür verantwortlich, ihre eigenen Argumente auszuwerten. Dies ist eine einfache Möglichkeit, dies zu ändern und leicht zu ändern. Eine Alternative dazu ist das sofortige Lesen aller Argumente in DoMyCommand . Sie könnten einzelne Argumente in ein globales Array von Strings einfügen argv[] .

Für dieses Beispiel habe ich zwei Befehle definiert:add und sub . Beide verwenden numerische Argumente, aber ich habe readWord . eingefügt (was als readStringToken bezeichnet werden könnte ), um ein Wort zurückzugeben. Sie können dieses readStringToken auch ändern um Zeichenfolgen wie "dies ist eine Zeichenfolge . zuzulassen ". Betrachten Sie es als eine Übung, die dem Leser überlassen wird.

Der schnellste Weg zum Laufen

Wenn Sie eine Hauptschleifendatei wie oben gezeigt haben, erstellen Sie eine neue Registerkarte mit dem nach unten zeigenden Dreieck rechts in Ihrem Arduino IDE-Fenster und kopieren Sie CommandLine.h (unten) Datei hinein, Sie sollten in der Lage sein, add . einzutippen und sub Befehle.

Jetzt liegt es an dir!

Code

  • Einfacher Befehlszeilen-Interpreter für Arduino
Einfacher Befehlszeilen-Interpreter für ArduinoC/C++
Sehen Sie sich die Kommentare in diesem Artikel oder im Code an, um Ihrer Arduino-Skizze eine einfache Befehlszeile hinzuzufügen.

Sie können Befehle wie diese hinzufügen:
5, 10 . hinzufügen
subtrahiere 10, 5

Oder alles andere was du brauchst
/******************************************** ********************************** So verwenden Sie die Befehlszeile:Erstellen Sie eine Skizze. Suchen Sie unten nach einem Beispiel-Setup und einem Hauptschleifencode und kopieren Sie ihn und fügen Sie ihn in die neue Skizze ein. Erstellen Sie eine neue Registerkarte. (Verwenden Sie das Dropdown-Menü (kleines Dreieck) ganz rechts im Arduino-Editor. Benennen Sie die Registerkarte CommandLine.h Fügen Sie diese Datei dort ein. Test:Laden Sie die soeben erstellte Skizze wie gewohnt auf Ihr Arduino herunter und öffnen Sie das serielle Fenster. Geben Sie diese Befehle ein, gefolgt von Return:add 5, 10 subtract 10, 5 Sehen Sie sich die enthaltenen Add- und Subtract-Befehle an und schreiben Sie dann Ihre eigenen!************************ ************************************************* ***** Hier ist, was unter der Decke passiert ************************************* **************************************** Einfacher und klarer Befehlszeileninterpreter Diese Datei ermöglicht Geben Sie Befehle in das serielle Fenster ein, fügen Sie 23.599 blink 5 playSong Yesterday zu Ihrem auf dem Arduino laufenden Sketch hinzu und führen Sie sie aus.Implementierungshinweis:Dies verwendet C-Strings im Gegensatz zu String-Objekten, basierend auf der Annahme, dass Sie eine Befehlszeile benötigen Interpreter, haben Sie wahrscheinlich auch wenig Platz und das String-Objekt neigt dazu, Platz ineffizient zu sein. 1) Einfache Protokollbefehle sind Wörter und Zahlen, entweder durch Leerzeichen oder durch Kommas getrennt Das erste Wort ist der Befehl, jedes weitere Wort ist ein Argument "\n" beendet jeden Befehl 2) Verwendung der C-Bibliotheksroutine strtok:Ein Befehl ist ein Wort, das durch getrennt ist Leerzeichen oder Kommas. Ein Wort, das durch bestimmte Zeichen (wie Leerzeichen oder Komma) getrennt ist, wird als Token bezeichnet. Um Token nacheinander abzurufen, verwende ich das C lib-Routing-Strtok (Teil von C stdlib.h siehe unten, wie man es einbindet). Es ist Teil der C-Sprachbibliothek , die Sie online nachschlagen können. Grundsätzlich:1) Übergeben Sie ihm eine Zeichenfolge (und die von Ihnen verwendeten Trennzeichen, dh Leerzeichen und Komma) und es wird das erste Token aus der Zeichenfolge zurückgegeben 2) bei nachfolgenden Aufrufen übergeben Sie es NULL (anstelle der Zeichenfolge ptr) und es wird Fahren Sie dort mit der Anfangszeichenfolge fort, wo sie aufgehört hat. Ich habe ein paar grundlegende Hilfsroutinen geschrieben:readNumber:verwendet strtok und atoi (atoi:ascii to int, wiederum Teil von C stdlib.h), um eine ganze Zahl zurückzugeben. Beachten Sie, dass atoi ein Int zurückgibt und wenn Sie 1-Byte-Ints wie uint8_t verwenden, müssen Sie das lowByte() abrufen. readWord:gibt einen ptr zu einem Textwort zurück 4) DoMyCommand:Eine Liste von if-then-elses für jeden Befehl. Sie könnten dies zu einer case-Anweisung machen, wenn alle Befehle ein einzelnes Zeichen wären. Die Verwendung eines Wortes ist besser lesbar. Für die Zwecke dieses Beispiels haben wir:Add Subtract nullCommand*//********************Beispiel-Hauptschleifencode ************ ********************** #include "CommandLine.h" void setup () { Serial.begin (115200); aufrechtzuerhalten. Void Schleife () { bool empfangen =getCommandLineFromSerialPort (CommandLine); //globale CommandLine ist in CommandLine.h definiert if (received) DoMyCommand(CommandLine); }**************************************************** ********************************* ///Benennen Sie diese Registerkarte:CommandLine.h#include  #include //das folgende Makro ist gut zum Debuggen, zB print2("myVar=", myVar);#define print2(x,y) (Serial.print(x), Serial.println(y))#define CR '\r'#define LF '\n'#define BS '\b'#define NULLCHAR '\0'#define SPACE ' '#define COMMAND_BUFFER_LENGTH 25 //Länge des seriellen Puffers für eingehende Befehlechar CommandLine[COMMAND_BUFFER_LENGTH + 1]; // Befehle von Serial in diesen Puffer lesen. +1 Länge für eine Beendigung charconst char *delimiters =", \n"; //Befehle können durch Return, Leerzeichen oder Komma getrennt werden/**************************************** ************************************************* ********************* Ihre Befehlsnamen hier*/const char *addCommandToken ="add"; //Ändere hierconst char *subtractCommandToken ="sub"; //Hier ändern/************************************************ ************************************************* ************** getCommandLineFromSerialPort() Gibt den String des nächsten Befehls zurück. Befehle werden durch Return" getrennt. Backspace-Zeichen behandeln Alle Zeichen in Kleinbuchstaben umwandeln**************************************** ************************************************* *********************/boolgetCommandLineFromSerialPort(char * commandLine){ static uint8_t charsRead =0; //Hinweis:COMAND_BUFFER_LENGTH muss kürzer als 255 Zeichen sein // asynchron lesen bis vollständige Befehlseingabe while (Serial.available ()) { char c =Serial.read (); switch (c) { case CR:// wahrscheinlich jetzt den vollständigen Befehl im Puffer haben, Befehle werden durch CR beendet und/oder LS case LF:commandLine[charsRead] =NULLCHAR; //null unser Befehls-Char-Array beenden if (charsRead> 0) { charsRead =0; //charsRead ist statisch, also muss Serial.println(commandLine) zurückgesetzt werden; return true; } break; case BS:// Backspace in der Eingabe behandeln:Leerzeichen in letztes Zeichen einfügen if (charsRead> 0) { //und commandLine und charsRead anpassen commandLine[--charsRead] =NULLCHAR; Serial < Die Summe ist =", Ergebnis); } else { if (strcmp(ptrToCommandName, subtractCommandToken) ==0) { //Hier ändern result =subtractCommand(); //K&R string.h pg. 251 print2("> Der Unterschied ist =", Ergebnis); aufrechtzuerhalten. Else { nullCommand (ptrToCommandName); } }}

Herstellungsprozess

  1. C#-Kommentare
  2. C#-Schnittstelle
  3. Java-Schnittstelle
  4. Schnittstelle zum drahtlosen Einfahrtssensor
  5. Ein einfacher analoger Näherungssensor mit digitaler Schnittstelle (für Raspberry Pi) [letztes Update:7. Februar 2014]
  6. ANDY:Ein "humanoider" Mehrzweckroboter
  7. Einfacher Pi-Roboter
  8. C - Befehlszeilenargumente
  9. C# - Schnittstellen
  10. Was ist eine Stahlspulen-Längsteilanlage?