目次

カラーセンサー関係スケッチ

 各LEDの色の違いで、どの程度の波長が出ているのかを
 調べるために、カラーセンサーを利用しました。



 秋月電子で販売されていたカラーセンサーS9706を
 変換基板に半田付けし、Arduinoに接続後RGBの各
 センサーの数値を、0から4095で表示します。



 センサーのデータ取得タイミングチャートを見て
 変換シーケンスを考えていきます。



 RANGEで感度を決め、GATEのH期間でシャッターを
 開いている時間を指定しています。その後にCLK
 に同期して出力されるRGBの各12ビットを取得する
 ことで、センサー情報になります。

 Arduinoとセンサーの接続は、以下としました。



 シーケンスを、ひとつの関数に担当させることに。

void get_color(byte which,byte xd)
{
  byte i ;
  word rgb[3] ;
  /* set RANGE */
  put_range( which ) ;
  /* disable GATE and CK */
  put_gate(OFF);
  put_ck(OFF);
  /* open GATE */
  put_gate( ON ) ;
  delay(xd+2);
  put_gate(OFF);
  /* loop */
  for ( i = 0 ; i < 3 ; i++ ) {
    /* interval */
    delayMicroseconds(4);
    /* get RGB information */
    *(rgb+i) = get_color_value() ;
  }
  /* copy */
  rxdat = *(rgb+0) ;
  gxdat = *(rgb+1) ;
  bxdat = *(rgb+2) ;
}

void put_range(byte x)
{
  if ( x == ON ) {
    PORTC |= (1 << RANGE_BIT) ;
  } else {
    PORTC &= ~(1 << RANGE_BIT) ;
  }
}

void put_gate(byte x)
{
  if ( x == HD ) {
    PORTC |= (1 << GATE_BIT) ;
  } else {
    PORTC &= ~(1 << GATE_BIT) ;
  }
}

void put_ck(byte x)
{
  if ( x == ON ) {
    PORTC |= (1 << CK_BIT) ;
  } else {
    PORTC &= ~(1 << CK_BIT) ;
  }
}

word get_color_value()
{
  word result ;
  byte i ;
  /* clear */
  result = 0 ;
  /* loop */
  for ( i = 0 ; i < 12 ; i++ ) {
    /* shift */
    result >>= 1 ;
    /* CK : H */
    put_ck( ON ) ;
    /* delay */
    delayMicroseconds(2);
    /* get data */
    if ( PINC & ON ) { result |= 0x800 ; }
    /* CK : L */
    put_ck( OFF ) ;
    /* delay */
    delayMicroseconds(2);
  }
  /* adjust */
  result &= 0xfff ;

  return result ;
}

 シリアルインタフェースで制御できるように
 コマンドインタプリタを用意し、操作が簡単
 になるようにします。

 コマンドは、次のように決めました。

 コマンドを決めたなら、データ転送速度を9600bpsとし
 スケッチを定義します。

#include <MsTimer2.h>

#define OFF 0
#define ON  OFF+1

#define LD 0
#define HD 1

/* color sensor pin assignment */
#define RANGE_BIT 3
#define CLK_BIT   2
#define GATE_BIT  1
#define DOUT_BIT  0

#define TBIT 11

/* monitor LED */
#define LED_BIT 5

/* global variables */
byte bflag ;
byte uflag ;
byte sindex ;
byte sbuf[8] ;
byte xcnt ;
word rxdat ;
word gxdat ;
word bxdat ;
byte timcnt ;

void  send_led(byte x)
{
  if ( x ) { PORTB |=  (1 << LED_BIT) ; }
  else     { PORTB &= ~(1 << LED_BIT) ; }
}

void  update_trigger(void)
{
  send_led( xcnt & ON );
  xcnt++ ;
}

void  rs_putchar(char x)
{
  Serial.write(x);
}

void  rs_puts(char *x)
{
  while ( *x ) {
    rs_putchar( *x ) ;
    x++ ;
  }
}
void  crlf()
{
  rs_putchar('\r');
  rs_putchar('\n');
}

byte  get_hex(char x)
{
  byte result ;

  result = 0 ;
  if ( '0' <= x && x <= '9' ) { result = x - '0' ; }
  if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; }
  if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; }

  return result ;
}

void  show_digit4(word x)
{
  byte j ;
  char msg[4] ;
  /* separate */
  for ( j = 0 ; j < 4 ; j++ ) {
    *(msg+3-j) = x % 10 + '0' ;
    x /= 10 ;
  }
  /* zero suppress */
  if ( *(msg+0) == '0' ) {
    *(msg+0) = ' ' ;
    if ( *(msg+1) == '0' ) {
      *(msg+1) = ' ' ;
      if ( *(msg+2) == '0' ) {
        *(msg+2) = ' ' ;
      }
    }
  }
  /* show */
  for ( j = 0 ; j < 4 ; j++ ) { rs_putchar( *(msg+j) ); }
}

void  show_help()
{
  rs_puts("? help")                        ; crlf();
  rs_puts("G get data and show")           ; crlf();
  rs_puts("T set delay time count(1-255)") ; crlf();
  rs_puts("R select range (0 or 1)")       ; crlf();
}

void get_color(byte which,byte xd)
{
  byte i ;
  word rgb[3] ;
  /* set RANGE */
  put_range( which ) ;
  /* disable GATE and CK */
  put_gate(OFF);
  put_ck(OFF);
  /* open GATE */
  put_gate( ON ) ;
  delay(xd+2);
  put_gate(OFF);
  /* loop */
  for ( i = 0 ; i < 3 ; i++ ) {
    /* interval */
    delayMicroseconds(4);
    /* get RGB information */
    *(rgb+i) = get_color_value() ;
  }
  /* copy */
  rxdat = *(rgb+0) ;
  gxdat = *(rgb+1) ;
  bxdat = *(rgb+2) ;
}

void put_range(byte x)
{
  if ( x == ON ) {
    PORTC |= (1 << RANGE_BIT) ;
  } else {
    PORTC &= ~(1 << RANGE_BIT) ;
  }
}

void put_gate(byte x)
{
  if ( x == HD ) {
    PORTC |= (1 << GATE_BIT) ;
  } else {
    PORTC &= ~(1 << GATE_BIT) ;
  }
}

void put_ck(byte x)
{
  if ( x == ON ) {
    PORTC |= (1 << CK_BIT) ;
  } else {
    PORTC &= ~(1 << CK_BIT) ;
  }
}

word get_color_value()
{
  word result ;
  byte i ;
  /* clear */
  result = 0 ;
  /* loop */
  for ( i = 0 ; i < 12 ; i++ ) {
    /* shift */
    result >>= 1 ;
    /* CK : H */
    put_ck( ON ) ;
    /* delay */
    delayMicroseconds(2);
    /* get data */
    if ( PINC & ON ) { result |= 0x800 ; }
    /* CK : L */
    put_ck( OFF ) ;
    /* delay */
    delayMicroseconds(2);
  }
  /* adjust */
  result &= 0xfff ;

  return result ;
}

void show_values()
{
  byte j ;
  word tmp ;

  for ( j = 0 ; j < 3 ; j++ ) {
    /* prompt */
    if ( j == 2 ) {
      rs_putchar('B') ;
      tmp = gxdat ;
    } else {
      if ( j == 1 ) {
        rs_putchar('G');
        tmp = bxdat ;
      } else {
        rs_putchar('R'); 
        tmp = rxdat ;
      }
    }
    rs_puts(" = ");
    show_digit4( tmp );
    crlf();
  }
}

void setup()
{
  /* initialize serial port */
  Serial.begin(9600);
  sindex = 0 ;
  /* define digital pin */
  PORTB = 0x00 ;
  PORTC = 0x00 ;
  PORTD = 0x01 ;
  /* set initial state */
  DDRB = 0xff ;
  DDRC = 0xfe ;
  DDRD = 0xfe ;
  /* clear flags */
  bflag = OFF ;
  uflag = OFF ;
  /* initialize variables */
  rxdat  = 0 ;
  gxdat  = 0 ;
  bxdat  = 0 ;
  timcnt = 0 ;
  xcnt   = 0 ;
  /* 250ms period */
  MsTimer2::set(250,update_trigger);
  /* enable */ 
  MsTimer2::start();
}

void loop()
{
  byte cmd ;
  byte i ;
  /* serial handling */
  if ( uflag == ON ) {
    /* clear flag */
    uflag = OFF ;
    /* new line */
    crlf();
    /* get command */
    cmd = *(sbuf+0) ;
    /* help */
    if ( cmd == '?' ) { show_help() ; }
    /* get color data and show */
    if ( cmd == 'G' ) {
      /* color sensor handling */
      get_color(bflag,timcnt);
      /* show values */
      show_values();
    }
    /* set delay time count */
    if ( cmd == 'T' ) {
      /* clear */
      timcnt = 0 ;
      /* convert */
      for ( i = 0 ; i < 3 ; i++ ) {
        /* judge */
        if ( *(sbuf+i+1) == '\r' ) break ;
        /* calcualte */
        timcnt = timcnt * 10 + get_hex( *(sbuf+i+1) ) ;
      }
      /* echo back */
      show_digit4( timcnt );
      crlf() ;
    }
    /* set range */
    if ( cmd == 'R' ) {
      /* default */
      bflag = OFF ;
      /* get selection code */
      if ( *(sbuf+1) == '1' ) { bflag = ON ; }
    }
  }
}

/* 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 ;
    }
  }
}

 このスケッチで、赤、緑、橙、黄、青、白の
 色に関係する周波数特性を把握できます。

目次

inserted by FC2 system