目次
前
次
スキャナ制御ファームウエア
回路図を作成したので、ライントレースロボットで使う
スキャナ制御用ファームウエアを設計します。
このファームウエアは、1,024回、データを入力して
リニアイメージセンサが出力する論理値を記憶して
出力します。
論理値出力Voutは、φ1の立ち上がりエッジでと規定されています。
Enable信号がHのときに、Voutを記憶します。
スキャナからは、2,094個の論理値が出力されますが、半分の
1,047個を捕捉します。この1,047のうち、最初の16と最後の7
ビットは不要なので、これらを除いた1,024個の情報を扱います。
128の整数倍の位置にある論理値を8個結合し、センサーデータ
にします。
有効なVoutが出力されていることは、EnableがHのときなので
シフトレジスタで、L→Hをとらえて、シーケンサを動かします。
0〜1024回目の処理を考えます。
データ入力を、次のシーケンスで実行します。
- SHの立ち上がりエッジ補足しカウンタイネーブル
- φ1の立ち上がりエッジでセンサーデータ入力
- 指定されたカウンタ値でEnableがHならば、シフトレジスタにデータ入力
- カウンタの値が1024ならば、8ビットセンサーデータを出力
- 1にもどる
φ1の立ち上がりエッジ補足は、シフトレジスタを利用します。
利用するマイコンは、ATtiny2313を選びました。
SHの立ち上がりエッジ捕捉で、内部カウンタをイネーブル
φ1の立ち上がりエッジ捕足で、データ入力トリガー生成
として対応します。
8ビットのシフトレジスタに、入力データを入れるかは
Enableの論理値で決定します。
無限ループの中で、次の処理を実行します。
- SHの立ち上がりエッジを捕捉し、センサーデータ、カウンタクリア
- φ1の立ち上がりエッジ捕捉し、カウンタインクリメント
- Voutを入力し、指定カウント値のとき、シフトレジスタに入力
ソースコードにまとめます。
#include <avr/io.h>
#include <avr/interrupt.h>
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
#define OFF 0
#define ON OFF+1
#define SH_BIT 2
#define CLKA_BIT 3
#define ENABLE_BIT 5
volatile UWORD scnt ;
volatile UBYTE shsft ;
volatile UBYTE clockasft ;
volatile UBYTE sensor ;
volatile UBYTE tmp ;
volatile UBYTE sdata ;
#define NO 0
#define YES NO+1
#define MASK01 0x01
#define MASK03 0x03
#define LAST 1050
/*--------------------------------*/
/* Insert user functions protoype */
/*--------------------------------*/
void user_initialize(void);
/*------*/
/* main */
/*------*/
int main(void)
{
/* initialize port and variables */
user_initialize();
/* endless loop */
while ( ON ) {
/* get signals */
tmp = PIND ;
/* shift */
shsft <<= 1 ;
clockasft <<= 1 ;
/* mask */
shsft &= MASK03 ;
clockasft &= MASK03 ;
/* store */
if ( tmp & (1 << SH_BIT) ) { shsft |= ON ; }
if ( tmp & (1 << CLKA_BIT) ) { clockasft |= ON ; }
/* judge SH rising edge */
if ( shsft == 0x01 ) {
scnt = 0 ;
sensor = 0 ;
}
/* judge CLOCKA rising edge */
if ( clockasft == MASK01 ) {
scnt++ ;
if ( scnt == LAST ) { scnt = 0 ; }
}
/* get data */
sdata = 0 ;
if ( tmp & 0x30 ) { sdata |= ON ; }
/* store */
if ( tmp & (1 << ENABLE_BIT) ) {
switch ( scnt ) {
case 79 : sensor <<= 1 ; sensor |= sdata ; break ;
case 207 : sensor <<= 1 ; sensor |= sdata ; break ;
case 335 : sensor <<= 1 ; sensor |= sdata ; break ;
case 463 : sensor <<= 1 ; sensor |= sdata ; break ;
case 591 : sensor <<= 1 ; sensor |= sdata ; break ;
case 719 : sensor <<= 1 ; sensor |= sdata ; break ;
case 847 : sensor <<= 1 ; sensor |= sdata ; break ;
case 975 : sensor <<= 1 ; sensor |= sdata ; break ;
default : break ;
}
}
/* impress */
if ( scnt == 1000 ) { PORTB = sensor ; }
}
/* dummy */
return 0 ;
}
/*-----------------------*/
/* Insert user functions */
/*-----------------------*/
void user_initialize(void)
{
/* PORT B */
PORTB = 0b00000000 ; /* 00000000 */
DDRB = 0b11111111 ; /* oooooooo */
/* PORT D */
PORTD = 0b00001100 ; /* 00000000 */
DDRD = 0b10000011 ; /* oiiiiioo */
/* clear */
scnt = 0 ;
shsft = 0 ;
clockasft = 0 ;
sensor = 0 ;
}
入力データの前後には、画素でないデータが存在しますが
有効な1024画素の中から8画素を入手する方法を取ります。
カウンタの値が128の奇数倍になるのは、カウンタの値が
1024になるまでに、いくつあるのかは、AWKで計算しました。
{
# calculate location
result = $1 * $2 ;
# set area center
result = result + $3 ;
# skip dummy data
result = result + $4 ;
# show
printf("%s => %d \n",$0,result);
}
元になるテキストファイルの内容は、以下。
0 128 64 15
1 128 64 15
2 128 64 15
3 128 64 15
4 128 64 15
5 128 64 15
6 128 64 15
7 128 64 15
このスクリプトで、次のように8回分の処理が
なされていることを確認できます。
0 128 64 15 => 79
1 128 64 15 => 207
2 128 64 15 => 335
3 128 64 15 => 463
4 128 64 15 => 591
5 128 64 15 => 719
6 128 64 15 => 847
7 128 64 15 => 975
目次
前
次