I am looking for a way to choose a pin on the Arduino Uno. This pin will be used to send the signal of an IR LED. I am using the IRremote library.
e.g.
Below is the IR send demo which uses pulse width modulation pin 3 to send the IR signal. I want to change that pin to any other pin.
Any pointers will make me very happy thanks.
/*
* IRremote: IRsendDemo - demonstrates sending IR codes with IRsend
* An IR LED must be connected to Arduino PWM pin 3.
* Version 0.1 July, 2009
* Copyright 2009 Ken Shirriff
* http://arcfn.com
*/
#include <IRremote.h>
IRsend irsend;
void setup()
{
}
void loop() {
for (int i = 0; i < 3; i++) {
irsend.sendSony(0xa90, 12);
delay(40);
}
delay(5000); //5 second delay between each signal burst
}
2 Answers 2
As the pin does not appear to be able to be defined when creating an object from the IRsend
class, it seems as if you will have to modify the IRremote library itself.
I recently had the same problem with the USB Host library, see Change select pin of USB Host library. It is annoying when you can't define the pin(s), that a particular library uses, yourself... However, the authors of the library probably have their reasons for doing so.
Looking through the various headers of the library, I found in boarddefs.h
on lines 134-138:
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
// ATmega48, ATmega88, ATmega168, ATmega328
#else
//#define IR_USE_TIMER1 // tx = pin 9
#define IR_USE_TIMER2 // tx = pin 3
So, the line to change, for the Uno, would seem to be line 138 in boarddefs.h
#define IR_USE_TIMER2 // tx = pin 3
However, it is not, as that merely states that for the Arduino Uno IR_USE_TIMER2
is used...
Looking further down to where the Timers are defined, you will see the section for Timer 2, on line 146. In that section the transmit pin, for a number of versions of the Arduino, is defined as TIMER_PWM_PIN
on lines 189-197:
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
|| defined(__AVR_ATmega164P__)
# define TIMER_PWM_PIN 14 // MightyCore
#else
# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
#endif // ATmega48, ATmega88, ATmega168, ATmega328
You will have to change this line in the library, Line 196 in boarddefs.h:
# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc
You could try changing the 3
so that you can use another pin. It might work. For example to use pin 5, en lieu of pin 3, change the 3
to a 5
, like so:
# define TIMER_PWM_PIN 5 // Arduino Duemilanove, Diecimila, LilyPad, etc
Be careful not to choose a pin that is used by something else, AND I think that the pin will need to be PWM capable.
Note that the definitions that are in boarddefs.h
used to be in RemoteInt.h
, in earlier versions of the library. See this comment at the very top:
// This file contains all board specific information. It was previously contained within
// IRremoteInt.h
So, make sure that you have the latest version of the IRremote library.
The above hack should also work for the Mega2560 as is uses the same timer, Timer 2, see lines 68-71:
// Arduino Mega
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
//#define IR_USE_TIMER1 // tx = pin 11
#define IR_USE_TIMER2 // tx = pin 9
Other boards are also defined in this file. If you have another type of board, the timer may be different, but the process to find which line to change would be very similar...
-
Note that I have not tried this, so I would be interested to hear if it works or not.Greenonline– Greenonline01/19/2017 07:33:15Commented Jan 19, 2017 at 7:33
-
Thanks for your answer. I have two questions: How do I know when a pin is being used by something else? Will I be able to choose more than one pin to do a task? e.g at the moment only pin 3 sends IR signal however, I would like pin3, pin 5 and pin6 to send IR signals.MALKAVIAN– MALKAVIAN01/20/2017 07:57:31Commented Jan 20, 2017 at 7:57
-
1) Your code will tell you if a pin is being used. W.R.T. the IRremote library, the documentation will tell you which pins it is using. 2) Looking at the library it seems that you can not, or at least not without further modification. Maybe you could activate another Timer, by uncommenting out another line, and then use the pin of that timer (as each timer, appears to use its own separate pin - from looking at that header file). I am not sure. If you really want to do that, then ask/post a separate (related) question, as it is significantly different from your original question.. :-)Greenonline– Greenonline01/20/2017 08:14:48Commented Jan 20, 2017 at 8:14
I tried to find where the pin is defined and gave up, I ended up swapping to pin9 by commenting out timer2, like this:
#define IR_USE_TIMER1 // tx = pin 9
//#define IR_USE_TIMER2 // tx = pin 3
Not ideal since I needed 9 also and I will add how annoying this library is that although I only need to receive signals and never send...it still takes up a pin for sending.
ANyway, the posts above helped me at least get my motor shield working, thanks guys.
IR_USE_TIMER2
is defined...