目次
前
次
カラーセンサー情報取得3
浜松ホトニクスのI2Cバスインタフェースカラーセンサーを
2個、Arduinoに接続してみます。
基板に回路を半田付けすると、次のようになります。
デジタルインタフェースがあるので、その2ビットを利用して
動作させることも可能ですが、AVRチップ内蔵ハードウエアを
利用して信頼度を確保します。
アナログスイッチを利用して、2個のカラーセンサーとの
接続を切り替えます。しかし、この方法では、うまく動作
しませんでした。
カラーセンサーは3.3Vで動作するため、プルアップしても
Arduinoが5V動作が前提であるため、電圧のレベル変換が
必要でした。
秋月電子で販売されている双方向電圧レベル変換モジュール
を利用して、対応しました。
このモジュールを利用して動作確認するために
作成したスケッチは、以下。
#include <MsTimer2.h>
#include <EEPROM.h>
#define OFF 0
#define ON OFF+1
#define MSCL_BIT 3
#define MSDA_BIT 2
#define MASK80 0x80
#define IIC_CNT 32
#define LED_BIT 5
#define DEVICE_ID 0x2A
#define CONTROL_REG 0x00
#define NPER 800
#define SCODE_ADR 0x100
#define SHOW_ADR 0x101
/* event flag */
boolean eflag ;
boolean tflag ;
boolean uflag ;
/* state flag */
boolean gflag ; /* select only green information */
boolean mflag ; /* mask flag */
/* timing counter */
byte xcnt ;
/* serial interface */
byte cmd ;
byte sindex ;
char sbuf[4] ;
/* RGB and IR */
word xrgbi[4] ;
/* sensor command */
byte scmd ;
/* LED flashing */
void send_led(byte x)
{
if ( x ) { PORTB |= (1 << LED_BIT) ; }
else { PORTB &= ~(1 << LED_BIT) ; }
}
/* generate trigger */
void update_trigger(void)
{
/* LED flashing */
send_led( xcnt & ON );
/* trigger */
xcnt++ ;
if ( xcnt & ON ) { tflag = ON ; }
}
/* putchar on serial interface */
void rs_putchar(char x)
{
Serial.write(x);
}
/* puts on serial interface */
void rs_puts(char *x)
{
while ( *x ) {
rs_putchar( *x );
x++ ;
}
}
/* new line */
void crlf()
{
rs_putchar('\r');
rs_putchar('\n');
}
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("E execute") ; crlf();
rs_puts("I idle") ; crlf();
rs_puts("C one shot") ; crlf();
rs_puts("S set sensibility 1:high 0:low") ; crlf();
rs_puts("L set exposure time Length(0/1/2/3)") ; crlf();
rs_puts("G set only Green information 1:YES 0:NO") ; crlf();
rs_puts("M set mask 1:YES 0:NO") ; crlf();
rs_puts("s show staus") ; crlf();
}
void show_value(word x)
{
word tmp ;
char msg[6] ;
byte i ;
/* copy */
tmp = x;
/* delimiter */
*(msg+5) = '\0' ;
/* separate */
for ( i = 0 ; i < 5 ; i++ ) {
/* value -> digit number */
*(msg+4-i) = (tmp % 10)+ '0' ;
/* next */
tmp /= 10 ;
}
/* zero surppress */
if ( x < 10000 ) {
*(msg+0) = ' ' ;
if ( x < 1000 ) {
*(msg+1) = ' ' ;
if ( x < 100 ) {
*(msg+2) = ' ' ;
if ( x < 10 ) {
*(msg+3) = ' ' ;
}
}
}
}
/* show */
rs_puts( msg ) ;
rs_putchar(' ');
}
void m_iic_wait(void)
{
byte i ;
/* wait */
for ( i = 0 ; i < IIC_CNT ; i++ ) ;
}
void m_iic_scl(byte x)
{
/* impress */
if ( x ) { PORTC |= (1 << MSCL_BIT) ; }
else { PORTC &= ~(1 << MSCL_BIT) ; }
/* delay */
m_iic_wait();
}
void m_iic_start(void)
{
/* both H */
PORTC |= (3 << MSDA_BIT) ;
/* delay */
m_iic_wait();
/* 0 -> SDA */
PORTC &= ~(1 << MSDA_BIT) ;
/* delay */
m_iic_wait();
/* 0 -> SCL */
PORTC &= ~(1 << MSCL_BIT) ;
}
void m_iic_stop(void)
{
/* set level */
PORTC |= (1 << MSCL_BIT) ;
PORTC &= ~(1 << MSDA_BIT) ;
/* delay */
m_iic_wait();
/* 1 -> SDA */
PORTC |= (1 << MSDA_BIT) ;
/* delay */
m_iic_wait();
}
byte m_iic_write(byte x)
{
byte i ;
byte tmp ;
/* load raw data */
tmp = x ;
/* transfer data with write code */
for ( i = 0 ; i < 8 ; i++ ) {
/* send bit datum */
PORTC &= ~(1 << MSDA_BIT) ;
if ( tmp & MASK80 ) { PORTC |= (1 << MSDA_BIT) ; }
/* 1 -> SCL */
m_iic_scl(ON);
/* shift */
tmp <<= 1 ;
/* 0 -> SCL */
m_iic_scl(OFF);
}
PORTC &= ~(1 << MSDA_BIT) ;
/* change inupt */
DDRC &= ~(1 << MSDA_BIT) ;
/* 1 -> SCL */
m_iic_scl(ON);
/* get acknowledge */
tmp = (PINC & (1 << MSDA_BIT)) >> 2 ;
/* 0 -> SCL */
m_iic_scl(OFF);
/* change output */
DDRC |= (1 << MSDA_BIT) ;
return tmp ;
}
byte m_iic_read(byte x)
{
byte i;
byte result ;
/* change inupt */
PORTC &= ~(1 << MSDA_BIT) ;
DDRC &= ~(1 << MSDA_BIT) ;
/* default */
result = 0 ;
for ( i = 0 ; i < 8 ; i++ ) {
/* shift */
result <<= 1 ;
/* 1 -> SCL */
m_iic_scl(ON);
/* get bit datum */
if ( PINC & (1 << MSDA_BIT) ) { result |= ON ; }
/* 0 -> SCL */
m_iic_scl(OFF);
}
/* change output */
DDRC |= (1 << MSDA_BIT) ;
if ( x ) { PORTC |= (1 << MSDA_BIT); }
else { PORTC &= ~(1 << MSDA_BIT); }
/* 1 -> SCL */
m_iic_scl(ON);
/* 0 -> SCL */
m_iic_scl(OFF);
return result ;
}
void get_color()
{
byte i ;
byte j ;
word tmp ;
byte xx[8] ;
/*
preset gain mode exposure time (each color ch)
00 = 87.5us => 0.9ms
01 = 1.4ms => 2.0ms
10 = 22.4ms => 23ms
11 = 179.2ms => 180ms
*/
i = scmd & 3 ;
if ( i == 3 ) { tmp = 180 * 4; }
if ( i == 2 ) { tmp = 23 * 4; }
if ( i < 2 ) { tmp = 2 * 4; }
/* */
j = DEVICE_ID ;
j <<= 1 ;
j &= 0xFE ;
/* initialize */
m_iic_start();
m_iic_write(j);
m_iic_write(CONTROL_REG);
m_iic_write(0x83);
m_iic_start();
m_iic_write(j);
m_iic_write(CONTROL_REG);
/* set High or Low and exposure length */
m_iic_write(0x03);
m_iic_stop();
/* wait */
delay( tmp ) ;
/* read */
m_iic_start();
m_iic_write(j);
m_iic_write(0x03);
m_iic_start();
m_iic_write(j | ON);
/* get */
j = 0 ;
for ( i = 0 ; i < 8 ; i++ ) {
if ( i == 7 ) { j = 1 ; }
*(xx+i) = m_iic_read(j);
}
/* stop */
m_iic_stop();
/* store */
for ( i = 0 ; i < 4 ; i++ ) {
j = (i << 1);
tmp = *(xx+j) ;
tmp <<= 8 ;
tmp |= *(xx+j+1) ;
*(xrgbi+i) = tmp ;
}
}
void show_yn()
{
char msg[2];
/* delimiter */
*(msg+1) = '\0' ;
/* sensibility */
{
*(msg+0) = 'L' ;
if ( scmd & 8 ) { *(msg+0) = 'H' ; }
rs_puts( msg );
}
/* exposure length */
{
rs_putchar( '0'+(scmd & 3) );
}
/* Green */
{
*(msg+0) = 'N' ;
if ( gflag == ON ) { *(msg+0) = 'Y' ; }
rs_puts( msg );
}
/* Mask */
{
*(msg+0) = 'N' ;
if ( mflag == ON ) { *(msg+0) = 'Y' ; }
rs_puts( msg );
}
/* new line */
crlf();
}
void store_param(byte which,byte x)
{
word madr ;
/* sensibility or exposure length */
if ( which < 2 ) { madr = SCODE_ADR ; }
/* Green information */
if ( which == 2 ) { madr = SHOW_ADR ; }
/* store */
EEPROM.write(madr,x);
}
void show_color(boolean x)
{
/* only Green information */
if ( x ) {
rs_puts("G :") ; show_value( *(xrgbi+1) );
}
else
/* all color informations */
{
rs_puts("R :") ; show_value( *(xrgbi+0) );
rs_puts("G :") ; show_value( *(xrgbi+1) );
rs_puts("B :") ; show_value( *(xrgbi+2) );
rs_puts("IR:") ; show_value( *(xrgbi+3) );
}
crlf();
}
void setup()
{
/* initialize serial port */
Serial.begin(9600);
sindex = 0 ;
/* set initial state */
PORTB = 0x00 ;
PORTC = 0x0C ;
PORTD = 0x01 ;
/* direction */
DDRB = 0xff ;
DDRC = 0xff ;
DDRD = 0xfe ;
/* clear flags */
tflag = OFF ;
eflag = OFF ;
uflag = OFF ;
gflag = OFF ;
/* resume previous state */
xcnt = EEPROM.read(SCODE_ADR);
if ( xcnt == 0xff ) {
scmd = 11 ;
EEPROM.write(SCODE_ADR,scmd);
} else {
scmd = xcnt ;
}
xcnt = EEPROM.read(SHOW_ADR);
if ( xcnt != OFF ) { gflag = ON ; }
/* initialize variables */
xcnt = 0 ;
for ( xcnt = 0 ; xcnt < 4 ; xcnt++ ) { *(xrgbi+xcnt) = 0 ; }
/* trigger period */
MsTimer2::set(NPER,update_trigger);
/* enable */
MsTimer2::start();
}
void loop()
{
/* serial handling */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* new line */
crlf();
/* get command */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help() ; }
/* enable */
if ( cmd == 'E' ) { eflag = ON ; }
/* disable */
if ( cmd == 'I' ) { eflag = OFF ; }
/* one shot */
if ( cmd == 'C' ) {
/* get color values */
get_color();
/* show */
show_color(gflag);
}
/* write sensibility state */
if ( cmd == 'S' ) {
/* set default (selct LOW) */
scmd &= 0xf7 ;
/* set flag (HIGH or LOW) */
if ( *(sbuf+1) == '1' ) { scmd |= (1 << 3) ; }
/* store EEPROM */
store_param(0,scmd);
}
/* write exposure length */
if ( cmd == 'L' ) {
/* clear */
scmd &= 0xfc ;
/* generate code */
scmd |= ((*(sbuf+1) - '0') & 3);
/* store EEPROM */
store_param(1,scmd);
}
/* write only Green information */
if ( cmd == 'G' ) {
/* default */
gflag = OFF ;
/* judge */
if ( *(sbuf+1) == '1' ) { gflag = ON ; }
/* store */
store_param(2,gflag);
}
/* write mask */
if ( cmd == 'M' ) {
/* default */
mflag = OFF ;
/* judge */
if ( *(sbuf+1) == '1' ) { mflag = ON ; }
}
/* show status */
if ( cmd == 's' ) { show_yn(); }
}
/* timer handling */
if ( tflag == ON ) {
/* clear flag */
tflag = OFF ;
/* get color values */
get_color();
/* show */
if ( eflag == ON ) { show_color(gflag) ; }
}
}
/* receive interrupt */
void serialEvent()
{
char ch;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
Arduinoでは、A5、A4にSCL、SDAがアサインされています。
汎用I/OでIICバスの処理を実現するため、専用関数を5種
ほど用意して対応しました。
IICのインタフェースは、次の項目を実現する関数の定義を
考えました。
- start condtion
- stop condtion
- write 1byte without acknowledge
- write 1byte with acknowledge
- read 1byte without acknowledge
- read 1byte with acknowledge
6種の関数を定義できますが、カラーセンサーを扱うのに
すべての関数が必要かをデータシートを使って確認します。
タイミングチャートを見てみます。
タイミングチャートからわかることを見ていきます。
8ビットをリードする場合、IICバスマスターから
acknowledgeを与えますが、1か0かを指定する時
があります。
8ビットをライトする場合、IICバススレーブから
必ずacknowledgeの0を確認しています。
ArduinoのポートCのA5、A4は、ライブラリで処理する
として、A3、A2にSCL、SDAを割り当てて、必要な関数
を定義します。
5種類の関数を定義していきます。
start condtion
start condtionは、次のタイミングチャートに従い
SCLが'H'のときに、SDAを'H'から'L'に変化させます。
SCL、SDAをともに'H'にした後、SDAを'L'にします。
さらにSCLを'L'にして終了です。
void m_iic_start(void)
{
/* both H */
PORTC |= (3 << MSDA_BIT) ;
/* delay */
m_iic_wait();
/* 0 -> SDA */
PORTC &= ~(1 << MSDA_BIT) ;
/* delay */
m_iic_wait();
/* 0 -> SCL */
PORTC &= ~(1 << MSCL_BIT) ;
}
IICバス用ディレイ
SCL、SDAを変化させたときには、少しの間
待ち時間を入れた方が、動作が安定します。
ディレイを定義します。
#define IIC_CNT 32
void m_iic_wait(void)
{
byte i ;
/* wait */
for ( i = 0 ; i < IIC_CNT ; i++ ) ;
}
stop condtion
stop condtionは、次のタイミングチャートに従い
SCLが'H'のときに、SDAを'L'から'H'に変化させます。
SCL、SDAをともに'L'にした後、SDAを'H'にします。
さらにSCLを'H'にして終了です。
void m_iic_stop(void)
{
/* set level */
PORTC |= (1 << MSCL_BIT) ;
PORTC &= ~(1 << MSDA_BIT) ;
/* delay */
m_iic_wait();
/* 1 -> SDA */
PORTC |= (1 << MSDA_BIT) ;
/* delay */
m_iic_wait();
}
write 1byte with acknowledge
タイミングチャートを確認します。
SCL、SDAを利用して、8ビット分のデータを転送後
スレーブの出力する'L'を確認します。
byte m_iic_write(byte x)
{
byte i ;
byte tmp ;
/* load raw data */
tmp = x ;
/* transfer data with write code */
for ( i = 0 ; i < 8 ; i++ ) {
/* send bit datum */
PORTC &= ~(1 << MSDA_BIT) ;
if ( tmp & MASK80 ) { PORTC |= (1 << MSDA_BIT) ; }
/* 1 -> SCL */
m_iic_scl(ON);
/* shift */
tmp <<= 1 ;
/* 0 -> SCL */
m_iic_scl(OFF);
}
PORTC &= ~(1 << MSDA_BIT) ;
/* change inupt */
DDRC &= ~(1 << MSDA_BIT) ;
/* 1 -> SCL */
m_iic_scl(ON);
/* get acknowledge */
tmp = (PINC & (1 << MSDA_BIT)) >> 2 ;
/* 0 -> SCL */
m_iic_scl(OFF);
/* change output */
DDRC |= (1 << MSDA_BIT) ;
return tmp ;
}
SCLレベル指定と遅延
SCLは、H、Lを頻繁に変えるときがあり、さらに
パルス幅も必要なので、論理レベルを指定する
関数を定義しておきます。
void m_iic_scl(byte x)
{
/* impress */
if ( x ) { PORTC |= (1 << MSCL_BIT) ; }
else { PORTC &= ~(1 << MSCL_BIT) ; }
/* delay */
m_iic_wait();
}
read 1byte with acknowledge
SDAを入力に設定して、SCLでパルスを与え8ビット分のデータを
リードします。さらに、acknowledgeを与えます。
byte m_iic_read(byte x)
{
byte i;
byte result ;
/* change inupt */
PORTC &= ~(1 << MSDA_BIT) ;
DDRC &= ~(1 << MSDA_BIT) ;
/* default */
result = 0 ;
for ( i = 0 ; i < 8 ; i++ ) {
/* shift */
result <<= 1 ;
/* 1 -> SCL */
m_iic_scl(ON);
/* get bit datum */
if ( PINC & (1 << MSDA_BIT) ) { result |= ON ; }
/* 0 -> SCL */
m_iic_scl(OFF);
}
/* change output */
DDRC |= (1 << MSDA_BIT) ;
if ( x ) { PORTC |= (1 << MSDA_BIT); }
else { PORTC &= ~(1 << MSDA_BIT); }
/* 1 -> SCL */
m_iic_scl(ON);
/* 0 -> SCL */
m_iic_scl(OFF);
return result ;
}
初期状態設定
IICバスをまったく利用しない場合は、SCL、SDAは
ともに'H'になります。これをsetup()の中で設定
します。
PORTC = 0x0C ;
利用する関数を定義できたので、処理シーケンスを
考えます。
データシートでは、次のように処理シーケンスを規定。
シーケンスを3処理に分割し、3処理を詳細に見て
Arduinoスケッチで使うコードを決めていきます。
initialize
初期化あるいはフォーマットと呼ばれる処理で
センター感度や変換に必要な時間を決めます。
start condition m_iic_start();
send ID(0x2A+'0') m_iic_write((0x2a << 1));
send 0x00 m_iic_write(0x00);
send 0x84 m_iic_write(0x84);
start condition m_iic_start();
send ID(0x2A+'0') m_iic_write((0x2a << 1));
send 0x00 m_iic_write(0x00);
send 0x04 m_iic_write(0x04);
stop condition m_iic_stop();
wait
センサーがR、G、Bおよび輝度の情報を取得するには
時間がかかります。Arduinoのライブラリを使った時
に使った計算式で、WAITの時間を決めます。
/*
preset gain mode exposure time (each color ch)
00 = 87.5us => 0.9ms
01 = 1.4ms => 2.0ms
10 = 22.4ms => 23ms
11 = 179.2ms => 180ms
*/
i = scmd & 3 ;
if ( i == 3 ) { tmp = 180 * 4; }
if ( i == 2 ) { tmp = 23 * 4; }
if ( i < 2 ) { tmp = 2 * 4; }
変数scmdでは、センサーの感度を決める場合に
指定するので、それに沿った値を計算して代入
します。
read
センサーからの情報取得なので、規定されている
シーケンスを見て、動作を記述します。
start condition m_iic_start();
send ID(0x2A+'0') m_iic_write((0x2a << 1));
send 0x03 m_iic_write(0x03);
start condition m_iic_start();
send ID(0x2A+'1') m_iic_write((0x2a << 1) | ON);
read upper data(red) rx = m_iic_read(0); rx <<= 8 ;
read lower data(red) rx |= m_iic_read(0);
read upper data(green) gx = m_iic_read(0); gx <<= 8 ;
read lower data(green) gx |= m_iic_read(0);
read upper data(blue) bx = m_iic_read(0); bx <<= 8 ;
read lower data(blue) bx |= m_iic_read(0);
read upper data(intensity) ix = m_iic_read(0); ix <<= 8 ;
read lower data(intensity) ix |= m_iic_read(1);
stop condition m_iic_stop();
シーケンスがわかったので、ひとつの関数にまとめます。
void get_color()
{
byte i ;
byte j ;
word tmp ;
byte xx[8] ;
/*
preset gain mode exposure time (each color ch)
00 = 87.5us => 0.9ms
01 = 1.4ms => 2.0ms
10 = 22.4ms => 23ms
11 = 179.2ms => 180ms
*/
i = scmd & 3 ;
if ( i == 3 ) { tmp = 180 * 4; }
if ( i == 2 ) { tmp = 23 * 4; }
if ( i < 2 ) { tmp = 2 * 4; }
/* */
j = DEVICE_ID ;
j <<= 1 ;
j &= 0xFE ;
/* initialize */
m_iic_start();
m_iic_write(j);
m_iic_write(CONTROL_REG);
m_iic_write(0x83);
m_iic_start();
m_iic_write(j);
m_iic_write(CONTROL_REG);
/* set High or Low and exposure length */
m_iic_write(0x03);
m_iic_stop();
/* wait */
delay( tmp ) ;
/* read */
m_iic_start();
m_iic_write(j);
m_iic_write(0x03);
m_iic_start();
m_iic_write(j | ON);
/* get */
j = 0 ;
for ( i = 0 ; i < 8 ; i++ ) {
if ( i == 7 ) { j = 1 ; }
*(xx+i) = m_iic_read(j);
}
/* stop */
m_iic_stop();
/* store */
for ( i = 0 ; i < 4 ; i++ ) {
j = (i << 1);
tmp = *(xx+j) ;
tmp <<= 8 ;
tmp |= *(xx+j+1) ;
*(xrgbi+i) = tmp ;
}
}
端末で動作を確認してみました。
問題なくカラーセンサーの情報を取得できています。
ハードウエアとソフトウエアの道具が揃ったので
2つのカラーセンサーから情報取得するスケッチ
を定義しました。
#include <MsTimer2.h>
#include <EEPROM.h>
#include "Wire.h"
#define OFF 0
#define ON OFF+1
#define LED_BIT 5
#define DEVICE_ID 0x2A
#define CONTROL_REG 0x00
#define NPER 800
#define SCODE_ADR 0x100
#define SHOW_ADR 0x101
#define MASK80 0x80
#define IIC_CNT 32
#define MSCL_BIT 3
#define MSDA_BIT 2
/* event flag */
boolean eflag ;
boolean tflag ;
boolean uflag ;
/* state flag */
boolean gflag ; /* select only green information */
boolean mflag ; /* mask flag */
/* timing counter */
byte xcnt ;
/* serial interface */
byte cmd ;
byte sindex ;
char sbuf[4] ;
/* RGB and IR */
word xrgbi[8] ;
/* sensor command */
byte scmd ;
/* which */
byte state ;
/* LED flashing */
void send_led(byte x)
{
if ( x ) { PORTB |= (1 << LED_BIT) ; }
else { PORTB &= ~(1 << LED_BIT) ; }
}
/* generate trigger */
void update_trigger(void)
{
/* LED flashing */
send_led( xcnt & ON );
/* trigger */
xcnt++ ;
if ( xcnt & ON ) { tflag = ON ; }
}
/* putchar on serial interface */
void rs_putchar(char x)
{
Serial.write(x);
}
/* puts on serial interface */
void rs_puts(char *x)
{
while ( *x ) {
rs_putchar( *x ) ;
x++ ;
}
}
/* new line */
void crlf()
{
rs_putchar('\r');
rs_putchar('\n');
}
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("E execute") ; crlf();
rs_puts("I idle") ; crlf();
rs_puts("C one shot") ; crlf();
rs_puts("S set sensibility 1:high 0:low") ; crlf();
rs_puts("L set exposure time Length(0/1/2/3)") ; crlf();
rs_puts("G set only Green information 1:YES 0:NO") ; crlf();
rs_puts("M set mask 1:YES 0:NO") ; crlf();
rs_puts("s show staus") ; crlf();
}
void show_value(word x)
{
word tmp ;
char msg[6] ;
byte i ;
/* copy */
tmp = x;
/* delimiter */
*(msg+5) = '\0' ;
/* separate */
for ( i = 0 ; i < 5 ; i++ ) {
/* value -> digit number */
*(msg+4-i) = (tmp % 10)+ '0' ;
/* next */
tmp /= 10 ;
}
/* zero surppress */
if ( x < 10000 ) {
*(msg+0) = ' ' ;
if ( x < 1000 ) {
*(msg+1) = ' ' ;
if ( x < 100 ) {
*(msg+2) = ' ' ;
if ( x < 10 ) {
*(msg+3) = ' ' ;
}
}
}
}
/* show */
rs_puts( msg ) ;
rs_putchar(' ');
}
void get_color()
{
byte i ;
word tmp ;
/*
preset gain mode exposure time (each color ch)
00 = 87.5us => 0.9ms
01 = 1.4ms => 2.0ms
10 = 22.4ms => 23ms
11 = 179.2ms => 180ms
*/
i = scmd & 3 ;
if ( i == 3 ) { tmp = 180 * 4; }
if ( i == 2 ) { tmp = 23 * 4; }
if ( i < 2 ) { tmp = 2 * 4; }
Wire.beginTransmission(DEVICE_ID);
Wire.write(CONTROL_REG);
Wire.write(0x83); /* reset ADC and wakeup */
Wire.endTransmission(OFF);
Wire.beginTransmission(DEVICE_ID);
Wire.write(CONTROL_REG);
/* set High or Low and exposure length */
Wire.write( scmd );
Wire.endTransmission(ON);
/* total exposure time */
delay(tmp);
/* get each color value */
Wire.beginTransmission(DEVICE_ID);
Wire.write(0x03);
Wire.endTransmission(OFF);
Wire.requestFrom(DEVICE_ID,8,ON);
/* 8 x 2 x 4 */
for ( i = 0 ; i < 4 ; i++ ) {
/* upper value */
tmp = Wire.read();
/* shift */
tmp <<= 8;
/* add lower value */
tmp |= Wire.read();
/* store */
*(xrgbi+i) = tmp ;
}
}
void m_iic_wait(void)
{
byte i ;
/* wait */
for ( i = 0 ; i < IIC_CNT ; i++ ) ;
}
void m_iic_scl(byte x)
{
/* impress */
if ( x ) { PORTC |= (1 << MSCL_BIT) ; }
else { PORTC &= ~(1 << MSCL_BIT) ; }
/* delay */
m_iic_wait();
}
void m_iic_start(void)
{
/* both H */
PORTC |= (3 << MSDA_BIT) ;
/* delay */
m_iic_wait();
/* 0 -> SDA */
PORTC &= ~(1 << MSDA_BIT) ;
/* delay */
m_iic_wait();
/* 0 -> SCL */
PORTC &= ~(1 << MSCL_BIT) ;
}
void m_iic_stop(void)
{
/* set level */
PORTC |= (1 << MSCL_BIT) ;
PORTC &= ~(1 << MSDA_BIT) ;
/* delay */
m_iic_wait();
/* 1 -> SDA */
PORTC |= (1 << MSDA_BIT) ;
/* delay */
m_iic_wait();
}
byte m_iic_write(byte x)
{
byte i ;
byte tmp ;
/* load raw data */
tmp = x ;
/* transfer data with write code */
for ( i = 0 ; i < 8 ; i++ ) {
/* send bit datum */
PORTC &= ~(1 << MSDA_BIT) ;
if ( tmp & MASK80 ) { PORTC |= (1 << MSDA_BIT) ; }
/* 1 -> SCL */
m_iic_scl(ON);
/* shift */
tmp <<= 1 ;
/* 0 -> SCL */
m_iic_scl(OFF);
}
PORTC &= ~(1 << MSDA_BIT) ;
/* change inupt */
DDRC &= ~(1 << MSDA_BIT) ;
/* 1 -> SCL */
m_iic_scl(ON);
/* get acknowledge */
tmp = (PINC & (1 << MSDA_BIT)) >> 2 ;
/* 0 -> SCL */
m_iic_scl(OFF);
/* change output */
DDRC |= (1 << MSDA_BIT) ;
return tmp ;
}
byte m_iic_read(byte x)
{
byte i;
byte result ;
/* change inupt */
PORTC &= ~(1 << MSDA_BIT) ;
DDRC &= ~(1 << MSDA_BIT) ;
/* default */
result = 0 ;
for ( i = 0 ; i < 8 ; i++ ) {
/* shift */
result <<= 1 ;
/* 1 -> SCL */
m_iic_scl(ON);
/* get bit datum */
if ( PINC & (1 << MSDA_BIT) ) { result |= ON ; }
/* 0 -> SCL */
m_iic_scl(OFF);
}
/* change output */
DDRC |= (1 << MSDA_BIT) ;
if ( x ) { PORTC |= (1 << MSDA_BIT); }
else { PORTC &= ~(1 << MSDA_BIT); }
/* 1 -> SCL */
m_iic_scl(ON);
/* 0 -> SCL */
m_iic_scl(OFF);
return result ;
}
void get_color2()
{
byte i ;
byte j ;
word tmp ;
byte xx[8] ;
/*
preset gain mode exposure time (each color ch)
00 = 87.5us => 0.9ms
01 = 1.4ms => 2.0ms
10 = 22.4ms => 23ms
11 = 179.2ms => 180ms
*/
i = scmd & 3 ;
if ( i == 3 ) { tmp = 180 * 4; }
if ( i == 2 ) { tmp = 23 * 4; }
if ( i < 2 ) { tmp = 2 * 4; }
/* */
j = DEVICE_ID ;
j <<= 1 ;
j &= 0xFE ;
/* initialize */
m_iic_start();
m_iic_write(j);
m_iic_write(CONTROL_REG);
m_iic_write(0x83);
m_iic_start();
m_iic_write(j);
m_iic_write(CONTROL_REG);
/* set High or Low and exposure length */
m_iic_write(0x03);
m_iic_stop();
/* wait */
delay( tmp ) ;
/* read */
m_iic_start();
m_iic_write(j);
m_iic_write(0x03);
m_iic_start();
m_iic_write(j | ON);
/* get */
j = 0 ;
for ( i = 0 ; i < 8 ; i++ ) {
if ( i == 7 ) { j = 1 ; }
*(xx+i) = m_iic_read(j);
}
/* stop */
m_iic_stop();
/* store */
for ( i = 0 ; i < 4 ; i++ ) {
j = (i << 1);
tmp = *(xx+j) ;
tmp <<= 8 ;
tmp |= *(xx+j+1) ;
*(xrgbi+i+4) = tmp ;
}
}
void show_yn()
{
char msg[2];
/* delimiter */
*(msg+1) = '\0' ;
/* sensibility */
{
*(msg+0) = 'L' ;
if ( scmd & 8 ) { *(msg+0) = 'H' ; }
rs_puts( msg );
}
/* exposure length */
{
rs_putchar( '0'+(scmd & 3) );
}
/* Green */
{
*(msg+0) = 'N' ;
if ( gflag == ON ) { *(msg+0) = 'Y' ; }
rs_puts( msg );
}
/* Mask */
{
*(msg+0) = 'N' ;
if ( mflag == ON ) { *(msg+0) = 'Y' ; }
rs_puts( msg );
}
/* new line */
crlf();
}
void store_param(byte which,byte x)
{
word madr ;
/* sensibility or exposure length */
if ( which < 2 ) { madr = SCODE_ADR ; }
/* Green information */
if ( which == 2 ) { madr = SHOW_ADR ; }
/* store */
EEPROM.write(madr,x);
}
void show_color(boolean x)
{
/* only Green information */
if ( x ) {
rs_puts("AG :") ; show_value( *(xrgbi+1) );
rs_puts("BG :") ; show_value( *(xrgbi+5) );
}
else
/* all color informations */
{
rs_puts("AR :") ; show_value( *(xrgbi+0) );
rs_puts("AG :") ; show_value( *(xrgbi+1) );
rs_puts("AB :") ; show_value( *(xrgbi+2) );
rs_puts("AIR:") ; show_value( *(xrgbi+3) );
rs_puts("BR :") ; show_value( *(xrgbi+4) );
rs_puts("BG :") ; show_value( *(xrgbi+5) );
rs_puts("BB :") ; show_value( *(xrgbi+6) );
rs_puts("BIR:") ; show_value( *(xrgbi+7) );
}
crlf();
}
void setup()
{
/* initialize serial port */
Serial.begin(9600);
sindex = 0 ;
/* set initial state */
PORTB = 0x00 ;
PORTC = 0x0C ;
PORTD = 0x01 ;
/* direction */
DDRB = 0xff ;
DDRC = 0xff ;
DDRD = 0xfe ;
/* clear flags */
tflag = OFF ;
eflag = OFF ;
uflag = OFF ;
gflag = OFF ;
/* resume previous state */
xcnt = EEPROM.read(SCODE_ADR);
if ( xcnt == 0xff ) {
scmd = 11 ;
EEPROM.write(SCODE_ADR,scmd);
} else {
scmd = xcnt ;
}
xcnt = EEPROM.read(SHOW_ADR);
if ( xcnt != OFF ) { gflag = ON ; }
/* initialize variables */
for ( xcnt = 0 ; xcnt < 4 ; xcnt++ ) {
*(xrgbi+xcnt) = 0 ;
}
xcnt = 0 ;
state = 0 ;
/* trigger period */
MsTimer2::set(NPER,update_trigger);
/* enable */
MsTimer2::start();
/* enable I2C bus interface */
Wire.begin();
}
void loop()
{
/* serial handling */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* new line */
crlf();
/* get command */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help() ; }
/* enable */
if ( cmd == 'E' ) { eflag = ON ; }
/* disable */
if ( cmd == 'I' ) { eflag = OFF ; }
/* one shot */
if ( cmd == 'C' ) {
/* get color values */
get_color();
get_color2();
/* show */
show_color(gflag);
}
/* write sensibility state */
if ( cmd == 'S' ) {
/* set default (selct LOW) */
scmd &= 0xf7 ;
/* set flag (HIGH or LOW) */
if ( *(sbuf+1) == '1' ) { scmd |= (1 << 3) ; }
/* store EEPROM */
store_param(0,scmd);
}
/* write exposure length */
if ( cmd == 'L' ) {
/* clear */
scmd &= 0xfc ;
/* generate code */
scmd |= ((*(sbuf+1) - '0') & 3);
/* store EEPROM */
store_param(1,scmd);
}
/* write only Green information */
if ( cmd == 'G' ) {
/* default */
gflag = OFF ;
/* judge */
if ( *(sbuf+1) == '1' ) { gflag = ON ; }
/* store */
store_param(2,gflag);
}
/* write mask */
if ( cmd == 'M' ) {
/* default */
mflag = OFF ;
/* judge */
if ( *(sbuf+1) == '1' ) { mflag = ON ; }
}
/* show status */
if ( cmd == 's' ) { show_yn(); }
}
/* timer handling */
if ( tflag == ON ) {
/* clear flag */
tflag = OFF ;
/* get color values */
if ( state ) { get_color2(); }
else { get_color(); }
/* update state */
state++ ;
state &= ON ;
/* show */
if ( eflag ) { show_color(gflag) ; }
}
}
/* receive interrupt */
void serialEvent()
{
char ch;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
カラーセンサーのどちらを利用するのかで関数を分けて
あります。get_color()がArduinoの内蔵ハードウエアを
利用します。get_color2()は、GPIOを利用したIICバス
でセンサー情報を取得します。
センサーが2個になったので、情報量は2倍となります。
word指定の配列のサイズを4から8とします。
get_color2()は、センサー情報を配列に格納するとき
オフセットの4をつけて対応しました。
タイマー割込みで、どちらのセンサーから情報を取得
するのかは、ステートマシンを利用して記述してます。
変数stateを用意し、0か1のいずれの値しか持たない
ように、からくりを用意しました。
/* get color values */
if ( state ) { get_color2(); }
else { get_color(); }
/* update state */
state++ ;
state &= ON ;
このスケッチで、2つのセンサーの情報を取得すると
次のようになります。
緑だけを抜き出すと、次のような端末表示です。
Arduino、カラーセンサー、電圧変換モジュールの接続は、以下。
A5、A4は、Arduinoの内蔵IICバス専用モジュールに接続される
ので、プルアップする電源電圧が3.3Vでも、問題ありません。
GPIOとして使う、A3、A2は、5Vインタフェースで扱うように
しておきます。カラーセンサーには、3.3Vを与えます。
電圧変換モジュール上にプルアップ抵抗があるため、外付けの
抵抗は不要。
エンハンスメントタイプのMOSFETを利用したインタフェースを
半田付けして、テストしてみました。
回路は、以下。
この回路では、Wireライブラリを使うと動作しなかったので
GPIOを使ったスケッチにしました。
2つのチャネルを(A5,A4)=(SCL,SDA)=(D19,D18)、(A3,A2)=(SCL,SDA)=(D17,D16)
に割り当てました。
#include <MsTimer2.h>
#include <EEPROM.h>
#define OFF 0
#define ON OFF+1
#define MASCL_BIT 5
#define MASDA_BIT 4
#define MBSCL_BIT 3
#define MBSDA_BIT 2
#define MASK80 0x80
#define IIC_CNT 32
#define LED_BIT 5
#define DEVICE_ID 0x2A
#define CONTROL_REG 0x00
#define NPER 800
#define SCODE_ADR 0x100
#define SHOW_ADR 0x101
/* event flag */
boolean eflag ;
boolean tflag ;
boolean uflag ;
/* state flag */
boolean gflag ; /* select only green information */
boolean mflag ; /* mask flag */
/* timing counter */
byte xcnt ;
/* serial interface */
byte cmd ;
byte sindex ;
char sbuf[4] ;
/* RGB and IR */
word xrgbi[8] ;
/* sensor command */
byte scmd ;
/* which sensor */
byte state ;
/* LED flashing */
void send_led(byte x)
{
if ( x ) { PORTB |= (1 << LED_BIT) ; }
else { PORTB &= ~(1 << LED_BIT) ; }
}
/* generate trigger */
void update_trigger(void)
{
/* LED flashing */
send_led( xcnt & ON );
/* trigger */
xcnt++ ;
if ( xcnt & ON ) { tflag = ON ; }
}
/* putchar on serial interface */
void rs_putchar(char x)
{
Serial.write(x);
}
/* puts on serial interface */
void rs_puts(char *x)
{
while ( *x ) {
rs_putchar( *x );
x++ ;
}
}
/* new line */
void crlf()
{
rs_putchar('\r');
rs_putchar('\n');
}
void show_help()
{
rs_puts("? help") ; crlf();
rs_puts("E execute") ; crlf();
rs_puts("I idle") ; crlf();
rs_puts("C one shot") ; crlf();
rs_puts("S set sensibility 1:high 0:low") ; crlf();
rs_puts("L set exposure time Length(0/1/2/3)") ; crlf();
rs_puts("G set only Green information 1:YES 0:NO") ; crlf();
rs_puts("M set mask 1:YES 0:NO") ; crlf();
rs_puts("s show staus") ; crlf();
}
void show_value(word x)
{
word tmp ;
char msg[6] ;
byte i ;
/* copy */
tmp = x;
/* delimiter */
*(msg+5) = '\0' ;
/* separate */
for ( i = 0 ; i < 5 ; i++ ) {
/* value -> digit number */
*(msg+4-i) = (tmp % 10)+ '0' ;
/* next */
tmp /= 10 ;
}
/* zero surppress */
if ( x < 10000 ) {
*(msg+0) = ' ' ;
if ( x < 1000 ) {
*(msg+1) = ' ' ;
if ( x < 100 ) {
*(msg+2) = ' ' ;
if ( x < 10 ) {
*(msg+3) = ' ' ;
}
}
}
}
/* show */
rs_puts( msg ) ;
rs_putchar(' ');
}
void m_iic_wait(void)
{
byte i ;
/* wait */
for ( i = 0 ; i < IIC_CNT ; i++ ) ;
}
void m_iic_scl(byte x,boolean wx)
{
byte xx ;
/* channel A */
xx = MASCL_BIT ;
/* channel B */
if ( wx ) { xx = MBSCL_BIT ; }
/* impress */
if ( x ) { PORTC |= (1 << xx) ; }
else { PORTC &= ~(1 << xx) ; }
/* delay */
m_iic_wait();
}
void m_iic_start(boolean wx)
{
byte xx ;
byte yy ;
/* channel A */
xx = MASDA_BIT ;
/* channel B */
if ( wx ) { xx = MBSDA_BIT ; }
yy = xx+1 ;
/* both H */
PORTC |= (3 << xx) ;
/* delay */
m_iic_wait();
/* 0 -> SDA */
PORTC &= ~(1 << xx) ;
/* delay */
m_iic_wait();
/* 0 -> SCL */
PORTC &= ~(1 << yy) ;
}
void m_iic_stop(boolean wx)
{
byte xx ;
byte yy ;
/* channel A */
xx = MASDA_BIT ;
/* channel B */
if ( wx ) { xx = MBSDA_BIT ; }
yy = xx+1 ;
/* set level */
PORTC |= (1 << yy) ;
PORTC &= ~(1 << xx) ;
/* delay */
m_iic_wait();
/* 1 -> SDA */
PORTC |= (1 << xx) ;
/* delay */
m_iic_wait();
}
byte m_iic_write(byte x,boolean wx)
{
byte i ;
byte tmp ;
byte xx ;
/* send bit datum */
xx = MASDA_BIT ;
if ( wx ) { xx = MBSDA_BIT ; }
/* load raw data */
tmp = x ;
/* transfer data with write code */
for ( i = 0 ; i < 8 ; i++ ) {
/* impress datum */
PORTC &= ~(1 << xx) ;
if ( tmp & MASK80 ) { PORTC |= (1 << xx) ; }
/* 1 -> SCL */
m_iic_scl(ON,wx);
/* shift */
tmp <<= 1 ;
/* 0 -> SCL */
m_iic_scl(OFF,wx);
}
PORTC &= ~(1 << xx) ;
/* change inupt */
DDRC &= ~(1 << xx) ;
/* 1 -> SCL */
m_iic_scl(ON,wx);
/* get acknowledge */
tmp = (PINC & (1 << xx)) >> xx ;
/* 0 -> SCL */
m_iic_scl(OFF,wx);
/* change output */
DDRC |= (1 << xx) ;
return tmp ;
}
byte m_iic_read(byte x,boolean wx)
{
byte i;
byte result ;
byte xx ;
/* channel A */
xx = MASDA_BIT ;
/* channel B */
if ( wx ) { xx = MBSDA_BIT ; }
/* change inupt */
PORTC &= ~(1 << xx) ;
DDRC &= ~(1 << xx) ;
/* default */
result = 0 ;
for ( i = 0 ; i < 8 ; i++ ) {
/* shift */
result <<= 1 ;
/* 1 -> SCL */
m_iic_scl(ON,wx);
/* 0 -> SCL */
m_iic_scl(OFF,wx);
/* get bit datum */
if ( PINC & (1 << xx) ) { result |= ON ; }
}
/* change output */
DDRC |= (1 << xx) ;
if ( x ) { PORTC |= (1 << xx); }
else { PORTC &= ~(1 << xx); }
/* 1 -> SCL */
m_iic_scl(ON,wx);
/* 0 -> SCL */
m_iic_scl(OFF,wx);
return result ;
}
void get_color(boolean wx)
{
byte i ;
byte j ;
word tmp ;
byte xx[8] ;
/*
preset gain mode exposure time (each color ch)
00 = 87.5us => 0.9ms
01 = 1.4ms => 2.0ms
10 = 22.4ms => 23ms
11 = 179.2ms => 180ms
*/
i = scmd & 3 ;
if ( i == 3 ) { tmp = 180 * 4; }
if ( i == 2 ) { tmp = 23 * 4; }
if ( i < 2 ) { tmp = 2 * 4; }
/* */
j = DEVICE_ID ;
j <<= 1 ;
j &= 0xFE ;
/* initialize */
m_iic_start(wx);
m_iic_write(j,wx);
m_iic_write(CONTROL_REG,wx);
m_iic_write(0x83,wx);
m_iic_start(wx);
m_iic_write(j,wx);
m_iic_write(CONTROL_REG,wx);
/* set High or Low and exposure length */
m_iic_write(0x03,wx);
m_iic_stop(wx);
/* wait */
delay( tmp ) ;
/* read */
m_iic_start(wx);
m_iic_write(j,wx);
m_iic_write(0x03,wx);
m_iic_start(wx);
m_iic_write(j | ON,wx);
/* get */
j = 0 ;
for ( i = 0 ; i < 8 ; i++ ) {
if ( i == 7 ) { j = 1 ; }
*(xx+i) = m_iic_read(j,wx);
}
/* stop */
m_iic_stop(wx);
/* store */
for ( i = 0 ; i < 4 ; i++ ) {
j = (i << 1);
tmp = *(xx+j) ;
tmp <<= 8 ;
tmp |= *(xx+j+1) ;
*(xrgbi+i+4*wx) = tmp ;
}
}
void show_yn()
{
char msg[2];
/* delimiter */
*(msg+1) = '\0' ;
/* sensibility */
{
*(msg+0) = 'L' ;
if ( scmd & 8 ) { *(msg+0) = 'H' ; }
rs_puts( msg );
}
/* exposure length */
{
rs_putchar( '0'+(scmd & 3) );
}
/* Green */
{
*(msg+0) = 'N' ;
if ( gflag == ON ) { *(msg+0) = 'Y' ; }
rs_puts( msg );
}
/* Mask */
{
*(msg+0) = 'N' ;
if ( mflag == ON ) { *(msg+0) = 'Y' ; }
rs_puts( msg );
}
/* new line */
crlf();
}
void store_param(byte which,byte x)
{
word madr ;
/* sensibility or exposure length */
if ( which < 2 ) { madr = SCODE_ADR ; }
/* Green information */
if ( which == 2 ) { madr = SHOW_ADR ; }
/* store */
EEPROM.write(madr,x);
}
void show_color(boolean x)
{
/* only Green information */
if ( x ) {
rs_puts("AG :") ; show_value( *(xrgbi+1) );
rs_puts("BG :") ; show_value( *(xrgbi+5) );
}
else
/* all color informations */
{
rs_puts("AR :") ; show_value( *(xrgbi+0) );
rs_puts("AG :") ; show_value( *(xrgbi+1) );
rs_puts("AB :") ; show_value( *(xrgbi+2) );
rs_puts("AIR:") ; show_value( *(xrgbi+3) );
rs_puts("BR :") ; show_value( *(xrgbi+4) );
rs_puts("BG :") ; show_value( *(xrgbi+5) );
rs_puts("BB :") ; show_value( *(xrgbi+6) );
rs_puts("BIR:") ; show_value( *(xrgbi+7) );
}
crlf();
}
void setup()
{
/* initialize serial port */
Serial.begin(9600);
sindex = 0 ;
/* set initial state */
PORTB = 0x00 ;
PORTC = 0x0C ;
PORTD = 0x01 ;
/* direction */
DDRB = 0xff ;
DDRC = 0xff ;
DDRD = 0xfe ;
/* clear flags */
tflag = OFF ;
eflag = OFF ;
uflag = OFF ;
gflag = OFF ;
/* resume previous state */
xcnt = EEPROM.read(SCODE_ADR);
if ( xcnt == 0xff ) {
scmd = 11 ;
EEPROM.write(SCODE_ADR,scmd);
} else {
scmd = xcnt ;
}
xcnt = EEPROM.read(SHOW_ADR);
if ( xcnt != OFF ) { gflag = ON ; }
/* initialize variables */
xcnt = 0 ;
for ( xcnt = 0 ; xcnt < 8 ; xcnt++ ) { *(xrgbi+xcnt) = 0 ; }
state = 0 ;
/* trigger period */
MsTimer2::set(NPER,update_trigger);
/* enable */
MsTimer2::start();
}
void loop()
{
/* serial handling */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* new line */
crlf();
/* get command */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help() ; }
/* enable */
if ( cmd == 'E' ) { eflag = ON ; }
/* disable */
if ( cmd == 'I' ) { eflag = OFF ; }
/* one shot */
if ( cmd == 'C' ) {
/* get color values */
get_color(OFF);
get_color(ON);
/* show */
show_color(gflag);
}
/* write sensibility state */
if ( cmd == 'S' ) {
/* set default (selct LOW) */
scmd &= 0xf7 ;
/* set flag (HIGH or LOW) */
if ( *(sbuf+1) == '1' ) { scmd |= (1 << 3) ; }
/* store EEPROM */
store_param(0,scmd);
}
/* write exposure length */
if ( cmd == 'L' ) {
/* clear */
scmd &= 0xfc ;
/* generate code */
scmd |= ((*(sbuf+1) - '0') & 3);
/* store EEPROM */
store_param(1,scmd);
}
/* write only Green information */
if ( cmd == 'G' ) {
/* default */
gflag = OFF ;
/* judge */
if ( *(sbuf+1) == '1' ) { gflag = ON ; }
/* store */
store_param(2,gflag);
}
/* write mask */
if ( cmd == 'M' ) {
/* default */
mflag = OFF ;
/* judge */
if ( *(sbuf+1) == '1' ) { mflag = ON ; }
}
/* show status */
if ( cmd == 's' ) { show_yn(); }
}
/* timer handling */
if ( tflag == ON ) {
/* clear flag */
tflag = OFF ;
/* get color values */
get_color(state);
state++ ;
state &= ON ;
/* show */
if ( eflag == ON ) { show_color(gflag) ; }
}
}
/* receive interrupt */
void serialEvent()
{
char ch;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
Arduinoと変換基板の接続は、次のようになります。
TeraTermを利用した、Arduinoスケッチの動作確認を
すると、以下の2チャネル分の情報を表示します。
Processingスケッチは、次頁にて説明。
目次
前
次