LoginSignup
yoshi_arduino
@yoshi_arduino

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Arduino「IRremote.hpp」ライブラリを使用してラジコンを動かしたい

解決したいこと

Freenoveのラジコンキットをつかい、IRリモコンでラジコンを操作したいです。
https://amzn.asia/d/ghOXhW0

発生している問題・エラー

サンプルファイルだとエラーはないが、動作しない
*発生している問題・エラー参照
シリアルモニタにてどのリモコンのボタンを押しても「FFFFFFF」と表示される

該当するソースコード

IR_Remote_Car.ino

/**********************************************************************
* Filename    : IR_Remote_Car.ino
* Product     : Freenove 4WD Car for UNO
* Description : An IR-Remote Car.
* Auther      : www.freenove.com
* Modification: 2019/08/06
**********************************************************************/
#include <IRremote.h>
#include "Freenove_4WD_Car_for_Arduino.h"

//define key, the code can not be changed.
#define IR_REMOTE_KEYCODE_UP      0xFF02FD
#define IR_REMOTE_KEYCODE_DOWN    0xFF9867
#define IR_REMOTE_KEYCODE_LEFT    0xFFE01F
#define IR_REMOTE_KEYCODE_RIGHT   0xFF906F
#define IR_REMOTE_KEYCODE_CENTER  0xFFA857

#define IR_UPDATE_TIMEOUT     120
#define IR_CAR_SPEED          180

IRrecv irrecv(PIN_IRREMOTE_RECV);
decode_results results;
u32 currentKeyCode, lastKeyCode;
bool isStopFromIR = false;
u32 lastIRUpdateTime = 0;

void setup() {
  irrecv.enableIRIn(); // Start the receiver
}

void loop() {
  if (irrecv.decode(&results)) {
    isStopFromIR = false;
    currentKeyCode = results.value;
    if (currentKeyCode != 0xFFFFFFFF) {
      lastKeyCode = currentKeyCode;
    }
    switch (lastKeyCode) {
      case IR_REMOTE_KEYCODE_UP:
        motorRun(IR_CAR_SPEED, IR_CAR_SPEED); //move forward
        break;
      case IR_REMOTE_KEYCODE_DOWN:
        motorRun(-IR_CAR_SPEED, -IR_CAR_SPEED); //move back
        break;
      case IR_REMOTE_KEYCODE_LEFT:
        motorRun(-IR_CAR_SPEED, IR_CAR_SPEED);  //turn left
        break;
      case IR_REMOTE_KEYCODE_RIGHT:
        motorRun(IR_CAR_SPEED, -IR_CAR_SPEED);  //turn right
        break;
      case IR_REMOTE_KEYCODE_CENTER:
        setBuzzer(true);              //turn on buzzer
        break;
      default:
        break;
    }
    irrecv.resume(); // Receive the next value
    lastIRUpdateTime = millis(); //write down current time
  }
  else {
    if (millis() - lastIRUpdateTime > IR_UPDATE_TIMEOUT) {
      if (!isStopFromIR) {
        isStopFromIR = true;
        motorRun(0, 0);
        setBuzzer(false);
      }
      lastIRUpdateTime = millis();
    }
  }
}
Freenove_4WD_Car_for_Arduino.cpp
#include "Freenove_4WD_Car_for_Arduino.h"

float batteryVoltage = 0;
bool isBuzzered = false;

void pinsSetup() {
	pinMode(PIN_DIRECTION_LEFT, OUTPUT);
	pinMode(PIN_MOTOR_PWM_LEFT, OUTPUT);
	pinMode(PIN_DIRECTION_RIGHT, OUTPUT);
	pinMode(PIN_MOTOR_PWM_RIGHT, OUTPUT);

	pinMode(PIN_SONIC_TRIG, OUTPUT);// set trigPin to output mode
	pinMode(PIN_SONIC_ECHO, INPUT); // set echoPin to input mode

	pinMode(PIN_TRACKING_LEFT, INPUT); // 
	pinMode(PIN_TRACKING_RIGHT, INPUT); // 
	pinMode(PIN_TRACKING_CENTER, INPUT); // 

	setBuzzer(false);
}

void motorRun(int speedl, int speedr) {
	int dirL = 0, dirR = 0;
  if (speedl > 0) {
    dirL = 0 ^ MOTOR_DIRECTION;
  } else {
    dirL = 1 ^ MOTOR_DIRECTION;
    speedl = -speedl;
  }

  if (speedr > 0) {
    dirR = 1 ^ MOTOR_DIRECTION;
  } else {
    dirR = 0 ^ MOTOR_DIRECTION;
    speedr = -speedr;
  }

	speedl = constrain(speedl, 0, 255);
	speedr = constrain(speedr, 0, 255);

	if (abs(speedl) < MOTOR_PWM_DEAD && abs(speedr) < MOTOR_PWM_DEAD) {
		speedl = 0;
		speedr = 0;
	}
	digitalWrite(PIN_DIRECTION_LEFT, dirL);
	digitalWrite(PIN_DIRECTION_RIGHT, dirR);
	analogWrite(PIN_MOTOR_PWM_LEFT, speedl);
	analogWrite(PIN_MOTOR_PWM_RIGHT, speedr);
}


bool getBatteryVoltage() {
	if (!isBuzzered) {
		pinMode(PIN_BATTERY, INPUT);
		int batteryADC = analogRead(PIN_BATTERY);
		if (batteryADC < 614)		// 3V/12V ,Voltage read: <2.1V/8.4V
		{
			batteryVoltage = batteryADC / 1023.0 * 5.0 * 4;
			return true;
		}
	}
	return false;
}
void setBuzzer(bool flag) {
	isBuzzered = flag;
	pinMode(PIN_BUZZER, flag);
	digitalWrite(PIN_BUZZER, flag);
}
void alarm(u8 beat, u8 repeat) {
	beat = constrain(beat, 1, 9);
	repeat = constrain(repeat, 1, 255);
	for (int j = 0; j < repeat; j++) {
		for (int i = 0; i < beat; i++) {
			setBuzzer(true);
			delay(100);
			setBuzzer(false);
			delay(100);
		}
		delay(500);
	}
}
void resetCarAction() {
	motorRun(0, 0);
	setBuzzer(false);
}

Freenove_4WD_Car_for_Arduino.h
// Freenove_4WD_Car_for_Arduino.h

#ifndef _FREENOVE_4WD_CAR_FOR_ARDUINO_h
#define _FREENOVE_4WD_CAR_FOR_ARDUINO_h

#if defined(ARDUINO) && ARDUINO >= 100
	#include "Arduino.h"
#else
	#include "WProgram.h"
#endif

#define PIN_SERVO			2

#define MOTOR_DIRECTION     0 //If the direction is reversed, change 0 to 1
#define PIN_DIRECTION_LEFT	4
#define PIN_DIRECTION_RIGHT	3
#define PIN_MOTOR_PWM_LEFT	6
#define PIN_MOTOR_PWM_RIGHT	5

#define PIN_SONIC_TRIG		7
#define	PIN_SONIC_ECHO		8

#define PIN_IRREMOTE_RECV	9

#define PIN_SPI_CE			9
#define PIN_SPI_CSN			10
#define PIN_SPI_MOSI		11
#define PIN_SPI_MISO		12
#define PIN_SPI_SCK			13

#define PIN_BATTERY			A0
#define PIN_BUZZER			A0

#define PIN_TRACKING_LEFT	A1
#define PIN_TRACKING_CENTER	A2
#define PIN_TRACKING_RIGHT	A3
#define MOTOR_PWM_DEAD		5

#define BAT_VOL_STANDARD	7.0

extern float batteryVoltage;

void pinsSetup();
void motorRun(int speedl, int speedr);

bool getBatteryVoltage();
void setBuzzer(bool flag);
void alarm(u8 beat, u8 repeat);
void resetCarAction();

#endif

自分で試したこと

そこで一度拡張ボードやモーターを取り外して、
①arduinoUno
②ジャンパーワイヤー
③IRセンサー
だけを使用し、不具合の原因切り分けを行った。
センサの信号線を9番→11番につけかえて下記コードでシリアルモニタを開くと正常に反応

#include <IRremote.hpp>

void setup() {
Serial.begin(115200);
IrReceiver.begin(11,true);
}

void loop() {
if(IrReceiver.decode()){
  Serial.println(IrReceiver.decodedIRData.command,HEX);
}
IrReceiver.resume();
delay(100);
}

IRremote.hではなく、IRremote.hppをつかったコードでリモコンの信号を受信できた
そのため、IRremote.hppのライブラリを使用することでうまくいくと考えたが
、何を変えればよいか不明
下記コードで書き替えたが、コンパイルエラー

IRmotormove.ino
#include <IRremote.hpp>
#include "Freenove_4WD_Car_for_Arduino.h"

#define IR_REMOTE_KEYCODE_UP      0xFF02FD
#define IR_REMOTE_KEYCODE_DOWN    0xFF9867
#define IR_REMOTE_KEYCODE_LEFT    0xFFE01F
#define IR_REMOTE_KEYCODE_RIGHT   0xFF906F
#define IR_REMOTE_KEYCODE_CENTER  0xFFA857
#define IR_CAR_SPEED 180 // モーターの速度を180として宣言
#define IR_UPDATE_TIMEOUT 500 // IRリモコンの受信が500ミリ秒間更新されなかった場合、停止する

IRrecv irrecv(PIN_IRREMOTE_RECV);
decode_results results;
u32 currentKeyCode, lastKeyCode;
bool isStopFromIR = false;
u32 lastIRUpdateTime = 0;

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();
}

void loop() {
  if (irrecv.decode(&results)) {
    isStopFromIR = false;
    currentKeyCode = results.value;
    if (currentKeyCode != 0xFFFFFFFF) {
      lastKeyCode = currentKeyCode;
    }
    switch (lastKeyCode) {
      case IR_REMOTE_KEYCODE_UP:
        motorRun(IR_CAR_SPEED, IR_CAR_SPEED);
        break;
      case IR_REMOTE_KEYCODE_DOWN:
        motorRun(-IR_CAR_SPEED, -IR_CAR_SPEED);
        break;
      case IR_REMOTE_KEYCODE_LEFT:
        motorRun(-IR_CAR_SPEED, IR_CAR_SPEED);
        break;
      case IR_REMOTE_KEYCODE_RIGHT:
        motorRun(IR_CAR_SPEED, -IR_CAR_SPEED);
        break;
      case IR_REMOTE_KEYCODE_CENTER:
        setBuzzer(true);
        break;
      default:
        break;
    }
    irrecv.resume();
    lastIRUpdateTime = millis();
  }
  else {
    if (millis() - lastIRUpdateTime > IR_UPDATE_TIMEOUT) {
      if (!isStopFromIR) {
        isStopFromIR = true;
        motorRun(0, 0);
        setBuzzer(false);
      }
      lastIRUpdateTime = millis();
    }
  }
}
エラーメッセージ

C:\Users\kabao\AppData\Local\Temp\.arduinoIDE-unsaved2024321-15896-n5z3bt.cvmqi\sketch_apr21a\sketch_apr21a.ino:2:10: fatal error: Freenove_4WD_Car_for_Arduino.h: No such file or directory
 #include "Freenove_4WD_Car_for_Arduino.h"
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
exit status 1

Compilation error: Freenove_4WD_Car_for_Arduino.h: No such file or directory
0

2Answer

ではなく、をつかったコードを作りたいが、何を変えればよいか不明

???

プログラムコードはコードブロックを使って記載してください。
また、< はHTMLのタグの始まりのため、正しく表示されません。

書き方
```c:IR_Remote_Car.ino
#include <IRremote.h>
#include "Freenove_4WD_Car_for_Arduino.h"

(以下省略)

```

1

Comments

  1. @yoshi_arduino

    Questioner

    すみません。ライブラリは
    IRremote.hではなく
    IRremote.hppを使用して、コードを書き換えたい、という意味です。

    また、コードブロックの使い方教えて頂きありがとうございます。改めてまた質問内容修正します。

  2. IRremote.hではなく
    IRremote.hppを使用して、コードを書き換えたい、という意味です。

    それは何故でしょうか?
    IRremote.hppはIRremote.hをインクルードしており、結局は同じだと思います。
    ↑これは間違いでした。失礼しました。


    下記コードで書き替えたが、コンパイルエラー

    コンパイルエラーを含む結果全体をコードブロックに貼ってください。

  3. @yoshi_arduino

    Questioner

    ご返信が遅くなりました。
    コンパイルエラーとFREENOVE_4WD_CAR_FOR_ARDUINOライブラリを追記しています。

そこで下記コードでシリアルモニタを開くと正常に反応

IrReceiver.begin(11,true);
こちらのプログラムは、ピン番号11を使っています。そうであれば、以下のようにピン番号を変更すだけで動くかも。

PIN_IRREMOTE_RECVは9だと思います。

IR_Remote_Car.ino
- IRrecv irrecv(PIN_IRREMOTE_RECV);
+ IRrecv irrecv(11);
0

Comments

  1. @yoshi_arduino

    Questioner

    スクリーンショット 2024-04-21 091529.png
    上記画像のように、ピンアサインは9となっております。

    なお、「そこで下記コードでシリアルモニタを開くと正常に反応」
    については別に、
    拡張ボードやモーターを取り外して、arduinoUnoとジャンパーワイヤー、センサーだけを使用し、9番→11番につけかえてためしたということです。
    *「自分で試したこと」に上記内容追記

  2. 9番ピンが正しいならば、以下のスケッチを実行して、リモコンのコードを確認してみてください。シリアルのスピードは適宜変更(9600→115200)してください。

    https://github.com/Freenove/Freenove_4WD_Car_Kit/blob/master/Sketches/04.1_IR_Receiver/04.1_IR_Receiver.ino
    /**********************************************************************
      Filename    : IR_Receiver.ino
      Product     : Freenove 4WD Car for UNO
      Description : A demo of uasage of IR-Recveiver.
      Auther      : www.freenove.com
      Modification: 2019/08/06
    **********************************************************************/
    #include <IRremote.h>             // incudle IRremote library
    #define PIN_IRREMOTE_RECV  9      // Infrared receiving pin
    
    IRrecv irrecv(PIN_IRREMOTE_RECV); // Create a class object used to receive
    
    decode_results results;           // Create a decoding results class object
    
    void setup()
    {
      Serial.begin(9600);         // Initialize the serial port and set the baud rate to 9600
      irrecv.enableIRIn();        // Start the receiver
    }
    
    void loop() {
      if (irrecv.decode(&results)) {        // Waiting for decoding
        Serial.println(results.value, HEX); // Print out the decoded results
        irrecv.resume();                    // Receive the next value
      }
      delay(100);
    }
    

    これで正しく受信できるならば、<IRremote.h>の問題ではない ということです。

  3. @yoshi_arduino

    Questioner

    早急にご対応いただきありがとうございます。
    ご提示いただいたコードで試してみましたが、下記の通り、どのリモコンのボタンを押してもFFFFFFとなってしまいます。
    スクリーンショット 2024-04-21 220650.png
    シリアルの速度を変更しても同様です。
    スクリーンショット 2024-04-21 220819.png

  4. どのリモコンのボタンを押してもFFFFFFとなってしまいます。

    9番ピンにIR受信センサーが接続されているとは考えられない結果ですが、
    IR受信モジュールは、下記写真の基板でしょうか?

    ir-recv.png

    ir-car.png

    arduinoUnoとジャンパーワイヤー、センサーだけを使用し、9番→11番につけかえてためしたということです。

    この時のIRセンサーも、上記のIR受信モジュールを使用したのでしょうか?

  5. @yoshi_arduino

    Questioner

    返信遅くなりすみません。
    はい、他に別の3ピン形式のimage.png
    IRレシーバーと類似のIRリモコンにつけかえても同様の結果でした。

  6. 手持ちのIR受信モジュールで試してみましたが、確かに"FFFF"と出ますね。

    実行すると、以下のメッセージがシリアルに出力され、これを読むと、バージョン2.0のAPIはサポートされずAPIを置き換えるようにと 書いてますね。

    **************************************************************************************************
    Thank you for using the IRremote library!
    It seems, that you are using a old version 2.0 code / example.
    This version is no longer supported!
    Please use one of the new code examples from the library,
     available at "File > Examples > Examples from Custom Libraries / IRremote".
    Or downgrade your library to version 2.6.0.
    
    Start with the SimpleReceiver or SimpleSender example.
    
    The examples are documented here:
     https://github.com/Arduino-IRremote/Arduino-IRremote#examples-for-this-library
    A guide how to convert your 2.0 program is here:
     https://github.com/Arduino-IRremote/Arduino-IRremote#converting-your-2x-program-to-the-4x-version
    
    Thanks
    **************************************************************************************************
    
    
    FFFFFFFF
    FFFFFFFF
    

    APIの書き換え方が、https://github.com/Arduino-IRremote/Arduino-IRremote#converting-your-2x-program-to-the-4x-versionにあります。

    そこにある、New 4.x program はちゃんと動きました。

    #include <IRremote.hpp>
    #define IR_RECEIVE_PIN 9
    
    void setup()
    {
      Serial.begin(115200);
      IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Start the receiver
    }
    
    void loop() {
      if (IrReceiver.decode()) {
          Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); // Print "old" raw data
          IrReceiver.printIRResultShort(&Serial); // Print complete received data in one line
          IrReceiver.printIRSendUsage(&Serial);   // Print the statement required to send this data
          delay(100);
          IrReceiver.resume(); // Enable receiving of the next value
      }
    }
    
    54AB6D82
    Protocol=NEC Address=0x6D82 Command=0xAB Raw-Data=0x54AB6D82 32 bits LSB first
    Send with: IrSender.sendNEC(0x6D82, 0xAB, <numberOfRepeats>);
    43BC6D82
    Protocol=NEC Address=0x6D82 Command=0xBC Raw-Data=0x43BC6D82 32 bits LSB first
    Send with: IrSender.sendNEC(0x6D82, 0xBC, <numberOfRepeats>);
    
  7. @yoshi_arduino

    Questioner

    ご回答毎度ありがとうございます。
    ①ご指摘いただいたのは、arduinoIDEのバージョンが新しいため、本プログラムと互換性
    がないということでしょうか。
    ②対策としてはご提示いただいた
    以下の2つを参照、ということでしょうか。
    ※実機確認はあらためてします。

    IMG_8734.png

    申し訳ありません。初心者なものでAPI
    を理解しかねております。下記リンクを参照しましたが、意味合いがピンときてません。
    https://garretlab.web.fc2.com/arduino.cc/docs/learn/starting-guide/getting-started-arduino/

    お手数ですがご回答のほどよろしくお願いします。

  8. ①ご指摘いただいたのは、arduinoIDEのバージョンが新しいため、本プログラムと互換性がないということでしょうか。

    いいえ、ArduinoIDEのバージョンのことではなく、IRRemoteライブラリのバージョンのことです。

    対策は、IRRemoteライブラリの新APIに書き換えることです。これは、@yoshi_arduino さんが、最初の質問時に言われていた、『 IRremote.h ではなく、IRremote.hpp を使用して、コードを書き換えたい』そのものでした。
    自分の理解がすぐにそこに及ばず、遠回りしましたが、
    以下のコードが『IRremote.hpp を使用するように書き換えたコード』です。
    実機を持っていないので動作確認はできませんが、コンパイルできるところまでは確認済みです。-が削除行、+が追加行を表します。

      /**********************************************************************
      * Filename    : IR_Remote_Car.ino
      * Product     : Freenove 4WD Car for UNO
      * Description : An IR-Remote Car.
      * Auther      : www.freenove.com
      * Modification: 2019/08/06
      **********************************************************************/
    - #include <IRremote.h>
    + #include <IRremote.hpp>
      #include "Freenove_4WD_Car_for_Arduino.h"
      
      //define key, the code can not be changed.
      #define IR_REMOTE_KEYCODE_UP      0xFF02FD
      #define IR_REMOTE_KEYCODE_DOWN    0xFF9867
      #define IR_REMOTE_KEYCODE_LEFT    0xFFE01F
      #define IR_REMOTE_KEYCODE_RIGHT   0xFF906F
      #define IR_REMOTE_KEYCODE_CENTER  0xFFA857
      
      #define IR_UPDATE_TIMEOUT     120
      #define IR_CAR_SPEED          180
      
    - IRrecv irrecv(PIN_IRREMOTE_RECV);
    - decode_results results;
      u32 currentKeyCode, lastKeyCode;
      bool isStopFromIR = false;
      u32 lastIRUpdateTime = 0;
      
      void setup() {
    + //Serial.begin(115200); //⭐️
    -   irrecv.enableIRIn(); // Start the receiver
    +   IrReceiver.begin(PIN_IRREMOTE_RECV, ENABLE_LED_FEEDBACK); // Start the receiver
      }
      
      void loop() {
    -   if (irrecv.decode(&results)) {
    +   if (IrReceiver.decode()) {
          isStopFromIR = false;
    -     currentKeyCode = results.value;
    +     currentKeyCode = IrReceiver.decodedIRData.decodedRawData;
    +   //Serial.println(currentKeyCode, HEX); //⭐️
          if (currentKeyCode != 0xFFFFFFFF) {
            lastKeyCode = currentKeyCode;
          }
          switch (lastKeyCode) {
            case IR_REMOTE_KEYCODE_UP:
              motorRun(IR_CAR_SPEED, IR_CAR_SPEED); //move forward
              break;
            case IR_REMOTE_KEYCODE_DOWN:
              motorRun(-IR_CAR_SPEED, -IR_CAR_SPEED); //move back
              break;
            case IR_REMOTE_KEYCODE_LEFT:
              motorRun(-IR_CAR_SPEED, IR_CAR_SPEED);  //turn left
              break;
            case IR_REMOTE_KEYCODE_RIGHT:
              motorRun(IR_CAR_SPEED, -IR_CAR_SPEED);  //turn right
              break;
            case IR_REMOTE_KEYCODE_CENTER:
              setBuzzer(true);              //turn on buzzer
              break;
            default:
              break;
          }
    -     irrecv.resume(); // Receive the next value
    +     IrReceiver.resume(); // Receive the next value
          lastIRUpdateTime = millis(); //write down current time
        }
        else {
          if (millis() - lastIRUpdateTime > IR_UPDATE_TIMEOUT) {
            if (!isStopFromIR) {
              isStopFromIR = true;
              motorRun(0, 0);
              setBuzzer(false);
            }
            lastIRUpdateTime = millis();
          }
        }
      }
    

    受信データを確認する場合は、⭐️印のコメントを外してください。

  9. @yoshi_arduino

    Questioner

    誠にありがとうございます。
    上記ご指摘いただいた内容で実機確認します。
    また確認次第ご連絡します。

Your answer might help someone💌