PICで二足歩行ロボットに挑戦

二足歩行ロボット製作超入門(浅草ギ研-著)と言う本に、BTC067(AVRマイコンボード)を使用したRCサーボを4個だけ で作る二足歩行ロボットが載っていた。そこでBTC067の代わりにPIC16F88を使って二足歩行ロボットを作ってみた。

正面
二足歩行ロボット正面
左側面
二足歩行ロボット左側面
背面
二足歩行ロボット背面
右側面
二足歩行ロボット右側面

二足歩行(MPEG1ムービー)

ハードウェアの作り方

RCサーボは手持ちのFutabaのS3001を使用しましたので、本の付録の型紙がそのまま使えず修正して使いました。 サーボの電源はラジコン用の4.8Vのニッカドバッテリーを使いました。サーボ#0の信号線をPICのRB0にサーボ#1の信号線をPICのRB1に サーボ#2の信号線をPICのRB2にサーボ#3の信号線をPICのRB3に接続します。

制御ソフトウェアの作り方

このプログラムは5msごとにピンを切替えパルスを立ち上げ順番に4個のサーボを駆動します。 5msごとにパルスを立ち上げる部分はタイマーと割込みを使って作りましたが、かなりてこずりました。

直進歩行プログラム

BTC067用のCプログラムを参考にしてPIC16F88用に書いたものです。このプログラムはフリーソフトのmikroCで作製しました。RSサーボS3001は実際に動作させたところ中点が1.3ms、カウント数80だったので初期値は80にしました。

/*********   four Servo controle test   *********************/

/*-----------------Global variable--------------------------*/
char phase=0;
unsigned char ServoPos[4]={80,80,80,80};
unsigned char HomePos[4]={78,80,80,80};
unsigned long int count;
/*----------------interrupt function------------------------*/
void interrupt()
{
//timer2 interrupt
 if (PIR1.TMR2IF){
    if (PR2==ServoPos[phase]){
      PORTB &=~((1<<0)|(1<<1)|(1<<2)|(1<<3)); /* portb0-3 low */
      T2CON.TMR2ON=0; /*timer2 stop */
      PIR1.TMR2IF=0;
      TMR1L=0;
      TMR1H=0;
      phase++;
      T1CON.TMR1ON=1; /*timer1 enable */
     }
     else {
      PORTB |=(1<3){
	phase=0;
	}
     }
   }
 //timer1 interrupt
 else if (PIR1.CCP1IF){ /* timer 1 compare match */
      T1CON.TMR1ON=0; /*timer1 stop */
      PIR1.CCP1IF=0;
      PR2=188-ServoPos[phase];
      TMR2=0;
      T2CON.TMR2ON=1; /*timer2 enable */
 }
}
/*----------wait_ms function-------------------------------*/
void wait_ms(unsigned long int msec)
{
 msec=93*msec;
 for (count=0; count<msec; count++){;}
}
/***********************************************************/
void main(void)
{
 OSCCON=0b01111110; /* Intermal RC Oscillator 8MHz */
 wait_ms(3000);
 ANSEL=0b00000000;
 TRISB=0;
 PORTB=0;
 PORTB &=~((1<<0)|(1<<1)|(1<<2)|(1<<3)); /* portb0-3 low */
//timer2 init -----------------------------------------------
 PIR1=0b00000000; /* interrupt Flag cler */
 TMR2=0;
 PR2=ServoPos[phase];
 PIE1=0b00000110; /* tmr2 pr2 match Enable CCP1IE enable */
 T2CON=0b00001010; /* postscal 2 prescal 16 */
 //timer1 init ----------------------------------------------
 TMR1L=0;
 TMR1H=0;
 CCPR1L=0xf4; /* 2msec */
 CCPR1H=0x01;
 CCP1CON=0b00001010; /* ccp1m set*/
 T1CON=0b00110001; /* prescal 1:8 tmr1 enable */
 INTCON=0b11000000; /* GIE  PEIE enable */
 while(1)
          {
	  ServoPos[0]=HomePos[0]+0;           
	  ServoPos[1]=HomePos[1]+20;
	  ServoPos[2]=HomePos[2]+0;
	  ServoPos[3]=HomePos[3]+20;
	  wait_ms(1000);
	  ServoPos[0]=HomePos[0]+28;
	  ServoPos[1]=HomePos[1]+20;
	  ServoPos[2]=HomePos[2]+15;
	  ServoPos[3]=HomePos[3]+20;
	  wait_ms(1000);
	  ServoPos[0]=HomePos[0]+15;
	  ServoPos[1]=HomePos[1]-20;
	  ServoPos[2]=HomePos[2]+15;
	  ServoPos[3]=HomePos[3]-20;
	  wait_ms(1000);
	  ServoPos[0]=HomePos[0]+0;
	  ServoPos[1]=HomePos[1]-20;
	  ServoPos[2]=HomePos[2]+0;
	  ServoPos[3]=HomePos[3]-20;
	  wait_ms(1000);
	  ServoPos[0]=HomePos[0]-15;
	  ServoPos[1]=HomePos[1]-20;
	  ServoPos[2]=HomePos[2]-28;
	  ServoPos[3]=HomePos[3]-20;
	  wait_ms(1000);
	  ServoPos[0]=HomePos[0]-15;
	  ServoPos[1]=HomePos[1]+20;
	  ServoPos[2]=HomePos[2]-15;
	  ServoPos[3]=HomePos[3]+20;
	  wait_ms(1000);
          }
}
/*************************************************************/
直進歩行Cプログラムソース
直進歩行プログラムHEXファイル

目次へ戻る