-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStrobe.ino
144 lines (121 loc) · 2.93 KB
/
Strobe.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
138
139
140
141
142
143
144
#include "state.h"
#include "command.h"
#define CONTROL_PIN 8
unsigned char state;
unsigned long flashingPeriodMs;
unsigned long lastFlashTimeMs;
void setup() {
pinMode(CONTROL_PIN, OUTPUT);
digitalWrite(CONTROL_PIN, LOW);
Serial.begin(9600);
Serial.setTimeout(10);
}
void loop() {
readCommand();
operate();
}
void readCommand() {
if (Serial.available()) {
unsigned char buffer[64];
size_t length = Serial.readBytes(buffer, 64);
parseCommand(buffer, length);
}
}
void parseCommand(unsigned char *data, unsigned short length) {
if (length == 0) {
return;
}
unsigned char command = *data;
switch (command) {
case COMMAND_SINGLE_FLASH:
state = STATE_REQUIRES_SINGLE_FLASH;
return;
case COMMAND_STOP_ALL:
state = STATE_IDLE;
return;
}
unsigned short payloadLength = length - 1;
switch (command) {
case COMMAND_FLASHING_HZ:
parseFlashingHzCommand(data + 1, payloadLength);
break;
case COMMAND_FLASHING_BPM:
parseFlashingBpmCommand(data + 1, payloadLength);
break;
}
}
void parseFlashingHzCommand(unsigned char *payload, unsigned short length) {
if (length != 1) {
return;
}
startFlashingHz(*payload);
}
void parseFlashingBpmCommand(unsigned char *payload, unsigned short length) {
if (length != 2) {
return;
}
unsigned short bpm = *((unsigned short*) payload);
startFlashingBpm(bpm);
}
/**
* Performs action according to the state
*/
void operate() {
switch(state) {
case STATE_REQUIRES_SINGLE_FLASH:
singleFlash();
state = STATE_IDLE;
break;
case STATE_CONTINUOUS_FLASHING:
flashingTick();
break;
}
}
/**
* Sets up continous flashing for given BPM value
*/
void startFlashingBpm(unsigned short bpm) {
flashingPeriodMs = round(1000.0 / (bpm / 60.0));
state = STATE_CONTINUOUS_FLASHING;
}
/**
* Sets up continous flashing for given Hz value
*/
void startFlashingHz(unsigned char hz) {
flashingPeriodMs = round(1000.0 / hz);
state = STATE_CONTINUOUS_FLASHING;
}
/**
* Performs single flash when it's needed
* according to the flashing period
*/
void flashingTick() {
unsigned long currentTimeMs = millis();
unsigned long delta = currentTimeMs - lastFlashTimeMs;
if (delta < 0) {
delta = flashingPeriodMs;
}
if (delta >= flashingPeriodMs) {
singleFlash(currentTimeMs);
}
}
/**
* Performs single flash,
* sets last flash time to the current
*/
void singleFlash() {
singleFlash(millis());
}
/**
* Performs single flash,
* sets last flash time to the given
*/
void singleFlash(unsigned long currentTimeMs) {
lastFlashTimeMs = currentTimeMs;
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(CONTROL_PIN, HIGH);
delay(20);
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(CONTROL_PIN, LOW);
delay(10);
}