Components and supplies
Arduino UNO
Project description
Code
Simple Command Line Interpreter for Arduino
c_cpp
See the comments in this article or in the code to add a simple command line to your Arduino sketch. You can add commands like this: add 5, 10 subtract 10, 5 Or anything else you need
1/***************************************************************************** 2 3 How to Use CommandLine: 4 Create a sketch. Look below for a sample setup and main loop code and copy and paste it in into the new sketch. 5 6 Create a new tab. (Use the drop down menu (little triangle) on the far right of the Arduino Editor. 7 Name the tab CommandLine.h 8 Paste this file into it. 9 10 Test: 11 Download the sketch you just created to your Arduino as usual and open the Serial Window. Typey these commands followed by return: 12 add 5, 10 13 subtract 10, 5 14 15 Look at the add and subtract commands included and then write your own! 16 17 18***************************************************************************** 19 Here's what's going on under the covers 20***************************************************************************** 21 Simple and Clear Command Line Interpreter 22 23 This file will allow you to type commands into the Serial Window like, 24 add 23,599 25 blink 5 26 playSong Yesterday 27 28 to your sketch running on the Arduino and execute them. 29 30 Implementation note: This will use C strings as opposed to String Objects based on the assumption that if you need a commandLine interpreter, 31 you are probably short on space too and the String object tends to be space inefficient. 32 33 1) Simple Protocol 34 Commands are words and numbers either space or comma spearated 35 The first word is the command, each additional word is an argument 36 "\ 37" terminates each command 38 39 2) Using the C library routine strtok: 40 A command is a word separated by spaces or commas. A word separated by certain characters (like space or comma) is called a token. 41 To get tokens one by one, I use the C lib routing strtok (part of C stdlib.h see below how to include it). 42 It's part of C language library <string.h> which you can look up online. Basically you: 43 1) pass it a string (and the delimeters you use, i.e. space and comman) and it will return the first token from the string 44 2) on subsequent calls, pass it NULL (instead of the string ptr) and it will continue where it left off with the initial string. 45 I've written a couple of basic helper routines: 46 readNumber: uses strtok and atoi (atoi: ascii to int, again part of C stdlib.h) to return an integer. 47 Note that atoi returns an int and if you are using 1 byte ints like uint8_t you'll have to get the lowByte(). 48 readWord: returns a ptr to a text word 49 50 4) DoMyCommand: A list of if-then-elses for each command. You could make this a case statement if all commands were a single char. 51 Using a word is more readable. 52 For the purposes of this example we have: 53 Add 54 Subtract 55 nullCommand 56*/ 57/******************sample main loop code ************************************ 58 59 #include "CommandLine.h" 60 61 void 62 setup() { 63 Serial.begin(115200); 64 } 65 66 void 67 loop() { 68 bool received = getCommandLineFromSerialPort(CommandLine); //global CommandLine is defined in CommandLine.h 69 if (received) DoMyCommand(CommandLine); 70 } 71 72**********************************************************************************/ 73 74//Name this tab: CommandLine.h 75 76#include <string.h> 77#include <stdlib.h> 78 79//this following macro is good for debugging, e.g. print2("myVar= ", myVar); 80#define print2(x,y) (Serial.print(x), Serial.println(y)) 81 82 83#define CR '\r' 84#define LF '\n' 85#define BS '\\b' 86#define NULLCHAR '\\0' 87#define SPACE ' ' 88 89#define COMMAND_BUFFER_LENGTH 25 //length of serial buffer for incoming commands 90char CommandLine[COMMAND_BUFFER_LENGTH + 1]; //Read commands into this buffer from Serial. +1 in length for a termination char 91 92const char *delimiters = ", \ 93"; //commands can be separated by return, space or comma 94 95/************************************************************************************************************* 96 your Command Names Here 97*/ 98const char *addCommandToken = "add"; //Modify here 99const char *subtractCommandToken = "sub"; //Modify here 100 101 102/************************************************************************************************************* 103 getCommandLineFromSerialPort() 104 Return the string of the next command. Commands are delimited by return" 105 Handle BackSpace character 106 Make all chars lowercase 107*************************************************************************************************************/ 108 109bool 110getCommandLineFromSerialPort(char * commandLine) 111{ 112 static uint8_t charsRead = 0; //note: COMAND_BUFFER_LENGTH must be less than 255 chars long 113 //read asynchronously until full command input 114 while (Serial.available()) { 115 char c = Serial.read(); 116 switch (c) { 117 case CR: //likely have full command in buffer now, commands are terminated by CR and/or LS 118 case LF: 119 commandLine[charsRead] = NULLCHAR; //null terminate our command char array 120 if (charsRead > 0) { 121 charsRead = 0; //charsRead is static, so have to reset 122 Serial.println(commandLine); 123 return true; 124 } 125 break; 126 case BS: // handle backspace in input: put a space in last char 127 if (charsRead > 0) { //and adjust commandLine and charsRead 128 commandLine[--charsRead] = NULLCHAR; 129 Serial << byte(BS) << byte(SPACE) << byte(BS); //no idea how this works, found it on the Internet 130 } 131 break; 132 default: 133 // c = tolower(c); 134 if (charsRead < COMMAND_BUFFER_LENGTH) { 135 commandLine[charsRead++] = c; 136 } 137 commandLine[charsRead] = NULLCHAR; //just in case 138 break; 139 } 140 } 141 return false; 142} 143 144 145/* **************************** 146 readNumber: return a 16bit (for Arduino Uno) signed integer from the command line 147 readWord: get a text word from the command line 148 149*/ 150int 151readNumber () { 152 char * numTextPtr = strtok(NULL, delimiters); //K&R string.h pg. 250 153 return atoi(numTextPtr); //K&R string.h pg. 251 154} 155 156char * readWord() { 157 char * word = strtok(NULL, delimiters); //K&R string.h pg. 250 158 return word; 159} 160 161void 162nullCommand(char * ptrToCommandName) { 163 print2("Command not found: ", ptrToCommandName); //see above for macro print2 164} 165 166 167/**************************************************** 168 Add your commands here 169*/ 170 171int addCommand() { //Modify here 172 int firstOperand = readNumber(); 173 int secondOperand = readNumber(); 174 return firstOperand + secondOperand; 175} 176 177int subtractCommand() { //Modify here 178 int firstOperand = readNumber(); 179 int secondOperand = readNumber(); 180 return firstOperand - secondOperand; 181} 182 183/**************************************************** 184 DoMyCommand 185*/ 186bool 187DoMyCommand(char * commandLine) { 188 // print2("\ 189Command: ", commandLine); 190 int result; 191 192 char * ptrToCommandName = strtok(commandLine, delimiters); 193 // print2("commandName= ", ptrToCommandName); 194 195 if (strcmp(ptrToCommandName, addCommandToken) == 0) { //Modify here 196 result = addCommand(); 197 print2("> The sum is = ", result); 198 199 } else { 200 if (strcmp(ptrToCommandName, subtractCommandToken) == 0) { //Modify here 201 result = subtractCommand(); //K&R string.h pg. 251 202 print2("> The difference is = ", result); 203 204 } else { 205 nullCommand(ptrToCommandName); 206 } 207 } 208}
Comments
Only logged in users can leave comments
mikefarr
0 Followers
•0 Projects
Table of contents
Intro
8
0