目次
前
次
ゲート制御スケッチ
角度を制御するには、サーボモータを利用します。
サーボモータの動きが最もよくわかるのは、駐車場
の出入口にあるゲートでしょう。
サーボモータのワイヤーは、3ピンになっています。
(電源、GND、信号の3ピン)
サーボモータを動かすには、パルスを与えます。
20ms周期で1ms〜2msの幅のパルスを利用し
角度を制御します。従ってPWM波形を出力
することになります。
Arduinoには、サーボモータを利用するための
ライブラリが用意されています。
どういう関数を利用するか、回路図等は
次のページで詳しく説明されています。
ページの右にある関数リストは、ライブラリServoを
利用することを宣言したときに使えます。
サーボモータの信号ピンに、パルスを出力する
には、analogWrite関数を使います。
ライブラリServoを利用すると、1つのサーボモータを
1つのオブジェクトとして扱います。Javaの仕様と同じ
と考えれば、わかりやすいでしょう。
端末から与えた角度で、サーボモータを0〜180度の
任意の角度を形作るスケッチは、以下となります。
#include <Servo.h>
// pin assignment
#define SERVOPIN 9
#define DMAX 179
#define DMID 90
#define DMIN 0
#define INTERV 200
// create servo object to control a servo
Servo oneservo;
int val;
char cmd ;
int xinterval ;
void setup()
{
// serial
Serial.begin(9600);
// attaches the servo
oneservo.attach(SERVOPIN);
// place 90 degree
val = DMID ;
oneservo.write(val);
// delay counter
xinterval = INTERV ;
}
void loop()
{
// serial handling
if (Serial.available() > 0) {
// get command
cmd = Serial.read();
// judge increment
if ( cmd == 'i' ) {
// increment
val++ ;
// upper limitter
if ( val > DMAX ) { val = DMAX ; }
}
// judge decrement
if ( cmd == 'd' ) {
// decrement
val-- ;
// lower limitter
if ( val < DMIN ) { val = DMIN ; }
}
}
// impress
oneservo.write(val);
// delay
delay(xinterval);
}
90度の位置に動かし、コマンド'i'、'd'により
角度を増減します。
シリアルでの動作を確認できたなら、スイッチを
利用して、ゲートの上げ下げを考えます。
2つのスイッチをTOP、BOTTOMに対応させ
0度か90度かを指定させます。
バーの上下動を制御するようにスケッチを
作成します。
基本となる内容を考えます。
スイッチの変化をとらえる
スイッチを2つ利用するとして、押したときに
ゲートバーの状態が変化させたいもの。
シフトレジスタを利用して、スイッチの状態に変化
があったとき、それを通知するようにします。
タイマー割込みで、スイッチの状態を読み込んで
シフトレジスタのLSBに付加してやります。
ms単位のタイマー処理は、次のページに解説が
あります。
ライブラリをダウンロード後、ArudinoIDEのある
ディレクトリのサブディレクトリlibrariesに
展開して入れておきます。
このページの情報から、タイマー割込みハンドラを
定義して、そのハンドラが使えるようにすればよい
ようです。タイマー割込みハンドラを定義します。
#define OFF 0
#define ON OFF+1
#define MASK01 0x01
#define MASK03 0x03
void update_sw() {
// shift
tsft <<= 1 ;
bsft <<= 1 ;
// mask
tsft &= MASK03 ;
bsft &= MASK03 ;
// get switch state
if ( digitalRead( TBUTTON ) == LOW ) { tsft |= ON ; }
if ( digitalRead( BBUTTON ) == LOW ) { bsft |= ON ; }
// judge
if ( tsft == MASK01 ) { tflag = ON ; }
if ( bsft == MASK01 ) { bflag = ON ; }
}
タイマー割込みハンドラの周期を設定し、割込みが利用
できるようにsetup関数の中で、setとstartの2メソッド
を使います。
// 100ms period
MsTimer2::set(100,update_sw);
// enable
MsTimer2::start();
状態管理
タイマー割込みハンドラからフラグで状態変更が
通知されるので、loopの中でサーボモータへの
角度を指定します。
フラグを監視し、対応するフラグでの通知が
来たなら、角度数値を再設定します。
処理は、非常に単純で、以下のようにします。
// rise bar
if ( tflag == ON ) {
// clear flag
tflag = OFF ;
// set 90 degree
val = DMID ;
}
// fall bar
if ( bflag == ON ) {
// clear flag
bflag = OFF ;
// set 90 degree
val = DMIN ;
}
必要な情報が整ったので、スケッチを定義します。
#include <MsTimer2.h>
#include <Servo.h>
// pin assignment
#define SERVOPIN 9
#define TBUTTON 10
#define BBUTTON 11
#define DMAX 179
#define DMID 90
#define DMIN 0
#define INTERV 200
#define OFF 0
#define ON OFF+1
#define MASK01 0x01
#define MASK03 0x03
// create servo object to control a servo
Servo oneservo;
int val;
char cmd ;
int xinterval ;
byte tsft ;
byte bsft ;
byte tflag ;
byte bflag ;
// MtTimer2 interrupt handler
void update_sw() {
// shift
tsft <<= 1 ;
bsft <<= 1 ;
// mask
tsft &= MASK03 ;
bsft &= MASK03 ;
// get switch state
if ( digitalRead( TBUTTON ) == LOW ) { tsft |= ON ; }
if ( digitalRead( BBUTTON ) == LOW ) { bsft |= ON ; }
// judge
if ( tsft == MASK01 ) { tflag = ON ; }
if ( bsft == MASK01 ) { bflag = ON ; }
}
void setup()
{
// pin assignment
pinMode(TBUTTON,INPUT);
pinMode(BBUTTON,INPUT);
// attaches the servo
oneservo.attach(SERVOPIN);
// place 0 degree
val = DMIN ;
oneservo.write(val);
// delay counter
xinterval = INTERV ;
// clear shift registers
tsft = 0 ;
bsft = 0 ;
// clear flags
tflag = OFF ;
bflag = OFF ;
// 10ms period
MsTimer2::set(10,update_sw);
// enable
MsTimer2::start();
}
void loop()
{
// rise bar
if ( tflag == ON ) {
// clear flag
tflag = OFF ;
// set 90 degree
val = DMID ;
}
// fall bar
if ( bflag == ON ) {
// clear flag
bflag = OFF ;
// set 90 degree
val = DMIN ;
}
// impress
oneservo.write(val);
// delay
delay(xinterval);
}
目次
前
次