×

らずらいと姫の挑戦日記(第16回)~モーターを動かしてみよう①~

2016-07-19

コントローラの仕組みと値を送信するプログラムは完成しました。今回からORIZURU本体側の作成にとりかかりたいと思います!
まずは、モーターについてです。ORIZURUを飛ばすための必需品ですね♪ 今回はDCモータについて勉強してみたいと思います。

6

 

この図は、ORIZURUの構成です。DCモーターで羽を動かして、サーボモーターで上下・左右の制御を行っています。

orizuru

ORIZURUに搭載されている小型版Lazurite(Lazurite Fly)から、2種類のモーターを動かしています。

1.DCモーター・・・羽をバタバタと羽ばたかせています。エンジンの働きをするモーターです。

2.サーボモーター・・・尾翼を左右上下させて方向を決めるモーター

stamp6DCモーターってどんなもの?

直流モータ(direct-current motor)とも呼ばれていて、内部にエナメル線を何重にも巻いたコイルと磁石が入っていて、コイルに電気が流れて磁性を持つことで、磁石と反発しながら回転するモーター、との事です。

模型やミニ四駆、ラジコンなどを走らせたり、扇風機の羽を回すことが出来るモーターです。

19     26

+から-へ電気を流すとモーターが回ります。-から+だと逆回転します。車のタイヤなら正回転させて前進、逆回転でバックする感じです。また、+から-、-から+の正負両方があるものをHブリッジとも呼ぶそうです。

ORIZURUの場合、コントローラーのスライドボリュームを操作してDCモーターを動かしています。DCモーターの値は0~1023の間で、レバーの位置によって力の強さが変わってきます。0の位置なら0/1023の力を出している、真ん中辺りなら510/1023、MAXで1023/1023でフルパワーでモーターが動いています。

34   35

※μs(マイクロセック)=1/1,000,000秒 ms(ミリセック)=1/1,000秒

 

DCモーターの力は『分数』で考えます。まず、分母にあたる周期を決めて、その周期のうちの何%の力を出すかを決めています。例えば、下の図の場合、

  1. 「周期が100でAが50」を分数にすると→50/100(50%の力)
  2. 「周期が-100でBが-40」を分数にすると→-40/-100(40%の力)

となります。

31 33

DCモーターを動すプログラム

ORIZURUのコントローラーから無線で送信された値を受信して、DCモーターを動かすプログラムです↓↓↓

#define DEBUG

#define SUBGHZ_CH 36
#define SUBGHZ_PANID 0xABCD
uint8_t rx_data[256];
uint32_t last_recv_time = 0;
SUBGHZ_STATUS rx;

#define MOTOR_PS 17
#define MOTOR_PWM 2

void setup(void)
{
 SUBGHZ_MSG msg;
 long myAddress;
#ifdef DEBUG
 Serial.begin(115200);
#endif

 msg = SubGHz.init();
 if(msg != SUBGHZ_OK)
 {
 SubGHz.msgOut(msg);
 while(1){ }
 }

#ifdef DEBUG
 myAddress = SubGHz.getMyAddress();
 Serial.print("myAddress1 = ");
 Serial.println_long(myAddress,HEX);
#endif
 msg = SubGHz.begin(SUBGHZ_CH, SUBGHZ_PANID, SUBGHZ_100KBPS, SUBGHZ_PWR_1MW);
 if(msg != SUBGHZ_OK)
 {
 SubGHz.msgOut(msg);
 while(1){ }
 }
 msg = SubGHz.rxEnable(NULL);
 if(msg != SUBGHZ_OK)
 {
 SubGHz.msgOut(msg);
 while(1){ }
 }
 pinMode(25,OUTPUT);
 digitalWrite(25,HIGH);

 // initializing motor
 digitalWrite(MOTOR_PWM, LOW);
 digitalWrite(MOTOR_PS, HIGH);

 pinMode(MOTOR_PWM,OUTPUT);
 pinMode(MOTOR_PS,OUTPUT);

 hhb.init(3,1023);
 hhb.attach(3,4,5);
 hhb.attach(3,6,7);
 hhb.write(3,0);
 hhb.start(3);

 return;
}

void loop(void)
{
 uint32_t get_time;
 uint32_t delta_time;
 short len;
 short motor[3];

 do
 {
 len = SubGHz.readData(rx_data,sizeof(rx_data));
 } while (len <= 0);
 memcpy(motor,&rx_data[7],6);

#ifdef DEBUG
 // Serial Output
 get_time = millis();
 SubGHz.getStatus(NULL,&rx);
 delta_time = get_time - last_recv_time;
 last_recv_time = get_time;
 Serial.print_long(delta_time,DEC);

 Serial.print(" ");
 Serial.print_long((long)rx.rssi,DEC);

 Serial.print(" ");
 Serial.print_long((long)rx.status,DEC);

 Serial.print(" ");
 Serial.print_long((long)motor[2],DEC);

 Serial.println("");
#endif
 hhb.write(3,(unsigned short)motor[2]);
 hhb.update();
 return;
}

54~58行目、95~96行目の『hhb』がDCモーター用のLazurite専用関数です。内容はこちらに記載されています。開発者いわく、全てハードウエアで制御しているので、モーターを制御するタイミングがずれずに、動作が安定しているそうです。
http://www.lapis-semi.com/lazurite-jp/contents/reference/motor.html

Hardware H-Bridgeライブラリ: hhb

モーターライブラリの初期化:

まずは初期化する部分を見てみたいと思います。

54行目:hhb.init(3,1023);

これはモーターを制御する3番回路をDCモーターで使う、その時の周期(間隔)は1023μs(1.023ms)という宣言になります。

55行目:hhb.attach(3,4,5);

56行目:hhb.attach(3,6,7);

3番回路の出力を正側4pin、負側5pinにする;3番回路の出力を正側6pin、負側7pinにする

40

57行目:hhb.write(3,0);

3番回路の出力を0にする

58行目:hhb.start(3);

モーター用の回路を動かして信号を出力する

コントローラから送られたモーターの値を反映する

72~74行目: ここで受信したデータをmotorという変数にコピーしています。

95行目: hhb.write(3,(unsigned short)motor[2]);
コントローラから受信したDCモータの値はmotor[2]に格納されています。それを、3番のモータ回路にそのまま書きこんでいます。コントローラから送信されてくる値が0~1023で、DCモータの周期も1.023ms(1023us)にしているので、そのまま書きこむことが出来るんですね。

96行目: hhb.update();
hhbライブラリではwriteするだけではDCモーターの値が反映されません。updateをして初めてその値が有効になります。

3番回路とは??

突然登場した、3番回路とは何でしょうか?

Lazuriteのマイコンには4個のモーターを動かす回路が入っていて、それをDCモーターやサーボに割り当てて使用しているようです。今回のORIZURUは、サーボ 2個、DCモータ1個なのですが、色々と訳があって次のように使用しているそうです。

3739

ORIZURUでの使用方法:

サーボ 1 = FTM0の0を使用
サーボ2=FTM1の2を使用
DCモータ=FTM3とFTM4を使用
(今回のサンプルプログラムではFTM3しか使用していません)

色々な事情があるようなのですが、とりあえずFTM3を使用してDCモータを動かしているという事は解りました。だからhhb.init(3,1023)のように、3番の回路を用いていたのですね。

今週はここまでです。実際に動いたところは最後にお見せしたいと思います。