Skip to content

Commit 93c2594

Browse files
Sync from Time-Circuits-Display-A10001986
1 parent 1af4ad2 commit 93c2594

30 files changed

Lines changed: 4373 additions & 2690 deletions

AddOns.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# DIY additions for the Time Circuits Display
32

43
- [Rotary Encoder](#rotary-encoder)
@@ -27,7 +26,7 @@ Up to two rotary encoders can be connected, one for speed, one for volume.
2726
In order to use an encoder for speed or volume, it needs to be configured as follows:
2827

2928
<table>
30-
<tr><td></td><td>Ada4991</td><td>DFRobot</td><td>DuPPA</td></tr>
29+
<tr><td></td><td>Ada4991/5880</td><td>DFRobot</td><td>DuPPA</td></tr>
3130
<tr><td>Speed</td><td>Default</td><td>SW1=0,SW2=0</td><td>A0 closed</td></tr>
3231
<tr><td>Volume</td><td>A0 closed</td><td>SW1=0,SW2=1</td><td>A0,A1 closed</td></tr>
3332
</table>
@@ -220,7 +219,7 @@ The TCD has a TT-OUT pin (marked "TT OUT (IO14)" or "IO14") which can be used to
220219

221220
Signaling is done by setting this pin HIGH (2.7-3.3V).
222221

223-
For connecting CircuitSetup/A10001986 props, see the prop's documentation ([Flux capacitor](https://github.com/realA10001986/Flux-Capacitor/tree/main?tab=readme-ov-file#connecting-a-tcd-by-wire), [SID](https://github.com/realA10001986/SID/tree/main?tab=readme-ov-file#connecting-a-tcd-by-wire), [Dash Gauges](https://github.com/realA10001986/Dash-Gauges/blob/main/hardware/README.md#connecting-a-tcd-to-the-dash-gauges-by-wire), [VSR](https://github.com/realA10001986/VSR#connecting-a-tcd-by-wire)).
222+
For connecting CircuitSetup/A10001986 props, see the prop's documentation ([Flux capacitor](https://github.com/CircuitSetup/Flux-Capacitor#connecting-a-tcd-by-wire), [SID](https://github.com/CircuitSetup/SID#connecting-a-tcd-by-wire), [Dash Gauges](https://github.com/CircuitSetup/Dash-Gauges/blob/main/hardware/README.md#connecting-a-tcd-to-the-dash-gauges-by-wire), [VSR](https://github.com/realA10001986/VSR#connecting-a-tcd-by-wire)).
224223

225224
In order to connect props that can sense HIGH/LOW levels (and don't use the TT OUT pin for power supply), you need two wires for connecting the TCD: TT-OUT and GND, which need to be connected to the prop:
226225

@@ -383,4 +382,4 @@ As you can see, there is no stall: The props receive proper info on when the tem
383382
Conclusion: If you are not planning on using GPS/Rotary Encoder/Futaba remote speed with your TCD, you can use the normal TIMETRAVEL command. In the other case, you need to teach your MQTT-aware device how to interpret the enhanced TIMETRAVEL_xxxx_yyyy command. Both xxxx and yyyy are always four digits. xxxx is the time until temporal displacement starts, yyyy is an approximation of the duration of the temporal displacement; however, don't use this value to time the reentry, instead wait for the REENTRY command to initiate your re-entry sequence.
384383

385384
---
386-
_Text & images: (C) Thomas Winischhofer ("A10001986"). See LICENSE._ Source: https://tcd.out-a-ti.me
385+
_Text & images: (C) Thomas Winischhofer ("A10001986"). See LICENSE._ Source: https://github.com/CircuitSetup/Time-Circuits-Display

CheatSheet.pdf

5.47 KB
Binary file not shown.

README.md

Lines changed: 177 additions & 84 deletions
Large diffs are not rendered by default.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* AudioFileSourceLoop
3+
* Read SD/SPIFFS/LittleFS file to be used by AudioGenerator
4+
* Reads file in a loop (for looped playback)
5+
*
6+
* Thomas Winischhofer (A10001986), 2023
7+
*
8+
* Based on AudioFileSourceSD by Earle F. Philhower, III
9+
*
10+
*/
11+
12+
#include "tc_global.h"
13+
#include "AudioFileSourceLoop.h"
14+
15+
AudioFileSourceLoop::AudioFileSourceLoop()
16+
{
17+
}
18+
19+
AudioFileSourceLoop::~AudioFileSourceLoop()
20+
{
21+
if(f) f.close();
22+
}
23+
24+
uint32_t AudioFileSourceLoop::read(void *data, uint32_t len)
25+
{
26+
uint32_t glen = f.read(reinterpret_cast<uint8_t*>(data), len);
27+
if(!doPlayLoop || glen == len) return glen;
28+
seek(startPos, SEEK_SET);
29+
return glen + f.read(reinterpret_cast<uint8_t*>(data) + glen, len - glen);
30+
}
31+
32+
bool AudioFileSourceLoop::seek(int32_t pos, int dir)
33+
{
34+
if(!f) return false;
35+
if(dir == SEEK_SET) return f.seek(pos);
36+
else if(dir == SEEK_CUR) return f.seek(f.position() + pos);
37+
else if(dir == SEEK_END) return f.seek(f.size() + pos);
38+
return false;
39+
}
40+
41+
bool AudioFileSourceLoop::close()
42+
{
43+
f.close();
44+
return true;
45+
}
46+
47+
bool AudioFileSourceLoop::isOpen()
48+
{
49+
return f ? true : false;
50+
}
51+
52+
uint32_t AudioFileSourceLoop::getSize()
53+
{
54+
if(!f) return 0;
55+
return f.size();
56+
}
57+
58+
uint32_t AudioFileSourceLoop::getPos()
59+
{
60+
if(!f) return 0;
61+
return f.position();
62+
}
63+
64+
void AudioFileSourceLoop::setStartPos(int32_t newStartPos)
65+
{
66+
startPos = newStartPos;
67+
}
68+
69+
void AudioFileSourceLoop::setPlayLoop(bool playLoop)
70+
{
71+
doPlayLoop = playLoop;
72+
}
73+
74+
75+
// SD -----------------------------------------------
76+
77+
AudioFileSourceSDLoop::AudioFileSourceSDLoop()
78+
{
79+
}
80+
81+
AudioFileSourceSDLoop::AudioFileSourceSDLoop(const char *filename)
82+
{
83+
open(filename);
84+
}
85+
86+
bool AudioFileSourceSDLoop::open(const char *filename)
87+
{
88+
f = SD.open(filename, FILE_READ);
89+
return f;
90+
}
91+
92+
// FlashFS -------------------------------------------
93+
94+
AudioFileSourceFSLoop::AudioFileSourceFSLoop()
95+
{
96+
}
97+
98+
AudioFileSourceFSLoop::AudioFileSourceFSLoop(const char *filename)
99+
{
100+
open(filename);
101+
}
102+
103+
bool AudioFileSourceFSLoop::open(const char *filename)
104+
{
105+
#ifdef USE_SPIFFS // ------------------------------
106+
f = SPIFFS.open(filename, FILE_READ);
107+
#else // ------------------------------------------
108+
f = LittleFS.open(filename, FILE_READ);
109+
#endif // -------------------------------------------
110+
return f;
111+
}

Software/src/AudioFileSourceLoop.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* AudioFileSourceLoop
3+
* Read SD/SPIFFS/LittleFS file to be used by AudioGenerator
4+
* Reads file in a loop (for looped playback)
5+
*
6+
* Thomas Winischhofer (A10001986), 2023
7+
*
8+
* Based on AudioFileSourceSD by Earle F. Philhower, III
9+
*
10+
*/
11+
12+
#ifndef _AudioFileSourceLoop_H
13+
#define _AudioFileSourceLoop_H
14+
15+
#include "src/ESP8266Audio/AudioFileSource.h"
16+
#include <SD.h>
17+
#ifdef USE_SPIFFS
18+
#include <SPIFFS.h>
19+
#else
20+
#include <LittleFS.h>
21+
#endif
22+
23+
class AudioFileSourceLoop : public AudioFileSource
24+
{
25+
public:
26+
AudioFileSourceLoop();
27+
virtual ~AudioFileSourceLoop() override;
28+
29+
//virtual bool open(const char *filename) override;
30+
virtual uint32_t read(void *data, uint32_t len) override;
31+
virtual bool seek(int32_t pos, int dir) override;
32+
virtual bool close() override;
33+
virtual bool isOpen() override;
34+
virtual uint32_t getSize() override;
35+
virtual uint32_t getPos() override;
36+
void setStartPos(int32_t newStartPos);
37+
void setPlayLoop(bool playLoop);
38+
39+
protected:
40+
File f;
41+
int32_t startPos = 0;
42+
bool doPlayLoop = false;
43+
};
44+
45+
class AudioFileSourceSDLoop : public AudioFileSourceLoop
46+
{
47+
public:
48+
AudioFileSourceSDLoop();
49+
AudioFileSourceSDLoop(const char *filename);
50+
51+
virtual bool open(const char *filename) override;
52+
};
53+
54+
class AudioFileSourceFSLoop : public AudioFileSourceLoop
55+
{
56+
public:
57+
AudioFileSourceFSLoop();
58+
AudioFileSourceFSLoop(const char *filename);
59+
60+
virtual bool open(const char *filename) override;
61+
};
62+
63+
#endif

Software/src/clockdisplay.cpp

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
#define CD_AMPM_POS CD_DAY_POS
7777
#define CD_COLON_POS CD_YEAR_POS
7878

79-
extern bool alarmOnOff;
79+
extern bool alarmOnOff;
80+
extern bool snoozeRunning();
8081
#ifdef TC_HAVEGPS
8182
extern bool gpsHaveFix();
8283
extern int gpsGetDM();
@@ -91,7 +92,9 @@ extern uint16_t loadClockState(int16_t& yoffs);
9192
extern bool saveClockState(uint16_t curYear, int16_t yearoffset);
9293
extern void getClockDataP(uint64_t& timeDifference, bool &timeDiffUp);
9394
extern dateStruct *getClockDataDL(uint8_t did);
95+
extern void updateClockDataP();
9496
extern bool saveClockDataP(bool force);
97+
extern void updateClockDataDL(uint8_t did, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute);
9598
extern bool saveClockDataDL(bool force, uint8_t did, uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute);
9699

97100
#ifndef IS_ACAR_DISPLAY
@@ -112,7 +115,13 @@ static const uint8_t idxtbl[] = {
112115
};
113116
#endif
114117

118+
static const char weekdays[7][4] = {
119+
"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"
120+
};
121+
115122
static const char *nullStr = "";
123+
static const char tempStr[] = "TEMP";
124+
static const char humStr[] = "HUMIDITY";
116125

117126
/*
118127
* ClockDisplay class
@@ -239,17 +248,19 @@ uint8_t clockDisplay::setBrightnessDirect(uint8_t level)
239248
// Setup date in buffer --------------------------------------------------------
240249

241250

242-
// Set the displayed time with supplied DateTime object
243-
void clockDisplay::setDateTime(DateTime& dt)
251+
// Set the displayed time from supplied DateTime object
252+
// If wd is non-zero, year is overwritten by weekday
253+
void clockDisplay::setDateTime(DateTime& dt, int wd)
244254
{
245255
setYear(dt.year());
246256
setMonth(dt.month());
247257
setDay(dt.day());
248258
setHour(dt.hour());
249259
setMinute(dt.minute());
260+
if(wd) setWeekDay(wd - 1);
250261
}
251262

252-
// Set YEAR, MONTH, DAY, HOUR, MIN from structure
263+
// Set the displayed time from dateStruct
253264
void clockDisplay::setFromStruct(const dateStruct *s)
254265
{
255266
setYear(s->year);
@@ -472,7 +483,12 @@ void clockDisplay::setHour(uint16_t hourNum)
472483

473484
void clockDisplay::setMinute(int minNum)
474485
{
475-
uint16_t seg = ((_did == DISP_PRES) && alarmOnOff) ? 0x8000 : 0;
486+
uint16_t seg = 0;
487+
488+
if(_did == DISP_PRES) {
489+
if(snoozeRunning()) seg = _beat ? 0x8000 : 0x0000;
490+
else if(alarmOnOff) seg = 0x8000;
491+
}
476492

477493
if(minNum < 0 || minNum > 59) {
478494
minNum = (minNum > 59) ? 59 : 0;
@@ -493,6 +509,20 @@ void clockDisplay::setYearOffset(int16_t yearOffs)
493509
}
494510
}
495511

512+
void clockDisplay::setWeekDay(int wd)
513+
{
514+
uint16_t temp;
515+
uint16_t seg = _displayBuffer[CD_YEAR_POS + 1] & 0x8000;
516+
517+
temp = getLED7AlphaChar(weekdays[wd][0]) << 8;
518+
//temp |= (getLED7AlphaChar(weekdays[wd][1]) << 8);
519+
_displayBuffer[CD_YEAR_POS] = temp;
520+
521+
temp = getLED7AlphaChar(weekdays[wd][1]);
522+
temp |= (getLED7AlphaChar(weekdays[wd][2]) << 8);
523+
temp |= seg;
524+
_displayBuffer[CD_YEAR_POS + 1] = temp;
525+
}
496526

497527
// Query data ------------------------------------------------------------------
498528

@@ -654,7 +684,7 @@ void clockDisplay::showTextDirect(const char *text, uint16_t flags)
654684
db[CD_YEAR_POS + 1] |= 0x8000;
655685

656686
if(flags & CDT_COLON)
657-
db[CD_YEAR_POS] |= 0x8080;
687+
db[CD_COLON_POS] |= 0x8080;
658688

659689
directBuf(db, pos);
660690

@@ -702,7 +732,7 @@ void clockDisplay::showSettingValDirect(const char* setting, int8_t val, uint16_
702732
void clockDisplay::showTempDirect(float temp, bool tempUnit, bool animate)
703733
{
704734
char buf[32];
705-
const char *ttem = animate ? " " : "TEMP";
735+
const char *ttem = animate ? nullStr : tempStr;
706736
int t2;
707737
char u = tempUnit ? 'C' : 'F';
708738

@@ -711,16 +741,16 @@ void clockDisplay::showTempDirect(float temp, bool tempUnit, bool animate)
711741

712742
if(isnan(temp)) {
713743
#ifdef IS_ACAR_DISPLAY
714-
sprintf(buf, "%s ----~%c", ttem, u);
744+
sprintf(buf, "%4.4s ----~%c", ttem, u);
715745
#else
716-
sprintf(buf, "%s ----~%c", ttem, u);
746+
sprintf(buf, "%4.4s ----~%c", ttem, u);
717747
#endif
718748
} else {
719749
t2 = abs((int)(temp * 100.0f) - ((int)temp * 100));
720750
#ifdef IS_ACAR_DISPLAY
721-
sprintf(buf, "%s%4d%02d~%c", ttem, (int)temp, t2, u);
751+
sprintf(buf, "%4.4s%4d%02d~%c", ttem, (int)temp, t2, u);
722752
#else
723-
sprintf(buf, "%s %4d%02d~%c", ttem, (int)temp, t2, u);
753+
sprintf(buf, "%4.4s %4d%02d~%c", ttem, (int)temp, t2, u);
724754
#endif
725755
}
726756

@@ -732,22 +762,22 @@ void clockDisplay::showTempDirect(float temp, bool tempUnit, bool animate)
732762
void clockDisplay::showHumDirect(int hum, bool animate)
733763
{
734764
char buf[16];
735-
const char *thum = animate ? " " : "HUMIDITY";
765+
const char *thum = animate ? nullStr : humStr;
736766

737767
if(!handleNM())
738768
return;
739769

740770
if(hum < 0) {
741771
#ifdef IS_ACAR_DISPLAY
742-
sprintf(buf, "%s--\x7f\x80", thum);
772+
sprintf(buf, "%8.8s--\x7f\x80", thum);
743773
#else
744-
sprintf(buf, "%s --\x7f\x80", thum);
774+
sprintf(buf, "%8.8s --\x7f\x80", thum);
745775
#endif
746776
} else {
747777
#ifdef IS_ACAR_DISPLAY
748-
sprintf(buf, "%s%2d\x7f\x80", thum, hum);
778+
sprintf(buf, "%8.8s%2d\x7f\x80", thum, hum);
749779
#else
750-
sprintf(buf, "%s %2d\x7f\x80", thum, hum);
780+
sprintf(buf, "%8.8s %2d\x7f\x80", thum, hum);
751781
#endif
752782
}
753783

@@ -855,6 +885,12 @@ bool clockDisplay::load()
855885
void clockDisplay::savePending()
856886
{
857887
_savePending = 1;
888+
889+
if(_did == DISP_PRES) {
890+
return updateClockDataP();
891+
}
892+
893+
updateClockDataDL(_did, _year, _month, _day, _hour, _minute);
858894
}
859895

860896
// Returns true if FS was accessed
@@ -901,7 +937,7 @@ uint8_t clockDisplay::getLED7NumChar(uint8_t value)
901937
// Returns bit pattern for provided character for display on 7 segment display
902938
uint8_t clockDisplay::getLED7AlphaChar(uint8_t value)
903939
{
904-
if(value < 32 || value >= 127 + 2)
940+
if(value < 32 || value >= 127 + 4)
905941
return 0;
906942

907943
if(value == '6' && _corr6)
@@ -914,7 +950,7 @@ uint8_t clockDisplay::getLED7AlphaChar(uint8_t value)
914950
#ifndef IS_ACAR_DISPLAY
915951
uint16_t clockDisplay::getLEDAlphaChar(uint8_t value)
916952
{
917-
if(value < 32 || value >= 127)
953+
if(value < 32 || value >= 127 + 4)
918954
return 0;
919955

920956
// For text, use common "6" pattern to conform with 7-seg-part

0 commit comments

Comments
 (0)