Repository navigation
Expand file tree
/
Copy pathBinaryTimerDio.java
More file actions
154 lines (141 loc) · 4.53 KB
/
Copy pathBinaryTimerDio.java
File metadata and controls
154 lines (141 loc) · 4.53 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
package com.nighthacking.binarytimer;
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import jdk.dio.DeviceManager;
import jdk.dio.gpio.GPIOPin;
/**
* @author Stephen Chin <steveonjava@gmail.com>
*/
public class BinaryTimerDio {
public static void main(String[] args) throws IOException, InterruptedException {
new BinaryTimerDio().run();
}
private final GPIOPin[] leds = new GPIOPin[17];
private final GPIOPin[] buttons = new GPIOPin[4];
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> future;
private int counter = 63 << 3; // light up all the greens initially [63s]
private volatile boolean paused = true;
private ScheduledFuture<?> shutdownFuture;
public void run() throws IOException, InterruptedException {
initPins();
Runtime.getRuntime().addShutdownHook(new Thread(this::closePins));
addListeners();
updateLeds();
runClock();
}
private void initPins() throws IOException {
for (int i = 0; i < 17; i++) {
leds[i] = DeviceManager.open(i + 1);
}
for (int i = 0; i < 4; i++) {
buttons[i] = DeviceManager.open(i + 18);
}
}
private void closePins() {
for (int i = 0; i < 17; i++) {
try {
leds[i].close();
} catch (IOException ex) {
Logger.getLogger(BinaryTimerDio.class.getName()).log(Level.SEVERE, null, ex);
}
}
for (int i = 0; i < 4; i++) {
try {
buttons[i].close();
} catch (IOException ex) {
Logger.getLogger(BinaryTimerDio.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void addListeners() throws IOException {
buttons[0].setInputListener(new DioDebouncer(new PLHelper(event -> {
if (!event.getValue() && paused) { // Blue Button: Add 1 (and then x2)
prepareEdit();
counter <<= 1; // shift the bits (time x2)
counter |= 0x8; // turn on the second bit (+1)
updateLeds();
}
})));
buttons[1].setInputListener(new DioDebouncer(new PLHelper(event -> {
if (!event.getValue() && paused) { // Gray Button: Add 0 (and then x2)
prepareEdit();
counter <<= 1; // shift the bits (time x2)
updateLeds();
}
})));
buttons[2].setInputListener(new DioDebouncer(new PLHelper(event -> {
if (!event.getValue()) { // Red Button: Divide by 2, Pause, Shutdown
shutdownFuture = executor.schedule(executor::shutdown, 3, TimeUnit.SECONDS);
if (!paused) {
paused = true;
} else {
prepareEdit();
counter >>>= 1; // shift the bits (time /2)
counter &= ~0x4; // clear the bit shifted off
}
updateLeds();
} else {
shutdownFuture.cancel(false);
}
})));
buttons[3].setInputListener(new DioDebouncer(new PLHelper(event -> {
if (!event.getValue()) { // Green Button: Run/Pause
if (paused && counter >= 0) {
counter &= 0x1FFFF; // clip to max leds
}
paused = !paused;
updateLeds();
}
})));
}
private void prepareEdit() {
if (counter < 0) { // if we went negative, clear out that funk
counter = 0;
}
counter &= ~0xC0000007; // turn off blue leds and high order bits
}
private void runClock() throws InterruptedException, IOException {
future = executor.scheduleAtFixedRate(() -> {
if (!paused) {
if (counter <= 0) {
if ((System.currentTimeMillis() / 250) % 2 == 0) {
setAllLeds(false);
} else {
updateLeds();
}
} else {
updateLeds();
}
counter--;
}
}, 0, 125, TimeUnit.MILLISECONDS);
}
private void updateLeds() {
for (int i = 0; i < 17; i++) {
GPIOPin pin = leds[16 - i];
boolean newValue = (counter >> i & 0x1) != 0;
try {
if (pin.getValue() != newValue) {
pin.setValue(newValue);
}
} catch (IOException ex) {
Logger.getLogger(BinaryTimerDio.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void setAllLeds(boolean value) {
for (int i = 0; i < 17; i++) {
try {
leds[16 - i].setValue(value);
} catch (IOException ex) {
Logger.getLogger(BinaryTimerDio.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}