未解决的重载函数类型错误

时间:2014-08-12 14:44:45

标签: c++ arduino

我看到很多关于这个错误的讨论,但我似乎找不到有效的格式。我收到以下错误:

In member function 'void radarClass::ping()':
error: no matching function for call to 'NewPing::ping_timer(<unresolved overloaded function type>)'
note: candidates are: void NewPing::ping_timer(void (*)())

我的完整代码附在下面,错误在第198行:

sonar->ping_timer(echoCheck);

我也尝试过失败:

sonar->ping_timer((void* ) &radarClass::echoCheck));
sonar->ping_timer(&radarClass::echoCheck);

完整代码:

#ifndef RADAR_CLASS
#define RADAR_CLASS

#include <NewPing.h>
#include <Servo.h>
#include <PString.h>



/*
**
** MOVING AVERAGE CLASS
** Special volatile impelentation, fixed Int type
**
*/

template <int N> class volatileMovingAverage
{
public:
    volatileMovingAverage(int def = 0) : sum(0), p(0)
    {
        for (int i = 0; i < N; i++) {
            samples[i] = def;
            sum += samples[i];
        }
    }

    int add(int new_sample)
    {
        sum = sum - samples[p] + new_sample;
        samples[p++] = new_sample;
        if (p >= N)
            p = 0;
        return sum / N;
    }

    int inline getAverage(void)
        {
            return sum / N;
        }

private:
    volatile int samples[N];
    volatile int sum;
    volatile int p;

};  // Class volatileMoving Average


/* *************************************************************** */

// RadarClass
//
// USAGE:
// ----------------------
// NewPing mySonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
// Servo myServo;
// radarClass myRadar(&myServo, &mySonar);
// myRadar.attachServo(pinNumber);
// myRadar.setServoSpeed(200);  // 0.2 seconds/60 degrees of rotation
// myRadar.run(); etc.


#define RADAR_DEBUG_MODE YES                        // for testing only, comment out otherwise
#define NO_ANGLES   9                               // number of angles, i.e. positions at which to take measurements

class radarClass
{
private:
    int maxAngle;                                   // 9 values, positions 0 - 8
    int angles[NO_ANGLES];                          // values: {0, 22, 44, 67, 90, 112, 135, 157, 180}
    volatileMovingAverage<4> sonarAverage[NO_ANGLES];  // array of moving average distances (one per angle)

    volatile uint8_t pos;                           // current position within angle array
    unsigned long int servoArrivalTime;             // time (millis) when servo will complete its rotation and arrive at next position
    int direction;                                  // direction traversing the angle array (+1 or -1)
    Servo *radarServo;                              // pointer to the servo
    NewPing *sonar;                                 // point to the NewPing sensor
    int maxDist;                                    // max distance (used by NewPing sensor)
    int servoSpeed;                                 // servo peed in milli-seconds to move 60 degrees (e.g. 0.15 seconds to move 60 degrees of rotation = 0.15 x 1000 = 150)
    volatile bool waitingForPing;                   // flag to mark when ping result received
    bool pingStarted;                               // flag to keep track of ping loop status
    volatile int pingValue;                         // used to pass  ping result between the two routines/ISRs

    void nextPosition(void);
    void ping(void);
    int getMinDistance(int start_pos, int end_pos);
    void commonInit(void);
    void echoCheck(void);

public:
    radarClass(Servo *svr, NewPing *snr);
    radarClass(NewPing *snr, Servo *svr);
    int getMinDistanceLeft(void);
    int getMinDistanceRight(void);
    int getMinDistasnceFront(void); 
    void run(void);
    void attachServo(int pin);
    void setServoSpeed(int);
    void setMaxDistance(int d) {maxDist = d;};
    #ifdef RADAR_DEBUG_MODE
        void printAllValues(void);
        void printInt(int val, int len);
    #endif
    //int getCurrentAngle(void) {return angles[pos];}
    //int getDistance(int p) {return sonarAverage[p].getAverage();}

};  // radarClass


/* ********************************************************** */
// constructor
radarClass::radarClass(Servo *svr, NewPing *snr)
{
    // save the passed pointers
    radarServo = svr;
    sonar = snr;

    // run common initialization routine
    commonInit(); 

}   // radarClass::radarClass constructor


/* ********************************************************** */
// constructor
radarClass::radarClass(NewPing *snr, Servo *svr)
{
    // save the passed pointers
    radarServo = svr;
    sonar = snr;

    // run common initialization routine
    commonInit(); 

}   // radarClass::radarClass constructor

/* ********************************************************** */
// constructor common initialization routine
void radarClass::commonInit(void)
{
    // initialize variables
    maxAngle = NO_ANGLES - 1;
    pos = 0;
    direction = 1;
    servoSpeed = 100;           // default to 0.10 s/60 degrees (x 1000 per millisecond) for TowerPro SG-90
    maxDist = 100;              // max distance usable by NewPing IN INCHES
    pingStarted = false;
    waitingForPing = false;

    // initialize the angle array...not elegant but it works
    // angles[] = {0, 22, 44, 67, 90, 112, 135, 157, 180};
    angles[0] = 0;
    angles[1] = 22;
    angles[2] = 44;
    angles[3] = 67;
    angles[4] = 90;
    angles[5] = 112;
    angles[6] = 135;
    angles[7] = 157;
    angles[8] = 180;

    // move servo to initial position 
    radarServo->write(angles[0]);

    // set arrival time (estimated)
    servoArrivalTime = millis() + (abs(angles[0] - angles[maxAngle]) * servoSpeed / 60 / 2); 
}


/* ********************************************************** */
// main external program loop...call continually, moves servo & reads values
void radarClass::run(void)
{
    unsigned long int t = millis();

    // has the servo arrived at target angle yet?
    if (t < servoArrivalTime)
        return;

    // read distance at current location, wait for result, and advance to next location
    ping();

}


/* ********************************************************** */
// get ping distance at current servo position
void radarClass::ping(void)
{
    if (!pingStarted)                                       // send new ping, echoCheck will be called by interrupt Timer2 until result received
        {
            pingStarted = true;
            waitingForPing = true;
            sonar->ping_timer(echoCheck);
            return;
        }
    else                                                    // pingStarted loop is true, already called ping timer...
        {
            if (!waitingForPing)                            // have we received the result back? 
                {
                    if (pingValue == 0)                     // NewPing returns 0 for undetactable ranges...
                        pingValue = maxDist;
                    sonarAverage[pos].add( pingValue );
                    pingStarted = false;                    // toggle flag to mark that we are ot of hte loop
                    nextPosition();                         // advance to the next position
                }
        }
}



/* ********************************************************** */
// function called by NewPing ISR to check for ping result;  
// Timer2 interrupt calls this function every 24uS where you can check the ping status.
void radarClass::echoCheck(void) 
{ 
  // Don't do anything here!
  if (sonar->check_timer())                                     // Check to see if the ping was received.
  {
      pingValue = (sonar->ping_result / US_ROUNDTRIP_IN);   // Ping returned, uS result in ping_result, convert to inches with US_ROUNDTRIP_IN. 
      waitingForPing = false;                               // toggle flag so we know result is complete
  }
  // Don't do anything here!
}


/* ********************************************************** */
// move servo to the next position
void radarClass::nextPosition(void)
{
    // if at either end, change direction
    if (pos == 0)
      direction = 1;
    else if (pos == maxAngle)
      direction = -1;

    // advance to next position
    pos += direction;
    radarServo->write(angles[pos]);

    // calculate arrival time at next position
    servoArrivalTime = millis() + ( (abs(angles[pos] - angles[pos + direction]) * servoSpeed ) / 60); 
}



/* ********************************************************** */
// set the servo speed, in milliseconds per 60 degrees
void radarClass::setServoSpeed(int spd)
{
    servoSpeed = spd;
}


/* ********************************************************** */
// Attach servo to specified pin
void radarClass::attachServo(int pin)
{
    radarServo->attach(pin);
}



/* ********************************************************** */
// return the longest distance for given array entries (inclusive)
int radarClass::getMinDistance(int start_pos, int end_pos)
{
    // to make sure underlying data isn't changed by ISR routine, briefly turn off interrupts
    //noInterrupts();

    // calculate the min value
    int smallest = sonarAverage[start_pos].getAverage();
    for (int t = start_pos + 1; t <= end_pos; t++)
        {
            int curr = sonarAverage[t].getAverage();
            if (curr < smallest)
                smallest = curr;
        }

    // turn interrupts back on
    //interrupts();

    // return the calculated value
    return (smallest);
}


/* ********************************************************** */
// return closest distance to left (positions 0, 1 & 2)
int radarClass::getMinDistanceLeft(void)
{
    return getMinDistance(0, 2);
}



/* ********************************************************** */
// return closest distance to right (positions 6, 7 & 8)
int radarClass::getMinDistanceRight(void)
{
    return getMinDistance(6, 8);
}


/* ********************************************************** */
// return closest distance to front (positions 3, 4 & 5)
int radarClass::getMinDistasnceFront(void)
{
    return getMinDistance(3, 5);
}

// code for debugging; prints all values in neat format
#ifdef RADAR_DEBUG_MODE
    void radarClass::printAllValues(void)
        {
            static bool firstEntry = true;

            if (firstEntry) // only print the header row once
            {
                Serial.println(" ");
                Serial.println(F("Angle 1 Angle 2 Angle 3 Angle 4 Angle 5 Angle 6 Angle 7 Angle 8 Angle 9"));
                for (int i = 0; i <= maxAngle; i++)  // print the angles
                    {
                        printInt(angles[i], 7);
                        Serial.print(" ");
                    }
                Serial.println("");
                Serial.println(F("------- ------- ------- ------- ------- ------- ------- ------- -------"));
                firstEntry = false;
            }

            // print the distances
            for (int i = 0; i <= maxAngle; i++)
                {
                    printInt(sonarAverage[i].getAverage(), 7);
                    Serial.print(" ");
                }
            Serial.println("");             
        }   // void printAllValues(void)


    /* ********************************************************** */
    // Print integer, padded for alignment
    void radarClass::printInt(int val, int len)
    {
        int strLen;
        char buffer[30];
        PString str(buffer, sizeof(buffer));

        // Find the length of the printed value
        str.begin();
        str.print(val);
        strLen = str.length();
        str.begin();

        // Pad string with leading spaces
        for (int t = len - strLen; t > 0; t--)
        {
            str += " ";
        }

        // then print the string
        str.print(val);
        //str += " ";

        // print result
        Serial.print(str);
    } // void printInt(int val, int len)

    #endif // RADAR_DEBUG_MODE


#endif // RADAR_CLASS


/* ****************************************************************************************** */


/* 
** TEST CODE HERE
******************************** 
*/

//#include <TimerOneThree.h>
#include <TimerOne.h>

#define RADAR_INT_TIME 100000               // 100,000 microseconds = 10x/second = 1 sweep of 9 angles per sceond


Servo myServo;
NewPing mySonar(10, 11, 250);
radarClass myRadar(&myServo, &mySonar);


// function to be called by the interrupt timer; will run the Radar code
void intRunRadar(void)
{
    myRadar.run();
}  // void intRunRadar()


void setupRadarInterrupt(void)
{
//  Timer1.initialize(RADAR_INT_TIME);                  // set how often to run the interrupt (in microseconds)
//  Timer1.attachInterrupt(intRunRadar);
} // void setupRadarInterrupt(void)



void setup()
{
    Serial.begin(9600);   
    myRadar.attachServo(3);
    myRadar.setServoSpeed(150);
    delay(500);
    //setupRadarInterrupt();
 }



void loop()
{
  unsigned long int t1, t2;

  t1 = millis();

  Serial.println("Starting test");

  while (1)
    {
      myRadar.run();
      t2 = millis();
          if (t2 >= t1 + 1000) 
        {
                 t1 = t2;           
                 myRadar.printAllValues();     
        }
    } // while
} // loop()

感谢您的帮助,我显然已经达到了我的知识极限。

1 个答案:

答案 0 :(得分:0)

向草图添加构造函数:

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); //