我看到很多关于这个错误的讨论,但我似乎找不到有效的格式。我收到以下错误:
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()
感谢您的帮助,我显然已经达到了我的知识极限。
答案 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); //