-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmillis_timestamp_events.ino
111 lines (88 loc) · 2.98 KB
/
millis_timestamp_events.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
// ---------------------------------------------
// millis_timestamp_events.ino
// ---------------------------------------------
// License: The Unlicense, Public Domain.
// Author: Koepel
// 2019 april 13, Version 1
// 2021 may 23, Version 2
// Added a small delay of 2ms at the end of the loop(),
// because button-bounching could fill the queue
// with a single press on the button.
// ---------------------------------------------
//
// Record events (button presses and button releases)
// and give each event a timestamp with millis.
// Put the data in a queue and use that to delay
// the events before they are send to the output (a led).
//
// A button is connected to pin 2 and GND.
//
// The LED_BUILTIN is the led on the Arduino board,
// any other digital pin can be used.
//
#define NUM_SAMPLES 100
struct EventQueueStruct
{
unsigned long timeStamp; // the timestamp (from millis)
int event; // the event (HIGH or LOW for led)
};
EventQueueStruct myEvents[NUM_SAMPLES];
int indexIn = 0; // index where to put new data
int indexOut = 0; // index where to read data
const unsigned long interval = 2000UL; // delay
const int pinButton = 2; // button to this pin and GND
const int pinLed = LED_BUILTIN; // The digital pin to which a led is connected.
int last_button_state;
void setup()
{
pinMode( pinButton, INPUT_PULLUP);
pinMode( pinLed, OUTPUT);
last_button_state = digitalRead( pinButton);
}
void loop()
{
unsigned long currentMillis = millis();
// --------------------------------------
// Write any button event to the queue.
// --------------------------------------
int buttonState = digitalRead( pinButton);
if( buttonState != last_button_state) // button changed ?
{
// Calculate the new index.
// The queue could be full.
// The data is only stored and the index is only advanced,
// when everything is okay.
int newIndex = indexIn + 1;
if( newIndex >= NUM_SAMPLES)
{
newIndex = 0;
}
if( newIndex != indexOut) // The queue is not full ?
{
// A LOW from the button is a HIGH for the led.
int ledstate = (buttonState == LOW) ? HIGH : LOW;
myEvents[indexIn].timeStamp = currentMillis;
myEvents[indexIn].event = ledstate;
indexIn = newIndex; // set index for next data
}
last_button_state = buttonState; // remember button state to detect a change
}
// --------------------------------------
// Read the queue and process the events.
// --------------------------------------
// The queue is empty when the indexIn is the same
// as the indexOut.
if( indexOut != indexIn) // something in the queue ?
{
if( currentMillis - myEvents[indexOut].timeStamp >= interval)
{
digitalWrite( pinLed, myEvents[indexOut].event);
indexOut++;
if( indexOut >= NUM_SAMPLES)
{
indexOut = 0;
}
}
}
delay( 2); // slow down the sketch to reduce button bounching
}