-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain.cpp
More file actions
143 lines (120 loc) · 4.13 KB
/
Copy pathmain.cpp
File metadata and controls
143 lines (120 loc) · 4.13 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
// libraries
#include <Arduino.h>
#include <avr/sleep.h>
// macros
#define EYE_LED_1_PIN 5
#define EYE_LED_2_PIN 5
#define NOSE_LED_PIN 3
#define BUTTON_PIN 4
#define POT_BRIGHTNESS_PIN A0
#define POT_BLINK_RATE_PIN A1
#define HEARTBEAT_LED_PIN 13
#define ANALOG_READ_RANGE 1023 // 10 bit
#define EYE_LED_DURATION_MS 5000
#define NOSE_LED_DURATION_MS 10000
#define HEARTBEAT_FREQ_HZ 1
#define HEARTBEAT_DUTY_CYCLE 25
#define HEARTBEAT_PERIOD_MS (1000 / HEARTBEAT_FREQ_HZ)
#define HEARTBEAT_TIME_ON_MS (HEARTBEAT_PERIOD_MS * HEARTBEAT_DUTY_CYCLE/100)
#define HEARTBEAT_TIME_OFF_MS (HEARTBEAT_PERIOD_MS - HEARTBEAT_TIME_ON_MS)
// variables
unsigned long current_time_ms = 0;
unsigned long heartbeat_led_last_toggle_time_ms = 0;
unsigned long heartbeat_led_time_since_last_toggle = 0;
volatile bool heartbeat_led_state = 0; // 0 = low = false, 1 = high = true
unsigned long led_start_time = 0;
unsigned long noseLedBlinkStartTime = 0;
unsigned long brightness = 0;
unsigned long blink_rate = 0;
bool noseLedState = false;
enum states {IDLE, READ_VOLTAGE, RUN_LED};
int state = IDLE;
// functions
void toggle_heartbeat_led(void);
void after_button_press(void);
void read_voltage(void);
void run_led(void);
// setup
void setup(){
pinMode(EYE_LED_1_PIN, OUTPUT);
pinMode(EYE_LED_2_PIN, OUTPUT);
pinMode(NOSE_LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(HEARTBEAT_LED_PIN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), after_button_press, FALLING); // FALLING = HIGH -> LOW transition
Serial.begin(9600);
Serial.println("INF: Device initialized.");
}
void loop(){
// heartbeat
current_time_ms = millis();
heartbeat_led_time_since_last_toggle = current_time_ms - heartbeat_led_last_toggle_time_ms;
if ((heartbeat_led_state == 0) && (heartbeat_led_time_since_last_toggle >= HEARTBEAT_TIME_OFF_MS)){
toggle_heartbeat_led();
}
else if ((heartbeat_led_state == 1) && (heartbeat_led_time_since_last_toggle >= HEARTBEAT_TIME_ON_MS)){
toggle_heartbeat_led();
}
// switch state
switch (state)
{
case IDLE:
state = IDLE;
break;
case READ_VOLTAGE:
read_voltage();
break;
case RUN_LED:
run_led();
break;
default:
break;
}
}
void toggle_heartbeat_led(){
heartbeat_led_state = !heartbeat_led_state;
digitalWrite(HEARTBEAT_LED_PIN, heartbeat_led_state);
heartbeat_led_last_toggle_time_ms = millis();
}
void after_button_press(){
Serial.println("Button pressed.");
led_start_time = current_time_ms;
detachInterrupt(digitalPinToInterrupt(BUTTON_PIN));
state = READ_VOLTAGE;
}
void read_voltage(){
Serial.println("Reading voltage.");
brightness = map(analogRead(POT_BRIGHTNESS_PIN), 0, (ANALOG_READ_RANGE*10/11), 0, 255); // map brightness from 0 to 255
blink_rate = map(analogRead(POT_BLINK_RATE_PIN), 0, (ANALOG_READ_RANGE*10/11), 100, 200); // map blink rate from 5hz to 10hz
Serial.println("Brightness");
Serial.println(brightness);
Serial.println("Blink rate");
Serial.println(blink_rate);
state = RUN_LED;
}
void run_led(){
// Serial.println("Running LEDs.");
// Serial.println(current_time_ms);
// eyes
if (current_time_ms - led_start_time >= EYE_LED_DURATION_MS) { // turn off after 5 seconds
analogWrite(EYE_LED_1_PIN, 0);
analogWrite(EYE_LED_2_PIN, 0);
}
else {
analogWrite(EYE_LED_1_PIN, brightness);
analogWrite(EYE_LED_2_PIN, brightness);
}
// nose
if (current_time_ms - noseLedBlinkStartTime >= blink_rate) { // blink with 50% duty cycle
noseLedBlinkStartTime = current_time_ms;
noseLedState = !noseLedState;
analogWrite(NOSE_LED_PIN, noseLedState * 255);
}
if (current_time_ms - led_start_time >= NOSE_LED_DURATION_MS) { // turn off after 10 seconds
noseLedState = false;
analogWrite(NOSE_LED_PIN, 0);
// reattach button and send back to IDLE
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), after_button_press, FALLING);
state = IDLE;
}
}