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

Commit 3f8a18c

Browse files
authored
v1.2.0 to fix multiple-definitions linker error
### Releases v1.2.0 1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories 2. Improve accuracy by using `float`, instead of `uint32_t` for `dutycycle`. Check [Change Duty Cycle #1](khoih-prog/ESP8266_PWM#1 (comment)) 3. DutyCycle to be optionally updated at the end current PWM period instead of immediately. Check [DutyCycle to be updated at the end current PWM period #2](khoih-prog/ESP8266_PWM#2) 4. Optimize library code by using `reference-passing` instead of `value-passing` 5. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project 6. Fix bug 7. Update examples accordingly 8. Update `Packages_Patches`
1 parent 85483eb commit 3f8a18c

24 files changed

+1205
-866
lines changed

CONTRIBUTING.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p
1414

1515
Please ensure to specify the following:
1616

17-
* Arduino IDE version (e.g. 1.8.16) or Platform.io version
18-
* `ArduinoCore-mbed` Core Version (e.g. `ArduinoCore-mbed` mbed_portenta core v2.5.2)
17+
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
18+
* `ArduinoCore-mbed` Core Version (e.g. `ArduinoCore-mbed` mbed_portenta core v2.6.1)
1919
* `Portenta_H7` Board type (e.g. Portenta_H7 Rev2 ABX00042, etc.)
2020
* Contextual information (e.g. what you were trying to achieve)
2121
* Simplest possible steps to reproduce
@@ -27,11 +27,11 @@ Please ensure to specify the following:
2727
### Example
2828

2929
```
30-
Arduino IDE version: 1.8.16
31-
`ArduinoCore-mbed` mbed_portenta core v2.5.2
30+
Arduino IDE version: 1.8.19
31+
`ArduinoCore-mbed` mbed_portenta core v2.6.1
3232
Portenta_H7 Rev2 ABX00042
3333
OS: Ubuntu 20.04 LTS
34-
Linux xy-Inspiron-3593 5.4.0-90-generic #101-Ubuntu SMP Fri Oct 15 20:00:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
34+
Linux xy-Inspiron-3593 5.4.0-97-generic #110-Ubuntu SMP Thu Jan 13 18:22:13 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
3535
3636
Context:
3737
I encountered a crash while using TimerInterrupt.

README.md

+179-126
Large diffs are not rendered by default.

changelog.md

+12
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
## Table of Contents
1313

1414
* [Changelog](#changelog)
15+
* [Releases v1.2.0](#releases-v120)
1516
* [Releases v1.1.0](#releases-v110)
1617
* [Initial Releases v1.0.0](#Initial-Releases-v100)
1718

@@ -20,6 +21,17 @@
2021

2122
## Changelog
2223

24+
### Releases v1.2.0
25+
26+
1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
27+
2. Improve accuracy by using `float`, instead of `uint32_t` for `dutycycle`. Check [Change Duty Cycle #1](https://github.com/khoih-prog/ESP8266_PWM/issues/1#issuecomment-1024969658)
28+
3. DutyCycle to be optionally updated at the end current PWM period instead of immediately. Check [DutyCycle to be updated at the end current PWM period #2](https://github.com/khoih-prog/ESP8266_PWM/issues/2)
29+
4. Optimize library code by using `reference-passing` instead of `value-passing`
30+
5. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project
31+
6. Fix bug
32+
7. Update examples accordingly
33+
8. Update `Packages_Patches`
34+
2335
### Releases v1.1.0
2436

2537
1. Add functions to modify PWM settings on-the-fly

examples/ISR_16_PWMs_Array/ISR_16_PWMs_Array.ino

+16-11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#define USING_MICROS_RESOLUTION true //false
2626

27+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
2728
#include "Portenta_H7_Slow_PWM.h"
2829

2930
#define LED_OFF HIGH
@@ -41,7 +42,7 @@
4142
#define LED_RED 23 // LEDR // Pin 23 control on-board LED_RED on Portenta_H7
4243
#endif
4344

44-
#define HW_TIMER_INTERVAL_US 20L
45+
#define HW_TIMER_INTERVAL_US 10L
4546

4647
volatile uint64_t startMicros = 0;
4748

@@ -69,8 +70,6 @@ void TimerHandler()
6970

7071
//////////////////////////////////////////////////////
7172

72-
#define NUMBER_ISR_PWMS 16
73-
7473
#define PIN_D0 D0
7574
#define PIN_D1 D1
7675
#define PIN_D2 D2
@@ -92,31 +91,37 @@ void TimerHandler()
9291
//////////////////////////////////////////////////////
9392

9493
// You can assign pins here. Be carefull to select good pin to use or crash, e.g pin 6-11
95-
uint32_t PWM_Pin[NUMBER_ISR_PWMS] =
94+
uint32_t PWM_Pin[] =
9695
{
9796
LEDG, LEDB, LEDR, PIN_D0, PIN_D1, PIN_D2, PIN_D3, PIN_D4,
9897
PIN_D5, PIN_D6, PIN_D7, PIN_D8, PIN_D9, PIN_D10, PIN_D11, PIN_D12
9998
};
10099

100+
//////////////////////////////////////////////////////
101+
102+
#define NUMBER_ISR_PWMS sizeof(PWM_Pin) / sizeof(uint32_t)
103+
104+
//////////////////////////////////////////////////////
105+
101106
// You can assign any interval for any timer here, in microseconds
102-
uint32_t PWM_Period[NUMBER_ISR_PWMS] =
107+
uint32_t PWM_Period[] =
103108
{
104109
1000000L, 500000L, 333333L, 250000L, 200000L, 166667L, 142857L, 125000L,
105110
111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L
106111
};
107112

108113
// You can assign any interval for any timer here, in Hz
109-
double PWM_Freq[NUMBER_ISR_PWMS] =
114+
float PWM_Freq[] =
110115
{
111116
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
112117
9.0f, 10.0f, 15.0f, 20.0f, 25.0f, 30.0f, 40.0f, 50.0f
113118
};
114119

115120
// You can assign any interval for any timer here, in milliseconds
116-
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
121+
float PWM_DutyCycle[] =
117122
{
118-
5, 10, 20, 30, 40, 45, 50, 55,
119-
60, 65, 70, 75, 80, 85, 90, 95
123+
5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0,
124+
60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0
120125
};
121126

122127
typedef void (*irqCallback) ();
@@ -189,7 +194,7 @@ void doingSomething15()
189194
{
190195
}
191196

192-
irqCallback irqCallbackStartFunc[NUMBER_ISR_PWMS] =
197+
irqCallback irqCallbackStartFunc[] =
193198
{
194199
doingSomething0, doingSomething1, doingSomething2, doingSomething3,
195200
doingSomething4, doingSomething5, doingSomething6, doingSomething7,
@@ -223,7 +228,7 @@ void setup()
223228
// You can use up to 16 timer for each ISR_PWM
224229
for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++)
225230
{
226-
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
231+
//void setPWM(uint32_t pin, float frequency, float dutycycle
227232
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
228233

229234
#if USING_PWM_FREQUENCY

examples/ISR_16_PWMs_Array_Complex/ISR_16_PWMs_Array_Complex.ino

+18-17
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#define USING_MICROS_RESOLUTION true //false
2626

27+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
2728
#include "Portenta_H7_Slow_PWM.h"
2829

2930
#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer
@@ -106,12 +107,12 @@ typedef struct
106107
irqCallback irqCallbackStopFunc;
107108

108109
#if USING_PWM_FREQUENCY
109-
uint32_t PWM_Freq;
110+
float PWM_Freq;
110111
#else
111112
uint32_t PWM_Period;
112113
#endif
113114

114-
uint32_t PWM_DutyCycle;
115+
float PWM_DutyCycle;
115116

116117
uint64_t deltaMicrosStart;
117118
uint64_t previousMicrosStart;
@@ -131,38 +132,38 @@ void doingSomethingStop(int index);
131132

132133
#else // #if USE_COMPLEX_STRUCT
133134

134-
volatile unsigned long deltaMicrosStart [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
135-
volatile unsigned long previousMicrosStart [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
135+
volatile unsigned long deltaMicrosStart [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
136+
volatile unsigned long previousMicrosStart [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
136137

137-
volatile unsigned long deltaMicrosStop [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
138-
volatile unsigned long previousMicrosStop [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
138+
volatile unsigned long deltaMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
139+
volatile unsigned long previousMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
139140

140141
// You can assign pins here. Be carefull to select good pin to use or crash, e.g pin 6-11
141-
uint32_t PWM_Pin[NUMBER_ISR_PWMS] =
142+
uint32_t PWM_Pin[] =
142143
{
143144
LEDG, LEDB, LEDR, PIN_D0, PIN_D1, PIN_D2, PIN_D3, PIN_D4,
144145
PIN_D5, PIN_D6, PIN_D7, PIN_D8, PIN_D9, PIN_D10, PIN_D11, PIN_D12
145146
};
146147

147148
// You can assign any interval for any timer here, in microseconds
148-
uint32_t PWM_Period[NUMBER_ISR_PWMS] =
149+
uint32_t PWM_Period[] =
149150
{
150151
1000000L, 500000L, 333333L, 250000L, 200000L, 166667L, 142857L, 125000L,
151152
111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L
152153
};
153154

154155
// You can assign any interval for any timer here, in Hz
155-
double PWM_Freq[NUMBER_ISR_PWMS] =
156+
float PWM_Freq[] =
156157
{
157158
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
158159
9.0f, 10.0f, 15.0f, 20.0f, 25.0f, 30.0f, 40.0f, 50.0f
159160
};
160161

161162
// You can assign any interval for any timer here, in milliseconds
162-
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
163+
float PWM_DutyCycle[] =
163164
{
164-
5, 10, 20, 30, 40, 45, 50, 55,
165-
60, 65, 70, 75, 80, 85, 90, 95
165+
5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0,
166+
60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0
166167
};
167168

168169
void doingSomethingStart(int index)
@@ -356,7 +357,7 @@ void doingSomethingStop15()
356357

357358
#if USING_PWM_FREQUENCY
358359

359-
ISR_PWM_Data curISR_PWM_Data[NUMBER_ISR_PWMS] =
360+
ISR_PWM_Data curISR_PWM_Data[] =
360361
{
361362
// pin, irqCallbackStartFunc, irqCallbackStopFunc, PWM_Freq, PWM_DutyCycle, deltaMicrosStart, previousMicrosStart, deltaMicrosStop, previousMicrosStop
362363
{ LEDG, doingSomethingStart0, doingSomethingStop0, 1, 5, 0, 0, 0, 0 },
@@ -379,7 +380,7 @@ void doingSomethingStop15()
379380

380381
#else // #if USING_PWM_FREQUENCY
381382

382-
ISR_PWM_Data curISR_PWM_Data[NUMBER_ISR_PWMS] =
383+
ISR_PWM_Data curISR_PWM_Data[] =
383384
{
384385
// pin, irqCallbackStartFunc, irqCallbackStopFunc, PWM_Period, PWM_DutyCycle, deltaMicrosStart, previousMicrosStart, deltaMicrosStop, previousMicrosStop
385386
{ LEDG, doingSomethingStart0, doingSomethingStop0, 1000000L, 5, 0, 0, 0, 0 },
@@ -422,15 +423,15 @@ void doingSomethingStop(int index)
422423

423424
#else // #if USE_COMPLEX_STRUCT
424425

425-
irqCallback irqCallbackStartFunc[NUMBER_ISR_PWMS] =
426+
irqCallback irqCallbackStartFunc[] =
426427
{
427428
doingSomethingStart0, doingSomethingStart1, doingSomethingStart2, doingSomethingStart3,
428429
doingSomethingStart4, doingSomethingStart5, doingSomethingStart6, doingSomethingStart7,
429430
doingSomethingStart8, doingSomethingStart9, doingSomethingStart10, doingSomethingStart11,
430431
doingSomethingStart12, doingSomethingStart13, doingSomethingStart14, doingSomethingStart15
431432
};
432433

433-
irqCallback irqCallbackStopFunc[NUMBER_ISR_PWMS] =
434+
irqCallback irqCallbackStopFunc[] =
434435
{
435436
doingSomethingStop0, doingSomethingStop1, doingSomethingStop2, doingSomethingStop3,
436437
doingSomethingStop4, doingSomethingStop5, doingSomethingStop6, doingSomethingStop7,
@@ -535,7 +536,7 @@ void setup()
535536
curISR_PWM_Data[i].previousMicrosStart = startMicros;
536537
//ISR_PWM.setInterval(curISR_PWM_Data[i].PWM_Period, curISR_PWM_Data[i].irqCallbackStartFunc);
537538

538-
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
539+
//void setPWM(uint32_t pin, float frequency, float dutycycle
539540
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
540541

541542
#if USING_PWM_FREQUENCY

examples/ISR_16_PWMs_Array_Simple/ISR_16_PWMs_Array_Simple.ino

+14-10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#define USING_MICROS_RESOLUTION true //false
2626

27+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
2728
#include "Portenta_H7_Slow_PWM.h"
2829

2930
#define LED_OFF HIGH
@@ -69,8 +70,6 @@ void TimerHandler()
6970

7071
//////////////////////////////////////////////////////
7172

72-
#define NUMBER_ISR_PWMS 16
73-
7473
#define PIN_D0 D0
7574
#define PIN_D1 D1
7675
#define PIN_D2 D2
@@ -92,32 +91,37 @@ void TimerHandler()
9291
//////////////////////////////////////////////////////
9392

9493
// You can assign pins here. Be carefull to select good pin to use or crash, e.g pin 6-11
95-
uint32_t PWM_Pin[NUMBER_ISR_PWMS] =
94+
uint32_t PWM_Pin[] =
9695
{
9796
LEDG, LEDB, LEDR, PIN_D0, PIN_D1, PIN_D2, PIN_D3, PIN_D4,
9897
PIN_D5, PIN_D6, PIN_D7, PIN_D8, PIN_D9, PIN_D10, PIN_D11, PIN_D12
9998
};
10099

100+
//////////////////////////////////////////////////////
101+
102+
#define NUMBER_ISR_PWMS sizeof(PWM_Pin) / sizeof(uint32_t)
103+
104+
//////////////////////////////////////////////////////
105+
101106
// You can assign any interval for any timer here, in microseconds
102-
uint32_t PWM_Period[NUMBER_ISR_PWMS] =
107+
uint32_t PWM_Period[] =
103108
{
104109
1000000L, 500000L, 333333L, 250000L, 200000L, 166667L, 142857L, 125000L,
105110
111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L
106111
};
107112

108-
109113
// You can assign any interval for any timer here, in Hz
110-
double PWM_Freq[NUMBER_ISR_PWMS] =
114+
float PWM_Freq[] =
111115
{
112116
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
113117
9.0f, 10.0f, 15.0f, 20.0f, 25.0f, 30.0f, 40.0f, 50.0f
114118
};
115119

116120
// You can assign any interval for any timer here, in milliseconds
117-
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
121+
float PWM_DutyCycle[] =
118122
{
119-
5, 10, 20, 30, 40, 45, 50, 55,
120-
60, 65, 70, 75, 80, 85, 90, 95
123+
5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0,
124+
60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0
121125
};
122126

123127

@@ -147,7 +151,7 @@ void setup()
147151
// You can use up to 16 timer for each ISR_PWM
148152
for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++)
149153
{
150-
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
154+
//void setPWM(uint32_t pin, float frequency, float dutycycle
151155
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
152156

153157
#if USING_PWM_FREQUENCY

examples/ISR_Changing_PWM/ISR_Changing_PWM.ino

+5-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#define USING_MICROS_RESOLUTION true //false
2626

27+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
2728
#include "Portenta_H7_Slow_PWM.h"
2829

2930
#define LED_OFF HIGH
@@ -75,19 +76,19 @@ void TimerHandler()
7576
uint32_t PWM_Pin = LED_BUILTIN;
7677

7778
// You can assign any interval for any timer here, in Hz
78-
double PWM_Freq1 = 1.0f;
79+
float PWM_Freq1 = 1.0f;
7980
// You can assign any interval for any timer here, in Hz
80-
double PWM_Freq2 = 2.0f;
81+
float PWM_Freq2 = 2.0f;
8182

8283
// You can assign any interval for any timer here, in microseconds
8384
uint32_t PWM_Period1 = 1000000 / PWM_Freq1;
8485
// You can assign any interval for any timer here, in microseconds
8586
uint32_t PWM_Period2 = 1000000 / PWM_Freq2;
8687

8788
// You can assign any duty_cycle for any PWM here, from 0-100
88-
uint32_t PWM_DutyCycle1 = 50;
89+
float PWM_DutyCycle1 = 50.0;
8990
// You can assign any duty_cycle for any PWM here, from 0-100
90-
uint32_t PWM_DutyCycle2 = 90;
91+
float PWM_DutyCycle2 = 90.0;
9192

9293
// Channel number used to identify associated channel
9394
int channelNum;

0 commit comments

Comments
 (0)