目次

カラーセンサー情報取得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スケッチは、一度作成したなら、それで完了と
 いう場合が多いですが、一部のみの変更で、新しい要求に
 答えられる柔軟性を残してあります。


目次

inserted by FC2 system