Skip to content

Commit afaddbc

Browse files
committed
Update
1 parent f7158d6 commit afaddbc

29 files changed

+744
-516
lines changed

README.md

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,33 @@
66
[![Build Status](https://github.com/ArminJo/Arduino-Utils/workflows/LibraryBuild/badge.svg)](https://github.com/ArminJo/Arduino-Utils/actions)
77
![Hit Counter](https://visitor-badge.laobi.icu/badge?page_id=ArminJo_Arduino-Utils)
88

9-
## My utility collection for Arduino
9+
# My utility collection for Arduino
1010

11-
### SimpleEMAFilters.cpp
12-
- A fixed set of 6 **ultrafast EMA (Exponential Moving Average) filters** which require only **1 to 2 microseconds**.
11+
## [SimpleEMAFilters.hpp](https://github.com/ArminJo/Arduino-Utils/blob/master/src/SimpleEMAFilters.hpp#L66)
12+
An EMA (**Exponential Moving Average**) filter behaves like an RC lowpass filter with RC = SamplePeriod((1-alpha)/alpha) see [here](https://en.wikipedia.org/wiki/Low-pass_filter#Simple_infinite_impulse_response_filter).<br/>
13+
An EMA filter is implemented by e.g. the following statement:
14+
15+
```c++
16+
int16_t Lowpass5 += ((InputValue - Lowpass5) >> 5;
17+
```
18+
which takes 2.5 us on a 16 MHz Arduino Uno.
19+
20+
The alpha's for the implemented **ultrafast EMA filters** are 1/2, 1/4, 1/8, 1/16, 1/32 and 1/256 corresponding to the shift values of 1, 2, 3, 4, 5 and 8.
21+
22+
#### For a 1 kHz sampling rate (1/1000s sampling interval) we get the following equivalent cutoff (-3db) frequencies:
23+
- For alpha 1/2 (shift 1) -> 160 Hz
24+
- 1/4 -> 53 Hz (160 Hz / 3)
25+
- 1/8 -> 22.7 Hz (160 Hz / 7)
26+
- 1/16 -> 10.6 Hz (160 Hz / 15)
27+
- 1/32 -> 5.13 Hz (160 Hz / 31)
28+
- 1/256 -> 0.624 Hz (160 Hz / 255)
29+
30+
### The SimpleEMAFilters.hpp contains:
31+
- A fixed set of 6 **ultrafast** EMA (Exponential Moving Average) filters which require only **1 to 2 microseconds**.
1332
- 3 derived filters (highpass and 2 bandpasses) by just subtracting one lowpass from input (highpass) or from another lowpass (bandpass).
1433
- Display routines for Arduino Plotter.
15-
An EMA filter behaves like an RC lowpass filter with RC = SamplePeriod((1-alpha)/alpha) see [here](https://en.wikipedia.org/wiki/Low-pass_filter#Simple_infinite_impulse_response_filter).<br/>
16-
The alpha's for the implemented **ultrafast EMA filters** are 1/2, 1/4, 1/8, 1/16, 1/32, and 1/256.
17-
#### For a 1 kHz sampling rate (1/1000s sampling interval) we get the following equivalent cutoff (-3db) frequencies:
18-
- 1/2 -> 160 Hz
19-
- 1/4 -> 53 Hz (160 / 3)
20-
- 1/8 -> 22.7 Hz (160 / 7)
21-
- 1/16 -> 10.6 Hz
22-
- 1/32 -> 5.13 Hz
23-
- 1/256 -> 0.624 Hz (160 / 255)
34+
35+
All implemented filters are applied at once to the input test signal calling `doFiltersStep(int16_t aInput)` and the results can in turn easily be displayed in the Arduino Plotter.
2436

2537
#### Plotter output representing e.g. a 20 Hz square / sine wave at a sample rate of 1 ms (or 40 Hz at 0.5 ms and so on)
2638
Arduino Plotter output for a rectangle input signal with a amplitude of +/- 100. E.g. Lowpass3 is the one with alpha 1/8 implemented by `>> 3`.
@@ -32,21 +44,23 @@ Arduino Plotter output for a sine input signal with a amplitude of +/- 100. Note
3244
Arduino Plotter output for a triangle input signal with a amplitude of +/- 100. Note that Lowpass5 is almost a perfect sine.
3345
![ArduinoPlotter output](pictures/LowPass_TriangleInput.png)
3446

35-
***Attention!** The 16 bit implementations are limited to a **maximum input value of +/- 16383** for rectangular input (which is the worst input case). The reason is, that the term `InputValue - Lowpass3` must always fit into a 16 bit signed integer.
36-
3747
The floating point implementation of the 1/32 EMA filter takes 24 to 34 µs.<br/>
3848

39-
All filters are applied to your test signal calling `doFiltersStep(int16_t)` and the results can in turn easily be displayed in the Arduino Plotter.<br/>
4049
There is no function implemented for one EMA filter, since it is better to implement it directly by e.g.
41-
```
50+
51+
```c++
4252
int16_t Lowpass3;
53+
int16_t Lowpass5;
4354
int32_t Lowpass5_int32;
4455
..
4556
Lowpass3 += ((InputValue - Lowpass3) + (1 << 2)) >> 3; // 1.8 us, alpha = 0.125, cutoff frequency 22.7 Hz @1kHz
4657
Lowpass5 += ((InputValue - Lowpass5) + (1 << 4)) >> 5; // 2.5 us, alpha = 1/32 0.03125, cutoff frequency 5.13 Hz @1kHz
4758
Lowpass5_int32 += ((((int32_t) InputValue) << 8) - Lowpass5_int32) >> 5; // Fixed point 4.2 us, value is Lowpass5_int32 >> 8
4859
Lowpass8_int32 += ((((int32_t) InputValue) << 16) - Lowpass8_int32) >> 8; // Fixed point 2.0 us because of fast shift, value is Lowpass8_int32 >> 16
4960
```
61+
62+
***Attention!** The 16 bit implementations are limited to a **maximum input value of +/- 16383** for rectangular input (which is the worst input case). The reason is, that the term `InputValue - Lowpass3` must always fit into a 16 bit signed integer.
63+
5064
#### Related Links
5165
- https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
5266
- https://www.dsprelated.com/blogimages/RickLyons/Exponential_Averaging_FIGURE2.gif
@@ -129,14 +143,15 @@ library available as an Arduino library.
129143

130144
### The very useful *digitalWriteFast.h* file from [Watterott electronic](https://github.com/watterott/Arduino-Libs).
131145

132-
### Modifying compile options with Arduino IDE
146+
### Changing include (*.h) files with Arduino IDE
133147
First, use *Sketch > Show Sketch Folder (Ctrl+K)*.<br/>
134-
If you did not yet stored the example as your own sketch, then you are instantly in the right library folder.<br/>
148+
If you have not yet saved the example as your own sketch, then you are instantly in the right library folder.<br/>
135149
Otherwise you have to navigate to the parallel `libraries` folder and select the library you want to access.<br/>
136-
In both cases the library files itself are located in the `src` directory.<br/>
150+
In both cases the library source and include files are located in the libraries `src` directory.<br/>
151+
The modification must be renewed for each new library version!
137152

138153
### Modifying compile options with Sloeber IDE
139-
If you are using Sloeber as your IDE, you can easily define global symbols with *Properties > Arduino > CompileOptions*.<br/>
154+
If you are using [Sloeber](https://eclipse.baeyens.it) as your IDE, you can easily define global symbols with *Properties > Arduino > CompileOptions*.<br/>
140155
![Sloeber settings](https://github.com/ArminJo/ServoEasing/blob/master/pictures/SloeberDefineSymbols.png)
141156

142157
# Revision History

examples/50Hz/50Hz.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* GNU General Public License for more details.
1212
1313
* You should have received a copy of the GNU General Public License
14-
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
14+
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
1515
*
1616
*/
1717

@@ -28,7 +28,7 @@ void setup() {
2828
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
2929
initTXPin();
3030

31-
# ifdef INFO
31+
# if defined(INFO)
3232
writeString(F("START " __FILE__ "\nVersion " VERSION " from " __DATE__ "\n"));
3333
# endif
3434

examples/ADCSwitchingTest/ADCSwitchingTest.ino

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919
* GNU General Public License for more details.
2020
*
2121
* You should have received a copy of the GNU General Public License
22-
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
22+
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
2323
*
2424
*/
2525

2626
#include <Arduino.h>
2727

28-
#include "ADCUtils.h"
28+
#include "ADCUtils.hpp"
2929

3030
#define VERSION_EXAMPLE "1.0"
3131

@@ -53,7 +53,7 @@ void setup() {
5353
pinMode(LED_BUILTIN, OUTPUT);
5454

5555
Serial.begin(115200);
56-
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_USB) || defined(SERIAL_PORT_USBVIRTUAL) || defined(ARDUINO_attiny3217)
56+
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217)
5757
delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!
5858
#endif
5959

0 commit comments

Comments
 (0)