2013-03-27 8 views
5

मैं एक अल्ट्रासोनिक दूरी सेंसर के लिए एक साधारण लाइब्रेरी लिख रहा हूं और सोचा कि मैं इंटरप्ट्स का उपयोग करने का प्रयास करूंगा।लाइब्रेरी में attachInterrupt का उपयोग नहीं कर सकता

हालांकि मैं अपने कार्यों को attachCallback विधि में ठीक से सेट नहीं कर सकता।

मुझे HCSR04Interrupt::echoHigh() और HCSR04Interrupt::echoLow() कहा जाता है जब पिन क्रमशः उच्च और निम्न हो जाता है।

मैंने इसका कोई फायदा नहीं हुआ है। Ardiuno आईडीई कहते हैं निम्नलिखित:

#ifndef _HCSR04Interrupt_ 
#define _HCSR04Interrupt_ 

#include "Arduino.h" 

#define HCSR04_CM_FACTOR 58.0 
#define HCSR04_IN_FACTOR 148.0 
#define HCSR04_CM_MODE 0 
#define HCSR04_IN_MODE 1 

class HCSR04Interrupt { 
    public: 
    double distance; 

    HCSR04Interrupt(int trigger_pin, int echo_pin, void (*callback)()); 

    void setUnits(int units); 

    void getDistance(); 
    private: 
    int _trigger_pin; 
    int _echo_pin; 
    int _units; 
    unsigned long _micros_start; 
    void (*_callback)(); 

    void initialize(); 
    void echoHigh(); 
    void echoLow(); 
}; 

#endif 

और मेरे कार्यान्वयन (पूरा नहीं कर सकते, क्योंकि मैं अतीत attachInterrupt कदम मिल):

./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp: In member function 'void HCSR04Interrupt::getDistance()': 
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp:31: error: argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()' 
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp: In member function 'void HCSR04Interrupt::echoHigh()': 
./Arduino/libraries/HCSR04/HCSR04Interrupt.cpp:47: error: argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)()' 

यहाँ मेरी शीर्ष लेख है

#include "Arduino.h" 
#include "HCSR04Interrupt.h" 

HCSR04Interrupt::HCSR04Interrupt(int trigger_pin, int echo_pin, void (*callback)()) { 
    _trigger_pin = trigger_pin; 
    _echo_pin = echo_pin; 
    _callback = callback; 

    initialize(); 
} 

void HCSR04Interrupt::setUnits(int units) { 
    _units = units; 
} 

void HCSR04Interrupt::initialize() { 
    pinMode(_trigger_pin, OUTPUT); 
    pinMode(_echo_pin, INPUT); 

    digitalWrite(_trigger_pin, LOW); 
} 

void HCSR04Interrupt::getDistance() { 
    //Listen for the RISING interrupt 
    attachInterrupt(_echo_pin - 2, echoHigh, RISING); 

    //The trigger pin should be pulled high, 
    digitalWrite(_trigger_pin, HIGH); 

    //for 10 us. 
    delayMicroseconds(20); 

    //Then reset it. 
    digitalWrite(_trigger_pin, LOW); 
} 

void HCSR04Interrupt::echoHigh() { 
    _micros_start = micros(); 

    detachInterrupt(_echo_pin - 2); 
    attachInterrupt(_echo_pin - 2, echoLow, FALLING); 
} 

void HCSR04Interrupt::echoLow() { 
    detachInterrupt(_echo_pin - 2); 

    unsigned long us = micros() - _micros_start; 

    distance = us; 

    (*_callback)(); 
} 

उत्तर

2

Arduino हस्तक्षेप हैंडलर केवल कार्य हो सकते हैं। आप एक ऑब्जेक्ट एक इंटरप्ट हैंडलर की विधि बनाने का प्रयास कर रहे हैं। इसलिए संकलक शिकायत करता है।

इसके बारे में अधिक सटीक होने के लिए, ऑब्जेक्ट विधियां फ़ंक्शंस की तरह हैं, लेकिन ऐसा लगता है जैसे वे "छुपा" पैरामीटर लेते हैं, जो ऑब्जेक्ट इंस्टेंस निर्दिष्ट करता है। इसलिए, वे वास्तव में सादे कार्यों से अलग प्रकार के हस्ताक्षर होते हैं। यह एक विधि सूचक को पास करने के लिए अनुमति देता है जब कोई फ़ंक्शन ढूंढ रहा है वह सादा फ़ंक्शन पॉइंटर है।

समाधान echoHigh() और echoLow()HCSR04Interrupt कक्षा में से स्थानांतरित करना है, और उन्हें सादे कार्य करना है।

5

तो संकलक (नहीं आईडीई) बताता है कि वास्तव में क्या गलत है:,

argument of type 'void (HCSR04Interrupt::)()' does not match 'void (*)() 

तो attachInterrupt() प्रकार void (*)() के एक समारोह सूचक लेता है, तो आप इसे एक गैर पारित करने के लिए कोशिश कर रहे हैं स्थैतिक सदस्य समारोह, जो आप नहीं कर सकते हैं। आप सदस्य समारोह static और कास्टिंग बनाने की कोशिश कर सकते:

static void echoHigh(); 

// ... 

attachInterrupt(_echo_pin - 2, reinterpret_cast<void (*)()>(&echoHigh), RISING); 
+0

attachInterrupt कि समारोह में यह बताते हैं होने के लिए आवश्यकता होती है स्थैतिक। और उसके बाद सभी सदस्य कार्य संलग्नक से ऊपर की ओर स्थिर होते हैं। मैंने यह सफलतापूर्वक किया है। – mpflaga

0

मैं एक singleton आधार वर्ग जो एक पूरे के रूप हार्डवेयर (जो थोड़े इस स्थिति में समझ में आता है वैसे भी) का प्रतिनिधित्व करता बनाकर इस पर मिल गया।

किसी भी फ़ंक्शन पॉइंटर्स को उप-घटक वर्ग में पास किया जा सकता है, और सिंगलटन द्वारा संभाला जा सकता है, जिसका सदस्य चर और विधियां सभी स्थिर हैं।

उदाहरण हेडर (untested):

// Sub-component 
class LampButton { 
public: 
    LampButton(int pin, void(*pushHandler)()); 
} 

// Sub-component 
class LampLed { 
public: 
    LampLed(int pin); 
    void toggle(); 
} 

// Singleton represents the hardware in it's entirety 
class Lamp { 
public: 
    // Call this instead of a constructor 
    static void initialize(int buttonPin, int ledPin); 

    // Function implemented inline for clarity - don't do this 
    static void handleButtonPush() { 
     led.toggle(); 
    } 

private: 
    static LampButton button; 
    static LampLed led; 
} 
1

के रूप में मैं इस सवाल पर ठोकर खाई और यह एक स्वीकार किए जाते हैं जवाब नहीं पड़ा है, मैं लिखने मैं क्या पाया है, जो मेरे लिए काम किया:

बाधा एक वैश्विक रैपर द्वारा बुलाया जाना है। इस रैपर को कक्षा के handleInterupt फ़ंक्शन को कॉल करने की आवश्यकता है। इसलिए इसे कक्षा को जानना है। यह इसे वैश्विक चर में संग्रहीत करके किया जा सकता है। यदि कक्षा के कई उदाहरणों का उपयोग किया जाना चाहिए, तो ऐसे कई वैश्विक चर का उपयोग किया जाना चाहिए।एक संदर्भ के रूप में देखने

MyClass theInstance_pin3 = NULL; 
MyClass theInstance_pin7 = NULL; 

// Somewhere, fill in an initialized copy of MyClass, 
// and set theInstance_pin3 or theInstance_pin7 to it 

void ISR_3() 
{ 
    if (theInstance_pin3) 
     theInstance_pin3->handleInterrupt(); 
} 
void ISR_7() 
{ 
    if (theInstance_pin7) 
     theInstance_pin7->handleInterrupt(); 
} 

:: लेकिन के रूप में व्यवधान पिन बस कुछ कर रहे हैं आप एक वैश्विक चर और हर पिन के लिए समारोह में लिख सकते हैं http://forum.arduino.cc/index.php?topic=41713.0 या http://forum.arduino.cc/index.php?topic=160101.0

संबंधित मुद्दे