Serial Input from multiple characters

Hello community!

I've programmed my arduino leonardo as to when it recieves a specific nummeric input, to print keyboard strokes. It works like a charm but it only gets input from 1-9, if i send 10 then it uses the number 1 setting etc...

This article came up as I was googling a solution but I didn't quite understand what I should do to make it work. Serial Input Basics

Could someone please guide me through?

This is the code I've been using so far:

#include <Keyboard.h>
#include <Mouse.h>

int i;
void setup() {    

    Serial.begin(9600);
}
void loop() {
  
  if(Serial.available() > 0){
    i = Serial.read() - '0';
   if(i == 1){
    Keyboard.press('w');
    delay(50);
    Keyboard.releaseAll();
    Serial.println(i);
   }
   else if(i == 2){
    Keyboard.press('s');
    delay(50);
    Keyboard.releaseAll();
    Serial.println(i);
   }
   else if(i == 3){
    Keyboard.press('a');
    delay(50);
    Keyboard.releaseAll();
    Serial.println(i);
   }
   else if(i == 4){
    Keyboard.press('d');
    delay(50);
    Keyboard.releaseAll();
    Serial.println(i);
   }
   else if(i == 5){
    Keyboard.press('r');
    delay(50);
    Keyboard.releaseAll();
    Serial.println(i);
   }
   else if(i == 6){
    Keyboard.press(' ');
    delay(50);
    Keyboard.releaseAll();
    delay(1600);
    Keyboard.press(' ');
    delay(50);
    Keyboard.releaseAll();
    Serial.println(i);
   }
   else if(i == 7){
    Keyboard.press('r');
    delay(50);
    Keyboard.releaseAll();
    Keyboard.press(' ');
    delay(50);
    Keyboard.releaseAll();
    Serial.println(i);
   }
   else if(i == 8){
    Keyboard.press('r');
    delay(50);
    Keyboard.releaseAll();
    Keyboard.press(' ');
    delay(2000);
    Keyboard.releaseAll();
    Serial.println(i);
   }
   
  }
}

The easier you make it to read and copy the code the more likely it is that you will get help

Please follow the advice given in the link below when posting code , use code tags and post the code here

Where are you stuck ?

The principle used is to add each character as it arrives to an array of chars then, when input is complete, signalled by receipt of the end marker, to terminate the char array with a '\0' to turn it into a C style string (NOT a String)

The string can then be used directly, converted to other forms or used to make decisions

Sorry for the inconvenience, I corrected my code above.

The code I posted above is pretty basic, with too little variables. The code at the other post has too many variables which I can't understand. Like:

void loop() {
 recvWithEndMarker();
 showNewData();
}

void recvWithEndMarker() {
 static byte ndx = 0;
 char endMarker = '\n';
 char rc;
 
 // if (Serial.available() > 0) {
           while (Serial.available() > 0 && newData == false) {
 rc = Serial.read();

 if (rc != endMarker) {
 receivedChars[ndx] = rc;
 ndx++;
 if (ndx >= numChars) {
 ndx = numChars - 1;
 }
 }

I make a new void recvWithEndMarker() { for every instance (my numbers above), and what is the serial read in this example, I had the numbers, what's the equivelant here?

if your input ends with a new line, then use that as your end marker
if your input can be multiple chars long, then you can't compare just with 1 char
you could use strcmp() to test if it's a known string.

if (! strcmp(receivedChars, "10")) { // we received "10"
  ...
} else 
if (! strcmp(receivedChars, "hello")) { // we received "hello"
  ...
} else {
  ...
} 

(you should ignore \r probably in the incoming data just to be safe)

Sorry but I am not really sure I understood you. But I am reading again and again the following example from Robin2

// Example 2 - Receive with an end-marker

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

and googling every unknown character in order to get the hang of it. But still I am not sure where the serial.read input goes. Lets say I want to send the input '2021' and the arduino to respond with w/e. The arduino response will be the

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }

In my case it will be smth like:

void showNewData() {
    if (newData == true) {
    Keyboard.press('d');
    delay(50);
    Keyboard.releaseAll();
    Serial.println(receivedChars);
    newData = false;
    }

But where does the '2021' go? I think it should go here?

else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;

so it will look smth like these:

else {
            receivedChars[ndx] = '2021'; // terminate the string
            ndx = 0;
            newData = true;

Is that making any sense?

If you enter the characters 2, 0, 1, 2 followed by a newline character then the receivedChars array will hold 2 then 20 then 201 then 2012. Receiving the newline will terminate the input and add '\0' to the array turning the array into a C style string which will contain the "2012" and the newData variable will be set to true indicating that data entry is complete.

Now you can test the string using the strcmp() function

if (strcmp(receivedChars , "2012") == 0) //true if the 2 strings are equal
{
  //do something here
}

FYI You say '2021' in a couple of places. That would be a syntax error. Single quotes (') for single characters ('a'), double quotes (") for strings ("a string").

I think I got an idea, will try these probably tomorrow and post my experience. Thanks for your help so far!

My web page on Arduino Software Solutions
has examples of reading from Serial, with their pros/cons
It uses Arduino String so you can say things like

input.trim(); // remove the CR LF
if (input == "2021") {
...

" Edit- Thanks to J-M-L

missing a quote :slight_smile: