読者です 読者をやめる 読者になる 読者になる

Nov11’s diary(自宅での開発環境作り )

3Dプリンタと切削加工機で工作した事をアップして行きます

PICを使用して開発する事にした(サーボモータ/DCモータ制御)(その1)

プログラム関係

液晶付きコントローラで、ロボットアームを自作し制御する事にしたので、PIC24FJ64GA002を使ってモータ制御の基本であるパルス幅変調(PWM:pulse width modulation)を行う事にした
と、言ってもいつも通り、MPLAB XのCode Configuratorがプログラムを自動生成してくれるので、
テストは簡単だった
余談だが、Code Configuratorの使用例がネット上にほとんど無い事に気づいてしまった...
今回のPWM制御の関数(OC1_DualCompareValueSetとOC1_SingleCompareValueSet)をググったら該当が1件で、クリックするとエラー404表示になってしまった
前回のI2C制御の送信関数(I2C1_MasterWrite)は、該当3件で、日本語サイトは見つからなかった
もしかしたら、とんでもなく見当違いを行っているのか心配になってしまう...
が!、目的は色々な製品を作成する事なので、ここはあまり気にしない事に決めた

んで、結果はと言うと残念ながら、ほぼ1kHzと10kHzの波形を確認する事しかできなかった
正確には、1000Hzが999.270Hzで、10000Hzが9987.14Hzとなってしまった
この方法が悪いのか、それともPICの性能なのかは不明だが、ほぼの精度でしか制御できなかった
PWM制御を行うだけなら問題は無いが、周波数出力用としては難しそうなので、精度が必要な場合には、DDSなどを使用した方が良いように思う
取りあえず、DCモータ制御用には大丈夫そうで、サーボモータはテスト結果から方向性を決める事にしようと思う

[動作結果]

f:id:Nov11:20160211105944p:plain

         (ブレットボードなので、波形にノイズがのっています)

[配線]

f:id:Nov11:20160211110103j:plain

     ((シリアル通信/UART通信)(その1)の時に使用した配線と同じです)

↓↓↓↓↓↓↓↓↓下記の内容は、MCC(v2.25.2)を使用しています↓↓↓↓↓↓↓↓
v2.25.2を使用する場合は、11月08日のブログを参照して下さい

[プログラム作成]
1)MPLAB Xを起動し、プロジェクトを作成する
2)Code Configuratorで、Systemを設定し、TMR1とOutput CompareのOC1とOC2を追加する
3)OC1の設定項目を以下の様に設定する
 Mode:Edge-Aligned PWM Mode,Clock:TMR2,Primary Compare:0x182,Secondary Compare:0x1f40に
 して、Code ConfiguratorのPin Managerで、出力ピン(OC1のOC1)を選択する
4)TMR2が追加されるので、Timer Periodに周波数周期時間を入力する
 例えば、1kHzなら1msと入力し、10kHzなら100usと入力する
5)OC2をOC1と同様に設定する
 OC1との違いは、ClockをTMR3にして、Secondary Compare:0x304,TMR3のTimer Periodを
 100usに設定する部分となる
6)TMR1を1000msに設定する
7)Generate Codeを押してコード生成を行う
8)パルス幅変更のプログラムをメイン関数に記述する
 と、言っても、MPLAB XのGenerate Codeがプログラムの大半を自動生成してくれているので、
 コーディングは以下の数行となる
-----------------------------------------------------------------------------------
uint8_t uiCount;
uint16_t uiDuty;
int main(void) {
    // initialize the device
    SYSTEM_Initialize();
    // デューティ比を90%に設定する
    uiDuty = 0x3840;
    OC1_DualCompareValueSet(0x182, uiDuty );
    while (1) {
        // Add your application code
        // デューティ比を1000mSec単位で変化させる
        if ( TMR1_SoftwareCounterGet() != uiCount ) {
            uiCount = TMR1_SoftwareCounterGet();
            // デューティ比を10%変化させる
            uiDuty -= 0x640;
            if ( uiDuty < 0x640) {
                uiDuty = 0x3840;
            }
            // PICにデューティ比の変更を指示する
           OC1_DualCompareValueSet(0x182,uiDuty);
        }
    }
    return -1;
}
-----------------------------------------------------------------------------------
7)プログラムを書き込む
8)オシロスコープロジックアナライザなどで出力ピンを測定してデューティ比が変化している事が
 確認出来れば正常動作となる
 また、計測器が無い場合には、出力ピンにLEDを接続すると明るさが変化していれば
 正常動作している事になる

なお、ブログの内容を参照して実行した結果に責任は負いかねますので、ご了承下さい