Skip to content

Commit e2ec9a7

Browse files
committed
ADCUtils non AVR compatibility. Improved EMA filter example.
1 parent bad4252 commit e2ec9a7

20 files changed

+549
-195
lines changed

README.md

+52-21
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Not yet available as Arduino library.
2626

2727
</div>
2828

29+
#### If you find this library useful, please give it a star.
30+
2931
<br/>
3032

3133
# Table of content
@@ -79,40 +81,62 @@ Using the [more exact formula](https://github.com/MakeMagazinDE/DigitaleFilter/b
7981
The **maximum output value for integer filters** is: InputValue - ((1 << (ShiftValue -1)) -1), i.e **85 for InputValue 100 and ShiftValue 5** (Lowpass5).
8082

8183
### The [SimpleEMAFilters.hpp](https://github.com/ArminJo/Arduino-Utils/blob/master/src/SimpleEMAFilters.hpp#L66) contains:
82-
- A fixed set of 6 **ultrafast** EMA (Exponential Moving Average) filters which require only **1 to 2 microseconds**.
83-
- 3 derived filters (highpass and 2 bandpasses) by just subtracting one lowpass from input (highpass) or from another lowpass (bandpass).
84+
- A set of **ultrafast** EMA (Exponential Moving Average) filters which require only **1 to 2 microseconds**.
85+
- 3 highpass and bandpass filters, generated by just subtracting one lowpass from input (highpass) or from another lowpass (bandpass).
86+
- 16 and 32 bit Biquad filters.
8487
- Display routines for Arduino Plotter.
8588

8689
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.
8790

88-
### Plotter outputs representing e.g. a 40, 20, 10, 5 Hz square / sine wave at a sample rate of 1 ms (or 80, 40 ... Hz at 0.5 ms and so on)
91+
### Plotter outputs representing e.g. a 42, 21, 10.5, 5.2 Hz square / sine wave at a sample rate of 1 ms (or 84, 42 ... Hz at a sample rate of 0.5 ms and so on)
92+
93+
Arduino Plotter output for a rectangle input signal with a amplitude of +/- 100. E.g. LowP3 is the Lowpass with alpha 1/8 implemented by `>> 3` and the cutoff frequency of 21 Hz.
94+
![ArduinoPlotter output SignificantFilters](pictures/SignificantFilters.png)
8995

90-
![ArduinoPlotter output](pictures/LowPass_HighInput.png)
91-
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` and the cutoff frequency of 21 Hz.
92-
<br/><br/>
9396
Note the following facts:
9497
- Highpass is always Input - Lowpass.
95-
- The Bandpass1_3 has an overshoot.
96-
- The 2 Lowpass3 and the 2 Lowpass5 lines are overlapping each other for this (high) amplitude.
98+
- Therefore highpass -here HighP3_16- can have an overshoot of 100%.
9799
- The output of DoubleLowpass3 and 4 is more and more resembling a delayed sine.
98-
- The output of Lowpass5 and DoubleLowpass4 have almost the same amplitude but DoubleLowpass4 is way more resembling a (delayed) sine.
99-
- The output of TripleLowpass3 has a higher amplitude than DoubleLowpass4 with both looking quite like a (delayed) sine.
100+
- The output of LowP5_32 and DoubleLowP4_16 have almost the same amplitude but DoubleLowP4_16 is way more resembling a (delayed) sine.
101+
- The output of TripleLowP3_16 has a higher amplitude than DoubleLowP4_16 with both looking quite like a (delayed) sine.
100102

101103
<br/>
102104

103-
![ArduinoPlotter output](pictures/LowPass_LowInput.png)
104-
Arduino Plotter output for a rectangle input signal with very low amplitude of +/- 20 where you see clipping effects due to the limited resolution of the used 16 bit math.<br/>
105+
Arduino Plotter output for a rectangle input signal with very low amplitude of +/- 20 where you see clipping effects due to the limited resolution of the used 16 bit math.
106+
![ArduinoPlotter output LowPass_LowInput](pictures/LowPass_LowInput.png)
105107
The Lowpass3_int32 and Lowpass5_int32 are 32 bit fixed point implementations for higher resolution which requires **4.2 &micro;s instead of the 1.8 / 2.5 &micro;s of 16 bit**.
106-
<br/><br/>
108+
<br/>
107109

108-
![ArduinoPlotter output](pictures/LowPass_SineInput.png)
109-
Arduino Plotter output for a sine input signal with a amplitude of +/- 100.<br/>
110-
Note the **-3db attenuation for the Lowpass3** value which represent a filter of 22.7 Hz in this example.
110+
Arduino Plotter output for a sine input signal with a amplitude of +/- 100.
111+
![ArduinoPlotter output for LowPass with sine input](pictures/SignificantFilters_Sine.png)
112+
Note the **different attenuations** at different frequencies.
111113
<br/><br/>
112114

113-
![ArduinoPlotter output](pictures/LowPass_TriangleInput.png)
114-
Arduino Plotter output for a triangle input signal with a amplitude of +/- 100.<br/>
115-
Note that Lowpass5 is almost a perfect sine.
115+
Arduino Plotter output for a triangle input signal with a amplitude of +/- 100.
116+
![ArduinoPlotter output triangle input](pictures/SignificantFilters_Triangle.png)
117+
Note that higher order filters and low pass with high shifts are almost a perfect sine.
118+
119+
Arduino Plotter output for a sawtooth input signal with a amplitude of +/- 100.
120+
![ArduinoPlotter output for sawtooth input](pictures/SignificantFilters_Sawtooth.png)
121+
122+
Arduino Plotter output for a random input signal with a amplitude of +/- 100.
123+
![ArduinoPlotter output for lowpass on random input](pictures/LowPass1_3_5_8_Random.png)
124+
125+
<br/>
126+
127+
### Arduino Plotter output for a rectangle input signal with 4 different frequencies 42 Hz > 21 Hz > 10.5 Hz > 5.2 Hz
128+
Click on the pictures to enlarge them.
129+
130+
| All lowpass filters. | Highpass filters.<br/>Generated by subtracting lowpass from input. |
131+
| :-: | :-: |
132+
| ![AllLowPass](pictures/AllLowPass.png) | ![HighPassFilters](pictures/HighPassFilters.png) |
133+
| Bandpass and reject filters.<br/>Bandpass is generated by subtracting one lowpass from onother with different shift value.<br/>Reject filter is input minus bandpass.| High order Lowpass. |
134+
| ![BandPassAndReject](pictures/BandPassAndReject.png) | ![HighOrderLowPass](pictures/HighOrderLowPass.png) |
135+
| LowPass1, 3, 5 and 8.<br/>Lowpass8 behave like a integrator here, resulting in a triangle output. | LowPass3, 5 and 8.<br/>Comparison of different implementations with 16 bit integer, 32 bit integer and 32 bit float. |
136+
| ![LowPass1_3_5_8](pictures/LowPass1_3_5_8.png) | ![LowPass16And32Bit](pictures/LowPass16And32Bit.png) |
137+
| BiQuad filters with damping factor = 0.<br/>You see the overshoot. | |
138+
| ![BiQuadFilters](pictures/BiQuadFilters.png) | |
139+
116140

117141
The floating point implementation of the 1/32 EMA filter takes **24 to 34 &micro;s**.<br/>
118142
There are convenience functions implemented for EMA filter, but normally it is better to implement it inline by e.g.
@@ -190,6 +214,15 @@ First voltage is measured. If voltage is zero, then the unknown resistance to gr
190214
- Sleep and sleep with watchdog functions.
191215
- Available Ram, Heap / Stack memory display.
192216

217+
RAM starts of variables initialized with values != 0, followed by variables initialized with 0 and variables not initialized by using attribute `__attribute__((section(".noinit")))`. It ends with the heap and the stack.
218+
219+
#### Sample output if stack runs into data
220+
```
221+
Size of Data + BSS, Heap start, Stack end=2041
222+
Stack used 20 of 7
223+
Currently available Heap=0
224+
```
225+
193226
# MillisUtils.cpp
194227
Unifies millis() timer handling for Digispark, AttinyCore and Arduino cores.
195228
- Start, stop and modify milliseconds timer and value.
@@ -265,5 +298,3 @@ The library examples are tested with GitHub Actions for the following boards:
265298
- Arduino Leonardo
266299
- Digispark (using ATTiny85 @1MHz)
267300
- Generic ATTiny85 @1MHz
268-
269-
#### If you find this library useful, please give it a star.
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
START ../src/AVRUtilsDemo.cpp
2+
Version 1.0 from Sep 11 2023
3+
sMCUSR=0xD5 BootReasonWasPowerUp=1
4+
sStaticVariable filled by analogRead(A0)=676
5+
sDummyArray[1000]=0x0
6+
DummyArray size=1800
7+
8+
Size of Data + BSS, Heap start, Stack end=2021
9+
Stack used 27 of 27
10+
Currently available Heap=0
11+
Stack unused=0, used=16
12+
13+
0x0880: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
14+
0x0890: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x40 0x02 0x66 0x04 0x40 .@.f.@
15+
0x08A0: 0x02 0x66 0x01 0x3C 0x1B 0x21 0x08 0x38 0x00 0x01 0x00 0x00 0x23 0xA3 0x00 0x02 .f.<...2 . #. .
16+
0x08B0: 0x93 0x08 0xE5 0x08 0xE5 0x08 0xE4 0x01 0xEE 0x08 0xC4 0x08 0xE4 0x08 0xC0 0x08 ................
17+
0x08C0: 0xC0 0x00 0x00 0x03 0x3A 0x04 0x40 0x02 0x66 0x04 0x40 0x02 0x66 0x01 0x3C 0x04 . .:.@.f.@.f.<.
18+
0x08D0: 0x40 0x00 0xD7 0x00 0x01 0x04 0x40 0x08 0xD8 0x00 0x02 0x01 0x07 0x08 0x30 0x00 @ . .@....(*..
19+
0x08E0: 0x02 0x00 0x00 0x23 0x33 0x00 0x08 0xEF 0x08 0xE8 0x00 0x00 0x08 0xE0 0x07 0x15 . #. .........%
20+
0x08F0: 0x00 0x00 0xEB 0x00 0xFB 0x38 0x7B 0x00 0x00 0x03 0x05 0x11 0x01 0x12 0x01 0x12 . .8{ .......
21+
22+
START ../src/AVRUtilsDemo.cpp
23+
Version 1.0 from Sep 11 2023
24+
sMCUSR=0xD5 BootReasonWasPowerUp=1
25+
sStaticVariable filled by analogRead(A0)=679
26+
sDummyArray[1000]=0x0
27+
DummyArray size=1700
28+
29+
Size of Data + BSS, Heap start, Stack end=1921
30+
Stack used 103 of 127
31+
Currently available Heap=0
32+
Stack unused=25, used=102
33+
34+
0x0880: 0x00 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A ZZZZZZZZZZZZZZZ
35+
0x0890: 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x04 0x40 0x02 0x66 0x04 0x40 ZZZZZZZZZZ.@.f.@
36+
0x08A0: 0x02 0x66 0x01 0x3C 0x1F 0x25 0x08 0x38 0x00 0x01 0x00 0x00 0x23 0xA3 0x00 0x02 .f.<...2 . #. .
37+
0x08B0: 0x93 0x08 0xE5 0x08 0xE5 0x08 0xE4 0x01 0xEE 0x08 0xC4 0x08 0xE4 0x08 0xC0 0x08 ................
38+
0x08C0: 0xC0 0x00 0x00 0x03 0x3A 0x04 0x40 0x02 0x66 0x04 0x40 0x02 0x66 0x01 0x3C 0x04 . .:.@.f.@.f.<.
39+
0x08D0: 0x40 0x00 0xD7 0x00 0x01 0x04 0x40 0x08 0xD8 0x00 0x02 0x05 0x0B 0x08 0x30 0x00 @ . .@....,...
40+
0x08E0: 0x02 0x00 0x00 0x23 0x33 0x00 0x08 0xEF 0x08 0xE8 0x00 0x00 0x08 0xE0 0x07 0x15 . #. .........%
41+
0x08F0: 0x00 0x00 0xEB 0x00 0xFB 0x38 0x7B 0x00 0x00 0x03 0x05 0x11 0x01 0x12 0x01 0x12 . .8{ .......
42+
43+
44+
START ../src/AVRUtilsDemo.cpp
45+
Version 1.0 from Sep 11 2023
46+
sMCUSR=0xD5 BootReasonWasPowerUp=1
47+
sStaticVariable filled by analogRead(A0)=671
48+
sDummyArray[1000]=0x0
49+
DummyArray size=1600
50+
51+
Size of Data + BSS, Heap start, Stack end=1821
52+
Stack used 103 of 227
53+
Currently available Heap=82
54+
Stack unused=125, used=102
55+
56+
0x0880: 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A ZZZZZZZZZZZZZZZZ
57+
0x0890: 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x5A 0x04 0x40 0x02 0x66 0x04 0x40 ZZZZZZZZZZ.@.f.@
58+
0x08A0: 0x02 0x66 0x01 0x3C 0x21 0x27 0x08 0x38 0x00 0x01 0x00 0x00 0x23 0xA3 0x00 0x02 .f.<...2 . #. .
59+
0x08B0: 0x96 0x08 0xE5 0x08 0xE5 0x08 0xE4 0x01 0xEE 0x08 0xC4 0x08 0xE4 0x08 0xC0 0x08 ................
60+
0x08C0: 0xC0 0x00 0x00 0x03 0x3A 0x04 0x40 0x02 0x66 0x04 0x40 0x02 0x66 0x01 0x3C 0x04 . .:.@.f.@.f.<.
61+
0x08D0: 0x40 0x00 0xD7 0x00 0x01 0x04 0x40 0x08 0xD8 0x00 0x02 0x07 0x0D 0x08 0x30 0x00 @ . .@.....0..
62+
0x08E0: 0x02 0x00 0x00 0x23 0x33 0x00 0x08 0xEF 0x08 0xE8 0x00 0x00 0x08 0xE0 0x07 0x15 . #. .........%
63+
0x08F0: 0x00 0x00 0xEB 0x00 0x9F 0x00 0x1A 0x00 0x00 0x03 0x05 0x11 0x01 0x12 0x01 0x12 . . . .......
64+

0 commit comments

Comments
 (0)