ブラシレスモータの低速回転実験

main.cpp

/*************************************************
"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 
Serial pc(SERIAL_TX,SERIAL_RX);


//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; //パワボード
            pc.printf("current status: %d\n",(int)mybutton);
        }

        //-------- 時間に関係しない処理 --------
        //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)

}

main.h

//半波sinテーブル 0〜180°
//x=0〜511:
//f(x)=0〜511: 0〜+1.0
const short sinTbl[512] = { //ROMにロケーション
0 ,3 ,6 ,9 ,
13 ,16 ,19 ,22 ,
25 ,28 ,31 ,35 ,
38 ,41 ,44 ,47 ,
50 ,53 ,56 ,60 ,
63 ,66 ,69 ,72 ,
75 ,78 ,81 ,84 ,
88 ,91 ,94 ,97 ,
100 ,103 ,106 ,109 ,
112 ,115 ,118 ,121 ,
124 ,127 ,130 ,134 ,
137 ,140 ,143 ,146 ,
149 ,152 ,155 ,158 ,
161 ,164 ,167 ,170 ,
172 ,175 ,178 ,181 ,
184 ,187 ,190 ,193 ,
196 ,199 ,202 ,205 ,
207 ,210 ,213 ,216 ,
219 ,222 ,225 ,227 ,
230 ,233 ,236 ,239 ,
241 ,244 ,247 ,250 ,
252 ,255 ,258 ,261 ,
263 ,266 ,269 ,271 ,
274 ,277 ,279 ,282 ,
284 ,287 ,290 ,292 ,
295 ,297 ,300 ,302 ,
305 ,308 ,310 ,313 ,
315 ,317 ,320 ,322 ,
325 ,327 ,330 ,332 ,
334 ,337 ,339 ,342 ,
344 ,346 ,348 ,351 ,
353 ,355 ,358 ,360 ,
362 ,364 ,366 ,369 ,
371 ,373 ,375 ,377 ,
379 ,381 ,384 ,386 ,
388 ,390 ,392 ,394 ,
396 ,398 ,400 ,402 ,
404 ,406 ,407 ,409 ,
411 ,413 ,415 ,417 ,
419 ,420 ,422 ,424 ,
426 ,427 ,429 ,431 ,
433 ,434 ,436 ,438 ,
439 ,441 ,442 ,444 ,
445 ,447 ,449 ,450 ,
452 ,453 ,454 ,456 ,
457 ,459 ,460 ,461 ,
463 ,464 ,465 ,467 ,
468 ,469 ,471 ,472 ,
473 ,474 ,475 ,477 ,
478 ,479 ,480 ,481 ,
482 ,483 ,484 ,485 ,
486 ,487 ,488 ,489 ,
490 ,491 ,492 ,493 ,
493 ,494 ,495 ,496 ,
497 ,497 ,498 ,499 ,
500 ,500 ,501 ,502 ,
502 ,503 ,503 ,504 ,
504 ,505 ,505 ,506 ,
506 ,507 ,507 ,508 ,
508 ,509 ,509 ,509 ,
510 ,510 ,510 ,510 ,
511 ,511 ,511 ,511 ,
511 ,512 ,512 ,512 ,
512 ,512 ,512 ,512 ,
512 ,512 ,512 ,512 ,
512 ,512 ,512 ,512 ,
511 ,511 ,511 ,511 ,
511 ,510 ,510 ,510 ,
510 ,509 ,509 ,509 ,
508 ,508 ,507 ,507 ,
506 ,506 ,505 ,505 ,
504 ,504 ,503 ,503 ,
502 ,502 ,501 ,500 ,
500 ,499 ,498 ,497 ,
497 ,496 ,495 ,494 ,
493 ,493 ,492 ,491 ,
490 ,489 ,488 ,487 ,
486 ,485 ,484 ,483 ,
482 ,481 ,480 ,479 ,
478 ,477 ,475 ,474 ,
473 ,472 ,471 ,469 ,
468 ,467 ,465 ,464 ,
463 ,461 ,460 ,459 ,
457 ,456 ,454 ,453 ,
452 ,450 ,449 ,447 ,
445 ,444 ,442 ,441 ,
439 ,438 ,436 ,434 ,
433 ,431 ,429 ,427 ,
426 ,424 ,422 ,420 ,
419 ,417 ,415 ,413 ,
411 ,409 ,407 ,406 ,
404 ,402 ,400 ,398 ,
396 ,394 ,392 ,390 ,
388 ,386 ,384 ,381 ,
379 ,377 ,375 ,373 ,
371 ,369 ,366 ,364 ,
362 ,360 ,358 ,355 ,
353 ,351 ,348 ,346 ,
344 ,342 ,339 ,337 ,
334 ,332 ,330 ,327 ,
325 ,322 ,320 ,317 ,
315 ,313 ,310 ,308 ,
305 ,302 ,300 ,297 ,
295 ,292 ,290 ,287 ,
284 ,282 ,279 ,277 ,
274 ,271 ,269 ,266 ,
263 ,261 ,258 ,255 ,
252 ,250 ,247 ,244 ,
241 ,239 ,236 ,233 ,
230 ,227 ,225 ,222 ,
219 ,216 ,213 ,210 ,
207 ,205 ,202 ,199 ,
196 ,193 ,190 ,187 ,
184 ,181 ,178 ,175 ,
172 ,170 ,167 ,164 ,
161 ,158 ,155 ,152 ,
149 ,146 ,143 ,140 ,
137 ,134 ,130 ,127 ,
124 ,121 ,118 ,115 ,
112 ,109 ,106 ,103 ,
100 ,97 ,94 ,91 ,
88 ,84 ,81 ,78 ,
75 ,72 ,69 ,66 ,
63 ,60 ,56 ,53 ,
50 ,47 ,44 ,41 ,
38 ,35 ,31 ,28 ,
25 ,22 ,19 ,16 ,
13 ,9 ,6 ,3 
};