#はじめに
とある事情でステージを動かしたかったのだが、そのステージを作っている企業さんが出しているコントローラでは加減速をしながらステージ操作が出来ないと言われ、しかたなく速度制御を行っているパルスを生成・制御するためにArduinoを使った.
#必要項目
今回のパルスの生成・制御には、以下のような要素を持たせる必要がある.
- 発振回数等での制御
- 最大10khzのパルス生成
- 発振周波数等のパラメータ変更
- 発振ピンの切り替え
発振周波数の変更や10khzの発振だけであればPWMを用いた下記ブログさんのような制御
Arduino Uno – PWM周波数を”自由に”変更する
(http://blog.kts.jp.net/arduino-pwm-change-freq/)
を行えば良いのだが発振回数等を用いた制御にはちょっと不便だなと思った.(知識不足の部分が大きいが)
であるので今回はシンプルにtimerとdigitalWriteを用いて実装した.
#手法
今回用いた手法はTimerOneというライブラリを用いて時間制御を
パルスの生成は標準のdigitalWriteを用いて行った.
なぜわざわざTimerOneのライブラリを用いて時間制御を行うかと言えば,
標準のdelayだと8bit駆動でありmsec単位での制御しか出来ず10khzのパルス生成を行えなかったからである.
TimerOneで使えるtimerはは元々PWMの制御用のtimerらしく16bitで駆動する.
そのためusec単位での時間制御が可能であるらしい.
そのへんに関して下記のブログさん辺りが詳しい
Arduinoのタイマーライブラリ - miso-engine
(http://miso-engine.hatenablog.com/entry/2015/07/20/221014)
#実装
正直コーディングには自信が無いので雑な実装になってると思うが
とりあえず動いてるので良しとする
#include <TimerOne.h>
#ピン制御切り替え用のフラグ
int main_flg = 0;
#HIGH/LOW切り替え用のフラグ
bool flg_13 =false;
bool flg_12 =false;
#発振周波数/発振周期
long hz = 1000;
long us = 1000000/hz;
#ピン番号切替
void choice_pin(){
if (main_flg == 1){
switch_puls_13();
}
else if (main_flg == -1){
switch_puls_12();
}
else{
puls_stop();
}
}
#初期設定
void setup() {
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
Serial.begin(9600);
Timer1.initialize(100);
Timer1.attachInterrupt(choice_pin);
}
#シリアル入力によるピン・速度制御
void loop() {
if(Serial.available()){
int inputchar = Serial.read();
switch(inputchar){
case 'j':
Serial.println("open");
main_flg = 1;
break;
case 'k':
Serial.println("close");
main_flg = -1;
break;
case 'h':
Serial.println("speed down");
hz = hz - 100;
us = 1000000/hz;
break;
case 'l':
Serial.println("speed up");
hz = hz + 100;
us = 1000000/hz;
break;
case 's':
Serial.println("stop");
main_flg = 0;
break;
}
}
}
#13番ピンHIGH/LOW切り替え
void switch_puls_13(){
digitalWrite(12, LOW);
if(flg_13 ==true){
digitalWrite(13, HIGH);
flg_13 =false;
}
else{
digitalWrite(13, LOW);
flg_13 =true;
}
Timer1.setPeriod(us);
}
#12番ピンHIGH/LOW切り替え
void switch_puls_12(){
digitalWrite(13, LOW);
if(flg_12 ==true){
t(12, HIGH);
flg_12 =false;
}
else{
digitalWrite(12, LOW);
flg_12 =true;
}
Timer1.setPeriod(us);
}
#信号停止
void puls_stop(){
digitalWrite(13, LOW);
digitalWrite(12, LOW);
}
発振回数による制御はここには書いてないが、まあ出来ると思う.
こんなところ.