Go Down

Topic: Calling functions within functions (Read 633 times) previous topic - next topic

tb0508

I am calling functions inside other functions. I am receiving input like:

Code: [Select]

S383
W235
S399
W235
S415
W236
S431
W234
S447
W235
S463
W234



My main problem is I need to use both values for S and W to calculate before moving to next value. So, once  call processSteer for 'S' I get 'targetPos' then I process 'W' for processWheel and get 'currentPos'. Now I am trying to get both of those values together into 'calculateError' function to use those values for calculations. Not sure of the process to get currentPos and targetPos together to calculate further.

Code: [Select]

/*****STEERING*******/
int processSteer (const unsigned int value)
{
 // do something with steer
 Serial.print ("Steer = ");
 Serial.println (value);
 int steeringInput = constrain(value, 400, 1023); //345 and 795 were min and max of steering wheel pot
 Serial.print("SteeringInput: ");
 Serial.println(steeringInput);
 
  int targetPos = map(steeringInput, 400, 1023, -100, 100);
  Serial.print("targetPos: ");
  Serial.println(targetPos);
  //calculateError(targetPos);
  return targetPos;

} // end of processSteer

int processWheel(const unsigned int value)
{
 Serial.print("Wheel = ");
 Serial.println(value);
 
 int wheelInput = constrain(value, 150, 480); //150 and 480 were min and max of wheel position pot
 Serial.print("WheelInput: ");
 Serial.println(wheelInput);
 
 int currentPos = map(wheelInput, 150, 480, -100,100);
 Serial.print("currentPos: ");
 Serial.println(currentPos);
 //calculateError(currentPos);
 return currentPos;
}

void calculateError(.....)
{
int error = targetPos - currentPos;
Serial.print("Error: ");
Serial.println(error);

setSteer(error);
}

int handlePreviousState ()
{
 switch (state)
 {
 case GOT_B:
   processBrake (currentValue);
   break;
 case GOT_G:
   processGas (currentValue);
   break;
 case GOT_S: //processes first part of Sxxx,xxx
   processSteer (currentValue);
   break;
 case GOT_W:
   processWheel(currentValue);
   break;
 }  // end of switch  

 currentValue = 0;
}  // end of handlePreviousState

void processIncomingByte (const byte c)
{
 if (isdigit (c))
 {
   currentValue *= 10;
   currentValue += c - '0';
 }  // end of digit

 else
 {

   // The end of the number signals a state change
   handlePreviousState ();

   // set the new state, if we recognize it
   switch (c)
   {
   case 'B':
     state = GOT_B;
     break;
   case 'G':
     state = GOT_G;
     break;
   case 'S':
     state = GOT_S;
     break;
   case 'W':
     state = GOT_W;
     break;
   default:
     state = NONE;
     break;
   }  // end of switch on incoming byte
 } // end of not digit  

} // end of processIncomingByte

void loop ()
{
 if (Serial.available ())
   processIncomingByte (Serial.read ());

 //if error is stopping motor, try to re-enable the motor
 

}  // end of loop

shelleycat

When you declare a function such as

int foo(int a, int b)
{
   return a+b;
}

you get the value out by declaring an int, and using the return value

int fooans;

fooans = foo(4, 5);

So in your case, you need an int to hold the return value of processWheel(), and the other function, then give those ints to the CalculateError() function.

At least I think that is what you are asking.

tb0508

Ok, where do I place to int of the return value for each? I did not call processSteer or processWheel from void loop. I called it from handlePreviousState(). Once I determine where to store the int I can call calculateError(int x, int y) with x and y being the int of the return values?

Marek080

You could use global variables - not that nice, but definitely working. Then you could declare static variables in handlePreviousState() which will be persistent between calls. They are like global variables but only accessible in the scope where they are declared. Or you could ...
loved the 68000 assembler back then and now I have to deal with THIS 8 bit thingy

tb0508

Yea, if there is another route to go besides using global variables then that would be better. If not, I will have to revert back to old code to finish the project rather than this route of multiple functions. I thought about static variables but not sure how to place the return value of the assigned variable in the correct function. And then call them both in calculateError like I mentioned in the previous post.

Marek080

Hmm, somehow I do not see what's bothering you  :~

Code: [Select]
void calculateError(int targetPos, int currentPos)
{
int error = targetPos - currentPos;
Serial.print("Error: ");
Serial.println(error);

setSteer(error);
}

int handlePreviousState ()
{
  static int targetPos= 0;
  static int currentPos= 0;
  switch (state)
  {
  case GOT_B:
    processBrake (currentValue);
    break;
  case GOT_G:
    processGas (currentValue);
    break;
  case GOT_S: //processes first part of Sxxx,xxx
    targetPos= processSteer (currentValue);
    break;
  case GOT_W:
    currentPos= processWheel(currentValue);
    calculateError(targetPos, currentPos);
    break;
  }  // end of switch 

  currentValue = 0;
}  // end of handlePreviousState


This assumes you always send a W after a S. targetPos and currentPos are only usable in the scope where they are declared.
loved the 68000 assembler back then and now I have to deal with THIS 8 bit thingy

tb0508

Yes, a W will be processed after an S. This compiles, I will be able to test it soon. Thank you.

I had did the process of assigning targetPos and currentPos to the processWheel and processSteer like you did but did not assign it static int.

tb0508

#7
Apr 11, 2012, 02:11 am Last Edit: Apr 11, 2012, 05:02 am by tb0508 Reason: 1
Got it working


Go Up