How to Control Arduino through the Serial Monitor

When I’m developing Arduino code, I often have variables that need to be tweaked during testing & calibration.
Rather than recompile and upload the code (a time consuming process) I wrote a few lines to let me open the Serial Monitor and send commands directly.

I hope you find this useful – I use it in all my robots!

#define DELAY   (5)
#define BAUD    (57600)
#define MAX_BUF (64)

char buffer[MAX_BUF];
int sofar;

char test_on=0;  // only used in processCommand as an example.
float pos_x;
float pos_y;
float pos_z;


void jog(float x, float y, float z) {
  // do some tests here to validate x, y, and z.
  pos_x=x;
  pos_y=y;
  pos_z=z;
}


void processCommand() {
  if(!strncmp(buffer,"help",4)) {
    Serial.println("commands: where; test (1/0); jog [x(float)] [y(float)] [z(float)];");
  } else if(!strncmp(buffer,"where",5)) {
    // no parameters
    Serial.print(pos_x);
    Serial.print(", ");
    Serial.print(pos_y);
    Serial.print(", ");
    Serial.println(pos_z);
  } else if(!strncmp(buffer,"test",4)) {
    // one whole number parameter
    char *state=strchr(buffer,' ')+1;
    Serial.println(state);
    if(state[0]=='0') {
      Serial.println("End test");
      test_on=0;
    } else {
      Serial.println("Start test");
      test_on=1;
    }
  } else if(!strncmp(buffer,"jog",3)) {
    // several optional float parameters.
    // then calls a method to do something with those parameters.
    float xx=pos_x;
    float yy=pos_y;
    float zz=pos_z;

    char *ptr=buffer;
    while(ptr && ptr < buffer+sofar) {
      ptr=strchr(ptr,' ')+1;
      switch(*ptr) {
      case 'x': case 'X': xx=atof(ptr+1);  Serial.print('x'); Serial.println(xx); break;
      case 'y': case 'Y': yy=atof(ptr+1);  Serial.print('y'); Serial.println(yy); break;
      case 'z': case 'Z': zz=atof(ptr+1);  Serial.print('z'); Serial.println(zz); break;
      default: ptr=0; break;
      }
    }
    
    jog(xx,yy,zz);
  }
}


void setup() {
  Serial.begin(BAUD);
  Serial.println("Init...");
  Serial.println("Stretching...");

  sofar=0;
  Serial.println(F("** AWAKE **"));
  Serial.print(F("\n> "));
}


void loop() {
  // listen for serial commands
  while(Serial.available() > 0) {
    char c = Serial.read();
    if(sofar < MAX_BUF-1)
      buffer[sofar++]=c;
    if(c=='\n') {
      // echo confirmation
      buffer[sofar]=0;
      Serial.println(buffer);

      // do something with the command
      processCommand();
      // reset the buffer
      sofar=0;
      // ready for more
      Serial.print(F("\n> "));
    }
  }
}

Edit 2016-07-11: closed a possible overflow in buffer[].