課題プログラム実行例とヒント

1.位置決め制御(ステップ入力)の例      実行ファイル例positioning.MOT

実行結果例
160msec程度で目標位置に達し,270msecには目標位置に停止している。
Time:時刻[msec]
PWMvalue:その時刻におけるPWM値
Position:その時刻におけるモータ角度
Velocity:その時刻におけるモータ角速度(5msec前のモータ角度と現在の角度との差)

以下の設定でpositioning.MOTを実行
position feedback gain kp= 10
velocity feedback gain kd= 40
integral feedback gain ki=  0

Time(msec)

 PWMvalue

 position

 velocity

0

0

0

0

10

1000

0

0

20

1000

15

10

30

1000

45

16

40

1000

87

22

50

1000

134

24

60

1000

188

27

70

1000

246

30

80

1000

307

31

90

1000

369

31

100

1000

434

32

110

1000

500

33

120

1000

567

33

130

290

635

34

140

-340

702

33

150

-740

762

28

160

-750

803

18

170

-540

822

8

180

-360

828

2

190

-240

828

-1

200

-60

822

-4

210

10

815

-4

220

90

807

-4

230

50

803

-2

240

40

800

-1

250

60

798

-1

260

-30

799

1

270

0

800

0

280

0

800

0

290

0

800

0

300

0

800

0

310

0

800

0

320

0

800

0

330

0

800

0

340

0

800

0

350

0

800

0

360

0

800

0

370

0

800

0

380

0

800

0

390

0

800

0

400

0

800

0

410

0

800

0

420

0

800

0

430

0

800

0

440

0

800

0

450

0

800

0

460

0

800

0

470

0

800

0

480

0

800

0

490

0

800

0

500

0

800

0

510

0

800

0

520

0

800

0

530

0

800

0

540

0

800

0

550

0

800

0

560

0

800

0

570

0

800

0

580

0

800

0

590

0

800

0

600

0

800

0

610

0

800

0

620

0

800

0

630

0

800

0

640

0

800

0

650

0

800

0

660

0

800

0

670

0

800

0

680

0

800

0

690

0

800

0

700

0

800

0

710

0

800

0

720

0

800

0

730

0

800

0

740

0

800

0

750

0

800

0

760

0

800

0

770

0

800

0

780

0

800

0

790

0

800

0

800

0

800

0

810

0

800

0

820

0

800

0

830

0

800

0

840

0

800

0

850

0

800

0

860

0

800

0

870

0

800

0

880

0

800

0

890

0

800

0

900

0

800

0

910

0

800

0

920

0

800

0

930

0

800

0

940

0

800

0

950

0

800

0

960

0

800

0

970

0

800

0

980

0

800

0

990

0

800

0

1000

0

800

0


位置決め制御(ステップ入力)の例

ヒント
位置決め制御(ステップ入力)の枠組み(未完成)

/**********************************************************
プログラムの説明
 1)カウンタ値0の位置からモータを駆動し,カウンタ値が800の位置でモータを
   止める。
 2)モータ駆動直前に角度センサのカウンタをクリアする。
 3)正確に800の位置に止められなくてもできるだけ800に近い位置に止める。
 4)この作業は何回でも繰返し出来るようにする。
 5)モータ起動時および起動後0.01秒ごとに,その時の時刻,PWM値,角度,角度
   差分を表示する。
  (この表示はキャプチャして,Excelでグラフ化し,これも提出すること)
 6)角度はその時刻のカウンタ値,角度差分は0.005秒間のカウンタ値の差分とす
   る。
 7)時刻,PWM値,角度,角度差分の表示はモータ起動1秒後までとする。
 8)角度,角度差分の表示は割り込み関数内で行なってはいけない。
  (割り込み関数は出来るだけ作業を短時間に終わりたいからである)
 9)PWM値の更新は0.005秒ごとに行なうことが出来るようにする。
 10)モータ停止位置は800であるが,キーボードからどのような値(負でもよい)
   でも設定できるようにする。
  (16ビットカウンタで指定できる範囲)
**********************************************************/
#include "h8-01.h"

/**********不足している関数をここに取り込む**********/

#define PWM_MAX 1000

volatile int x;                  /*割り込み時位置*/
volatile int oldx;               /*前回割り込み時位置*/
volatile int v;                  /*位置差分(速度)*/
volatile int pwmvalue;           /*モータ指令値*/
volatile int requestDisplaydata; /*表示リクエスト*/
int thePosition=800;             /*目標値*/
volatile int timecounter;        /*制御開始時点からの時間[msec]*/
volatile int tick;               /*表示を10msecごとにするための変数*/

void setConstants(void)
{
    /* ここで必要な定数の設定を行なうと良い                */
    /* nankanoteisuu=getIntSCI1("input nankanoteisuu-->"); */
    /* のような記述もよいでしょう                          */
}

void setReference(void)
/*ここでは目標値を設定する*/
{
    thePosition=getIntSCI1("input reference(-10000..10000)--> ");
}

void controlMotor(void)
{
    timecounter=0;
    pwmvalue=0;x=0;oldx=0,v=0;
    requestDisplaydata=1;
    tick=1;
    clearPhaseCounter();                         /* counter(ITUch2)クリア*/
    SCI1_printf("Time(msec) PWMvalue Position Velocity\n");
    E_INT();                                     /* CPU割り込み許可*/
    startTimer1();                               /* 割り込みカウンタスタート*/
    do {
        if (requestDisplaydata) {
            SCI1_printf("%5d%5d%5d%5d\n",timecounter,pwmvalue,x,v);
            requestDisplaydata=0;
        }
    } while(timecounter<=1000);
    stopTimer1();                                /* 割り込タイマストップ*/
    D_INT();                                     /*割り込み禁止*/
    driveMotor(0);
}

main()
{
    int key=-1;
    initSCI1();          /*SCI1初期化*/
    initPhaseCounter();  /*Rotaryencoder counter ITUch2初期化*/
    init_pwm3(PWM_MAX);  /*PWMの初期設定*/
    initTimer1Int(5000); /* 5msecごとの割り込み関数起動を設定*/
    while (1) {
        SCI1_printf("\n\n***   Motor Control Program by namename   ***\n");
        SCI1_printf("1 set constants\n");
        SCI1_printf("2 set reference\n");
        SCI1_printf("3 execute!!\n");
        do {key=getCharSCI1();} while(key<'1'||'3'<key);
        SCI1_printf("\n");
        if (key=='1') setConstants();
        else if (key=='2') setReference();
        else if (key=='3') controlMotor();
    }
}

void interrupt_cfunc() /*割り込みルーチン この関数名は固定*/
{
    x=getPhaseCounter();     /*位相カウンタの読み出し*/
    v=x-oldx;
    oldx=x;

    /* ここにpwmvalueを作るコードを書く    */
    /* このプログラムの一番大事なコードである */
    /* ここにpwmvalueを作るコードを書く    */
    /* このプログラムの一番大事なコードである */
    /* ここにpwmvalueを作るコードを書く    */
    /* このプログラムの一番大事なコードである */

    driveMotor(pwmvalue); /*モータ指令値出力*/
    timecounter+=5; /*5msecの割り込み周期なので*/
    tick=1-tick;    /*5msecの割り込み周期なので1回おきに表示要求を出す*/
    if (tick) requestDisplaydata=1;
}

 

 

2.プログラム制御(ランプ応答)の例        実行ファイル例velocity.MOT

実行結果例
起動直後に増加中の目標値に遅れるが,170msecほどで追いつき,その後は目標値の変化に追従している。
Time:時刻[msec]
PWMvalue:その時刻におけるPWM値
Reference:その時刻における目標値
Position:その時刻におけるモータ角度
Velocity:その時刻におけるモータ角速度(5msec前のモータ角度と現在の角度との差)

以下の設定でvelocity.MOTを実行
position feedback gain kp= 10
velocity feedback gain kd= 40
integral feedback gain ki=  3

Time(msec)

 PWMvalue

 Reference

 Position

 Velocity

0

0

0

0

0

10

422

40

0

0

20

662

80

5

4

30

844

120

18

8

40

890

160

42

13

50

842

200

76

18

60

755

240

118

22

70

692

280

165

24

80

644

320

214

25

90

567

360

265

26

100

451

400

319

27

110

364

440

373

27

120

255

480

428

27

130

96

520

483

28

140

-35

560

538

28

150

-25

600

590

25

160

-84

640

640

24

170

-107

680

686

23

180

-2

720

727

20

190

-8

760

767

20

200

48

800

805

19

210

66

840

843

19

220

95

880

880

19

230

116

920

918

19

240

139

960

956

19

250

102

1000

996

20

260

166

1040

1034

19

270

131

1080

1074

20

280

146

1120

1113

20

290

140

1160

1154

20

300

95

1200

1195

21

310

138

1240

1235

20

320

92

1280

1276

21

330

124

1320

1317

20

340

65

1360

1359

21

350

55

1400

1400

21

360

85

1440

1441

20

370

73

1480

1482

20

380

21

1520

1523

21

390

59

1560

1563

20

400

57

1600

1603

20

410

55

1640

1643

20

420

103

1680

1682

19

430

61

1720

1722

20

440

110

1760

1761

19

450

69

1800

1801

20

460

79

1840

1840

20

470

90

1880

1879

20

480

141

1920

1918

19

490

103

1960

1958

20

500

104

2000

1998

20

510

106

2040

2038

20

520

107

2080

2078

20

530

109

2120

2118

20

540

99

2160

2159

20

550

100

2200

2199

20

560

101

2240

2239

20

570

91

2280

2280

20

580

91

2320

2320

20

590

91

2360

2360

20

600

91

2400

2400

20

610

80

2440

2441

20

620

79

2480

2481

20

630

79

2520

2521

20

640

78

2560

2561

20

650

66

2600

2602

20

660

76

2640

2641

20

670

75

2680

2681

20

680

74

2720

2721

20

690

73

2760

2761

20

700

73

2800

2801

20

710

72

2840

2841

20

720

71

2880

2881

20

730

81

2920

2920

20

740

132

2960

2959

19

750

42

3000

3000

21

760

93

3040

3039

20

770

93

3080

3079

20

780

94

3120

3119

20

790

95

3160

3159

20

800

96

3200

3199

20

810

96

3240

3239

20

820

97

3280

3279

20

830

48

3320

3320

21

840

88

3360

3360

20

850

88

3400

3400

20

860

88

3440

3440

20

870

37

3480

3481

21

880

37

3520

3521

21

890

76

3560

3561

20

900

75

3600

3601

20

910

125

3640

3640

19

920

85

3680

3680

20

930

85

3720

3720

20

940

85

3760

3760

20

950

85

3800

3800

20

960

135

3840

3839

19

970

96

3880

3879

20

980

46

3920

3920

21

990

86

3960

3960

20

1000

86

4000

4000

20


プログラム制御(ランプ応答)の例

ヒント
位置決め制御(ランプ入力)の枠組み(未完成)

/**********************************************************
プログラムの説明
 1)カウンタ値0の位置からモータを駆動し,0.005秒ごとに,カウンタ値が20ず
   つ増加するようにする。
  (0.000秒:0 0.005秒:20 0.010秒:40 0.015秒:60 0.020秒:80 ..
    ...)
 2)モータ駆動直前に角度センサのカウンタをクリアする。
 3)正確に予定した時刻に予定した位置を通過しなくてもよいが,できるだけこ
   のような軌跡になるようにする。
 4)モータ起動時および起動後0.005秒ごとに,その時の時刻,PWM値,角度目標
   値,角度,角度差分を表示する。
  (この表示はキャプチャして,Excelでグラフ化し,これも提出すること)
 5)角度はその時刻のカウンタ値,角度差分は0.005秒間のカウンタ値の差分とす
   る。
 6)PWM値,角度,角度差分の表示はモータ起動1秒後までとする。
 7)角度,角度差分の表示は割り込み関数内で行なってはいけない。
  (割り込み関数は出来るだけ作業を短時間に終わりたいからである)
 8)PWM値の更新は0.005秒ごとに行なうことが出来るようにする。
 9)モータは起動後1秒後に停止することにし,この作業は何回でも実行できるよ
   うにする。
 10)カウンタ値の増分は20であるが,キーボードから-30〜30程度を入力して,
   任意の値に出来るようにしておくこと
**********************************************************/
#include "h8-01.h"

/**********不足している関数をここに取り込む**********/

#define PWM_MAX 1000

volatile int x;                  /*割り込み時位置*/
volatile int oldx;               /*前回割り込み時位置*/
volatile int v;                  /*位置差分(速度)*/
volatile int pwmvalue;           /*モータ指令値*/
volatile int requestDisplaydata; /*表示リクエスト*/
volatile int thePosition=0;      /*目標値*/
volatile int delta=20;           /*目標値増分*/
volatile int timecounter;        /*制御開始時点からの時間[msec]*/
volatile int tick;               /*表示を10msecごとにするための変数*/

void setConstants(void)
{
    /* ここで必要な定数の設定を行なうと良い                */
    /* nankanoteisuu=getIntSCI1("input nankanoteisuu-->"); */
    /* のような記述もよいでしょう                          */
}

void setDelta(void)
/*ここでは目標値の5msecごとの増分を設定する*/
{
    delta=getIntSCI1("input position difference [delta=](-30..30)--> ");
}

void controlMotor(void)
{
    timecounter=0;
    pwmvalue=0;x=0;oldx=0,v=0;
    requestDisplaydata=1;
    tick=1;
    thePosition=0;
    clearPhaseCounter();                         /* counter(ITUch2)クリア*/
    SCI1_printf("Time(msec) PWMvalue reference Position velocity\n");
    E_INT();                                     /* CPU割り込み許可*/
    startTimer1();                               /* 割り込みカウンタスタート*/
    do {
        if (requestDisplaydata) {
            SCI1_printf("%5d%5d%5d%5d%5d\n",timecounter,pwmvalue,thePosition,x,v);
            requestDisplaydata=0;
        }
    } while(timecounter<=1000);
    stopTimer1();                                /* 割り込みタイマストップ*/
    D_INT();                                     /*割り込み禁止*/
    driveMotor(0);
}

main()
{
    int key=-1;
    initSCI1();          /*SCI1初期化*/
    initPhaseCounter();  /*Rotaryencoder counter ITUch2初期化*/
    init_pwm3(PWM_MAX);  /*PWMの初期設定*/
    initTimer1Int(5000); /* 5msecごとの割り込み関数起動を設定*/
    while (1) {
        SCI1_printf("\n\n***   Motor Driving with PID control by Kosaka   ***\n");
        SCI1_printf("1 set constants\n");
        SCI1_printf("2 set delta\n");
        SCI1_printf("3 execute!!\n");
        do {key=getCharSCI1();} while(key<'1'||'3'<key);
        SCI1_printf("\n");
        if (key=='1') setConstants();
        else if (key=='2') setDelta();
        else if (key=='3') controlMotor();
    }
}

void interrupt_cfunc() /*割り込みルーチン この関数名は固定*/
{
    thePosition+=delta;  /*目標値が増加する*/
    x=getPhaseCounter();     /*位相カウンタの読み出し*/
    v=x-oldx;
    oldx=x;

    /* ここにpwmvalueを作るコードを書く    */
    /* このプログラムの一番大事なコードである */
    /* ここにpwmvalueを作るコードを書く    */
    /* このプログラムの一番大事なコードである */
    /* ここにpwmvalueを作るコードを書く    */
    /* このプログラムの一番大事なコードである */

    driveMotor(pwmvalue); /*モータ指令値出力*/
    timecounter+=5; /*5msecの割り込み周期なので*/
    tick=1-tick;    /*5msecの割り込み周期なので1回おきに表示要求を出す*/
    if (tick) requestDisplaydata=1;
}