// https://forum.arduino.cc/t/w-a-s-d-controls-for-omni-car/1419561/
// solving for multiple character commands
const int buffersize = 10; // commands allowed in one entry line, plus linefeed/EOL
char buffer[buffersize]; // command input buffer
// const int motorpin[] = {46, 47, 48, 49, 50, 51, 52, 53}; // Mega motor pin-pairs
const int motorpin[] = {2, 3, 4, 5, 6, 7, 8, 9}; // Uno/Nano motor pin-pairs
const int motorpinsize = sizeof(motorpin) / sizeof(motorpin[0]); // should be (8)
#define linefeed 10 // end-of-line character
char data; // data byte
int index; // buffer index
bool endofline = 0; // flag for EOL
bool stopfirsttime = 1; // prevent multiple stop() commands
void setup() {
Serial.begin(115200); // start serial communications
Serial.println(); // handshake to wake up serial comm line
for (int i = 0; i < motorpinsize; i++) // each motor pin...
pinMode(motorpin[i], OUTPUT); // ... configure pins for output
}
void loop() {
readinput();
runmotors();
if (stopfirsttime) // stop motors after first time... reset in go();
stop();
}
void readinput() {
while (Serial.available() && endofline == 0) { // serial line has data AND not at end of line
data = Serial.read(); // read serial data (one byte)
if (data == linefeed) { // verify data is endofline/enter to end data capture
endofline = 1; // disable serial data read
data = ""; // clear linefeed from data input after buffer overflow
} else { // data is other than endofline/enter
if (data == 'a' || data == 'd' || data == 'e' || data == 'q' || data == 's' || data == 'w') {
buffer[index] = data; // append character to buffer string
index++; // increment buffer index
if (index > buffersize) { // buffer index is at maximum...
index = buffersize; // constrain buffer size
endofline = 1; // disable serial data read
}
}
}
}
}
void runmotors() {
for (int i = 0; i < index; i++) { // EOL or buffer full, send motor commands
switch (buffer[i]) {
case 'a': go (0b10100101); break; // rotate left
case 'd': go (0b01011010); break; // rotate right
case 'e': go (0b10010110); break; // turn right
case 'q': go (0b01101001); break; // turn left
case 's': go (0b01010101); break; // reverse
case 'w': go (0b10101010); break; // forward
default: break;
}
}
index = 0; // reset buffer index
}
void go(byte motorcommands) { // receive motor command byte
stopfirsttime = 1; // enable stop()
for (int i = 0; i < 8; i++) // parse each bit/state
digitalWrite(motorpin[i], bitRead(motorcommands, i)); // set each motor to its bit state
delay(500); // let motor run
}
void stop() {
stopfirsttime = 0; // disable multiple stop() commands
delay(20); // pause before stopping
for (int i = 0; i < 8; i++)
digitalWrite(motorpin[i], LOW); // stop each motor
endofline = 0; // allow serial data reading
}