-
Notifications
You must be signed in to change notification settings - Fork 1
/
cardiograph.ino
138 lines (133 loc) · 4.49 KB
/
cardiograph.ino
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
#include <SoftwareSerial.h>
const int PIN_INPUT_1 = A0;
const byte MESSAGE_PULSE = 0x00;
const byte MESSAGE_1 = 0x01;
int FRAME_RATE = 60;
int BYTES_PER_FRAME = 3;
int AVERAGE_TOLERANCE = 20;
int MAX_TOLERANCE = 10;
int pCalibrationDuration = 10 * 1000;
bool pCalibrating = false;
bool pNeedCalibration = false;
unsigned long pCalibrationTimeStart = 0;
unsigned long pMaxValueTime = 0;
int pMaxValue = 0;
int pAverageValue = 0;
int pCalibrationAverageAmount = 0;
int pCalibrationAverageCount = 0;
boolean pAverageCrossed = false;
int pLastValues[6] = {-1, -1, -1, -1, -1, -1};
void setup(){
analogReference(DEFAULT);
Serial.begin(38400);
while(!Serial){}
}
void loop(){
while (Serial.available() > 0) {
int incoming = Serial.read();
bool sync = false;
if (byte(incoming) == 0xff) { // we got handshake request. We have to sync with 3 bytes of 0xff and continue broadcast data
int counter = 0;
sync = true;
while (sync) {
while (Serial.available() > 0) { // now we going to sync
int incoming = Serial.read();
switch (counter++) {
case 0:
FRAME_RATE = incoming;
break;
case 1:
BYTES_PER_FRAME = incoming;
break;
case 2:
AVERAGE_TOLERANCE = incoming;
break;
case 3:
MAX_TOLERANCE = incoming;
sync = false;
break;
}
}
}
Serial.flush();
delay(500);
for (int i = 0; i < BYTES_PER_FRAME + 1; i++) {
Serial.write(byte(0xee));
}
Serial.flush();
pNeedCalibration = true;
} else if (byte(incoming) == 0xee) { // pulse calibrate signal
pNeedCalibration = true;
}
}
unsigned long timeStart = millis();
int data1 = int(analogRead(PIN_INPUT_1)) - 511;
send(MESSAGE_1, data1);
analysePulse(data1);
Serial.flush();
unsigned long delayTime = 1000/FRAME_RATE - (millis() - timeStart);
if (delayTime > 0) delay(delayTime);
}
void analysePulse(int value){
if (pNeedCalibration) {
if (!pCalibrating) {
pCalibrating = true;
pCalibrationTimeStart = millis();
pMaxValue = 0;
pAverageValue = 0;
pCalibrationAverageAmount = 0;
pCalibrationAverageCount = 0;
send(MESSAGE_PULSE, -2);
}
pNeedCalibration = false;
}
if (pCalibrating) {
if (value > pMaxValue) pMaxValue = value;
pCalibrationAverageAmount += value;
pCalibrationAverageCount++;
if (millis() > pCalibrationTimeStart + pCalibrationDuration) { // calibration finished
pCalibrating = false;
pAverageValue = int(pCalibrationAverageAmount / pCalibrationAverageCount);
pMaxValueTime = 0;
pAverageCrossed = false;
for (int i = 0; i < 6; i++) {
pLastValues[i] = -1;
}
send(MESSAGE_PULSE, -1);
}
} else {
if (!pAverageCrossed && abs(pAverageValue - value) < AVERAGE_TOLERANCE) {
pAverageCrossed = true;
} else if (pAverageCrossed && abs(pMaxValue - value) < MAX_TOLERANCE) {
pAverageCrossed = false;
if (pMaxValueTime == 0) {
pMaxValueTime = millis();
} else {
for (int i = 4; i >= 0; i--) {
pLastValues[i + 1] = pLastValues[i];
}
pLastValues[0] = int(float(60000) / float(millis() - pMaxValueTime));
int pValue = 0;
int counter = 0;
for (int i = 0; i < 6; i++) {
if (pLastValues[i] >= 0) {
pValue += pLastValues[i];
counter++;
}
}
if (counter > 0) {
pValue /= counter;
} else {
pValue = -1;
}
send(MESSAGE_PULSE, pValue);
pMaxValueTime = millis();
}
}
}
}
void send(byte flag, int data){
Serial.write(flag);
Serial.write(byte(data));
Serial.write(byte(data >> 8));
}