2016-12-22 51 views
-1

我一直在试图编译和修复从GitHub这个库,将允许有人来创建自己的规模;然而,当我尝试为arduino编译它时,我得到这个错误。Arduino的平衡库错误

Arduino: 1.6.13 (Windows 10), Board: "Arduino Nano, ATmega328"

C:\Users\user\Documents\GitHub\Q2-Balance-Arduino-Library\examples\hx711_two_cell\hx711_two_cell.ino: In function 'void loop()':

hx711_two_cell:40: error: no matching function for call to 'Q2Balance::tare(int)'

balance.tare(100); 

       ^

C:\Users\user\Documents\GitHub\Q2-Balance-Arduino-Library\examples\hx711_two_cell\hx711_two_cell.ino:40:21: note: candidate is:

In file included from C:\Users\user\Documents\GitHub\Q2-Balance-Arduino-Library\examples\hx711_two_cell\hx711_two_cell.ino:1:0:

C:\Users\user\Documents\Arduino\libraries\Q2-Balance-Arduino-Library-master\src/Q2Balance.h:64:10: note: void Q2Balance::tare(long int, void (*)())

void tare(long milliseconds, void (*afterTared)(void)); 

我很困惑,为什么需要有这第二空位参数(右,回调函数)

我不确定我需要什么,为了改变这个功能得到这个编译 这是.h文件:

#ifndef q2balance_h 
#define q2balance_h 
#include "Arduino.h" 

#define Q2BALANCE_MARKER_COUNT 10 
// #define Q2BALANCE_DEBUG 

#define Q2BALANCE_UNIT_GRAM 0 
#define Q2BALANCE_UNIT_POUND 1 
#define Q2BALANCE_UNIT_OUNCE 2 
#define Q2BALANCE_UNIT_GRAIN 3 
#define Q2BALANCE_UNIT_TROY 4 
#define Q2BALANCE_UNIT_PWT 5 
#define Q2BALANCE_UNIT_CARAT 6 
#define Q2BALANCE_UNIT_NEWTON 7 

struct BalanceCalibrationStruct { 
    long calibrationZero; 
    long calibrationMV[Q2BALANCE_MARKER_COUNT]; 
    long calibrationMeasured[Q2BALANCE_MARKER_COUNT]; 
    float calibrationScaler[Q2BALANCE_MARKER_COUNT]; 
}; 

class Q2Balance 
{ 
    private: 
    BalanceCalibrationStruct _settings; 
    bool _tared = false; 
    bool _taring = false; 
    bool _calibrating = false; 
    bool _calibratingZero = false; 
    bool _settling = false; 
    long _smoothValue = 0; 
    long _rawValue = 0; 
    long _tareValue = 0; 
    unsigned long _settleTimeout; 
    long _settleMinVal = 0; 
    long _settleMaxVal = 0; 
    long _jitter = 0; 
    int _calibrationIndex; 
    void (*_afterCalibrated)(void); 
    void sortCalibrations(); 
    int findCalibrationWindow(long voltage); 
    float calcValue(int units, long value); 
    public: 
    long TARELIMIT = 110; 
    long JUMPLIMIT = 200; 
    long SAMPLE_COUNT = 10; 
    bool LOGGING = false; 
    Q2Balance(); 
    virtual ~Q2Balance(); 
    bool taring(); 
    bool tared(); 
    bool settling(); 
    bool calibrating(); 
    float adjustedValue(int units); 
    float adjustedRawValue(int units); 
    long smoothValue(); 
    long rawValue(); 
    long jitter(); 
    void calibrateZero(long milliseconds, void (*afterCalibrated)(void)); 
    void calibrate(int index, long measurement, long milliseconds, void (*afterCalibrated)(void)); 
    void measure(long measurement); 
    void tare(long milliseconds, void (*afterTared)(void)); 
    long settle(long milliseconds); 
    BalanceCalibrationStruct getCalibration(); 
    void setCalibration(BalanceCalibrationStruct newSettings); 
    void tick(); 
    void printCalibration(int index); 
    void printCalibrations(); 
}; 

#endif /* q2balance_h */ 

和cpp文件

#include "q2balance.h" 

Q2Balance::Q2Balance(){ 
    _settings.calibrationZero = 0; 
    for(int i = 0;i<Q2BALANCE_MARKER_COUNT;i++) 
    { 
    _settings.calibrationMV[i]= 0; 
    _settings.calibrationMeasured[i] = 0; 
    _settings.calibrationScaler[i] = 0; 
    } 
} 

Q2Balance::~Q2Balance(){ 
} 

BalanceCalibrationStruct Q2Balance::getCalibration(){ 
    BalanceCalibrationStruct newSettings; 
    newSettings.calibrationZero = _settings.calibrationZero; 
    for(int i = 0;i<Q2BALANCE_MARKER_COUNT;i++) 
    { 
    newSettings.calibrationMV[i] = _settings.calibrationMV[i]; 
    newSettings.calibrationMeasured[i] = _settings.calibrationMeasured[i]; 
    newSettings.calibrationScaler[i] = _settings.calibrationScaler[i]; 
    } 
    return newSettings; 
} 

void Q2Balance::setCalibration(BalanceCalibrationStruct newSettings){ 
    _settings.calibrationZero = newSettings.calibrationZero; 
    for(int i = 0;i<10;i++) 
    { 
    _settings.calibrationMV[i] = newSettings.calibrationMV[i]; 
    _settings.calibrationMeasured[i] = newSettings.calibrationMeasured[i]; 
    _settings.calibrationScaler[i] = newSettings.calibrationScaler[i]; 
    } 
} 

void Q2Balance::tick(){ 
    unsigned long now = millis(); 
    if (_settling){ 
    if (_smoothValue < _settleMinVal){ 
     _settleMinVal = _smoothValue; 
    } 
    if (_smoothValue > _settleMaxVal){ 
     _settleMaxVal = _smoothValue; 
    } 
    _jitter = _settleMaxVal - _settleMinVal; 
    if (now > _settleTimeout){ 
     _settling = false; 
    } else { 
     return; 
    } 
    } 

    if(_taring){ 
    _taring = false; 
    _tared = true; 
    _smoothValue = _rawValue; 
    _tareValue = _rawValue; 
    if (_afterCalibrated!=NULL){ 
     (*_afterCalibrated)(); 
     _afterCalibrated = NULL; 
    } 
    } 

    if (_tared && abs(_smoothValue - _tareValue) > TARELIMIT){ 
    _tared = false; 
    } 

    if (_calibratingZero) { 
    _settings.calibrationZero = _smoothValue; 

    for(int i = 0;i<Q2BALANCE_MARKER_COUNT;i++) // Recalc calibrations if zero changed 
    { 
     if(_settings.calibrationScaler[i] != 0){ 
     float delta = (float)(_settings.calibrationMV[i] - _settings.calibrationZero); 
     float scaler = (float)_settings.calibrationMeasured[i]/delta; 
     _settings.calibrationScaler[i] = scaler; 
     } 
    } 

    _calibratingZero = false; 
    _calibrating = false; 

    if (_afterCalibrated!=NULL){ 
     (*_afterCalibrated)(); 
     _afterCalibrated = NULL; 
    } 

    } 

    if (_calibrating) { 
    _calibrating = false; 
    _settings.calibrationMV[_calibrationIndex] = _smoothValue; 
    float delta = (float)(_smoothValue - _settings.calibrationZero); 
    float scaler = (float)_settings.calibrationMeasured[_calibrationIndex]/delta; 

    _settings.calibrationScaler[_calibrationIndex] = scaler; 

    if (_afterCalibrated!=NULL){ 
     (*_afterCalibrated)(); 
     _afterCalibrated = NULL; 
    } 
    } 
} 

long Q2Balance::settle(long settleTime) { 
    _settling = true; 
    _settleMinVal = _smoothValue; 
    _settleMaxVal = _smoothValue; 
    _settleTimeout = millis() + settleTime; 
} 

bool Q2Balance::settling(){ 
    return _settling; 
}; 

bool Q2Balance::calibrating(){ 
    return _calibrating; 
}; 

void Q2Balance::tare(long settleTime, void (*afterTared)(void)){ 
    if (!_calibrating && !_settling){ 
    _taring = true; 
    _afterCalibrated = afterTared; 
    settle(settleTime); 
    } 
} 

bool Q2Balance::taring(){ 
    return _taring; 
}; 

bool Q2Balance::tared(){ 
    return _tared; 
}; 

void Q2Balance::calibrateZero(long settleTime, void (*afterCalibrated)(void)){ 
    if (!_calibrating && !_settling){ 
    _afterCalibrated = afterCalibrated; 
    _calibratingZero = true; 
    _calibrating = true; 
    settle(settleTime); 
    } 
} 

void Q2Balance::calibrate(int index, long measurement, long settleTime, void (*afterCalibrated)(void)){ 
    if (!_calibrating && !_settling){ 
    if (index < Q2BALANCE_MARKER_COUNT){ 
     _afterCalibrated = afterCalibrated; 
     _calibrating = true; 
     _calibrationIndex = index; 
     _settings.calibrationMeasured[index] = measurement; 
     settle(settleTime); 
    } 
    } 
} 

void Q2Balance::measure(long measurement){ 
    long avg = _smoothValue; 
    _rawValue = measurement; 
    if (abs(measurement-_smoothValue) > JUMPLIMIT){ // If there is a large jump, abandon smoothing and set the value. 
    _smoothValue = measurement; 
    return; 
    } 
    avg -= avg/SAMPLE_COUNT; 
    avg += measurement/SAMPLE_COUNT; 
    _smoothValue = avg; 
}; 

long Q2Balance::smoothValue(){ 
    return _smoothValue; 
}; 

long Q2Balance::rawValue(){ 
    return _rawValue; 
}; 

long Q2Balance::jitter(){ 
    return _jitter; 
} 

float Q2Balance::calcValue(int units, long value){ 
    if(_settings.calibrationZero == 0){ 
    return 0; //unzeroed 
    } 

    int index = findCalibrationWindow(_smoothValue); 

    if (index == -1){ 
    return 0; //uncalibrated 
    } 
    long val = _smoothValue - _tareValue; 
    if (_tared){ 
    return (0); 
    } 

    float scaled = round(val * _settings.calibrationScaler[index] * 100.0)/100.0; 

    if (units > 0){ 

    switch (units) { 
    case Q2BALANCE_UNIT_POUND: 
     scaled = scaled * 0.002204622; 
     break; 
    case Q2BALANCE_UNIT_OUNCE: 
     scaled = scaled * 0.0352734; 
     break; 
    case Q2BALANCE_UNIT_GRAIN: 
     scaled = scaled * 15.43; 
     break; 
    case Q2BALANCE_UNIT_TROY: 
     scaled = scaled * 0.032; 
     break; 
    case Q2BALANCE_UNIT_PWT: 
     scaled = scaled * 0.643; 
     break; 
    case Q2BALANCE_UNIT_CARAT: 
     scaled = scaled * 5; 
     break; 
    case Q2BALANCE_UNIT_NEWTON: 
     scaled = scaled * 0.009; 
     break; 
    } 
    } 

    return scaled; 

} 

float Q2Balance::adjustedValue(int units){ 
    return calcValue(_smoothValue, units); 
} 

float Q2Balance::adjustedRawValue(int units){ 
    return calcValue(_rawValue, units); 
} 

void Q2Balance::printCalibrations(){ 
    char buffer[128]; 
    sprintf(buffer, "ZERO %ld ",_settings.calibrationZero); 
    Serial.println(buffer); 
    for(int c=0;c<Q2BALANCE_MARKER_COUNT;c++){ 
    printCalibration(c); 
    } 
} 

void Q2Balance::printCalibration(int index){ 
    char buffer[128]; 
    char str_scaler[16]; 
    dtostrf(_settings.calibrationScaler[index], 6, 6, str_scaler); 
    sprintf(buffer, "IDX %dMV %ld M %ld SC %s", 
    index, 
    _settings.calibrationMV[index], 
    _settings.calibrationMeasured[index], 
    str_scaler 
); 
    Serial.println(buffer); 
} 

int Q2Balance::findCalibrationWindow(long voltage){ 
    int i,t=0; 
    for (i = 0; i < Q2BALANCE_MARKER_COUNT; i++) 
    { 
    if (_settings.calibrationMV[i] == 0){ 
     break; 
    } 
    if (_settings.calibrationMV[i] >= voltage){ 
     break; 
    } 
    t = i; 
    } 
    if (_settings.calibrationMV[t] == 0){ 
    return -1; 
    } 
    return t; 
} 
+0

目的是提供一个回调函数。 –

回答

0

当库函数balance.tare完成时,它将调用您自己的函数(又名回调函数),该函数在该附加输入参数中提供给函数balance.tare

你可以将这个回调机制的概念为“叫我当你做”的。


通常有两种方法来实现回调的机制:

静态链接:

功能balance.tare调用预定义的(硬编码)名称的函数。

您必须实现您的代码,名称的功能。

由于函数调用和函数本身必须位于不同的源文件中,因此编译器必须假定此函数存在于代码中的某处,并将地址解析留给链接器(最终将替换为跳转到你的函数地址)。

动态链接:

功能balance.tare需要一个函数指针作为输入,并通过指针调用该函数(如果需要的话,即,推压输入参数并跳转到尖功能)。

根本没有符号解析 - 无论是编译期间还是链接期间(可以说函数调用在运行时都是“解决的”)。

这使您可以在每次调用函数balance.tare时调用不同的函数。

唯一的缺点可能是输入参数的附加内存读取操作,该操作会存储您的函数的地址,以便跳转到该函数。

这不是跳转到一个已知的(常量)地址。

但它确实取决于平台,也就是说,某些HW体系结构可以在单个指令内执行此操作(就像任何其他函数调用一样)。


就你而言,图书馆的所有者选择了后者。

用例:

void MyAfterTaredCallbackFunction(void) 
{ 
    // Do some stuff 
} 

int main() 
{ 
    ... 
    balance.tare(100, MyAfterTaredCallbackFunction); 
    ... 
}