For the latest in the saga...
We added a flag-pole and a stepper motor to raise and lower a flag. We were hoping to have it play a tune while the flag was lowering. It works great, except...
After the tune plays, the IR receiver stops interpreting the signals correctly. If anyone can help point out the downfall, please let me know. Here is the code:
/*
* SimpleReceiver.cpp
*
* Demonstrates receiving ONLY NEC protocol IR codes with IRremote
* If no protocol is defined, all protocols (except Bang&Olufsen) are active.
*
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
*
************************************************************************************
* MIT License
*
* Copyright (c) 2020-2023 Armin Joachimsmeyer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
************************************************************************************
*/
/*
* Specify which protocol(s) should be used for decoding.
* If no protocol is defined, all protocols (except Bang&Olufsen) are active.
* This must be done before the #include <IRremote.hpp>
*/
/*#define DECODE_DENON // Includes Sharp
* #define DECODE_JVC
* #define DECODE_KASEIKYO
* #define DECODE_PANASONIC // alias for DECODE_KASEIKYO
* #define DECODE_LG
* #define DECODE_NEC // Includes Apple and Onkyo. To enable all protocols , just comment/disable this line.
* #define DECODE_SAMSUNG
* #define DECODE_SONY
* #define DECODE_RC5
* #define DECODE_RC6
* #define DECODE_BOSEWAVE
* #define DECODE_LEGO_PF
* #define DECODE_MAGIQUEST
* #define DECODE_WHYNTER
* #define DECODE_FAST
* #define DECODE_DISTANCE_WIDTH // Universal decoder for pulse distance width protocols
* #define DECODE_HASH // special decoder for all protocols
* #define DECODE_BEO // This protocol must always be enabled manually, i.e. it is NOT enabled if no protocol is defined. It prevents decoding of SONY!
* #define DEBUG // Activate this for lots of lovely debug output from the decoders.
* #define RAW_BUFFER_LENGTH 180 // Default is 112 if DECODE_MAGIQUEST is enabled, otherwise 100.
*/
#include <Arduino.h> //This include defines the actual pin number for pins like IR_RECEIVE_PIN, IR_SEND_PIN for many different boards and architectures
#include "PinDefinitionsAndMore.h" //This includes Pin 11 as IR receive pin
#include <IRremote.hpp> // include the library
#include "Notes.h"
#include <Stepper.h>
const int stepsPerRevolution = 200; //Change this to match the stepper
int sensorvalue = 0;
const int motor1pin1 = 2;
const int motor1pin2 = 3;
const int motor2pin1 = 4;
const int motor2pin2 = 5;
Stepper myStepper(stepsPerRevolution, 7, 8, 9, 10);
const int speakerPin = 12;
const int flagpole[] = {27, // Array for Flag pole sound effect & song
NOTE_G2, 10, NOTE_C3, 10, NOTE_E3, 10, NOTE_G3, 10, NOTE_C4, 10, NOTE_E4, 10, NOTE_G4, 3, NOTE_E4, 3, NOTE_GS2, 10, NOTE_C3, 10,
NOTE_DS3, 10, NOTE_GS3, 10, NOTE_C4, 10, NOTE_DS4, 10, NOTE_GS4, 3, NOTE_DS4, 3, NOTE_AS2, 10, NOTE_D3, 10, NOTE_F3, 10,
NOTE_AS3, 10, NOTE_D4, 10, NOTE_F4, 10, NOTE_AS4, 3, NOTE_AS4, 10, NOTE_AS4, 10, NOTE_AS4, 10, NOTE_C5, 2};
const int death[] = {17, // Array for Death sound effect & song
NOTE_C4, 32, NOTE_CS4, 32, NOTE_D4, 16, NOTE_H, 4, NOTE_H, 2, NOTE_B3, 8, NOTE_F4, 8, NOTE_H, 8, NOTE_F4, 8, NOTE_F4, 6,
NOTE_E4, 6, NOTE_D4, 6, NOTE_C4, 8, NOTE_E3, 8, NOTE_H, 8, NOTE_E3, 8, NOTE_C3, 8};
const int gameover[] = {15, // Array for Game over song
NOTE_C4, 8, NOTE_H, 8, NOTE_H, 8, NOTE_G3, 8, NOTE_H, 4, NOTE_E3, 4, NOTE_A3, 6, NOTE_B3, 6, NOTE_A3, 6, NOTE_GS3, 6, NOTE_AS3, 6,
NOTE_GS3, 6, NOTE_G3, 8, NOTE_F3, 8, NOTE_G3, 4};
String Forwardnote = "Forward";
String Reversenote = "Beeeep, Beeeep";
String Rightnote = "Right Turn";
String Leftnote = "Left Turn";
String Stopnote = "Stop";
String Raisenote = "Raising";
String Dropnote = "Lowering";
void Forward(){
digitalWrite(motor1pin1, HIGH);
digitalWrite(motor1pin2, LOW);
digitalWrite(motor2pin1, HIGH);
digitalWrite(motor2pin2, LOW);
}
void Stop(){
digitalWrite(motor1pin1, LOW);
digitalWrite(motor1pin2, LOW);
digitalWrite(motor2pin1, LOW);
digitalWrite(motor2pin2, LOW);
}
void Reverse(){
digitalWrite(motor1pin1, LOW);
digitalWrite(motor1pin2, HIGH);
digitalWrite(motor2pin1, LOW);
digitalWrite(motor2pin2, HIGH);
}
void Right(){
digitalWrite(motor1pin1, HIGH);
digitalWrite(motor1pin2, LOW);
digitalWrite(motor2pin1, LOW);
digitalWrite(motor2pin2, HIGH);
}
void Left(){
digitalWrite(motor1pin1, LOW);
digitalWrite(motor1pin2, HIGH);
digitalWrite(motor2pin1, HIGH);
digitalWrite(motor2pin2, LOW);
}
void Raise(){
Serial.println("Raising");
myStepper.step(stepsPerRevolution);
delay(500);
Stop();
}
void Lower(){
Serial.println("Lowering");
myStepper.step(-stepsPerRevolution);
delay(500);
Stop();
}
void FlagSong(){
for (int thisNote = 1; thisNote < (flagpole[0] * 2 + 1); thisNote = thisNote + 2) { // Run through the notes one at a time
tone(speakerPin, flagpole[thisNote], (1000/flagpole[thisNote + 1]));// Play the single note
delay((1000/flagpole[thisNote + 1]) * 1.30); // Delay for the specified time
noTone(speakerPin); // Silence the note that was playing
}
Serial.println("Done");
}
void setup() {
pinMode(motor1pin1, OUTPUT);
pinMode(motor1pin2, OUTPUT);
pinMode(motor2pin1, OUTPUT);
pinMode(motor2pin2, OUTPUT);
pinMode(speakerPin, OUTPUT);
//Stepper motor pinouts initialized as output in Stepper.h
Serial.begin(115200);
// Just to know which program is running on my Arduino
Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));
// Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
Serial.print(F("Ready to receive IR signals of protocols: "));
printActiveIRProtocols(&Serial);
Serial.println(F("at pin " STR(IR_RECEIVE_PIN)));
}
void loop() {
/*
* Check if received data is available and if yes, try to decode it.
* Decoded result is in the IrReceiver.decodedIRData structure.
*
* E.g. command is in IrReceiver.decodedIRData.command
* address is in command is in IrReceiver.decodedIRData.address
* and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData
*/
if (IrReceiver.decode()) {
/*
* Print a summary of received data
*/
if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));
// We have an unknown protocol here, print extended info
IrReceiver.printIRResultRawFormatted(&Serial, true);
IrReceiver.resume(); // Do it here, to preserve raw data for printing with printIRResultRawFormatted()
} else {
IrReceiver.resume(); // Early enable receiving of the next IR frame
IrReceiver.printIRResultShort(&Serial);
IrReceiver.printIRSendUsage(&Serial);
}
Serial.println();
/*
* Finally, check the received data and perform actions according to the received command
*/
if (IrReceiver.decodedIRData.command == 0xB0) {
Serial.println(Forwardnote);
sensorvalue = 1;// do something
} else if (IrReceiver.decodedIRData.command == 0xB2) {
Serial.println(Reversenote);
sensorvalue = 2;// do something
} else if (IrReceiver.decodedIRData.command == 0xB1) {
Serial.println(Rightnote);
sensorvalue = 3;
} else if (IrReceiver.decodedIRData.command == 0xB3) {
Serial.println(Leftnote);
sensorvalue = 4;
} else if (IrReceiver.decodedIRData.command == 0x85) {
Serial.println(Stopnote);
sensorvalue = 0;
} else if (IrReceiver.decodedIRData.command == 0x86) {
Serial.println(Raisenote);
Raise();
} else if (IrReceiver.decodedIRData.command == 0x87) {
Serial.println(Dropnote);
Lower();
FlagSong();
} else if (IrReceiver.decodedIRData.command == 0x98) {
Serial.println("dead");
} else if (IrReceiver.decodedIRData.command == 0x99) {
Serial.println("game over");
}
if (sensorvalue == 0) {
Stop ();
} else if (sensorvalue == 1) {
Forward ();
} else if (sensorvalue == 2) {
Reverse ();
} else if (sensorvalue == 3) {
Right ();
} else if (sensorvalue == 4) {
Left ();
}
}
} //void loop close
/*
Why is this unable to read IR signals after the flagsong?
*/
And here is part of the Serial Printout (after the "Lowering" the "Stop" command was sent, but wasn't decoded correctly as it had been earlier):
Protocol=NEC Address=0x5583 Command=0x85 Raw-Data=0x7A855583 32 bits LSB first
Send with: IrSender.sendNEC(0x5583, 0x85, );
Stop
Protocol=NEC Address=0x5583 Command=0x87 Raw-Data=0x78875583 32 bits LSB first
Send with: IrSender.sendNEC(0x5583, 0x87, );
Lowering
Lowering
Done
Received noise or an unknown (or not yet enabled) protocol
rawData[30]:
-1196250
- 450,- 200
- 50,- 50 + 50,- 50 + 50,- 200 + 100,- 50
- 50,- 50 + 50,- 200 + 50,- 50 + 100,- 50
- 50,- 300 + 200,- 300 + 100,- 50 + 50,- 50
- 50,- 200 + 50
Sum: 3250