I know there are many links about PWM studies BUT I watched so many of them and I could not solve this little code yet.
I try to turn on two leds with an arduino MEGA using any pin to generate two different PWM with different frequency ( one led 50 Hz and the other led 10 Hz ) I think it has to be designed with two different TIMERS because I need two different frequencies. Also is very important for these code do not include any DELAYS.
I tried using libraries like timerone and timerthree but I didnt get good results
You can try this. I've written it at work and don't have a Mega with me to try it so it may be completely wrong. It does compile.
It's supposed to use timers 1 and 3 to give you a 50Hz PWM on pin 11 and a 10Hz PWM on pin 5. The duty cycle should cycle on each, changing every 200uS going from ~0% to ~100% and back etc.
At least that's the intent. I can debug this evening if this doesn't work as expected.
#define TOP_T1 0x4E20 //ticks Period E = N x 2 / Fclkt = 0x4e20 x 2 / 2MHz = 20mS
#define TOP_T3 0x30D4 //ticks Period E = N x 2 / Fclkt = 0x30d4 x 2 / 250kHz = 100mS
#define BOTTOM 0x0000 //ticks lowest count value
#define DC_TICK_TIME 200ul //uS time between duty cycle ticks
const byte pinOC1A = 11;
const byte pinOC3A = 5;
bool
bDir1,
bDir3;
void setup()
{
pinMode( pinOC1A, OUTPUT );
digitalWrite( pinOC1A, LOW );
pinMode( pinOC3A, OUTPUT );
digitalWrite( pinOC3A, LOW );
//waveform gen mode 8 (PWM, phase & frequency correct); WGM3:0 = 1000
//prescaler = clkio/8 (010)
//TOP == ICR1 = 20000d; count up/down (== 20mS or 50Hz
//OCR1A varies from 0 to 40000 (TOP)
TCCR1A = (1<<COM1A1);
TCCR1B = (1<<WGM13) | (1<<CS11);
ICR1 = TOP_T1;
OCR1A = TOP_T1 >> 1; //should give 50% duty cycle
bDir1 = true;
//waveform gen mode 8 (PWM, phase & frequency correct); WGM3:0 = 1000
//prescaler = clkio/64 (011)
//TOP == ICR1 = 25000d; at 250kHz clk == 100mS or 10Hz
//OCR1A varies from 0 to 25000 (TOP)
TCCR3A = (1<<COM3A1);
TCCR3B = (1<<WGM13) | (1<<CS31) | (1<<CS30);
ICR3 = TOP_T3;
OCR3A = TOP_T3 >> 1; //should give 50% duty cycle
bDir3 = false;
}//setup
void loop()
{
static unsigned long
timeTick=0;
unsigned long
timeNow;
timeNow = micros();
if( timeNow - timeTick >= DC_TICK_TIME )
{
timeTick = timeNow;
//vary the duty on pin 11
if( bDir1 )
{
if( OCR1A < TOP_T1 )
OCR1A = OCR1A + 1;
else
bDir1 = false;
}//if
else
{
if( OCR1A > BOTTOM )
OCR1A = OCR1A - 1;
else
bDir1 = true;
}//else
//vary the duty on pin 5
if( bDir3 )
{
if( OCR3A < TOP_T3 )
OCR3A = OCR3A + 1;
else
bDir3 = false;
}//if
else
{
if( OCR3A > BOTTOM )
OCR3A = OCR3A - 1;
else
bDir3 = true;
}//else
}//if
}//loop
As the frequencies (10/50 Hz) are so low, you easily could do it with a millis() timer and software PWM - leaving the hardware untouched for other tricks.