Go Down

Topic: IRremote Library works on UNO but not MEGA 2560 (Read 3 times) previous topic - next topic

whunter31

Dec 13, 2010, 07:04 pm Last Edit: Dec 13, 2010, 07:05 pm by whunter31 Reason: 1
I am attempting to use the Arduino to forward IR commands using the following code and Ken Shirriff's IRremote library.  Although the code controls the equipment fine with a Arduino UNO, there is no response when the same code is running on the MEGA 2560.  Unfortunately, my project requires the extra headroom that the MEGA 2560 affords.  

Code: [Select]
#include <IRremote.h>

IRsend irsend;
unsigned int powerOnOff[23] =  {550, 4500, 550, 4500, 550, 4500, 550, 4500, 550, 4500, 500, 4550, 500, 4550, 500, 4550, 500, 4550, 500, 4550, 550, 4500, 550};

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

void loop() {
 if (Serial.read() != -1) {
   for (int i = 0; i < 3; i++) {
     irsend.sendRaw(powerOnOff, 23, 40);
     delay(100);
   }
 }
}


Would anyone have any advice or experience using Ken Shirriff's IRremote library on an Arduino MEGA-2560?

Thanks,
Bill

arbarnhart

This post:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1276098589
seems to indicate you will need to use a different pin and make a source change.

whunter31

Thank you Arbarnhart.  My application is centered around IRremote and it appears that the IRremote.lib doesn't support pin change.  I guess I will need to figure a way to make IRremote work on the UNO.  

Thank you once again for your help.

arbarnhart

It looks like to me you can change whatever you want. I was confused about how the Arduino worked at first and thought libraries were .lib or whatever. They aren't. Go look in the libraries\IRRemote folder. The source is there and you can change it. It will recompile each time you build it.

davekw7x

#4
Dec 14, 2010, 05:33 pm Last Edit: Dec 14, 2010, 11:24 pm by davekw7x Reason: 1
@whunter31:
Quote
IRremote.lib doesn't support pin change


@arbarnhart:
Quote
you can change whatever you want


Here's the deal: for IRremote::IRrecv objects you can use any pin you want.

For IRremote::IRsend objects, the library is hardcoded to use Arduino Pin 3 and works for Arduino boards that use ATmega328 or '168 chips, but not for Arduino boards based on '1280 or '2560 chips.

There are two things that determine which Arduino pin is used for transmitting:

1.  The library uses Timer2 for timing, and the ATmega OCR2B pin is used for the output signal.  Changing the timer and the timer's comparison register pin is not (that's not) simply a matter of defining a different pin number.  The code that initializes whatever timer you use and the code that enables and disables that timer's selected OCR pin must be changed.  (Not a big deal, really, but for your first pass, I'll show how I make it work with a Mega board without changing the library).

2.  The library initializes Arduino Pin 3 (hard-coded) as an output to be used for transmitting the IR signals.  This is easy to change in the library, but I'll show a sketch that changes it without having to alter the library. But:  See Footnote.

Here's the problem:

Now, for Arduino boards using ATmega328 and '168 chips the ATmega OCR2B pin is connected to Arduino Pin 3 and everything works as long as you connect your IR LED (through a suitable resistor) to Arduino Pin 3.

However...

For Arduino boards using ATmega1280 and '2560 chips the ATmega OCR2B pin is connected to Arduino pin 9.  Oh, crap!


@whunter31:
Quote
...experience using Ken Shirriff's IRremote library on an Arduino MEGA-2560

Here's the way that I got the unmodified IRremote library to work with my Mega1280 board:

1.  Connect the IR LED (through a suitable resistor) to Arduino Pin 9 on your Mega1280 or Mega2560.

2.  In any sketch that uses IRremote::send(), initialize Arduino Pin 9 to be an output with a low value.

Here is my IRsend demo sketch:

Code: [Select]

//
// Demo of IRremote send() function on an Arduino Mega
// board.
//
// Derived from IRsendDemo from Ken Shirriff's IRremote library
// version 0.1 July, 2009
// Copyright 2009 by KenShirriff
//
// davekw7x
//
// For Mega boards, connect the IR led to Arduino pin 9
// through a suitable resistor.
//
#include <IRremote.h>

IRsend irsend;

void setup()
{
 Serial.begin(9600);
 pinMode(9,OUTPUT); // The library initializes pin 3 as an output
 digitalWrite(9, LOW);// Since our LED is connected to pin 9, we initialize it here
}
int n = 0;
void loop() {
   Serial.println(n++);

   for (int i = 0; i < 3; i++) { // Send a burst of three commands
     irsend.sendSony(0xa90, 12); // Sony TV power code
     delay(100);
   }

 delay(1000); // Repeat every second
}





Regards,

Dave

Footnote:

The test sketch that I posted above is for proof-of-concept and shows that IRremote can work on an Arduino Mega board.

Here's the thing:

The various transmit routines (sendNEC(), sendSony(), etc.) call IRsend::enableIROut(), which reinitializes Pin 3 (hardcoded) to an output and sets its value low each time.  My simple sketch seems to work OK even though I only initialize the (different) output pin once, in setup().  I think I would rather do it Mr. Shirriff's way, which would require a minor change in the library file.

Furthermore:

If you think you will want to use Arduino Pin 3 for anything else in your sketches, you should modify the enableIROut() library function to initialize Pin 9, not Pin 3.

Maybe a conditional definition that depends on the board type would be a simple (and safe, I think) library modification.  (Along with comments that indicate which output pin is used for each board type.)

Go Up