Can their be a simple library for inputing serial data?

I have been trying to wrap my brain around how complicated it is to input data into the serial monitor, compared to for loops its rocket science to me.

all i want to do is type x = 100 and have the robot move to that location, or SetSpeed = 2000, and have that variable change on the fly.

and the only way i have to do this is to assign a numeric value to each variable that i would like to change, and type it in with the delimiter and all that, then type in the value. Why can't i just change any not constant program value by typing it in to the serial monitor? it would make so much sense!

it just seems silly to have a whole subroutine dedicated to a user interface thats still extremely complicated to use.

void processNumber (const long n)
 {
 //Serial.println (n);
 if(WaitForSerialVal > 0){
 if(WaitForSerialVal == 1){
AccelDecelPoints = n;
Serial.print("Accel Val :");
Serial.print(AccelDecelPoints);
WaitForSerialVal = 0;
}

if(WaitForSerialVal == 2){
SetSpeed = n;
Serial.print("SpeedSetAt : ");
Serial.println(SetSpeed);
WaitForSerialVal = 0;
}
 }else{
if(n == 0){
  m = 0;
  HomeJoints = 0;
  Serial.println("Recieved Home Joints Command");
  PointOnLine = 0;

}
if(n == 1){

AccelControl = 1;
Serial.println("Acc on");
}
if(n == 2){

AccelControl = 0;
Serial.println("Acc off");
}
if(n == 3){
WaitForSerialVal = 1;
Serial.print("Enter Accel Val");
}
if(n == 4){
WaitForSerialVal = 2;
Serial.print("Enter Set Speed");
}
 }





 }  // end of processNumber

void processInput ()
 {
 static long receivedNumber = 0;
 static boolean negative = false;

 byte c = Serial.read ();

 switch (c)
   {
     
   case endOfNumberDelimiter:  
     if (negative) 
       processNumber (- receivedNumber); 
     else
       processNumber (receivedNumber); 

   // fall through to start a new number
   case startOfNumberDelimiter: 
     receivedNumber = 0; 
     negative = false;
     break;
     
   case '0' ... '9': 
     receivedNumber *= 10;
     receivedNumber += c - '0';
     break;
     
   case '-':
     negative = true;
     break;
     
   } // end of switch  
 }  // end of processInput

You can associate text strings with memory locations by creating an array containing them both, and code to index its fields.

aarg: You can associate text strings with memory locations by creating an array containing them both, and code to index its fields.

i have no idea what you mean :(

An array of function pointers comes to mind, specifically if everything is numeric and continuous.

Create functions for what you want to do, e.g.

void displayAccelval(const long n)
{
  AccelDecelPoints = n;
  Serial.print("Accel Val :");
  Serial.print(AccelDecelPoints);
  WaitForSerialVal = 0;
}

void displaySpeedval(const long n)
{
  SetSpeed = n;
  Serial.print("SpeedSetAt : ");
  Serial.println(SetSpeed);
  WaitForSerialVal = 0;
}

Next create an array of function pointers for the display functions

void (*displaySetting[])(const long x) =
{
  displayAccelval,
  displaySpeedval,
};

Now in processNumber, you can call one off the functions based on index

 if (WaitForSerialVal > 0)
  {
    displaySetting[WaitForSerialVal - 1](n);
  }
  else
  {
    ...
    ...
  }

As WaitForSerialVal can only be 1 or 2 (if it's not 0; according to your code) we subtract 1 to get the index into the array and execute that function.

You need to harden the code to make sure that the index does not exceed the boundaries of the array.

Same for the commands (if I understand your code correctly)

void cmdHomejoints()
{
  Serial.println("Recieved Home Joints Command");
}

void cmdAcc()
{
  Serial.println("Acc on");
}

void (*cmdActions[])() =
{
  cmdHomejoints,
  cmdAcc,
};

You need to modify the functions to suite your needs.

And processNumber can become

void processNumber (const long n)
{
  if (WaitForSerialVal > 0)
  {
    displaySetting[WaitForSerialVal - 1](n);
  }
  else
  {
    cmdActions[n]();
  }
}

Again, you need to make sure that n does not exceed the boundaries of the array.

Not tested but it gives you the idea and you can read up on function pointers.

Note: Sparkyman, I typed this post while you posted a reply.

//Edit PS the name displayXXX is not quite correct as it also sets something; I leave it up to you to use proper names for the displayXXX functions and the displaySetting array.

I suspect the suggestions in Replies #1 and #3 are adding complexity that the OP does not understand - given that OP started by (reasonably) complaining that sending data is too complex :slight_smile:

@Sparkyman, a large part of the problem is that every person will want something different - even different programs developed by the same person will require different data input and different variables.

For that reason the standard Serial code is very general and you have to write your own Arduino program to interpret the received data and put it into the appropriate variables. The parse example in Serial Input Basics illustrates how to do that. It can be extended to provide a fair amount of the functionality you are talking about. I deliberately did not write that tutorial as a library but in many ways I use it like one by including the relevant functions in any program where I need them.

You should also be aware that in sophisticated PC programs or web applications a large percentage of the program code will be involved in making the user-input work smoothly. Calculating how much tax you should pay is trivial compared to getting you to provide the data needed for the calculation.

…R