Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of EC by
EC.h@0:20fc96400ca3, 2016-06-16 (annotated)
- Committer:
- jack0325suzu
- Date:
- Thu Jun 16 07:36:15 2016 +0000
- Revision:
- 0:20fc96400ca3
- Child:
- 1:d10ca555a103
????????????????
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| jack0325suzu | 0:20fc96400ca3 | 1 | #ifndef __INCLUDED_EC_H_ |
| jack0325suzu | 0:20fc96400ca3 | 2 | #define __INCLUDED_EC_H_ |
| jack0325suzu | 0:20fc96400ca3 | 3 | |
| jack0325suzu | 0:20fc96400ca3 | 4 | #ifndef M_pi |
| jack0325suzu | 0:20fc96400ca3 | 5 | #define M_pi 3.141592 |
| jack0325suzu | 0:20fc96400ca3 | 6 | #endif |
| jack0325suzu | 0:20fc96400ca3 | 7 | /**increment型encoder用class*/ |
| jack0325suzu | 0:20fc96400ca3 | 8 | |
| jack0325suzu | 0:20fc96400ca3 | 9 | class Ec{ |
| jack0325suzu | 0:20fc96400ca3 | 10 | private: |
| jack0325suzu | 0:20fc96400ca3 | 11 | int S; //A相B相のパターン(1~4) |
| jack0325suzu | 0:20fc96400ca3 | 12 | bool stateA,stateB; //A・B相の状態 |
| jack0325suzu | 0:20fc96400ca3 | 13 | int count; //カウント数 分解能分で一周 |
| jack0325suzu | 0:20fc96400ca3 | 14 | int pre_count; //一つ前のカウント |
| jack0325suzu | 0:20fc96400ca3 | 15 | double precount; //4倍精度カウント |
| jack0325suzu | 0:20fc96400ca3 | 16 | int solution; //分解能 |
| jack0325suzu | 0:20fc96400ca3 | 17 | double dt; //角速度の計算間隔 |
| jack0325suzu | 0:20fc96400ca3 | 18 | |
| jack0325suzu | 0:20fc96400ca3 | 19 | |
| jack0325suzu | 0:20fc96400ca3 | 20 | InterruptIn signalA_; |
| jack0325suzu | 0:20fc96400ca3 | 21 | InterruptIn signalB_; |
| jack0325suzu | 0:20fc96400ca3 | 22 | |
| jack0325suzu | 0:20fc96400ca3 | 23 | void upA(); |
| jack0325suzu | 0:20fc96400ca3 | 24 | void downA(); |
| jack0325suzu | 0:20fc96400ca3 | 25 | void upB(); |
| jack0325suzu | 0:20fc96400ca3 | 26 | void downB(); |
| jack0325suzu | 0:20fc96400ca3 | 27 | |
| jack0325suzu | 0:20fc96400ca3 | 28 | public: |
| jack0325suzu | 0:20fc96400ca3 | 29 | double omega; //角速度 |
| jack0325suzu | 0:20fc96400ca3 | 30 | /** コンストラクタの定義 |
| jack0325suzu | 0:20fc96400ca3 | 31 | * |
| jack0325suzu | 0:20fc96400ca3 | 32 | * main関数の前に必ず一度宣言する |
| jack0325suzu | 0:20fc96400ca3 | 33 | * |
| jack0325suzu | 0:20fc96400ca3 | 34 | * 使うエンコーダの数だけ設定する必要がある |
| jack0325suzu | 0:20fc96400ca3 | 35 | * |
| jack0325suzu | 0:20fc96400ca3 | 36 | * @param signalA エンコーダA相のピン名 |
| jack0325suzu | 0:20fc96400ca3 | 37 | * @param signalB エンコーダB相のピン名 |
| jack0325suzu | 0:20fc96400ca3 | 38 | * @param s エンコーダの分解能(省略可) |
| jack0325suzu | 0:20fc96400ca3 | 39 | * @param t 角速度計算の間隔(省略可) |
| jack0325suzu | 0:20fc96400ca3 | 40 | */ |
| jack0325suzu | 0:20fc96400ca3 | 41 | Ec(PinName signalA,PinName signalB,int s,double t); |
| jack0325suzu | 0:20fc96400ca3 | 42 | |
| jack0325suzu | 0:20fc96400ca3 | 43 | ///countの値を返す関数(int型) |
| jack0325suzu | 0:20fc96400ca3 | 44 | int getCount(); |
| jack0325suzu | 0:20fc96400ca3 | 45 | ///omega(角速度 rad/s)の値を計算する関数 |
| jack0325suzu | 0:20fc96400ca3 | 46 | /** @section CAUTION |
| jack0325suzu | 0:20fc96400ca3 | 47 | * CalOmega関数は、一定時間ごと(dtごと)に計算される必要があるので、main関数内でタイマー割り込みを設定する必要がある。 |
| jack0325suzu | 0:20fc96400ca3 | 48 | * @code |
| jack0325suzu | 0:20fc96400ca3 | 49 | * #include "mbed.h" |
| jack0325suzu | 0:20fc96400ca3 | 50 | * #include "EC.h" |
| jack0325suzu | 0:20fc96400ca3 | 51 | * |
| jack0325suzu | 0:20fc96400ca3 | 52 | * Ec Ec1(PA_0,PA_1,1024,0.05); //分解能1024、計算間隔0.05秒に設定 |
| jack0325suzu | 0:20fc96400ca3 | 53 | * Ticker ticker; |
| jack0325suzu | 0:20fc96400ca3 | 54 | * DigitalIn button(USER_BUTTON); |
| jack0325suzu | 0:20fc96400ca3 | 55 | * Serial pc(USBTX,USBRX); |
| jack0325suzu | 0:20fc96400ca3 | 56 | * |
| jack0325suzu | 0:20fc96400ca3 | 57 | * void calOmega(){ |
| jack0325suzu | 0:20fc96400ca3 | 58 | * Ec1.CalOmega(); |
| jack0325suzu | 0:20fc96400ca3 | 59 | * } |
| jack0325suzu | 0:20fc96400ca3 | 60 | * |
| jack0325suzu | 0:20fc96400ca3 | 61 | * int main(){ |
| jack0325suzu | 0:20fc96400ca3 | 62 | * ticker.attach(&calOmega,0.05); //0.05秒間隔で角速度を計算 |
| jack0325suzu | 0:20fc96400ca3 | 63 | * while(1){ |
| jack0325suzu | 0:20fc96400ca3 | 64 | * pc.printf(" count1=%d ",Ec1.getCount()); |
| jack0325suzu | 0:20fc96400ca3 | 65 | * pc.printf(" omega1=%f\r\n ",Ec1.getOmega()); |
| jack0325suzu | 0:20fc96400ca3 | 66 | * if(button) Ec1.reset(); //USERボタンを押したらリセット |
| jack0325suzu | 0:20fc96400ca3 | 67 | * } |
| jack0325suzu | 0:20fc96400ca3 | 68 | * } |
| jack0325suzu | 0:20fc96400ca3 | 69 | * @endcode |
| jack0325suzu | 0:20fc96400ca3 | 70 | */ |
| jack0325suzu | 0:20fc96400ca3 | 71 | void CalOmega(); |
| jack0325suzu | 0:20fc96400ca3 | 72 | ///omega(角速度 rad/s)の値を返す関数(double型) |
| jack0325suzu | 0:20fc96400ca3 | 73 | double getOmega(); |
| jack0325suzu | 0:20fc96400ca3 | 74 | ///四倍精度のcountの値を返す関数(double型) |
| jack0325suzu | 0:20fc96400ca3 | 75 | double getPreCount(); |
| jack0325suzu | 0:20fc96400ca3 | 76 | ///エンコーダを初期状態に戻す関数 countやomegaの値を0にする |
| jack0325suzu | 0:20fc96400ca3 | 77 | void reset(); |
| jack0325suzu | 0:20fc96400ca3 | 78 | ///角速度計算の間隔dtを決めることができる(デフォルトは0.05秒) |
| jack0325suzu | 0:20fc96400ca3 | 79 | void setTime(double t); |
| jack0325suzu | 0:20fc96400ca3 | 80 | |
| jack0325suzu | 0:20fc96400ca3 | 81 | ///角速度計算の間隔 |
| jack0325suzu | 0:20fc96400ca3 | 82 | static double deftime; |
| jack0325suzu | 0:20fc96400ca3 | 83 | ///エンコーダの分解能のデフォルト値 |
| jack0325suzu | 0:20fc96400ca3 | 84 | static int defsolution; |
| jack0325suzu | 0:20fc96400ca3 | 85 | |
| jack0325suzu | 0:20fc96400ca3 | 86 | |
| jack0325suzu | 0:20fc96400ca3 | 87 | |
| jack0325suzu | 0:20fc96400ca3 | 88 | }; |
| jack0325suzu | 0:20fc96400ca3 | 89 | |
| jack0325suzu | 0:20fc96400ca3 | 90 | ///速度制御用class |
| jack0325suzu | 0:20fc96400ca3 | 91 | ///Ec classを継承している |
| jack0325suzu | 0:20fc96400ca3 | 92 | /** @section Example |
| jack0325suzu | 0:20fc96400ca3 | 93 | * @code |
| jack0325suzu | 0:20fc96400ca3 | 94 | * #include "mbed.h" |
| jack0325suzu | 0:20fc96400ca3 | 95 | * #include "EC.h" //ヘッダファイルをインクルード |
| jack0325suzu | 0:20fc96400ca3 | 96 | * |
| jack0325suzu | 0:20fc96400ca3 | 97 | * SpeedControl motor1(PA_0,PA_1,1024,0.05,PB_8,PB_9); //エンコーダ分解能1024、角速度計算間隔を0.05秒に設定 |
| jack0325suzu | 0:20fc96400ca3 | 98 | * Ticker ticker; //角速度計算用ticker |
| jack0325suzu | 0:20fc96400ca3 | 99 | * DigitalIn button(USER_BUTTON); |
| jack0325suzu | 0:20fc96400ca3 | 100 | * Serial pc(USBTX,USBRX); |
| jack0325suzu | 0:20fc96400ca3 | 101 | * |
| jack0325suzu | 0:20fc96400ca3 | 102 | * void calOmega() //角速度計算関数 |
| jack0325suzu | 0:20fc96400ca3 | 103 | * { |
| jack0325suzu | 0:20fc96400ca3 | 104 | * motor1.CalOmega(); |
| jack0325suzu | 0:20fc96400ca3 | 105 | * } |
| jack0325suzu | 0:20fc96400ca3 | 106 | * |
| jack0325suzu | 0:20fc96400ca3 | 107 | * int main() |
| jack0325suzu | 0:20fc96400ca3 | 108 | * { |
| jack0325suzu | 0:20fc96400ca3 | 109 | * ticker.attach(&calOmega,0.05); //0.05秒間隔で角速度を計算 |
| jack0325suzu | 0:20fc96400ca3 | 110 | * motor1.setPIDparam(0.15,0.0,0.15); //PIDパラメータを設定 |
| jack0325suzu | 0:20fc96400ca3 | 111 | * motor1.setDOconstant(46.3); //duty比と角速度の変換係数を46.3に設定 |
| jack0325suzu | 0:20fc96400ca3 | 112 | * |
| jack0325suzu | 0:20fc96400ca3 | 113 | * int kai=0; |
| jack0325suzu | 0:20fc96400ca3 | 114 | * |
| jack0325suzu | 0:20fc96400ca3 | 115 | * while(1) { |
| jack0325suzu | 0:20fc96400ca3 | 116 | * motor1.Sc(-10); //角速度10rad/sで逆回転 |
| jack0325suzu | 0:20fc96400ca3 | 117 | * if(kai>=500){ //ループ500回ごとに角速度・出力duty比を表示 |
| jack0325suzu | 0:20fc96400ca3 | 118 | * pc.printf("omega=%f duty=%f \r\n",motor1.getOmega(),motor1.duty); |
| jack0325suzu | 0:20fc96400ca3 | 119 | * kai=0; |
| jack0325suzu | 0:20fc96400ca3 | 120 | * } |
| jack0325suzu | 0:20fc96400ca3 | 121 | * if(!button) break; //ボタンを押したら停止 |
| jack0325suzu | 0:20fc96400ca3 | 122 | * kai++; |
| jack0325suzu | 0:20fc96400ca3 | 123 | * } |
| jack0325suzu | 0:20fc96400ca3 | 124 | * motor1.stop(); |
| jack0325suzu | 0:20fc96400ca3 | 125 | * } |
| jack0325suzu | 0:20fc96400ca3 | 126 | * @endcode |
| jack0325suzu | 0:20fc96400ca3 | 127 | */ |
| jack0325suzu | 0:20fc96400ca3 | 128 | |
| jack0325suzu | 0:20fc96400ca3 | 129 | |
| jack0325suzu | 0:20fc96400ca3 | 130 | class SpeedControl : public Ec{ |
| jack0325suzu | 0:20fc96400ca3 | 131 | private: |
| jack0325suzu | 0:20fc96400ca3 | 132 | double Kv_p,Kv_d,Kv_i; |
| jack0325suzu | 0:20fc96400ca3 | 133 | double diff,diff_old,integral; |
| jack0325suzu | 0:20fc96400ca3 | 134 | double out_duty,out; |
| jack0325suzu | 0:20fc96400ca3 | 135 | |
| jack0325suzu | 0:20fc96400ca3 | 136 | protected: |
| jack0325suzu | 0:20fc96400ca3 | 137 | PwmOut pwm_F_; |
| jack0325suzu | 0:20fc96400ca3 | 138 | PwmOut pwm_B_; |
| jack0325suzu | 0:20fc96400ca3 | 139 | |
| jack0325suzu | 0:20fc96400ca3 | 140 | public: |
| jack0325suzu | 0:20fc96400ca3 | 141 | /** constractorの定義 |
| jack0325suzu | 0:20fc96400ca3 | 142 | * @param signalA encoderA相のピン名 |
| jack0325suzu | 0:20fc96400ca3 | 143 | * @param signalB encoderB相のピン名 |
| jack0325suzu | 0:20fc96400ca3 | 144 | * @param s encoderの分解能(省略可) |
| jack0325suzu | 0:20fc96400ca3 | 145 | * @param t 角速度計算の間隔(省略可) |
| jack0325suzu | 0:20fc96400ca3 | 146 | * @param pwm_F motorを正転させるpwmピン名 |
| jack0325suzu | 0:20fc96400ca3 | 147 | * @param pwm_B motorを後転させるpwmピン名 |
| jack0325suzu | 0:20fc96400ca3 | 148 | * motorを正転させるとencoderのcountが正のほうに加算されるようにencoderとmotorを設置する |
| jack0325suzu | 0:20fc96400ca3 | 149 | */ |
| jack0325suzu | 0:20fc96400ca3 | 150 | SpeedControl( PinName signalA , PinName signalB , int s, double t, PinName pwm_F , PinName pwm_B); |
| jack0325suzu | 0:20fc96400ca3 | 151 | /** duty比を角速度に変換させるための定数 |
| jack0325suzu | 0:20fc96400ca3 | 152 | * |
| jack0325suzu | 0:20fc96400ca3 | 153 | * 使うモーターやギア比や供給電圧によって変化するので一度duty比と角速度の関係を調べてグラフの傾きから求める |
| jack0325suzu | 0:20fc96400ca3 | 154 | * |
| jack0325suzu | 0:20fc96400ca3 | 155 | * 多少ずれてもPIDが何とかしてくれるのでそこまでの精度は必要ない |
| jack0325suzu | 0:20fc96400ca3 | 156 | * |
| jack0325suzu | 0:20fc96400ca3 | 157 | * デフォルトは45 これは380モータとエンコーダを直結して12V電圧で動かしたときの結果 |
| jack0325suzu | 0:20fc96400ca3 | 158 | * |
| jack0325suzu | 0:20fc96400ca3 | 159 | * |
| jack0325suzu | 0:20fc96400ca3 | 160 | */ |
| jack0325suzu | 0:20fc96400ca3 | 161 | double C; |
| jack0325suzu | 0:20fc96400ca3 | 162 | /** 速度制御関数、引数は目標速度 |
| jack0325suzu | 0:20fc96400ca3 | 163 | * |
| jack0325suzu | 0:20fc96400ca3 | 164 | * この目標角加速度になるようにモーターを回転させることができる |
| jack0325suzu | 0:20fc96400ca3 | 165 | * |
| jack0325suzu | 0:20fc96400ca3 | 166 | * 負の数を代入すれば逆回転することができる |
| jack0325suzu | 0:20fc96400ca3 | 167 | * |
| jack0325suzu | 0:20fc96400ca3 | 168 | * 出力できるduty比は最大で0.5までに設定してある |
| jack0325suzu | 0:20fc96400ca3 | 169 | * @param target_omega 目標角速度 |
| jack0325suzu | 0:20fc96400ca3 | 170 | * |
| jack0325suzu | 0:20fc96400ca3 | 171 | * @section CAUTION(printfについて) |
| jack0325suzu | 0:20fc96400ca3 | 172 | * |
| jack0325suzu | 0:20fc96400ca3 | 173 | * 上記のプログラムのように、速度制御ではループ500回ごとにprintfをしている。 |
| jack0325suzu | 0:20fc96400ca3 | 174 | * |
| jack0325suzu | 0:20fc96400ca3 | 175 | * printfはプログラム的に大きな負担がかかり、かなり時間がかかってしまうものである。 |
| jack0325suzu | 0:20fc96400ca3 | 176 | * |
| jack0325suzu | 0:20fc96400ca3 | 177 | * なのでループごとにいちいちprintfをさせると、速度の収束にかなり時間がかかってしまう。 |
| jack0325suzu | 0:20fc96400ca3 | 178 | * |
| jack0325suzu | 0:20fc96400ca3 | 179 | * (どんなプログラムにも言えるが、)そのためこのようなprintfの頻度を少なくさせるような工夫が必要になる。 |
| jack0325suzu | 0:20fc96400ca3 | 180 | * |
| jack0325suzu | 0:20fc96400ca3 | 181 | */ |
| jack0325suzu | 0:20fc96400ca3 | 182 | void Sc(double target_omega); |
| jack0325suzu | 0:20fc96400ca3 | 183 | /** PIDパラメータ設定関数 |
| jack0325suzu | 0:20fc96400ca3 | 184 | * |
| jack0325suzu | 0:20fc96400ca3 | 185 | * 引数はそれぞれp,i,dパラメータ |
| jack0325suzu | 0:20fc96400ca3 | 186 | * |
| jack0325suzu | 0:20fc96400ca3 | 187 | * デフォルトは全部0に設定してある |
| jack0325suzu | 0:20fc96400ca3 | 188 | * |
| jack0325suzu | 0:20fc96400ca3 | 189 | * だいたいp=0.15くらいでなんとかなる(知らんけど) |
| jack0325suzu | 0:20fc96400ca3 | 190 | * @param p p制御パラメータ |
| jack0325suzu | 0:20fc96400ca3 | 191 | * @param i i制御パラメータ |
| jack0325suzu | 0:20fc96400ca3 | 192 | * @param d d制御パラメータ |
| jack0325suzu | 0:20fc96400ca3 | 193 | */ |
| jack0325suzu | 0:20fc96400ca3 | 194 | void setPIDparam(double p,double i,double d); |
| jack0325suzu | 0:20fc96400ca3 | 195 | /** 角速度・duty比変換定数(C)の設定関数 |
| jack0325suzu | 0:20fc96400ca3 | 196 | * |
| jack0325suzu | 0:20fc96400ca3 | 197 | * 文字通りである |
| jack0325suzu | 0:20fc96400ca3 | 198 | * @param c duty比を角速度に変換させるための定数 |
| jack0325suzu | 0:20fc96400ca3 | 199 | */ |
| jack0325suzu | 0:20fc96400ca3 | 200 | void setDOconstant(double c); |
| jack0325suzu | 0:20fc96400ca3 | 201 | |
| jack0325suzu | 0:20fc96400ca3 | 202 | /** モーター停止用関数 */ |
| jack0325suzu | 0:20fc96400ca3 | 203 | void stop(); |
| jack0325suzu | 0:20fc96400ca3 | 204 | |
| jack0325suzu | 0:20fc96400ca3 | 205 | /** モーター正回転用関数 |
| jack0325suzu | 0:20fc96400ca3 | 206 | @param duty 回転duty比 |
| jack0325suzu | 0:20fc96400ca3 | 207 | */ |
| jack0325suzu | 0:20fc96400ca3 | 208 | void turnF(double duty); |
| jack0325suzu | 0:20fc96400ca3 | 209 | |
| jack0325suzu | 0:20fc96400ca3 | 210 | /** モーター逆回転用関数 |
| jack0325suzu | 0:20fc96400ca3 | 211 | @param duty 回転duty比 |
| jack0325suzu | 0:20fc96400ca3 | 212 | */ |
| jack0325suzu | 0:20fc96400ca3 | 213 | void turnB(double duty); |
| jack0325suzu | 0:20fc96400ca3 | 214 | |
| jack0325suzu | 0:20fc96400ca3 | 215 | /** 出力duty比 |
| jack0325suzu | 0:20fc96400ca3 | 216 | */ |
| jack0325suzu | 0:20fc96400ca3 | 217 | double duty; |
| jack0325suzu | 0:20fc96400ca3 | 218 | }; |
| jack0325suzu | 0:20fc96400ca3 | 219 | #endif |
