Skip to content

Commit ad28370

Browse files
committed
Merge branch 'develop' for 5.3-RC1
2 parents 6a506d4 + 3b0c410 commit ad28370

25 files changed

+975
-726
lines changed

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
1+
Liam/LocalDefinition.h
12
.DS_Store
23
.vscode
4+
*/.vs/
5+
*/__vm/
6+
*/Debug/
7+
*.sln
8+
*.vcxproj*
9+
*.orig
10+
*/Release/*

Liam/BWFSensor.cpp

+87-30
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,76 @@
77
Licensed under GPLv3
88
======================
99
*/
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+
*/
1041

1142
#include "BWFSensor.h"
1243

13-
int BWFSENSOR::outside_code[] = {OUTSIDE_BWF};
44+
int BWFSENSOR::outside_code[] = {OUTSIDE_BWF, INSIDE_BWF-OUTSIDE_BWF};
1445
int BWFSENSOR::inside_code[] = {INSIDE_BWF};
1546

16-
/** Specific constructor.
17-
*/
47+
int currentSensor = 0;
48+
1849
BWFSENSOR::BWFSENSOR(int selA, int selB) {
1950
selpin_A = selA;
2051
selpin_B = selB;
2152
}
2253

2354

24-
// select this sensor to be active
55+
// Select active sensor
2556
void BWFSENSOR::select(int sensornumber) {
57+
if (currentSensor == sensornumber) {
58+
59+
return;
60+
}
61+
currentSensor = sensornumber;
62+
2663
digitalWrite(selpin_A, (sensornumber & 1) > 0 ? HIGH : LOW);
2764
digitalWrite(selpin_B, (sensornumber & 2) > 0 ? HIGH : LOW);
2865
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);
3074
}
3175

3276

3377
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;
3680
signal_status = NOSIGNAL;
3781
pulse_count_inside = 0;
3882
pulse_count_outside = 0;
@@ -48,60 +92,73 @@ bool BWFSENSOR::isOutside() {
4892
return (signal_status == OUTSIDE);
4993
}
5094

95+
bool BWFSENSOR::isOutOfBounds() {
96+
if (BWF_DETECTION_ALWAYS)
97+
return !isInside();
98+
else
99+
return isOutside();
100+
}
101+
51102
bool BWFSENSOR::isTimedOut() {
52-
return (signal_status_checked + TIMEOUT_DELAY < millis());
103+
return (last_match + TIMEOUT_DELAY < millis());
53104
}
54105

55106
bool BWFSENSOR::hasNoSignal() {
56-
return (signal_status_checked + NO_SIGNAL_DELAY < millis());
107+
return (last_match + NO_SIGNAL_DELAY < millis());
57108
}
58109

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
60113
void BWFSENSOR::readSensor() {
61-
volatile int pulse_unit = 0;
114+
long now = micros();
62115

63116
// 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;
67119

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;
72122

73123
// 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) {
75125
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
77128
if (pulse_count_inside >= sizeof(inside_code)/sizeof(inside_code[0])) {
78129
signal_status = INSIDE;
79-
signal_status_checked = millis();
130+
last_match = millis();
80131
pulse_count_inside=0;
81132
}
82-
}
83-
else
133+
} else {
84134
pulse_count_inside=0;
135+
}
85136

86137
// 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) {
88139
pulse_count_outside++;
89140
if (pulse_count_outside >= sizeof(outside_code)/sizeof(outside_code[0])) {
90141
signal_status = OUTSIDE;
91-
signal_status_checked = millis();
142+
last_match = millis();
92143
pulse_count_outside=0;
93144
}
94-
}
95-
else
145+
} else {
96146
pulse_count_outside=0;
147+
}
148+
97149

150+
// Store the received code for debug output
151+
arr[arr_count++] = pulse_length;
152+
if (arr_count>arr_length) arr_count=0;
98153
}
99154

100155
void BWFSENSOR::printSignal() {
101-
102-
for (int i=0; i<arr_length; i++) {
156+
for (int i = 0; i < arr_length; i++) {
103157
Serial.print(arr[i]);
104158
Serial.print(" ");
105159
}
106-
107160
}
161+
bool BWFSENSOR::gotSignal()
162+
{
163+
return arr_count >= BWF_NUMBER_OF_PULSES ? true : false;
164+
}

Liam/BWFSensor.h

+20-19
Original file line numberDiff line numberDiff line change
@@ -19,48 +19,49 @@
1919
#define OUTSIDE -1
2020

2121
// BWF Code for timout and no signal (in milliseconds)
22-
#define TIMEOUT_DELAY 20000
23-
#define NO_SIGNAL_DELAY 4000
22+
#define TIMEOUT_DELAY 20000
23+
#define NO_SIGNAL_DELAY 4000
24+
2425

2526
class BWFSENSOR {
2627
public:
2728
BWFSENSOR(int selA, int selB);
2829

2930
void select(int sensornumber);
31+
void clearSignal();
3032

31-
void attach(int intpin);
32-
void readSensor();
33-
34-
bool isTimedOut();
3533
bool isInside();
3634
bool isOutside();
35+
bool isTimedOut();
36+
bool isOutOfBounds();
3737
bool hasNoSignal();
38+
bool gotSignal();
3839

39-
void printSignal();
40-
void clearSignal();
40+
void readSensor();
4141

42+
void printSignal();
4243

4344
private:
4445
// BWF Code for inside and outside the fence
4546
static int inside_code[];
4647
static int outside_code[];
48+
49+
const static int pulse_unit_length = 100;
50+
51+
int pulse_count_inside;
52+
int pulse_count_outside;
53+
4754
int selpin_A;
4855
int selpin_B;
49-
int counter;
56+
5057
int signal_status;
51-
long last_interrupt;
52-
long signal_status_checked;
53-
long pulse_length;
54-
long pulse_time;
55-
int pulse_count_inside;
56-
int pulse_count_outside;
57-
int sensor_number;
58-
const static int pulse_unit_length = 100;
59-
const static int half_unit_length = 50;
58+
long last_match;
59+
long last_pulse;
60+
61+
// Array for debug printing
6062
const static int arr_length=10;
6163
int arr[arr_length];
6264
int arr_count;
63-
6465
};
6566

6667
#endif /* _BWFSENSOR_H_ */

Liam/Battery.cpp

+43-30
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@
99
*/
1010

1111
#include "Battery.h"
12+
#include "Definition.h"
1213

13-
/** Specific constructor.
14-
*/
15-
BATTERY::BATTERY(int type, int socpin, int dockpin) {
14+
BATTERY::BATTERY(int type, int sensepin, int dockpin) {
1615
batType = type;
17-
batSocpin = socpin;
18-
batDockpin = dockpin;
16+
batSensePin = sensepin;
17+
batDockPin = dockpin;
18+
19+
// Battery types are defined in Definition.h
20+
// LIION
21+
// NIMH
22+
// LEAD_ACID
1923

2024
if (batType == LIION) {
2125
fullyChargedLevel = LIIONFULL;
@@ -35,22 +39,22 @@ BATTERY::BATTERY(int type, int socpin, int dockpin) {
3539
}
3640

3741

38-
// set the level when battery is concidered fully charged
39-
void BATTERY::setFullyChargedLevel(int level) {
40-
fullyChargedLevel = level;
41-
}
42-
4342
int BATTERY::getBatteryType() {
4443
return batType;
4544
}
4645

4746

47+
// Set the voltage at which battery is considered fully charged (mV)
48+
void BATTERY::setFullyChargedLevel(int level) {
49+
fullyChargedLevel = level;
50+
}
51+
4852
int BATTERY::getFullyChargedLevel() {
4953
return fullyChargedLevel;
5054
}
5155

5256

53-
// set the level when battery is concidered depleted
57+
// Set the voltage at which battery is considered depleted (mV)
5458
void BATTERY::setDepletedLevel(int level) {
5559
depletedLevel = level;
5660
}
@@ -59,36 +63,45 @@ int BATTERY::getDepletedLevel() {
5963
return depletedLevel;
6064
}
6165

62-
int BATTERY::getSOC() {
63-
return averageSOC;
66+
67+
bool BATTERY::mustCharge() {
68+
return (averageVoltage < depletedLevel);
6469
}
6570

66-
void BATTERY::resetSOC() {
67-
averageSOC = readBatteryAndCalcValue();
71+
bool BATTERY::isBeingCharged() {
72+
return digitalRead(batDockPin);
6873
}
6974

70-
bool BATTERY::mustCharge() {
71-
return (averageSOC < depletedLevel);
75+
bool BATTERY::isFullyCharged() {
76+
return (readBatteryAndCalcValue() > fullyChargedLevel);
7277
}
7378

7479

75-
void BATTERY::updateSOC() {
76-
averageSOC = averageSOC - (averageSOC / FILTER) + (readBatteryAndCalcValue() / FILTER);
80+
// Get battery voltage in mV (filtered through running average)
81+
int BATTERY::getVoltage() {
82+
return averageVoltage;
7783
}
7884

79-
80-
word BATTERY::readBatteryAndCalcValue(){
81-
unsigned long newReading = analogRead(batSocpin);
82-
newReading = newReading * 488 * VOLTDIVATOR;
83-
newReading /= 10000;
84-
//return newReading;
85-
return word(newReading);
85+
void BATTERY::resetVoltage() {
86+
averageVoltage = readBatteryAndCalcValue();
8687
}
8788

88-
bool BATTERY::isBeingCharged() {
89-
return digitalRead(batDockpin);
89+
// Take a battery reading and recalculate running average
90+
void BATTERY::updateVoltage() {
91+
averageVoltage -= averageVoltage / FILTER;
92+
averageVoltage += readBatteryAndCalcValue() / FILTER;
9093
}
9194

92-
bool BATTERY::isFullyCharged() {
93-
return (readBatteryAndCalcValue() > fullyChargedLevel);
95+
// Measure battery voltage in mV
96+
word BATTERY::readBatteryAndCalcValue(){
97+
unsigned long reading = analogRead(batSensePin);
98+
99+
// Convert from ADC units to uV
100+
reading = reading * 4880;
101+
// Adjust for voltage divider circuit
102+
reading = (reading * VOLTDIVATOR) / 10;
103+
// Convert to mV
104+
reading = reading / 1000;
105+
106+
return word(reading);
94107
}

0 commit comments

Comments
 (0)