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

Commit

Permalink
v1.1.0 to modify PWM settings on-the-fly
Browse files Browse the repository at this point in the history
### Releases v1.1.0

1. Add functions to modify PWM settings on-the-fly
2. Add example to demo how to modify PWM settings on-the-fly
  • Loading branch information
khoih-prog authored Nov 11, 2021
1 parent dc2f436 commit ae074bd
Show file tree
Hide file tree
Showing 26 changed files with 933 additions and 137 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Please ensure to specify the following:
Arduino IDE version: 1.8.16
Arduino megaAVR Core Version 1.8.7
OS: Ubuntu 20.04 LTS
Linux xy-Inspiron-3593 5.4.0-86-generic #97-Ubuntu SMP Fri Sep 17 19:19:40 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
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
Context:
I encountered a crash while trying to use the Timer Interrupt.
Expand Down
101 changes: 90 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,18 @@
* [1. Init Hardware Timer](#1-init-hardware-timer)
* [2. Set PWM Frequency, dutycycle, attach irqCallbackStartFunc and irqCallbackStopFunc functions](#2-Set-PWM-Frequency-dutycycle-attach-irqCallbackStartFunc-and-irqCallbackStopFunc-functions)
* [Examples](#examples)
* [ 1. ISR_8_PWMs_Array](examples/ISR_8_PWMs_Array)
* [ 2. ISR_8_PWMs_Array_Complex](examples/ISR_8_PWMs_Array_Complex)
* [ 3. ISR_8_PWMs_Array_Simple](examples/ISR_8_PWMs_Array_Simple)
* [ 1. ISR_8_PWMs_Array](examples/ISR_8_PWMs_Array)
* [ 2. ISR_8_PWMs_Array_Complex](examples/ISR_8_PWMs_Array_Complex)
* [ 3. ISR_8_PWMs_Array_Simple](examples/ISR_8_PWMs_Array_Simple)
* [ 4. ISR_Changing_PWM](examples/ISR_Changing_PWM)
* [ 5. ISR_Modify_PWM](examples/ISR_Modify_PWM)
* [Example ISR_8_PWMs_Array_Complex](#Example-ISR_8_PWMs_Array_Complex)
* [Debug Terminal Output Samples](#debug-terminal-output-samples)
* [1. ISR_8_PWMs_Array_Complex on megaAVR Nano Every](#1-ISR_8_PWMs_Array_Complex-on-megaAVR-Nano-Every)
* [2. ISR_8_PWMs_Array on megaAVR Nano Every](#2-isr_8_pwms_array-on-megaAVR-Nano-Every)
* [3. ISR_8_PWMs_Array_Simple on megaAVR Nano Every](#3-ISR_8_PWMs_Array_Simple-on-megaAVR-Nano-Every)
* [4. ISR_Modify_PWM on megaAVR Nano Every](#4-ISR_Modify_PWM-on-megaAVR-Nano-Every)
* [5. ISR_Changing_PWM on megaAVR Nano Every](#5-ISR_Changing_PWM-on-megaAVR-Nano-Every)
* [Debug](#debug)
* [Troubleshooting](#troubleshooting)
* [Issues](#issues)
Expand All @@ -55,7 +59,7 @@

### Features

This library enables you to use ISR-based PWM channels on ATmega4809-based boards, such as UNO WiFi Rev2, AVR_Nano_Every, etc., using [`Arduino megaAVR core`](https://github.com/arduino/ArduinoCore-megaavr) to create and output PWM any GPIO pin. Because this library doesn't use the powerful purely hardware-controlled PWM with many limitations, the maximum PWM frequency is currently limited at **500Hz**, which is still suitable for many real-life applications.
This library enables you to use ISR-based PWM channels on ATmega4809-based boards, such as UNO WiFi Rev2, AVR_Nano_Every, etc., using [`Arduino megaAVR core`](https://github.com/arduino/ArduinoCore-megaavr) to create and output PWM any GPIO pin. Because this library doesn't use the powerful purely hardware-controlled PWM with many limitations, the maximum PWM frequency is currently limited at **500Hz**, which is still suitable for many real-life applications. Now you can change the PWM settings on-the-fly

---

Expand Down Expand Up @@ -245,7 +249,9 @@ void setup()

1. [ISR_8_PWMs_Array](examples/ISR_8_PWMs_Array)
2. [ISR_8_PWMs_Array_Complex](examples/ISR_8_PWMs_Array_Complex)
3. [ISR_8_PWMs_Array_Simple](examples/ISR_8_PWMs_Array_Simple)
3. [ISR_8_PWMs_Array_Simple](examples/ISR_8_PWMs_Array_Simple)
4. [ISR_Changing_PWM](examples/ISR_Changing_PWM)
5. [ISR_Modify_PWM](examples/ISR_Modify_PWM)


---
Expand Down Expand Up @@ -386,11 +392,10 @@ uint32_t PWM_Period[NUMBER_ISR_PWMS] =
1000L, 500L, 333L, 250L, 200L, 166L, 142L, 125L
};
// You can assign any interval for any timer here, in Hz
uint32_t PWM_Freq[NUMBER_ISR_PWMS] =
double PWM_Freq[NUMBER_ISR_PWMS] =
{
1, 2, 3, 4, 5, 6, 7, 8
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
Expand Down Expand Up @@ -767,7 +772,7 @@ The following is the sample terminal output when running example [ISR_8_PWMs_Arr

```
Starting ISR_8_PWMs_Array_Complex on megaAVR Nano Every
megaAVR_SLOW_PWM v1.0.0
megaAVR_SLOW_PWM v1.1.0
CPU Frequency = 16 MHz
TCB Clock Frequency = 16MHz for highest accuracy
[PWM] TCB 1
Expand Down Expand Up @@ -832,7 +837,7 @@ The following is the sample terminal output when running example [**ISR_8_PWMs_A

```
Starting ISR_8_PWMs_Array on megaAVR Nano Every
megaAVR_SLOW_PWM v1.0.0
megaAVR_SLOW_PWM v1.1.0
CPU Frequency = 16 MHz
TCB Clock Frequency = 16MHz for highest accuracy
[PWM] TCB 1
Expand Down Expand Up @@ -871,7 +876,7 @@ The following is the sample terminal output when running example [**ISR_8_PWMs_A
```
Starting ISR_8_PWMs_Array_Simple on megaAVR Nano Every
megaAVR_SLOW_PWM v1.0.0
megaAVR_SLOW_PWM v1.1.0
CPU Frequency = 16 MHz
TCB Clock Frequency = 16MHz for highest accuracy
[PWM] TCB 1
Expand Down Expand Up @@ -901,6 +906,79 @@ Channel : 6 Period : 142857 OnTime : 57142 Start_Time : 2012956
Channel : 7 Period : 125000 OnTime : 56250 Start_Time : 2012956
```

---

### 4. ISR_Modify_PWM on megaAVR Nano Every

The following is the sample terminal output when running example [ISR_Modify_PWM](examples/ISR_Modify_PWM) on **megaAVR Nano Every** to demonstrate how to modify PWM settings on-the-fly without deleting the PWM channel

```
Starting ISR_Modify_PWM on megaAVR Nano Every
megaAVR_SLOW_PWM v1.1.0
CPU Frequency = 16 MHz
TCB Clock Frequency = 16MHz for highest accuracy
[PWM] TCB 1
[PWM] ==================
[PWM] Init, Timer = 1
[PWM] CTRLB = 0
[PWM] CCMP = 65535
[PWM] INTCTRL = 0
[PWM] CTRLA = 1
[PWM] ==================
[PWM] Frequency = 30000.00 , CLK_TCB_FREQ = 16000000
[PWM] setFrequency: _CCMPValueRemaining = 533
[PWM] ==================
[PWM] set_CCMP, Timer = 1
[PWM] CTRLB = 0
[PWM] CCMP = 533
[PWM] INTCTRL = 1
[PWM] CTRLA = 1
Starting ITimer1 OK, micros() = 2012212
Using PWM Freq = 1.00, PWM DutyCycle = 10
Channel : 0 Period : 1000000 OnTime : 100000 Start_Time : 2017184
Channel : 0 Period : 500000 OnTime : 450000 Start_Time : 12024008
Channel : 0 Period : 1000000 OnTime : 100000 Start_Time : 22024396
Channel : 0 Period : 500000 OnTime : 450000 Start_Time : 32025840
```

---

### 5. ISR_Changing_PWM on megaAVR Nano Every

The following is the sample terminal output when running example [ISR_Changing_PWM](examples/ISR_Changing_PWM) on **megaAVR Nano Every** to demonstrate how to modify PWM settings on-the-fly by deleting the PWM channel and reinit the PWM channel

```
Starting ISR_Changing_PWM on megaAVR Nano Every
megaAVR_SLOW_PWM v1.1.0
CPU Frequency = 16 MHz
TCB Clock Frequency = 16MHz for highest accuracy
[PWM] TCB 1
[PWM] ==================
[PWM] Init, Timer = 1
[PWM] CTRLB = 0
[PWM] CCMP = 65535
[PWM] INTCTRL = 0
[PWM] CTRLA = 1
[PWM] ==================
[PWM] Frequency = 30000.00 , CLK_TCB_FREQ = 16000000
[PWM] setFrequency: _CCMPValueRemaining = 533
[PWM] ==================
[PWM] set_CCMP, Timer = 1
[PWM] CTRLB = 0
[PWM] CCMP = 533
[PWM] INTCTRL = 1
[PWM] CTRLA = 1
Starting ITimer1 OK, micros() = 2012392
Using PWM Freq = 1.00, PWM DutyCycle = 50
Channel : 0 Period : 1000000 OnTime : 500000 Start_Time : 2017384
Using PWM Freq = 2.00, PWM DutyCycle = 90
Channel : 0 Period : 500000 OnTime : 450000 Start_Time : 12024552
Using PWM Freq = 1.00, PWM DutyCycle = 50
Channel : 0 Period : 1000000 OnTime : 500000 Start_Time : 22029376
Using PWM Freq = 2.00, PWM DutyCycle = 90
Channel : 0 Period : 500000 OnTime : 450000 Start_Time : 32034340
```


---
---
Expand Down Expand Up @@ -945,6 +1023,7 @@ Submit issues to: [megaAVR_Slow_PWM issues](https://github.com/khoih-prog/megaAV

1. Basic hardware multi-channel PWM for **Arduino megaAVR boards, such as UNO WiFi Rev2, AVR_Nano_Every, etc.** using [`Arduino megaAVR core`](https://github.com/arduino/ArduinoCore-megaavr)
2. Add Table of Contents
3. Add functions to modify PWM settings on-the-fly

---
---
Expand Down
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@
## Table of Contents

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

---
---

## Changelog

### Releases v1.1.0

1. Add functions to modify PWM settings on-the-fly
2. Add example to demo how to modify PWM settings on-the-fly

### Initial Releases v1.0.0

1. Initial coding to support **Arduino megaAVR boards, such as UNO WiFi Rev2, AVR_Nano_Every, etc.**, etc. using [`Arduino megaAVR core`](https://github.com/arduino/ArduinoCore-megaavr)
Expand Down
11 changes: 2 additions & 9 deletions examples/ISR_8_PWMs_Array/ISR_8_PWMs_Array.ino
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
Therefore, their executions are not blocked by bad-behaving functions / tasks.
This important feature is absolutely necessary for mission-critical tasks.
Version: 1.0.0
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K.Hoang 27/09/2021 Initial coding for megaAVR-based boards (UNO WiFi Rev2, NANO_EVERY, etc. )
*****************************************************************************************************************************/

#if ( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
Expand Down Expand Up @@ -102,11 +96,10 @@ 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
uint32_t PWM_Freq[NUMBER_ISR_PWMS] =
double PWM_Freq[NUMBER_ISR_PWMS] =
{
1, 2, 3, 4, 5, 6, 7, 8
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
Expand Down
11 changes: 2 additions & 9 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 @@ -11,12 +11,6 @@
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
Therefore, their executions are not blocked by bad-behaving functions / tasks.
This important feature is absolutely necessary for mission-critical tasks.
Version: 1.0.0
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K.Hoang 27/09/2021 Initial coding for megaAVR-based boards (UNO WiFi Rev2, NANO_EVERY, etc. )
*****************************************************************************************************************************/

#if ( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
Expand Down Expand Up @@ -151,11 +145,10 @@ uint32_t PWM_Period[NUMBER_ISR_PWMS] =
1000L, 500L, 333L, 250L, 200L, 166L, 142L, 125L
};


// You can assign any interval for any timer here, in Hz
uint32_t PWM_Freq[NUMBER_ISR_PWMS] =
double PWM_Freq[NUMBER_ISR_PWMS] =
{
1, 2, 3, 4, 5, 6, 7, 8
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
Expand Down
11 changes: 2 additions & 9 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 @@ -11,12 +11,6 @@
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
Therefore, their executions are not blocked by bad-behaving functions / tasks.
This important feature is absolutely necessary for mission-critical tasks.
Version: 1.0.0
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K.Hoang 27/09/2021 Initial coding for megaAVR-based boards (UNO WiFi Rev2, NANO_EVERY, etc. )
*****************************************************************************************************************************/

#if ( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
Expand Down Expand Up @@ -102,11 +96,10 @@ 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
uint32_t PWM_Freq[NUMBER_ISR_PWMS] =
double PWM_Freq[NUMBER_ISR_PWMS] =
{
1, 2, 3, 4, 5, 6, 7, 8
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
Expand Down
Loading

0 comments on commit ae074bd

Please sign in to comment.