LoginSignup
1
1

More than 3 years have passed since last update.

GR-ADZUKIでカムロボをリモコンで動かしてみよう

Last updated at Posted at 2019-05-04

GR-ADZUKIをIRリモコンを動かしてみましょう。

GR-CITRUSとロボット覚醒プロジェクト第一弾
http://gadget.renesas.com/ja/product/cotton_sp9.html
http://gadget.renesas.com/ja/project/robot_s2/
を組み合わせています。

リモコンと受光部はAliexpressで100円以下(送料込み)で買えます。

まずは、Cottonのコードで入れてリモコンのコードを調べてみましょう
http://gadget.renesas.com/ja/product/cotton_sp9.html
・リモコンのボタンに応じてLEDを光らせる。
のプログラムをそのまま使用します。
赤外線受光部は、2番ピンにさします。

今回リモコンのコードを調べたところ以下の通りでした。

↑:46
←:44
→:43
OK:40
下:15

1:16
2:19
3:D
4:C
5:18
6:5E
7:8
8:1C
9:5A
0:42
*:52
#:4A

下記のコードは手持ちのリモコンを基にしていますので、ご自身のリモコンに合わせて書き換えます。
今回は、リモコンのボタンを押すと前進したり、後退したりさせようと思います。
サンプルコードから

      case 0xD8: // POWER BUTTON
        digitalWrite(22, LOW);
        delay(100);
        digitalWrite(22, HIGH);
        break;

とあるところを書き換えます。
例えば

前進:
        analogWrite(6, data);
        analogWrite(11, 0);
        analogWrite(9, data);
        analogWrite(10, 0);

dataに数値を入れれば指定速度で前進します。
これは、モータードライバーから各ピンに電気を出力するプログラムになります。
dataの数値を変えることでスピードが変わるので試してみてください。
さらに、この(6,11)(9,10)の組み合わせで前進、旋回、後退が可能になります。
まずは、ここを変えて動かしてみましょう。

次にCottonのサンプルをもとに

      case 0x46: // UP_Button
        analogWrite(6, 200);
        analogWrite(11, 0);
        analogWrite(9, 200);
        analogWrite(10, 0);
        break;

とします。
case xx;とは、xxと入力があった際に、次のことをしなさいとなります。
今回は、↑ボタンである0x46が入力されたら、前進しなさいとなります。
なお、case文は「break;」を入れないと次の入力を受け付けませんので必ず入れてください。

今回は、これをさらに、関数化します。

void xxx(){
プログラム
}

入れてみると

void up_move()  //UP
{
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
    analogWrite(9, 200);
    analogWrite(10, 0);
    analogWrite(6, 200);
    analogWrite(11, 0);
  }

となります。

up_move();と入れると、前進するプログラムを呼び出すようになります
これをさらに弄ると一定回前進して、後退するというプログラムも書くことが可能です。

#include <Arduino.h>

#define IR_PIN 2
#define IR_INTERRUPT 0
#define LED1 22
#define LED2 23
#define LED3 24
#define LED4 12
#define LED5 13

#define FORWARD   0
#define BACKWARD  1
#define RIGHT_MOTOR 200
#define LEFT_MOTOR  250
#define RIGHT_TH  1500
#define LEFT_TH   1500

uint8_t g_ir_data = 0;
bool    g_ir_available = false;

void ir_receive_interrupt();
void ir_receive_start();
uint8_t ir_getData();
bool ir_available();
double IRread ;

void motor1_init(){
  analogWrite(9, 0);
  analogWrite(10, 0);
}

void motor2_init(){
  analogWrite(6, 0);
  analogWrite(11, 0);
}

void up_move()  //UP
{
 // if (IRread<400)
 // {  
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
    analogWrite(9, 200);
    analogWrite(10, 0);
    analogWrite(6, 200);
    analogWrite(11, 0);
/*  }
  else
  {  
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
    analogWrite(9, 0);
    analogWrite(10, 0);
    analogWrite(6, 0);
    analogWrite(11, 0);
  }
*/
}
void left_move()  //left
{
  digitalWrite(LED4, LOW);
  digitalWrite(LED5, HIGH);
  analogWrite(9, 200);
  analogWrite(10, 0);
  analogWrite(6, 0);
  analogWrite(11, 0);
} 

void right_move()  //right
{
  digitalWrite(LED4, HIGH);
  digitalWrite(LED5, LOW);

  analogWrite(9, 0);
  analogWrite(10, 0);
  analogWrite(6, 200);
  analogWrite(11, 0);
} 

void back_move()  //back
{
  digitalWrite(LED4, HIGH);
  digitalWrite(LED5, LOW);
  analogWrite(9, 0);
  analogWrite(10, 200);
  analogWrite(6, 0);
  analogWrite(11, 200);
} 

void stop_move()  //back
{
  digitalWrite(LED4, HIGH);
  digitalWrite(LED5, LOW);
  analogWrite(9, 0);
  analogWrite(10, 0);
  analogWrite(6, 0);
  analogWrite(11, 0);
} 

void setup() {
  setPowerManagementMode(PM_STOP_MODE);
  Serial.begin(9600);
  pinMode(IR_PIN, INPUT_PULLUP);
  ir_receive_start();
  digitalWrite(LED1, HIGH);
  digitalWrite(LED2, HIGH);
  digitalWrite(LED3, HIGH);
  digitalWrite(LED4, LOW);
  digitalWrite(LED5, LOW);
  motor1_init();
  motor2_init();
  IRread=0;
}

void loop() {
  ir_receive_start();
  delay(0xFFFFFFFF); // hold STOP mode until receiving IR signal.

  if(ir_available()){
    IRread = analogRead(A0);
    Serial.println(IRread) ;       // 距離(ln有りで改行、無しで改行なし)
    Serial.println(ir_getData(), HEX);
    Serial.flush();
    int i;
    switch (ir_getData()) {
    case 0x46: // UP BUTTON   
      up_move();
      break;
    case 0x44: // Left BUTTON
      left_move();
      break;
    case 0x43: // Right BUTTON
      right_move();
      break;
    case 0x15: // BACK BUTTON
      back_move();
      break;
    case 0x40: // STOP
      motor1_init();
      motor2_init();

    default:
      break;
    }
  }   
}

/************ IR utility function ***************/
void ir_receive_interrupt(){

  unsigned long last_time;

  detachInterrupt(IR_INTERRUPT);
  last_time = micros();

  // confirm if reader code is correct
  uint8_t err = 0;
  while(!digitalRead(IR_PIN)){ // until change from low to high
    if((micros() - last_time) > 10000){ // interval low should be 9ms or less 
      err = true;
      break;
    }
  }
  while(digitalRead(IR_PIN)){ // until change from high to low
    if((micros() - last_time) > 15000){ // interval of reader code should be 13.5ms or less
      err = true;
      break;
    }
  }
  if(((micros() - last_time) < 13000) || (err == true)){ // Unknown code
    attachInterrupt(0, ir_receive_interrupt, FALLING);
    g_ir_available = false;
    return; // not available remote controller
  }

  // get data
  uint8_t receive_count = 0;
  uint8_t temp_ir_data[4] = {
    0                        };
  g_ir_data = 0;
  last_time = micros();
  while((32 > receive_count) && ((micros() - last_time) < 80000)){
    // interval of a frame data should be 76.5ms or less
    last_time = micros();
    while(!digitalRead(IR_PIN) && ((micros() - last_time) < 1000)){
      // interval of low state is about 0.56ms. 
    }
    while(digitalRead(IR_PIN) && ((micros() - last_time) < 2500)){
      // interval of a bit is between 1.125ms and 2.25ms
    }
    if((micros() - last_time) > 1500){
      bitSet(temp_ir_data[receive_count / 8], receive_count % 8);
    }
    receive_count++;
  }

  if(temp_ir_data[2] == (uint8_t)~temp_ir_data[3]){
    g_ir_data = temp_ir_data[2]; // set actual data
    g_ir_available = true;
  }

}

void ir_receive_start(){
  attachInterrupt(IR_INTERRUPT, ir_receive_interrupt, FALLING);
}

uint8_t ir_getData(){
  g_ir_available = false;
  return g_ir_data;
}

bool ir_available(){
  return g_ir_available;
}

カムロボットに入れたものです。
cumrobot-GR-Adzuki-1.jpg
cumrobot-GR-Adzuki-2.jpg

サヌキテックネットさんの「9-2.カムプログラムロボットの制御 - (2)組み立てる前に」を参考にしてください。
https://sanuki-tech.net/micro-bit/tamiya/before-assembly-cam-program-robot/
私は、読まないでやったために余計な部品を取り付けており、正直失敗しました。
カムロボットとして使わない場合は、この通りに組むことをお勧めします。

近接センサーと、赤外線受光部は、両面テープで取り付けています。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1