目次
前
次
カラーセンサー情報取得5
2つのカラーセンサーから情報取得することができる
ようになりました。人間の目は、周波数では、555nmの
波長の色の感度が高いと照明工学で習いました。
カラーセンサーの緑の情報だけを選んで表示する
スケッチを作成しました。
GUIの画面は、以下。
右にあるメニュー項目ボタンの「Green」のYES/NOで
緑だけとフルカラーの情報表示を選択できます。
YES/NOのクリックで、緑だけとフルカラーの選択が
できますが、YESのクリックで緑だけになります。
フルカラーの場合、表示は次のようになります。
緑のみの情報表示にするかフルカラーにするかを
クリッカブルマップで選択できるようにします。
/* gmask (YES) */
if ( isRangeOk(mouseX,301,339) &&
isRangeOk(mouseY,320,340) ) {
/* update */
gmask = "YES" ;
gflag = true ;
}
/* gmask (NO) */
if ( isRangeOk(mouseX,341,379) &&
isRangeOk(mouseY,320,340) ) {
/* update */
gmask = "NO" ;
gflag = false ;
}
どちらの表示にするのかを、フラグgflagに格納しています。
フラグgflagで、テキストとバーの表示関数の内容を改定すれば
全体構成変更をしないでよいので、内部処理を変更します。
void show_values(int x,int y,int z,int u,int wx)
{
int sx = 20 ;
int sy = 80 ;
int lx ;
int ly ;
int offset = 30 ;
String msg_r ;
String msg_g ;
String msg_b ;
String msg_ix ;
/* 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 += nf(x,5) ;
msg_g += nf(y,5) ;
msg_b += nf(z,5) ;
msg_ix += nf(u,5) ;
/* set location */
lx = sx ;
ly = sy ;
if ( wx == 1 ) { lx += 190 ; }
/* show */
textSize(15) ;
if ( gflag == true ) {
text(msg_g ,lx,ly+offset*1);
} else {
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 */
if ( gflag == true ) {
rate_g = 25 ;
fill( 0,255, 0); rect(lx,ly+offset*1,rate_g,20);
} else {
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);
}
}
テキストとバーの表示は、これで解決ですが、Arduinoの
送信情報を、緑のみとフルカラーで区別して表示すると
しなければなりません。
フラグgflagで、情報を切り出す位置を変えます。
String型オブジェクトのメソッドsubstringで緑
情報を含んだ文字列の開始位置を取得し、切出し
します。
AG、BGを見つけて、その右にある数字を切出します。
処理コードは単純で、以下。
if ( gflag == true ) {
String xstmp ;
int idx ;
xstmp = stmp.substring(0,loop-1) ;
idx = xstmp.indexOf("AG :");
text(xstmp.substring(idx,idx+10),20,40);
xstmp = stmp.substring(loop,stmp.length()) ;
idx = xstmp.indexOf("BG :");
text(xstmp.substring(idx,idx+10),20,60);
} else {
text(stmp.substring(0,loop-1),20,40);
text(stmp.substring(loop,stmp.length()),20,60);
}
肝となる部分を定義したので、スケッチを記述します。
import processing.serial.*;
Serial cport;
PImage imgGet ;
PImage imgExecute ;
PImage imgIdle ;
PImage imgExit ;
PImage imgSense ;
PImage imgXtime ;
PImage imgXmask ;
PImage imgGmask ;
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 ;
String gmask ;
boolean eflag ;
boolean oflag ;
boolean gflag ;
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 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 isAcode(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 ;
int offset = 30 ;
String msg_r ;
String msg_g ;
String msg_b ;
String msg_ix ;
/* 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 += nf(x,5) ;
msg_g += nf(y,5) ;
msg_b += nf(z,5) ;
msg_ix += nf(u,5) ;
/* set location */
lx = sx ;
ly = sy ;
if ( wx == 1 ) { lx += 190 ; }
/* show */
textSize(15) ;
if ( gflag == true ) {
text(msg_g ,lx,ly+offset*1);
} else {
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 */
if ( gflag == true ) {
rate_g = 25 ;
fill( 0,255, 0); rect(lx,ly+offset*1,rate_g,20);
} else {
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);
image(imgGmask ,300,320);
}
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);
text("Green",300,316);
}
void clear_area()
{
/* black */
fill(0,0,0);
/* clear status area */
rect(390,200,100,140);
}
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);
text(gmask ,400,334);
}
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" ; }
/* gmask */
if ( gmask == "YES" ) { stmp += "1" ; }
else { stmp += "0" ; }
println(stmp);
/* file handling */
outFN = createWriter("istatus.txt");
outFN.println(stmp);
outFN.close();
}
void setup()
{
size(440,340);
/* title caption */
surface.setTitle("Test 06");
/* 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");
imgGmask = loadImage("gmask.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" ; }
gmask = "NO" ;
gflag = false ;
if ( ss[3] == '1' ) {
gmask = "YES" ;
gflag = true ;
}
/* 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);
if ( gflag == true ) {
String xstmp ;
int idx ;
xstmp = stmp.substring(0,loop-1) ;
idx = xstmp.indexOf("AG :");
text(xstmp.substring(idx,idx+10),20,40);
xstmp = stmp.substring(loop,stmp.length()) ;
idx = xstmp.indexOf("BG :");
text(xstmp.substring(idx,idx+10),20,60);
} else {
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 ( isAcode(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" ;
}
/* gmask (YES) */
if ( isRangeOk(mouseX,301,339) &&
isRangeOk(mouseY,320,340) ) {
/* update */
gmask = "YES" ;
gflag = true ;
}
/* gmask (NO) */
if ( isRangeOk(mouseX,341,379) &&
isRangeOk(mouseY,320,340) ) {
/* update */
gmask = "NO" ;
gflag = false ;
}
}
/* Exit */
if ( mouseButton == RIGHT ) {
/* send command */
cport.write('I');
cport.write('\r');
store_status();
exit();
}
}
void serialEvent(Serial p)
{
scflag = true ;
}
このスケッチでは、緑のYES/NOをArduinoから情報取得
している最中でも切り替えることが可能です。
感度、露光時間、マスクの他に緑情報のみ表示フラグを
ファイルに保存、またはファイルからの取得も含みます。
テキストファイルへの保存は、次のように定義しました。
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" ; }
/* gmask */
if ( gmask == "YES" ) { stmp += "1" ; }
else { stmp += "0" ; }
println(stmp);
/* file handling */
outFN = createWriter("istatus.txt");
outFN.println(stmp);
outFN.close();
}
テキストファイルから設定情報を復旧する処理は、以下。
/* 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" ; }
gmask = "NO" ;
gflag = false ;
if ( ss[3] == '1' ) {
gmask = "YES" ;
gflag = true ;
}
組込み関数loadStringsを利用して、全行を読み取り後
1文字ごとの内容を展開します。
Processingでは、Classを利用できるので、もう少し簡潔な
スケッチとなりますが、動作を優先させ、関数によるデータ
操作にしました。
Arduinoスケッチでは、Green情報のみを送信させることも
可能ですが、全色の情報を送信させておき、Processing側
で、必要な情報のみを取り出す方式を採用しました。
今回は、Green情報を引き出すだけでしたが、他の色だけ
を取り出すように変更するなら、IDコード(AR、BRなど)を
変えるだけで済ませられます。
Processingスケッチは、一度作成したなら、それで完了と
いう場合が多いですが、一部のみの変更で、新しい要求に
答えられる柔軟性を残してあります。
目次
前
次