1

I have a simple sketch which sends IR codes, plays a sound and toggles an LED when you press a button and toggles another LED when it receives that code. The idea is that I have two Arduinos with this same sketch and when you press the button on one, the LED is toggled and so is another LED on the other Arduino. This program works as intended when the sound is not included.

Here is the sketch:


#include <IRremote.h> // For the IR transmition and receiving
#include <PCM.h> // For the audio output 

IRsend irsend; // Setup the IR transmitter
const int receiver = 8; // Initialize pin 13 as recevier pin.
IRrecv irrecv(receiver); // Create a new instance of receiver
decode_results results;

// Declare arrays to hold sound notes to play
const unsigned char gunShot[] PROGMEM = {}; // There is a huge list of numbers in this array, but I removed them to make the code easier to read

const unsigned char gunClick[] PROGMEM = {}; // There is a huge list of numbers in this array, but I removed them to make the code easier to read


// declare consants
const int button = 13;
const int greenLight = 7;
const int yellowLight = 2;
const int timeBetweenTransmittion = 800; // At least 800 milliseconds between two transmissions
// The speaker is fixed on pin 11

// declare variables
bool toggleGreen = true; // Bool variables to toggle the lights
bool toggleYellow = true;
long int previousTransmittion = 0; // Long int to store the timestamp in millis of the previous transmission

// put your setup code in here, to run once:
void setup() 
{
  pinMode(button, INPUT_PULLUP); // Setup the button with an internal pullup resistor
  Serial.begin(9600);
  irrecv.enableIRIn(); // Enable the receiver
  Serial.println("start");
}

// put your main code in here, to run repeatedly:
void loop() {
  if (not digitalRead(button) && millis() > previousTransmittion + timeBetweenTransmittion) // If the button is pressed and it's been enought time since the last transmittion
  { 
    Serial.println("send!");

    // Different orders of these lines of code were tried:
    
    //startPlayback(gunShot, sizeof(gunShot)); // Play shot before sending the code and enabling the receiver (play command 1 for reference)
    //delay(250);
    
    irsend.sendNEC(1367857, 32); // Send the code

    //startPlayback(gunShot, sizeof(gunShot)); // Play shot between sending the code and enabling the receiver (play command 2 for reference)
    //delay(250);
    
    irrecv.enableIRIn(); // Sending ir stops the receiver so start the receiver again
    
    startPlayback(gunShot, sizeof(gunShot)); // Play shot after sending the code and enabling the receiver (play command 3 for reference)
    delay(250);


    // Toggle the yellow light
    digitalWrite(yellowLight, toggleYellow);
    toggleYellow = not toggleYellow;

    previousTransmittion = millis(); // Set the record for latest transmittion to the currnt time  
  }


  
  if (irrecv.decode(&results)) // If we have received an IR signal
  { 
    Serial.println (String(results.value, HEX)); // Display HEX results 
    if (String(results.value, DEC) == "1367857") // If the code is the right one
    {
      Serial.println("correct code");
      
      // toggle the green light
      digitalWrite(greenLight, toggleGreen);
      toggleGreen = not toggleGreen;
    }
    irrecv.resume(); // Prepare the receiver for the next code    
 }
}

// End of sketch

As you can see, I tried putting the play sound line before, between and after the IR transmission lines of code. The delays are there so I can see if the audio starts to play and stops or if it just never plays. Here is what I found from all the combinations:

  • In all the combinations (play command 1, 2 and 3), The IR receiver worked as intended if used BEFORE ever pressing the button.

  • None of the combinations stop the loop as if I put <Serial.println("loop");> at the start of the loop() routine, it continues to print "loop", regardless of what I do.

  • In play command 1 and 2, the sound plays when I press the button, but stops after the 250ms delay. Once the button has been pressed once, it doesn't do anything when I press it again (doesn't print "send!" or toggle the light). The receiver receives one more code after pressing the button, but always prints the code "2a", regardless of what button on my tv remote I press (the tv remote usually prints a 6 character hex code). After it prints "2a", it doesn't receive any more codes.

  • Play command 3 plays the full sound and sends the right code, and allows me to do it as many times as I want (the button still works after pressing it more than once). However the receiver still no longer works after the first time I press the button. It doesn't receive "2a" the first time after pressing the button unlike the first 2.

I am using the libraries IRremote by shirriff, z3t0 and ArminJo (VERSION 2.6.1) and PCM by David Mellis, Michael Smith (VERSION 1.0.0) (http://highlowtech.org/?p=1963). I don't know if there is a simple way around this problem or if these libraries just cannot be used together.

I have the speaker on pin 11.

If you need anything clarifying please ask. Any help would be appreciated, thanks in advance.

1

The PCM library uses timer 1, and timer 2. The IRremote library uses timer 1. So they both need timer 1. So there's a conflict. So you can't use both libraries at the same time, unfortunately.

3
  • Okay, thanks. Do you know of any other libraries that I could use together that would allow me to use IR and sound which don't conflict? – Patrick Feb 17 at 17:36
  • 1
    Easiest would be to offload the sound playback to a different chip, like the dfplayer mini (which carries a micro SD card) – chrisl Feb 17 at 22:36
  • Okay, thanks. I've had a brief look and that looks like a good solution. – Patrick Feb 18 at 0:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.