外部割り込みにチャタリング対策を施したライブラリになっている.イベントが発生するとタイマーを起動させ,時間を空けて再度ピンの状態を調べるのだ.フライトピンのみならず,分離検知機構にも利用できるぞ!!

Dependents:   Hybrid_main_FirstEdtion

ExternalTrigger.hpp

Committer:
Gaku0606
Date:
2017-07-17
Revision:
2:5545caf08e9c
Parent:
1:9164a72286f1

File content as of revision 2:5545caf08e9c:

#ifndef _EXTERNAL_TRIGGER_HPP_
#define _EXTERNAL_TRIGGER_HPP_

#include "mbed.h"

/**
*  @file ExternalTrigger.hpp
*  @author Gaku Matsumoto
*  @data 2016/01/28
*/

/**
*  立ち上がりか立ち下がりかを決める引数
*/
typedef enum{
    RISE = 1,
    FALL = 0
}InterruptMode;

/**
*  @bref ピン変化割り込みをより身近にするためのライブラリです
*  @author Gaku MATSUMOTO
*  @note 別に使わなくてもいいです
*/
class ExtTrigger{
    public:
        /**
        *  @bref コンストラクタ,ピン割り込みを設定したいピン番号と割り込みモードを設定
        *  @param[in] pin ピン番号 ex)p12
        *  @param[in] mode RISE:立ち上がり割り込み, FALL:立ち下がり割り込み
        *  @param[in] seconds チャタリング待ち時間
        *  @note チャタリング待ち時間は引数無しだと無効になります.
        */
        ExtTrigger(PinName pin, InterruptMode mode, float seconds = 0.0);
        
        /**
        *  @bref コンストラクタ,ピン割り込みを設定したいピン番号と割り込みモードを設定
        *  @param[in] pin ピン番号 ex)p12
        *  @param[in] mode RISE:立ち上がり割り込み, FALL:立ち下がり割り込み
        *  @param[in] *func イベントが発生したときに呼び出す関数のアドレス
        *  @param[in] seconds チャタリング待ち時間
        *  @note チャタリング待ち時間は引数無しだと無効になります
        */
        ExtTrigger(PinName pin, InterruptMode mode, void (*func)(), float seconds = 0.0);
        
        /**
        *  @bref デストラクタ,割り込みピンを開放します.
        */
        ~ExtTrigger(){
            _pin.disable_irq();  
        };
        
    public:
        
        /**
        *  @bref 指定したピンをプルダウンに設定します
        */
        void setPullDown();
        
        /**
        *  @bref 指定したピンをプルアップ設定します
        */
        void setPullUp();
        
        /**
        *   @bref 指定したピンをオープンにします.
        */
        void setPullNone();
        
        /**
        *   フラグが立っているかどうかを確認します
        *   @return 1: 指定した動作が行われた,0: まだイベントは起きていない
        */
        int judgement();
        
        /**
        * @bref フラグを強制的に下げます.
        */
        void clear();
        
        /**
        *   @bref チャタリング対策として,最初のトリガーから設定した時間経った後再度確認するタイマーをセットします.
        *   @param[in] seconds float型,[秒]
        */
        void antiChattering(float seconds);
        
        /**
        *  @bref 呼び出される関数を後から設定したり,変更します.
        *  @note インスタンス生成のときに入れた方がいいかもしれません.
        */
        void setCallFunc(void (*func)());
        
        /**
        * @bref ピンの状態を読み取る
        */
        int read(){
            return _pin.read();   
        }
        
    private:
        Timeout antiC_timer;
        float _sec;
        ExtTrigger* _ext;
        InterruptIn _pin;
        void (*callFunc)();
        int userFuncFlag;
        void checkAgain();
        void interruptFunc();
        int flag;
        InterruptMode _mode;
};

ExtTrigger::ExtTrigger(PinName pin, InterruptMode mode, float seconds) : _pin(pin){
    userFuncFlag = 0;
    _mode = mode;
    _sec = seconds;
    _ext = this;
    flag = 0;
    //立ち上がり割り込み設定
    if(mode == RISE){
        _pin.rise(_ext, &ExtTrigger::interruptFunc);   
    }
    //立ち下がり割り込み設定
    else if (mode == FALL){
        _pin.fall(_ext, &ExtTrigger::interruptFunc);   
    }
    else{
        error("ExternalTrigger error\r\n");   
    }
}

ExtTrigger::ExtTrigger(PinName pin, InterruptMode mode, void (*func)(), float seconds) : _pin(pin){
    
    userFuncFlag = 0;
    _mode = mode;
    _sec = seconds;
    _ext = this;
    flag = 0;
    callFunc = *func;
    userFuncFlag = 1;
    //立ち上がり割り込み設定
    if(mode == RISE){
        _pin.rise(_ext, &ExtTrigger::interruptFunc);   
    }
    //立ち下がり割り込み設定
    else if (mode == FALL){
        _pin.fall(_ext, &ExtTrigger::interruptFunc);   
    }
    else{
        error("ExternalTrigger error\r\n");   
    }
}

int ExtTrigger::judgement(){
    return flag; 
}

void ExtTrigger::clear(){
    flag = 0;
    return;   
}

void ExtTrigger::antiChattering(float seconds){
    _sec = seconds;
    return;   
}

void ExtTrigger::setCallFunc(void (*func)()){
    if(*func != NULL){
        userFuncFlag = 1;
        callFunc = *func;//関数のアドレスを保存
    }
    else{
        userFuncFlag = 0;   
    }
}

void ExtTrigger::interruptFunc(){
    //タイマーセット
    flag = 0;
    if(_sec != 0.0){
        antiC_timer.attach(_ext, &ExtTrigger::checkAgain, _sec);
    }
    else{
        flag = 1;
        if(userFuncFlag) (*callFunc)();   
    }
    return;
}

void ExtTrigger::checkAgain(){
    if(_mode == RISE){
        if(_pin.read() == 1) flag = 1;
        else flag = 0;
    }
    else{
        if(_pin.read() == 0) flag = 1;   
        else flag = 0;
    }
    
    if(userFuncFlag && flag)    (*callFunc)();
    return;
}

void ExtTrigger::setPullDown(){
    _pin.mode(PullDown);
    return;   
}

void ExtTrigger::setPullUp(){
    _pin.mode(PullUp);
    return;
}

void ExtTrigger::setPullNone(){
    _pin.mode(PullNone);
    return;   
}

#endif