2

I am currently trying to build a very basic serial shell with my arduino.

I am able to get an output from the device using Serial.read() and can get the character it has outputted, but I cannot work out how to then add that character to a longer to form the full command.

I tried the logical thing but it doesn't work:

char Command[];

void loop(){
  if(Serial.available() > 0){
    int clinput = Serial.read();
    Command = Command + char(clinput);
}

Can anybody help? Thank You.

6 Answers 6

3

You have to write character by character into an array. For example like this:

#define MAX_COMMAND_LENGTH 20

char Command[MAX_COMMAND_LENGTH];
int commandLength;    

void loop(){
  if(Serial.available() > 0){
    int clinput = Serial.read();
    if (commandLength < MAX_COMMAND_LENGTH) {
      Command[commandLength++] = (char)clinput;
    }
}

BTW: This is not complete. E.g. commandLength has to be initialized with 0.

Sign up to request clarification or add additional context in comments.

Comments

1

You need to allocate enough space in command hold the longest commmand and then write characters into it as the come in. When you run out of characters, you null terminate the command and then return.

char Command[MAX_COMMAND_CHARS];

void loop() {
  int ix = 0; 
  // uncomment this to append to the Command buffer
  //ix = strlen(Command);

  while(ix < MAX_COMMAND_CHARS-1 && Serial.available() > 0) {
     Command[ix] = Serial.read();
     ++ix;
  }

  Command[ix] = 0; // null terminate the command
}

Comments

0

Use std::string if you can. If you can't :

snprintf(Command, sizeof(Command), "%s%c", Command, clinput);

or (remeber to check that Command does not grow too much...)

size_t len = strlen(Command);
Command[len] = clinput;
Command[len + 1] = '\0';

2 Comments

command doesnt point at anything, sizeof (command) = 4 (or maybe 2 on arduino)
Thanks so much, I've literally spent a day googling :D
0

Use std::ostringstream with std::string:

#include <sstream>
#include <string>

std::string loop()
{
    std::ostringstream oss;
    while ( Serial.available() > 0 ){
        oss << static_cast<char>(Serial.read());
    }
    return oss.str();
}

You can also concatenate multiple instances of std::string with operator+.

Comments

0

Since its also tagged C,

char *command = (char *)malloc(sizeof(char) * MAXLENGTH);
*command = '\0';

void loop(){
  char clinput[2] = {}; //for nullifying the array
  if(Serial.available() > 0){
    clinput[0] = (char)Serial.read();
    strcat(command, clinput);
}

1 Comment

strcat takes a char* as its second arg
-1
 char command[MAX_COMMAND];
 void loop(){
     char *p = command;
    if(Serial.available() > 0){
      int clinput = Serial.read();
    command[p++] = (char)clinput;
   }
  }

4 Comments

Should check for buffer overflow though.
Almost certainly a seg fault if it even compiles. p is a pointer to char, not an index into a char array.
@simon are you serious? char * points perfectly happily to char array. Hopefully you will downvoted the accepted answer since that writes to an unitilaized pointer
Simon is probably serious, since he is correct. Look at your last line. I doubt you meant to index the command array with a pointer. Perhaps you meant *p++ = (char)clinput;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.