| #include <IRremote.h> |
|
| // 各コンポーネントのピン定義 |
| const int RECV_PIN = 2; // 赤外線センサ |
| const int LED_RED_PIN = 10; // 赤色LED |
| const int LED_GREEN_PIN = 9; // 緑色LED |
| const int LED_BLUE_PIN = 8; // 青色LED |
| const int SPEAKER_PIN = 13; // スピーカー |
| const int MOTOR1_PIN_A = 6; // モータ1 |
| const int MOTOR1_PIN_B = 7; |
| const int MOTOR2_PIN_A = 4; // モータ2 |
| const int MOTOR2_PIN_B = 5; |
|
| // リモコンの各ボタンのコード(ユーザー指定のHEX値) |
| #define CODE_FORWARD 0xFF02FD |
| #define CODE_BACKWARD 0xFF9867 |
| #define CODE_RIGHT 0xFF906F |
| #define CODE_LEFT 0xFFE01F |
| #define CODE_1 0xFF30CF |
| #define CODE_2 0xFF18E7 |
| #define CODE_3 0xFF7A85 |
| #define CODE_4 0xFF10EF |
| #define CODE_5 0xFF38C7 |
| #define CODE_6 0xFF5AA5 |
| #define CODE_7 0xFF42BD |
| #define CODE_9 0xFF52AD |
|
| // IRremoteライブラリのインスタンス |
| IRrecv irrecv(RECV_PIN); |
| decode_results results; |
|
| void setup() { |
| // ピンモード設定 |
| pinMode(RECV_PIN, INPUT); |
| pinMode(LED_RED_PIN, OUTPUT); |
| pinMode(LED_GREEN_PIN, OUTPUT); |
| pinMode(LED_BLUE_PIN, OUTPUT); |
| pinMode(SPEAKER_PIN, OUTPUT); |
| pinMode(MOTOR1_PIN_A, OUTPUT); |
| pinMode(MOTOR1_PIN_B, OUTPUT); |
| pinMode(MOTOR2_PIN_A, OUTPUT); |
| pinMode(MOTOR2_PIN_B, OUTPUT); |
|
| // 赤外線受信の開始 |
| irrecv.enableIRIn(); |
| } |
|
| void loop() { |
| // 赤外線信号を受信 |
| if (irrecv.decode(&results)) { |
| // ボタンのコードを比較して動作を実行 |
| switch (results.value) { |
| case CODE_FORWARD: |
| goForward(); |
| break; |
| case CODE_BACKWARD: |
| goBackward(); |
| break; |
| case CODE_RIGHT: |
| turnRight(); |
| break; |
| case CODE_LEFT: |
| turnLeft(); |
| break; |
| case CODE_1: |
| blinkLED(LED_RED_PIN, 1000); |
| break; |
| case CODE_2: |
| blinkLED(LED_BLUE_PIN, 1000); |
| break; |
| case CODE_3: |
| blinkLED(LED_GREEN_PIN, 1000); |
| break; |
| case CODE_4: |
| blinkMultiLED(LED_RED_PIN, LED_BLUE_PIN, 1000); |
| break; |
| case CODE_5: |
| blinkMultiLED(LED_GREEN_PIN, LED_BLUE_PIN, 1000); |
| break; |
| case CODE_6: |
| blinkMultiLED(LED_GREEN_PIN, LED_RED_PIN, 1000); |
| break; |
| case CODE_7: |
| blinkAllLEDs(1000); |
| break; |
| case CODE_9: |
| resetArduino(); |
| break; |
| default: |
| // 上記以外のボタン |
| defaultAction(); |
| break; |
| } |
| // 次の信号を受信可能にする |
| irrecv.resume(); |
| } |
| } |
|
| // 1秒間前進 |
| void goForward() { |
| digitalWrite(LED_BLUE_PIN, HIGH); |
| delay(1000); |
| digitalWrite(LED_BLUE_PIN, LOW); |
| |
| digitalWrite(MOTOR1_PIN_A, HIGH); |
| digitalWrite(MOTOR1_PIN_B, LOW); |
| digitalWrite(MOTOR2_PIN_A, HIGH); |
| digitalWrite(MOTOR2_PIN_B, LOW); |
| delay(1000); |
| stopMotors(); |
| } |
|
| // 1秒間後退 |
| void goBackward() { |
| digitalWrite(LED_GREEN_PIN, HIGH); |
| delay(1000); |
| digitalWrite(LED_GREEN_PIN, LOW); |
| |
| digitalWrite(MOTOR1_PIN_A, LOW); |
| digitalWrite(MOTOR1_PIN_B, HIGH); |
| digitalWrite(MOTOR2_PIN_A, LOW); |
| digitalWrite(MOTOR2_PIN_B, HIGH); |
| delay(1000); |
| stopMotors(); |
| } |
|
| // 0.1秒右折後0.1秒前進 |
| void turnRight() { |
| digitalWrite(LED_RED_PIN, HIGH); |
| delay(100); |
| digitalWrite(LED_RED_PIN, LOW); |
| |
| // 右折(片方のモータを前進、もう一方を停止) |
| digitalWrite(MOTOR1_PIN_A, HIGH); |
| digitalWrite(MOTOR1_PIN_B, LOW); |
| digitalWrite(MOTOR2_PIN_A, LOW); |
| digitalWrite(MOTOR2_PIN_B, LOW); |
| delay(100); |
| |
| // 前進 |
| digitalWrite(MOTOR1_PIN_A, HIGH); |
| digitalWrite(MOTOR1_PIN_B, LOW); |
| digitalWrite(MOTOR2_PIN_A, HIGH); |
| digitalWrite(MOTOR2_PIN_B, LOW); |
| delay(100); |
| |
| stopMotors(); |
| } |
|
| // 0.1秒左折後0.1秒前進 |
| void turnLeft() { |
| digitalWrite(LED_RED_PIN, HIGH); |
| delay(100); |
| digitalWrite(LED_RED_PIN, LOW); |
| |
| // 左折(片方のモータを停止、もう一方を前進) |
| digitalWrite(MOTOR1_PIN_A, LOW); |
| digitalWrite(MOTOR1_PIN_B, LOW); |
| digitalWrite(MOTOR2_PIN_A, HIGH); |
| digitalWrite(MOTOR2_PIN_B, LOW); |
| delay(100); |
| |
| // 前進 |
| digitalWrite(MOTOR1_PIN_A, HIGH); |
| digitalWrite(MOTOR1_PIN_B, LOW); |
| digitalWrite(MOTOR2_PIN_A, HIGH); |
| digitalWrite(MOTOR2_PIN_B, LOW); |
| delay(100); |
| |
| stopMotors(); |
| } |
|
| // モータを停止 |
| void stopMotors() { |
| digitalWrite(MOTOR1_PIN_A, LOW); |
| digitalWrite(MOTOR1_PIN_B, LOW); |
| digitalWrite(MOTOR2_PIN_A, LOW); |
| digitalWrite(MOTOR2_PIN_B, LOW); |
| } |
|
| // 単一LEDを点滅 |
| void blinkLED(int pin, int duration) { |
| digitalWrite(pin, HIGH); |
| delay(duration); |
| digitalWrite(pin, LOW); |
| } |
|
| // 複数LEDを同時に点灯 |
| void blinkMultiLED(int pin1, int pin2, int duration) { |
| digitalWrite(pin1, HIGH); |
| digitalWrite(pin2, HIGH); |
| delay(duration); |
| digitalWrite(pin1, LOW); |
| digitalWrite(pin2, LOW); |
| } |
|
| // 全LEDを点灯 |
| void blinkAllLEDs(int duration) { |
| digitalWrite(LED_RED_PIN, HIGH); |
| digitalWrite(LED_GREEN_PIN, HIGH); |
| digitalWrite(LED_BLUE_PIN, HIGH); |
| delay(duration); |
| digitalWrite(LED_RED_PIN, LOW); |
| digitalWrite(LED_GREEN_PIN, LOW); |
| digitalWrite(LED_BLUE_PIN, LOW); |
| } |
|
| // Arduinoをリセット |
| void resetArduino() { |
| // ソフトウェアリセットの代わりに、簡潔なメッセージを表示して通知 |
| // ハードウェアリセットは、外部の回路やボタンを使用する必要があるため、 |
| // この例ではソフトウェアで可能な範囲で対応 |
| Serial.println("Arduino is resetting..."); |
| // 実際のリセットは、asm("jmp 0;") を使用することが多いが、 |
| // IRremoteライブラリとの互換性や安定性を考慮し、 |
| // ここでは動作を停止してリセット状態をシミュレート |
| stopMotors(); |
| delay(100); |
| digitalWrite(LED_RED_PIN, HIGH); |
| digitalWrite(LED_GREEN_PIN, HIGH); |
| digitalWrite(LED_BLUE_PIN, HIGH); |
| delay(2000); |
| digitalWrite(LED_RED_PIN, LOW); |
| digitalWrite(LED_GREEN_PIN, LOW); |
| digitalWrite(LED_BLUE_PIN, LOW); |
| } |
|
| // その他のボタンの動作 |
| void defaultAction() { |
| // 0.3秒前進 |
| digitalWrite(MOTOR1_PIN_A, HIGH); |
| digitalWrite(MOTOR1_PIN_B, LOW); |
| digitalWrite(MOTOR2_PIN_A, HIGH); |
| digitalWrite(MOTOR2_PIN_B, LOW); |
| |
| // スピーカーを0.3秒鳴らす |
| tone(SPEAKER_PIN, 1000); // 1000Hzの音 |
| |
| delay(300); |
| |
| stopMotors(); |
| noTone(SPEAKER_PIN); |
| } |