Use timer interrupt and PWM at same time, how can I do this?

Hi,

I'm having trouble using timer interrupt and using PWM at the same time.

Explanation of what I want to achieve :
I use the IRremote library and need to produce a non continus 38kHz signal on pin 3, period is not important.

I also need to output 4 independant PWM signals. I know I cannot use PWM on pins 11 and 3 while using the IRremote 38kHz mark function, because timer2 is used by the library.

I wanted to use timer1 interrupt to disable/enable periodicaly the 38kHz signal so it is not continuous (the continuous signal is filtered by my IR detectors TL1838).

But when I do that, pins 9 and 10 become unable to do PWM, which let me with only 2 PWM capable pins, which is not enough.

I was hoping I could get periodic interrupt from timer1 without disturbing PWM capability, up to me then to add an increment variable in the interrupt method to adjust my period.

How is this possible ?

But when I do that, pins 9 and 10 become unable to do PWM, which let me with only 2 PWM capable pins, which is not enough.

A Mega has more than 6 PWM pins AND more than 3 timers.

I was hoping I could get periodic interrupt from timer1 without disturbing PWM capability

I was hoping to win the Powerball lottery without buying a ticket, too. Didn't happen for me. Won't happen for you.

sierramike:
I'm having trouble using timer interrupt and using PWM at the same time.

On what Arduino?

Read this before posting a programming question

How to use this forum

Sorry I didn't add the details : I'm working with Arduino Nano (so Atmega 328p) and stuck with that because of place and costs (there will be a lot of circuits in my final project)

The Atmega328P has 3 timers which can output to 6 pins. Can you clarify (without worrying about what libraries can do) what you would assign to each of those 6 outputs? Each of the 3 timers can only have one mode and prescaler.

See: Gammon Forum : Electronics : Microprocessors : Timers and counters

PaulS:
A Mega has more than 6 PWM pins AND more than 3 timers.
I was hoping to win the Powerball lottery without buying a ticket, too. Didn't happen for me. Won't happen for you.

Thanks for the precision, the difference is that you know you have to buy a ticket to win, where in my case I don't know everything about the Arduino, that's the reason I ask here ...

I'm willing to manage model trains. So I would output 4 different "speeds" by PWM on 4 pins.
I also need to output a 38kHz IR signal for train detection, which is achieved by IRremote library, using timer2 (I think in FastPWM mode but not sure), which prevents me from using pin 11 as a PWM pin.

I wanted to use timer1 interrupt to disable/enable periodicaly the 38kHz signal so it is not continuous

What frequency/period do you want to turn Timer2 output on and off?

You might be able to use an overflow interrupt from Timer2 or indeed, from one of the other timers to manage Timer2. The overflow interrupts should be independent of the PWM.

I can't use the timer2 as it is already busy providing the 38kHz signal. So I'm left with the timer1.

I don't need a precise period, so if you have any code snippet to turn on overflow on timer1 without disturbing the PWM capability, that would be great !
I could still increment a variable to get a longer period if needed !

Before we get too deep into this, it looks to me like you should be able to turn off the Timer 2 38kHz output on pin 3 with

digitalWrite(3, LOW);

Yes, I know that, my target is to periodically turn off, then on, then off, then on etc. the 38kHz output on pin 3. I have the source code to achieve this (mark() and space() methods of the IRremote library).

What I need is an interrupt that will do the "off/on/off/on/off/on" thing, while keeping 4 active PWM pins.

If the period doesn't matter then use the timer overflow interrupt and that won't affect your PWM on those pins. If you're careful and don't care about the frequency of the PWM you can even use the prescaler to get some rough co,tell over the period.

sierramike:
I can't use the timer2 as it is already busy providing the 38kHz signal. So I'm left with the timer1.

Well, can't you PWM the trains at 38 kHz?

The 38kHz signal on pin 3 is used to drive an IR emitter, I can't vary the duty cycle for my trains, but the overflow route may help, I will search the web on how to accomplish this

How often do you want to turn on and off the 38khz output?

I think I could give it a try every 20ms

I'm not familiar with the IR library in use. Does it make use of the Timer2 overflow interrupt vector? I think it would be best to manage the pwm output from timer2 without involving the other timers, but I'm not certain if the Timer2 overflow vector is available.

For 20ms cycling of the pulse train, you may be able to do that with a software millis() based timer. You say that you know how to turn the IR pwm train on and off. Have you tried that with a "blink without delay" millis() based timer?

Sure, 20ms on and off doesn't need an interrupt at all. Just keep your loop code tight and non blocking.

If Timer1 pwm is running at the default rate of 490 Hz, then there will be very close to 10 cycles of that timer every 20 ms.

First, enable a Timer 1 overflow interrupt in your setup.

TIMSK1 |= 1 << TOIE1; //overflow interrupt enable

Then you can add a Timer1 overflow interrupt vector into your code, which will toggle pin 3 between an input and output and effectively turn the pwm on that pin on and off.

ISR(TIMER1_OVF_vect) 
{
   
 static unsigned long ovf_count;

  ovf_count++;               //Increments the overflow counter

  if (ovf_count >= 10) 
  {

    DDRD ^= 1 << 3;  //toggles pin3 input/output

    ovf_count = 0;       //Resets the overflow counter
  }
}

Great, thanks Cattledog that seems to be what I need, I will test it this evening !