目次
前
次
スタブ作成
Processingで通信する場合、受信割込みを利用します。
通信相手が必要なので、Arduinoを利用してスタブを
作成して対応しました。
カラーセンサーからデータを定期的に取得して
それをバーで表示するので、Arduinoを利用して
Processingのスケッチをテストするための環境を
用意したと言えばよいでしょう。
スタブを利用する場合、スタブを動かすための
プログラムが必要です。このプログラムコード
を、テストドライバと呼びます。
テストドライバをProcessingスケッチで書くのは
面倒なので、TeraTermをテストドライバもどきで
利用します。
TeraTermの内容は、以下。
定期的に2チャネル分のデータを生成して送信する
スケッチを作成すればよいでしょう。
データは乱数で生成して、それなりのデータになる
ようにします。Arduinoの乱数の仕様は以下。
random(min, max)
min: 生成する乱数の下限。省略可能
max: 生成する乱数の上限
2チャネル分のデータは、8個になるのでひとつの乱数を
生成し、剰余系で8データにしました。
long rx = random(50,1200) ;
*(cha+0) = rx % 800 ;
*(cha+1) = rx % 900 ;
*(cha+2) = rx % 1000 ;
*(cha+3) = rx % 1100 ;
*(chb+0) = rx % 400 ;
*(chb+1) = rx % 500 ;
*(chb+2) = rx % 600 ;
*(chb+3) = rx % 700 ;
タイマー割込みで乱数を生成し、擬似のセンサー
データを生成します。
どこに入れるかというとは関数get_sensorの中です。
スケッチは、以下。
#include <MsTimer2.h>
#define OFF 0
#define ON OFF+1
#define MASK80 0x80
#define LED_BIT 5
#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 get_color(boolean wx)
{
long rx ;
/* generate random number */
rx = random(50,1200) ;
/* which */
if ( wx ) {
/* channel B */
*(xrgbi+4) = rx % 400 ;
*(xrgbi+5) = rx % 500 ;
*(xrgbi+6) = rx % 600 ;
*(xrgbi+7) = rx % 700 ;
} else {
/* channel A */
*(xrgbi+0) = rx % 800 ;
*(xrgbi+1) = rx % 900 ;
*(xrgbi+2) = rx % 1000 ;
*(xrgbi+3) = rx % 1100 ;
}
}
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) );
}
/* Mask */
{
*(msg+0) = 'N' ;
if ( mflag == ON ) { *(msg+0) = 'Y' ; }
rs_puts( msg );
}
/* Green */
{
*(msg+0) = 'N' ;
if ( gflag == 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 ; }
}
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) );
crlf();
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 ;
/* 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 ;
}
}
}
カラーセンサーから情報を取得する部分だけを
スタブにしてあるので、Processingスケッチの
テスト、デバッグが終わった段階で、スタブを
実処理に置換します。
スケッチでは、関数get_colorだけがスタブですが
数値の文字列変換、1文字送信、文字列送信等の
付随する処理を同時にテストしています。
1文字送信を作成したなら、そのラッパー関数である
文字列送信の関数を定義。
建築物の礎石を並べていくように、最も下位レベルのI/Oを
作成します。そのプリミティブ関数をラッパー関数で包む
作業を続けていきます。
ラッパー関数は、スタブを動かすためのテストドライバと
呼んでもよいでしょう。
目次
前
次