チーム1464

課題名

ラジコンカー

研究者名

2-14-44 Tomohiro Mizukoshi
2-14-45 Satoru Murakami

概要

リモコンで操作するラジコンカー!

リモコンを操作することで動く、曲がる、止まるの動作を行える。

リモコンの操作方法
ボタンが2つあり、左右のモーターそれぞれの対応している。
何もしていないときには止まっており、
左のボタンを押せば左のタイヤが動き、
右のボタンを押すと右のタイヤが動く。

なので、
右に曲がるには右のボタンを
左に曲がるには左のボタンを
直進するには左右のボタンを
押せば動く。

使用したもの


PSoC 2つ
ジャンパー線 複数本
ボタン 2つ
モーター用ブリッジドライバ 2つ
赤外線信号送信機 1つ
赤外線信号受信器 1つ
車 1つ
電池 4本



ソースコード

送信機

ir_sender.png
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#pragma interrupt_handler myISR

#define SW_LEFT 0b00000010
#define SW_RIGHT 0b00000100
#define SW_STRAIGHT 0b00000110
#define SW_STOP 0b00000000
#define SW_SEND 0b00001000

unsigned int data[2] = {0,0};
unsigned int dataPr;
int count = 0;

void myISR(void) {
      if(count > 1) {
           count = 0;
       }
       if(data[count] == 1){
           PWM8_Start();
       } else { 
           PWM8_Stop();
       }
       count += 1;
}

void main(void) {
    PWM8_Start();
      LCD_Start();
   
   M8C_EnableGInt;
   Timer16_EnableInt();
   Timer16_Start();
   
      while(1){
           //左のボタンが押された
          if(PRT0DR & SW_LEFT){
           LCD_Position(0,0);
           LCD_PrHexInt(1);
              data[0] = 1;
              //data[1] = 0;
          }
        //右のボタンが押された
      if(PRT0DR & SW_RIGHT){
           LCD_Position(0,0);
           LCD_PrHexInt(2);
           //data[0] = 0;
           data[1] = 1;
       }
               
       if(!(PRT0DR & SW_LEFT) && !(PRT0DR & SW_RIGHT)){
           data[0] = 0;
           data[1] = 0;
       }
   
      }
}

受信機

block1464.png

/*データの受信を行いモータの動作を制御する*/

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#pragma interrupt_handler receive
#define SW 0b00010000
#define left 0b00000001
#define right 0b00000100

int RC = 0; //受信ビット数のカウント
static int rv=0b00; //受信したものを記憶していく
int mode = 0; //受信中かどうかを判定する

int data[2] = {0,0};
int count = 0;

void receive(void){
  if(count > 1) {
       count = 0;
   }
   if(PRT1DR & SW){
       data[count] = 0;
   } else { 
       data[count] = 1;
   }
   count += 1;
}


void main(void)
{
  int flg=1, dataPr = 0, i;
   LCD_Start();
       LCD_InitBG(LCD_SOLID_BG);
   PGA_Start(PGA_HIGHPOWER);
   M8C_EnableGInt;
   Timer16_EnableInt();
   PRT1DR &= (~SW); 

 while(1){

     if(PRT1DR & SW){
       LCD_Position(1,0);
       LCD_PrHexInt(0);
       PRT1DR &=(~right);
          PRT1DR &=(~left);
      } else if(flg){
       //タイマーを動かしデータの受信を行う
       Timer16_Start();
       LCD_Position(1,0);
     LCD_PrHexInt(1);
     flg=0;
      }
      // 受信が終了したら以下のif文の動作を行う
      
      // 受信内容が11であったら左右のモーターへの出力を1にする
          if(data[0] == 1 && data[1] == 1){
           PRT1DR |= left;
           PRT1DR |= right;
       }
      
      // 受信内容が10であったら左のモーターへの出力を1,右のモーターは0
          else if(data[0] == 1 && data[1] == 0){
           PRT1DR |= left;
           PRT1DR &=(~right);
       }
       
    // 受信内容が01であったら右のモーターへの出力を1,左のモーターは0
           else if(data[0] == 0 && data[1] == 1){
           PRT1DR &=(~left);
           PRT1DR |= right;
       }
       
    // 受信内容が00であったら左右のモーターへの出力は0
       else if(data[0] == 0 && data[1] == 0){
           PRT1DR &=(~left);
           PRT1DR &=(~right);
       }
     // 受信したものをLCDに表示する
      for(i = 1; i > -1; i--) {
           dataPr <<= 4;
           dataPr += data[i];
       }
       LCD_Position(0,0);
       LCD_PrHexInt(dataPr);
       dataPr = 0;
      }
  
}

考察


今回使用した赤外線送信機は1bitの情報しか送ることができない。なので1bitの情報を
2回送ることで2bitの情報を送信しているが、これを1つ1つの情報として認識させるのではなく
2つの情報をを1つの連続した情報として認識させる必要がある。
これを実現させるためには、ユーザー側で送る時間の間隔を合わせるという方法が考えられる。
このやり方は、1つ目の情報を送信したら、受信機で情報を解析する時間が必要なので、この間隔をユーザー側で空けてから
2つ目の情報を送信するという考えである。
ただ、仕様を知らない人にとってはうまく動作できないと思われる。

また、受信側と送信側のタイミングを合わせる必要がある。
これは、同様のタイマーでカウントすることで実現している。

  • 最終更新:2015-07-06 17:16:53

このWIKIを編集するにはパスワード入力が必要です

認証パスワード