New hardware-PWM AVR_PWM Library


Initial Releases v1.0.0

  1. Initial coding to support AVR boards, such as Mega-2560, UNO, Nano, Leonardo, etc., using AVR cores
  2. The hardware-based PWM channels can generate very high frequencies.

Debug Terminal Output

1. PWM_Waveform on Arduino AVR Mega2560

The following is the sample terminal output when running example PWM_Waveform on AVR Mega2560, to demonstrate how to use the setPWM_manual() function in wafeform creation

Starting PWM_Waveform on Arduino AVR Mega2560/ADK
AVR_PWM v1.0.0
[PWM] AVR_PWM: _dutycycle = 0
[PWM] setPWM: _dutycycle = 0
[PWM] setPWM_Int: _dutycycle = 0
[PWM] setPWM_Int:using TIMER4C
[PWM] setPeriod_Timer4: F_CPU = 16000000 , cycles = 8000
[PWM] setPeriod_Timer4: clockSelectBits = 1 , pwmPeriod = 8000
[PWM] setPWM_Int:using TIMER4C, _dutycycle = 0
============================================================================================
Actual data: pin = 8, PWM DutyCycle = 0.00, PWMPeriod = 8000.00, PWM Freq (Hz) = 1000.0000
============================================================================================
[PWM] PWM enabled, DCValue = 0 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 8000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 0 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00

2. PWM_Waveform on Arduino AVR ATMega32U4

The following is the sample terminal output when running example PWM_Waveform on ATMega32U4, to demonstrate how to use the setPWM_manual() function in wafeform creation

Starting PWM_Waveform on Arduino AVR ATMega32U4
AVR_PWM v1.0.0
[PWM] AVR_PWM: _dutycycle = 0
[PWM] setPWM: _dutycycle = 0
[PWM] setPWM_Int: _dutycycle = 0
[PWM] setPWM_Int:using TIMER1A
[PWM] setPeriod_Timer1: F_CPU = 16000000 , cycles = 8000
[PWM] setPeriod_Timer1: clockSelectBits = 1 , pwmPeriod = 8000
============================================================================================
Actual data: pin = 9, PWM DutyCycle = 0.00, PWMPeriod = 8000.00, PWM Freq (Hz) = 1000.0000
============================================================================================
[PWM] PWM enabled, DCValue = 0 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 8000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 0 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00

3. PWM_Waveform on Arduino AVR Nano

The following is the sample terminal output when running example PWM_Waveform on AVR Nano, to demonstrate how to use the setPWM_manual() function in wafeform creation

Starting PWM_Waveform on Arduino AVR UNO, Nano, etc.
AVR_PWM v1.0.0
[PWM] AVR_PWM: _dutycycle = 0
[PWM] setPWM: _dutycycle = 0
[PWM] setPWM_Int: _dutycycle = 0
[PWM] setPWM_Int:using TIMER1B
[PWM] setPeriod_Timer1: F_CPU = 16000000 , cycles = 8000
[PWM] setPeriod_Timer1: clockSelectBits = 1 , pwmPeriod = 8000
============================================================================================
Actual data: pin = 10, PWM DutyCycle = 0.00, PWMPeriod = 8000.00, PWM Freq (Hz) = 1000.0000
============================================================================================
[PWM] PWM enabled, DCValue = 0 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 8000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 7000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 6000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 5000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 4000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 3000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 2000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 1000 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 500 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00
[PWM] PWM enabled, DCValue = 0 , pwmPeriod = 8000 , _frequency = 1000.00 , _actualFrequency = 1000.00

4. PWM_DynamicDutyCycle on Arduino AVR Mega2560

The following is the sample terminal output when running example PWM_DynamicDutyCycle on AVR Mega2560, to demonstrate the ability to provide high PWM frequencies and ability to change DutyCycle on-the-fly.

Starting PWM_DynamicDutyCycle on Arduino AVR Mega2560/ADK
AVR_PWM v1.0.0
[PWM] AVR_PWM: _dutycycle = 32767
[PWM] setPWM_Int: _dutycycle = 32767
[PWM] setPWM_Int:using TIMER4C
[PWM] setPeriod_Timer4: F_CPU = 16000000 , cycles = 1600
[PWM] setPeriod_Timer4: clockSelectBits = 1 , pwmPeriod = 1600
[PWM] setPWM_Int:using TIMER4C, _dutycycle = 799
=====================================================================================
Change PWM DutyCycle to 90.00
[PWM] setPWM: _dutycycle = 58981
[PWM] setPWM_Int: _dutycycle = 58981
[PWM] setPWM_Int:using TIMER4C
[PWM] setPeriod_Timer4: F_CPU = 16000000 , cycles = 8000
[PWM] setPeriod_Timer4: clockSelectBits = 1 , pwmPeriod = 8000
[PWM] setPWM_Int:using TIMER4C, _dutycycle = 7199
=====================================================================================
Actual data: pin = 8, PWM DC = 89.99, PWMPeriod = 8000.00, PWM Freq (Hz) = 1000.0000
=====================================================================================
Change PWM DutyCycle to 10.00
[PWM] setPWM: _dutycycle = 6553
[PWM] setPWM_Int: _dutycycle = 6553
[PWM] setPWM_Int:using TIMER4C
[PWM] setPeriod_Timer4: F_CPU = 16000000 , cycles = 8000
[PWM] setPeriod_Timer4: clockSelectBits = 1 , pwmPeriod = 8000
[PWM] setPWM_Int:using TIMER4C, _dutycycle = 799
=====================================================================================
Actual data: pin = 8, PWM DC = 9.99, PWMPeriod = 8000.00, PWM Freq (Hz) = 1000.0000
=====================================================================================
2 Likes

All the examples have 1kHz ... where are these 'high frequencies'?

Maybe I'm not following your meaning...

:smiley_cat:

Thanks for having a look at the library.

You can try using much higher frequencies, up to 100-200KHz, certainly with the catch of lower PWM accuracy because of low F_CPU (16KHz) and only 8 or 16-bit timer registers. Those are just examples to illustrate the features.

The PWM_Waveform example is designed only for 1000Hz, but you can change, provided you adjust the PWM_data array values accordingly


Updated:

The PWM_Waveform example has just been updated to be used with other frequencies besides 1000Hz. The dutycycle values are adjusted automatically according to the actual frequency being used.

:+1: on the high frequency... I have some 20kHz things I'd like to try...

I looked at the instantiation and was wonder if I can configure it for both the pwm and the inverted pwm at the same time..?

Such as this from my Tiny85...

 PB0 ^OC0B  pin 5  DDB0   PWM_NOT
 PB1  OC0B  pin 6  DDB1   PWM
PWM_Instance = new AVR_PWM(PWM_Pins, freq, dutyCycle);

Seems to indicate I can have only one pin configured for pwm output... ?

:smiley_cat:

You must create one independent instance for every PWM pin.

Check PWM_Multi example for how to deal with multiple pins and frequencies, certainly must be on different Timers.

I run my TIny85 with both outputs from the same timer. One is just the following the other, but inverted.


These damn things can be pretty frustrating with all the options... especially when it's been some time...

I did look and I am using PB0 as OC0A and PB1 as ^OC0A for it's inverted output... The documentation in my code was wrong there...

:smiley_cat:

Sorry, I'm not interested in Tiny45 / 85 as they're so old and weak (low memory, frequency, number of pins, etc).

I'm also afraid the library doesn't support them. You're on your own.

Good Luck,

Well thanks... I believe I did this on my first Arduino Uno...

Take care...

:smiley_cat:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.