- Notifications
You must be signed in to change notification settings - Fork0
This library enables you to use Hardware-based PWM channels on Teensy boards, such as Teensy 2.x, Teensy LC, Teensy 3.x, Teensy 4.x, Teensy MicroMod, etc., to create and output PWM to pins. Using the same functions as other FastPWM libraries to enable you to port PWM code easily between platforms.
License
khoih-prog/Teensy_PWM
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
- Why do we need this Teensy_PWM library
- Changelog
- Prerequisites
- Installation
- Packages' Patches
- 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 thisTeensy_PWM library
This hardware-based PWM library, a wrapper and enhancement aroundTeensy PWM code, enables you to use Hardware-PWM onTeensy boards, such as Teensy 2.x, Teensy LC, Teensy 3.x, Teensy 4.x, Teensy MicroMod, etc., etc. usingTeensyduno core, 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 and default resolution is16-bit resolution.
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 onTeensy.
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.
- Teensy boards such as :
- Teensy 4.1, Teensy MicroMod, Teensy 4.0
- Teensy 3.6, 3.5, 3.2/3.1, 3.0
- Teensy LC
- Teensy++ 2.0 and Teensy 2.0
Arduino IDE 1.8.19+for Arduino.Teensy core v1.57+for Teensy 4.1.
The best and easiest way is to useArduino Library Manager. Search forTeensy_PWM, then select / install the latest version.You can also use this link for more detailed instructions.
Another way to install is to:
- Navigate toTeensy_PWM page.
- Download the latest release
Teensy_PWM-main.zip. - Extract the zip file to
Teensy_PWM-maindirectory - Copy whole
Teensy_PWM-mainfolder to Arduino libraries' directory such as~/Arduino/libraries/.
- InstallVS Code
- InstallPlatformIO
- InstallTeensy_PWM library by usingLibrary Manager. Search forTeensy_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
To be able to compile and run on Teensy boards, you have to copy the fileTeensy boards.txt into Teensy hardware directory (./arduino-1.8.19/hardware/teensy/avr/boards.txt).
Supposing the Arduino version is 1.8.19. These files must be copied into the directory:
./arduino-1.8.19/hardware/teensy/avr/boards.txt./arduino-1.8.19/hardware/teensy/avr/cores/teensy/Stream.h./arduino-1.8.19/hardware/teensy/avr/cores/teensy3/Stream.h./arduino-1.8.19/hardware/teensy/avr/cores/teensy4/Stream.h
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zzThis file must be copied into the directory:
./arduino-x.yy.zz/hardware/teensy/avr/boards.txt./arduino-x.yy.zz/hardware/teensy/avr/cores/teensy/Stream.h./arduino-x.yy.zz/hardware/teensy/avr/cores/teensy3/Stream.h./arduino-x.yy.zz/hardware/teensy/avr/cores/teensy4/Stream.h
Before using any PWMTimer andchannel, you have to make sure theTimer andchannel has not been used by any other purpose.
Teensy_PWM* PWM_Instance;PWM_Instance =new Teensy_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_StepperControl
ExamplePWM_Multi
Teensy_PWM/examples/PWM_Multi/PWM_Multi.ino
Lines 11 to 113 ind0c7f2a
| #define_PWM_LOGLEVEL_4 | |
| #include"Teensy_PWM.h" | |
| #defineUSING_FLEX_TIMERStrue | |
| // To select correct pins from different timers for different frequencies | |
| // For example, pin 7/FlexPWM1_3_B and pin8/FlexPWM1_3_A will have same frequency, etc. | |
| // For the whole list, check Teensy_PWM.h or README.md | |
| #if USING_FLEX_TIMERS | |
| // Using FlexTimers | |
| uint32_t PWM_Pins[] = {4,5,6,7 }; | |
| #else | |
| // Using QuadTimers | |
| uint32_t PWM_Pins[] = {10,11,14,15 }; | |
| #endif | |
| float frequency[] = {2000.0f,3000.0f,4000.0f,8000.0f }; | |
| float dutyCycle[] = {10.0f,30.0f,50.0f,90.0f }; | |
| #defineNUM_OF_PINS (sizeof(PWM_Pins) /sizeof(uint32_t) ) | |
| Teensy_PWM* PWM_Instance[NUM_OF_PINS]; | |
| char dashLine[] ="====================================================================================="; | |
| voidprintPWMInfo(Teensy_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_FLEX_TIMERS | |
| Serial.print(F("\nStarting PWM_Multi using FlexTimers on")); | |
| #else | |
| Serial.print(F("\nStarting PWM_Multi using QuadTimers on")); | |
| #endif | |
| Serial.println(BOARD_NAME); | |
| Serial.println(TEENSY_PWM_VERSION); | |
| for (uint8_t index =0; index < NUM_OF_PINS; index++) | |
| { | |
| PWM_Instance[index] =newTeensy_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_t index =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_t index =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 using FlexTimers onTeensy 4.0, to demonstrate the ability to provide high PWM frequencies and ability to change DutyCycleon-the-fly
Starting PWM_DynamicDutyCycleusing FlexTimers on Teensy4.0Teensy_PWM v1.1.1[PWM] setupPWM: Mapping dutycycle =0 to newDC =0for _resolution =16[PWM] setupPWM: Using FlexTimer2 moduleIndex =1for PWM pin =5=====================================================================================Change PWM DutyCycle to90.00[PWM] setPWM: _dutycycle =58982 , frequency =5000.00[PWM] setPWM_Int: dutycycle =58982 , frequency =5000.00[PWM] setupPWM: Mapping dutycycle =58982 to newDC =58982for _resolution =16=====================================================================================Actual data: pin =5, 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: Mapping dutycycle = 13107 to newDC = 13107 for _resolution = 16=====================================================================================Actual data: pin = 5, 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: Mapping dutycycle = 58982 to newDC = 58982 for _resolution = 16=====================================================================================Actual data: pin = 5, 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: Mapping dutycycle = 13107 to newDC = 13107 for _resolution = 16=====================================================================================Actual data: pin = 5, PWM DC = 20.00, PWMPeriod = 200.00, PWM Freq (Hz) = 5000.0000=====================================================================================
The following is the sample terminal output when running examplePWM_Multi using QuadTimers onTeensy 4.0, to demonstrate the ability to provide high PWM frequencies on multiplePWM-capable pins
Starting PWM_Multiusing QuadTimers on Teensy4.0Teensy_PWM v1.1.1[PWM] setupPWM: Mapping dutycycle =6554 to newDC =6554for _resolution =16[PWM] setupPWM: Using QuadTimer1 moduleIndex =0for PWM pin =10[PWM] setPWM_Int: dutycycle =6554 , frequency =2000.00[PWM] setupPWM: Mapping dutycycle =6554 to newDC =6554for _resolution =16[PWM] setupPWM: Mapping dutycycle =19661 to newDC =19661for _resolution =16[PWM] setupPWM: Using QuadTimer1 moduleIndex =2for PWM pin =11[PWM] setPWM_Int: dutycycle =19661 , frequency =3000.00[PWM] setupPWM: Mapping dutycycle =19661 to newDC =19661for _resolution =16[PWM] setupPWM: Mapping dutycycle =32768 to newDC =32768for _resolution =16[PWM] setupPWM: Using QuadTimer3 moduleIndex =2for PWM pin =14[PWM] setPWM_Int: dutycycle =32768 , frequency =4000.00[PWM] setupPWM: Mapping dutycycle =32768 to newDC =32768for _resolution =16[PWM] setupPWM: Mapping dutycycle =58982 to newDC =58982for _resolution =16[PWM] setupPWM: Using QuadTimer3 moduleIndex =3for PWM pin =15[PWM] setPWM_Int: dutycycle =58982 , frequency =8000.00[PWM] setupPWM: Mapping dutycycle =58982 to newDC =58982for _resolution =16=====================================================================================IndexPinPWM_freqDutyCycleActual Freq=====================================================================================0102000.0010.002000.00001113000.0030.003000.00002144000.0050.004000.00003158000.0090.008000.0000=====================================================================================Actual data: pin =10, PWM DC =10.00, PWMPeriod =500.00, PWMFreq (Hz) = 2000.0000==========================================================================================================================================================================Actual data: pin = 11, PWM DC = 30.00, PWMPeriod = 333.33, PWM Freq (Hz) = 3000.0000==========================================================================================================================================================================Actual data: pin = 14, PWM DC = 50.00, PWMPeriod = 250.00, PWM Freq (Hz) = 4000.0000==========================================================================================================================================================================Actual data: pin = 15, PWM DC = 90.00, PWMPeriod = 125.00, PWM Freq (Hz) = 8000.0000=====================================================================================
The following is the sample terminal output when running examplePWM_DynamicFreq using FlexTimers onTeensy 4.0, to demonstrate the ability to change dynamically PWM frequencies
Starting PWM_DynamicFrequsing FlexTimers on Teensy4.0Teensy_PWM v1.1.1[PWM] setupPWM: Mapping dutycycle =32768 to newDC =32768for _resolution =16[PWM] setupPWM: Using FlexTimer2 moduleIndex =1for PWM pin =5=====================================================================================Change PWM Freq to20000.00[PWM] setPWM: _dutycycle =32768 , frequency =20000.00[PWM] setPWM_Int: dutycycle =32768 , frequency =20000.00[PWM] setupPWM: Mapping dutycycle =32768 to newDC =32768for _resolution =16=====================================================================================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: Mapping dutycycle = 32768 to newDC = 32768 for _resolution = 16=====================================================================================Actual data: pin = 5, PWM DC = 50.00, PWMPeriod = 100.00, PWM Freq (Hz) = 10000.0000=====================================================================================
The following is the sample terminal output when running examplePWM_Waveform using FlexTimers onTeensy 4.0, to demonstrate how to use thesetPWM_manual() function in wafeform creation
Starting PWM_Waveformusing FlexTimers on Teensy4.0Teensy_PWM v1.1.1[PWM] setupPWM: Mapping dutycycle =0 to newDC =0for _resolution =16[PWM] setupPWM: Using FlexTimer2 moduleIndex =1for PWM pin =5[PWM] setPWM: _dutycycle =0 , frequency =2000.00[PWM] setPWM_Int: dutycycle =0 , frequency =2000.00[PWM] setupPWM: Mapping dutycycle =0 to newDC =0for _resolution =16============================================================================================Actual data: pin =5, PWM DutyCycle =0.00, PWMPeriod =500.00, PWMFreq (Hz) = 2000.0000============================================================================================[PWM] setPWM_manual: _dutycycle = 0 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 0 to newDC = 0 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 3276 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 3276 to newDC = 3276 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 6553 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 6553 to newDC = 6553 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 9830 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 9830 to newDC = 9830 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 13107 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 13107 to newDC = 13107 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 16383 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 16383 to newDC = 16383 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 19660 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 19660 to newDC = 19660 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 22937 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 22937 to newDC = 22937 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 26214 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 26214 to newDC = 26214 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 29490 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 29490 to newDC = 29490 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 32767 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 32767 to newDC = 32767 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 36044 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 36044 to newDC = 36044 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 39321 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 39321 to newDC = 39321 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 42597 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 42597 to newDC = 42597 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 45874 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 45874 to newDC = 45874 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 49151 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 49151 to newDC = 49151 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 52428 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 52428 to newDC = 52428 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 55704 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 55704 to newDC = 55704 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 58981 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 58981 to newDC = 58981 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 62258 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 62258 to newDC = 62258 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 65535 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 65535 to newDC = 65535 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 62258 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 62258 to newDC = 62258 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 58981 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 58981 to newDC = 58981 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 55704 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 55704 to newDC = 55704 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 52428 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 52428 to newDC = 52428 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 49151 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 49151 to newDC = 49151 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 45874 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 45874 to newDC = 45874 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 42597 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 42597 to newDC = 42597 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 39321 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 39321 to newDC = 39321 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 36044 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 36044 to newDC = 36044 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 32767 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 32767 to newDC = 32767 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 29490 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 29490 to newDC = 29490 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 26214 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 26214 to newDC = 26214 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 22937 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 22937 to newDC = 22937 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 19660 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 19660 to newDC = 19660 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 16383 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 16383 to newDC = 16383 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 13107 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 13107 to newDC = 13107 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 9830 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 9830 to newDC = 9830 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 6553 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 6553 to newDC = 6553 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 3276 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 3276 to newDC = 3276 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 0 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 0 to newDC = 0 for _resolution = 16
The following is the sample terminal output when running examplePWM_Waveform using QuadTimers onTeensy 4.0, to demonstrate how to use thesetPWM_manual() function in wafeform creation
Starting PWM_Waveformusing QuadTimers on Teensy4.0Teensy_PWM v1.1.1[PWM] setupPWM: Mapping dutycycle =0 to newDC =0for _resolution =16[PWM] setupPWM: Using QuadTimer3 moduleIndex =3for PWM pin =15[PWM] setPWM: _dutycycle =0 , frequency =2000.00[PWM] setPWM_Int: dutycycle =0 , frequency =2000.00[PWM] setupPWM: Mapping dutycycle =0 to newDC =0for _resolution =16============================================================================================Actual data: pin =15, PWM DutyCycle =0.00, PWMPeriod =500.00, PWMFreq (Hz) = 2000.0000============================================================================================[PWM] setPWM_manual: _dutycycle = 0 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 0 to newDC = 0 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 3276 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 3276 to newDC = 3276 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 6553 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 6553 to newDC = 6553 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 9830 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 9830 to newDC = 9830 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 13107 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 13107 to newDC = 13107 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 16383 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 16383 to newDC = 16383 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 19660 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 19660 to newDC = 19660 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 22937 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 22937 to newDC = 22937 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 26214 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 26214 to newDC = 26214 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 29490 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 29490 to newDC = 29490 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 32767 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 32767 to newDC = 32767 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 36044 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 36044 to newDC = 36044 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 39321 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 39321 to newDC = 39321 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 42597 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 42597 to newDC = 42597 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 45874 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 45874 to newDC = 45874 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 49151 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 49151 to newDC = 49151 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 52428 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 52428 to newDC = 52428 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 55704 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 55704 to newDC = 55704 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 58981 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 58981 to newDC = 58981 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 62258 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 62258 to newDC = 62258 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 65535 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 65535 to newDC = 65535 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 62258 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 62258 to newDC = 62258 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 58981 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 58981 to newDC = 58981 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 55704 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 55704 to newDC = 55704 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 52428 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 52428 to newDC = 52428 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 49151 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 49151 to newDC = 49151 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 45874 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 45874 to newDC = 45874 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 42597 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 42597 to newDC = 42597 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 39321 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 39321 to newDC = 39321 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 36044 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 36044 to newDC = 36044 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 32767 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 32767 to newDC = 32767 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 29490 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 29490 to newDC = 29490 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 26214 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 26214 to newDC = 26214 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 22937 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 22937 to newDC = 22937 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 19660 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 19660 to newDC = 19660 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 16383 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 16383 to newDC = 16383 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 13107 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 13107 to newDC = 13107 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 9830 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 9830 to newDC = 9830 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 6553 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 6553 to newDC = 6553 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 3276 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 3276 to newDC = 3276 for _resolution = 16[PWM] setPWM_manual: _dutycycle = 0 , frequency = 2000.00[PWM] setupPWM: Mapping dutycycle = 0 to newDC = 0 for _resolution = 16
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:Teensy_PWM issues
- Search for bug and improvement.
- Support toTeensy 2.x
- Basic hardware PWM-channels forTeensy 4.x boards, such as Teensy 4.0, Teensy 4.1, Teensy MicroMod, etc., usingTeensyduno core.
- Add support toTeensy 3.x and Teensy LC
- 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 enables you to use Hardware-based PWM channels on Teensy boards, such as Teensy 2.x, Teensy LC, Teensy 3.x, Teensy 4.x, Teensy MicroMod, etc., to create and output PWM to pins. Using the same functions as other FastPWM libraries to enable you to port PWM code easily between platforms.
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.

