Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.61 KB | None | 0 0
  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. "\n" terminates each command
  37.  
  38. 2) Using the C library routine strtok:
  39. A command is a word separated by spaces or commas. A word separated by certain characters (like space or comma) is called a token.
  40. To get tokens one by one, I use the C lib routing strtok (part of C stdlib.h see below how to include it).
  41. It's part of C language library <string.h> which you can look up online. Basically you:
  42. 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
  43. 2) on subsequent calls, pass it NULL (instead of the string ptr) and it will continue where it left off with the initial string.
  44. I've written a couple of basic helper routines:
  45. readNumber: uses strtok and atoi (atoi: ascii to int, again part of C stdlib.h) to return an integer.
  46. Note that atoi returns an int and if you are using 1 byte ints like uint8_t you'll have to get the lowByte().
  47. readWord: returns a ptr to a text word
  48.  
  49. 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.
  50. Using a word is more readable.
  51. For the purposes of this example we have:
  52. Add
  53. Subtract
  54. nullCommand
  55. */
  56. /******************sample main loop code ************************************
  57.  
  58. #include "CommandLine.h"
  59.  
  60. void
  61. setup() {
  62. Serial.begin(115200);
  63. }
  64.  
  65. void
  66. loop() {
  67. bool received = getCommandLineFromSerialPort(CommandLine); //global CommandLine is defined in CommandLine.h
  68. if (received) DoMyCommand(CommandLine);
  69. }
  70.  
  71. **********************************************************************************/
  72.  
  73. //Name this tab: CommandLine.h
  74.  
  75. #include <string.h>
  76. #include <stdlib.h>
  77.  
  78. //this following macro is good for debugging, e.g. print2("myVar= ", myVar);
  79. #define print2(x,y) (Serial.print(x), Serial.println(y))
  80.  
  81.  
  82. #define CR '\r'
  83. #define LF '\n'
  84. #define BS '\b'
  85. #define NULLCHAR '\0'
  86. #define SPACE ' '
  87.  
  88. #define COMMAND_BUFFER_LENGTH 25 //length of serial buffer for incoming commands
  89. char CommandLine[COMMAND_BUFFER_LENGTH + 1]; //Read commands into this buffer from Serial. +1 in length for a termination char
  90.  
  91. const char *delimiters = ", \n"; //commands can be separated by return, space or comma
  92.  
  93. /*************************************************************************************************************
  94. your Command Names Here
  95. */
  96. const char *addCommandToken = "add"; //Modify here
  97. const char *subtractCommandToken = "sub"; //Modify here
  98.  
  99.  
  100. /*************************************************************************************************************
  101. getCommandLineFromSerialPort()
  102. Return the string of the next command. Commands are delimited by return"
  103. Handle BackSpace character
  104. Make all chars lowercase
  105. *************************************************************************************************************/
  106.  
  107. bool
  108. getCommandLineFromSerialPort(char * commandLine)
  109. {
  110. static uint8_t charsRead = 0; //note: COMAND_BUFFER_LENGTH must be less than 255 chars long
  111. //read asynchronously until full command input
  112. while (Serial.available()) {
  113. char c = Serial.read();
  114. switch (c) {
  115. case CR: //likely have full command in buffer now, commands are terminated by CR and/or LS
  116. case LF:
  117. commandLine[charsRead] = NULLCHAR; //null terminate our command char array
  118. if (charsRead > 0) {
  119. charsRead = 0; //charsRead is static, so have to reset
  120. Serial.println(commandLine);
  121. return true;
  122. }
  123. break;
  124. case BS: // handle backspace in input: put a space in last char
  125. if (charsRead > 0) { //and adjust commandLine and charsRead
  126. commandLine[--charsRead] = NULLCHAR;
  127. Serial << byte(BS) << byte(SPACE) << byte(BS); //no idea how this works, found it on the Internet
  128. }
  129. break;
  130. default:
  131. // c = tolower(c);
  132. if (charsRead < COMMAND_BUFFER_LENGTH) {
  133. commandLine[charsRead++] = c;
  134. }
  135. commandLine[charsRead] = NULLCHAR; //just in case
  136. break;
  137. }
  138. }
  139. return false;
  140. }
  141.  
  142.  
  143. /* ****************************
  144. readNumber: return a 16bit (for Arduino Uno) signed integer from the command line
  145. readWord: get a text word from the command line
  146.  
  147. */
  148. int
  149. readNumber () {
  150. char * numTextPtr = strtok(NULL, delimiters); //K&R string.h pg. 250
  151. return atoi(numTextPtr); //K&R string.h pg. 251
  152. }
  153.  
  154. char * readWord() {
  155. char * word = strtok(NULL, delimiters); //K&R string.h pg. 250
  156. return word;
  157. }
  158.  
  159. void
  160. nullCommand(char * ptrToCommandName) {
  161. print2("Command not found: ", ptrToCommandName); //see above for macro print2
  162. }
  163.  
  164.  
  165. /****************************************************
  166. Add your commands here
  167. */
  168.  
  169. int addCommand() { //Modify here
  170. int firstOperand = readNumber();
  171. int secondOperand = readNumber();
  172. return firstOperand + secondOperand;
  173. }
  174.  
  175. int subtractCommand() { //Modify here
  176. int firstOperand = readNumber();
  177. int secondOperand = readNumber();
  178. return firstOperand - secondOperand;
  179. }
  180.  
  181. /****************************************************
  182. DoMyCommand
  183. */
  184. bool
  185. DoMyCommand(char * commandLine) {
  186. // print2("\nCommand: ", commandLine);
  187. int result;
  188.  
  189. char * ptrToCommandName = strtok(commandLine, delimiters);
  190. // print2("commandName= ", ptrToCommandName);
  191.  
  192. if (strcmp(ptrToCommandName, addCommandToken) == 0) { //Modify here
  193. result = addCommand();
  194. print2("> The sum is = ", result);
  195.  
  196. } else {
  197. if (strcmp(ptrToCommandName, subtractCommandToken) == 0) { //Modify here
  198. result = subtractCommand(); //K&R string.h pg. 251
  199. print2("> The difference is = ", result);
  200.  
  201. } else {
  202. nullCommand(ptrToCommandName);
  203. }
  204. }
  205. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement