-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOptoLEDcontroller.ino
More file actions
245 lines (181 loc) · 6.77 KB
/
OptoLEDcontroller.ino
File metadata and controls
245 lines (181 loc) · 6.77 KB
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
// Length of flash that LED is on, in milliseconds
#define LEDonTime 500
// Interval between LED flashes, in milliseconds
#define LEDinterval 2000
// Total length of experiment, in milliseconds
// Note: if the experiment ends when LED is on, LED will turn off immediately
#define totalExperimentTime 10*1000
// Define brightness on scale from 0-255
// LEDonValue is used because driver is active-low
#define brightness 10
#define OptoLEDon 255-brightness
#define OptoLEDoff 255
/************************************************************************/
// Define states for state machine
#define initialPseudoState 0
#define standby 1
#define lightOn 2
#define lightOff 3
/************************************************************************/
// Define events
#define GOTO_STANDBY 0
#define BEGIN_EXPERIMENT 1
#define LED_FLASH_TIMER_EXPIRED 2
#define LED_INTERVAL_TIMER_EXPIRED 3
#define EXPERIMENT_COMPLETE 4
/************************************************************************/
// Define readable names
#define controlPin 6
#define referencePin 7
// For digital outputs
#define LEDoff HIGH
#define LEDon LOW
/************************************************************************/
// Declare functions
void runStateMachine(char);
/************************************************************************/
// Declare variables
char currentState = initialPseudoState;
unsigned long lightOnTime;
unsigned long lightOffTime;
unsigned long experimentEndTime = totalExperimentTime;
void setup() {
/************************************************************************/
// setup serial port to PC
Serial.begin(9600);
Serial.println("LED Controller for Optogenetics");
Serial.println("Initializing...");
/************************************************************************/
// check to make sure parameters are legal
if (LEDonTime > LEDinterval) {
Serial.print("Warning: LED on time is greater than the interval between flashes. Controller may not behave as expected.");
}
/************************************************************************/
// setup pins
// analog output to PWM LED driver
pinMode(controlPin, OUTPUT); // use digital I/O for simple testing
// digitalWrite(controlPin, LEDoff); // start with LEDs off
analogWrite(controlPin, OptoLEDoff);
// analog output for LED driver reference
pinMode(referencePin, OUTPUT);
digitalWrite(referencePin, HIGH); // reference stays at 5V
// digital output for LED on Arduino board
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW); // make sure light is off to start
/************************************************************************/
// setup timers
/************************************************************************/
runStateMachine(GOTO_STANDBY);
Serial.println("Press 's' key to start experiment...");
}
void loop() {
// put your main code here, to run repeatedly:
unsigned long currentTime = millis();
// event checker to see if LED flash timer expired
if (currentTime >= lightOffTime) {
runStateMachine(LED_FLASH_TIMER_EXPIRED); // send timer event
lightOffTime += LEDinterval; // reset timer for next time
}
// event checker to see if it's time to turn LED on
if (currentTime >= lightOnTime) {
runStateMachine(LED_INTERVAL_TIMER_EXPIRED); // send timer event
lightOnTime += LEDinterval; // reset timer for next time
}
// event checker to see if experiment is over yet
if (currentTime >= experimentEndTime) {
runStateMachine(EXPERIMENT_COMPLETE); // send timer event
}
// event checker for keystrokes from PC
if (Serial.available() > 0) {
char characterReceived = Serial.read();
if (characterReceived == 's') {
runStateMachine(BEGIN_EXPERIMENT);
}
else if (characterReceived == 'i') {
runStateMachine(LED_INTERVAL_TIMER_EXPIRED);
}
else if (characterReceived == 'o') {
runStateMachine(LED_FLASH_TIMER_EXPIRED);
}
else if (characterReceived == 'c') {
runStateMachine(EXPERIMENT_COMPLETE);
}
}
}
void runStateMachine(char event) {
switch (currentState) {
case initialPseudoState:
// we start here
switch (event) {
case GOTO_STANDBY: // we only care about this event when starting
digitalWrite(LED_BUILTIN, LOW); // make sure light is off
// digitalWrite(controlPin, LEDoff); // make sure light is off
analogWrite(controlPin, OptoLEDoff);
currentState = standby; // move into standby state when experiment starts
break;
}
break;
case standby:
// LEDs off
// no print statements to computer
// no response to timer expiring
// waiting for experiment to start
switch (event) {
case BEGIN_EXPERIMENT:
digitalWrite(LED_BUILTIN, HIGH);
// digitalWrite(controlPin, LEDon);
analogWrite(controlPin, OptoLEDon);
lightOnTime = millis();
lightOffTime = lightOnTime + LEDonTime;
experimentEndTime = lightOnTime + totalExperimentTime;
Serial.println("Time \t LED status");
Serial.print(lightOnTime);
Serial.println("\t 1");
currentState = lightOn;
break;
}
break;
case lightOn:
// LEDs on at desired brightness until timer expires
switch (event) {
case LED_FLASH_TIMER_EXPIRED:
digitalWrite(LED_BUILTIN, LOW); // turn off LED
// digitalWrite(controlPin, LEDoff);
analogWrite(controlPin, OptoLEDoff);
Serial.print(lightOffTime); // record time
Serial.println("\t 0");
currentState = lightOff;
break;
case EXPERIMENT_COMPLETE:
digitalWrite(LED_BUILTIN, LOW); // turn off LED
// digitalWrite(controlPin, LEDoff);
analogWrite(controlPin, OptoLEDoff);
Serial.print(experimentEndTime);
Serial.println("\t Experiment Complete");
currentState = standby;
break;
}
break;
case lightOff:
// LEDs off
switch (event) {
case LED_INTERVAL_TIMER_EXPIRED:
digitalWrite(LED_BUILTIN, HIGH); // turn on LED
// digitalWrite(controlPin, LEDon);
analogWrite(controlPin, OptoLEDon);
Serial.print(lightOnTime); // record status
Serial.println("\t 1");
currentState = lightOn;
break;
case EXPERIMENT_COMPLETE:
digitalWrite(LED_BUILTIN, LOW); // turn off LED
// digitalWrite(controlPin, LEDoff);
analogWrite(controlPin, OptoLEDoff);
Serial.print(experimentEndTime);
Serial.println("\t Experiment Complete");
currentState = standby;
break;
}
break;
}
}