7th_DENSOU / Encoder

Dependents:   Touteki_publish

Files at this revision

API Documentation at this revision

Comitter:
oshin1030
Date:
Wed Mar 18 13:00:13 2020 +0000
Commit message:
tweaked a little;

Changed in this revision

EC.cpp Show annotated file Show diff for this revision Revisions of this file
EC.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EC.cpp	Wed Mar 18 13:00:13 2020 +0000
@@ -0,0 +1,113 @@
+#include "mbed.h"
+#include "EC.h"
+
+
+Ec::Ec(int res,int multi):
+    count_(0),pre_count_(0),resolution_(res),multiplication_(multi)
+{
+    timer_.start();
+}
+
+int Ec::getCount()const
+{
+    return count_;
+}
+
+double Ec::getRad()const
+{
+    return count_*2.0f*M_PI/(multiplication_*resolution_);
+}
+
+void Ec::calOmega()
+{
+    double t=timer_.read();
+    omega_=(count_-pre_count_)*2.0f*M_PI/(multiplication_*resolution_*(t-ptw_));
+    pre_count_=count_;
+    ptw_=t;
+}
+
+double Ec::getOmega()const
+{
+    return omega_;
+}
+void Ec::setResolution(int res)
+{
+    resolution_=res;
+}
+
+/*reset関数の定義*/
+/*エンコーダを初期状態に戻すことができる*/
+void Ec::reset()
+{
+    count_=0;
+    pre_count_=0,omega_=0;
+    ptw_=0;
+    timer_.stop();
+    timer_.reset();
+    timer_.start();
+}
+
+
+////////////////////////////////////////////////////1逓倍//////////////////////////////////////////////////////////////////
+Ec1multi::Ec1multi(PinName signalA,PinName signalB,int res) : Ec(res,1),signalA_(signalA),signalB_(signalB)
+{
+    signalA_.rise(callback(this,&Ec1multi::upA));
+}
+
+//ピン変化割り込み関数の定義
+void Ec1multi::upA()
+{
+    if(signalB_.read())count_++;
+    else count_--;
+}
+////////////////////////////////////////////////////2逓倍//////////////////////////////////////////////////////////////////
+Ec2multi::Ec2multi(PinName signalA,PinName signalB,int res) : Ec(res,2),signalA_(signalA),signalB_(signalB)
+{
+    signalA_.rise(callback(this,&Ec2multi::upA));
+    signalA_.fall(callback(this,&Ec2multi::downA));
+}
+
+//ピン変化割り込み関数の定義
+void Ec2multi::upA()
+{
+    if(signalB_.read())count_++;
+    else count_--;
+}
+void Ec2multi::downA()
+{
+    if(signalB_.read())count_--;
+    else count_++;
+}
+
+////////////////////////////////////////////////////4逓倍//////////////////////////////////////////////////////////////////
+Ec4multi::Ec4multi(PinName signalA,PinName signalB,int res) : Ec(res,4),signalA_(signalA),signalB_(signalB),pa_(0),pb_(0)
+{
+    signalA_.rise(callback(this,&Ec4multi::upA));
+    signalA_.fall(callback(this,&Ec4multi::downA));
+    signalB_.rise(callback(this,&Ec4multi::upB));
+    signalB_.fall(callback(this,&Ec4multi::downB));
+}
+void Ec4multi::upA()
+{
+    pa_=1;
+    if(pb_==1)count_++;
+    else count_--;
+}
+void Ec4multi::downA()
+{
+    pa_=0;
+    if(pb_==1)count_--;
+    else count_++;
+}
+void Ec4multi::upB()
+{
+    pb_=1;
+    if(pa_==1)count_--;
+    else count_++;
+}
+void Ec4multi::downB()
+{
+    pb_=0;
+    if(pa_==1)count_++;
+    else count_--;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EC.h	Wed Mar 18 13:00:13 2020 +0000
@@ -0,0 +1,168 @@
+#ifndef _INCLUDED_EC_H_
+#define _INCLUDED_EC_H_
+
+#ifndef M_PI
+#define M_PI 3.14159265359f
+#endif
+
+/** @section SAMPLE
+* @code
+* //プログラム例
+* #include "mbed.h"
+* #include "EC.h"
+*
+* #define RESOLUTION 500
+* Ticker ticker;
+* Serial pc(USBTX,USBRX);
+*
+* //          (A層,B層,分解能)
+* Ec1multi EC(p7,p8,RESOLUTION);  //1逓倍用class
+* //            or
+* //Ec2multi EC(p7,p8,RESOLUTION);  //2逓倍用class
+* //            or
+* //Ec4multi EC(p7,p8,RESOLUTION);  //4逓倍用class
+* void calcOmega();
+*
+* int main()
+* {
+*     int count=0;
+*     double omega;
+*     ticker.attach(&calcOmega,0.05);
+* 
+*     while(1) {
+*         count=EC.getCount();
+*         omega=EC.getOmega();
+*         pc.printf("count=%d,",count);
+*         pc.printf("omega=%f\r\n",omega);
+*     }
+* }
+* void calcOmega()
+* {
+*     EC.calOmega();
+* }
+* @endcode
+*/
+
+/**
+* @brief increment型エンコーダ用class
+* @details 1逓倍:Ec1multi
+* 2逓倍:Ec2multi
+* 4逓倍:Ec4multi
+**/
+class Ec
+{
+protected:
+    int count_; //カウント数
+    double omega_;  //角速度(rad/s)
+    int pre_count_;  //一つ前のカウント
+    int resolution_;   //分解能
+    int multiplication_;
+    double ptw_;
+
+public:
+    /*コンストラクタの定義
+    1,2,4逓倍の元となるclass
+
+    @param res エンコーダの分解能
+    @param multi エンコーダの逓倍
+
+    @remarks このclassは各逓倍のclassに継承されるため、使用者が宣言する必要はない
+    */
+    Ec(int res,int multi);
+    /** @details エンコーダのcountを返す関数
+    * 1周のcount=分解能×逓倍
+    * @return count
+    */
+    int getCount()const;
+    /**
+    *   軸の回転角度を返す関数
+    *   @return θ[rad]
+    */
+    double getRad()const;
+    /**
+    * 軸の角速度を返す関数
+    * @return ω [rad/s]
+    */
+    
+    double getOmega()const;
+    /**
+    * 角速度を計算するための関数
+    * 微分を微小時間の変位として計算しているので、タイマー割込などで回さなければいけない
+    */
+    void calOmega();
+    /**
+    * 分解能を指定するための関数
+    * @param res エンコーダの分解能
+    */
+    void setResolution(int res);
+    ///エンコーダのcountやωをリセットするための関数
+    void reset();
+    Timer timer_;
+};
+///@brief increment型エンコーダ用class(1逓倍)
+class Ec1multi : public Ec
+{
+private:
+    InterruptIn signalA_;
+    DigitalIn signalB_;
+    void upA();
+public:
+    /**
+    * @brief コンストラクタの定義
+    * @details main関数の前に必ず一度宣言する
+    * 使うエンコーダの数だけ設定する必要がある
+
+    @ param signalA エンコーダのA相のピン名
+    @ param signalB エンコーダのB相のピン名
+    @ param res エンコーダの分解能
+    @ remark 2,4逓倍も同様
+    */
+    Ec1multi(PinName signalA,PinName signalB,int res);
+};
+///@brief increment型エンコーダ用class(2逓倍)
+class Ec2multi : public Ec
+{
+private:
+    InterruptIn signalA_;
+    DigitalIn signalB_;
+    void upA();
+    void downA();
+public:
+    /**
+    * @brief コンストラクタの定義
+    * @details main関数の前に必ず一度宣言する
+    * 使うエンコーダの数だけ設定する必要がある
+
+    @ param signalA エンコーダのA相のピン名
+    @ param signalB エンコーダのB相のピン名
+    @ param res エンコーダの分解能
+    */
+    Ec2multi(PinName signalA,PinName signalB,int res);
+};
+///@brief increment型エンコーダ用class(4逓倍)
+class Ec4multi : public Ec
+{
+private:
+    InterruptIn signalA_;
+    InterruptIn signalB_;
+    void upA();
+    void downA();
+    void upB();
+    void downB();
+    int pa_,pb_;
+public:
+    /**
+    * @brief コンストラクタの定義
+    * @details main関数の前に必ず一度宣言する
+    * 使うエンコーダの数だけ設定する必要がある
+
+    @ param signalA エンコーダのA相のピン名
+    @ param signalB エンコーダのB相のピン名
+    @ param res エンコーダの分解能
+    */
+    Ec4multi(PinName signalA,PinName signalB,int res);
+};
+
+
+
+#endif
\ No newline at end of file