discstation 0.1.27 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/arduino/c6/DiscStation_C6.ino +65 -9
- package/arduino/v1/DiscStation.ino +65 -10
- package/package.json +1 -1
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
#define POT_READ_MS 200
|
|
32
32
|
#define DONE_RESET_MS 30000
|
|
33
33
|
#define STANDBY_BLANK_MS 60000
|
|
34
|
-
#define IDLE_BLANK_MS 45000 //
|
|
34
|
+
#define IDLE_BLANK_MS 45000 // no input this long on HOME/STANDBY -> spinning-disc screensaver
|
|
35
|
+
#define SAVER_FRAME_MS 90 // screensaver frame interval (~11fps)
|
|
35
36
|
#define PING_TIMEOUT_MS 30000
|
|
36
37
|
|
|
37
38
|
#define WIFI_RESET_HOLD_MS 10000
|
|
@@ -241,8 +242,10 @@ bool editingSpeed = false;
|
|
|
241
242
|
int playVolume = 50;
|
|
242
243
|
unsigned long standbyStartTime = 0;
|
|
243
244
|
unsigned long lastMsgTime = 0;
|
|
244
|
-
unsigned long lastInputTime = 0; // last button press / screen change; drives
|
|
245
|
-
bool displayBlank = false;
|
|
245
|
+
unsigned long lastInputTime = 0; // last button press / screen change; drives the idle screensaver
|
|
246
|
+
bool displayBlank = false; // true = real UI hidden, disc screensaver running; any input restores it
|
|
247
|
+
unsigned long lastSaverFrame = 0;
|
|
248
|
+
int saverStep = 0;
|
|
246
249
|
bool audioPlayMode = false;
|
|
247
250
|
int displayRotation = 0;
|
|
248
251
|
|
|
@@ -545,8 +548,50 @@ void drawLoading() {
|
|
|
545
548
|
display.display();
|
|
546
549
|
}
|
|
547
550
|
|
|
548
|
-
|
|
549
|
-
|
|
551
|
+
// 24-step sine table x64: sin(i*15deg)*64. Drives the idle disc screensaver.
|
|
552
|
+
const int8_t SIN24[24] = {
|
|
553
|
+
0, 17, 32, 45, 55, 62, 64, 62, 55, 45, 32, 17,
|
|
554
|
+
0, -17, -32, -45, -55, -62, -64, -62, -55, -45, -32, -17
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
// Spinning-disc screensaver frame - shown after IDLE_BLANK_MS on HOME/STANDBY
|
|
558
|
+
// instead of powering the panel off. Keeps the OLED lit and the I2C bus busy so
|
|
559
|
+
// a USB power-bank feeding the remote doesn't hit its no-load auto-shutoff.
|
|
560
|
+
void drawDiscSaver(int step) {
|
|
561
|
+
if (!displayOk) return;
|
|
562
|
+
const int cx = 64, cy = 32, R = 30;
|
|
563
|
+
display.clearDisplay();
|
|
564
|
+
display.fillCircle(cx, cy, R, SSD1306_WHITE); // vinyl body
|
|
565
|
+
|
|
566
|
+
for (int cl = 0; cl < 2; cl++) { // 2 groove clusters, 180 apart
|
|
567
|
+
int base = step + cl * 12;
|
|
568
|
+
for (int g = 0; g < 3; g++) { // 3 nested "sound wave" grooves
|
|
569
|
+
for (int t = 0; t < 3; t++) { // 3px-thick stroke
|
|
570
|
+
int r = 16 + g * 5 + t;
|
|
571
|
+
int px = -100, py = -100;
|
|
572
|
+
for (int a = 0; a <= 4; a++) { // ~60deg arc, 4 chords
|
|
573
|
+
int i = (base + a) % 24;
|
|
574
|
+
int x = cx + r * SIN24[(i + 6) % 24] / 64;
|
|
575
|
+
int y = cy + r * SIN24[i] / 64;
|
|
576
|
+
if (px > -100) display.drawLine(px, py, x, y, SSD1306_BLACK);
|
|
577
|
+
px = x; py = y;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
display.fillCircle(cx, cy, 13, SSD1306_BLACK); // concentric label
|
|
584
|
+
display.fillCircle(cx, cy, 11, SSD1306_WHITE);
|
|
585
|
+
display.fillCircle(cx, cy, 8, SSD1306_BLACK);
|
|
586
|
+
display.fillCircle(cx, cy, 5, SSD1306_WHITE);
|
|
587
|
+
display.fillCircle(cx, cy, 2, SSD1306_BLACK); // center hole
|
|
588
|
+
display.display();
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Returns true if this call actually woke a blanked screen - callers use that
|
|
592
|
+
// to swallow the wake press so it doesn't also trigger a menu action.
|
|
593
|
+
bool wakeDisplay() {
|
|
594
|
+
if (!displayBlank || !displayOk) return false;
|
|
550
595
|
display.ssd1306_command(0xAF);
|
|
551
596
|
displayBlank = false;
|
|
552
597
|
switch (uiState) {
|
|
@@ -561,6 +606,7 @@ void wakeDisplay() {
|
|
|
561
606
|
case UI_LOADING: drawLoading(); break;
|
|
562
607
|
case UI_SETUP: drawSetup(); break;
|
|
563
608
|
}
|
|
609
|
+
return true;
|
|
564
610
|
}
|
|
565
611
|
|
|
566
612
|
void drawPlay() {
|
|
@@ -655,6 +701,8 @@ void parseMessage(String msg) {
|
|
|
655
701
|
line1 = msg.substring(5);
|
|
656
702
|
line2 = "Playing disc";
|
|
657
703
|
playVolume = readPercent();
|
|
704
|
+
Out.print("POT:"); // push the knob's current level so playback starts at it
|
|
705
|
+
Out.println(playVolume);
|
|
658
706
|
drawPlay();
|
|
659
707
|
|
|
660
708
|
} else if (msg.startsWith("PLAY_MODE:")) {
|
|
@@ -810,7 +858,7 @@ void setup() {
|
|
|
810
858
|
}
|
|
811
859
|
|
|
812
860
|
void handleSelectPress(bool longPress) {
|
|
813
|
-
wakeDisplay();
|
|
861
|
+
if (wakeDisplay()) { lastInputTime = millis(); return; } // wake-only press, swallow the action
|
|
814
862
|
lastInputTime = millis();
|
|
815
863
|
if (uiState == UI_HOME) {
|
|
816
864
|
if (longPress) {
|
|
@@ -896,7 +944,7 @@ void handleSelectPress(bool longPress) {
|
|
|
896
944
|
}
|
|
897
945
|
|
|
898
946
|
void handleUp(bool longPress) {
|
|
899
|
-
wakeDisplay();
|
|
947
|
+
if (wakeDisplay()) { lastInputTime = millis(); return; } // wake-only press, swallow the action
|
|
900
948
|
lastInputTime = millis();
|
|
901
949
|
if (uiState == UI_HOME) {
|
|
902
950
|
if (homeCount > 0) {
|
|
@@ -933,7 +981,7 @@ void handleUp(bool longPress) {
|
|
|
933
981
|
}
|
|
934
982
|
|
|
935
983
|
void handleDown(bool longPress) {
|
|
936
|
-
wakeDisplay();
|
|
984
|
+
if (wakeDisplay()) { lastInputTime = millis(); return; } // wake-only press, swallow the action
|
|
937
985
|
lastInputTime = millis();
|
|
938
986
|
if (uiState == UI_HOME) {
|
|
939
987
|
if (homeCount > 0) {
|
|
@@ -1113,11 +1161,19 @@ void loop() {
|
|
|
1113
1161
|
if (!displayBlank) drawLoading();
|
|
1114
1162
|
}
|
|
1115
1163
|
|
|
1164
|
+
// --- Idle disc screensaver (HOME + STANDBY) ---
|
|
1116
1165
|
if (displayOk && !displayBlank &&
|
|
1117
1166
|
(uiState == UI_HOME || uiState == UI_STANDBY) &&
|
|
1118
1167
|
(long)(millis() - lastInputTime) >= IDLE_BLANK_MS) {
|
|
1119
|
-
display.ssd1306_command(0xAE);
|
|
1120
1168
|
displayBlank = true;
|
|
1169
|
+
saverStep = 0;
|
|
1170
|
+
lastSaverFrame = 0;
|
|
1171
|
+
}
|
|
1172
|
+
if (displayBlank && displayOk &&
|
|
1173
|
+
(long)(millis() - lastSaverFrame) >= SAVER_FRAME_MS) {
|
|
1174
|
+
lastSaverFrame = millis();
|
|
1175
|
+
drawDiscSaver(saverStep);
|
|
1176
|
+
saverStep = (saverStep + 1) % 24;
|
|
1121
1177
|
}
|
|
1122
1178
|
|
|
1123
1179
|
if (uiState != UI_DISCONNECTED &&
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
#define POT_READ_MS 200
|
|
33
33
|
#define DONE_RESET_MS 30000
|
|
34
34
|
#define STANDBY_BLANK_MS 60000
|
|
35
|
-
#define IDLE_BLANK_MS 45000 //
|
|
35
|
+
#define IDLE_BLANK_MS 45000 // no input this long on HOME/STANDBY -> spinning-disc screensaver
|
|
36
|
+
#define SAVER_FRAME_MS 90 // screensaver frame interval (~11fps)
|
|
36
37
|
#define PING_TIMEOUT_MS 30000
|
|
37
38
|
|
|
38
39
|
#define WIFI_RESET_HOLD_MS 10000 // hold SELECT this long on HOME to wipe Wi-Fi creds
|
|
@@ -245,8 +246,10 @@ bool editingSpeed = false;
|
|
|
245
246
|
int playVolume = 50;
|
|
246
247
|
unsigned long standbyStartTime = 0;
|
|
247
248
|
unsigned long lastMsgTime = 0;
|
|
248
|
-
unsigned long lastInputTime = 0; // last button press / screen change; drives
|
|
249
|
-
bool displayBlank = false;
|
|
249
|
+
unsigned long lastInputTime = 0; // last button press / screen change; drives the idle screensaver
|
|
250
|
+
bool displayBlank = false; // true = real UI hidden, disc screensaver running; any input restores it
|
|
251
|
+
unsigned long lastSaverFrame = 0;
|
|
252
|
+
int saverStep = 0;
|
|
250
253
|
bool audioPlayMode = false;
|
|
251
254
|
int displayRotation = 0;
|
|
252
255
|
|
|
@@ -531,8 +534,50 @@ void drawDisconnected() {
|
|
|
531
534
|
display.display();
|
|
532
535
|
}
|
|
533
536
|
|
|
534
|
-
|
|
535
|
-
|
|
537
|
+
// 24-step sine table x64: sin(i*15deg)*64. Drives the idle disc screensaver.
|
|
538
|
+
const int8_t SIN24[24] = {
|
|
539
|
+
0, 17, 32, 45, 55, 62, 64, 62, 55, 45, 32, 17,
|
|
540
|
+
0, -17, -32, -45, -55, -62, -64, -62, -55, -45, -32, -17
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
// Spinning-disc screensaver frame - shown after IDLE_BLANK_MS on HOME/STANDBY
|
|
544
|
+
// instead of powering the panel off. Keeps the OLED lit and the I2C bus busy so
|
|
545
|
+
// a USB power-bank feeding the remote doesn't hit its no-load auto-shutoff.
|
|
546
|
+
void drawDiscSaver(int step) {
|
|
547
|
+
if (!displayOk) return;
|
|
548
|
+
const int cx = 64, cy = 32, R = 30;
|
|
549
|
+
display.clearDisplay();
|
|
550
|
+
display.fillCircle(cx, cy, R, SSD1306_WHITE); // vinyl body
|
|
551
|
+
|
|
552
|
+
for (int cl = 0; cl < 2; cl++) { // 2 groove clusters, 180 apart
|
|
553
|
+
int base = step + cl * 12;
|
|
554
|
+
for (int g = 0; g < 3; g++) { // 3 nested "sound wave" grooves
|
|
555
|
+
for (int t = 0; t < 3; t++) { // 3px-thick stroke
|
|
556
|
+
int r = 16 + g * 5 + t;
|
|
557
|
+
int px = -100, py = -100;
|
|
558
|
+
for (int a = 0; a <= 4; a++) { // ~60deg arc, 4 chords
|
|
559
|
+
int i = (base + a) % 24;
|
|
560
|
+
int x = cx + r * SIN24[(i + 6) % 24] / 64;
|
|
561
|
+
int y = cy + r * SIN24[i] / 64;
|
|
562
|
+
if (px > -100) display.drawLine(px, py, x, y, SSD1306_BLACK);
|
|
563
|
+
px = x; py = y;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
display.fillCircle(cx, cy, 13, SSD1306_BLACK); // concentric label
|
|
570
|
+
display.fillCircle(cx, cy, 11, SSD1306_WHITE);
|
|
571
|
+
display.fillCircle(cx, cy, 8, SSD1306_BLACK);
|
|
572
|
+
display.fillCircle(cx, cy, 5, SSD1306_WHITE);
|
|
573
|
+
display.fillCircle(cx, cy, 2, SSD1306_BLACK); // center hole
|
|
574
|
+
display.display();
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// Returns true if this call actually woke a blanked screen - callers use that
|
|
578
|
+
// to swallow the wake press so it doesn't also trigger a menu action.
|
|
579
|
+
bool wakeDisplay() {
|
|
580
|
+
if (!displayBlank || !displayOk) return false;
|
|
536
581
|
display.ssd1306_command(0xAF);
|
|
537
582
|
displayBlank = false;
|
|
538
583
|
switch (uiState) {
|
|
@@ -546,6 +591,7 @@ void wakeDisplay() {
|
|
|
546
591
|
case UI_DISCONNECTED: drawDisconnected(); break;
|
|
547
592
|
case UI_SETUP: drawSetup(); break;
|
|
548
593
|
}
|
|
594
|
+
return true;
|
|
549
595
|
}
|
|
550
596
|
|
|
551
597
|
void drawPlay() {
|
|
@@ -640,6 +686,8 @@ void parseMessage(String msg) {
|
|
|
640
686
|
line1 = msg.substring(5);
|
|
641
687
|
line2 = "Playing disc";
|
|
642
688
|
playVolume = readPercent();
|
|
689
|
+
Out.print("POT:"); // push the knob's current level so playback starts at it
|
|
690
|
+
Out.println(playVolume);
|
|
643
691
|
drawPlay();
|
|
644
692
|
|
|
645
693
|
} else if (msg.startsWith("PLAY_MODE:")) {
|
|
@@ -775,7 +823,7 @@ void setup() {
|
|
|
775
823
|
}
|
|
776
824
|
|
|
777
825
|
void handleSelectPress(bool longPress) {
|
|
778
|
-
wakeDisplay();
|
|
826
|
+
if (wakeDisplay()) { lastInputTime = millis(); return; } // wake-only press, swallow the action
|
|
779
827
|
lastInputTime = millis();
|
|
780
828
|
if (uiState == UI_HOME) {
|
|
781
829
|
if (longPress) {
|
|
@@ -865,7 +913,7 @@ void handleSelectPress(bool longPress) {
|
|
|
865
913
|
}
|
|
866
914
|
|
|
867
915
|
void handleUp(bool longPress) {
|
|
868
|
-
wakeDisplay();
|
|
916
|
+
if (wakeDisplay()) { lastInputTime = millis(); return; } // wake-only press, swallow the action
|
|
869
917
|
lastInputTime = millis();
|
|
870
918
|
if (uiState == UI_HOME) {
|
|
871
919
|
if (homeCount > 0) {
|
|
@@ -905,7 +953,7 @@ void handleUp(bool longPress) {
|
|
|
905
953
|
}
|
|
906
954
|
|
|
907
955
|
void handleDown(bool longPress) {
|
|
908
|
-
wakeDisplay();
|
|
956
|
+
if (wakeDisplay()) { lastInputTime = millis(); return; } // wake-only press, swallow the action
|
|
909
957
|
lastInputTime = millis();
|
|
910
958
|
if (uiState == UI_HOME) {
|
|
911
959
|
if (homeCount > 0) {
|
|
@@ -1091,12 +1139,19 @@ void loop() {
|
|
|
1091
1139
|
if (!displayBlank) drawStatus();
|
|
1092
1140
|
}
|
|
1093
1141
|
|
|
1094
|
-
// ---
|
|
1142
|
+
// --- Idle disc screensaver (HOME + STANDBY) ---
|
|
1095
1143
|
if (displayOk && !displayBlank &&
|
|
1096
1144
|
(uiState == UI_HOME || uiState == UI_STANDBY) &&
|
|
1097
1145
|
(long)(millis() - lastInputTime) >= IDLE_BLANK_MS) {
|
|
1098
|
-
display.ssd1306_command(0xAE);
|
|
1099
1146
|
displayBlank = true;
|
|
1147
|
+
saverStep = 0;
|
|
1148
|
+
lastSaverFrame = 0;
|
|
1149
|
+
}
|
|
1150
|
+
if (displayBlank && displayOk &&
|
|
1151
|
+
(long)(millis() - lastSaverFrame) >= SAVER_FRAME_MS) {
|
|
1152
|
+
lastSaverFrame = millis();
|
|
1153
|
+
drawDiscSaver(saverStep);
|
|
1154
|
+
saverStep = (saverStep + 1) % 24;
|
|
1100
1155
|
}
|
|
1101
1156
|
|
|
1102
1157
|
// --- PING timeout (disconnected) ---
|