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

Commit c5c1aa5

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 32c65d7 commit c5c1aa5

21 files changed

+2151
-1773
lines changed

CONTRIBUTING.md

Lines changed: 5 additions & 5 deletions
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-
* `Teensyduino` Core Version (e.g. Teensy core v1.55)
17+
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
18+
* `Teensyduino` Core Version (e.g. Teensy core v1.56)
1919
* Contextual information (e.g. what you were trying to achieve)
2020
* Simplest possible steps to reproduce
2121
* Anything that might be relevant in your opinion, such as:
@@ -26,10 +26,10 @@ Please ensure to specify the following:
2626
### Example
2727

2828
```
29-
Arduino IDE version: 1.8.16
30-
Teensyduino Core Version 1.55
29+
Arduino IDE version: 1.8.19
30+
Teensyduino Core Version 1.56
3131
OS: Ubuntu 20.04 LTS
32-
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
32+
Linux xy-Inspiron-3593 5.4.0-99-generic #112-Ubuntu SMP Thu Feb 3 13:50:55 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
3333
3434
Context:
3535
I encountered a crash while trying to use the Timer Interrupt.

README.md

Lines changed: 178 additions & 120 deletions
Large diffs are not rendered by default.

changelog.md

Lines changed: 11 additions & 8 deletions
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,16 @@
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. Update examples accordingly
32+
33+
2334
### Releases v1.1.0
2435

2536
1. Add functions to modify PWM settings on-the-fly
@@ -31,11 +42,3 @@
3142

3243
2. The hybrid ISR-based PWM channels can generate from very low (much less than 1Hz) to highest PWM frequencies up to 500-1000Hz with acceptable accuracy.
3344

34-
---
35-
---
36-
37-
## Copyright
38-
39-
Copyright 2021- Khoi Hoang
40-
41-

examples/ISR_8_PWMs_Array/ISR_8_PWMs_Array.ino

Lines changed: 8 additions & 7 deletions
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 "Teensy_Slow_PWM.h"
2829

2930
#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer
@@ -48,8 +49,8 @@
4849
#if defined(__IMXRT1062__)
4950
// For Teensy 4.0 and 4.1
5051
// Don't change these numbers to make higher Timer freq. System can hang
51-
#define HW_TIMER_INTERVAL_MS 0.0333f
52-
#define HW_TIMER_INTERVAL_FREQ 30000L
52+
#define HW_TIMER_INTERVAL_MS 0.01f
53+
#define HW_TIMER_INTERVAL_FREQ 100000L
5354
#elif defined(__MK66FX1M0__)
5455
// For Teensy 3.6
5556
// Don't change these numbers to make higher Timer freq. System can hang
@@ -99,15 +100,15 @@ uint32_t PWM_Pin[] =
99100
#define NUMBER_ISR_PWMS ( sizeof(PWM_Pin) / sizeof(uint32_t) )
100101

101102
// You can assign any interval for any timer here, in Hz
102-
double PWM_Freq[NUMBER_ISR_PWMS] =
103+
float PWM_Freq[] =
103104
{
104105
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
105106
};
106107

107108
// You can assign any interval for any timer here, in Microseconds
108-
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
109+
float PWM_DutyCycle[] =
109110
{
110-
5, 10, 20, 25, 30, 35, 40, 45
111+
5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0
111112
};
112113

113114
typedef void (*irqCallback) ();
@@ -149,7 +150,7 @@ void doingSomething7()
149150
}
150151

151152

152-
irqCallback irqCallbackStartFunc[NUMBER_ISR_PWMS] =
153+
irqCallback irqCallbackStartFunc[] =
153154
{
154155
doingSomething0, doingSomething1, doingSomething2, doingSomething3,
155156
doingSomething4, doingSomething5, doingSomething6, doingSomething7
@@ -200,7 +201,7 @@ void setup()
200201
// You can use up to 16 timer for each ISR_PWM
201202
for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++)
202203
{
203-
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
204+
//void setPWM(uint32_t pin, float frequency, float dutycycle
204205
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
205206

206207
// You can use this with PWM_Freq in Hz

examples/ISR_8_PWMs_Array_Complex/ISR_8_PWMs_Array_Complex.ino

Lines changed: 23 additions & 21 deletions
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 "Teensy_Slow_PWM.h"
2829

2930
#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer
@@ -48,8 +49,8 @@
4849
#if defined(__IMXRT1062__)
4950
// For Teensy 4.0 and 4.1
5051
// Don't change these numbers to make higher Timer freq. System can hang
51-
#define HW_TIMER_INTERVAL_MS 0.0333f
52-
#define HW_TIMER_INTERVAL_FREQ 30000L
52+
#define HW_TIMER_INTERVAL_MS 0.01f
53+
#define HW_TIMER_INTERVAL_FREQ 100000L
5354
#elif defined(__MK66FX1M0__)
5455
// For Teensy 3.6
5556
// Don't change these numbers to make higher Timer freq. System can hang
@@ -112,9 +113,9 @@ typedef struct
112113
irqCallback irqCallbackStartFunc;
113114
irqCallback irqCallbackStopFunc;
114115

115-
uint32_t PWM_Freq;
116+
float PWM_Freq;
116117

117-
uint32_t PWM_DutyCycle;
118+
float PWM_DutyCycle;
118119

119120
uint32_t deltaMicrosStart;
120121
uint32_t previousMicrosStart;
@@ -134,29 +135,30 @@ void doingSomethingStop(int index);
134135

135136
#else // #if USE_COMPLEX_STRUCT
136137

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

140-
volatile unsigned long deltaMicrosStop [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
141-
volatile unsigned long previousMicrosStop [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
141+
volatile unsigned long deltaMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0 };
142+
volatile unsigned long previousMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0 };
142143

143144

144145
// You can assign any interval for any timer here, in Microseconds
145-
uint32_t PWM_Period[NUMBER_ISR_PWMS] =
146+
uint32_t PWM_Period[] =
146147
{
147148
1000L, 500L, 333L, 250L, 200L, 166L, 142L, 125L
148149
};
149150

150151
// You can assign any interval for any timer here, in Hz
151-
double PWM_Freq[NUMBER_ISR_PWMS] =
152+
// You can assign any interval for any timer here, in Hz
153+
float PWM_Freq[] =
152154
{
153155
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
154156
};
155157

156158
// You can assign any interval for any timer here, in Microseconds
157-
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
159+
float PWM_DutyCycle[] =
158160
{
159-
5, 10, 20, 25, 30, 35, 40, 45
161+
5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0
160162
};
161163

162164
void doingSomethingStart(int index)
@@ -270,17 +272,17 @@ void doingSomethingStop7()
270272

271273
#if USE_COMPLEX_STRUCT
272274

273-
ISR_PWM_Data curISR_PWM_Data[NUMBER_ISR_PWMS] =
275+
ISR_PWM_Data curISR_PWM_Data[] =
274276
{
275277
// pin, irqCallbackStartFunc, irqCallbackStopFunc, PWM_Freq, PWM_DutyCycle, deltaMicrosStart, previousMicrosStart, deltaMicrosStop, previousMicrosStop
276278
{ LED_BUILTIN, doingSomethingStart0, doingSomethingStop0, 1, 5, 0, 0, 0, 0 },
277279
{ PIN_D0, doingSomethingStart1, doingSomethingStop1, 2, 10, 0, 0, 0, 0 },
278280
{ PIN_D1, doingSomethingStart2, doingSomethingStop2, 3, 20, 0, 0, 0, 0 },
279-
{ PIN_D2, doingSomethingStart3, doingSomethingStop3, 4, 25, 0, 0, 0, 0 },
280-
{ PIN_D3, doingSomethingStart4, doingSomethingStop4, 5, 30, 0, 0, 0, 0 },
281-
{ PIN_D4, doingSomethingStart5, doingSomethingStop5, 6, 35, 0, 0, 0, 0 },
282-
{ PIN_D5, doingSomethingStart6, doingSomethingStop6, 7, 40, 0, 0, 0, 0 },
283-
{ PIN_D6, doingSomethingStart7, doingSomethingStop7, 8, 45, 0, 0, 0, 0 },
281+
{ PIN_D2, doingSomethingStart3, doingSomethingStop3, 4, 30, 0, 0, 0, 0 },
282+
{ PIN_D3, doingSomethingStart4, doingSomethingStop4, 5, 40, 0, 0, 0, 0 },
283+
{ PIN_D4, doingSomethingStart5, doingSomethingStop5, 6, 45, 0, 0, 0, 0 },
284+
{ PIN_D5, doingSomethingStart6, doingSomethingStop6, 7, 50, 0, 0, 0, 0 },
285+
{ PIN_D6, doingSomethingStart7, doingSomethingStop7, 8, 55, 0, 0, 0, 0 },
284286
};
285287

286288

@@ -304,13 +306,13 @@ void doingSomethingStop(int index)
304306

305307
#else // #if USE_COMPLEX_STRUCT
306308

307-
irqCallback irqCallbackStartFunc[NUMBER_ISR_PWMS] =
309+
irqCallback irqCallbackStartFunc[] =
308310
{
309311
doingSomethingStart0, doingSomethingStart1, doingSomethingStart2, doingSomethingStart3,
310312
doingSomethingStart4, doingSomethingStart5, doingSomethingStart6, doingSomethingStart7
311313
};
312314

313-
irqCallback irqCallbackStopFunc[NUMBER_ISR_PWMS] =
315+
irqCallback irqCallbackStopFunc[] =
314316
{
315317
doingSomethingStop0, doingSomethingStop1, doingSomethingStop2, doingSomethingStop3,
316318
doingSomethingStop4, doingSomethingStop5, doingSomethingStop6, doingSomethingStop7
@@ -428,7 +430,7 @@ void setup()
428430
curISR_PWM_Data[i].previousMicrosStart = startMicros;
429431
//ISR_PWM.setInterval(curISR_PWM_Data[i].PWM_Period, curISR_PWM_Data[i].irqCallbackStartFunc);
430432

431-
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
433+
//void setPWM(uint32_t pin, float frequency, float dutycycle
432434
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
433435

434436
// You can use this with PWM_Freq in Hz

examples/ISR_8_PWMs_Array_Simple/ISR_8_PWMs_Array_Simple.ino

Lines changed: 7 additions & 6 deletions
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 "Teensy_Slow_PWM.h"
2829

2930
#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer
@@ -48,8 +49,8 @@
4849
#if defined(__IMXRT1062__)
4950
// For Teensy 4.0 and 4.1
5051
// Don't change these numbers to make higher Timer freq. System can hang
51-
#define HW_TIMER_INTERVAL_MS 0.0333f
52-
#define HW_TIMER_INTERVAL_FREQ 30000L
52+
#define HW_TIMER_INTERVAL_MS 0.01f
53+
#define HW_TIMER_INTERVAL_FREQ 100000L
5354
#elif defined(__MK66FX1M0__)
5455
// For Teensy 3.6
5556
// Don't change these numbers to make higher Timer freq. System can hang
@@ -99,15 +100,15 @@ uint32_t PWM_Pin[] =
99100
#define NUMBER_ISR_PWMS ( sizeof(PWM_Pin) / sizeof(uint32_t) )
100101

101102
// You can assign any interval for any timer here, in Hz
102-
double PWM_Freq[NUMBER_ISR_PWMS] =
103+
float PWM_Freq[] =
103104
{
104105
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
105106
};
106107

107108
// You can assign any interval for any timer here, in Microseconds
108-
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
109+
float PWM_DutyCycle[] =
109110
{
110-
5, 10, 20, 25, 30, 35, 40, 45
111+
5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0
111112
};
112113

113114
////////////////////////////////////////////////
@@ -154,7 +155,7 @@ void setup()
154155
// You can use up to 16 timer for each ISR_PWM
155156
for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++)
156157
{
157-
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
158+
//void setPWM(uint32_t pin, float frequency, float dutycycle
158159
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
159160

160161
// You can use this with PWM_Freq in Hz

examples/ISR_Changing_PWM/ISR_Changing_PWM.ino

Lines changed: 5 additions & 4 deletions
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 "Teensy_Slow_PWM.h"
2829

2930
#define LED_OFF HIGH
@@ -86,19 +87,19 @@ void TimerHandler()
8687
uint32_t PWM_Pin = LED_BUILTIN;
8788

8889
// You can assign any interval for any timer here, in Hz
89-
double PWM_Freq1 = 1.0f;
90+
float PWM_Freq1 = 1.0f;
9091
// You can assign any interval for any timer here, in Hz
91-
double PWM_Freq2 = 2.0f;
92+
float PWM_Freq2 = 2.0f;
9293

9394
// You can assign any interval for any timer here, in microseconds
9495
uint32_t PWM_Period1 = 1000000 / PWM_Freq1;
9596
// You can assign any interval for any timer here, in microseconds
9697
uint32_t PWM_Period2 = 1000000 / PWM_Freq2;
9798

9899
// You can assign any duty_cycle for any PWM here, from 0-100
99-
uint32_t PWM_DutyCycle1 = 50;
100+
float PWM_DutyCycle1 = 50.0;
100101
// You can assign any duty_cycle for any PWM here, from 0-100
101-
uint32_t PWM_DutyCycle2 = 90;
102+
float PWM_DutyCycle2 = 90.0;
102103

103104
// Channel number used to identify associated channel
104105
int channelNum;

examples/ISR_Modify_PWM/ISR_Modify_PWM.ino

Lines changed: 5 additions & 4 deletions
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 "Teensy_Slow_PWM.h"
2829

2930
#define LED_OFF HIGH
@@ -86,19 +87,19 @@ void TimerHandler()
8687
uint32_t PWM_Pin = LED_BUILTIN;
8788

8889
// You can assign any interval for any timer here, in Hz
89-
double PWM_Freq1 = 1.0f;
90+
float PWM_Freq1 = 1.0f;
9091
// You can assign any interval for any timer here, in Hz
91-
double PWM_Freq2 = 2.0f;
92+
float PWM_Freq2 = 2.0f;
9293

9394
// You can assign any interval for any timer here, in microseconds
9495
uint32_t PWM_Period1 = 1000000 / PWM_Freq1;
9596
// You can assign any interval for any timer here, in microseconds
9697
uint32_t PWM_Period2 = 1000000 / PWM_Freq2;
9798

9899
// You can assign any duty_cycle for any PWM here, from 0-100
99-
uint32_t PWM_DutyCycle1 = 10;
100+
float PWM_DutyCycle1 = 50.0;
100101
// You can assign any duty_cycle for any PWM here, from 0-100
101-
uint32_t PWM_DutyCycle2 = 90;
102+
float PWM_DutyCycle2 = 90.0;
102103

103104
// Channel number used to identify associated channel
104105
int channelNum;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/****************************************************************************************************************************
2+
multiFileProject.cpp
3+
4+
For nRF52-based boards using Adafruit_nRF52_Arduino core
5+
Written by Khoi Hoang
6+
7+
Built by Khoi Hoang https://github.com/khoih-prog/nRF52_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"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/****************************************************************************************************************************
2+
multiFileProject.h
3+
4+
For nRF52-based boards using Adafruit_nRF52_Arduino core
5+
Written by Khoi Hoang
6+
7+
Built by Khoi Hoang https://github.com/khoih-prog/nRF52_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 "Teensy_Slow_PWM.hpp"

0 commit comments

Comments
 (0)