Arduino/Genuino101でサーボモータの制御方法です。servo.hライブラリを使用すれば簡単に制御できるのですが、ライブラリではサーボの制御信号周期が20ms程度で固定されています。この信号周期を任意で変更したかったので、今回はライブラリは利用せずにサーボを制御してみたいと思います。
サーボモータの概要
簡単に、サーボモータの制御方法です。パルス幅500μs~2600μs程度、周期20ms程度の信号をサーボに送れば制御できます。サーボの回転角はパルス幅を変更することで制御できます。
今回使用したサーボは、パルス幅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の関係ない部分を一切排除したようなスケッチです。
コメント