PR

Arduino/Genuino101でサーボモータを制御

記事内に広告が含まれています。

 Arduino/Genuino101でサーボモータの制御方法です。servo.hライブラリを使用すれば簡単に制御できるのですが、ライブラリではサーボの制御信号周期が20ms程度で固定されています。この信号周期を任意で変更したかったので、今回はライブラリは利用せずにサーボを制御してみたいと思います。

 

スポンサーリンク

サーボモータの概要

 簡単に、サーボモータの制御方法です。パルス幅500μs~2600μs程度、周期20ms程度の信号をサーボに送れば制御できます。サーボの回転角はパルス幅を変更することで制御できます。

093_02

 今回使用したサーボは、パルス幅1600μsでほぼ中央(0°)、580μsで-90°、2620μsで+90°でした。PWMなどでパルス信号を作り出せば制御できます。

 

スケッチ

 ライブラリにあるservo.hを使用すれば、簡単にサーボ制御はできると思います。ただライブラリでは制御周期は20ms程度で固定されているため。少し融通が利きまん。また今回は、101の割り込みの勉強も兼ねて、101のtimer関係のライブラリも使用せずにスケッチしてみました。

 

▼サーボ制御スケッチ▼

#include "aux_regs.h"
#include "interrupt.h"
#include "conf.h"

#define servoPinAssign 9
#define period         10 // ms

typedef struct {
  uint8_t  nbr;
  uint8_t  isState;
  uint32_t ticks;
} servoPin_t;
servoPin_t servoPin;

void setup() {
  servoPin.nbr = servoPinAssign;
  servoPin.isState = 0;
  pinMode(servoPin.nbr, OUTPUT);
  servoPin.ticks = 1500 * 32;

  timer1_init(servoPin.ticks);
}

void loop() {
  for (int i = 580; i < 2620; i++) {
    noInterrupts();
    servoPin.ticks = i * 32;
    interrupts();
    delay(1);
  }
  for (int i = 2620; i > 580; i--) {
    noInterrupts();
    servoPin.ticks = i * 32;
    interrupts();
    delay(1);
  }
}

void timer1_isr() {
  /* clear the interrupt*/
  aux_reg_write(ARC_V2_TMR1_CONTROL, ARC_V2_TMR_CTRL_NH | ARC_V2_TMR_CTRL_IE);

  uint32_t nextCnt;
  servoPin.isState = 1 - servoPin.isState;
  digitalWrite(servoPin.nbr, servoPin.isState);

  nextCnt = (servoPin.isState ? servoPin.ticks :  (period * 32 * 1000) - servoPin.ticks);
  timer1_init(nextCnt);
}

inline void timer1_init(uint32_t ticks) {
  aux_reg_write(ARC_V2_TMR1_CONTROL, 0);
  aux_reg_write(ARC_V2_TMR1_COUNT, 0);    /* clear the count value */

  interrupt_connect(ARCV2_IRQ_TIMER1, timer1_isr);

  aux_reg_write(ARC_V2_TMR1_LIMIT, ticks); /* write the limit value */
  aux_reg_write(ARC_V2_TMR1_CONTROL, ARC_V2_TMR_CTRL_NH | ARC_V2_TMR_CTRL_IE);
  aux_reg_write(ARC_V2_TMR1_COUNT, 0); /* write the start value */

  interrupt_enable(ARCV2_IRQ_TIMER1);
}

 

 出力を9pin、制御周期を10msにしてます。このスケッチでは、サーボモータをー90°~+90°へ連続で往復させてます。101ボード前提でスケッチしていますので、UNOで使用する場合は割り込み関係、タイミングをUNO用に変更すれば動作可能です。

 

 servo.hの中身を直接変更すればもっと簡単にできるのですが、ライブラリ弄るのは抵抗があるのと、予期せぬことが起きそうでやめました。内容はほぼservo.h/.cppの関係ない部分を一切排除したようなスケッチです。

 

スマホからサーボモータを制御

 

コメント

タイトルとURLをコピーしました