- Notifications
You must be signed in to change notification settings - Fork0
This library, a wrapper around SAM DUE analogWrite() function, enables you to use Hardware-based PWM channels on SAM_DUE boards to create and output PWM to pins. Using similar functions as some other FastPWM libraries, it enables you to port PWM code easily between platforms
License
khoih-prog/SAMDUE_PWM
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
- Why do we need this SAMDUE_PWM library
- Changelog
- Prerequisites
- Installation
- Usage
- Examples
- Example PWM_Multi
- Debug Terminal Output Samples
- Debug
- Troubleshooting
- Issues
- TO DO
- DONE
- Contributions and Thanks
- Contributing
- License
- Copyright
Why do we need thisSAMDUE_PWM library
This hardware-based PWM library enables you to use Hardware-PWM onSAM_DUE boards to create and output PWM. These purely hardware-based PWM channels can generate very high PWM frequencies, depending on CPU clock and acceptable accuracy. The maximum resolution is only8-bit resolution.
This library is based onanalogWrite()
function inwiring_analog.c
of Arduino SAM_DUE core, to enable dynamic frequencies and dutycycles.
This library is using thesame or similar functions as other FastPWM libraries, as follows, to enable you toport your PWM code easily between platforms
- RP2040_PWM
- AVR_PWM
- megaAVR_PWM
- ESP32_FastPWM
- SAMD_PWM
- SAMDUE_PWM
- nRF52_PWM
- Teensy_PWM
- ATtiny_PWM
- Dx_PWM
- Portenta_H7_PWM
- MBED_RP2040_PWM
- nRF52_MBED_PWM
- STM32_PWM
The most important feature is they're purely hardware-based PWM channels. Therefore, their operations arenot blocked by bad-behaving software functions / tasks.
This important feature is absolutely necessary for mission-critical tasks. These hardware PWM-channels, still work even if other software functions are blocking. Moreover, they are much more precise (certainly depending on clock frequency accuracy) than other software timers usingmillis()
ormicros()
. That's necessary if you need to control external systems (Servo, etc.) requiring better accuracy.
New efficientsetPWM_manual()
function enables waveform creation using PWM.
ThePWM_Multi example will demonstrate the usage of multichannel PWM using multiple Hardware-PWM blocks (Timer & Channel). The 4 independent Hardware-PWM channels are usedto control 4 different PWM outputs, with totally independent frequencies and dutycycles onSAM_DUE
.
Being hardware-based PWM, their executions are not blocked by bad-behaving functions / tasks, such as connecting to WiFi, Internet or Blynk services.
This non-being-blocked important feature is absolutely necessary for mission-critical tasks.
Imagine you have a system with amission-critical function, controlling a robot or doing something much more important. You normally use a software timer to poll, or even place the function inloop()
. But what if another function isblocking theloop()
orsetup()
.
So your functionmight not be executed, and the result would be disastrous.
You'd prefer to have your function called, no matter what happening with other functions (busy loop, bug, etc.).
The correct choice is to usehardware-based PWM
.
These hardware-based PWM channels still work even if other software functions are blocking. Moreover, they are much moreprecise (certainly depending on clock frequency accuracy) than other software-based PWMs, usingmillis()
ormicros()
.
Functions using normal software-based PWMs, relying onloop()
and callingmillis()
, won't work if theloop()
orsetup()
is blocked by certain operation. For example, certain function is blocking while it's connecting to WiFi or some services.
- SAM_DUE boards, using
Arduino SAM core
The best and easiest way is to useArduino Library Manager
. Search forSAMDUE_PWM, then select / install the latest version.You can also use this link for more detailed instructions.
Another way to install is to:
- Navigate toSAMDUE_PWM page.
- Download the latest release
SAMDUE_PWM-main.zip
. - Extract the zip file to
SAMDUE_PWM-main
directory - Copy whole
SAMDUE_PWM-main
folder to Arduino libraries' directory such as~/Arduino/libraries/
.
- InstallVS Code
- InstallPlatformIO
- InstallSAMDUE_PWM library by usingLibrary Manager. Search forSAMDUE_PWM inPlatform.io Author's Libraries
- Use includedplatformio.ini file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples atProject Configuration File
Before using any PWMTimer
andchannel
, you have to make sure theTimer
andchannel
has not been used by any other purpose.
// SAM_DUE:// PWM pins: 6, 7, 8, 9// Timer pins: 2-5, 10-13.// pin2: TC0_CHA0, pin3: TC2_CHA7, pin4: TC2_CHB6, pin5: TC2_CHA6// pin 10: TC2_CHB7, pin11: TC2_CHA8, pin12: TC2_CHB8, pin13: TC0_CHB0
SAMDUE_PWM* PWM_Instance;PWM_Instance =new SAMDUE_PWM(pinToUse, frequency, dutyCycle, channel, PWM_resolution);
if (PWM_Instance){ PWM_Instance->setPWM();}
To usefloat new_dutyCycle
PWM_Instance->setPWM(PWM_Pins, new_frequency, new_dutyCycle);
such as
dutyCycle =10.0f; Serial.print(F("Change PWM DutyCycle to")); Serial.println(dutyCycle);PWM_Instance->setPWM(pinToUse, frequency, dutyCycle);
To useuint32_t new_dutyCycle
=(real_dutyCycle * 65536) / 100
PWM_Instance->setPWM_Int(PWM_Pins, new_frequency, new_dutyCycle);
such as forreal_dutyCycle = 50%
// 50% dutyCycle = (real_dutyCycle * 65536) / 100dutyCycle =32768;Serial.print(F("Change PWM DutyCycle to (%)"));Serial.println((float) dutyCycle *100 /65536);PWM_Instance->setPWM_Int(pinToUse, frequency, dutyCycle);
forreal_dutyCycle = 50%
// 20% dutyCycle = (real_dutyCycle * 65536) / 100dutyCycle =13107;Serial.print(F("Change PWM DutyCycle to (%)"));Serial.println((float) dutyCycle *100 /65536);PWM_Instance->setPWM_Int(pinToUse, frequency, dutyCycle);
Function prototype
boolsetPWM_manual(constuint8_t& pin,constuint16_t& DCValue);
Need to call only once for each pin
PWM_Instance->setPWM(PWM_Pins, frequency, dutyCycle);
after that, if just changingdutyCycle
/level
, use
PWM_Instance->setPWM_manual(PWM_Pins, new_level);
- PWM_Basic
- PWM_DynamicDutyCycle
- PWM_DynamicDutyCycle_Int
- PWM_DynamicFreq
- PWM_Multi
- PWM_MultiChannel
- PWM_Waveform
- PWM_StepperControlNew
ExamplePWM_Multi
SAMDUE_PWM/examples/PWM_Multi/PWM_Multi.ino
Lines 11 to 117 ina5ac09f
#define_PWM_LOGLEVEL_4 | |
// Can't use PWM for different frequencies | |
#defineUSING_TIMERtrue | |
#include"SAMDUE_PWM.h" | |
// SAM_DUE: | |
// PWM pins: 6, 7, 8, 9 ===> must be same frequency | |
// Timer pins: 2-5, 10-13. | |
// pin2: TC0_CHA0, pin3: TC2_CHA7, pin4: TC2_CHB6, pin5: TC2_CHA6 | |
// pin10: TC2_CHB7, pin11: TC2_CHA8, pin12: TC2_CHB8, pin13: TC0_CHB0 | |
#if USING_TIMER | |
// To select correct pins for different frequencies | |
uint32_t PWM_Pins[] = {2,3,5,11 }; | |
float frequency[] = {2000.0f,3000.0f,4000.0f,8000.0f }; | |
#else | |
// always same frequency | |
uint32_t PWM_Pins[] = {6,7,8,9 }; | |
float frequency[] = {2000.0f,2000.0f,2000.0f,2000.0f }; | |
#endif | |
#defineNUM_OF_PINS (sizeof(PWM_Pins) /sizeof(uint32_t) ) | |
float dutyCycle[] = {10.0f,30.0f,50.0f,90.0f }; | |
SAMDUE_PWM* PWM_Instance[NUM_OF_PINS]; | |
char dashLine[] ="====================================================================================="; | |
voidprintPWMInfo(SAMDUE_PWM* PWM_Instance) | |
{ | |
Serial.println(dashLine); | |
Serial.print("Actual data: pin ="); | |
Serial.print(PWM_Instance->getPin()); | |
Serial.print(", PWM DC ="); | |
Serial.print(PWM_Instance->getActualDutyCycle()); | |
Serial.print(", PWMPeriod ="); | |
Serial.print(PWM_Instance->getPWMPeriod()); | |
Serial.print(", PWM Freq (Hz) ="); | |
Serial.println(PWM_Instance->getActualFreq(),4); | |
Serial.println(dashLine); | |
} | |
voidsetup() | |
{ | |
Serial.begin(115200); | |
while (!Serial &&millis() <5000); | |
delay(500); | |
#if USING_TIMER | |
Serial.print(F("\nStarting PWM_Multi using Timer on")); | |
#else | |
Serial.print(F("\nStarting PWM_Multi using PWM on")); | |
#endif | |
Serial.println(BOARD_NAME); | |
Serial.println(SAMDUE_PWM_VERSION); | |
for (uint8_tindex =0;index < NUM_OF_PINS;index++) | |
{ | |
PWM_Instance[index] =newSAMDUE_PWM(PWM_Pins[index], frequency[index], dutyCycle[index]); | |
if (PWM_Instance[index]) | |
{ | |
PWM_Instance[index]->setPWM(); | |
} | |
} | |
Serial.println(dashLine); | |
Serial.println("Index\tPin\tPWM_freq\tDutyCycle\tActual Freq"); | |
Serial.println(dashLine); | |
for (uint8_tindex =0;index < NUM_OF_PINS;index++) | |
{ | |
if (PWM_Instance[index]) | |
{ | |
Serial.print(index); | |
Serial.print("\t"); | |
Serial.print(PWM_Pins[index]); | |
Serial.print("\t"); | |
Serial.print(frequency[index]); | |
Serial.print("\t\t"); | |
Serial.print(dutyCycle[index]); | |
Serial.print("\t\t"); | |
Serial.println(PWM_Instance[index]->getActualFreq(),4); | |
} | |
else | |
{ | |
Serial.println(); | |
} | |
} | |
for (uint8_tindex =0;index < NUM_OF_PINS;index++) | |
{ | |
printPWMInfo(PWM_Instance[index]); | |
} | |
} | |
voidloop() | |
{ | |
//Long delay has no effect on the operation of hardware-based PWM channels | |
delay(1000000); | |
} |
The following is the sample terminal output when running examplePWM_DynamicDutyCycle onSAM_DUE, to demonstrate the ability to provide high PWM frequencies and ability to change DutyCycleon-the-fly
usingPWM
Starting PWM_DynamicDutyCycleusing PWM on SAM_DUESAMDUE_PWM v1.0.1[PWM] setupPWM: _pin =6 , _pinAttr =12 , frequency =5000 , _dutycycle =0[PWM] setupPWM: Not PWMEnabled, PWMC_ConfigureClocks, frequency =5000[PWM] setupPWM:new _pin =6 , _channel =7[PWM] setupPWM: _channel =7 , _dutycycle =0=====================================================================================Change PWM DutyCycle to90.00[PWM] setPWM: _dutycycle =58982 , frequency =5000.00[PWM] setPWM_Int: dutycycle =58982 , frequency =5000.00[PWM] setupPWM: _pin =6 , _pinAttr =12 , frequency =5000 , _dutycycle =58982[PWM] setupPWM: _channel =7 , _dutycycle =58982=====================================================================================Actual data: pin =6, PWM DC =90.00, PWMPeriod =200.00, PWMFreq (Hz) = 5000.0000=====================================================================================Change PWM DutyCycle to 20.00[PWM] setPWM: _dutycycle = 13107 , frequency = 5000.00[PWM] setPWM_Int: dutycycle = 13107 , frequency = 5000.00[PWM] setupPWM: _pin = 6 , _pinAttr = 12 , frequency = 5000 , _dutycycle = 13107[PWM] setupPWM: _channel = 7 , _dutycycle = 13107=====================================================================================Actual data: pin = 6, PWM DC = 20.00, PWMPeriod = 200.00, PWM Freq (Hz) = 5000.0000=====================================================================================Change PWM DutyCycle to 90.00[PWM] setPWM: _dutycycle = 58982 , frequency = 5000.00[PWM] setPWM_Int: dutycycle = 58982 , frequency = 5000.00[PWM] setupPWM: _pin = 6 , _pinAttr = 12 , frequency = 5000 , _dutycycle = 58982[PWM] setupPWM: _channel = 7 , _dutycycle = 58982=====================================================================================Actual data: pin = 6, PWM DC = 90.00, PWMPeriod = 200.00, PWM Freq (Hz) = 5000.0000=====================================================================================Change PWM DutyCycle to 20.00[PWM] setPWM: _dutycycle = 13107 , frequency = 5000.00[PWM] setPWM_Int: dutycycle = 13107 , frequency = 5000.00[PWM] setupPWM: _pin = 6 , _pinAttr = 12 , frequency = 5000 , _dutycycle = 13107[PWM] setupPWM: _channel = 7 , _dutycycle = 13107=====================================================================================Actual data: pin = 6, PWM DC = 20.00, PWMPeriod = 200.00, PWM Freq (Hz) = 5000.0000=====================================================================================
The following is the sample terminal output when running examplePWM_Multi onSAM_DUE, to demonstrate the ability to provide high PWM frequencies on multiplePWM-capable
pins usingTimer for PWM
Starting PWM_Multiusing Timer on SAM_DUESAMDUE_PWM v1.0.1[PWM] setupPWM Timer: _pin =2 , _pinAttr =20 , frequency =2000 , dutycycle =2058[PWM] setupPWMnew Timer, frequency =2000[PWM] setupPWM Timer: _pin =2 , _pinAttr =20 , frequency =2000 , dutycycle =2058[PWM] setupPWM Timer: _pin =3 , _pinAttr =20 , frequency =3000 , dutycycle =4172[PWM] setupPWMnew Timer, frequency =3000[PWM] setupPWM Timer: _pin =3 , _pinAttr =20 , frequency =3000 , dutycycle =4172[PWM] setupPWM Timer: _pin =5 , _pinAttr =20 , frequency =4000 , dutycycle =5270[PWM] setupPWMnew Timer, frequency =4000[PWM] setupPWM Timer: _pin =5 , _pinAttr =20 , frequency =4000 , dutycycle =5270[PWM] setupPWM Timer: _pin =11 , _pinAttr =20 , frequency =8000 , dutycycle =4735[PWM] setupPWMnew Timer, frequency =8000[PWM] setupPWM Timer: _pin =11 , _pinAttr =20 , frequency =8000 , dutycycle =4735=====================================================================================IndexPinPWM_freqDutyCycleActual Freq=====================================================================================022000.0010.002000.0000133000.0030.003000.0000254000.0050.004000.00003118000.0090.008000.0000=====================================================================================Actual data: pin =2, PWM DC =10.00, PWMPeriod =500.00, PWMFreq (Hz) = 2000.0000==========================================================================================================================================================================Actual data: pin = 3, PWM DC = 30.00, PWMPeriod = 333.33, PWM Freq (Hz) = 3000.0000==========================================================================================================================================================================Actual data: pin = 5, PWM DC = 50.00, PWMPeriod = 250.00, PWM Freq (Hz) = 4000.0000==========================================================================================================================================================================Actual data: pin = 11, PWM DC = 90.00, PWMPeriod = 125.00, PWM Freq (Hz) = 8000.0000=====================================================================================
The following is the sample terminal output when running examplePWM_DynamicFreq onSAM_DUE, to demonstrate the ability to change dynamically PWM frequencies usingTimer for PWM
Starting PWM_DynamicFrequsing Timer on SAM_DUESAMDUE_PWM v1.0.1[PWM] setupPWM Timer: _pin =5 , _pinAttr =20 , frequency =10000 , dutycycle =2108[PWM] setupPWMnew Timer, frequency =10000=====================================================================================Change PWM Freq to20000.00[PWM] setPWM: _dutycycle =32768 , frequency =20000.00[PWM] setPWM_Int: dutycycle =32768 , frequency =20000.00[PWM] setupPWM Timer: _pin =5 , _pinAttr =20 , frequency =20000 , dutycycle =1054[PWM] setupPWM: change frequency to20000 from10000.00=====================================================================================Actual data: pin =5, PWM DC =50.00, PWMPeriod =50.00, PWMFreq (Hz) = 20000.0000=====================================================================================Change PWM Freq to 10000.00[PWM] setPWM: _dutycycle = 32768 , frequency = 10000.00[PWM] setPWM_Int: dutycycle = 32768 , frequency = 10000.00[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 10000 , dutycycle = 2108[PWM] setupPWM: change frequency to 10000 from 20000.00=====================================================================================Actual data: pin = 5, PWM DC = 50.00, PWMPeriod = 100.00, PWM Freq (Hz) = 10000.0000=====================================================================================Change PWM Freq to 20000.00[PWM] setPWM: _dutycycle = 32768 , frequency = 20000.00[PWM] setPWM_Int: dutycycle = 32768 , frequency = 20000.00[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 20000 , dutycycle = 1054[PWM] setupPWM: change frequency to 20000 from 10000.00=====================================================================================Actual data: pin = 5, PWM DC = 50.00, PWMPeriod = 50.00, PWM Freq (Hz) = 20000.0000=====================================================================================
The following is the sample terminal output when running examplePWM_Waveform onSAM_DUE, to demonstrate how to use thesetPWM_manual()
function in wafeform creation usingPWM for PWM
Starting PWM_Waveformusing PWM on SAM_DUESAMDUE_PWM v1.0.1[PWM] setupPWM: _pinAttr =12 , frequency =2000 , _dutycycle =0[PWM] setupPWM: Not PWMEnabled, PWMC_ConfigureClocks, frequency =2000[PWM] setupPWM:new _pin =6 , _channel =7[PWM] setupPWM: _channel =7 , _dutycycle =0[PWM] setPWM: _dutycycle =0 , frequency =2000.00[PWM] setupPWM: _pinAttr =12 , frequency =2000 , _dutycycle =0[PWM] setupPWM: _channel =7 , _dutycycle =0============================================================================================Actual data: pin =6, PWM DutyCycle =0.00, PWMPeriod =500.00, PWMFreq (Hz) = 2000.0000============================================================================================[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 0[PWM] setupPWM: _channel = 7 , _dutycycle = 0[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 3276[PWM] setupPWM: _channel = 7 , _dutycycle = 3276[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 6553[PWM] setupPWM: _channel = 7 , _dutycycle = 6553[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 9830[PWM] setupPWM: _channel = 7 , _dutycycle = 9830[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 13107[PWM] setupPWM: _channel = 7 , _dutycycle = 13107[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 16383[PWM] setupPWM: _channel = 7 , _dutycycle = 16383[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 19660[PWM] setupPWM: _channel = 7 , _dutycycle = 19660[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 22937[PWM] setupPWM: _channel = 7 , _dutycycle = 22937[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 26214[PWM] setupPWM: _channel = 7 , _dutycycle = 26214[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 29490[PWM] setupPWM: _channel = 7 , _dutycycle = 29490[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 32767[PWM] setupPWM: _channel = 7 , _dutycycle = 32767[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 36044[PWM] setupPWM: _channel = 7 , _dutycycle = 36044[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 39321[PWM] setupPWM: _channel = 7 , _dutycycle = 39321[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 42597[PWM] setupPWM: _channel = 7 , _dutycycle = 42597[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 45874[PWM] setupPWM: _channel = 7 , _dutycycle = 45874[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 49151[PWM] setupPWM: _channel = 7 , _dutycycle = 49151[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 52428[PWM] setupPWM: _channel = 7 , _dutycycle = 52428[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 55704[PWM] setupPWM: _channel = 7 , _dutycycle = 55704[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 58981[PWM] setupPWM: _channel = 7 , _dutycycle = 58981[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 62258[PWM] setupPWM: _channel = 7 , _dutycycle = 62258[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 65535[PWM] setupPWM: _channel = 7 , _dutycycle = 65535[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 62258[PWM] setupPWM: _channel = 7 , _dutycycle = 62258[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 58981[PWM] setupPWM: _channel = 7 , _dutycycle = 58981[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 55704[PWM] setupPWM: _channel = 7 , _dutycycle = 55704[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 52428[PWM] setupPWM: _channel = 7 , _dutycycle = 52428[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 49151[PWM] setupPWM: _channel = 7 , _dutycycle = 49151[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 45874[PWM] setupPWM: _channel = 7 , _dutycycle = 45874[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 42597[PWM] setupPWM: _channel = 7 , _dutycycle = 42597[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 39321[PWM] setupPWM: _channel = 7 , _dutycycle = 39321[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 36044[PWM] setupPWM: _channel = 7 , _dutycycle = 36044[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 32767[PWM] setupPWM: _channel = 7 , _dutycycle = 32767[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 29490[PWM] setupPWM: _channel = 7 , _dutycycle = 29490[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 26214[PWM] setupPWM: _channel = 7 , _dutycycle = 26214[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 22937[PWM] setupPWM: _channel = 7 , _dutycycle = 22937[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 19660[PWM] setupPWM: _channel = 7 , _dutycycle = 19660[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 16383[PWM] setupPWM: _channel = 7 , _dutycycle = 16383[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 13107[PWM] setupPWM: _channel = 7 , _dutycycle = 13107[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 9830[PWM] setupPWM: _channel = 7 , _dutycycle = 9830[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 6553[PWM] setupPWM: _channel = 7 , _dutycycle = 6553[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 3276[PWM] setupPWM: _channel = 7 , _dutycycle = 3276[PWM] setupPWM: _pinAttr = 12 , frequency = 2000 , _dutycycle = 0[PWM] setupPWM: _channel = 7 , _dutycycle = 0
The following is the sample terminal output when running examplePWM_Waveform onSAM_DUE, to demonstrate how to use thesetPWM_manual()
function in wafeform creation usingTimer for PWM
Starting PWM_Waveformusing Timer on SAM_DUESAMDUE_PWM v1.0.1[PWM] setupPWM Timer: _pin =5 , _pinAttr =20 , frequency =2000 , dutycycle =0[PWM] setupPWMnew Timer, frequency =2000[PWM] setPWM: _dutycycle =0 , frequency =2000.00[PWM] setupPWM Timer: _pin =5 , _pinAttr =20 , frequency =2000 , dutycycle =0============================================================================================Actual data: pin =5, PWM DutyCycle =0.00, PWMPeriod =500.00, PWMFreq (Hz) = 2000.0000============================================================================================[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 0[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 988[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 2058[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 3129[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 4200[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 5188[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 6258[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 7329[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 8400[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 9470[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 10458[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 11529[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 12600[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 13670[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 14741[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 15729[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 16800[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 17870[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 18941[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 20011[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 21000[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 20011[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 18941[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 17870[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 16800[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 15729[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 14741[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 13670[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 12600[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 11529[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 10458[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 9470[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 8400[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 7329[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 6258[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 5188[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 4200[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 3129[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 2058[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 988[PWM] setupPWM Timer: _pin = 5 , _pinAttr = 20 , frequency = 2000 , dutycycle = 0
Debug is enabled by default on Serial.
You can also change the debugging level_PWM_LOGLEVEL_
from 0 to 4
// Don't define _PWM_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.#define_PWM_LOGLEVEL_0
If you get compilation errors, more often than not, you may need to install a newer version of the core for Arduino boards.
Sometimes, the library will only work if you update the board core to the latest version because I am using newly added functions.
Submit issues to:SAMDUE_PWM issues
- Search for bug and improvement.
- Similar features for remaining Arduino boards
- Basic hardware PWM-channels forSAM_DUE boards using
Arduino SAM core
- Add examplePWM_StepperControl to demo how to control Stepper Motor using PWM
Many thanks for everyone for bug reporting, new feature suggesting, testing and contributing to the development of this library.
- Thanks toPaul van Dinther for proposing new way to use PWM to drive Stepper-Motor inUsing PWM to step a stepper driver #16, leading to v2.0.3
![]() Paul van Dinther |
If you want to contribute to this project:
- Report bugs and errors
- Ask for enhancements
- Create issues and pull requests
- Tell other people about this library
- The library is licensed underMIT
Copyright (c) 2022- Khoi Hoang
About
This library, a wrapper around SAM DUE analogWrite() function, enables you to use Hardware-based PWM channels on SAM_DUE boards to create and output PWM to pins. Using similar functions as some other FastPWM libraries, it enables you to port PWM code easily between platforms