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

Commit

Permalink
v1.2.3 to replace double with float
Browse files Browse the repository at this point in the history
### Releases v1.2.2

1. Use `float` for `DutyCycle` and `Freq`, `uint32_t` for `period`. 
2. Optimize code by not calculation in ISR
  • Loading branch information
khoih-prog authored Feb 2, 2022
1 parent 7b4b1fb commit 42d95b1
Show file tree
Hide file tree
Showing 17 changed files with 122 additions and 131 deletions.
90 changes: 33 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ void setup()
#define USING_MICROS_RESOLUTION true //false
// Default is true, uncomment to false
//#define CHANGING_PWM_END_OF_CYCLE false
//#define CHANGING_PWM_END_OF_CYCLE false
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "AVR_Slow_PWM.h"
Expand Down Expand Up @@ -394,9 +394,9 @@ typedef struct
irqCallback irqCallbackStartFunc;
irqCallback irqCallbackStopFunc;
double PWM_Freq;
float PWM_Freq;
double PWM_DutyCycle;
float PWM_DutyCycle;
uint32_t deltaMicrosStart;
uint32_t previousMicrosStart;
Expand Down Expand Up @@ -424,19 +424,19 @@ volatile unsigned long previousMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0 };
// You can assign any interval for any timer here, in Microseconds
double PWM_Period[] =
uint32_t PWM_Period[] =
{
1000.0, 500.0, 333.333, 250.0, 200.0, 166.667, 142.857, 125.0
1000, 500, 333, 250, 200, 167, 143, 125
};
// You can assign any interval for any timer here, in Hz
double PWM_Freq[] =
float PWM_Freq[] =
{
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
};
// You can assign any interval for any timer here, in Microseconds
double PWM_DutyCycle[] =
float PWM_DutyCycle[] =
{
5.0, 10.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0
};
Expand Down Expand Up @@ -746,7 +746,7 @@ void setup()
curISR_PWM_Data[i].previousMicrosStart = startMicros;
//ISR_PWM.setInterval(curISR_PWM_Data[i].PWM_Period, curISR_PWM_Data[i].irqCallbackStartFunc);
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
//void setPWM(uint32_t pin, float frequency, float dutycycle
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
// You can use this with PWM_Freq in Hz
Expand Down Expand Up @@ -793,7 +793,7 @@ The following is the sample terminal output when running example [ISR_8_PWMs_Arr

```
Starting ISR_8_PWMs_Array_Complex on Arduino AVR ATMega32U4
AVR_Slow_PWM v1.2.1
AVR_Slow_PWM v1.2.2
CPU Frequency = 16 MHz
[PWM] T3
[PWM] Freq * 1000 = 10000000.00
Expand Down Expand Up @@ -837,42 +837,24 @@ PWM Channel : 7, prog Period (ms): 125.00, actual (uS) : 125192, prog DutyCycle
The following is the sample terminal output when running example [**ISR_8_PWMs_Array**](examples/ISR_8_PWMs_Array) on **AVR Mega2560/ADK** to demonstrate how to use multiple PWM channels with simple callback functions.

```
Starting ISR_8_PWMs_Array_Complex on Arduino AVR Mega2560/ADK
AVR_Slow_PWM v1.2.1
Starting ISR_8_PWMs_Array on Arduino AVR Mega2560/ADK
AVR_Slow_PWM v1.2.2
CPU Frequency = 16 MHz
[PWM] T3
[PWM] Freq * 1000 = 10000000.00
[PWM] F_CPU = 16000000 , preScalerDiv = 1
[PWM] OCR = 1599 , preScalerIndex = 1
[PWM] OK in loop => _OCR = 1599
[PWM] _preScalerIndex = 1 , preScalerDiv = 1
Starting ITimer3 OK, micros() = 2024104
Channel : 0 Period : 1000000 OnTime : 50000 Start_Time : 2024988
Channel : 1 Period : 500000 OnTime : 50000 Start_Time : 2024988
Channel : 2 Period : 333333 OnTime : 66666 Start_Time : 2024988
Channel : 3 Period : 250000 OnTime : 62500 Start_Time : 2024988
Channel : 4 Period : 200000 OnTime : 60000 Start_Time : 2024988
Channel : 5 Period : 166666 OnTime : 58333 Start_Time : 2024988
Channel : 6 Period : 142857 OnTime : 57142 Start_Time : 2024988
Channel : 7 Period : 125000 OnTime : 56250 Start_Time : 2024988
SimpleTimer (us): 2000, us : 12070388, Dus : 10045444
PWM Channel : 0, prog Period (ms): 1000.00, actual (uS) : 1000000, prog DutyCycle : 5, actual : 4.98
PWM Channel : 1, prog Period (ms): 500.00, actual (uS) : 499996, prog DutyCycle : 10, actual : 10.00
PWM Channel : 2, prog Period (ms): 333.33, actual (uS) : 333396, prog DutyCycle : 20, actual : 19.98
PWM Channel : 3, prog Period (ms): 250.00, actual (uS) : 250196, prog DutyCycle : 25, actual : 24.94
PWM Channel : 4, prog Period (ms): 200.00, actual (uS) : 200192, prog DutyCycle : 30, actual : 29.88
PWM Channel : 5, prog Period (ms): 166.67, actual (uS) : 166792, prog DutyCycle : 35, actual : 34.90
PWM Channel : 6, prog Period (ms): 142.86, actual (uS) : 142988, prog DutyCycle : 40, actual : 39.87
PWM Channel : 7, prog Period (ms): 125.00, actual (uS) : 125196, prog DutyCycle : 45, actual : 44.89
SimpleTimer (us): 2000, us : 22144772, Dus : 10074384
PWM Channel : 0, prog Period (ms): 1000.00, actual (uS) : 1000000, prog DutyCycle : 5, actual : 5.00
PWM Channel : 1, prog Period (ms): 500.00, actual (uS) : 499996, prog DutyCycle : 10, actual : 10.00
PWM Channel : 2, prog Period (ms): 333.33, actual (uS) : 333396, prog DutyCycle : 20, actual : 19.98
PWM Channel : 3, prog Period (ms): 250.00, actual (uS) : 250196, prog DutyCycle : 25, actual : 24.94
PWM Channel : 4, prog Period (ms): 200.00, actual (uS) : 200196, prog DutyCycle : 30, actual : 29.87
PWM Channel : 5, prog Period (ms): 166.67, actual (uS) : 166792, prog DutyCycle : 35, actual : 34.90
PWM Channel : 6, prog Period (ms): 142.86, actual (uS) : 143016, prog DutyCycle : 40, actual : 39.87
PWM Channel : 7, prog Period (ms): 125.00, actual (uS) : 125008, prog DutyCycle : 45, actual : 44.96
Starting ITimer3 OK, micros() = 2023732
Channel : 0 Period : 1000000 OnTime : 50000 Start_Time : 2031420
Channel : 1 Period : 500000 OnTime : 50000 Start_Time : 2042728
Channel : 2 Period : 333333 OnTime : 66666 Start_Time : 2054724
Channel : 3 Period : 250000 OnTime : 62500 Start_Time : 2067932
Channel : 4 Period : 200000 OnTime : 60000 Start_Time : 2084232
Channel : 5 Period : 166666 OnTime : 58333 Start_Time : 2115432
Channel : 6 Period : 142857 OnTime : 57142 Start_Time : 3075536
Channel : 7 Period : 125000 OnTime : 56250 Start_Time : 4221280
```

---
Expand All @@ -883,7 +865,7 @@ The following is the sample terminal output when running example [**ISR_8_PWMs_A

```
Starting ISR_8_PWMs_Array_Complex on Arduino AVR UNO, Nano, etc.
AVR_Slow_PWM v1.2.1
AVR_Slow_PWM v1.2.2
CPU Frequency = 16 MHz
[PWM] T1
[PWM] Freq * 1000 = 10000000.00
Expand Down Expand Up @@ -929,20 +911,16 @@ The following is the sample terminal output when running example [ISR_Modify_PWM

```
Starting ISR_Modify_PWM on Arduino AVR Mega2560/ADK
AVR_Slow_PWM v1.2.1
AVR_Slow_PWM v1.2.2
CPU Frequency = 16 MHz
[PWM] T3
[PWM] Freq * 1000 = 10000000.00
[PWM] F_CPU = 16000000 , preScalerDiv = 1
[PWM] OCR = 1599 , preScalerIndex = 1
[PWM] OK in loop => _OCR = 1599
[PWM] _preScalerIndex = 1 , preScalerDiv = 1
Starting ITimer3 OK, micros() = 2023160
Using PWM Freq = 1.00, PWM DutyCycle = 10
Channel : 0 Period : 1000000 OnTime : 100000 Start_Time : 2028040
Channel : 0 Period : 500000 OnTime : 450000 Start_Time : 12033220
Channel : 0 Period : 1000000 OnTime : 100000 Start_Time : 22034628
Channel : 0 Period : 500000 OnTime : 450000 Start_Time : 32036036
Starting ITimer3 OK, micros() = 2023764
Using PWM Freq = 1.00, PWM DutyCycle = 50.00
```

---
Expand All @@ -953,23 +931,21 @@ The following is the sample terminal output when running example [ISR_Changing_P

```
Starting ISR_Changing_PWM on Arduino AVR Mega2560/ADK
AVR_Slow_PWM v1.2.1
AVR_Slow_PWM v1.2.2
CPU Frequency = 16 MHz
[PWM] T3
[PWM] Freq * 1000 = 10000000.00
[PWM] F_CPU = 16000000 , preScalerDiv = 1
[PWM] OCR = 1599 , preScalerIndex = 1
[PWM] OK in loop => _OCR = 1599
[PWM] _preScalerIndex = 1 , preScalerDiv = 1
Starting ITimer3 OK, micros() = 2023336
Using PWM Freq = 1.00, PWM DutyCycle = 50
Channel : 0 Period : 1000000 OnTime : 500000 Start_Time : 2028216
Using PWM Freq = 2.00, PWM DutyCycle = 90
Channel : 0 Period : 500000 OnTime : 450000 Start_Time : 12035408
Using PWM Freq = 1.00, PWM DutyCycle = 50
Channel : 0 Period : 1000000 OnTime : 500000 Start_Time : 22040404
Using PWM Freq = 2.00, PWM DutyCycle = 90
Channel : 0 Period : 500000 OnTime : 450000 Start_Time : 32045592
Starting ITimer3 OK, micros() = 2023844
Using PWM Freq = 1.00, PWM DutyCycle = 50.00
Using PWM Freq = 2.00, PWM DutyCycle = 90.00
Using PWM Freq = 1.00, PWM DutyCycle = 50.00
Using PWM Freq = 2.00, PWM DutyCycle = 90.00
Using PWM Freq = 1.00, PWM DutyCycle = 50.00
Using PWM Freq = 2.00, PWM DutyCycle = 90.00
```

---
Expand Down Expand Up @@ -1018,7 +994,7 @@ Submit issues to: [AVR_Slow_PWM issues](https://github.com/khoih-prog/AVR_Slow_P
3. Add functions to modify PWM settings on-the-fly
4. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
5. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project
6. Improve accuracy by using `double`, instead of `uint32_t` for `dutycycle`, `period`
6. Improve accuracy by using `float`, instead of `uint32_t` for `dutycycle`
7. Optimize library code by using `reference-passing` instead of `value-passing`
8. DutyCycle to be optionally updated at the end current PWM period instead of immediately.

Expand Down
6 changes: 6 additions & 0 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.2](#releases-v122)
* [Releases v1.2.1](#releases-v121)
* [Releases v1.2.0](#releases-v120)
* [Releases v1.1.0](#releases-v110)
Expand All @@ -22,6 +23,11 @@

## Changelog

### Releases v1.2.2

1. Use `float` for `DutyCycle` and `Freq`, `uint32_t` for `period`.
2. Optimize code by not calculation in ISR

### Releases v1.2.1

1. 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)
Expand Down
6 changes: 3 additions & 3 deletions examples/ISR_8_PWMs_Array/ISR_8_PWMs_Array.ino
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ 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[] =
float PWM_Freq[] =
{
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
};

// You can assign any interval for any timer here, in Microseconds
double PWM_DutyCycle[] =
float PWM_DutyCycle[] =
{
5.0, 10.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0
};
Expand Down Expand Up @@ -238,7 +238,7 @@ void setup()
// You can use up to 16 timer for each ISR_PWM
for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++)
{
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
//void setPWM(uint32_t pin, float frequency, float dutycycle
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)

// You can use this with PWM_Freq in Hz
Expand Down
14 changes: 7 additions & 7 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 @@ -114,9 +114,9 @@ typedef struct
irqCallback irqCallbackStartFunc;
irqCallback irqCallbackStopFunc;

double PWM_Freq;
float PWM_Freq;

double PWM_DutyCycle;
float PWM_DutyCycle;

uint32_t deltaMicrosStart;
uint32_t previousMicrosStart;
Expand Down Expand Up @@ -144,19 +144,19 @@ volatile unsigned long previousMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0 };


// You can assign any interval for any timer here, in Microseconds
double PWM_Period[] =
uint32_t PWM_Period[] =
{
1000.0, 500.0, 333.333, 250.0, 200.0, 166.667, 142.857, 125.0
1000, 500, 333, 250, 200, 167, 143, 125
};

// You can assign any interval for any timer here, in Hz
double PWM_Freq[] =
float PWM_Freq[] =
{
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
};

// You can assign any interval for any timer here, in Microseconds
double PWM_DutyCycle[] =
float PWM_DutyCycle[] =
{
5.0, 10.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0
};
Expand Down Expand Up @@ -466,7 +466,7 @@ void setup()
curISR_PWM_Data[i].previousMicrosStart = startMicros;
//ISR_PWM.setInterval(curISR_PWM_Data[i].PWM_Period, curISR_PWM_Data[i].irqCallbackStartFunc);

//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
//void setPWM(uint32_t pin, float frequency, float dutycycle
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)

// You can use this with PWM_Freq in Hz
Expand Down
4 changes: 2 additions & 2 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 @@ -101,13 +101,13 @@ 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[] =
float PWM_Freq[] =
{
1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
};

// You can assign any interval for any timer here, in Microseconds
double PWM_DutyCycle[] =
float PWM_DutyCycle[] =
{
5.0, 10.0, 20.0, 25.0, 30.0, 35.0, 40.0, 45.0
};
Expand Down
12 changes: 6 additions & 6 deletions examples/ISR_Changing_PWM/ISR_Changing_PWM.ino
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,19 @@ void TimerHandler()
uint32_t PWM_Pin = LED_BUILTIN;

// You can assign any interval for any timer here, in Hz
double PWM_Freq1 = 1.0f;
float PWM_Freq1 = 1.0f;
// You can assign any interval for any timer here, in Hz
double PWM_Freq2 = 2.0f;
float PWM_Freq2 = 2.0f;

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

// You can assign any duty_cycle for any PWM here, from 0-100
double PWM_DutyCycle1 = 50.0;
float PWM_DutyCycle1 = 50.0;
// You can assign any duty_cycle for any PWM here, from 0-100
double PWM_DutyCycle2 = 90.0;
float PWM_DutyCycle2 = 90.0;

// Channel number used to identify associated channel
int channelNum;
Expand Down
12 changes: 6 additions & 6 deletions examples/ISR_Modify_PWM/ISR_Modify_PWM.ino
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,19 @@ void TimerHandler()
uint32_t PWM_Pin = LED_BUILTIN;

// You can assign any interval for any timer here, in Hz
double PWM_Freq1 = 1.0f;
float PWM_Freq1 = 1.0f;
// You can assign any interval for any timer here, in Hz
double PWM_Freq2 = 2.0f;
float PWM_Freq2 = 2.0f;

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

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

// Channel number used to identify associated channel
int channelNum;
Expand Down
4 changes: 2 additions & 2 deletions examples/multiFileProject/multiFileProject.ino
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#warning Using Timer3
#endif

#define AVR_SLOW_PWM_VERSION_MIN_TARGET F("AVR_Slow_PWM v1.2.0")
#define AVR_SLOW_PWM_VERSION_MIN 1002000
#define AVR_SLOW_PWM_VERSION_MIN_TARGET F("AVR_Slow_PWM v1.2.2")
#define AVR_SLOW_PWM_VERSION_MIN 1002002

#include "multiFileProject.h"

Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "AVR_Slow_PWM",
"version": "1.2.1",
"version": "1.2.2",
"keywords": "timing, device, control, timer, interrupt, hardware, isr, isr-based, hardware-timer, mission-critical, accuracy, precise, non-blocking, avr, mega-2560, nano, uno, leonardo, 32u4, 16u4, at-mega",
"description": "This library enables you to use ISR-based PWM channels on AVR-based boards, such as Mega-2560, UNO,Nano, Leonardo, etc., to create and output PWM any GPIO pin. It now supports 16 ISR-based PWM channels, while consuming only 1 Hardware Timer. PWM channel interval can be very long (ulong microsecs / millisecs). The most important feature is they're ISR-based PWM channels, supporting lower PWM frequencies with suitable accuracy. Their executions are not blocked by bad-behaving functions or tasks. This important feature is absolutely necessary for mission-critical tasks. These ISR-based PWMs, still work even if other software functions are blocking. Moreover, they are much more precise (certainly depending on clock frequency accuracy) than other software-based PWM using millis() or micros(). That's necessary if you need to control devices requiring high precision. Now you can change the PWM settings on-the-fly",
"authors":
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=AVR_Slow_PWM
version=1.2.1
version=1.2.2
author=Khoi Hoang <[email protected]>
maintainer=Khoi Hoang <[email protected]>
sentence=This library enables you to use ISR-based PWM channels on AVR-based boards, such as Mega-2560, UNO,Nano, Leonardo, etc., to create and output PWM any GPIO pin.
Expand Down
3 changes: 2 additions & 1 deletion src/AVR_Slow_PWM.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
Therefore, their executions are not blocked by bad-behaving functions / tasks.
This important feature is absolutely necessary for mission-critical tasks.
Version: 1.2.1
Version: 1.2.2
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K.Hoang 27/09/2021 Initial coding for AVR-based boards (UNO, Nano, Mega, 32U4, 16U4, etc. )
1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly
1.2.0 K Hoang 29/01/2022 Fix multiple-definitions linker error. Improve accuracy
1.2.1 K Hoang 30/01/2022 DutyCycle to be updated at the end current PWM period
1.2.2 K Hoang 01/02/2022 Use float for DutyCycle and Freq, uint32_t for period. Optimize code
*****************************************************************************************************************************/

#pragma once
Expand Down
Loading

0 comments on commit 42d95b1

Please sign in to comment.