Skip to content
This repository was archived by the owner on Feb 4, 2023. It is now read-only.

Commit 4ed15d0

Browse files
authored
v1.6.0 to optimize speed by setPWM_manual_Fast
### Releases v1.6.0 1. Optimize speed with new `setPWM_manual_Fast` function to improve almost 50% compared to `setPWM_manual`. Check 2. Add example [PWM_SpeedTest](https://github.com/khoih-prog/RP2040_PWM/tree/main/examples/PWM_SpeedTest) to demo the better speed of new `setPWM_manual_Fast` function 3. Modify examples [PWM_manual](https://github.com/khoih-prog/RP2040_PWM/tree/main/examples/PWM_manual) to use new `setPWM_manual_Fast` function
1 parent 2ab254c commit 4ed15d0

10 files changed

+252
-24
lines changed

CONTRIBUTING.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ Please be educated, civilized and constructive as you've always been. Disrespect
3333

3434
```
3535
Arduino IDE version: 1.8.19
36-
Arduino-mbed mbed_nano v3.5.4
37-
NANO_RP2040_CONNECT Module
38-
OS: Ubuntu 21.04 LTS
36+
arduino-pico core v2.7.1
37+
RASPBERRY_PI_PICO
38+
OS: Ubuntu 20.04 LTS
3939
Linux xy-Inspiron-3593 5.15.0-58-generic #64~20.04.1-Ubuntu SMP Fri Jan 6 16:42:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
4040
4141
Context:

README.md

+50-10
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
* [ 8. PWM_Basic](examples/PWM_Basic)
4747
* [ 9. PWM_StepperControl](examples/PWM_StepperControl) **New**
4848
* [10. PWM_manual](examples/PWM_manual) **New**
49+
* [11. PWM_SpeedTest](examples/PWM_SpeedTest) **New**
4950
* [Example PWM_Multi](#example-PWM_Multi)
5051
* [Debug Terminal Output Samples](#debug-terminal-output-samples)
5152
* [1. PWM_Multi on MBED RaspberryPi Pico](#1-PWM_Multi-on-MBED-RaspberryPi-Pico)
@@ -56,6 +57,7 @@
5657
* [6. PWM_Waveform on RASPBERRY_PI_PICO](#6-PWM_Waveform-on-RASPBERRY_PI_PICO)
5758
* [7. PWM_Waveform_Fast on RASPBERRY_PI_PICO](#7-PWM_Waveform_Fast-on-RASPBERRY_PI_PICO)
5859
* [8. PWM_manual on RASPBERRY_PI_PICO](#8-PWM_manual-on-RASPBERRY_PI_PICO)
60+
* [9. PWM_SpeedTest on RASPBERRY_PI_PICO](#9-PWM_SpeedTest-on-RASPBERRY_PI_PICO)
5961
* [Debug](#debug)
6062
* [Troubleshooting](#troubleshooting)
6163
* [Issues](#issues)
@@ -288,7 +290,7 @@ after that, if just changing `dutyCycle` / `level`, use
288290
289291
```cpp
290292
// For 50.0f dutycycle
291-
new_level = 50.0f * PWM_Instance->get_TOP() / 100.0f ;
293+
new_level = 50.0f * PWM_Instance->get_TOP() / 100.0f;
292294
PWM_Instance->setPWM_manual(PWM_Pins, new_level);
293295
```
294296

@@ -299,6 +301,14 @@ new_DCPercentage = 50.0f;
299301
PWM_Instance->setPWM_DCPercentage_manual(PWM_Pins, new_DCPercentage);
300302
```
301303
304+
and the fastest
305+
306+
```cpp
307+
// For 50.0f dutycycle
308+
new_level = 50.0f * PWM_Instance->get_TOP() / 100.0f;
309+
PWM_Instance->setPWM_manual_Fast(pinToUse, dutycycle);
310+
```
311+
302312
#### 5. Important Notes
303313

304314
##### When using `phaseCorrect == true`
@@ -349,6 +359,7 @@ PWM_Instance->setPWM_Int(pinToUse, frequency, dutyCycle);
349359
8. [PWM_Basic](examples/PWM_Basic)
350360
9. [PWM_StepperControl](examples/PWM_StepperControl) **New**
351361
10. [PWM_manual](examples/PWM_manual) **New**
362+
11. [PWM_SpeedTest](examples/PWM_SpeedTest) **New**
352363

353364

354365
---
@@ -371,7 +382,7 @@ The following is the sample terminal output when running example [PWM_Multi](exa
371382

372383
```cpp
373384
Starting PWM_Multi on RaspberryPi Pico
374-
RP2040_PWM v1.5.0
385+
RP2040_PWM v1.6.0
375386
=============================================================
376387
Index Pin PWM_freq DutyCycle Actual Freq
377388
=============================================================
@@ -395,7 +406,7 @@ The following is the sample terminal output when running example [**PWM_Multi**]
395406

396407
```cpp
397408
Starting PWM_Multi on RASPBERRY_PI_PICO
398-
RP2040_PWM v1.5.0
409+
RP2040_PWM v1.6.0
399410
=============================================================
400411
Index Pin PWM_freq DutyCycle Actual Freq
401412
=============================================================
@@ -419,7 +430,7 @@ The following is the sample terminal output when running example [**PWM_DynamicF
419430

420431
```cpp
421432
Starting PWM_DynamicFreq on Nano RP2040 Connect
422-
RP2040_PWM v1.5.0
433+
RP2040_PWM v1.6.0
423434
[PWM] _PWM_config.top = 12499 , _actualFrequency = 1000.00
424435
[PWM] PWM enabled, frequency = 1000.00
425436
=============================================================
@@ -464,7 +475,7 @@ The following is the sample terminal output when running example [**PWM_DynamicD
464475

465476
```cpp
466477
Starting PWM_DynamicDutyCycle on RASPBERRY_PI_PICO
467-
RP2040_PWM v1.5.0
478+
RP2040_PWM v1.6.0
468479
[PWM] _PWM_config.top = 13299 , _actualFrequency = 1000.00
469480
[PWM] pin = 25 , PWM_CHAN = 1
470481
[PWM] PWM enabled, slice = 4 , _frequency = 1000.00
@@ -521,7 +532,7 @@ The following is the sample terminal output when running example [**PWM_MultiCha
521532

522533
```cpp
523534
Starting PWM_MultiChannel on RASPBERRY_PI_PICO
524-
RP2040_PWM v1.5.0
535+
RP2040_PWM v1.6.0
525536
=============================================================
526537
Index Pin PWM_freq DutyCycle Actual Freq
527538
=============================================================
@@ -539,7 +550,7 @@ The following is the sample terminal output when running example [**PWM_Waveform
539550

540551
```cpp
541552
Starting PWM_Waveform on RASPBERRY_PI_PICO
542-
RP2040_PWM v1.5.0
553+
RP2040_PWM v1.6.0
543554
[PWM] _PWM_config.top = 12499 , _actualFrequency = 1000.00
544555
[PWM] pin = 10 , PWM_CHAN = 0
545556
[PWM] PWM enabled, slice = 5 , top = 1000 , div = 10 , level = 0
@@ -653,7 +664,7 @@ The following is the sample terminal output when running example [**PWM_Waveform
653664

654665
```cpp
655666
Starting PWM_Waveform_Fast on RASPBERRY_PI_PICO
656-
RP2040_PWM v1.5.0
667+
RP2040_PWM v1.6.0
657668
[PWM] _PWM_config.top = 12499 , _actualFrequency = 1000.00
658669
[PWM] pin = 10 , PWM_CHAN = 0
659670
[PWM] PWM enabled, slice = 5 , top = 1000 , div = 10 , level = 0
@@ -769,7 +780,7 @@ The following is the sample terminal output when running example [**PWM_manual**
769780

770781
```cpp
771782
Starting PWM_manual on RASPBERRY_PI_PICO
772-
RP2040_PWM v1.5.0
783+
RP2040_PWM v1.6.0
773784
=================================================================================================
774785
Actual data: pin = 10, PWM DutyCycle % = 0.00, PWMPeriod = 13299, PWM Freq (Hz) = 1000.0000
775786
=================================================================================================
@@ -806,7 +817,31 @@ Actual data: pin = 10, PWM DutyCycle % = 50.00, PWMPeriod = 13299, PWM Freq (Hz)
806817
...
807818
```
808819
820+
---
821+
822+
### 9. PWM_SpeedTest on RASPBERRY_PI_PICO
809823
824+
The following is the sample terminal output when running example [**PWM_SpeedTest**](examples/PWM_SpeedTest) on **RASPBERRY_PI_PICO**, running [`arduino-pico core`](https://github.com/earlephilhower/arduino-pico), to demonstrate how to use new faster `setPWM_manual_Fast()` function in wafeform creation, The time is `1597ns` compared to `2889ns` when using `setPWM_manual()` function
825+
826+
```cpp
827+
Starting PWM_SpeedTest on RASPBERRY_PI_PICO
828+
RP2040_PWM v1.6.0
829+
=================================================================================================
830+
Actual data: pin = 10, PWM DutyCycle % = 0.00, PWMPeriod = 13299, PWM Freq (Hz) = 1000.0000
831+
=================================================================================================
832+
Average time of setPWM function
833+
ns=1598
834+
ns=1597
835+
ns=1597
836+
ns=1597
837+
ns=1597
838+
ns=1597
839+
ns=1597
840+
ns=1597
841+
ns=1597
842+
ns=1597
843+
...
844+
```
810845
---
811846
---
812847

@@ -868,7 +903,8 @@ Submit issues to: [RP2040_PWM issues](https://github.com/khoih-prog/RP2040_PWM/i
868903
18. Add example [PWM_manual](https://github.com/khoih-prog/RP2040_PWM/tree/main/examples/PWM_manual) to demo how to correctly use PWM to generate waveform
869904
19. Add function `setPWM_DCPercentage_manual()` to facilitate the setting PWM DC manually by using `DCPercentage`, instead of `absolute DCValue` depending on varying `TOP`
870905
20. Add functions `getPin()` and `getActualDutyCycle()`
871-
906+
21. Optimize speed with new `setPWM_manual_Fast` function to improve almost 50% compared to `setPWM_manual`. Check
907+
22. Add example [PWM_SpeedTest](https://github.com/khoih-prog/RP2040_PWM/tree/main/examples/PWM_SpeedTest) to demo the better speed of new `setPWM_manual_Fast` function
872908

873909
---
874910
---
@@ -889,6 +925,7 @@ Many thanks for everyone for bug reporting, new feature suggesting, testing and
889925
- [added minimal viable program to get the user up and running #9](https://github.com/khoih-prog/RP2040_PWM/pull/9) leading to v1.3.1
890926
5. Thanks to [Rocking Y Productions](https://github.com/RockingYProductions) to request enhancement in [Changing Duty Cycle Dynamically Creates Runt PWM pulse #10](https://github.com/khoih-prog/RP2040_PWM/issues/10), leading to v1.4.0
891927
6. Thanks to [Paul van Dinther](https://github.com/dinther) for proposing new way to use PWM to drive `Stepper-Motor` in [Using PWM to step a stepper driver #16](https://github.com/khoih-prog/RP2040_PWM/issues/16), leading to v1.4.1
928+
7. Thanks to [jmdodd95682](https://github.com/jmdodd95682) for open discussion about `setPWM_manual()` speed in [setPWM latency #19](https://github.com/khoih-prog/RP2040_PWM/issues/19), leading to v1.6.0
892929

893930

894931
<table>
@@ -900,6 +937,9 @@ Many thanks for everyone for bug reporting, new feature suggesting, testing and
900937
<td align="center"><a href="https://github.com/RockingYProductions"><img src="https://github.com/RockingYProductions.png" width="100px;" alt="RockingYProductions"/><br /><sub><b>Rocking Y Productions</b></sub></a><br /></td>
901938
<td align="center"><a href="https://github.com/dinther"><img src="https://github.com/dinther.png" width="100px;" alt="dinther"/><br /><sub><b>Paul van Dinther</b></sub></a><br /></td>
902939
</tr>
940+
<tr>
941+
<td align="center"><a href="https://github.com/jmdodd95682"><img src="https://github.com/jmdodd95682.png" width="100px;" alt="jmdodd95682"/><br /><sub><b>jmdodd95682</b></sub></a><br /></td>
942+
</tr>
903943
</table>
904944

905945
---

changelog.md

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
## Table of Contents
1919

2020
* [Changelog](#changelog)
21+
* [Releases v1.6.0](#Releases-v160)
2122
* [Releases v1.5.0](#Releases-v150)
2223
* [Releases v1.4.1](#Releases-v141)
2324
* [Releases v1.4.0](#Releases-v140)
@@ -38,6 +39,12 @@
3839

3940
## Changelog
4041

42+
### Releases v1.6.0
43+
44+
1. Optimize speed with new `setPWM_manual_Fast` function to improve almost 50% compared to `setPWM_manual`. Check
45+
2. Add example [PWM_SpeedTest](https://github.com/khoih-prog/RP2040_PWM/tree/main/examples/PWM_SpeedTest) to demo the better speed of new `setPWM_manual_Fast` function
46+
3. Modify examples [PWM_manual](https://github.com/khoih-prog/RP2040_PWM/tree/main/examples/PWM_manual) to use new `setPWM_manual_Fast` function
47+
4148
### Releases v1.5.0
4249

4350
1. Add example [PWM_manual](https://github.com/khoih-prog/RP2040_PWM/tree/main/examples/PWM_manual) to demo how to correctly use PWM to generate waveform
+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/****************************************************************************************************************************
2+
PWM_SpeedTest.ino
3+
For RP2040 boards
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/RP2040_PWM
7+
Licensed under MIT license
8+
9+
The RP2040 PWM block has 8 identical slices. Each slice can drive two PWM output signals, or measure the frequency
10+
or duty cycle of an input signal. This gives a total of up to 16 controllable PWM outputs. All 30 GPIO pins can be driven
11+
by the PWM block
12+
*****************************************************************************************************************************/
13+
// This example to demo the new function setPWM_manual(uint8_t pin, uint16_t top, uint8_t div, uint16_t level, bool phaseCorrect = false)
14+
// used to generate a waveform. Check https://github.com/khoih-prog/RP2040_PWM/issues/6
15+
16+
#define _PWM_LOGLEVEL_ 2
17+
18+
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
19+
defined(ARDUINO_GENERIC_RP2040) ) && defined(ARDUINO_ARCH_MBED)
20+
21+
#if(_PWM_LOGLEVEL_>3)
22+
#warning USING_MBED_RP2040_PWM
23+
#endif
24+
25+
#elif ( defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
26+
defined(ARDUINO_GENERIC_RP2040) ) && !defined(ARDUINO_ARCH_MBED)
27+
28+
#if(_PWM_LOGLEVEL_>3)
29+
#warning USING_RP2040_PWM
30+
#endif
31+
#else
32+
#error This code is intended to run on the RP2040 mbed_nano, mbed_rp2040 or arduino-pico platform! Please check your Tools->Board setting.
33+
#endif
34+
35+
#include "RP2040_PWM.h"
36+
37+
#define UPDATE_INTERVAL 1000L
38+
39+
#define pinToUse 10
40+
41+
RP2040_PWM* PWM_Instance;
42+
43+
float frequency = 1000.0f;
44+
//float frequency = 10000.0f;
45+
46+
// Using setPWM_DCPercentage_manual if true
47+
#define USING_DC_PERCENT false
48+
//#define USING_DC_PERCENT true
49+
50+
#if USING_DC_PERCENT
51+
float dutycyclePercent = 0.0f;
52+
float DCStepPercent = 5.0f;
53+
#else
54+
uint16_t dutycycle = 0;
55+
uint16_t DCStep;
56+
#endif
57+
58+
uint16_t PWMPeriod;
59+
60+
char dashLine[] = "=================================================================================================";
61+
62+
void printPWMInfo(RP2040_PWM* PWM_Instance)
63+
{
64+
Serial.println(dashLine);
65+
Serial.print("Actual data: pin = ");
66+
Serial.print(PWM_Instance->getPin());
67+
Serial.print(", PWM DutyCycle % = ");
68+
Serial.print(PWM_Instance->getActualDutyCycle() / 1000.0f);
69+
Serial.print(", PWMPeriod = ");
70+
Serial.print(PWM_Instance->get_TOP());
71+
Serial.print(", PWM Freq (Hz) = ");
72+
Serial.println(PWM_Instance->getActualFreq(), 4);
73+
Serial.println(dashLine);
74+
}
75+
76+
void setup()
77+
{
78+
Serial.begin(115200);
79+
80+
while (!Serial && millis() < 5000);
81+
82+
delay(100);
83+
84+
Serial.print(F("\nStarting PWM_SpeedTest on "));
85+
Serial.println(BOARD_NAME);
86+
Serial.println(RP2040_PWM_VERSION);
87+
88+
// Create a dummy instance
89+
PWM_Instance = new RP2040_PWM(pinToUse, frequency, 0);
90+
91+
if (PWM_Instance)
92+
{
93+
uint16_t PWM_TOP = PWM_Instance->get_TOP();
94+
uint16_t PWM_DIV = PWM_Instance->get_DIV();
95+
uint16_t PWM_Level = 0;
96+
97+
// setPWM_manual(uint8_t pin, uint16_t top, uint8_t div, uint16_t level, bool phaseCorrect = false)
98+
PWM_Instance->setPWM_manual(pinToUse, PWM_TOP, PWM_DIV, PWM_Level, true);
99+
100+
PWMPeriod = PWM_Instance->get_TOP();
101+
102+
#if USING_DC_PERCENT
103+
dutycyclePercent = 50.0f;
104+
#else
105+
// 5% steps
106+
DCStep = round( PWMPeriod / 20.0f);
107+
108+
// 50%
109+
dutycycle = PWMPeriod / 2;
110+
#endif
111+
112+
printPWMInfo(PWM_Instance);
113+
}
114+
115+
Serial.println(F("Average time of setPWM function"));
116+
}
117+
118+
void loop()
119+
{
120+
static unsigned long update_timeout = UPDATE_INTERVAL + millis();
121+
static uint64_t count = 0;
122+
123+
#if USING_DC_PERCENT
124+
// 4569ns
125+
PWM_Instance->setPWM_DCPercentage_manual(pinToUse, dutycyclePercent);
126+
#else
127+
// 2889ns
128+
//PWM_Instance->setPWM_manual(pinToUse, dutycycle);
129+
// 1597ns
130+
PWM_Instance->setPWM_manual_Fast(pinToUse, dutycycle);
131+
132+
#endif
133+
134+
count++;
135+
136+
// Update DC every UPDATE_INTERVAL (1000) milliseconds
137+
if (millis() > update_timeout)
138+
{
139+
Serial.print(F("ns="));
140+
Serial.println(UPDATE_INTERVAL * 1000000 / count);
141+
142+
count = 0;
143+
update_timeout = millis() + UPDATE_INTERVAL;
144+
}
145+
}

examples/PWM_manual/PWM_manual.ino

+5-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#define UPDATE_INTERVAL 1000L
3838

3939
// Using setPWM_DCPercentage_manual if true
40-
#define USING_DC_PERCENT true
40+
#define USING_DC_PERCENT false //true
4141

4242
#define LED_ON LOW
4343
#define LED_OFF HIGH
@@ -130,12 +130,14 @@ void loop()
130130
#else
131131
if (dutycycle > PWMPeriod)
132132
{
133-
PWM_Instance->setPWM_manual(pinToUse, PWMPeriod);
133+
//PWM_Instance->setPWM_manual(pinToUse, PWMPeriod);
134+
PWM_Instance->setPWM_manual_Fast(pinToUse, PWMPeriod);
134135
dutycycle = 0;
135136
}
136137
else
137138
{
138-
PWM_Instance->setPWM_manual(pinToUse, dutycycle);
139+
//PWM_Instance->setPWM_manual(pinToUse, dutycycle);
140+
PWM_Instance->setPWM_manual_Fast(pinToUse, dutycycle);
139141
dutycycle += DCStep;
140142
}
141143
#endif

keywords.txt

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ PWM_slice KEYWORD1
1616
setPWM_Int KEYWORD2
1717
setPWM KEYWORD2
1818
setPWM_manual KEYWORD2
19+
setPWM_manual_Fast KEYWORD2
20+
setPWM_DCPercentage_manual KEYWORD2
1921
setPWM_Period KEYWORD2
2022
enablePWM KEYWORD2
2123
disablePWM KEYWORD2

0 commit comments

Comments
 (0)