目次
前
次
スタートゲートセンサー再考
mugen2016、mugen2015には、スタートゲートセンサーと
して超音波センサーを利用してきました。
この超音波センサーでは、距離をパルス幅で出力してくる
ので、デジタル回路で計測していました。この計測時間を
なくすことを考えました。
¥50程度で入手できるフォトリフレクタを
評価してみました。
フォトリフレクタは、物体までの距離は反射があるのは
10mmが限度でした。この距離だと、センサーはゲートに
密着させる程度までにしないと駄目。
実際に使われているスタートゲートは、以下。
ゲートの開閉をとらえるためには、象の鼻のように
センサーを密着させる程度に近づける必要あり。
データシートには、次の回路をサンプルとしています。
光の反射があると、'L'レベルであり、反射がないと'H'。
そのまま利用すると、次の判定をすればゲートの開閉を
判断できます。
'L'レベル=ゲートは閉じている
'H'レベル=ゲートは開いている
マイコン、FPGAでの論理レベル判定をするためには
NPN型トランジスタかNchエンハンスメント型MOSFET
による電圧フォロワを入れて対応すべきでしょう。
NPN型トランジスタを利用すると、エミッタフォロワの
出力電圧は、ベース電圧から0.6V程度引いた値になり
3.3Vを与えると2.7V程度。
光が入ると、フォトリフレクタのコレクタは0V近くまで
電圧が下がり、エミッタフォロワの出力電圧も0Vに。
フォトリフレクタの内蔵LEDは、60mAまでの許容電流が
あるので、100Ωでは (3.3V-1.8V)/100=15mA 程度です
から、破損することはないでしょう。
フォトリフレタは、距離測定が不要なのでシーケンス
処理をしないで済ませられます。
光を扱う場合、変調をかけて照射し受光側で整流する
のが定番なので、その回路を考えます。
変調は単純なON/OFF信号を与え、受信側では2倍圧整流
してみます。回路構成は、以下。
ゲートの開閉をデジタル値で出力すればよいので、シリコン
ダイオードを利用した2倍圧整流で対応します。
変調用クロックは、1kHz前後でよいと判断しました。
クロック生成は、555のような発振ICで簡単に生成。
555は、抵抗値の組み合わせで任意の周波数を指定できます。
低消費電力にするためには、CMOSタイプの555を選定すべきでしょう。
CMOSタイプの555は、3種程度もっているので、次の基板で
抵抗値の組み合わせを調べられるようにしてます。
ダイオードで、変調波を復調して直流に変換するので
1kHzから100Hzの矩形波でよいとわかりました。
555は、8ピンなのでPIC12F1501を利用して
常にスタートゲートまでの距離を測定して電圧
で出力する基板も作成しました。
回路図は、以下。
VOUT、VOUTXが距離に相当する電圧を出力し
TOVER、TOVERXが距離が範囲外の場合、'1'とします。
PICが動作していることを、TOTからパルスを出力して
アナログマルチメータでは、電圧を積分したカタチで
固定電圧で判断できるようにしました。
LEDを接続すると、薄ぼんやりと点灯するので、LEDを
接続しても、動作していると判断できます。
PIC12F1501のファームウエアは、以下。
/* redefine data type */
typedef unsigned char UBYTE ;
typedef unsigned int UWORD ;
typedef unsigned long ULONG ;
typedef union {
struct {
unsigned B0:1;
unsigned B1:1;
unsigned B2:1;
unsigned B3:1;
unsigned B4:1;
unsigned B5:1;
unsigned B6:1;
unsigned B7:1;
} BIT ;
unsigned char DR ;
} FLAGSP ;
volatile FLAGSP xflags ;
volatile UBYTE xcnt ;
volatile UBYTE ycnt ;
volatile UBYTE dh ;
volatile UBYTE dl ;
volatile UWORD xtim ;
volatile UBYTE xlen ;
#define EFLAG xflags.BIT.B0
#define SFLAG xflags.BIT.B1
#define OFLAG xflags.BIT.B2
#define OFF 0
#define ON OFF+1
#define CNTBEGIN 6
#define DEFX 588
#define TOVER PORTA.F1
#define DMON PORTA.F2
#define ECHO PORTA.F4
#define TRG PORTA.F5
/* function prototype */
void init_usr(void);
void dac_write(UBYTE x);
void dac_init(void);
/* interrupt handler */
void interrupt(void)
{
/* generate trigger 1ms interval */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* initialize */
TMR0 = CNTBEGIN ;
/* increment */
xcnt++ ;
/* judge */
if ( xcnt == 100 ) {
xcnt = 0 ;
EFLAG = ON ;
}
}
/* echo handling */
if ( PIR1.TMR1GIF == ON ) {
/* clear flag */
PIR1.TMR1GIF = OFF ;
/* set flag */
SFLAG = ON ;
}
/* echo handling (overflow) */
if ( PIR1.TMR1IF == ON ) {
/* clear flag */
PIR1.TMR1IF = OFF ;
/* set flag */
OFLAG = ON ;
}
}
void main(void)
{
UBYTE i ;
/* user initialize */
init_usr();
/* endless loop */
while ( ON ) {
/* sensor handling */
if ( SFLAG == ON ) {
/* clear flag */
SFLAG = OFF ;
/* stop timer1 */
T1CON.TMR1ON = OFF ;
/* get timer counter */
dl = TMR1L ;
dh = TMR1H ;
xtim = dh * 256 + dl ;
/* calculate distance 100mm : 588 us */
xlen = (UBYTE)((32.0 * xtim) / DEFX) ;
/* upper limiter */
if ( xlen > 21 ) { xlen = 21 ; }
/* calculate voltage */
dac_write(xlen);
}
/* sensor handling (overflow) */
if ( OFLAG == ON ) {
/* clear flag */
OFLAG = OFF ;
/* impress */
TOVER = ON ;
}
/* execute */
if ( EFLAG == ON ) {
/* clear flag */
EFLAG = OFF ;
/* monitor counter increment */
ycnt++ ;
if ( ycnt & ON ) { DMON = ON ; }
else { DMON = OFF ; }
/* clear */
TMR1L = 0 ;
TMR1H = 0 ;
/* start timer1 */
T1CON.TMR1ON = ON ;
/* indicator */
TOVER = OFF ;
/* send start trigger */
TRG = ON ;
for ( i = 0 ; i < 160 ; i++ ) ;
TRG = OFF ;
}
}
}
/* define function body */
void init_usr(void)
{
/* select 16MHz */
OSCCON = (15 << 3) | 0x03 ;
/* disable A/D converter */
ADCON0.ADON = OFF ;
ADCON2 = 0 ;
ANSELA = 0 ;
/* initialize D/A converter */
dac_init();
/* disable compare module */
CM1CON0.C1ON = OFF ;
CM1CON0.C1OE = OFF ;
/* I/O state */
PORTA = 0x00 ;
/* I/O directions */
TRISA = 0x18 ; /* bit0,1,2,5 as output , others as input */
/* pull up */
WPUA = 0x10 ;
/* initialize timer 0 */
{
/*
16MHz/4 = 4MHz (Fosc)
Fosc/4 = 1MHz
1MHz/4 = 250kHz prescaler = 1:4
*/
OPTION_REG = 0x01 ;
/* 256 - 250 = 6 */
TMR0 = CNTBEGIN ;
/* enable timer0 overflow interrupt */
INTCON.TMR0IE = ON ;
}
/* initialize timer 1 */
{
T1CON = 0x24 ;
T1GCON = 0xc0 ;
/* select RA4 */
APFCON.T1GSEL = OFF ;
/* enable peripheral TMR1GE */
PIE1.TMR1GE = ON ;
/* enable TMR1 overflow interrupt */
PIE1.TMR1IE = ON ;
/* enable peripheral interrupt */
INTCON.PEIE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
/* clear flags */
xflags.DR = 0 ;
/* initialize variables */
xcnt = 0 ;
ycnt = 0 ;
xtim = 0 ;
xlen = 0 ;
}
void dac_write(UBYTE x)
{
DACCON1 = (0x1f & x);
}
void dac_init(void)
{
/* reference Vdd */
DACCON0.DACPSS = OFF ;
/* enable DAC output #1 */
DACCON0.DACOE1 = ON ;
/* use DAC */
DACCON0.DACEN = ON ;
}
目次
前
次