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

Commit e91722c

Browse files
authored
v1.2.0 to optimize speed, add PWM_SpeedTest, etc
### Releases v1.2.0 1. Optimize speed with new `setPWM_DCPercentageInt_manual` function to improve speed almost 500 times compared to `setPWM` 2. Add example [PWM_manual](https://github.com/khoih-prog/SAMD_PWM/tree/main/examples/PWM_manual) to demo how to correctly use PWM to generate waveform. Check [About DCValue in setPWM_manual #2](khoih-prog/AVR_PWM#2) 3. Add example [PWM_SpeedTest](https://github.com/khoih-prog/SAMD_PWM/tree/main/examples/PWM_SpeedTest) to demo the better speed of new `setPWM_DCPercentageInt_manual` function 4. Breaking change: Modify `setPWM_manual` function to take `16-bit` dutycycle instead from merely `0-100` for better accuracy 5. Modify example [PWM_Waveform](https://github.com/khoih-prog/SAMD_PWM/tree/main/examples/PWM_Waveform) to adapt to breaking change of `setPWM_manual` function 6. Improve `README.md` so that links can be used in other sites, such as `PIO` 7. Bump up to v1.2.0 to sync with other Fast PWM libraries
1 parent cdf0261 commit e91722c

File tree

8 files changed

+586
-73
lines changed

8 files changed

+586
-73
lines changed

README.md

Lines changed: 247 additions & 27 deletions
Large diffs are not rendered by default.

changelog.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,26 @@
1717
## Table of Contents
1818

1919
* [Changelog](#changelog)
20-
* [Releases v1.0.1](#releases-v101)
20+
* [Releases v1.2.0](#Releases-v120)
21+
* [Releases v1.0.1](#Releases-v101)
2122
* [Releases v1.0.0](#releases-v100)
2223

2324
---
2425
---
2526

2627
## Changelog
2728

29+
### Releases v1.2.0
30+
31+
1. Optimize speed with new `setPWM_DCPercentageInt_manual` function to improve speed almost 500 times compared to `setPWM`
32+
2. Add example [PWM_manual](https://github.com/khoih-prog/SAMD_PWM/tree/main/examples/PWM_manual) to demo how to correctly use PWM to generate waveform. Check [About DCValue in setPWM_manual #2](https://github.com/khoih-prog/AVR_PWM/discussions/2)
33+
3. Add example [PWM_SpeedTest](https://github.com/khoih-prog/SAMD_PWM/tree/main/examples/PWM_SpeedTest) to demo the better speed of new `setPWM_DCPercentageInt_manual` function
34+
4. Breaking change: Modify `setPWM_manual` function to take `16-bit` dutycycle instead from merely `0-100` for better accuracy
35+
5. Modify example [PWM_Waveform](https://github.com/khoih-prog/SAMD_PWM/tree/main/examples/PWM_Waveform) to adapt to breaking change of `setPWM_manual` function
36+
6. Improve `README.md` so that links can be used in other sites, such as `PIO`
37+
7. Bump up to v1.2.0 to sync with other Fast PWM libraries
38+
39+
2840
### Releases v1.0.1
2941

3042
1. Add example [PWM_StepperControl](https://github.com/khoih-prog/SAMD_PWM/tree/main/examples/PWM_StepperControl) to demo how to control Stepper Motor using PWM. Check [Using PWM to step a stepper driver #16](https://github.com/khoih-prog/RP2040_PWM/issues/16)
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/****************************************************************************************************************************
2+
PWM_SpeedTest.ino
3+
For SAMD21/SAMD51 boards using hardware-based PWM
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/SAMD_PWM
7+
Licensed under MIT license
8+
*****************************************************************************************************************************/
9+
10+
#define _PWM_LOGLEVEL_ 1
11+
12+
#include "SAMD_PWM.h"
13+
14+
#define UPDATE_INTERVAL 1000L
15+
16+
// Not OK for Nano_33_IoT (0, 1, 7, 8, 13, 14, 15 )
17+
// OK for Nano_33_IoT (2, 3, 4, 5, 6, 9, 10, 11, 12, 16, 17)
18+
// TCC OK => pin 4, 5, 6, 8, 9, 10, 11, 16/A2, 17/A3
19+
// TC OK => pin 12
20+
// For ITSYBITSY_M4
21+
// 16-bit Higher accuracy, Lower Frequency, PWM Pin OK: TCCx: 0-2, 4, 5, 7, 9-13
22+
// 8-bit Lower accuracy, Hi Frequency, PWM Pin OK: TCx: 18-20, 24-25
23+
24+
#define pinToUse 11
25+
26+
//creates pwm instance
27+
SAMD_PWM* PWM_Instance;
28+
29+
float frequency = 2000.0f;
30+
//float frequency = 10000.0f;
31+
32+
// Using setPWM_DCPercentage_manual if true
33+
//#define USING_DC_PERCENT false
34+
#define USING_DC_PERCENT true
35+
36+
#if USING_DC_PERCENT
37+
float dutycyclePercent = 0.0f;
38+
float DCStepPercent = 5.0f;
39+
40+
// dutycyclePercentInt = dutycyclePercent * 65535 / 100
41+
uint16_t dutycyclePercentInt = 0;
42+
#else
43+
uint16_t dutycycle = 0;
44+
uint16_t DCStep;
45+
#endif
46+
47+
uint16_t PWMPeriod;
48+
49+
char dashLine[] = "=================================================================================================";
50+
51+
void printPWMInfo(SAMD_PWM* PWM_Instance)
52+
{
53+
Serial.println(dashLine);
54+
Serial.print("Actual data: pin = ");
55+
Serial.print(PWM_Instance->getPin());
56+
Serial.print(", PWM DC = ");
57+
Serial.print(PWM_Instance->getActualDutyCycle());
58+
Serial.print(", PWMPeriod = ");
59+
Serial.print(PWM_Instance->getPWMPeriod());
60+
Serial.print(", PWM Freq (Hz) = ");
61+
Serial.println(PWM_Instance->getActualFreq(), 4);
62+
Serial.println(dashLine);
63+
}
64+
65+
void setup()
66+
{
67+
Serial.begin(115200);
68+
69+
while (!Serial && millis() < 5000);
70+
71+
delay(100);
72+
73+
Serial.print(F("\nStarting PWM_SpeedTest on "));
74+
Serial.println(BOARD_NAME);
75+
Serial.println(SAMD_PWM_VERSION);
76+
77+
// Create a dummy instance
78+
PWM_Instance = new SAMD_PWM(pinToUse, frequency, 0);
79+
80+
if (PWM_Instance)
81+
{
82+
if (!PWM_Instance->setPWM())
83+
{
84+
Serial.println(F("Stop here"));
85+
86+
// stop here
87+
while (true)
88+
delay(1000);
89+
}
90+
}
91+
92+
#if USING_DC_PERCENT
93+
dutycyclePercent = 50.0f;
94+
95+
// dutycyclePercentInt = dutycyclePercent * 65535 / 100
96+
dutycyclePercentInt = MAX_16BIT / 2;
97+
#else
98+
// 5% steps
99+
DCStep = round( MAX_16BIT / 20.0f);
100+
101+
// 50%
102+
dutycycle = MAX_16BIT / 2;
103+
#endif
104+
105+
Serial.print(F("Average time of setPWM function"));
106+
107+
#if USING_DC_PERCENT
108+
Serial.println(F(" USING_DC_PERCENT"));
109+
#else
110+
Serial.println(F(" not USING_DC_PERCENT"));
111+
#endif
112+
}
113+
114+
void loop()
115+
{
116+
static unsigned long update_timeout = UPDATE_INTERVAL + millis();
117+
static uint32_t count = 0;
118+
119+
#if USING_DC_PERCENT
120+
// Very inefficient, don't use => 499251 ns
121+
//PWM_Instance->setPWM(pinToUse, frequency, dutycyclePercent);
122+
// 1259 ns
123+
//PWM_Instance->setPWM_DCPercentage_manual(pinToUse, dutycyclePercent);
124+
// 1067 ns
125+
PWM_Instance->setPWM_DCPercentageInt_manual(pinToUse, dutycyclePercentInt);
126+
#else
127+
// dutycycle = 0-65535 for 0-100%
128+
// 1084 ns
129+
PWM_Instance->setPWM_manual(pinToUse, dutycycle);
130+
#endif
131+
132+
count++;
133+
134+
// Update DC every UPDATE_INTERVAL (1000) milliseconds
135+
if (millis() > update_timeout)
136+
{
137+
printPWMInfo(PWM_Instance);
138+
139+
Serial.print(F("count="));
140+
Serial.print( count);
141+
Serial.print(F(", ns="));
142+
Serial.println( (uint32_t) (UPDATE_INTERVAL * 1000000 / count));
143+
144+
count = 0;
145+
update_timeout = millis() + UPDATE_INTERVAL;
146+
}
147+
}

examples/PWM_Waveform/PWM_Waveform.ino

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
Licensed under MIT license
99
*****************************************************************************************************************************/
1010

11-
#define _PWM_LOGLEVEL_ 4
11+
#define _PWM_LOGLEVEL_ 1
1212

1313
#include "SAMD_PWM.h"
1414

@@ -33,52 +33,52 @@ typedef struct
3333
// Data for 0-100%
3434
PWD_Data PWM_data[] =
3535
{
36-
{ 0 },
37-
{ 5 },
38-
{ 10 },
39-
{ 15 },
40-
{ 20 },
41-
{ 25 },
42-
{ 30 },
43-
{ 35 },
44-
{ 40 },
45-
{ 45 },
46-
{ 50 },
47-
{ 55 },
48-
{ 60 },
49-
{ 65 },
50-
{ 70 },
51-
{ 75 },
52-
{ 80 },
53-
{ 85 },
54-
{ 90 },
55-
{ 95 },
56-
{ 100 },
57-
{ 95 },
58-
{ 90 },
59-
{ 85 },
60-
{ 80 },
61-
{ 75 },
62-
{ 70 },
63-
{ 65 },
64-
{ 60 },
65-
{ 55 },
66-
{ 50 },
67-
{ 45 },
68-
{ 40 },
69-
{ 35 },
70-
{ 30 },
71-
{ 25 },
72-
{ 20 },
73-
{ 15 },
74-
{ 10 },
75-
{ 5 },
76-
{ 0 },
36+
{ 0 },
37+
{ ( 5 * 65535 ) / 100 },
38+
{ ( 10 * 65535 ) / 100 },
39+
{ ( 15 * 65535 ) / 100 },
40+
{ ( 20 * 65535 ) / 100 },
41+
{ ( 25 * 65535 ) / 100 },
42+
{ ( 30 * 65535 ) / 100 },
43+
{ ( 35 * 65535 ) / 100 },
44+
{ ( 40 * 65535 ) / 100 },
45+
{ ( 45 * 65535 ) / 100 },
46+
{ ( 50 * 65535 ) / 100 },
47+
{ ( 55 * 65535 ) / 100 },
48+
{ ( 60 * 65535 ) / 100 },
49+
{ ( 65 * 65535 ) / 100 },
50+
{ ( 70 * 65535 ) / 100 },
51+
{ ( 75 * 65535 ) / 100 },
52+
{ ( 80 * 65535 ) / 100 },
53+
{ ( 85 * 65535 ) / 100 },
54+
{ ( 90 * 65535 ) / 100 },
55+
{ ( 95 * 65535 ) / 100 },
56+
{ (100 * 65535 ) / 100 },
57+
{ ( 95 * 65535 ) / 100 },
58+
{ ( 90 * 65535 ) / 100 },
59+
{ ( 85 * 65535 ) / 100 },
60+
{ ( 80 * 65535 ) / 100 },
61+
{ ( 75 * 65535 ) / 100 },
62+
{ ( 70 * 65535 ) / 100 },
63+
{ ( 65 * 65535 ) / 100 },
64+
{ ( 60 * 65535 ) / 100 },
65+
{ ( 55 * 65535 ) / 100 },
66+
{ ( 50 * 65535 ) / 100 },
67+
{ ( 45 * 65535 ) / 100 },
68+
{ ( 40 * 65535 ) / 100 },
69+
{ ( 35 * 65535 ) / 100 },
70+
{ ( 30 * 65535 ) / 100 },
71+
{ ( 25 * 65535 ) / 100 },
72+
{ ( 20 * 65535 ) / 100 },
73+
{ ( 15 * 65535 ) / 100 },
74+
{ ( 10 * 65535 ) / 100 },
75+
{ ( 5 * 65535 ) / 100 },
76+
{ 0 },
7777
};
7878

7979
#define NUM_PWM_POINTS ( sizeof(PWM_data) / sizeof(PWD_Data) )
8080

81-
float frequency = 1000.0f;
81+
float frequency = 2000.0f;
8282
float dutyCycle = 0.0f;
8383

8484
uint8_t channel = 0;

0 commit comments

Comments
 (0)