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

Commit 43927a8

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. Update examples accordingly
1 parent 551bec0 commit 43927a8

20 files changed

+1162
-871
lines changed

CONTRIBUTING.md

+6-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-
* `RP2040` Core Version (e.g. arduino-pico core v1.9.6)
17+
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
18+
* `RP2040` Core Version (e.g. arduino-pico core v1.9.15)
1919
* `RP2040` Board type (e.g. NANO_RP2040_CONNECT, RASPBERRY_PI_PICO, ADAFRUIT_FEATHER_RP2040, GENERIC_RP2040, 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-
arduino-pico core v1.9.6
30+
Arduino IDE version: 1.8.19
31+
arduino-pico core v1.9.5
3232
RASPBERRY_PI_PICO
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-96-generic #109-Ubuntu SMP Wed Jan 12 16:49:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
3535
3636
Context:
3737
I encountered a crash while using TimerInterrupt.
@@ -52,3 +52,4 @@ There are usually some outstanding feature requests in the [existing issues list
5252
### Sending Pull Requests
5353

5454
Pull Requests with changes and fixes are also welcome!
55+

README.md

+175-147
Large diffs are not rendered by default.

changelog.md

+10
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
* [Releases v1.0.1](#Releases-v101)
1718
* [Initial Releases v1.0.0](#Initial-Releases-v100)
@@ -21,6 +22,15 @@
2122

2223
## Changelog
2324

25+
### Releases v1.2.0
26+
27+
1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
28+
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)
29+
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)
30+
4. Optimize library code by using `reference-passing` instead of `value-passing`
31+
5. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project
32+
6. Update examples accordingly
33+
2434
### Releases v1.1.0
2535

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

examples/ISR_16_PWMs_Array/ISR_16_PWMs_Array.ino

+8-8
Original file line numberDiff line numberDiff line change
@@ -87,31 +87,31 @@ bool TimerHandler(struct repeating_timer *t)
8787
//////////////////////////////////////////////////////
8888

8989
// You can assign pins here. Be carefull to select good pin to use or crash, e.g pin 6-11
90-
uint32_t PWM_Pin[NUMBER_ISR_PWMS] =
90+
uint32_t PWM_Pin[] =
9191
{
9292
LED_BUILTIN, LED_BLUE, LED_RED, PIN_D0, PIN_D1, PIN_D2, PIN_D3, PIN_D4,
9393
PIN_D5, PIN_D6, PIN_D7, PIN_D8, PIN_D9, PIN_D10, PIN_D11, PIN_D12
9494
};
9595

9696
// You can assign any interval for any timer here, in microseconds
97-
uint32_t PWM_Period[NUMBER_ISR_PWMS] =
97+
uint32_t PWM_Period[] =
9898
{
9999
1000000L, 500000L, 333333L, 250000L, 200000L, 166667L, 142857L, 125000L,
100100
111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L
101101
};
102102

103103
// You can assign any interval for any timer here, in Hz
104-
double PWM_Freq[NUMBER_ISR_PWMS] =
104+
float PWM_Freq[] =
105105
{
106106
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
107107
9.0f, 10.0f, 15.0f, 20.0f, 25.0f, 30.0f, 40.0f, 50.0f
108108
};
109109

110110
// You can assign any interval for any timer here, in milliseconds
111-
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
111+
float PWM_DutyCycle[] =
112112
{
113-
5, 10, 20, 30, 40, 45, 50, 55,
114-
60, 65, 70, 75, 80, 85, 90, 95
113+
5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0,
114+
60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0
115115
};
116116

117117
typedef void (*irqCallback) ();
@@ -184,7 +184,7 @@ void doingSomething15()
184184
{
185185
}
186186

187-
irqCallback irqCallbackStartFunc[NUMBER_ISR_PWMS] =
187+
irqCallback irqCallbackStartFunc[] =
188188
{
189189
doingSomething0, doingSomething1, doingSomething2, doingSomething3,
190190
doingSomething4, doingSomething5, doingSomething6, doingSomething7,
@@ -218,7 +218,7 @@ void setup()
218218
// You can use up to 16 timer for each ISR_PWM
219219
for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++)
220220
{
221-
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
221+
//void setPWM(uint32_t pin, float frequency, float dutycycle
222222
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
223223

224224
#if USING_PWM_FREQUENCY

examples/ISR_16_PWMs_Array_Complex/ISR_16_PWMs_Array_Complex.ino

+17-17
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ typedef struct
101101
irqCallback irqCallbackStopFunc;
102102

103103
#if USING_PWM_FREQUENCY
104-
uint32_t PWM_Freq;
104+
float PWM_Freq;
105105
#else
106106
uint32_t PWM_Period;
107107
#endif
108108

109-
uint32_t PWM_DutyCycle;
109+
float PWM_DutyCycle;
110110

111111
uint64_t deltaMicrosStart;
112112
uint64_t previousMicrosStart;
@@ -126,38 +126,38 @@ void doingSomethingStop(int index);
126126

127127
#else // #if USE_COMPLEX_STRUCT
128128

129-
volatile unsigned long deltaMicrosStart [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
130-
volatile unsigned long previousMicrosStart [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
129+
volatile unsigned long deltaMicrosStart [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
130+
volatile unsigned long previousMicrosStart [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
131131

132-
volatile unsigned long deltaMicrosStop [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
133-
volatile unsigned long previousMicrosStop [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
132+
volatile unsigned long deltaMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
133+
volatile unsigned long previousMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
134134

135135
// You can assign pins here. Be carefull to select good pin to use or crash, e.g pin 6-11
136-
uint32_t PWM_Pin[NUMBER_ISR_PWMS] =
136+
uint32_t PWM_Pin[] =
137137
{
138138
LED_BUILTIN, LED_BLUE, LED_RED, PIN_D0, PIN_D1, PIN_D2, PIN_D3, PIN_D4,
139139
PIN_D5, PIN_D6, PIN_D7, PIN_D8, PIN_D9, PIN_D10, PIN_D11, PIN_D12
140140
};
141141

142142
// You can assign any interval for any timer here, in microseconds
143-
uint32_t PWM_Period[NUMBER_ISR_PWMS] =
143+
uint32_t PWM_Period[] =
144144
{
145145
1000000L, 500000L, 333333L, 250000L, 200000L, 166667L, 142857L, 125000L,
146146
111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L
147147
};
148148

149149
// You can assign any interval for any timer here, in Hz
150-
double PWM_Freq[NUMBER_ISR_PWMS] =
150+
float PWM_Freq[] =
151151
{
152152
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
153153
9.0f, 10.0f, 15.0f, 20.0f, 25.0f, 30.0f, 40.0f, 50.0f
154154
};
155155

156156
// You can assign any interval for any timer here, in milliseconds
157-
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
157+
float PWM_DutyCycle[] =
158158
{
159-
5, 10, 20, 30, 40, 45, 50, 55,
160-
60, 65, 70, 75, 80, 85, 90, 95
159+
5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0,
160+
60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0
161161
};
162162

163163
void doingSomethingStart(int index)
@@ -351,7 +351,7 @@ void doingSomethingStop15()
351351

352352
#if USING_PWM_FREQUENCY
353353

354-
ISR_PWM_Data curISR_PWM_Data[NUMBER_ISR_PWMS] =
354+
ISR_PWM_Data curISR_PWM_Data[] =
355355
{
356356
// pin, irqCallbackStartFunc, irqCallbackStopFunc, PWM_Freq, PWM_DutyCycle, deltaMicrosStart, previousMicrosStart, deltaMicrosStop, previousMicrosStop
357357
{ LED_BUILTIN, doingSomethingStart0, doingSomethingStop0, 1, 5, 0, 0, 0, 0 },
@@ -374,7 +374,7 @@ void doingSomethingStop15()
374374

375375
#else // #if USING_PWM_FREQUENCY
376376

377-
ISR_PWM_Data curISR_PWM_Data[NUMBER_ISR_PWMS] =
377+
ISR_PWM_Data curISR_PWM_Data[] =
378378
{
379379
// pin, irqCallbackStartFunc, irqCallbackStopFunc, PWM_Period, PWM_DutyCycle, deltaMicrosStart, previousMicrosStart, deltaMicrosStop, previousMicrosStop
380380
{ LED_BUILTIN, doingSomethingStart0, doingSomethingStop0, 1000000L, 5, 0, 0, 0, 0 },
@@ -417,15 +417,15 @@ void doingSomethingStop(int index)
417417

418418
#else // #if USE_COMPLEX_STRUCT
419419

420-
irqCallback irqCallbackStartFunc[NUMBER_ISR_PWMS] =
420+
irqCallback irqCallbackStartFunc[] =
421421
{
422422
doingSomethingStart0, doingSomethingStart1, doingSomethingStart2, doingSomethingStart3,
423423
doingSomethingStart4, doingSomethingStart5, doingSomethingStart6, doingSomethingStart7,
424424
doingSomethingStart8, doingSomethingStart9, doingSomethingStart10, doingSomethingStart11,
425425
doingSomethingStart12, doingSomethingStart13, doingSomethingStart14, doingSomethingStart15
426426
};
427427

428-
irqCallback irqCallbackStopFunc[NUMBER_ISR_PWMS] =
428+
irqCallback irqCallbackStopFunc[] =
429429
{
430430
doingSomethingStop0, doingSomethingStop1, doingSomethingStop2, doingSomethingStop3,
431431
doingSomethingStop4, doingSomethingStop5, doingSomethingStop6, doingSomethingStop7,
@@ -530,7 +530,7 @@ void setup()
530530
curISR_PWM_Data[i].previousMicrosStart = startMicros;
531531
//ISR_PWM.setInterval(curISR_PWM_Data[i].PWM_Period, curISR_PWM_Data[i].irqCallbackStartFunc);
532532

533-
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
533+
//void setPWM(uint32_t pin, float frequency, float dutycycle
534534
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
535535

536536
#if USING_PWM_FREQUENCY

examples/ISR_16_PWMs_Array_Simple/ISR_16_PWMs_Array_Simple.ino

+6-6
Original file line numberDiff line numberDiff line change
@@ -95,24 +95,24 @@ uint32_t PWM_Pin[NUMBER_ISR_PWMS] =
9595
};
9696

9797
// You can assign any interval for any timer here, in microseconds
98-
uint32_t PWM_Period[NUMBER_ISR_PWMS] =
98+
uint32_t PWM_Period[] =
9999
{
100100
1000000L, 500000L, 333333L, 250000L, 200000L, 166667L, 142857L, 125000L,
101101
111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L
102102
};
103103

104104
// You can assign any interval for any timer here, in Hz
105-
double PWM_Freq[NUMBER_ISR_PWMS] =
105+
float PWM_Freq[] =
106106
{
107107
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
108108
9.0f, 10.0f, 15.0f, 20.0f, 25.0f, 30.0f, 40.0f, 50.0f
109109
};
110110

111111
// You can assign any interval for any timer here, in milliseconds
112-
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
112+
float PWM_DutyCycle[] =
113113
{
114-
5, 10, 20, 30, 40, 45, 50, 55,
115-
60, 65, 70, 75, 80, 85, 90, 95
114+
5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0,
115+
60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0
116116
};
117117

118118

@@ -142,7 +142,7 @@ void setup()
142142
// You can use up to 16 timer for each ISR_PWM
143143
for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++)
144144
{
145-
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
145+
//void setPWM(uint32_t pin, float frequency, float dutycycle
146146
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
147147

148148
#if USING_PWM_FREQUENCY

examples/ISR_Changing_PWM/ISR_Changing_PWM.ino

+4-4
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,19 @@ bool TimerHandler(struct repeating_timer *t)
7272
uint32_t PWM_Pin = LED_BUILTIN;
7373

7474
// You can assign any interval for any timer here, in Hz
75-
double PWM_Freq1 = 1.0f;
75+
float PWM_Freq1 = 1.0f;
7676
// You can assign any interval for any timer here, in Hz
77-
double PWM_Freq2 = 2.0f;
77+
float PWM_Freq2 = 2.0f;
7878

7979
// You can assign any interval for any timer here, in microseconds
8080
uint32_t PWM_Period1 = 1000000 / PWM_Freq1;
8181
// You can assign any interval for any timer here, in microseconds
8282
uint32_t PWM_Period2 = 1000000 / PWM_Freq2;
8383

8484
// You can assign any duty_cycle for any PWM here, from 0-100
85-
uint32_t PWM_DutyCycle1 = 50;
85+
float PWM_DutyCycle1 = 50.0;
8686
// You can assign any duty_cycle for any PWM here, from 0-100
87-
uint32_t PWM_DutyCycle2 = 90;
87+
float PWM_DutyCycle2 = 90.0;
8888

8989
// Channel number used to identify associated channel
9090
int channelNum;

examples/ISR_Modify_PWM/ISR_Modify_PWM.ino

+4-4
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,19 @@ bool TimerHandler(struct repeating_timer *t)
7272
uint32_t PWM_Pin = LED_BUILTIN;
7373

7474
// You can assign any interval for any timer here, in Hz
75-
double PWM_Freq1 = 1.0f;
75+
float PWM_Freq1 = 1.0f;
7676
// You can assign any interval for any timer here, in Hz
77-
double PWM_Freq2 = 2.0f;
77+
float PWM_Freq2 = 2.0f;
7878

7979
// You can assign any interval for any timer here, in microseconds
8080
uint32_t PWM_Period1 = 1000000 / PWM_Freq1;
8181
// You can assign any interval for any timer here, in microseconds
8282
uint32_t PWM_Period2 = 1000000 / PWM_Freq2;
8383

8484
// You can assign any duty_cycle for any PWM here, from 0-100
85-
uint32_t PWM_DutyCycle1 = 10;
85+
float PWM_DutyCycle1 = 50.0;
8686
// You can assign any duty_cycle for any PWM here, from 0-100
87-
uint32_t PWM_DutyCycle2 = 90;
87+
float PWM_DutyCycle2 = 90.0;
8888

8989
// Channel number used to identify associated channel
9090
int channelNum;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/****************************************************************************************************************************
2+
multiFileProject.cpp
3+
4+
For RP2040-based boards
5+
Written by Khoi Hoang
6+
7+
Built by Khoi Hoang https://github.com/khoih-prog/RP2040_Slow_PWM
8+
Licensed under MIT license
9+
*****************************************************************************************************************************/
10+
11+
// To demo how to include files in multi-file Projects
12+
13+
#include "multiFileProject.h"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/****************************************************************************************************************************
2+
multiFileProject.h
3+
4+
For RP2040-based boards
5+
Written by Khoi Hoang
6+
7+
Built by Khoi Hoang https://github.com/khoih-prog/RP2040_Slow_PWM
8+
Licensed under MIT license
9+
*****************************************************************************************************************************/
10+
11+
// To demo how to include files in multi-file Projects
12+
13+
#pragma once
14+
15+
#define USING_MICROS_RESOLUTION true //false
16+
17+
// Default is true, uncomment to false
18+
//#define CHANGING_PWM_END_OF_CYCLE false
19+
20+
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
21+
#include "RP2040_Slow_PWM.hpp"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/****************************************************************************************************************************
2+
multiFileProject.ino
3+
4+
For RP2040-based boards
5+
Written by Khoi Hoang
6+
7+
Built by Khoi Hoang https://github.com/khoih-prog/RP2040_Slow_PWM
8+
Licensed under MIT license
9+
*****************************************************************************************************************************/
10+
11+
// To demo how to include files in multi-file Projects
12+
13+
#if !( ( defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || defined(ARDUINO_GENERIC_RP2040) ) && !defined(ARDUINO_ARCH_MBED) )
14+
#error This code is intended to run on the non-mbed RP2040 arduino-pico platform! Please check your Tools->Board setting.
15+
#endif
16+
17+
#define RP2040_SLOW_PWM_VERSION_MIN_TARGET "RP2040_Slow_PWM v1.2.0"
18+
#define RP2040_SLOW_PWM_VERSION_MIN 1002000
19+
20+
#include "multiFileProject.h"
21+
22+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
23+
#include "RP2040_Slow_PWM.h"
24+
25+
void setup()
26+
{
27+
Serial.begin(115200);
28+
while (!Serial);
29+
30+
Serial.println("\nStart multiFileProject");
31+
Serial.println(RP2040_SLOW_PWM_VERSION);
32+
33+
#if 0 //defined(RP2040_SLOW_PWM_VERSION_MIN)
34+
if (RP2040_SLOW_PWM_VERSION_INT < RP2040_SLOW_PWM_VERSION_MIN)
35+
{
36+
Serial.print("Warning. Must use this example on Version equal or later than : ");
37+
Serial.println(RP2040_SLOW_PWM_VERSION_MIN_TARGET);
38+
}
39+
#endif
40+
}
41+
42+
void loop()
43+
{
44+
// put your main code here, to run repeatedly:
45+
}

0 commit comments

Comments
 (0)