-
Notifications
You must be signed in to change notification settings - Fork 9
/
FerrarisSensor.cpp
157 lines (149 loc) · 4.36 KB
/
FerrarisSensor.cpp
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "FerrarisSensor.h"
FerrarisSensor::FerrarisSensor(byte p1, byte p2, int p, int sid, int f) :
BaseSensor(p,sid,f)
{
pin1 = p1;
pin2 = p2;
Type = 24; // this sensor always logs to the consumption value
// and the generation is added to create total consumption
}
void FerrarisSensor::Begin(byte i)
{
BaseSensor::Begin(i);
threshold1L = 314; // actual switching threshold
threshold1H = 393; // will be adjusted every 10000 samples
threshold2L = 203;
threshold2H = 256;
input1 = false;
input2 = false;
// variables for auto adjusting thresholds
thresholdSampleCounter = 0;
low1 = 5000;
low2 = 5000;
sum1 = 0;
sum2 = 0;
state = 1; // 1=on/on 2=off/on 2=off/off 4=on/off
sensorValue1 = 0;
sensorValue2 = 0;
readCounter = 0;
}
void FerrarisSensor::CheckSensor()
{
// measure the analog inputs 6 times to eliminate noise
sensorValue1 += analogRead(pin1);
sensorValue2 += analogRead(pin2);
readCounter++;
if(readCounter == 6)
{
last1 = sensorValue1;
last2 = sensorValue2;
// determine the digital state
if(sensorValue1 > threshold1H) input1 = true;
if(sensorValue1 < threshold1L) input1 = false;
if(sensorValue2 > threshold2H) input2 = true;
if(sensorValue2 < threshold2L) input2 = false;
// keep track of the range
if(low1 > sensorValue1) low1 = sensorValue1;
if(low2 > sensorValue2) low2 = sensorValue2;
sum1 += sensorValue1;
sum2 += sensorValue2;
thresholdSampleCounter++;
// depending on the level of the inputs go to the next state
switch(state)
{
case 1:
if(!input1 && input2)
{
// passed the sensors in positive direction
todayCnt++;
if(forward) pulseLength = millis() - lastMillis;
else pulseLength = 0;
lastMillis = millis();
forward = true;
// goto next state
state = 2;
}
if(input1 && !input2)
{
state = 4;
}
break;
case 2:
if(!input1 && !input2)
{
state = 3;
}
if(input1 && input2)
{
// passed the sensors in negative direction
todayCnt--;
if(forward) pulseLength = 0;
else pulseLength = lastMillis - millis(); // negative!
lastMillis = millis();
forward = false;
state = 1;
}
break;
case 3:
if(input1 && !input2)
{
state = 4;
}
if(!input1 && input2)
{
state = 2;
}
break;
case 4:
if(input1 && input2)
{
state = 1;
}
if(!input1 && !input2)
{
state = 3;
}
break;
}
// ready for the next sample
sensorValue1 = 0;
sensorValue2 = 0;
readCounter = 0;
}
}
void FerrarisSensor::CalculateActuals()
{
BaseSensor::CalculateActuals();
if(thresholdSampleCounter > 10000)
{
// if the detected range is large enough we have seen bright and dark pulses
// then setup the thresholds on 25% and 75% of the range
// left sensor
int range = (sum1 / thresholdSampleCounter) - low1;
if(range>100)
{
threshold1L = low1 + range/4;
threshold1H = low1 + range/2;
}
// same for right sensor
range = (sum2 / thresholdSampleCounter) - low2;
if(range>100)
{
threshold2L = low2 + range/4;
threshold2H = low2 + range/2;
}
// start measuring new range
low1 = 7000;
low2 = 7000;
sum1 = 0;
sum2 = 0;
thresholdSampleCounter = 0;
}
}
void FerrarisSensor::Status(Print& client)
{
BaseSensor::Status(client);
client << F("<td>C=") << thresholdSampleCounter;
client << F(" 1=") << threshold1L << "-" << threshold1H << ":" << last1;
client << F(" 2=") << threshold2L << "-" << threshold2H << ":" << last2;
}