目次

ファームウエア


 このファームウエアには、GBCからの画像入力の他、MCRマシンを
 動かす機能も少し含まれています。

 システムクロックを8MHzとしています。

#include <avr/io.h>
#include <avr/io8535.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

#define OFF 0
#define ON  OFF+1

#define FOSC   8000000
#define BAUD   38400
#define MYUBRR (FOSC/16/BAUD)-1

typedef unsigned char  UBYTE ;
typedef unsigned short UWORD ;
typedef unsigned long  ULONG ;
typedef   signed char  SBYTE ;
typedef   signed short SWORD ;

typedef union {
  struct {
    unsigned char B0:1;
    unsigned char B1:1;
    unsigned char B2:1;
    unsigned char B3:1;
    unsigned char B4:1;
    unsigned char B5:1;
    unsigned char B6:1;
    unsigned char B7:1;
  } BIT ;
  unsigned char DR ;
} FLAGSP ;

volatile FLAGSP x_flags ;

#define UFLAG x_flags.BIT.B0
#define TFLAG x_flags.BIT.B1
#define AFLAG x_flags.BIT.B2
#define IFLAG x_flags.BIT.B3
#define DFLAG x_flags.BIT.B7

#define BUFSIZE 8

#define MONITOR 7
#define START   6
#define SIN     5
#define LOAD    4
#define RST     3
#define XCK     2
#define READ    1

#define PMAX 100

volatile UBYTE sbuf[BUFSIZE] ;
volatile UBYTE sindex;

volatile UBYTE lcnt ;

volatile ULONG tickcount ;

volatile UBYTE pcnt ;
volatile UBYTE duty[3] ;
volatile UBYTE dutyx[3] ;
volatile UBYTE direction[3] ;

volatile UBYTE state ;
volatile UBYTE lane ;
volatile UBYTE threshold ;

volatile UBYTE rdat[8] ;
volatile UBYTE sdat[128] ;

const prog_char msg_h[] PROGMEM = "? help" ;
const prog_char msg_c[] PROGMEM = "C reset camera" ;
const prog_char msg_r[] PROGMEM = "R set register value" ;
const prog_char msg_g[] PROGMEM = "G get image" ;
const prog_char msg_s[] PROGMEM = "S default setting" ;
const prog_char msg_d[] PROGMEM = "D debug" ;
const prog_char msg_p[] PROGMEM = "P set duty ratio(Pdvvc)" ;

const prog_char msg_sp[] PROGMEM = "p show duty ratio" ;

const prog_char msg_st[] PROGMEM = "START TRIGGER" ;
const prog_char msg_gi[] PROGMEM = "Get IMAGE" ;
const prog_char msg_cp[] PROGMEM = "COMPLETE" ;

const prog_char msg_first[] PROGMEM = "MCR controller" ;

#define MSG_HELP     0
#define MSG_RESET    1
#define MSG_REGISTER 2
#define MSG_IMAGE    3
#define MSG_DEFAULT  4
#define MSG_DEBUG    5
#define MSG_ST       6
#define MSG_GI       7
#define MSG_CP       8
#define MSG_PULSE    9
#define MSG_DUTY     10

#define NO  0
#define YES NO+1

#define MASKFF 0xff
#define MASK0F 0x0f
#define MASKF0 0xf0
#define MASK80 0x80

#define MAX_SIZE 16384

#define ALL_BLACK    0
#define ALL_WHITE    1
#define LEFT_WHITE   2
#define RIGHT_WHITE  3
#define CENTER       4
#define LITTLE_LEFT  5
#define LEFT         6
#define BIG_LEFT     7
#define LITTLE_RIGHT 8
#define RIGHT        9
#define BIG_RIGHT    10
#define CRANK_RIGHT  11
#define CRANK_LEFT   12

#define LANE_RIGHT 0
#define LANE_LEFT  1

/*--------------------------------*/
/* Insert user functions protoype */
/*--------------------------------*/
void  user_initialize(void);

void  uart_putchar(UBYTE x);
void  crlf(void);
void  uart_puts(UBYTE *x);
void  first_message(void);

UBYTE get_hex(UBYTE x);

void  delay_ms(UWORD x);

void  uart_interpreter(void);

void  set_xck(UBYTE x);
void  set_sin(UBYTE x);
void  reset_cam(void);
void  send_cam(UWORD x);
void  send_start(void);
void  get_img(UBYTE x);
void  send_default(void);

void  start_adc(void);
void  wai_adc(void);
void  show_value(UWORD x);

void  send_uart_msg(UBYTE x);

void  rotate(UBYTE dx,UBYTE px);
void  set_speed(UBYTE x);
void  set_led_duty(UBYTE x);
void  blind_run(void);
void  mcr_run(void);
void  get_sensor(void);
UBYTE is_center(UWORD x);
UBYTE is_edge(UWORD x);
void  binary_display(UBYTE x);

/*------*/
/* main */
/*------*/
int main(void)
{
  /* disable interrupt */
  cli();
  /* initialize port and variables */
  user_initialize();
  /* enable interrupt */
  sei();
  /* endless loop */
  first_message();
  while ( ON ) {
    /* USART handling */
    if ( UFLAG ) {
      /* clear flag */
      UFLAG = OFF ;
      /* interpreter */
      uart_interpreter();
    }
    /* monitoring */
    if ( TFLAG ) {
      /* clear flag */
      TFLAG = OFF ;
      /* increment */
      lcnt++ ;
      /* toggle port bit */
      PORTA &= ~(1 << MONITOR) ;
      if ( lcnt & 1 ) { PORTA |= (1 << MONITOR) ; }
     }
     /* moving */
     if ( AFLAG ) {
       if ( IFLAG == OFF ) {
         get_img(ON);
         blind_run();
         IFLAG = ON ;
       }
       if ( IFLAG == ON ) { mcr_run(); }
    }
  }
  /* dummy */
  return 0 ;
}

#/*-----------------------*/
/* Insert user functions */
/*-----------------------*/
void user_initialize(void)
{
  /* PORT A */
  PORTA = 0b00001000 ; /* 00001000 */
  DDRA  = 0b11111100 ; /* ooooooii */
  /* PORT B */		
  PORTB = 0b00000000 ; /* 00000000 */
  DDRB  = 0b11111111 ; /* oooooooo */
  /* PORT C */		
  PORTC = 0b00000000 ; /* 00000000 */
  DDRC  = 0b11111111 ; /* oooooooo */
  /* PORT D */		
  PORTD = 0b00001100 ; /* 00001100 */
  DDRD  = 0b11110010 ; /* ooooiioi */
  /* initialize flags */
  x_flags.DR = 0 ;
  /* initialize serial */
  {
    /* clear index */
    sindex = 0 ;
    /* set Baud Rate Registers */
    UBRR = MASKFF ;
    /* Enable receive interrupt , receive module and transmit module */
    UCR = (1 << TXEN) | (1 << RXEN) | (1 << RXCIE);
  }
  /* initialize ADC */
  {
    /* select channel 0 */
    ADMUX = 0 ;
    /* enable ADC , enable interrupt , select prescaler (/128) */
    ADCSR = (1 << ADEN) | (1 << ADIE) | (7 << ADPS0) ;
  }
  /* initialize timer1 */
  {
    tickcount = 0 ;
    /* select CTC , (presclae /8) 1MHz */
    TCCR1B = (1 << CTC1) | (1 << CS11) ;
    /* clear timer/counter */
    TCNT1 = 0 ;
    OCR1A =  999 ;
    OCR1B = 1200 ;
    /* Enable Compare match interruption */
    TIMSK |= (1 << OCIE1A) ;
  }
  /* initialize timer2 */
  {
    lcnt = 0 ;
    /* select clock source (presclae /1024) about 8kHz */
    TCCR2 = (1 << CTC2) | (1 << CS20) ;
    /* clear timer/counter */
    TCNT2 = 0 ;
    OCR2 = 78 ;
    /* Enable Compare match interruption */
    TIMSK |= (1 << OCIE2) ;
  }
  /* initialize interrupt */
  {
    /* select falling edge */
    MCUCR = (1 << ISC11) | (1 << ISC01) ;
    /* Enable external interruption */
    GIMSK = (1 << INT1) | (1 << INT0) ;
  }
  /* */
  pcnt = 0 ;
  *(duty+0) = 0 ;
  *(duty+1) = 0 ;
  *(duty+2) = 90 ;
  *(dutyx+0) = 0 ;
  *(dutyx+1) = 0 ;
  *(dutyx+2) = 90 ;
  *(direction+0) = 0 ;
  *(direction+1) = 2 ;
  *(direction+2) = 1 ;
  state = 0 ;
}

/* UART receive interrupt */
ISR(UART_RX_vect)
{
  volatile UBYTE ch ;
  /* get 1 charactoer */
  ch = UDR ;
  /* store */
  *(sbuf+sindex) = ch ;
  sindex++ ;
  /* judge */
  if ( ch == '\r' || ch == '\n' ) {
    UFLAG = ON ;
    sindex = 0 ;
  }
}

/* TIMER1 interrupt */
ISR(TIMER1_COMPA_vect)
{
  /* increment */
  tickcount++ ;
}

/* TIMER2 interrupt */
ISR(TIMER2_COMP_vect)
{
  UBYTE cport ;
  /* default */
  cport = 0 ;
  /* judge */
  if ( pcnt < *(dutyx+0) ) {
    if ( *(direction+0) == 1 ) { cport |= 0x01 ; }
    if ( *(direction+0) == 2 ) { cport |= 0x02 ; }
  }
  if ( pcnt < *(dutyx+1) ) {
    if ( *(direction+1) == 1 ) { cport |= 0x04 ; }
    if ( *(direction+1) == 2 ) { cport |= 0x08 ; }
  }
  if ( pcnt < *(dutyx+2) ) {
    if ( *(direction+2) == 1 ) { cport |= 0x10 ; }
    if ( *(direction+2) == 2 ) { cport |= 0x20 ; }
  }
  /* impress */
  PORTC = cport ;
  /* increment */
  pcnt++ ;
  if ( pcnt == PMAX ) {
    pcnt = 0 ;
    *(dutyx+0) = *(duty+0);
    *(dutyx+1) = *(duty+1);
    *(dutyx+2) = *(duty+2);
    *(dutyx+3) = *(duty+3);
  }
  /* set flag */
  TFLAG = ON ;
}

/* INT0 interrupt */
ISR(INT0_vect)
{
  AFLAG = ON ;
}

/* INT1 interrupt */
ISR(INT1_vect)
{
  AFLAG = OFF ; IFLAG = OFF ;
}

UBYTE get_hex(UBYTE x)
{
  volatile UBYTE result ;
  /* default */
  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  uart_putchar(UBYTE x)
{
  while ( !(USR & (1 << UDRE)) ) ;
  UDR = x ;
}

void  crlf(void)
{
  uart_putchar('\r');
  uart_putchar('\n');
}

void  uart_puts(UBYTE *x)
{
  while ( *x != '\0' ) {
    uart_putchar( *x ) ;
    x++ ;
  }
  crlf();
}

void  first_message(void)
{
  char msg[20];
  /* copy */
  strcpy_P(msg,msg_first);
  /* show */
  uart_puts((UBYTE *)msg);
}

void  delay_ms(UWORD x)
{
  ULONG target ;
  /* set counter */
  target = tickcount + (ULONG)x ;
  /* wait */
  while ( target > tickcount ) ;
}

void uart_interpreter(void)
{
  UBYTE cmd ;
  UBYTE chx ;
  UBYTE dir ;
  UBYTE val[2] ;
  /* get command character */
  cmd = *(sbuf+0) ;
  /* reset camera  */
  if ( cmd == 'C' ) {
    reset_cam() ;
    if ( DFLAG ) { send_uart_msg(MSG_RESET) ; }
  }
  /* set register value */
  if ( cmd == 'R' ) {
    /* get channel */
    chx = get_hex( *(sbuf+3) );
    /* get code */
    *(val+0) = get_hex( *(sbuf+1) );
    *(val+1) = get_hex( *(sbuf+2) );
    /* send this value to camera */
    send_cam( (chx << 8) | ((val[0] << 4)+ val[1]) );
    if ( DFLAG ) { send_uart_msg(MSG_REGISTER) ; }
  }
  /* set default value */
  if ( cmd == 'S' ) {
    send_default() ;
    if ( DFLAG ) { send_uart_msg(MSG_DEFAULT) ; }
  }
  /* set debug flag */
  if ( cmd == 'D' ) {
    DFLAG = OFF ;
    if ( *(sbuf+1) == '1' ) { DFLAG = ON ; }
    crlf();
  }
  /* get picture */
  if ( cmd == 'G' ) { get_img(OFF) ; }
  /* set duty */
  if ( cmd == 'P' ) {
    /* get channel */
    chx = get_hex( *(sbuf+4) );
    /* get direction */
    dir = get_hex( *(sbuf+1) );
    /* get code */
    *(val+0) = get_hex( *(sbuf+2) );
    *(val+1) = get_hex( *(sbuf+3) );
    /* store */
    *(direction+chx) = dir ;
    *(duty+chx) = 10 * val[0] + val[1] ;
  }
  /* show duty */
  if ( cmd == 'p' ) {
    for ( chx = 0 ; chx < 4 ; chx++ ) {
      /* direction */
      uart_putchar( *(direction+chx) + '0' );
      uart_putchar( ' ' );
      /* duty */
      *(val+0) = *(duty+chx) / 10 ;
      *(val+1) = *(duty+chx) % 10 ;
      uart_putchar( *(val+0) + '0' );
      uart_putchar( *(val+1) + '0' );
      /* new line */
      crlf();
    }
  }
  /* help */
  if ( cmd == '?' ) {
    send_uart_msg(MSG_HELP);
    send_uart_msg(MSG_RESET);
    send_uart_msg(MSG_REGISTER);
    send_uart_msg(MSG_IMAGE);
    send_uart_msg(MSG_DEFAULT);
    send_uart_msg(MSG_DEBUG);
    send_uart_msg(MSG_PULSE);
    send_uart_msg(MSG_DUTY);
  }
}

void  set_xck(UBYTE x)
{
  /* impress signal */
  if ( x ) { PORTA |=  (1 << XCK) ; }
  else     { PORTA &= ~(1 << XCK) ; }
}

void  set_sin(UBYTE x)
{
  if ( x ) { PORTA |=  (1 << SIN) ; }
  else     { PORTA &= ~(1 << SIN) ; }
}

void  reset_cam(void)
{
  /* impress XCK:L */
  set_xck(OFF) ;
  /* impress RST:L */
  PORTA &= ~(1 << RST) ;
  /* impress XCK:H */
  set_xck(ON) ;
  /* impress RST:H */
  PORTA |=  (1 << RST) ;
  /* impress XCK:L */
  set_xck(OFF) ;
}

void  send_cam(UWORD x)
{
  UBYTE i ;
  UWORD tmp ;
  /* get data */
  tmp = x ;
  /* default */
  set_xck(OFF) ;
  set_sin(OFF);
  PORTA &= ~(1 << LOAD);
  /* send address */
  for ( i = 0 ; i < 3 ; i++ ) {
    /* impress data bit */
    set_sin(OFF);
    if ( tmp & 0x400 ) { set_sin(ON); }
    /* impress XCK:H */
    set_xck(ON) ;
    /* shift */
    tmp <<= 1 ;
    /* impress XCK:L */
    set_xck(OFF) ;
  }
  /* get data */
  tmp = x ;
  /* send data */
  for ( i = 0 ; i < 8 ; i++ ) {
    /* impress LOAD bit */
    if ( i == 7 ) { PORTA |= (1 << LOAD); }
    /* impress data bit */
    set_sin(OFF);
    if ( x & MASK80 ) { set_sin(ON); }
    /* impress XCK:H */
    set_xck(ON) ;
    /* shift */
    x <<= 1 ;
    /* impress XCK:L */
    set_xck(OFF) ;
  }
  PORTA &= ~(1 << LOAD);
  set_sin(OFF);
}

void  send_start(void)
{
  /* impress XCK:L */
  set_xck(OFF) ;
  /* impress STARST:H */
  PORTA |=  (1 << START) ;
  /* impress XCK:H */
  set_xck(ON) ;
  /* impress RST:L */
  PORTA &= ~(1 << START) ;
  /* impress XCK:L */
  set_xck(OFF) ;
}
  
volatile  UWORD img_cnt ;

void  get_img(UBYTE x)
{
  UWORD result ;
  UBYTE tmp ;
  UWORD max ;
  UWORD min ;
  /* debug */
  if ( DFLAG ) { send_uart_msg(MSG_ST) ; }
  /* send start */
  send_start();
  /* debug */
  if ( DFLAG ) { send_uart_msg(MSG_GI) ; }
  /* READ data and show*/
  img_cnt = 0 ;
  max = 0 ;
  min = 0 ;
  while ( img_cnt < MAX_SIZE ) {
    /* impress XCK:H */
    set_xck(ON);
    /* impress XCK:L */
    set_xck(OFF) ;
    /* judge */
    tmp = PINA ;
    if ( DFLAG ) { binary_display(tmp) ; }
    if ( tmp & 2 ) {
      /* start conversion */
      start_adc() ; 
      /* wait */
      wai_adc() ;
      /* get data */
      result = (ADCH << 8) | ADCL ;
      result >>= 2 ;
      /* threshold */
      if ( x == ON ) {
        max += result ;
        min += result ;
      }
      /* uart handling */
      if ( x == OFF ) {
        /* show */
        show_value( result );
        /* new line */
        if ( (img_cnt % 16) == 15 ) { crlf() ; }
      }
      /* increment */
     img_cnt++ ;
    }
  }
  /* debug threshold */
  if ( DFLAG ) { send_uart_msg(MSG_CP) ; }
  /* calculate */
  if ( x == ON ) {
    max >>= 2 ;
    min >>= 2 ;
    threshold = (UBYTE)((max+min) >> 1) ;
  }
}

void  send_default(void)
{
  send_cam((0 << 8) | 0x80);
  /* exposure */
  send_cam((1 << 8) | 0x00);
  /* exposure time change this to adjust picture light */  
  send_cam((2 << 8) | 0x00);
  send_cam((3 << 8) | 0x80);
  send_cam((4 << 8) | 0x00);
  send_cam((5 << 8) | 0x01);
  send_cam((6 << 8) | 0x00);
  send_cam((7 << 8) | 0x01);
}

void start_adc(void)
{
  ADCSR |= (1 << ADSC) ; 
}

void  wai_adc(void)
{
  while ( (ADCSR & (1 << ADSC)) )  ;
}

void  show_value(UWORD x)
{
  UWORD tmp ;
  UBYTE val[4] ;
  /* store */
  tmp = x ;
  /* separate */
  *(val+0) = tmp / 1000 + '0' ; tmp %= 1000 ;
  *(val+1) = tmp / 100  + '0' ; tmp %= 100  ;
  *(val+2) = tmp / 10   + '0' ;
  *(val+3) = tmp % 10   + '0' ;
  /* show */
  uart_putchar( *(val+0) );  
  uart_putchar( *(val+1) );
  uart_putchar( *(val+2) );
  uart_putchar( *(val+3) );
  /* send space */
  uart_putchar(' ');
}

void send_uart_msg(UBYTE x)
{
  char  msg[20] ;
  /* set message */
  switch (x) {
    case MSG_HELP     : strcpy_P(msg,msg_h) ; break ;
    case MSG_RESET    : strcpy_P(msg,msg_c) ; break ;
    case MSG_REGISTER : strcpy_P(msg,msg_r) ; break ;
    case MSG_IMAGE    : strcpy_P(msg,msg_g) ; break ;
    case MSG_DEFAULT  : strcpy_P(msg,msg_s) ; break ;
    case MSG_DEBUG    : strcpy_P(msg,msg_d) ; break ;
    case MSG_PULSE    : strcpy_P(msg,msg_p) ; break ;
    case MSG_ST       : strcpy_P(msg,msg_st); break ;
    case MSG_GI       : strcpy_P(msg,msg_gi); break ;
    case MSG_CP       : strcpy_P(msg,msg_cp); break ;
    case MSG_DUTY     : strcpy_P(msg,msg_sp); break ;
  }
  /* send */
  uart_puts((UBYTE *)msg );
}

void  rotate(UBYTE dx,UBYTE px)
{
  *(direction+0) = dx ;
  *(duty+0) = px ;
}

void  set_speed(UBYTE x)
{
  *(direction+1) = 2 ;
  *(duty+1) = x ;
}

void  set_led_duty(UBYTE x)
{
  *(duty+2) = x ;
}

void  blind_run(void)
{
  /* slow */
  set_speed(10);
  delay_ms(1000);
  /* mid */
  set_speed(20);
  delay_ms(1000);
  /* top */
  set_speed(30);
  delay_ms(1000);
}

void  mcr_run(void)
{
  UBYTE sensor_data ;
  UBYTE dir ;
  /* default direction */
  dir = 0 ;
  lane = 0 ;
  /* get sensor data */
  sensor_data = *(sdat+63);
  /* state machine */
  switch ( state ) {
    case 0 : /* judge */
      state = 0 ;
      if ( sensor_data == ALL_WHITE    ) { state = 100 ; }
      if ( sensor_data == LEFT_WHITE   ) { state = 200 ; lane = LANE_LEFT ; }
      if ( sensor_data == RIGHT_WHITE  ) { state = 200 ; lane = LANE_RIGHT; }
      if ( sensor_data == CENTER       ) { state =  10 ; }
      if ( sensor_data == LITTLE_LEFT  ) { state =  20 ; }
      if ( sensor_data == LEFT         ) { state =  30 ; }
      if ( sensor_data == BIG_LEFT     ) { state =  40 ; }
      if ( sensor_data == LITTLE_RIGHT ) { state =  50 ; }
      if ( sensor_data == RIGHT        ) { state =  60 ; }
      if ( sensor_data == BIG_RIGHT    ) { state =  70 ; }
      break ;
    /* CENTER */
    case 10 :
      state = 80 ;
      set_speed(20);
      break ;
    /* LITTLE_LEFT (move center) */
    case 20 :
      state = 80 ;
      set_speed(10); rotate(1, 5);
      break ;
    /* LEFT (move center) */
    case 30 : 
      state = 80 ;
      set_speed(10); rotate(1,10);
      break ;
    /* BIG_LEFT (move center) */
    case 40 :
      state = 80 ;
      set_speed(10); rotate(1,15);
      break ;
    /* LITTLE_RIGHT (move center) */
    case 50 :
      state = 80 ;
      set_speed(10); rotate(2, 5);
      break ;
    /* RIGHT (move center) */
    case 60 :
      state = 80 ;
      set_speed(10); rotate(2,10);
      break ;
    /* BIG_RIGHT (move center) */
    case 70 :
      state = 80 ;
      set_speed(10); rotate(2,15);
      break ;
    /* delay */
    case 80 :
      state = 90 ;
      delay_ms(1000) ;
      break ;
    /* return */
    case 90 :
      state = 0 ;
      set_speed(20); rotate(0,0);
      break ;
    /* CRANK */
    case 100 : /* slow move */
      state = 100 ;
      set_speed(10); rotate(0,0);
      delay_ms(1000);
	  if ( sensor_data == CRANK_RIGHT ) { state = 110 ; dir = 1 ; }
      if ( sensor_data == CRANK_LEFT  ) { state = 110 ; dir = 2 ; }
      break ;
    case 110 : /* rotate */
      state = 120 ;
	  set_speed(5); rotate(dir,10);
      delay_ms(3000);
      break ;
    case 120 : /* rotate right (bit by bit) */
      state = 120 ;
      if ( sensor_data == CENTER ) { state = 130 ; }
      else { rotate(dir,5) ; delay_ms(100); }
      break ;
    case 130 : /* slow move */
      state = 140 ;
      set_speed(10); rotate(0,0);
      delay_ms(1000);
      break ;
    case 150 : /* return */
      state = 0 ;
      set_speed(20); rotate(0,0);
      break ;
    /* LANE */
    case 200 : /* slow move */
      state = 200 ;
      set_speed(10); rotate(0,0);
      delay_ms(1000);
      if ( sensor_data == ALL_BLACK ) {
        state  = 210 ; 
        dir = 1 ;
        if ( lane == LANE_LEFT ) { dir = 2 ; }
      }
      break ;
    case 210 : /* rotate */
      state = 220 ;
      set_speed(5); rotate(dir,10);
      delay_ms(1000);
      break ;
    case 220 : /* move */
      state = 220 ;
      rotate(0,0);
      if ( sensor_data == CENTER ) { state = 230 ; }
      else {
	    set_speed(10);
        delay_ms(1000);
      }
      break ;
    case 230 : /* roate (reverse) */
      state = 240 ;
	  if ( dir == 1 ) { dir = 2 ; }
      else             { dir = 1 ; }
	  set_speed(5); rotate(dir,10);		
	  delay_ms(1000);
      break ;
    case 240 : /* slow move */
      state = 250 ;
      set_speed(10); rotate(0,0);
      delay_ms(1000);
      break ;
    case 250 : /* return */
      state = 0 ;
      set_speed(20);
      break ;
  }
  /* */
  get_sensor() ;
}

void  get_sensor(void)
{
  UWORD result  ;
  UBYTE index ;
  UBYTE res ;
  UBYTE i ;
  UBYTE sensor ;
  UBYTE avr ;
  /* send start */
  send_start();
  /* READ data and show*/
  img_cnt = 0 ;
  index = 0 ;
  i = 0 ;
  res = 0 ;
  while ( img_cnt < MAX_SIZE ) {
    /* impress XCK:H */
    set_xck(ON);
    /* impress XCK:L */
    set_xck(OFF) ;
    /* judge */
    if ( PINA & 2 ) {
      /* start conversion */
      start_adc() ; 
      /* wait */
      wai_adc() ;
      /* get data */
      result = (ADCH << 8) + ADCL ;
      result >>= 2 ;
      /* judge */
      if ( result > threshold ) { res++ ; }
      /* generate line code */
      if ( (img_cnt % 16) == 15 ) {
        *(rdat+index) = res ;
        res = 0 ;
        index++ ;
        index %= 8 ;
      }
      /* generate sensor data */
      if ( (img_cnt % 128) == 127 ) {
        /* average */
        avr = 0 ;
        avr += *(rdat+0) ; avr += *(rdat+1) ;
        avr += *(rdat+2) ; avr += *(rdat+3) ;
        avr += *(rdat+4) ; avr += *(rdat+5) ;
        avr += *(rdat+6) ; avr += *(rdat+7) ;
        avr >>= 3 ;
        /* compare */
        sensor = 0 ;
        if ( *(rdat+0) > avr ) { sensor |= 0x80 ; }
        if ( *(rdat+1) > avr ) { sensor |= 0x40 ; }
        if ( *(rdat+2) > avr ) { sensor |= 0x20 ; }
        if ( *(rdat+3) > avr ) { sensor |= 0x10 ; }
        if ( *(rdat+4) > avr ) { sensor |= 0x08 ; }
        if ( *(rdat+5) > avr ) { sensor |= 0x04 ; }
        if ( *(rdat+6) > avr ) { sensor |= 0x02 ; }
        if ( *(rdat+7) > avr ) { sensor |= 0x01 ; }
        /* store */
        *(sdat+i) = sensor ;
        /* increment */
        i++ ;
      }
      /* increment */
      img_cnt++ ;
    }
  }
}

UBYTE is_center(UWORD x)
{
  if ( x == 8127 ) return ON ; /* 128*63+63 */
  if ( x == 8128 ) return ON ; /* 128*63+64 */
  if ( x == 8255 ) return ON ; /* 128*64+63 */
  if ( x == 8256 ) return ON ; /* 128*64+64 */
  return OFF ;
}

UBYTE is_edge(UWORD x)
{
  if ( x == 8064 ) return ON ; /* 128*63     */
  if ( x == 8191 ) return ON ; /* 128*63+127 */
  if ( x == 8192 ) return ON ; /* 128*64     */
  if ( x == 8319 ) return ON ; /* 128*64+127 */
  return OFF ;
}

void  binary_display(UBYTE x)
{
  int i ;
  for ( i = 7 ; i > -1 ; i-- ) {
    uart_putchar('0'+((x >> i) & 1));
  }
  crlf();
}

目次

inserted by FC2 system