目次
前
次
カラーセンサー情報取得4
ArduinoにIICバスを2つ用意し、2個のカラーセンサーから
情報取得するためのProcessingスケッチを考えます。
1個のカラーセンサーの場合、次のように画面を構成していました。
カラーセンサーは2個にするので、左右に並べて表示します。
カラーセンサーには、次のパラメータ指定が可能です。
感度、マスク指定は論理値で設定し、露光時間は
1から4の整数値にします。
これらを2個のセンサーを一緒に指定できるように
します。
3項目に相当するボタンを用意し、クリックすると
キャプションの右に、現在の指定状態を表示します。
ボタンは、クリッカブルマップで領域を指定すれば
どの値になっているかを判定できます。
クリッカブルマップによる領域指定を使うことに
すると、各ボタンの絵を作成するだけになります。
スケッチは、以下。
import processing.serial.*;
Serial cport;
PImage imgGet ;
PImage imgExecute ;
PImage imgIdle ;
PImage imgExit ;
PImage imgSense ;
PImage imgXtime ;
PImage imgXmask ;
int FRATE = 25 ;
String stmp ;
boolean scflag ;
int loop ;
int rxa ;
int gxa ;
int bxa ;
int ixa ;
int rxb ;
int gxb ;
int bxb ;
int ixb ;
String xsense ;
String xtime ;
String xmask ;
boolean eflag ;
boolean oflag ;
PrintWriter outFN ;
boolean isRangeOk(int x,int bx,int ex)
{
boolean result ;
/* default */
result = false ;
/* judge */
if ( bx <= x && x <= ex ) { result = true ; }
return result ;
}
boolean isdigitx(char x)
{
boolean result ;
/* default */
result = false ;
/* judge */
if ( '0' <= x && x <= '9' ) { result = true ; }
return result ;
}
boolean isNcode(char x)
{
boolean result ;
/* default */
result = false ;
/* judge */
if ( x == 'A' ) { result = true ; }
if ( x == 'B' ) { result = true ; }
if ( x == 'R' ) { result = true ; }
if ( x == 'G' ) { result = true ; }
if ( x == 'I' ) { result = true ; }
if ( x == ':' ) { result = true ; }
if ( x == ' ' ) { result = true ; }
return result ;
}
boolean isNcode(char x)
{
boolean result ;
/* default */
result = false ;
/* judge */
if ( isdigitx(x) && !isacode(x) ) {
result = true ;
}
return result ;
}
void show_values(int x,int y,int z,int u,int wx)
{
int sx = 20 ;
int sy = 80 ;
int lx ;
int ly ;
String msg_r ;
String msg_g ;
String msg_b ;
String msg_ix ;
int offset = 30 ;
/* generate text */
msg_r = "AR :";
msg_g = "AG :";
msg_b = "AB :";
msg_ix = "AIR:";
if ( wx == 1 ) {
msg_r = "BR :";
msg_g = "BG :";
msg_b = "BB :";
msg_ix = "BIR:";
}
msg_r = msg_r + nf(x,5) ;
msg_g = msg_g + nf(y,5) ;
msg_b = msg_b + nf(z,5) ;
msg_ix = msg_ix + nf(u,5) ;
/* set location */
lx = sx ;
ly = sy ;
if ( wx == 1 ) { lx += 190 ; }
/* show */
textSize(15) ;
text(msg_r ,lx,ly+offset*0);
text(msg_g ,lx,ly+offset*1);
text(msg_b ,lx,ly+offset*2);
text(msg_ix,lx,ly+offset*3);
}
void show_bars(int x,int y,int z,int u,int wx)
{
int rgbi ;
int rate_r ;
int rate_g ;
int rate_b ;
int rate_i ;
int sx = 100 ;
int sy = 70 ;
int offset = 27 ;
int lx ;
int ly ;
/* calculate ratio */
rgbi = max(max(x,y),max(z,u)) ;
rate_r = (int)( (x * 100.0) / rgbi ) ;
rate_g = (int)( (y * 100.0) / rgbi ) ;
rate_b = (int)( (z * 100.0) / rgbi ) ;
rate_i = (int)( (u * 100.0) / rgbi ) ;
/* calcualte location */
lx = sx ;
ly = sy ;
if ( wx == 1 ) { lx = 290 ; }
/* show bar */
fill(255, 0, 0); rect(lx,ly+offset*0,rate_r,20);
fill( 0,255, 0); rect(lx,ly+offset*1,rate_g,20);
fill( 0, 0,255); rect(lx,ly+offset*2,rate_b,20);
fill(255,255,255); rect(lx,ly+offset*3,rate_i,20);
}
void show_btn()
{
image(imgGet , 20,300);
image(imgExecute, 80,300);
image(imgIdle ,140,300);
image(imgExit ,220,300);
image(imgSense ,300,200);
image(imgXtime ,300,240);
image(imgXmask ,300,280);
}
void show_caption_p()
{
/* white */
fill(255,255,255);
/* size */
textSize(12);
/* caption */
text("Sensivility",300,196);
text("Exposure",300,236);
text("Mask",300,276);
}
void clear_area()
{
/* black */
fill(0,0,0);
/* clear status area */
rect(390,200,100,100);
}
void show_caption()
{
clear_area();
/* white */
fill(255,255,255);
/* size */
textSize(12);
/* status */
text(xsense,400,214);
text(xtime ,400,254);
text(xmask ,400,294);
}
void send_sense_cmd(boolean x)
{
cport.write('S');
if ( x ) { cport.write('1'); }
else { cport.write('0'); }
cport.write('\r');
}
void send_exposure_cmd(int x)
{
if ( 0 < x && x < 5 ) {
cport.write('L');
if ( x == 1 ) { cport.write('1'); }
if ( x == 2 ) { cport.write('2'); }
if ( x == 3 ) { cport.write('3'); }
if ( x == 4 ) { cport.write('4'); }
cport.write('\r');
}
}
void send_mask_cmd(boolean x)
{
cport.write('M');
if ( x ) { cport.write('1'); }
else { cport.write('0'); }
cport.write('\r');
}
void store_status()
{
String stmp ;
/* clear */
stmp = "" ;
/* sensivility */
if ( xsense == "HIGH" ) { stmp += "1" ; }
else { stmp += "0" ; }
/* exposure time */
if ( xtime == "1" ) { stmp += "1" ; }
if ( xtime == "2" ) { stmp += "2" ; }
if ( xtime == "3" ) { stmp += "3" ; }
if ( xtime == "4" ) { stmp += "4" ; }
/* mask */
if ( xmask == "YES" ) { stmp += "1" ; }
else { stmp += "0" ; }
/* file handling */
outFN = createWriter("istatus.txt");
outFN.println(stmp);
outFN.close();
}
void setup()
{
size(440,340);
/* title caption */
surface.setTitle("Test 05");
/* select framerate */
frameRate(FRATE);
/* select back ground color with BLACK */
background(0,0,0);
//show serial port list (0:COM1 , 1:COM2 ... )
//println(Serial.list());
String arduinoPort = Serial.list()[4];
/* initialize serial port */
cport = new Serial(this,arduinoPort,9600);
cport.clear();
cport.bufferUntil('\n');
scflag = false ;
/* get image */
imgGet = loadImage("get.png");
imgExecute = loadImage("execute.png");
imgIdle = loadImage("idle.png");
imgExit = loadImage("exit.png");
imgSense = loadImage("sense.png");
imgXtime = loadImage("xtime.png");
imgXmask = loadImage("xmask.png");
/* set caption */
String[] xline = loadStrings("istatus.txt");
char[] ss = xline[0].toCharArray();
/* set status */
xsense = "LOW" ;
if ( ss[0] == '1' ) { xsense = "HIGH" ; }
xtime = "1" ;
if ( ss[1] == '2' ) { xtime = "2" ; }
if ( ss[1] == '3' ) { xtime = "3" ; }
if ( ss[1] == '4' ) { xtime = "4" ; }
xmask = "NO" ;
if ( ss[2] == '1' ) { xmask = "YES" ; }
/* first one shot */
oflag = true ;
}
void draw()
{
/* first one shot */
if ( oflag ) {
oflag = false ;
/* sensivility */
if ( xsense == "HIGH" ) { send_sense_cmd(true); }
else { send_sense_cmd(false); }
/* exposure time */
send_exposure_cmd(int(xtime));
/* mask */
if ( xmask == "YES" ) { send_mask_cmd(true); }
else { send_mask_cmd(false); }
}
/* button */
show_btn();
/* caption */
show_caption_p();
show_caption();
/* serial receive */
if ( scflag == true ) {
scflag = false ;
/* check */
stmp = trim(cport.readStringUntil('\n'));
/* separate */
char[] ss = stmp.toCharArray();
loop = stmp.indexOf("BR :");
/* judge */
eflag = true ;
if ( loop < 40 ) { eflag = false ; }
/* show */
if ( eflag ) {
/* clear area */
background(0,0,0);
/* show */
textSize(20);
text(stmp.substring(0,loop-1),20,40);
text(stmp.substring(loop,stmp.length()),20,60);
/* clear */
loop = 0 ;
rxa = gxa = bxa = ixa = 0 ;
rxb = gxb = bxb = ixb = 0 ;
for (char ch : ss) {
/* check entry */
if ( ch == ':' ) { loop++ ; }
/* calculate */
if ( isNcode(ch) == true ) {
if ( loop == 1 ) { rxa = rxa * 10 + (ch-'0') ; }
if ( loop == 2 ) { gxa = gxa * 10 + (ch-'0') ; }
if ( loop == 3 ) { bxa = bxa * 10 + (ch-'0') ; }
if ( loop == 4 ) { ixa = ixa * 10 + (ch-'0') ; }
if ( loop == 5 ) { rxb = rxb * 10 + (ch-'0') ; }
if ( loop == 6 ) { gxb = gxb * 10 + (ch-'0') ; }
if ( loop == 7 ) { bxb = bxb * 10 + (ch-'0') ; }
if ( loop == 8 ) { ixb = ixb * 10 + (ch-'0') ; }
}
}
print('\n');
/* clear information */
fill(0,0,0);
rect(10,70,300,200);
fill(255,255,255);
/* show values */
show_values(rxa,gxa,bxa,ixa,0);
show_values(rxb,gxb,bxb,ixb,1);
/* draw bars */
int rate_rgbi ;
rate_rgbi = max(max(rxa,gxa),max(bxa,ixa));
if ( rate_rgbi > 0 ) { show_bars(rxa,gxa,bxa,ixa,0); }
rate_rgbi = max(max(rxb,gxb),max(bxb,ixb));
if ( rate_rgbi > 0 ) { show_bars(rxb,gxb,bxb,ixb,1); }
}
}
}
void mouseClicked()
{
if ( mouseButton == LEFT ) {
/* get */
if ( isRangeOk(mouseX, 20, 70) &&
isRangeOk(mouseY,300,320) ) {
/* debug */
println("Get");
/* send command */
cport.write('C');
cport.write('\r');
}
/* execute */
if ( isRangeOk(mouseX, 80,130) &&
isRangeOk(mouseY,300,320) ) {
/* debug */
println("Execute");
/* send command */
cport.write('E');
cport.write('\r');
}
/* idle */
if ( isRangeOk(mouseX,140,190) &&
isRangeOk(mouseY,300,320) ) {
/* debug */
println("Idle");
/* send command */
cport.write('I');
cport.write('\r');
}
/* exit */
if ( isRangeOk(mouseX,220,390) &&
isRangeOk(mouseY,300,320) ) {
/* send command */
cport.write('I');
cport.write('\r');
/* status */
store_status();
exit();
}
/* sensivility (HIGH) */
if ( isRangeOk(mouseX,301,339) &&
isRangeOk(mouseY,200,220) ) {
/* send command */
send_sense_cmd(true);
/* update */
xsense = "HIGH" ;
}
/* sensivility (LOW) */
if ( isRangeOk(mouseX,341,379) &&
isRangeOk(mouseY,200,220) ) {
/* send command */
send_sense_cmd(false);
/* update */
xsense = "LOW" ;
}
/* xtime (1) */
if ( isRangeOk(mouseX,301,319) &&
isRangeOk(mouseY,240,260) ) {
/* send command */
send_exposure_cmd(1);
/* update */
xtime = "1" ;
}
/* xtime (2) */
if ( isRangeOk(mouseX,321,339) &&
isRangeOk(mouseY,240,260) ) {
/* send command */
send_exposure_cmd(2);
/* update */
xtime = "2" ;
}
/* xtime (3) */
if ( isRangeOk(mouseX,341,359) &&
isRangeOk(mouseY,240,260) ) {
/* send command */
send_exposure_cmd(3);
/* update */
xtime = "3" ;
}
/* xtime (4) */
if ( isRangeOk(mouseX,361,379) &&
isRangeOk(mouseY,240,260) ) {
/* send command */
send_exposure_cmd(4);
/* update */
xtime = "4" ;
}
/* xmask (YES) */
if ( isRangeOk(mouseX,301,339) &&
isRangeOk(mouseY,280,300) ) {
/* send command */
send_mask_cmd(true);
/* update */
xmask = "YES" ;
}
/* xmask (NO) */
if ( isRangeOk(mouseX,341,379) &&
isRangeOk(mouseY,280,300) ) {
/* send command */
send_mask_cmd(false);
/* update */
xmask = "NO" ;
}
}
/* Exit */
if ( mouseButton == RIGHT ) {
/* send command */
cport.write('I');
cport.write('\r');
store_status();
exit();
}
}
void serialEvent(Serial p)
{
scflag = true ;
}
表示は、次のようになります。
スケッチの内容に関し、次の5項目に分けて説明します。
- 通信処理
- ボタン操作
- テキスト描画
- バー描画
- ファイル処理
通信処理
通信処理は、受信割込みと文字列処理の2ブロックで構成します。
受信割込みは単純で、'\n'が来たならイベントフラグscflagをセットし
関数draw()に通知。
void serialEvent(Serial p)
{
scflag = true ;
}
関数draw()の中で、イベントフラグscflagによる通知で
受信バッファに保存されている情報を扱います。
受信バッファに40文字以上保存されていた場合だけ
文字列を処理します。
if ( scflag == true ) {
scflag = false ;
/* check */
stmp = trim(cport.readStringUntil('\n'));
/* separate */
char[] ss = stmp.toCharArray();
loop = stmp.indexOf("BR :");
/* judge */
eflag = true ;
if ( loop < 40 ) { eflag = false ; }
/* show */
if ( eflag ) {
/* clear area */
background(0,0,0);
/* show */
textSize(20);
text(stmp.substring(0,loop-1),20,40);
text(stmp.substring(loop,stmp.length()),20,60);
/* clear */
loop = 0 ;
rxa = gxa = bxa = ixa = 0 ;
rxb = gxb = bxb = ixb = 0 ;
for (char ch : ss) {
/* check entry */
if ( ch == ':' ) { loop++ ; }
/* calculate */
if ( isNcode(ch) == true ) {
if ( loop == 1 ) { rxa = rxa * 10 + (ch-'0') ; }
if ( loop == 2 ) { gxa = gxa * 10 + (ch-'0') ; }
if ( loop == 3 ) { bxa = bxa * 10 + (ch-'0') ; }
if ( loop == 4 ) { ixa = ixa * 10 + (ch-'0') ; }
if ( loop == 5 ) { rxb = rxb * 10 + (ch-'0') ; }
if ( loop == 6 ) { gxb = gxb * 10 + (ch-'0') ; }
if ( loop == 7 ) { bxb = bxb * 10 + (ch-'0') ; }
if ( loop == 8 ) { ixb = ixb * 10 + (ch-'0') ; }
}
}
print('\n');
/* clear information */
fill(0,0,0);
rect(10,70,300,200);
fill(255,255,255);
/* show values */
show_values(rxa,gxa,bxa,ixa,0);
show_values(rxb,gxb,bxb,ixb,1);
/* draw bars */
int rate_rgbi ;
rate_rgbi = max(max(rxa,gxa),max(bxa,ixa));
if ( rate_rgbi > 0 ) { show_bars(rxa,gxa,bxa,ixa,0); }
rate_rgbi = max(max(rxb,gxb),max(bxb,ixb));
if ( rate_rgbi > 0 ) { show_bars(rxb,gxb,bxb,ixb,1); }
}
}
String型からchar型に文字列を変換し、チャネルA、Bの
2行に分割します。それぞれのRGBおよびIR情報から各色の
数値に分割変換します。数値に変換するのは、バーを表示
するときに、要求されるからです。
RGBおよびIR情報は、「:」で区切られているので、何度目かの
出現かを判断し、文字列を数値に変換します。
文字列を1文字ずつスキャンしていくのに、for文を使っています。
for文を使うと、1文字ずつのバラけた状態になるので、数字か英字の
どちらかを判定して、数字だったなら、10進数になるように計算。
数字かスキップする英字かを判断するため、専用関数を定義しています。
boolean isdigitx(char x)
{
boolean result ;
/* default */
result = false ;
/* judge */
if ( '0' <= x && x <= '9' ) { result = true ; }
return result ;
}
boolean isacode(char x)
{
boolean result ;
/* default */
result = false ;
/* judge */
if ( x == 'A' ) { result = true ; }
if ( x == 'B' ) { result = true ; }
if ( x == 'R' ) { result = true ; }
if ( x == 'G' ) { result = true ; }
if ( x == 'I' ) { result = true ; }
if ( x == ':' ) { result = true ; }
if ( x == ' ' ) { result = true ; }
return result ;
}
boolean isNcode(char x)
{
boolean result ;
/* default */
result = false ;
/* judge */
if ( isdigitx(x) && !isacode(x) ) {
result = true ;
}
return result ;
}
ボタン操作
ボタン操作は、クリッカブルマップ処理をしています。
クリッカブルマップ処理は、マウスカーソルがボタンアイコンの
占有する範囲にあるかを判定して、その範囲なら該当する動作を
実行します。
ボタンは、Arduinoの動作を指定する類とそれ以外になりますが
Arduinoの動作を指定するコマンドと1対1に対応する処理は
以下。
/* sensivility (HIGH) */
if ( isRangeOk(mouseX,301,339) &&
isRangeOk(mouseY,200,220) ) {
/* send command */
send_sense_cmd(true);
/* update */
xsense = "HIGH" ;
}
/* sensivility (LOW) */
if ( isRangeOk(mouseX,341,379) &&
isRangeOk(mouseY,200,220) ) {
/* send command */
send_sense_cmd(false);
/* update */
xsense = "LOW" ;
}
/* xtime (1) */
if ( isRangeOk(mouseX,301,319) &&
isRangeOk(mouseY,240,260) ) {
/* send command */
send_exposure_cmd(1);
/* update */
xtime = "1" ;
}
/* xtime (2) */
if ( isRangeOk(mouseX,321,339) &&
isRangeOk(mouseY,240,260) ) {
/* send command */
send_exposure_cmd(2);
/* update */
xtime = "2" ;
}
/* xtime (3) */
if ( isRangeOk(mouseX,341,359) &&
isRangeOk(mouseY,240,260) ) {
/* send command */
send_exposure_cmd(3);
/* update */
xtime = "3" ;
}
/* xtime (4) */
if ( isRangeOk(mouseX,361,379) &&
isRangeOk(mouseY,240,260) ) {
/* send command */
send_exposure_cmd(4);
/* update */
xtime = "4" ;
}
/* xmask (YES) */
if ( isRangeOk(mouseX,301,339) &&
isRangeOk(mouseY,280,300) ) {
/* send command */
send_mask_cmd(true);
/* update */
xmask = "YES" ;
}
/* xmask (NO) */
if ( isRangeOk(mouseX,341,379) &&
isRangeOk(mouseY,280,300) ) {
/* send command */
send_mask_cmd(false);
/* update */
xmask = "NO" ;
}
Arduinoに与えるコマンドを実現する関数は、以下のように定義しました。
void send_sense_cmd(boolean x)
{
cport.write('S');
if ( x ) { cport.write('1'); }
else { cport.write('0'); }
cport.write('\r');
}
void send_exposure_cmd(int x)
{
if ( 0 < x && x < 5 ) {
cport.write('L');
if ( x == 1 ) { cport.write('1'); }
if ( x == 2 ) { cport.write('2'); }
if ( x == 3 ) { cport.write('3'); }
if ( x == 4 ) { cport.write('4'); }
cport.write('\r');
}
}
void send_mask_cmd(boolean x)
{
cport.write('M');
if ( x ) { cport.write('1'); }
else { cport.write('0'); }
cport.write('\r');
}
テキスト描画
テキスト描画は、一度画面に出力すると変更なしの場合と
状況により変更して再表示する場合があります。
どちらにも対応できるように、関数を分割して定義しました。
void show_values(int x,int y,int z,int u,int wx)
{
int sx = 20 ;
int sy = 80 ;
int lx ;
int ly ;
String msg_r ;
String msg_g ;
String msg_b ;
String msg_ix ;
int offset = 30 ;
/* generate text */
msg_r = "AR :";
msg_g = "AG :";
msg_b = "AB :";
msg_ix = "AIR:";
if ( wx == 1 ) {
msg_r = "BR :";
msg_g = "BG :";
msg_b = "BB :";
msg_ix = "BIR:";
}
msg_r = msg_r + nf(x,5) ;
msg_g = msg_g + nf(y,5) ;
msg_b = msg_b + nf(z,5) ;
msg_ix = msg_ix + nf(u,5) ;
/* set location */
lx = sx ;
ly = sy ;
if ( wx == 1 ) { lx += 190 ; }
/* show */
textSize(15) ;
text(msg_r ,lx,ly+offset*0);
text(msg_g ,lx,ly+offset*1);
text(msg_b ,lx,ly+offset*2);
text(msg_ix,lx,ly+offset*3);
}
void show_caption_p()
{
/* white */
fill(255,255,255);
/* size */
textSize(12);
/* caption */
text("Sensivility",300,196);
text("Exposure",300,236);
text("Mask",300,276);
}
void clear_area()
{
/* black */
fill(0,0,0);
/* clear status area */
rect(390,200,100,100);
}
void show_caption()
{
clear_area();
/* white */
fill(255,255,255);
/* size */
textSize(12);
/* status */
text(xsense,400,214);
text(xtime ,400,254);
text(xmask ,400,294);
}
関数show_valuesは、RGBおよびIRの数値と2チャネルのどちらかを
指定すると、画面に各色の情報を数字で表示します。
関数show_caption_pとshow_captionは、一度画面表示すると変更が
ない文字列を表示します。
関数clear_areaは、過去に画面に表示した数字を、矩形領域の
黒による塗り潰しで消します。
バー描画
バー描画は、通信処理で生成した数値情報を
関数に与えることで、バーとします。
関数には、RGBおよびIRの数値と2チャネルのどちらを
描画するのかをパラメータとして与えます。
void show_bars(int x,int y,int z,int u,int wx)
{
int rgbi ;
int rate_r ;
int rate_g ;
int rate_b ;
int rate_i ;
int sx = 100 ;
int sy = 70 ;
int offset = 27 ;
int lx ;
int ly ;
/* calculate ratio */
rgbi = max(max(x,y),max(z,u)) ;
rate_r = (int)( (x * 100.0) / rgbi ) ;
rate_g = (int)( (y * 100.0) / rgbi ) ;
rate_b = (int)( (z * 100.0) / rgbi ) ;
rate_i = (int)( (u * 100.0) / rgbi ) ;
/* calcualte location */
lx = sx ;
ly = sy ;
if ( wx == 1 ) { lx = 290 ; }
/* show bar */
fill(255, 0, 0); rect(lx,ly+offset*0,rate_r,20);
fill( 0,255, 0); rect(lx,ly+offset*1,rate_g,20);
fill( 0, 0,255); rect(lx,ly+offset*2,rate_b,20);
fill(255,255,255); rect(lx,ly+offset*3,rate_i,20);
}
関数内で、各色の最大値を決めておきます。
最大値をもつ色は、200ピクセルのバーにしておき、他の色は
その何分の1なのかでバーの長さを指定します。
ファイル処理
ファイル内の情報は、カラーセンサーの次の項目を指定します。
テキストファイルには、感度とマスク指定を1か0の論理値で
露光時間コードは、1から4の自然数として格納します。
各指定の並びは、感度、露光時間コード、マスク指定の順で
1行にまとめます。
テキストファイル名は、「istatus.txt」としています。
ファイルから情報を取得する場合は、関数setupの中に
次の処理を書いて対応。
xsense = "LOW" ;
if ( ss[0] == '1' ) { xsense = "HIGH" ; }
xtime = "1" ;
if ( ss[1] == '2' ) { xtime = "1" ; }
if ( ss[1] == '3' ) { xtime = "2" ; }
if ( ss[1] == '4' ) { xtime = "3" ; }
xmask = "NO" ;
if ( ss[2] == '1' ) { xmask = "YES" ; }
/* first one shot */
oflag = true ;
ファイルへ情報を保存する場合、専用関数store_statusを使います。
void store_status()
{
String stmp ;
/* clear */
stmp = "" ;
/* sensivility */
if ( xsense == "HIGH" ) { stmp += "1" ; }
else { stmp += "0" ; }
/* exposure time */
if ( xtime == "1" ) { stmp += "1" ; }
if ( xtime == "2" ) { stmp += "2" ; }
if ( xtime == "3" ) { stmp += "3" ; }
if ( xtime == "4" ) { stmp += "4" ; }
/* mask */
if ( xmask == "YES" ) { stmp += "1" ; }
else { stmp += "0" ; }
/* file handling */
outFN = createWriter("istatus.txt");
outFN.println(stmp);
outFN.close();
}
関数store_statusを呼び出すのは、スケッチを終了する
場合に限定しています。
ファイルから情報を読込んだときに、Arduinoにコマンドを
出力するため、1回だけコマンドを送信するようにoflagを
使い、関数drawに通知。
関数draw内では、通知フラグoflagを判断してコマンドを
1回だけ発行するように定義します。
if ( oflag ) {
oflag = false ;
/* sensivility */
if ( xsense == "HIGH" ) { send_sense_cmd(true); }
else { send_sense_cmd(false); }
/* exposure time */
send_exposure_cmd(int(xtime));
/* mask */
if ( xmask == "YES" ) { send_mask_cmd(true); }
else { send_mask_cmd(false); }
}
ここから先は、備忘録としての記述です。
Processingは、Javaの言語仕様に影響を受けているので
文字列処理はStringオブジェクトを使うのが基本。
Stringオブジェクトは、文字列を簡単に扱うことを考えて
設計されています。char型で充分な処に、オブジェクトを
使うのは面倒なので、Arduinoが送信してきた文字情報を
char型に変換して扱います。
String型からchar型の変換は、メソッドtoCharArrayに
任せておき、char型になった文字列を、スキャンして
数字から数値に変換しました。
loop = 0 ;
rxa = gxa = bxa = ixa = 0 ;
rxb = gxb = bxb = ixb = 0 ;
for (char ch : ss) {
/* check entry */
if ( ch == ':' ) { loop++ ; }
/* calculate */
if ( isNcode(ch) == true ) {
if ( loop == 1 ) { rxa = rxa * 10 + (ch-'0') ; }
if ( loop == 2 ) { gxa = gxa * 10 + (ch-'0') ; }
if ( loop == 3 ) { bxa = bxa * 10 + (ch-'0') ; }
if ( loop == 4 ) { ixa = ixa * 10 + (ch-'0') ; }
if ( loop == 5 ) { rxb = rxb * 10 + (ch-'0') ; }
if ( loop == 6 ) { gxb = gxb * 10 + (ch-'0') ; }
if ( loop == 7 ) { bxb = bxb * 10 + (ch-'0') ; }
if ( loop == 8 ) { ixb = ixb * 10 + (ch-'0') ; }
}
}
RGBおよびIR情報を表現する数字には、区別しやすい
ように、IDコード(AR、BRなど)がついています。
IDコードの次に数字の開始を意味するマーカー「:」が
あるので、マーカーを見つけたなら、最大5文字の数字
を数値に変換するカラクリを作りました。
数字であれば数値に変換し、10進数の数値情報を
組み上げることを8回繰り返します。
ひとつの色を表現する文字列は最大5文字で、数字と
スペースで構成されているので、スペースをスキップ
しています。
forでは、文字列を1文字ごとに分割してしまうので
スキップする文字は、スペースだけではなく、以下の
文字としてあります。
'A' 'B' 'R' 'G' 'I' ':'
スキップする文字と数字の区別ができれば、色情報の
文字列を10進数で計算するため、重みの10を乗算する
処理と1桁の数字から数値に変換する処理を組合わせ
色情報の数値に仕立てます。
目次
前
次