Good morning all!
I'm currently trying to do a basic multi-motor response code where someone can type in a letter and a number to describe which motor to turn on (the letter) and how long it is to run (number). For example, Typing in A3 would make motor A run for 3 seconds. I'm able to get the SerialRead to understand the entire text entered, but not individually split a response like A3 into 'A' and '3'.
Currently, the code below is set up only to SerialRead a letter and 'TIME' is a set input of 3 seconds. If anyone has advice on how to I could get it to read a number input after a letter input so I could make TIME equal that, it would be greatly appreciated!
Thank you
String input;
// Motor A
int enA = 9;
int in1 = 8;
int in2 = 7;
// Motor B
int enB = 3;
int in3 = 5;
int in4 = 4;
void setup() {
Serial.begin(9600);
delay(1000);
Serial.println("Type A or B");
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
}
void loop() {
if(Serial.available()){
input = Serial.readStringUntil('\n');
if (input == "A") {
Serial.println ("Picked A");
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, 200);
int TIME = 3000;
delay (TIME);
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
}
else if (input == "B") {
Serial.println ("Picked B");
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, 200);
delay (3000);
int TIME = 3000;
delay (TIME)
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
}
}
}
You should also put this line above where you turn on the motor, otherwise the time spent waiting for the number to arrive will become part of the movement time.
String input;
// Motor A
int enA = 9;
int in1 = 8;
int in2 = 7;
// Motor B
int enB = 3;
int in3 = 5;
int in4 = 4;
void setup() {
Serial.begin(9600);
for (int i = 10; i > 0; i--) {
Serial.print(' '); Serial.print(i);
delay(500);
}
Serial.println();
Serial.println("Type A or B followed by time in sec, e.g. A55 or A 55");
input.reserve(10); // pre-allocate some space
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
}
// read Serial until until_c char found, returns true when found else false
// non-blocking, until_c is returned as last char in String, updates input String with chars read
bool readStringUntil(String& input, char until_c) {
while (Serial.available()) {
char c = Serial.read();
input += c;
if (c == until_c) {
return true;
}
}
return false;
}
void loop() {
if (readStringUntil(input, '\n')) {
// go a line of input
input.trim(); // remove any \r and leading/trailing space
input.toUpperCase(); // a -> A etc
char AB_type = input[0];
input.remove(0, 1); // remove the char
input.trim();
long time = input.toInt(); // to int actually returns a long
if (input != String(time)) {
// invalid time
Serial.print(input); Serial.println(F(" not a valid time"));
} else {
if (AB_type == 'A') {
Serial.print(F("Picked A")); Serial.print(F(" with time:")); Serial.println(time);
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, 200);
delay (time * 1000);
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
} else if (AB_type == 'B') {
Serial.print(F("Picked B")); Serial.print(F(" with time:")); Serial.println(time);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, 200);
delay (3000);
delay(time * 1000);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
} else {
Serial.print(AB_type); Serial.println(F(" invalid type, must be A or B followed by time in sec"));
}
}
input = ""; // ALWAYS clear for next read
}
// other loop stuff here
}
The previous sketch is still using delays which cause the input processing to be held up while the previous cmd is being actioned.
That may be useful in this case but in general delays are not recommended