Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Eenvoudige opdrachtregelinterface

Componenten en benodigdheden

Arduino UNO
× 1

Over dit project

Opdrachtregel

Er komt een moment dat je de waarde van een sensor moet vinden of je wilt je robot vertellen iets te doen als "naar links gaan". Misschien moet u uw programma om de runtime-waarde van een variabele vragen, of u moet de waarde van een digitale potentiometer instellen.

Wat je nodig hebt, is een opdrachtregel. Ja, het is gemakkelijk om uw Arduino te laten reageren op tekstcommando's.

Hier is er een waar je op kunt bouwen. Het is een eenvoudige, snelle en zeer geheugenefficiënte Command Line Interface (CLI) die u in een paar minuten in uw eigen code kunt knippen en plakken en aan de slag kunt. Commando's bestaan ​​uit een naam gevolgd door meerdere argumenten. Het ondersteunt zelfs backspace wanneer je je commando's typt.  

Snel overzicht

Elke schets heeft een loop() functie. De jouwe kan net zo eenvoudig zijn als die hieronder. Het roept twee routines aan op een apart tabblad met de naam CommandLine.h . Ik zal je door deze twee bestanden leiden en je kunt aan de slag.

Loop

Wat het doet:  Elke keer loop() voert het uit om te zien of we een opdracht van de seriële poort hebben, die getCommandLineFromSerialPort() aanroept . De variabele CommandLine wordt gedeclareerd in CommandLine.h maar stilistisch wil je het misschien naar het hoofdlus-tabblad verplaatsen. Wanneer een volledige opdracht is aangekomen op de seriële poort en is gekopieerd naar de opdrachtbuffer:

        char   commandLine[COMMAND_BUFFER_LENGTH + 1]; 

Dan loop() roept DoMyCommand() . aan om de juiste opdracht uit te voeren.

Laten we nu eens kijken wat er in CommandLine.h staat . Ik moet erop wijzen dat ik alle code in CommandLine.h . heb gezet , want dan hoef je deze code alleen maar te knippen en in een nieuw tabblad in je Arduino IDE te plakken (zorg ervoor dat je het tabblad een naam geeft die eindigt op ".h "). Voeg dit bestand dan toe aan uw hoofdbestand, d.w.z.

 #include "CommandLine.h" 

Wat dit doet, is dat u alle opdrachtregelcode op één tabblad kunt plaatsen en toch zonder extra code naar de routines elders in uw programma kunt verwijzen.

Zoeken in CommandLine.h

Het bestand CommandLine.h staat aan het einde van dit bericht. Binnen CommandLine.h , elke regel die u moet wijzigen, is gemarkeerd met de opmerking, //Hier wijzigen . Het bestand bevat twee voorbeeldopdrachten add en sub en laat zien hoe ze worden aangeroepen vanuit DoMyCommand .

Voor velen van jullie is dat alles wat je nodig hebt. Ga gewoon door CommandLine.h . Voor degenen die een meer gedetailleerde kijk willen, blijf lezen.

Dieper kijken

Binnen CommandLine.h we nemen eerst . op . String.h is een C-standaardbibliotheek . Als u C-bibliotheken nog niet eerder bent tegengekomen, zoek dan snel op internet naar "De C-programmeertaal". De C-bijbel is jaren geleden geschreven door Brian Kernigan en Dennis Ritchie en is up-to-date gehouden. De meeste mensen hebben een exemplaar, maar u kunt het gratis online vinden.

We gebruiken alleen de strtok() routine (string naar token) van . Deze routine leest een token, dat wil zeggen een woord dat wordt begrensd door bepaalde tekens (de tweede parameter van strtok ). Het werkt als volgt.

  • Als je het voor het eerst aanroept, geef je het een tekenreeks ptr en het zal het eerste token teruggeven
  • Bij volgende oproepen (hier komt het glorieuze hackgedeelte) geef het NULL door in plaats van een string ptr en het gaat verder waar het was gebleven met de eerste tekenreeks, en krijgt zo één token (ongeveer een woord) per keer.

We hebben ook waarvan we alleen atoi() . gebruiken voor ascii-naar-geheel-conversie. Maak je geen zorgen, de compiler zal alleen deze ene routine bevatten, niet de hele bibliotheek, maar misschien wil je de andere routines in deze bibliotheken bekijken, omdat ze nuttig zijn.

De volgende is een optionele kleine macro die ik heb geschreven met de naam print2:

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

Ik wil altijd een label en een string uitprinten. Je gebruikt het als volgt:

print2("myVar =", mijnVar); 

Als myVar 25 is, wordt dit afgedrukt naar het seriële venster:

mijnVar =25 

CommandLine.h bevat getCommandLineFromSerialPort() die een opdrachtregel van de seriële poort assembleert. Elke keer dat het wordt aangeroepen, leest het van de seriële poort en slaat het de invoer op in de globale invoerbuffer, CommandLine[] . Wanneer het een retour bereikt teken dat het einde van het commando aangeeft en het geeft true . terug .

De volledig geassembleerde buffer wordt nu doorgegeven aan DoMyCommand() die uitzoekt welke functie de gebruiker vraagt ​​en deze aanroept. Met een groot aantal commando's kun je een vrij onpraktische if-the-else-statement krijgen.

Als je echt een enorm aantal commando's hebt, zijn er veel manieren om dingen te versnellen, zoals het adopteren van een zogenaamde hash-functie. Als alternatief kunt u van de opdrachten slechts één teken maken en dat ene teken vervolgens gebruiken als het label van een switch-case-statement. Ik vind dat geen van beide vaak nodig is. Een woord is veel gemakkelijker te onthouden dan een enkel teken en aangezien dit een Arduino is, hoeveel commando's kun je echt hebben voordat je ruimte op de chip opraakt?

Toevoegen en Sub

Elke opdrachtfunctie is verantwoordelijk voor het ontleden van zijn eigen argumenten. Dit is een eenvoudige manier om het te doen en is gemakkelijk genoeg om aan te passen. Een alternatief hiervoor is om alle argumenten onmiddellijk te lezen in DoMyCommand . Je zou individuele argumenten in een globale array van strings kunnen plaatsen argv[] .

Voor dit voorbeeld heb ik twee commando's gedefinieerd:add en sub . Beide gebruiken numerieke argumenten, maar ik heb readWord . toegevoegd (die zou kunnen worden genoemd readStringToken ) om een ​​woord terug te geven. U kunt deze readStringToken ook aanpassen om tekenreeksen toe te staan ​​zoals "dit is een tekenreeks ". Beschouw het als een oefening voor de lezer.

De snelste manier om te rennen

Als je een hoofdlusbestand hebt zoals hierboven weergegeven, maak dan een nieuw tabblad aan met behulp van de naar beneden wijzende driehoek aan de rechterkant van je Arduino IDE-venster, en kopieer CommandLine.h (hieronder) bestand erin, zou je in staat moeten zijn om add . te typen en sub commando's.

Nu is het aan jou!

Code

  • Eenvoudige opdrachtregelinterpreter voor Arduino
Eenvoudige opdrachtregelinterpreter voor ArduinoC/C++
Zie de opmerkingen in dit artikel of in de code om een ​​eenvoudige opdrachtregel aan je Arduino-schets toe te voegen.

U kunt als volgt opdrachten toevoegen:
voeg 5, 10 . toe
aftrekken 10, 5

Of iets anders dat je nodig hebt
/********************************************* *********************************** Hoe CommandLine te gebruiken:Maak een schets. Kijk hieronder voor een voorbeeldopstelling en hoofdluscode en kopieer en plak deze in de nieuwe schets. Maak een nieuw tabblad. (Gebruik het vervolgkeuzemenu (driehoekje) uiterst rechts van de Arduino-editor. Noem het tabblad CommandLine.h Plak dit bestand erin. Test:download de schets die u zojuist hebt gemaakt naar uw Arduino zoals gewoonlijk en open het seriële venster. Typ deze commando's gevolgd door return:optellen 5, 10 aftrekken 10, 5 Kijk naar de optel- en aftrekcommando's die zijn opgenomen en schrijf dan je eigen!************************* ********************************************** ****** Dit is wat er onder de dekens gebeurt ************************************ **************************************** Eenvoudige en duidelijke opdrachtregelinterpreter Dit bestand zal toestaan:je typt commando's in het seriële venster zoals, voeg 23.599 blink 5 playSong Yesterday toe aan je schets die op de Arduino draait en voer ze uit. Implementatie opmerking:dit zal C strings gebruiken in tegenstelling tot String Objects gebaseerd op de veronderstelling dat als je een commandLine nodig hebt interpreter, je hebt waarschijnlijk ook een tekort aan ruimte en het String-object is meestal ruimte-inefficiënt. 1) Eenvoudige protocolcommando's zijn woorden en getallen met spatie of komma's Het eerste woord is het commando, elk extra woord is een argument "\n" beëindigt elk commando 2) Gebruik van de C-bibliotheekroutine strtok:Een commando is een woord gescheiden door spaties of komma's. Een woord gescheiden door bepaalde tekens (zoals spatie of komma) wordt een token genoemd. Om tokens één voor één te krijgen, gebruik ik de C lib routing strtok (onderdeel van C stdlib.h zie hieronder hoe je het kunt opnemen). Het maakt deel uit van de C-taalbibliotheek  die u online kunt opzoeken. In principe:1) geef het een tekenreeks door (en de scheidingstekens die u gebruikt, dwz spatie en komma) en het zal het eerste token van de tekenreeks retourneren 2) bij volgende oproepen, geef het NULL door (in plaats van de tekenreeks ptr) en het zal ga verder waar het was gebleven met de eerste tekenreeks. Ik heb een aantal basishulproutines geschreven:readNumber:gebruikt strtok en atoi (atoi:ascii naar int, weer onderdeel van C stdlib.h) om een ​​geheel getal te retourneren. Merk op dat atoi een int retourneert en als je 1 byte ints gebruikt zoals uint8_t, moet je de lowByte() krijgen. readWord:retourneert een ptr naar een tekstwoord 4) DoMyCommand:Een lijst met als-dan-anders voor elk commando. Je zou hier een case-statement van kunnen maken als alle commando's een enkele char waren. Het gebruik van een woord is beter leesbaar. Voor de doeleinden van dit voorbeeld hebben we:Add Subtract nullCommand*//******************voorbeeld hoofdluscode *********** ********************* #include "CommandLine.h" void setup() { Serial.begin(115200); } void loop () { bool ontvangen =getCommandLineFromSerialPort (CommandLine); //global CommandLine is gedefinieerd in CommandLine.h indien (ontvangen) DoMyCommand(CommandLine); }************************************************** *******************************/// Noem dit tabblad:CommandLine.h#include  #include //deze volgende macro is goed voor foutopsporing, bijv. 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 //lengte van seriële buffer voor binnenkomende commandschar CommandLine[COMMAND_BUFFER_LENGTH + 1]; //Lees commando's in deze buffer vanuit Serial. +1 in lengte voor een beëindiging charconst char *delimiters =", \n"; //commando's kunnen worden gescheiden door return, spatie of komma/**************************************** ********************************************** ********************* uw opdrachtnamen hier*/const char *addCommandToken ="add"; // Wijzig hereconst char *subtractCommandToken ="sub"; // Wijzig hier/********************************************* ********************************************** *************** getCommandLineFromSerialPort() Retourneert de tekenreeks van de volgende opdracht. Commando's worden gescheiden door return" Handvat BackSpace-teken Maak alle tekens in kleine letters**************************************** ********************************************** **********************/boolgetCommandLineFromSerialPort(char * commandLine){ static uint8_t charsRead =0; //opmerking:COMAND_BUFFER_LENGTH moet minder dan 255 tekens lang zijn // lees asynchroon tot volledige opdrachtinvoer while (Serial.available()) {char c =Serial.read(); switch (c) { case CR:// heb waarschijnlijk nu de volledige opdracht in buffer, opdrachten worden beëindigd door CR en/of LS case LF:commandLine [charsRead] =NULLCHAR; //null beëindigt onze opdracht char array if (charsRead> 0) {charsRead =0; //charsRead is statisch, dus moet Serial.println (commandLine) opnieuw worden ingesteld; return true; } break; case BS:// handle backspace in input:plaats een spatie in last char if (charsRead> 0) { //and pas commandLine en charsRead commandLine [--charsRead] =NULLCHAR; Serial < De som is =", resultaat); } else {if (strcmp(ptrToCommandName, subtractCommandToken) ==0) {//Hier aanpassen resultaat =subtractCommand (); //K&R string.h pag. 251 print2("> Het verschil is =", resultaat); } else { nullCommand(ptrToCommandName); } }}

Productieproces

  1. C# Opmerkingen
  2. C#-interface
  3. Java-interface
  4. Interface naar draadloze opritsensor
  5. Een eenvoudige analoge naderingssensor met digitale interface (voor Raspberry Pi) [laatste update:7 februari 2014]
  6. ANDY:een multifunctionele "humanoïde" robot
  7. Simple Pi Robot
  8. C - Commandoregelargumenten
  9. C# - Interfaces
  10. Wat is Steel Coil snijlijn?
  11. Op lengte gesneden lijnfabrikanten in één oogopslag