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

Commit

Permalink
v1.2.0 to fix multiple-definitions linker error
Browse files Browse the repository at this point in the history
### Releases v1.2.0

1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
2. 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)
3. Add examples [multiFileProject](examples/multiFileProject) to demo for multiple-file project
4. Improve accuracy by using `double`, instead of `uint32_t` for `dutycycle`, `period`. Check [Change Duty Cycle #1](khoih-prog/ESP8266_PWM#1 (comment))
5. Optimize library code by using `reference-passing` instead of `value-passing`
6. Update examples accordingly
  • Loading branch information
khoih-prog committed Feb 1, 2022
1 parent 3ec17d1 commit 486a8cd
Show file tree
Hide file tree
Showing 21 changed files with 1,578 additions and 1,266 deletions.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p

Please ensure to specify the following:

* Arduino IDE version (e.g. 1.8.16) or Platform.io version
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
* `SAMDUE` Core Version (e.g. Arduino SAMDUE_ core v1.6.12)
* Contextual information (e.g. what you were trying to achieve)
* Simplest possible steps to reproduce
Expand All @@ -26,10 +26,10 @@ Please ensure to specify the following:
### Example

```
Arduino IDE version: 1.8.16
Arduino IDE version: 1.8.19
Arduino SAMDUE Core Version 1.6.12
OS: Ubuntu 20.04 LTS
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
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
Context:
I encountered a crash while trying to use the Timer Interrupt.
Expand Down
226 changes: 118 additions & 108 deletions README.md

Large diffs are not rendered by default.

17 changes: 11 additions & 6 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
## Table of Contents

* [Changelog](#changelog)
* [Releases v1.2.0](#releases-v120)
* [Releases v1.1.0](#releases-v110)
* [Initial Releases v1.0.0](#Initial-Releases-v100)

Expand All @@ -20,6 +21,16 @@

## Changelog

### Releases v1.2.0

1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
2. 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)
3. Add examples [multiFileProject](examples/multiFileProject) to demo for multiple-file project
4. Improve accuracy by using `double`, instead of `uint32_t` for `dutycycle`, `period`. Check [Change Duty Cycle #1](https://github.com/khoih-prog/ESP8266_PWM/issues/1#issuecomment-1024969658)
5. Optimize library code by using `reference-passing` instead of `value-passing`
6. Update examples accordingly


### Releases v1.1.0

1. Add functions to modify PWM settings on-the-fly
Expand All @@ -31,11 +42,5 @@

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

---
---

## Copyright

Copyright 2021- Khoi Hoang


20 changes: 12 additions & 8 deletions examples/ISR_8_PWMs_Array/ISR_8_PWMs_Array.ino
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,20 @@
// Don't define _PWM_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define _PWM_LOGLEVEL_ 4

// Default is true, uncomment to false
#define CHANGING_PWM_END_OF_CYCLE false

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

#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer

#define LED_OFF HIGH
#define LED_ON LOW

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
//#ifndef LED_BUILTIN
// #define LED_BUILTIN 13
//#endif

#ifndef LED_BLUE
#define LED_BLUE 2
Expand All @@ -44,8 +48,8 @@
#define USING_HW_TIMER_INTERVAL_MS false //true

// Don't change these numbers to make higher Timer freq. System can hang
#define HW_TIMER_INTERVAL_US 10L
#define HW_TIMER_INTERVAL_FREQ 100000L
#define HW_TIMER_INTERVAL_US 30L
#define HW_TIMER_INTERVAL_FREQ 33333L

volatile uint32_t startMicros = 0;

Expand Down Expand Up @@ -80,15 +84,15 @@ uint32_t PWM_Pin[] =
#define NUMBER_ISR_PWMS ( sizeof(PWM_Pin) / sizeof(uint32_t) )

// You can assign any interval for any timer here, in Hz
double PWM_Freq[NUMBER_ISR_PWMS] =
double PWM_Freq[] =
{
1.0f, 2.0f, 3.0f, 5.0f, 10.0f, 20.0f, 30.0f, 50.0f
};

// You can assign any duty-cycle for any PWM channel here, in %
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
double PWM_DutyCycle[] =
{
5, 10, 20, 25, 30, 35, 40, 45
5.0, 10.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0
};


Expand Down
54 changes: 29 additions & 25 deletions examples/ISR_8_PWMs_Array_Complex/ISR_8_PWMs_Array_Complex.ino
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,20 @@
// Don't define _PWM_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define _PWM_LOGLEVEL_ 3

// Default is true, uncomment to false
//#define CHANGING_PWM_END_OF_CYCLE false

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

#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer

#define LED_OFF HIGH
#define LED_ON LOW

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
//#ifndef LED_BUILTIN
// #define LED_BUILTIN 13
//#endif

#ifndef LED_BLUE
#define LED_BLUE 2
Expand All @@ -44,8 +48,8 @@
#define USING_HW_TIMER_INTERVAL_MS false //true

// Don't change these numbers to make higher Timer freq. System can hang
#define HW_TIMER_INTERVAL_US 10L
#define HW_TIMER_INTERVAL_FREQ 100000L
#define HW_TIMER_INTERVAL_US 30L
#define HW_TIMER_INTERVAL_FREQ 33333L

volatile uint32_t startMicros = 0;

Expand Down Expand Up @@ -93,9 +97,9 @@ typedef struct
irqCallback irqCallbackStartFunc;
irqCallback irqCallbackStopFunc;

uint32_t PWM_Freq;
double PWM_Freq;

uint32_t PWM_DutyCycle;
double PWM_DutyCycle;

uint32_t deltaMicrosStart;
uint32_t previousMicrosStart;
Expand All @@ -115,22 +119,22 @@ void doingSomethingStop(int index);

#else // #if USE_COMPLEX_STRUCT

volatile unsigned long deltaMicrosStart [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
volatile unsigned long previousMicrosStart [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
volatile unsigned long deltaMicrosStart [] = { 0, 0, 0, 0, 0, 0, 0, 0 };
volatile unsigned long previousMicrosStart [] = { 0, 0, 0, 0, 0, 0, 0, 0 };

volatile unsigned long deltaMicrosStop [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
volatile unsigned long previousMicrosStop [NUMBER_ISR_PWMS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
volatile unsigned long deltaMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0 };
volatile unsigned long previousMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0 };

// You can assign any interval for any timer here, in Hz
double PWM_Freq[NUMBER_ISR_PWMS] =
double PWM_Freq[] =
{
1.0f, 2.0f, 3.0f, 5.0f, 10.0f, 20.0f, 30.0f, 50.0f
};

// You can assign any duty-cycle for any PWM channel here, in %
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
double PWM_DutyCycle[] =
{
5, 10, 20, 25, 30, 35, 40, 45
5.0, 10.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0
};

void doingSomethingStart(int index)
Expand Down Expand Up @@ -244,17 +248,17 @@ void doingSomethingStop7()

#if USE_COMPLEX_STRUCT

ISR_PWM_Data curISR_PWM_Data[NUMBER_ISR_PWMS] =
ISR_PWM_Data curISR_PWM_Data[] =
{
// pin, irqCallbackStartFunc, irqCallbackStopFunc, PWM_Freq, PWM_DutyCycle, deltaMicrosStart, previousMicrosStart, deltaMicrosStop, previousMicrosStop
{ LED_BUILTIN, doingSomethingStart0, doingSomethingStop0, 1, 5, 0, 0, 0, 0 },
{ PIN_22, doingSomethingStart1, doingSomethingStop1, 2, 10, 0, 0, 0, 0 },
{ PIN_23, doingSomethingStart2, doingSomethingStop2, 3, 20, 0, 0, 0, 0 },
{ PIN_24, doingSomethingStart3, doingSomethingStop3, 5, 25, 0, 0, 0, 0 },
{ PIN_25, doingSomethingStart4, doingSomethingStop4, 10, 30, 0, 0, 0, 0 },
{ PIN_26, doingSomethingStart5, doingSomethingStop5, 20, 35, 0, 0, 0, 0 },
{ PIN_27, doingSomethingStart6, doingSomethingStop6, 30, 40, 0, 0, 0, 0 },
{ PIN_28, doingSomethingStart7, doingSomethingStop7, 50, 45, 0, 0, 0, 0 },
{ LED_BUILTIN, doingSomethingStart0, doingSomethingStop0, 1.0, 5.0, 0, 0, 0, 0 },
{ PIN_22, doingSomethingStart1, doingSomethingStop1, 2.0, 10.0, 0, 0, 0, 0 },
{ PIN_23, doingSomethingStart2, doingSomethingStop2, 3.0, 20.0, 0, 0, 0, 0 },
{ PIN_24, doingSomethingStart3, doingSomethingStop3, 5.0, 25.0, 0, 0, 0, 0 },
{ PIN_25, doingSomethingStart4, doingSomethingStop4, 10.0, 30.0, 0, 0, 0, 0 },
{ PIN_26, doingSomethingStart5, doingSomethingStop5, 20.0, 35.0, 0, 0, 0, 0 },
{ PIN_27, doingSomethingStart6, doingSomethingStop6, 30.0, 40.0, 0, 0, 0, 0 },
{ PIN_28, doingSomethingStart7, doingSomethingStop7, 50.0, 45.0, 0, 0, 0, 0 },
};


Expand All @@ -278,13 +282,13 @@ void doingSomethingStop(int index)

#else // #if USE_COMPLEX_STRUCT

irqCallback irqCallbackStartFunc[NUMBER_ISR_PWMS] =
irqCallback irqCallbackStartFunc[] =
{
doingSomethingStart0, doingSomethingStart1, doingSomethingStart2, doingSomethingStart3,
doingSomethingStart4, doingSomethingStart5, doingSomethingStart6, doingSomethingStart7
};

irqCallback irqCallbackStopFunc[NUMBER_ISR_PWMS] =
irqCallback irqCallbackStopFunc[] =
{
doingSomethingStop0, doingSomethingStop1, doingSomethingStop2, doingSomethingStop3,
doingSomethingStop4, doingSomethingStop5, doingSomethingStop6, doingSomethingStop7
Expand Down
20 changes: 12 additions & 8 deletions examples/ISR_8_PWMs_Array_Simple/ISR_8_PWMs_Array_Simple.ino
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,20 @@
// Don't define _PWM_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define _PWM_LOGLEVEL_ 3

// Default is true, uncomment to false
#define CHANGING_PWM_END_OF_CYCLE false

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

#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer

#define LED_OFF HIGH
#define LED_ON LOW

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
//#ifndef LED_BUILTIN
// #define LED_BUILTIN 13
//#endif

#ifndef LED_BLUE
#define LED_BLUE 2
Expand All @@ -44,8 +48,8 @@
#define USING_HW_TIMER_INTERVAL_MS false //true

// Don't change these numbers to make higher Timer freq. System can hang
#define HW_TIMER_INTERVAL_US 10L
#define HW_TIMER_INTERVAL_FREQ 100000L
#define HW_TIMER_INTERVAL_US 30L
#define HW_TIMER_INTERVAL_FREQ 33333L

volatile uint32_t startMicros = 0;

Expand Down Expand Up @@ -80,15 +84,15 @@ uint32_t PWM_Pin[] =
#define NUMBER_ISR_PWMS ( sizeof(PWM_Pin) / sizeof(uint32_t) )

// You can assign any interval for any timer here, in Hz
double PWM_Freq[NUMBER_ISR_PWMS] =
double PWM_Freq[] =
{
1.0f, 2.0f, 3.0f, 5.0f, 10.0f, 20.0f, 30.0f, 50.0f
};

// You can assign any duty-cycle for any PWM channel here, in %
uint32_t PWM_DutyCycle[NUMBER_ISR_PWMS] =
double PWM_DutyCycle[] =
{
5, 10, 20, 25, 30, 35, 40, 45
5.0, 10.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0
};


Expand Down
22 changes: 13 additions & 9 deletions examples/ISR_Changing_PWM/ISR_Changing_PWM.ino
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@
// Don't define _PWM_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define _PWM_LOGLEVEL_ 3

// Default is true, uncomment to false
//#define CHANGING_PWM_END_OF_CYCLE false

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

#define LED_OFF HIGH
#define LED_ON LOW

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
//#ifndef LED_BUILTIN
// #define LED_BUILTIN 13
//#endif

#ifndef LED_BLUE
#define LED_BLUE 2
Expand All @@ -42,8 +46,8 @@
#define USING_HW_TIMER_INTERVAL_MS false //true

// Don't change these numbers to make higher Timer freq. System can hang
#define HW_TIMER_INTERVAL_US 10L
#define HW_TIMER_INTERVAL_FREQ 100000L
#define HW_TIMER_INTERVAL_US 20L
#define HW_TIMER_INTERVAL_FREQ 50000L

volatile uint32_t startMicros = 0;

Expand Down Expand Up @@ -72,14 +76,14 @@ double PWM_Freq1 = 1.0f;
double PWM_Freq2 = 2.0f;

// You can assign any interval for any timer here, in microseconds
uint32_t PWM_Period1 = 1000000 / PWM_Freq1;
double PWM_Period1 = 1000000 / PWM_Freq1;
// You can assign any interval for any timer here, in microseconds
uint32_t PWM_Period2 = 1000000 / PWM_Freq2;
double PWM_Period2 = 1000000 / PWM_Freq2;

// You can assign any duty_cycle for any PWM here, from 0-100
uint32_t PWM_DutyCycle1 = 50;
double PWM_DutyCycle1 = 50;
// You can assign any duty_cycle for any PWM here, from 0-100
uint32_t PWM_DutyCycle2 = 90;
double PWM_DutyCycle2 = 90;

// Channel number used to identify associated channel
int channelNum;
Expand Down
24 changes: 14 additions & 10 deletions examples/ISR_Modify_PWM/ISR_Modify_PWM.ino
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@
// Don't define _PWM_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define _PWM_LOGLEVEL_ 3

// Default is true, uncomment to false
//#define CHANGING_PWM_END_OF_CYCLE false

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

#define LED_OFF HIGH
#define LED_ON LOW

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
//#ifndef LED_BUILTIN
// #define LED_BUILTIN 13
//#endif

#ifndef LED_BLUE
#define LED_BLUE 2
Expand All @@ -42,8 +46,8 @@
#define USING_HW_TIMER_INTERVAL_MS false //true

// Don't change these numbers to make higher Timer freq. System can hang
#define HW_TIMER_INTERVAL_US 10L
#define HW_TIMER_INTERVAL_FREQ 100000L
#define HW_TIMER_INTERVAL_US 20L
#define HW_TIMER_INTERVAL_FREQ 50000L

volatile uint32_t startMicros = 0;

Expand Down Expand Up @@ -72,14 +76,14 @@ double PWM_Freq1 = 1.0f;
double PWM_Freq2 = 2.0f;

// You can assign any interval for any timer here, in microseconds
uint32_t PWM_Period1 = 1000000 / PWM_Freq1;
double PWM_Period1 = 1000000.0 / PWM_Freq1;
// You can assign any interval for any timer here, in microseconds
uint32_t PWM_Period2 = 1000000 / PWM_Freq2;
double PWM_Period2 = 1000000.0 / PWM_Freq2;

// You can assign any duty_cycle for any PWM here, from 0-100
uint32_t PWM_DutyCycle1 = 10;
double PWM_DutyCycle1 = 10.0;
// You can assign any duty_cycle for any PWM here, from 0-100
uint32_t PWM_DutyCycle2 = 90;
double PWM_DutyCycle2 = 90.0;

// Channel number used to identify associated channel
int channelNum;
Expand Down Expand Up @@ -134,7 +138,7 @@ void changePWM()
static uint8_t count = 1;

double PWM_Freq;
uint32_t PWM_DutyCycle;
double PWM_DutyCycle;

if (count++ % 2)
{
Expand Down
Loading

0 comments on commit 486a8cd

Please sign in to comment.