IRRemote library, timers and PWM

Hi - first off I'm a huge newbie at both Arduino development and the Arduino forums, so mods please move this if it's not in the right place or something.

I'm trying to integrate Ken Shirriff's IR Remote library (available from his blog here http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html) with the SparkFun ArduMoto motor shield (SparkFun Ardumoto - Motor Driver Shield - DEV-14129 - SparkFun Electronics). The test project I'm using is simple enough - it includes the IRRemote library, turns on recieving, then if it detects the hex code for the power button on the remote control I'm using it tries to power the motor. Unfortunately, the ArduMoto shield uses pins 3, 12, 13 and 11, with 13 and 3 using PWM for speed/power control. The IRRemote library, from what I've been able to glean from my research, uses the ATMega's internal timer2, which unfortunately precludes using pin 3 for PWM. This means that running irrecv.enableIRIn() means I can no longer control my motors.

I've thought of a couple possible solutions - the ideal would be updating the library to use the ATMega timer1 (although again from my limited research this looks like a 16-bit instead of an 8-bit timer, which might screw some stuff up?), unfortunately I don't really know how to go about doing this. Next up would be cutting the trace lines on the ArduMoto and soldering in some jump wires to the pins, but I'd rather not do that just for the sake of keeping all of the printed labels on the shield correct (I don't want to have to flip it over four times two weeks from now wondering "if I plug in to pin 10 here it's actually getting jumped to 7...or is that 6?"). The final option would be to just run the motor shield off of one Arduino and the IR receiver on another, with them communicating in some way (I'm assuming this would be pretty easy, I would have tested it already but my Leonardo board is being finicky). Again I'd prefer not to go this route because it seems like complete overkill, plus I'd need another power supply.

Some of my example code is below, I've tried to clean it up a bit while still getting the gist across. Motor A is commented out because I figured without using pin 3 I might be able to get the receiver working with just Motor B - sadly, no dice (incidentally I'm really curious as to why this is, I must be missing something. Ideas?).

/*
Test project with IR Remote library and ArduMoto shield
*/
#include <IRremote.h>

#define ON_CODE 0x61D648B7
#define MODE_STOP 0
#define MODE_FORWARD 1


//int pwm_a = 3;  
int pwm_b = 11;  
//int dir_a = 12;  
int dir_b = 13;  
int IRRecPin = 6;
int mode = MODE_STOP;
boolean isRunning = false;

IRrecv irrecv(IRRecPin);
decode_results results;
void setup()
{
  //pinMode(pwm_a, OUTPUT); 
  pinMode(pwm_b, OUTPUT);
  //pinMode(dir_a, OUTPUT);
  pinMode(dir_b, OUTPUT);
  Serial.begin(9600);
  Serial.println("Initialized control pins");

  irrecv.enableIRIn(); //enable the receiver, kill the motors....all in a day's work *sigh*
 Serial.println("Initialized IR reciever");
  //analogWrite(pwm_a, 150);  //test running motors after enableIRIn() (won't work!!)
//  analogWrite(pwm_b, 150);
  
}

void loop()
{
  
  if (irrecv.decode(&results)){ //catch results from the remote
   Serial.print(results.value, HEX); //log it, make sure it's sane
    if(results.value==ON_CODE){
     // mode=MODE_FORWARD;
 isRunning=true;
   }
   irrecv.resume(); //allows more IR input if I understand correctly
  }

  if (isRunning){
   // digitalWrite(dir_a, HIGH); 
    //digitalWrite(dir_b, HIGH);
    //analogWrite(pwm_a, 200);
     analogWrite(pwm_b, 200); 
     Serial.println("Motors on"); //this will print to the serial monitor when the motors should be running but aren't
    delay(1000);  //just so we don't flood the serial monitor - hey, if we're at this point we're already 'on' and a second delay for the IR decoding doesn't matter much
  }
  }

Any thoughts/ideas/comments? All help is greatly appreciated!

Probably the easiest would be to use a ATtiny85 for receiving the IR signals and communicate that to the Arduino using I2C.

pylon:
Probably the easiest would be to use a ATtiny85 for receiving the IR signals and communicate that to the Arduino using I2C.

Are you serious? I mean at this point all I really want is the IR receiver and the two motors, seems I should be able to get that running off of a single ATMega328. I've been looking to order some extra random AVR chips anyways for ICSP practice, but I'd rather not resort to one in this project if possible. Thanks for the suggestion, though.

Any other ideas? Any help?

EDIT: If this question would fit better in a different subforum please let me know!

You don't wanna change your motor shield, changing the IRremote code is not what you want and you don't wanna add hardware, what options do you leave?

  • You can change your motor shield to use another PWM pin, other than pin 3.
  • You can change the IRremote code to use another time, so PWM on pin 3 has it's timer.
  • You can put the whole IR stuff externally by using some other hardware.

Do you see another feasible option?

You can change the sketch to use timer1, generate a timer interrupt and do the PWM for pin 3 in that interrupt routine. Maybe that fits your needs better? It's quite complex to accomplish though.

Like I said above, I think changing the IRRemote library to hit a different timer would be the ideal solution, I just don't really know how to go about it. I'm a software developer by trade but I'm unfamiliar with low-level stuff like timers - if you have some guidance or can point me towards a tutorial that would be great. The external hardware route is going to be a last resort here.

I have an ir romote lib that will work on any port that supports interupts. You can get it from here:
http://zbotic.com/index.php/download/

Note it only supports remotes that use nec protocol but that seems pretty popular.

Anybody has gotten the IR remote to work with timer 0 or timer 1 instead of timer 2?