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

Commit 7ebf1b9

Browse files
authored
Add PWM_StepperControl example
Credits of `Paul van Dinther` (https://github.com/dinther). Check khoih-prog/RP2040_PWM#16
1 parent 20eb345 commit 7ebf1b9

File tree

3 files changed

+150
-55
lines changed

3 files changed

+150
-55
lines changed

examples/PWM_Multi/PWM_Multi.ino

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@
55
66
Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_PWM
77
Licensed under MIT license
8-
9-
Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
10-
unsigned long miliseconds), you just consume only one Portenta_H7 STM32 timer and avoid conflicting with other cores' tasks.
11-
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
12-
Therefore, their executions are not blocked by bad-behaving functions / tasks.
13-
This important feature is absolutely necessary for mission-critical tasks.
148
*****************************************************************************************************************************/
159

1610
#if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) )
@@ -28,7 +22,7 @@
2822
// Can't use same TimerIndex again, e.g., the D1 and D2, using TIM1, can't be use concurrently
2923
// That's why D0, D1, D3, D4 and D6 (using TimerIndex 8, 1, HRTIM and 3) are OK together
3024

31-
// Only OK for D0, D1, D2, D4 and D5, PA_0C(D15/A0), PA_1C(D16/A1),
25+
// Only OK for D0, D1, D2, D4 and D5, PA_0C(D15/A0), PA_1C(D16/A1),
3226
// D3, D6, D7, D8, D9, D10, D11, D12, D13, D14, D17(PC_2C/A2), D18(PC_3C/3), PC2(D19/A4) LEDG, LEDB not OK
3327
#define pinD0 D0 // PH15 / TIM8_CH3N
3428
#define pinD1 D1 // PK1 / TIM1_CH1, TIM8_CH3
@@ -39,10 +33,10 @@
3933
#define pinD6 D6 // PA8 / HRTIM_CHB2 (TIM1_CH1, TIM8_BKIN2)
4034

4135
// See https://www.st.com/resource/en/datasheet/stm32h747xi.pdf, Table 7, page 53
42-
// Can't use pins with same TIMx. For example,
36+
// Can't use pins with same TIMx. For example,
4337
// pinD1 and pinD2, using same TIM1, can't be used at the same time
4438
// pinD4 and pinD5, using same TIM3, can't be used at the same time
45-
// pinD3 and pinD6 are using HRTIM, can't be used at the same time and the minimum freq must be ~770Hz
39+
// pinD3 and pinD6 are using HRTIM, can't be used at the same time and the minimum freq must be ~770Hz
4640
uint32_t pins[] = { pinD0, pinD1, pinD3, pinD5 };
4741

4842
#define NUM_OF_PINS ( sizeof(pins) / sizeof(uint32_t) )
@@ -62,11 +56,12 @@ void startAllPWM()
6256
digitalWrite(LEDG, LED_ON);
6357
digitalWrite(LEDB, LED_OFF);
6458
digitalWrite(LEDR, LED_OFF);
65-
59+
6660
for (uint8_t index = 0; index < NUM_OF_PINS; index++)
6761
{
68-
PWM_LOGERROR7("Freq = ", freq[index], ", \tDutyCycle % = ", dutyCycle[index], ", \tDutyCycle = ", dutyCycle[index] / 100, ", \tPin = ", pins[index]);
69-
62+
PWM_LOGERROR7("Freq = ", freq[index], ", \tDutyCycle % = ", dutyCycle[index], ", \tDutyCycle = ",
63+
dutyCycle[index] / 100, ", \tPin = ", pins[index]);
64+
7065
// setPWM(mbed::PwmOut* &pwm, pin_size_t pin, float frequency, float dutyCycle)
7166
setPWM(pwm[index], pins[index], freq[index], dutyCycle[index]);
7267
}
@@ -77,12 +72,12 @@ void restoreAllPWM()
7772
digitalWrite(LEDG, LED_ON);
7873
digitalWrite(LEDB, LED_OFF);
7974
digitalWrite(LEDR, LED_OFF);
80-
75+
8176
for (uint8_t index = 0; index < NUM_OF_PINS; index++)
8277
{
8378
curFreq[index] = freq[index];
8479
curDutyCycle[index] = dutyCycle[index];
85-
80+
8681
// setPWM(mbed::PwmOut* &pwm, pin_size_t pin, float frequency, float dutyCycle)
8782
setPWM(pwm[index], pins[index], freq[index], dutyCycle[index]);
8883
}
@@ -93,12 +88,12 @@ void changeAllPWM()
9388
digitalWrite(LEDG, LED_OFF);
9489
digitalWrite(LEDB, LED_ON);
9590
digitalWrite(LEDR, LED_OFF);
96-
91+
9792
for (uint8_t index = 0; index < NUM_OF_PINS; index++)
9893
{
9994
curFreq[index] = freq[index] * 2;
10095
curDutyCycle[index] = dutyCycle[index] / 2;
101-
96+
10297
// setPWM(mbed::PwmOut* &pwm, pin_size_t pin, float frequency, float dutyCycle)
10398
setPWM(pwm[index], pins[index], curFreq[index], curDutyCycle[index]);
10499
}
@@ -109,20 +104,21 @@ void stopAllPWM()
109104
digitalWrite(LEDG, LED_OFF);
110105
digitalWrite(LEDB, LED_OFF);
111106
digitalWrite(LEDR, LED_ON);
112-
107+
113108
for (uint8_t index = 0; index < NUM_OF_PINS; index++)
114109
{
115110
curFreq[index] = 1000.0f;
116111
curDutyCycle[index] = 0.0f;
117-
112+
118113
//stopPWM(mbed::PwmOut* &pwm, pin_size_t pin)
119114
stopPWM(pwm[index], pins[index]);
120115
}
121116
}
122117

123118
void printLine()
124119
{
125-
Serial.println(F("\n=========================================================================================================="));
120+
Serial.println(
121+
F("\n=========================================================================================================="));
126122
}
127123

128124
void printPulseWidth()
@@ -132,15 +128,17 @@ void printPulseWidth()
132128
if (num++ % 50 == 0)
133129
{
134130
printLine();
135-
131+
136132
for (uint8_t index = 0; index < NUM_OF_PINS; index++)
137133
{
138-
Serial.print(F("PW (us) ")); Serial.print(index); Serial.print(F("\t"));
134+
Serial.print(F("PW (us) "));
135+
Serial.print(index);
136+
Serial.print(F("\t"));
139137
}
140138

141139
printLine();
142140
}
143-
141+
144142
if (num > 1)
145143
{
146144
for (uint8_t index = 0; index < NUM_OF_PINS; index++)
@@ -150,11 +148,13 @@ void printPulseWidth()
150148
if ( (pins[index] == pinD3) || (pins[index] == pinD6) )
151149
{
152150
// Using HRTIM => fake by calculating PW
153-
Serial.print( (10000 * curDutyCycle[index]) / curFreq[index] ); Serial.print(F("\t\t"));
151+
Serial.print( (10000 * curDutyCycle[index]) / curFreq[index] );
152+
Serial.print(F("\t\t"));
154153
}
155154
else
156155
{
157-
Serial.print((float) pwm[index]->read_pulsewitdth_us()); Serial.print(F("\t\t"));
156+
Serial.print((float) pwm[index]->read_pulsewitdth_us());
157+
Serial.print(F("\t\t"));
158158
}
159159
}
160160
}
@@ -183,18 +183,18 @@ void check_status()
183183

184184
if ( (millis() > changePWM_timeout) && (millis() > CHANGE_INTERVAL) )
185185
{
186-
186+
187187
if (PWM_orig)
188188
{
189-
if (count++ %2 == 0)
189+
if (count++ % 2 == 0)
190190
{
191191
Serial.println("Stop all PWM");
192192
stopAllPWM();
193193
}
194194
else
195195
{
196196
Serial.println("Change all PWM");
197-
197+
198198
changeAllPWM();
199199

200200
PWM_orig = !PWM_orig;
@@ -203,12 +203,12 @@ void check_status()
203203
else
204204
{
205205
Serial.println("Restore all PWM");
206-
206+
207207
restoreAllPWM();
208208

209209
PWM_orig = !PWM_orig;
210210
}
211-
211+
212212
changePWM_timeout = millis() + CHANGE_INTERVAL;
213213
}
214214
}
@@ -230,11 +230,13 @@ void setup()
230230
}
231231

232232
Serial.begin(115200);
233+
233234
while (!Serial);
234235

235236
delay(100);
236237

237-
Serial.print(F("\nStarting PWM_Multi on ")); Serial.println(BOARD_NAME);
238+
Serial.print(F("\nStarting PWM_Multi on "));
239+
Serial.println(BOARD_NAME);
238240
Serial.println(PORTENTA_H7_PWM_VERSION);
239241

240242
// Automatically retrieve TIM instance and channel associated to pin

examples/PWM_Single/PWM_Single.ino

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@
55
66
Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_PWM
77
Licensed under MIT license
8-
9-
Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
10-
unsigned long miliseconds), you just consume only one Portenta_H7 STM32 timer and avoid conflicting with other cores' tasks.
11-
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
12-
Therefore, their executions are not blocked by bad-behaving functions / tasks.
13-
This important feature is absolutely necessary for mission-critical tasks.
148
*****************************************************************************************************************************/
159

1610
#if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) )
@@ -28,7 +22,7 @@
2822
// Can't use same TimerIndex again, e.g., the D1 and D2, using TIM1, can't be use concurrently
2923
// That's why D0, D1, D3, D4 and D6 (using TimerIndex 8, 1, HRTIM and 3) are OK together
3024

31-
// Only OK for D0, D1, D2, D4 and D5, PA_0C(D15/A0), PA_1C(D16/A1),
25+
// Only OK for D0, D1, D2, D4 and D5, PA_0C(D15/A0), PA_1C(D16/A1),
3226
// D3, D6, D7, D8, D9, D10, D11, D12, D13, D14, D17(PC_2C/A2), D18(PC_3C/3), PC2(D19/A4) LEDG, LEDB not OK
3327
#define pinD0 D0 // PH15 / TIM8_CH3N
3428
#define pinD1 D1 // PK1 / TIM1_CH1, TIM8_CH3
@@ -39,10 +33,10 @@
3933
#define pinD6 D6 // PA8 / HRTIM_CHB2 (TIM1_CH1, TIM8_BKIN2)
4034

4135
// See https://www.st.com/resource/en/datasheet/stm32h747xi.pdf, Table 7, page 53
42-
// Can't use pins with same TIMx. For example,
36+
// Can't use pins with same TIMx. For example,
4337
// pinD1 and pinD2, using same TIM1, can't be used at the same time
4438
// pinD4 and pinD5, using same TIM3, can't be used at the same time
45-
// pinD3 and pinD6 are using HRTIM, can't be used at the same time and the minimum freq must be ~770Hz
39+
// pinD3 and pinD6 are using HRTIM, can't be used at the same time and the minimum freq must be ~770Hz
4640
uint32_t myPin = pinD5;
4741

4842
float dutyCycle = 50.0f;
@@ -70,10 +64,10 @@ void restorePWM()
7064
digitalWrite(LEDG, LED_ON);
7165
digitalWrite(LEDB, LED_OFF);
7266
digitalWrite(LEDR, LED_OFF);
73-
67+
7468
curFreq = freq;
7569
curDutyCycle = dutyCycle;
76-
70+
7771
// setPWM(mbed::PwmOut* &pwm, pin_size_t pin, float frequency, float dutyCycle)
7872
setPWM(pwm, myPin, freq, dutyCycle);
7973
}
@@ -83,10 +77,10 @@ void changePWM()
8377
digitalWrite(LEDG, LED_OFF);
8478
digitalWrite(LEDB, LED_ON);
8579
digitalWrite(LEDR, LED_OFF);
86-
80+
8781
curFreq = freq * 2;
8882
curDutyCycle = dutyCycle / 2;
89-
83+
9084
// setPWM(mbed::PwmOut* &pwm, pin_size_t pin, float frequency, float dutyCycle)
9185
setPWM(pwm, myPin, curFreq, curDutyCycle);
9286
}
@@ -96,10 +90,10 @@ void stopMyPWM()
9690
digitalWrite(LEDG, LED_OFF);
9791
digitalWrite(LEDB, LED_OFF);
9892
digitalWrite(LEDR, LED_ON);
99-
93+
10094
curFreq = 1000.0f;
10195
curDutyCycle = 0.0f;
102-
96+
10397
//stopPWM(mbed::PwmOut* &pwm, pin_size_t pin)
10498
stopPWM(pwm, myPin);
10599
}
@@ -116,24 +110,26 @@ void printPulseWidth()
116110
if (num++ % 50 == 0)
117111
{
118112
printLine();
119-
113+
120114
Serial.print(F("PW (us)"));
121115

122116
printLine();
123117
}
124-
118+
125119
if (num > 1)
126120
{
127121
if (pwm)
128122
{
129123
if ( (myPin == pinD3) || (myPin == pinD6) )
130124
{
131125
// Using HRTIM => fake by calculating PW
132-
Serial.print( (10000 * curDutyCycle) / curFreq ); Serial.print(F("\t\t"));
126+
Serial.print( (10000 * curDutyCycle) / curFreq );
127+
Serial.print(F("\t\t"));
133128
}
134129
else
135130
{
136-
Serial.print((float) pwm->read_pulsewitdth_us()); Serial.print(F("\t\t"));
131+
Serial.print((float) pwm->read_pulsewitdth_us());
132+
Serial.print(F("\t\t"));
137133
}
138134
}
139135

@@ -161,18 +157,18 @@ void check_status()
161157

162158
if ( (millis() > changePWM_timeout) && (millis() > CHANGE_INTERVAL) )
163159
{
164-
160+
165161
if (PWM_orig)
166162
{
167-
if (count++ %2 == 0)
163+
if (count++ % 2 == 0)
168164
{
169165
Serial.println("Stop PWM");
170166
stopMyPWM();
171167
}
172168
else
173169
{
174170
Serial.println("Change PWM");
175-
171+
176172
changePWM();
177173

178174
PWM_orig = !PWM_orig;
@@ -181,12 +177,12 @@ void check_status()
181177
else
182178
{
183179
Serial.println("Restore PWM");
184-
180+
185181
restorePWM();
186182

187183
PWM_orig = !PWM_orig;
188184
}
189-
185+
190186
changePWM_timeout = millis() + CHANGE_INTERVAL;
191187
}
192188
}
@@ -205,11 +201,13 @@ void setup()
205201
digitalWrite(myPin, LOW);
206202

207203
Serial.begin(115200);
204+
208205
while (!Serial);
209206

210207
delay(100);
211208

212-
Serial.print(F("\nStarting PWM_Single on ")); Serial.println(BOARD_NAME);
209+
Serial.print(F("\nStarting PWM_Single on "));
210+
Serial.println(BOARD_NAME);
213211
Serial.println(PORTENTA_H7_PWM_VERSION);
214212

215213
// Automatically retrieve TIM instance and channel associated to pin

0 commit comments

Comments
 (0)