目次
前
次
方向指示器スケッチ
自動車の方向指示器と建物へ導く方向指示器の
2つのスケッチを作成してみます。
自動車の方向指示器は、2つのプッシュスイッチ
と2つのLEDを利用してエミュレーションします。
各デバイスとピン番号を指定します。
ブレッドボード上にLEDとスイッチを実装
すると、以下です。
点滅周期は500msとして、左、右のどちらで
点滅するかをmodeという変数でわかるとして
みます。
変数stateを利用して、このLSBが1か0かで
LEDを点滅させる仕様としました。
// none
if ( mode == MODE_NONE ) {
digitalWrite(LEFT_LED ,LED_LOW);
digitalWrite(RIGHT_LED,LED_LOW);
}
// left direction
if ( mode == MODE_LEFT ) {
if ( state & 1 ) { digitalWrite(LEFT_LED,LED_HIGH); }
else { digitalWrite(LEFT_LED,LED_LOW) ; }
}
// right direction
if ( mode == MODE_RIGHT ) {
if ( state & 1 ) { digitalWrite(RIGHT_LED,LED_HIGH); }
else { digitalWrite(RIGHT_LED,LED_LOW) ; }
}
// increment
state++ ;
// delay
delay(xinterval);
変数modeの値を2スイッチの状態で
決定することにします。
それには、2スイッチの状態を入力
する必要があるので、以下のように
定義しました。
tmp = (digitalRead(LEFT_SW) << 1) | digitalRead(RIGHT_SW) ;
変数tmpの値で、mode値を決定します。
switch ( tmp ) {
case 1 : mode = MODE_LEFT ; break ;
case 2 : mode = MODE_RIGHT ; break ;
default : mode = MODE_NONE ; break ;
}
loopの内容が確定したので、setupを入れて
スケッチを完成させます。
#define INTERV 500
#define LED_LOW HIGH
#define LED_HIGH LOW
#define MODE_NONE 0
#define MODE_RIGHT 1
#define MODE_LEFT 2
// define data types
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
// pin assign
#define LEFT_LED 12
#define RIGHT_LED 11
#define LEFT_SW 9
#define RIGHT_SW 8
// variables
UWORD xinterval ;
UBYTE state ;
UBYTE mode ;
UBYTE tmp ;
void setup() {
// PWM pin
pinMode(LEFT_LED ,OUTPUT);
pinMode(RIGHT_LED,OUTPUT);
pinMode(LEFT_SW ,INPUT);
pinMode(RIGHT_SW ,INPUT);
// set interval
xinterval = INTERV ;
// set state
state = 0 ;
// set mode
mode = MODE_NONE ;
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
// get mode
tmp = (digitalRead(LEFT_SW) << 1) | digitalRead(RIGHT_SW) ;
switch ( tmp ) {
case 1 : mode = MODE_LEFT ; break ;
case 2 : mode = MODE_RIGHT ; break ;
default : mode = MODE_NONE ; break ;
}
// none
if ( mode == MODE_NONE ) {
digitalWrite(LEFT_LED ,LED_LOW);
digitalWrite(RIGHT_LED,LED_LOW);
}
// left direction
if ( mode == MODE_LEFT ) {
if ( state & 1 ) { digitalWrite(LEFT_LED,LED_HIGH); }
else { digitalWrite(LEFT_LED,LED_LOW) ; }
}
// right direction
if ( mode == MODE_RIGHT ) {
if ( state & 1 ) { digitalWrite(RIGHT_LED,LED_HIGH); }
else { digitalWrite(RIGHT_LED,LED_LOW) ; }
}
// increment
state++ ;
// delay
delay(xinterval);
}
次に建物に導く方向指示器のスケッチを考えます。
2つのプッシュスイッチと6つのLEDを利用して
エミュレーションします。
各デバイスとピン番号を指定します。
ブレッドボード上に部品を実装すると以下。
点滅周期は自動車と同じにして、スイッチを
押している間、左から右あるいは右から左に
LEDを点滅していくことに。
6個のLEDの点滅パターンを配列に入れます。
*(dirled+0) = ~0x01 ; // 1111 1110
*(dirled+1) = ~0x02 ; // 1111 1101
*(dirled+2) = ~0x04 ; // 1111 1011
*(dirled+3) = ~0x08 ; // 1111 0111
*(dirled+4) = ~0x10 ; // 1110 1111
*(dirled+5) = ~0x20 ; // 1101 1111
表示は、左から右、右から左の2通りに
なりますが、パターンの引出し方を変え
対応します。
// left direction
if ( mode == MODE_LEFT ) {
PORTC = *(dirled+state) ;
}
// right direction
if ( mode == MODE_RIGHT ) {
i = LAST-state ;
PORTC = *(dirled+i) ;
}
通常アナログで利用するピンは、デジタルに
すると、14〜19になっています。14〜19ピン
は、ポートCに接続されています。
複数ピンを一度に扱うため、DDRC、PORTCを
適用します。
ここまで仕様を詰めたなら、自動車の方向指示器
スケッチをコピーして、必要な部分を修正、追加
します。出来上がったプログラムは、以下です。
#define INTERV 100
#define LAST 5
#define MAX 6
// define data types
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
// pin assign
#define LEFT_SW 9
#define RIGHT_SW 8
#define MODE_NONE 0
#define MODE_RIGHT 1
#define MODE_LEFT 2
// variables
UWORD xinterval ;
UBYTE state ;
UBYTE mode ;
UBYTE dirled[6] ;
UBYTE tmp ;
UBYTE i ;
UBYTE cport ;
void setup() {
// PWM pin
pinMode(LEFT_SW ,INPUT);
pinMode(RIGHT_SW ,INPUT);
DDRC = 0xff ;
// set interval
xinterval = INTERV ;
// set state
state = 0 ;
// set mode
mode = MODE_NONE ;
// set values
*(dirled+0) = ~0x01 ; // 1111 1110
*(dirled+1) = ~0x02 ; // 1111 1101
*(dirled+2) = ~0x04 ; // 1111 1011
*(dirled+3) = ~0x08 ; // 1111 0111
*(dirled+4) = ~0x10 ; // 1110 1111
*(dirled+5) = ~0x20 ; // 1101 1111
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
// command interpreter
{
tmp = (digitalRead(LEFT_SW) << 1) | digitalRead(RIGHT_SW) ;
// get mode
switch ( tmp ) {
case 1 : mode = MODE_LEFT ; break ;
case 2 : mode = MODE_RIGHT ; break ;
default : mode = MODE_NONE ; break ;
}
}
// state machine
{
// none
if ( mode == MODE_NONE ) { cport = 0xff ; }
// left direction
if ( mode == MODE_LEFT ) { cport = *(dirled+state) ; }
// right direction
if ( mode == MODE_RIGHT ) {
i = LAST-state ;
cport = *(dirled+i) ;
}
// impress
PORTC = cport ;
// increment
state++ ;
if ( state == MAX ) { state = 0 ; }
// delay
delay(xinterval);
}
}
loopの中は単純に、次のことを繰返しているだけです。
- 2つのスイッチの状態を取得
- 状態からモードを確定
- モードによりLEDへ出力するパターン生成
- LEDへパターン出力
- 状態値更新
- ディレイ
- 1にもどる
PORTCは、ハードウエアピンなので、外部メモリ変数
cportに値を保存し、一度だけアクセスしています。
外部へのビットパターン出力は、一度きりにすると
バグが入る余地が少なくなります。
目次
前
次