I was wondering if anyone has any idea how to receive input from Serial Monitor whilst a switch case is already running, and conduct an action based on that input.
Please note that the intention is to run both Case and the Code associated with Serial Monitor input. For example, see code below.
char switchCases;
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
switchCases = Serial.read();
}
switch (switchCases) {
case 'a':
Serial.print("This is first switch case...\nPlease choose another function to run simultaneously with me\n");
if (Serial.read() == 'p') {
Serial.print("User pressed P");
//move motor by X amount in X direction each time 'p' is entered in Serial Monitor
}
break;
}
}
In this example, when the user enters "a" in the Serial Monitor input, the Serial Monitor will print
"This is first switch case...
Please choose another function to run simultaneously with me
"
However, the issue is that if the user enters "p" whilst case 'a' is running, the code works, however, if I enter "p" a few times one after the other, the code eventually stops running.
Is there a way to have "p" code run each time I enter "p", whilst case 'a' is running?
Why do you keep creating new threads? You are not checking if Serial.available() says there are any chars ready before attempting your read. Read up on the documentation for Serial.read() to understand what that does.
I don't know about repeating 'p' while 'a' is running, but you could save the last thing received, and if the same one came in again you could use it over without needing and 'a'.
Presumably you will want other commands, 'b', 'c', 'd', that will do different things also, so you'd want
appppppp
or
bppppppp
or maybe
cmmmmm
or
dnnnnnnn
blh64:
Why do you keep creating new threads? You are not checking if Serial.available() says there are any chars ready before attempting your read. Read up on the documentation for Serial.read() to understand what that does.
Incase people are interested in knowing about this specific topic. I figured it would be helpful to others as well if I created a new thread, instead of sifting through the old thread to find this info.
I will check up on Serial.read() as you suggested. Many thanks.
paulsamaroo:
Please choose another function to run simultaneously with me
Don't forget that the Arduino is single threaded - it can only do one thing at a time. If you break your tasks into small pieces though, you can make it appear to the user that multiple things are happening at once.
CrossRoads:
I don't know about repeating 'p' while 'a' is running, but you could save the last thing received, and if the same one came in again you could use it over without needing and 'a'.
Presumably you will want other commands, 'b', 'c', 'd', that will do different things also, so you'd want
appppppp
or
bppppppp
or maybe
cmmmmm
or
dnnnnnnn
Yes I think this is more in line with what I want to accomplish.
So basically, if I have the following:
int position = 0;
char switchCases;
void loop(){
if (Serial.available() > 0) {
switchCases = Serial.read();
}
switch (switchCases){
case a:
//run code here
if(Serial.read() == 'p'){
position++;
}
break;
}
}
if Case A is running, and user would like to increase position to 10, then using your example, it would be like this...
apppppppppp
So Case A will run first, then whilst case A is running, user enters 'p' 10 times until position variable = 10. However, according to @blh64, I should be checking if Serial.available first, before attempting to deal with 'p'.
wildbill:
Don't forget that the Arduino is single threaded - it can only do one thing at a time. If you break your tasks into small pieces though, you can make it appear to the user that multiple things are happening at once.
What are you actually trying to do?
Yes, within a few milliseconds is fine as well. I think the example I wrote above should cover what I'm trying to achieve.
CrossRoads:
I don't know about repeating 'p' while 'a' is running, but you could save the last thing received, and if the same one came in again you could use it over without needing and 'a'.
Presumably you will want other commands, 'b', 'c', 'd', that will do different things also, so you'd want
appppppp
or
bppppppp
or maybe
cmmmmm
or
dnnnnnnn
So, I'm thinking you can have commands and nested subcommands.
Do something like this - read the byte, determine if its a command;
If so, save it, and clear out the prior subcommand so it doesn't execute it.
Next time thru loop(), see if a subcommand came in, if so save it and execute it.
Might have to tweak this a bit for proper { } pairings.
void loop(){
if (Serial.available() > 0) {
newByte = Serial.read(); // read the current data received
if (newByte == 'a' || newByte == 'b' || newByte == 'b' ){ // new command received
switchCase = newByte; // save new command for use
subCase = 0; // "clear out" prior subCase
}
else { // old command still in play, see if new sub command came in
if (newByte == 'p' || newByte == 'r'){
subCase = newByte; // same command being used, do whatever function was received, such as 'p'
}
else {
// neither command nor subCase came in - maybe make this smarter to ignore CR and LF
switchCase = 0;
subCase = 0;
Serial.print ("invalid command/subCase: ");
Serial.println {newByte);
}
switch (switchCase) {
case 'a':
// do stuff with subCase
if (subCase != 0){
switch (subCase){
case 'p':
// p code
break;
case 'r':
// r code
break;
}
break;
case 'b':
// do stuff with subCase
if (subCase != 0){
switch (subCase){
case 'p':
// p code
break;
case 'r':
// r code
break;
}
break;
case 'c':
// do stuff with subCase
if (subCase != 0){
switch (subCase){
case 'p':
// p code
break;
case 'r':
// r code
break;
}
break;
} // end outer switch:case
} // end loop()
CrossRoads:
So, I'm thinking you can have commands and nested subcommands.
Do something like this - read the byte, determine if its a command;
If so, save it, and clear out the prior subcommand so it doesn't execute it.
Next time thru loop(), see if a subcommand came in, if so save it and execute it.
Might have to tweak this a bit for proper { } pairings.
void loop(){
if (Serial.available() > 0) {
newByte = Serial.read(); // read the current data received
if (newByte == 'a' || newByte == 'b' || newByte == 'b' ){ // new command received
switchCase = newByte; // save new command for use
subCase = 0; // "clear out" prior subCase
}
else { // old command still in play, see if new sub command came in
if (newByte == 'p' || newByte == 'r'){
subCase = newByte; // same command being used, do whatever function was received, such as 'p'
}
else {
// neither command nor subCase came in - maybe make this smarter to ignore CR and LF
switchCase = 0;
subCase = 0;
Serial.print ("invalid command/subCase: ");
Serial.println {newByte);
}
switch (switchCase) {
case 'a':
// do stuff with subCase
if (subCase != 0){
switch (subCase){
case 'p':
// p code
break;
case 'r':
// r code
break;
}
break;
case 'b':
// do stuff with subCase
if (subCase != 0){
switch (subCase){
case 'p':
// p code
break;
case 'r':
// r code
break;
}
break;
case 'c':
// do stuff with subCase
if (subCase != 0){
switch (subCase){
case 'p':
// p code
break;
case 'r':
// r code
break;
}
break;
} // end outer switch:case
} // end loop()
Ahhh that looks quite interesting. I'll take a look at it and see how I can incorporate this in my project. Thank you!