NUCLEOのキットを使ったルーレット
Diff: main.cpp
- Revision:
- 0:b8098a4ce012
diff -r 000000000000 -r b8098a4ce012 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Mar 22 22:53:00 2016 +0000 @@ -0,0 +1,173 @@ +/************************************************* +"Nucleo_motor_control2" +Nucleo Pack + マイコンボード NUCLEO-F302R8 + 拡張ボード X-NUCLEO-IHM07M1 + モーター BR2804-1700KV-1 +を使ったモーター制御の実験 + +アナログPWM版 ルーレット仕様 + Copyright(C) 2016 Columbus-seiki + + 2016-02-22 Rev0 + +**************************************************/ +#include "mbed.h" +#include "main.h" + +#define POLE_PAIR 7//モーターの磁極対数 +#define PERIOD_TIMER 0.005 //タイマー周期(S) +#define SINTBL_LENGTH 512 //sinTbl[]要素数 +#define PERIOD_PWM 0.0002 //PWM周期(S) これ以下では ヒゲ がでる +#define HALF_PWM (PERIOD_PWM / 2) //PWM周期の真ん中 PERIOD_PWM÷2 +#define DEG360 1024 //360°相当 +#define DEG120 341 //120° +#define DEG240 682 //240° + + +//入出力ピンを定義 +DigitalIn mybutton(USER_BUTTON); +Serial pc(PA_2, PA_3); //USB/COM パソコンの仮想シリアルポートへ。ここでは使いません +DigitalOut ld2(PB_13); //LD2 グリーンLED +DigitalOut d11(PB_2); //D11 パワボード赤LED + +//pwm出力の定義 +PwmOut pwmU(PA_8), pwmV(PA_9), pwmW(PA_10);//それぞれUH_PWM, VH_PWM, WH_PWM + +//IOの定義 +DigitalOut enableU(PC_10), enableV(PC_11), enableW(PC_12);//それぞれEnable_CH1-L6230, _CH2-, _CH3- + +//アナログ入力の定義 +AnalogIn ain(PB_1);//R42 POTENTIOPOTENTIOMETER +AnalogIn ainThrm(PC_2);// Temperature feedback + +//タイマーの定義 +Ticker myTimer;//繰返しタイマー + +//変数 +int preMybutton; //記憶 +int enablePWM=0;//PWM開始と停止フラグ +//int scope[100];//モニター用バッファ +int count, loopCount=0; //カウンター +double outDuty=0 ,outU, outV, outW; //PWM出力デューティー +float theta, omega; //角度と角速度 +int timePerRound=60; //1回転時間(S) + +int sumThrm; //積算値 +bool runRoulette=false; +int thetaMech=0; //機械(物理的な)モータ角度 + +/********************************** + sin関数 + 引数:最大1024=360° + 出力:最大512=1.0 +***********************************/ +int mySin(int angleNum) +{ + + angleNum &= 0x3ff; //0x3ff=1023 でマスク + if(angleNum >= 512) //180~360° + return -sinTbl[angleNum - 512]; + else //0~180° + return sinTbl[angleNum]; +} + + +/********************************** + タイマー割込み関数 5mS +***********************************/ +void myTimerCallBack() //全相をONにする +{ + outDuty = 0.2; //最大1.0 出力電圧を調整します + + theta += omega; //増加分 + if(theta >= 1024) //360°オーバーフローを防止 + theta -= 1024; + else if(theta <= -1024) + theta += 1024; + + pwmU.pulsewidth(HALF_PWM + outDuty * mySin((int)theta & 0x3ff) / 512.0 * HALF_PWM); + pwmV.pulsewidth(HALF_PWM + outDuty * mySin(((int)theta - DEG120) & 0x3ff) / 512.0 * HALF_PWM); + pwmW.pulsewidth(HALF_PWM + outDuty * mySin(((int)theta - DEG240) & 0x3ff) / 512.0 * HALF_PWM); + + thetaMech += omega; //増加分 + + //サイクルカウンター処理(同期) + count++; + if( count == 100) { + count = 0; + loopCount = 1; //loopの同期用 5mS X 100 = 0.5S + } + +} +/*********************************** + +************************************/ +int main() +{ + + //pwmデューティー 初期値 + outU = 0; + outV = 0; + outW = 0; + + //PWM設定 + enableU = 0;//PWM出力OFF. L6230PのENable端子です + enableV = 0; + enableW = 0; + + pwmU.period(PERIOD_PWM);//0.2mS 5KHz + pwmV.period(PERIOD_PWM); + pwmW.period(PERIOD_PWM); + + //タイマー設定 + myTimer.attach(&myTimerCallBack, PERIOD_TIMER);//5mS毎にmyTimerCallBack()がコールされます + + + while(1) { + //------ およそ一定周期の処理 ------- + if(loopCount != 0) {//5x100=0.5S + loopCount = 0; + + ld2 = !ld2; //点滅 + d11 = !d11; //パワボード + + //ルーレット目標位置の作成用データ + sumThrm += (float)ainThrm * 1000000; //積算 + + //pc.printf("%f", ((float)(sumThrm & 0x1f) / 32.0 + 10) * 1024 * POLE_PAIR); + } + + //-------- 時間に関係しない処理 -------- + //PWM開始と停止 + if((int)mybutton != preMybutton) {//ボタンが押された。チャタリングを考慮していません + preMybutton = (int)mybutton;//次に押されたときのために記憶 + + if(mybutton == 0) {//押されたときだけ。 + runRoulette = true; //enablePWM = ~enablePWM;//オルタネート + thetaMech = 0;//機械角リセット + //PWM開始 + enableU = 1;//PWM出力ON. L6230PのENable端子です + enableV = 1; + enableW = 1; + } + } + + //ルーレット停止位置 + if( thetaMech > ((float)(sumThrm & 0x1f) / 32.0F + 5) * 1024 * POLE_PAIR)// + runRoulette = false; + //thetaMechが1024*POLE_PAIRで一回転. 5回転を追加. sumThrmの0~31を抽出 + + + //角速度に変換 ルーレットのスタートと停止 + if(runRoulette) { //回転 + timePerRound = 2;//速度指定(S/r) + omega = PERIOD_TIMER * DEG360 * POLE_PAIR / timePerRound; + } else //停止 + omega = 0; + + }//END while(1) + + +} +