7
7
Licensed under GPLv3
8
8
======================
9
9
*/
10
+ /*
11
+ The BWF sensor works by measuring the time between rising edges
12
+
13
+ Example:
14
+ Signal in BWF
15
+
16
+ I
17
+ ^
18
+ | _ _
19
+ | | | | |
20
+ | | | | |
21
+ |...__| | _____| | ___...
22
+ | | | | |
23
+ | | | | |
24
+ | |_| |_|
25
+ |
26
+ +----------------------> t
27
+ 1 1 5 1 1 5...
28
+
29
+ Outside of the fence, the sensor coil and amplifier circuit will sense the
30
+ rising edges in the signal. Inside the fence, the signal is inverted, and
31
+ the circuit will sense the falling edges of the signal instead.
32
+
33
+ In this example, the time between rising edges is 2 units, followed by 5,
34
+ 2, 5, and so on. The time between falling edges is 7 units.
35
+
36
+ When a rising edge is detected on the currently selected sensor, the function
37
+ readSensor() is run. By keeping track of the last time it was run, it can
38
+ calculate the time between pulses and check if it matches what was expected
39
+ for being inside or outside of the fence.
40
+ */
10
41
11
42
#include " BWFSensor.h"
12
43
13
- int BWFSENSOR::outside_code[] = {OUTSIDE_BWF};
44
+ int BWFSENSOR::outside_code[] = {OUTSIDE_BWF, INSIDE_BWF-OUTSIDE_BWF };
14
45
int BWFSENSOR::inside_code[] = {INSIDE_BWF};
15
46
16
- /* * Specific constructor.
17
- */
47
+ int currentSensor = 0 ;
48
+
18
49
BWFSENSOR::BWFSENSOR (int selA, int selB) {
19
50
selpin_A = selA;
20
51
selpin_B = selB;
21
52
}
22
53
23
54
24
- // select this sensor to be active
55
+ // Select active sensor
25
56
void BWFSENSOR::select (int sensornumber) {
57
+ if (currentSensor == sensornumber) {
58
+
59
+ return ;
60
+ }
61
+ currentSensor = sensornumber;
62
+
26
63
digitalWrite (selpin_A, (sensornumber & 1 ) > 0 ? HIGH : LOW);
27
64
digitalWrite (selpin_B, (sensornumber & 2 ) > 0 ? HIGH : LOW);
28
65
clearSignal ();
29
- delay (200 ); // Wait a little to collect signal
66
+ long time = millis ();
67
+ while (signal_status == NOSIGNAL
68
+ && millis () - time < BWF_COLLECT_SIGNAL_TIME) // max time of 200ms
69
+ {
70
+ delay (1 );
71
+ }
72
+
73
+ // delay(200);
30
74
}
31
75
32
76
33
77
void BWFSENSOR::clearSignal () {
34
- for (int i= 0 ; i< arr_length; i++)
35
- arr[i]= 0 ;
78
+ for (int i = 0 ; i < arr_length; i++)
79
+ arr[i] = 0 ;
36
80
signal_status = NOSIGNAL;
37
81
pulse_count_inside = 0 ;
38
82
pulse_count_outside = 0 ;
@@ -48,60 +92,73 @@ bool BWFSENSOR::isOutside() {
48
92
return (signal_status == OUTSIDE);
49
93
}
50
94
95
+ bool BWFSENSOR::isOutOfBounds () {
96
+ if (BWF_DETECTION_ALWAYS)
97
+ return !isInside ();
98
+ else
99
+ return isOutside ();
100
+ }
101
+
51
102
bool BWFSENSOR::isTimedOut () {
52
- return (signal_status_checked + TIMEOUT_DELAY < millis ());
103
+ return (last_match + TIMEOUT_DELAY < millis ());
53
104
}
54
105
55
106
bool BWFSENSOR::hasNoSignal () {
56
- return (signal_status_checked + NO_SIGNAL_DELAY < millis ());
107
+ return (last_match + NO_SIGNAL_DELAY < millis ());
57
108
}
58
109
59
- // This routine is run at every timer interrupt and updates the sensor status
110
+
111
+ // This function is run each time the BWF pin gets a pulse
112
+ // For accuracy, this function should be kept as fast as possible
60
113
void BWFSENSOR::readSensor () {
61
- volatile int pulse_unit = 0 ;
114
+ long now = micros () ;
62
115
63
116
// Calculate the time since last pulse
64
- pulse_length = int (micros () - pulse_time);
65
- pulse_time = micros ();
66
- pulse_unit = (pulse_length+half_unit_length) / pulse_unit_length;
117
+ int time_since_pulse = int (now - last_pulse);
118
+ last_pulse = now;
67
119
68
-
69
- // Store the numbers for debug printout
70
- arr[arr_count++] = pulse_unit;
71
- if (arr_count>arr_length) arr_count=0 ;
120
+ // Convert to pulse units (rounding up)
121
+ int pulse_length = (time_since_pulse+(pulse_unit_length/2 )) / pulse_unit_length;
72
122
73
123
// Check if the latest pulse fits the code for inside
74
- if (abs (pulse_unit -inside_code[pulse_count_inside]) < 2 ) {
124
+ if (abs (pulse_length -inside_code[pulse_count_inside]) < 2 ) {
75
125
pulse_count_inside++;
76
- // If the whole code sequence has been OK, then set signal status to 1
126
+
127
+ // Check if the entire pulse train has been batched
77
128
if (pulse_count_inside >= sizeof (inside_code)/sizeof (inside_code[0 ])) {
78
129
signal_status = INSIDE;
79
- signal_status_checked = millis ();
130
+ last_match = millis ();
80
131
pulse_count_inside=0 ;
81
132
}
82
- }
83
- else
133
+ } else {
84
134
pulse_count_inside=0 ;
135
+ }
85
136
86
137
// Check if the latest pulse fits the code for outside
87
- if (abs (pulse_unit -outside_code[pulse_count_outside]) < 2 ) {
138
+ if (abs (pulse_length -outside_code[pulse_count_outside]) < 2 ) {
88
139
pulse_count_outside++;
89
140
if (pulse_count_outside >= sizeof (outside_code)/sizeof (outside_code[0 ])) {
90
141
signal_status = OUTSIDE;
91
- signal_status_checked = millis ();
142
+ last_match = millis ();
92
143
pulse_count_outside=0 ;
93
144
}
94
- }
95
- else
145
+ } else {
96
146
pulse_count_outside=0 ;
147
+ }
148
+
97
149
150
+ // Store the received code for debug output
151
+ arr[arr_count++] = pulse_length;
152
+ if (arr_count>arr_length) arr_count=0 ;
98
153
}
99
154
100
155
void BWFSENSOR::printSignal () {
101
-
102
- for (int i=0 ; i<arr_length; i++) {
156
+ for (int i = 0 ; i < arr_length; i++) {
103
157
Serial.print (arr[i]);
104
158
Serial.print (" " );
105
159
}
106
-
107
160
}
161
+ bool BWFSENSOR::gotSignal ()
162
+ {
163
+ return arr_count >= BWF_NUMBER_OF_PULSES ? true : false ;
164
+ }
0 commit comments