2016-08-11 2 views
0

Ich erstelle eine Arduino-Bibliothek für den Einsatz in einer Skizze. Es nutzt die Encoder Library, aber wenn ich einen stumpfen Fehler erhalten Kompilieren:Keine passende Funktion für Aufruf in Arduino Library

/var/folders/jy/f8dvlhcd4vdcvtl49bk8ytwc0000gn/T/builda847c0675e0bee2f5f05581e35ae65fe.tmp/sketch/MIDIEncoder.cpp: In constructor 'MIDIEncoder::MIDIEncoder(uint8_t, uint8_t, byte, byte)': MIDIEncoder.cpp:8: error: no matching function for call to 'Encoder::Encoder()' MIDIEncoder::MIDIEncoder(uint8_t pinA, uint8_t pinB, byte midiChannel, byte midiCCNumber) ^ /var/folders/jy/f8dvlhcd4vdcvtl49bk8ytwc0000gn/T/builda847c0675e0bee2f5f05581e35ae65fe.tmp/sketch/MIDIEncoder.cpp:8:89: note: candidates are: In file included from /var/folders/jy/f8dvlhcd4vdcvtl49bk8ytwc0000gn/T/builda847c0675e0bee2f5f05581e35ae65fe.tmp/sketch/MIDIEncoder.h:17:0, from /var/folders/jy/f8dvlhcd4vdcvtl49bk8ytwc0000gn/T/builda847c0675e0bee2f5f05581e35ae65fe.tmp/sketch/MIDIEncoder.cpp:2: /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Encoder/Encoder.h:72:2: note: Encoder::Encoder(uint8_t, uint8_t) Encoder(uint8_t pin1, uint8_t pin2) { ^ /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Encoder/Encoder.h:72:2: note: candidate expects 2 arguments, 0 provided /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Encoder/Encoder.h:69:7: note: constexpr Encoder::Encoder(const Encoder&) class Encoder ^ /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Encoder/Encoder.h:69:7: note: candidate expects 1 argument, 0 provided /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Encoder/Encoder.h:69:7: note: constexpr Encoder::Encoder(Encoder&&) /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Encoder/Encoder.h:69:7: note: candidate expects 1 argument, 0 provided no matching function for call to 'Encoder::Encoder()'

Im Grunde glaube ich, der Compiler sagt mir, es kann keinen Konstruktor für die Encoder-Bibliothek finden MIDIEncoder.cpp:8: error: no matching function for call to 'Encoder::Encoder()', aber ich bin ratlos, wie zu Warum. Im Folgenden finden Sie die vollständige Quelle für meine Bibliothek.

MIDIEncoder.h

/* 
    MIDIEncoder.h 
    A library for creating relative MIDI CC messages from a rotary encoder. 

    Created by Paul Williamson, 11 August 2016. 

    Project source available at: 
    http://github.com/squarefrog/teensy-midi-encoder-box 

    Released into the public domain. 
*/ 

#ifndef MIDIEncoder_h 
#define MIDIEncoder_h 

#include "Arduino.h" 
#include <Encoder.h> 

class MIDIEncoder 
{ 
    public:  
    MIDIEncoder(uint8_t pin1, uint8_t pin2, byte midiChannel, byte midiCCNumber); 
    byte channel; 
    byte ccNumber; 

    byte read(); 

    private: 
    unsigned long _lastTurnedTime; 
    long _oldPosition; 
    Encoder _enc; 
}; 

#endif 

MIDIEncoder.cpp

#include "MIDIEncoder.h" 
#include <Encoder.h> 

const byte incrementValue = 66; // A constant for the start of increment values 
const byte decrementValue = 2; // A constant for the start of decrement values 

MIDIEncoder::MIDIEncoder(uint8_t pin1, uint8_t pin2, byte midiChannel, byte midiCCNumber) 
{ 
    channel = midiChannel; 
    ccNumber = midiCCNumber; 
    _enc = Encoder(pin1, pin2); 
    _oldPosition = -999; 
    _lastTurnedTime = millis(); 
} 

byte MIDIEncoder::read() 
{ 
    long newPosition = _enc.read(); 

    // If position hasn't changed, ignore. 
    if (newPosition == _oldPosition) { 
    return 0; 
    } 

    // If position is not divisible by 4, ignore. 
    if (newPosition % 4 != 0) { 
    return 0; 
    } 

    unsigned long delta = millis() - _lastTurnedTime; 
    byte offset = 0; 

    // Apply crude acceleration 
    if (delta < 100) offset = 4; 
    if (delta > 99 && delta < 180) offset = 2; 
    if (delta > 179 && delta <= 250) offset = 1; 

    _lastTurnedTime = millis(); 

    // Return MIDI CC value 
    if (newPosition > _oldPosition) { 
    return incrementValue + offset; 
    } else { 
    return decrementValue + offset; 
    } 
} 

Einige ausgezeichnete Antworten unten. Nun, da ich weiß, worauf ich achten muss, habe ich this resource gefunden, was erklärt, wo ich meinen Fehler gemacht habe. Insbesondere Blick auf Nummer 3.

Antwort

2

Encoder keinen Default-Konstruktor, und es wird hier implizit

MIDIEncoder::MIDIEncoder(uint8_t pin1, uint8_t pin2, byte midiChannel, byte midiCCNumber) 
    /*Implicit constructor call*/ 
{ 
    //... 
} 

Sie haben versucht, es der der Konstruktor Körper zu nennen rufen, aber dann „es ist zu späte ":) Was ich meine ist, _enc muss bereits initialisiert werden, wenn der Konstruktor Körper ausgeführt wird, aber _enc kann nicht standardmäßig initialisiert werden, so beschwert sich der Compiler.

Das ist, was der Konstruktor Initialisiererliste ist für:

MIDIEncoder::MIDIEncoder(uint8_t pin1, uint8_t pin2, byte midiChannel, byte midiCCNumber) 
    : _enc(pin1, pin2) //Calls appropriate constructor for _enc, not default 
{ 
    //... 
} 
+0

Oh snap. Ich dachte, dass der Variablenname in der Header-Deklaration nur ein Platzhalter für die Verwendung in der Implementierungsdatei war. Das hätte ich nie herausgefunden. – squarefrog

+0

Tatsächlich ruft die Deklaration in der Kopfzeile keinen Konstruktor auf. Der Standardkonstruktor wird implizit innerhalb des Konstruktors "MIDIEncoder" zusammen mit Konstruktoren für die anderen Mitgliedsvariablen aufgerufen (ist nicht anders angegeben). –

+0

Ich dachte, ich würde den Konstruktor mit 'Encoder (pin1, pin2) aufrufen;'. Ich nehme an, es sind nur Objekte, die auf diese Weise konstruiert werden müssen. – squarefrog

1

Du bist zu spät, um Ihre _enc Objekt initialisiert wird.

Am Anfang des MIDIEncoder-Konstruktors sollte _enc bereits erstellt werden, daher versucht der Compiler, ihn mit dem (fehlenden) Standardkonstruktor zu instanziieren und schlägt fehl.

initialisieren es im Konstruktor Initialisierungsliste statt:

MIDIEncoder::MIDIEncoder(uint8_t pin1, uint8_t pin2, ...) : _enc(pin1, pin2) 
{ 

Eigentlich das Gleiche gilt für die anderen Variablen - es gibt keinen Grund, sie innerhalb Konstruktorrumpf zu initialisieren.

+0

Oh wirklich? Das ist, was ich in anderen Sprachen gewohnt bin, so ist es leicht zu sehen, wo ich diesen Fehler gemacht habe. Ich folgte mit dem Tutorial der Arduino-Bibliothek https: //www.arduino.cc/de/Hacking/LibraryTutorial, das den Konstruktor verwendet hat. – squarefrog

+0

'es gibt keinen Grund, es innerhalb Konstruktor Körper zu initialisieren.'Ich weiß, was du meinst, aber wird der Token Pedant sein! Man kann die Mitglieder im Körper einfach nicht initialisieren. Man kann ihnen nur _assign_. Aber ja, abgesehen von der Terminologie stimme ich zu, dass "es keinen Grund gibt". Alles, was in der Initialisierungsliste _ _ initialisiert werden kann, _ sollte _ sein, auch wenn man es stattdessen im Körper zuordnen könnte. Das ist nur semantisch korrekt und in vielen Fällen effizienter. Plus, für Objekt ist wie die OP, oder "const" Mitglieder, oder etc .... Initialisierung ist die ** nur ** mögliche Option. –

+0

Pedanterie ist willkommen, wenn Sie eine neue Sprache lernen! Also Objekte, Konstanten, alles andere offensichtlich, das soll dort instanziiert werden? – squarefrog

Verwandte Themen