forked from tinkerspy/Automaton
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAtm_comparator.cpp
More file actions
executable file
·121 lines (110 loc) · 2.89 KB
/
Atm_comparator.cpp
File metadata and controls
executable file
·121 lines (110 loc) · 2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <Automaton.h>
#include "Atm_comparator.h"
Atm_comparator & Atm_comparator::begin( int attached_pin, int samplerate, triggercb_t cb )
{
const static state_t state_table[] PROGMEM = {
/* ON_ENTER ON_LOOP ON_EXIT EVT_TRIGGER EVT_TIMER ELSE */
/* IDLE */ -1, -1, -1, -1, SAMPLE, -1,
/* SAMPLE */ ACT_SAMPLE, -1, -1, SEND, -1, IDLE,
/* SEND */ ACT_SEND, -1, -1, -1, -1, IDLE,
};
Machine::begin( state_table, ELSE );
pin = attached_pin;
timer.begin( this, samplerate );
bitmap_sample = 0;
bitmap_previous = 0;
callback = cb;
return *this;
}
int Atm_comparator::read_sample()
{
return analogRead( pin );
}
int Atm_comparator::_avg()
{
uint16_t v = read_sample();
avg_buf_total = avg_buf_total + v - avg_buf[avg_buf_head];
avg_buf[avg_buf_head] = v;
if ( avg_buf_head + 1 >= avg_buf_size ) {
avg_buf_head = 0;
} else {
avg_buf_head++;
}
return avg_buf_total / avg_buf_size;
}
int Atm_comparator::sample()
{
return avg_buf_size > 0 ? _avg() : read_sample();
}
Atm_comparator & Atm_comparator::threshold( uint16_t * v, uint16_t size, bool catchUp )
{
p_threshold = v;
p_threshold_size = size;
if ( catchUp == false ){
v_sample = sample();
bitmap( v_sample );
v_previous = v_sample;
bitmap_previous = bitmap_sample;
}
return *this;
}
Atm_comparator & Atm_comparator::average( uint16_t * v, uint16_t size )
{
avg_buf = v;
avg_buf_size = size;
avg_buf_head = 0;
avg_buf_total = 0;
for ( uint16_t i = 0; i < avg_buf_size; i++ ) {
avg_buf[i] = read_sample();
avg_buf_total += avg_buf[i];
}
return *this;
}
Atm_comparator & Atm_comparator::bitmap( int v )
{
bitmap_sample = 0;
for ( int i = 0; i < p_threshold_size; i++ ) {
if ( v >= p_threshold[i] ) bitmap_sample |= ( 1 << i );
}
bitmap_diff = bitmap_sample ^ bitmap_previous;
return *this;
}
int Atm_comparator::event( int id )
{
switch ( id ) {
case EVT_TRIGGER :
if ( bitmap_diff ) {
return 1;
}
return 0;
case EVT_TIMER :
return timer.expired();
}
return 0;
}
void Atm_comparator::action( int id )
{
switch ( id ) {
case ACT_SAMPLE :
v_previous = v_sample;
bitmap_previous = bitmap_sample;
v_sample = sample();
bitmap( v_sample );
return;
case ACT_SEND :
if ( v_sample >= v_previous ) {
for ( int i = 0; i < p_threshold_size; i++ ) {
if ( (bitmap_diff >> i ) & 1 ) {
(*callback)( v_sample, 1, i, p_threshold[i] );
}
}
} else {
for ( int i = p_threshold_size; i >= 0; i-- ) {
if ( (bitmap_diff >> i ) & 1 ) {
(*callback)( v_sample, 0, i, p_threshold[i] );
}
}
}
return;
}
}