problems passing a ServoTimer1 object...

Currently, I'm working on a class that essentially manipulates a servo and causes an IR sensor to take readings. The code rotates the servo by one degree increments and averages ten Ir sensor measurements to get one average 'distance' reading.

The problem really isn't in the IR sensor or the algorithm used, it's in passing a ServoTimer1 object to a function to be manipulated. The error is:

In function IRtower::GetDistAngle()': C:\Documents and Settings\...\libraries\IRtower\irtower.cpp:27: undefined reference to ServoTimer1::write(int)'

Here's the part of the code that's giving me troubles:

Class declaration of IRtower class:

class IRtower{
  private:
   int servopin;
   int sensorpin;
  public:
  int distance;
  int angle;
  void Init(int); //takes pin that sensor is connected to
  void GetDistAngle(ServoTimer1); //this is the troublesome function
  
};

and now, the code of the troublesome function GetDistAngle(ServoTimer1):

void IRtower::GetDistAngle(ServoTimer1 tower) //the hard function 
{
  //handles servo rotation and data collection. Will have to look 'left' and 'right' from center
  tower.write(0); //PROBLEM IS HERE.
  angle= 0;  
  int distances[90][1];
  int ycomps[90][1];
  for(;angle<=90;angle++)   {
    tower.write(angle);//PROBLEM IS HERE, TOO.

//all code below this line seems to compile okay. 

    for(int i(0);i<10;i++) //take ten samples and average them.
    {
      double tempdist = (1/((8*pow(10,-5))*(analogRead(sensorpin))))-0.0016; //damnit...probably need at least a float here to store these values. Start with double, try float later.
      distances[angle][1] +=tempdist; //okay, so this is an int taking a double...a HUGE no no to me personally. I really need those vectors...this should work with a 'data type' warning.
     delay(10); //little delay to give the program time to do stuff    
    }
    distances[angle][1]= (distances[angle][1])/10; //should store final averaged distance
    //store y components
    ycomps[angle][1] = distances[angle][1]*sin((angle+45)*acos(-1)/180); //gets y components
    delay(10); //another little delay.
    //Bear in mind the angle is just a counting variable at this point. 45 needs to be added to it to get the 'true' angle reading. 
    //indices on array will be 0-89 and 0. 
  }
  
   //break this into three cases dependent on y comps. ycomps increase (on the left wall), y comps stay the same (on the back wall), y comps decrease(on the rightt wall)
    int deltaycomps(0); //this value will store the difference between two values. Will find the points for the three cases
    for(angle=0;angle<90;angle++)
   {
     deltaycomps = ycomps[angle-1][1] - ycomps[angle-2][1]; //get the delta y from two previous values.
     //compare it to the delta y between current and one previous value. is it the same?
    int currdeltay = ycomps[angle][1] - ycomps[angle-1][1];
    if(currdeltay>(deltaycomps + 3) || currdeltay<(deltaycomps-3)) //the three is sort of a 'fudge' factor here. It may need to be tightened up. 
    {
      //if you're in here, the value was outside of the delta range and may be the threat object.
      //consider sticking a 'fine tune' function here, that will get the center of the can
      distance = distances[angle][1];
      angle +=45; //who knows...maybe this is the actual distance and angle.
    }
    else if(currdeltay<(deltaycomps + 2) && currdeltay>(deltaycomps-2)) //this condition means two values are within 2 centimeters of each other...enough to assume you are at the back wall
      {
        for(;angle<90;angle++)
        {
          if(distances[angle-1][1]> distances[angle][1] + 3) //a previous measurement that is much larger than the first one means you've found the can
          {
            distance = distances[angle][1];
            angle +=45;
          }
        }
      }
      else if(currdeltay-deltaycomps <0) //this means y values are decreasing in size and you're on 'right' side of platform
      {
        for(;angle<90;angle++)
        {
          if(ycomps[angle-1][1]<ycomps[angle][1]) //previous value is smaller than current value, so previous value must've been threat object
          {
            distance = distances[angle-1][1];
            angle +=44; //angle is angle of 'previous' value...the threat object
          }
        }
      }
    else
    { 
      //do stuff 
    }

}
}

I've put the comment ''PROBLEM IS HERE'' where the problematic lines of code are. It's two places, basically where I ask my ServoTimer1 object, tower, to do something.

And the main Arduino sketch:

#include "irtower.h"

 IRtower sensor;
 ServoTimer1 servo;


void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  sensor.Init(14); //sets up IR sensor pin
  servo.attach(9);
}


void loop() {
 
  
  for(int i=0;i<1;i++)
  {
    sensor.GetDistAngle(servo);
    servo.write(sensor.angle);
  }
  
}

So basically, I cannot declare a ServoTimer1 object in my setup loop and manipulate it from another class, even if I'm passing into a member function of that class...any suggestions on how to remedy this?

Thanks guys.

Ha..wow...I made a rookie mistake here, guys. The above problem is remedied by changing the code of the main sketch to look like:

#include "irtower.h"
#include "ServoTimer1.h" //oops...forgot to add this

 IRtower sensor;
 ServoTimer1 servo;


void setup() 
{
  Serial.begin(9600);           // set up Serial library at 9600 bps
  sensor.Init(14); //sets up IR sensor pin
  servo.attach(9);
}


void loop() 
{
 for(int i=0;i<1;i++)
  {
    sensor.GetDistAngle(servo);
    servo.write(sensor.angle);
  }
  
}

However, with no other changes to the code, I now get this error:

o: In function loop': undefined reference to IRtower::GetDistAngle(ServoTimer1)'o: In function `setup':

I'll keep trying to hunt this one down. In the meantime, any help would be appreciated.

Thanks!

CHANGE:

class IRtower{
  private:
   int servopin;
   int sensorpin;
  public:
  int distance;
  int angle;
  void Init(int); //takes pin that sensor is connected to
  void GetDistAngle(ServoTimer1); //this is the troublesome function

};

TO:

class ServoTimer1; //remember to #include "ServoTimer1.h" in .cpp

class IRtower{
  private:
   int servopin;
   int sensorpin;
  public:
  int distance;
  int angle;
  void Init(int); //takes pin that sensor is connected to
  void GetDistAngle(ServoTimer1); //this is the troublesome function

};

Maybe this helps?

Forward declaration? D'oh!

The idea of forward declaration had slipped my mind. Coming from a C++ background, I can say that would fix the problem, I think. That's in a C++ program, though...working with these crazy robots on the other hand...who knows? :stuck_out_tongue:

I'll give it a shot this afternoon. Thanks for the suggestion