Newer
Older
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
/*
Boitarire software
Plays a sound through an external MP3 module
when triggered by external sensor :
- inclination switch
- accelerometer module
- touch sensors
Configuration is selected through compilation switches.
created 25 nov 2021
by Florian Savard
This example code is in the public domain.
https://code.electrolab.fr/Flax/boitarire
*/
// Defines - Macros - Constants
#define SENSOR_INCLINATION
#define SENSOR_ACCELEROMETER
#define SENSOR_TOUCHSENSOR1
#define SENSOR_TOUCHSENSOR2
// Other constants
#define PIN_SENSOR_POSITION 9 // Position sensor input
#define PIN_GROUND_SWITCH 7 // MP3 module ground switch command output
#define PLAY_BLANK_DELAY 1000 // Blanking when playing a sound (ms)
#define DELAY_GROUND_OFF 100 // Time of ground cut of MP3 module for re-init (ms)
#ifdef SENSOR_INCLINATION
#define DEBOUNCE_DELAY 200 // Position sensor input debounce (ms)
#endif
// Local variables
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
#ifdef SENSOR_INCLINATION
int debounce_delay_mem;
bool input_prev, input_now, edge_detect, edge_timeout, edge_timeout_prev;
#endif
int play_blank_mem, ground_off_mem;
bool trig_inclination, trig_accelero, trig_touch1, trig_touch2;
bool play_busy, ground_off;
// Local function prototypes
void ReadPlayState (void);
void WritePlay (void);
// Setup function
void setup() {
// Initialize serial:
Serial.begin(9600);
// Reserve 200 bytes for the inputString:
inputString.reserve(200);
#ifdef SENSOR_INCLINATION
// Position sensor input pin - D9 - Input pull-up
pinMode(PIN_SENSOR_POSITION, INPUT_PULLUP);
#endif
// LED output for visualisation
pinMode(LED_BUILTIN, OUTPUT);
// MP3 module ground switch command - D7 - Output push-pull
pinMode(PIN_GROUND_SWITCH, OUTPUT);
play_busy = false;
play_blank_mem = 0;
ground_off = false;
ground_off_mem = 0;
#ifdef SENSOR_INCLINATION
debounce_delay_mem = 0;
input_prev = 0;
input_now = 0;
edge_detect = false;
edge_timeout = false;
edge_timeout_prev = false;
#endif
// Connect ground for MP3 module
digitalWrite(PIN_GROUND_SWITCH, HIGH);
}
// Main loop
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
Serial.println(inputString);
switch (inputString[0])
{
case 0x30:
WritePlay();
break;
default:
break;
}
// clear the string:
inputString = "";
stringComplete = false;
}
#ifdef SENSOR_INCLINATION
// Read instantaneous value of position sensor
input_now = digitalRead(PIN_SENSOR_POSITION);
// Edge detection
if ((input_now == 0) && (input_prev == 1))
{
edge_detect = true;
debounce_delay_mem = millis();
}
// LED for visualisation
if (input_now == 1)
{
edge_detect = false;
digitalWrite(LED_BUILTIN, LOW);
}
// Debounce delay
if (edge_detect == true)
{ // If edge detected on position sensor input, inscrease debounce counter
if ((edge_timeout == false) && (millis() - debounce_delay_mem > DEBOUNCE_DELAY))
{ // If debounce delay reached, set LED and timeout flag
edge_timeout = true;
digitalWrite(LED_BUILTIN, HIGH);
}
// Edge detection on timeout flag
if ((edge_timeout == true) && (edge_timeout_prev == false))
{ // Send play command to MP3 module
trig_inclination = true;
}
}
else
{
edge_timeout = false;
}
#else
trig_inclination = false;
#endif
if (trig_inclination == true)
{
trig_inclination = false;
if ((play_busy == false) && (ground_off == false))
{
play_busy = true;
WritePlay();
}
}
if ((play_busy == true) && (play_blank_mem < PLAY_BLANK_DELAY))
{
play_blank_mem++;
}
else if (play_blank_mem >= PLAY_BLANK_DELAY)
{
play_blank_mem = 0;
play_busy = false;
ground_off = true;
// Disconnect MP3 module - Reset
digitalWrite(PIN_GROUND_SWITCH, LOW);
}
if ((ground_off == true) && (ground_off_mem < DELAY_GROUND_OFF))
{
ground_off_mem++;
}
else if (ground_off_mem >= DELAY_GROUND_OFF)
{
ground_off_mem = 0;
ground_off = false;
// Connect MP3 module - Reset
digitalWrite(PIN_GROUND_SWITCH, HIGH);
}
// Update memorisations for edge detection
input_prev = input_now;
edge_timeout_prev = edge_timeout;
}
/*
SerialEvent occurs whenever a new data comes in the hardware serial RX. This
routine is run between each time loop() runs, so using delay inside loop can
delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
void ReadPlayState (void)
{
// Send Play State read request
Serial.write(170); // 0xAA
Serial.write(1); // 0x01
Serial.write(0); // 0x00
Serial.write(171); // 0xAB
}
void WritePlay (void)
{
// Send Play request
Serial.write(170); // 0xAA
Serial.write(2); // 0x02
Serial.write(0); // 0x00
Serial.write(172); // 0xAC
}