the user is allowed to enter a set of command in the void loop() and according to the command, the program will shift to a specific function and do the task. This is direct, you enter, shift to a function and it returns to main loop and continues or limits can be made for controlling.
What I want to implement is the ability for the user to set a series of command and the arduino will do one at a time, that is, the user enters 4 data, a b c d. the program will do the first one a then will do the b and so on.
Couldnt find the appropriate keywords to search for this. Is it realizable as arduino is sequential. the data are stored and use one at a time. And also I thought of doing a count sytem so that it can eliminate one at a time, I dont know if it makes sense.
the data entered will be numbers up to hundreds(ranging from 0 to 180) and a text.
These data will be related to the motion of stepper motor in other functions.
You said replay, Im not doing a replay but more of doing one at a time and after the end, the main function is done.
pcRead accepts a optional multii-digit # followed by a single char command
// pcRead - debugging using serial monitor
const char version [] = "PcRead 201114a";
int debug = 0;
// ---------------------------------------------------------
// toggle output bit
void
pinToggle (
int pin)
{
static int bits = 0;
int bit = 1 << pin;
if (debug) {
Serial.print ("pinToggle: ");
Serial.println (pin);
}
if (bits & bit) {
digitalWrite (pin, LOW);
bits &= ~bit;
}
else {
digitalWrite (pin, HIGH);
bits |= bit;
}
}
// ---------------------------------------------------------
// toggle output bit
int
readString (
char *s,
int maxChar )
{
int n = 0;
Serial.print ("> ");
do {
if (Serial.available()) {
int c = Serial.read ();
if ('\n' == c)
break;
s [n++] = c;
if (maxChar == n)
break;
}
} while (true);
return n;
}
// -----------------------------------------------------------------------------
// process single character commands from the PC
#define MAX_CHAR 10
char s [MAX_CHAR] = {};
int analogPin = 0;
void
pcRead (void)
{
static int val = 0;
if (Serial.available()) {
int c = Serial.read ();
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
val = c - '0' + (10 * val);
break;
case 'A':
analogPin = val;
Serial.print ("analogPin = ");
Serial.println (val);
val = 0;
break;
case 'D':
debug ^= 1;
break;
case 'I':
pinMode (val, INPUT);
Serial.print ("pinMode ");
Serial.print (val);
Serial.println (" INPUT");
val = 0;
break;
case 'O':
pinMode (val, OUTPUT);
Serial.print ("pinMode ");
Serial.print (val);
Serial.println (" OUTPUT");
val = 0;
break;
case 'P':
pinMode (val, INPUT_PULLUP);
Serial.print ("pinMode ");
Serial.print (val);
Serial.println (" INPUT_PULLUP");
val = 0;
break;
case 'a':
Serial.print ("analogRead: ");
Serial.println (analogRead (val));
val = 0;
break;
case 'c':
digitalWrite (val, LOW);
Serial.print ("digitalWrite: LOW ");
Serial.println (val);
val = 0;
break;
case 'p':
#if !defined(ARDUINO_ARCH_ESP32)
analogWrite (analogPin, val);
Serial.print ("analogWrite: pin ");
Serial.print (analogPin);
Serial.print (", ");
Serial.println (val);
val = 0;
#endif
break;
case 'r':
Serial.print ("digitalRead: pin ");
Serial.print (val);
Serial.print (", ");
Serial.println (digitalRead (val));
val = 0;
break;
case 's':
digitalWrite (val, HIGH);
Serial.print ("digitalWrite: HIGH ");
Serial.println (val);
val = 0;
break;
case 't':
Serial.print ("pinToggle ");
Serial.println (val);
digitalWrite (val, ! digitalRead (val));
val = 0;
break;
case 'v':
Serial.print ("\nversion: ");
Serial.println (version);
break;
case '\n': // ignore
break;
case '"':
while ('\n' != Serial.read ()) // discard linefeed
;
readString (s, MAX_CHAR-1);
Serial.println (s);
break;
case '?':
Serial.println ("\npcRead:\n");
Serial.println (" [0-9] append to #");
Serial.println (" A # - set analog pin #");
Serial.println (" D # - set debug to #");
Serial.println (" I # - set pin # to INPUT");
Serial.println (" O # - set pin # to OUTPUT");
Serial.println (" P # - set pin # to INPUT_PULLUP");
Serial.println (" a # - analogRead (pin #)");
Serial.println (" c # - digitalWrite (pin #, LOW)");
Serial.println (" p # -- analogWrite (analogPin, #)");
Serial.println (" r # - digitalRead (pin #)");
Serial.println (" s - digitalWrite (pin #, HIGH)");
Serial.println (" t -- toggle pin # output");
Serial.println (" v - print version");
Serial.println (" \" - read string");
Serial.println (" ? - list of commands");
break;
default:
Serial.print ("unknown char ");
Serial.println (c,HEX);
break;
}
}
}
// -----------------------------------------------------------------------------
void
loop (void)
{
pcRead ();
}
// -----------------------------------------------------------------------------
void
setup (void)
{
Serial.begin(115200);
Serial.println (version);
#if defined(ARDUINO_ARCH_ESP32)
Serial.println ("esp32");
#endif
}
the following code demonstrates reading a multi-char string which could be compared to a list (as demonstrated). that list can have function pointers to executer when there's a match. capturing a optional argument is a bit more work
int array1[] = {2,3};
int array2[] = {5,6};
struct Array_s {
const char *name;
int *array;
int size;
};
Array_s arrays [] = {
{ "array1", array1, sizeof(array1)/sizeof(int) },
{ "array2", array2, sizeof(array2)/sizeof(int) },
};
#define N_ARRAYS (sizeof(arrays)/sizeof(Array_s))
const char *prompt = "Which array do you want? array1[] or array2.[]";
char line [80];
int idx = 0;
// -----------------------------------------------------------------------------
void
process (
char *line )
{
for (unsigned n = 0; n < N_ARRAYS; n++) {
if (! strcmp (arrays [n].name, line)) {
for (int i = 0; i < arrays [n].size; i++) {
Serial.print (" ");
Serial.print (arrays [n].array [i]);
}
Serial.println ();
return;
}
}
Serial.println (" unknown array name");
}
// -----------------------------------------------------------------------------
void loop() {
if (Serial.available ()) {
char c = Serial.read ();
if ('\n' == c) {
line [idx] = '\0';
process (line);
idx = 0;
Serial.print (prompt);
}
else
line [idx++] = c;
}
}
void setup() {
Serial.begin(9600);
Serial.print (prompt);
}
As you receive your commands, push them into the Queue. When you receive the last command or otherwise know you are done, start popping commands off the queue and executing them until the queue is empty.
If you design your program properly, you can receive new commands while executing commands.
/*
example of using a queue
send: A,B,C,D
send: BAD DAD
*/
#include <QueueArray.h>
// These are user callable actions
enum Cmds { CMD_A, CMD_B, CMD_C, CMD_D };
// create a queue of ints to hold list of states that need to be executed in order
QueueArray <int> cmdQueue;
void setup() {
Serial.begin(9600);
delay(500);
Serial.println("Send a series of A,B,C,D....");
}
void loop() {
// fetch any input
while (Serial.available()) {
int inByte = Serial.read();
if ( isLowerCase(inByte) ) {
inByte -= 32;
}
switch (inByte) {
case '?': // help
Serial.println("Send a series of A,B,C,D....");
break;
case 'A':
cmdQueue.push( CMD_A );
break;
case 'B':
cmdQueue.push( CMD_B );
break;
case 'C':
cmdQueue.push( CMD_C );
break;
case 'D':
cmdQueue.push( CMD_D );
break;
case ' ':
case ',':
case '\r':
case '\n':
break;
default: // unknown command
Serial.println("Unknown command. Type ? for help" );
}
}
// execute any commands in the queue
if (cmdQueue.isEmpty() == false) {
switch ( cmdQueue.pop()) {
case CMD_A:
Serial.println("Cmd A executed");
break;
case CMD_B:
Serial.println("Cmd B executed");
break;
case CMD_C:
Serial.println("Cmd C executed");
break;
case CMD_D:
Serial.println("Cmd D executed");
break;
}
}
}
well pcRead is a simple approach that allows commands to be concatenated together. the other code shows how strings can be read and searched for in a table.
i assumed you would see how the two could be combined to do what you want