NUCLEOのキットを使った秒針

Dependencies:   mbed-src

main.cpp

Committer:
motomiya
Date:
2016-03-22
Revision:
0:a1180efb20e0

File content as of revision 0:a1180efb20e0:

/*************************************************
"Nucleo_motor_control"
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

//タイマーの定義
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)

/**********************************
    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);

    //サイクルカウンター処理(同期)
    count++;
    if( count == 100) {
        count = 0;
        loopCount = 1;  //loopの同期用 5mS X 100 = 0.5S
    }

}
/***********************************

************************************/
int main()
{

    //pwmデューティー 初期値
    outU = 0;
    outV = 0;
    outW = 0;
    
    //PWM設定
    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; //パワボード
        }

        //-------- 時間に関係しない処理 --------
        //PWM開始と停止
        if((int)mybutton != preMybutton) {//ボタンが押された。チャタリングを考慮していません
            preMybutton = (int)mybutton;//次に押されたときのために記憶
            
            if(mybutton == 0)//押されたときだけ。  
                enablePWM = ~enablePWM;//オルタネート
            
            //PWM開始    
            if(enablePWM) {
                enableU = 1;//PWM出力ON. L6230PのENable端子です
                enableV = 1;
                enableW = 1;
            } else {
                enableU = 0;//PWM出力OFF. L6230PのENable端子です. PWM出力は止まりません
                enableV = 0;
                enableW = 0;
            }
        } //ボタンが押された の終わり

        //速度指定 ポテンショメータをディップスイッチのように処理
        if(ain < 0.3L) //ain=0~1.0
            timePerRound = 60 * 5; //5分時計 ボリューム左一杯
        else if( ain < 0.6L)
            timePerRound = 60 * 3; //3分時計 ボリューム中央
        else
            timePerRound = 60; //1分時計 ボリューム右一杯
        
        //指定の周期を角速度に変換
        omega = PERIOD_TIMER * DEG360 * POLE_PAIR / timePerRound;


    }//END while(1)


}