├── .gitattributes ├── .gitignore ├── Button.cpp ├── Button.h ├── Colors.h ├── Configuration.h ├── Debug.cpp ├── Debug.h ├── Languages.h ├── LedDriver.cpp ├── LedDriver.h ├── LedDriverBase.cpp ├── LedDriverBase.h ├── LedDriverNeoPixel.cpp ├── LedDriverNeoPixel.h ├── Modes.h ├── QlockWiFive.ino ├── README.md ├── Renderer.cpp ├── Renderer.h ├── Settings.cpp ├── Settings.h ├── Staben.h ├── Woerter_CH.h ├── Woerter_D3.h ├── Woerter_DE.h ├── Woerter_DE_MKF.h ├── Woerter_EN.h ├── Woerter_ES.h ├── Woerter_FR.h ├── Woerter_IT.h ├── Woerter_NL.h ├── Zahlen.h ├── _Schaltplan.fzz ├── _Schaltplan.png └── _Stueckliste.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | *.publishproj 131 | 132 | # NuGet Packages Directory 133 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 134 | #packages/ 135 | 136 | # Windows Azure Build Output 137 | csx 138 | *.build.csdef 139 | 140 | # Windows Store app package directory 141 | AppPackages/ 142 | 143 | # Others 144 | sql/ 145 | *.Cache 146 | ClientBin/ 147 | [Ss]tyle[Cc]op.* 148 | ~$* 149 | *~ 150 | *.dbmdl 151 | *.[Pp]ublish.xml 152 | *.pfx 153 | *.publishsettings 154 | 155 | # RIA/Silverlight projects 156 | Generated_Code/ 157 | 158 | # Backup & report files from converting an old project file to a newer 159 | # Visual Studio version. Backup files are not needed, because we have git ;-) 160 | _UpgradeReport_Files/ 161 | Backup*/ 162 | UpgradeLog*.XML 163 | UpgradeLog*.htm 164 | 165 | # SQL Server files 166 | App_Data/*.mdf 167 | App_Data/*.ldf 168 | 169 | ############# 170 | ## Windows detritus 171 | ############# 172 | 173 | # Windows image file caches 174 | Thumbs.db 175 | ehthumbs.db 176 | 177 | # Folder config file 178 | Desktop.ini 179 | 180 | # Recycle Bin used on file shares 181 | $RECYCLE.BIN/ 182 | 183 | # Mac crap 184 | .DS_Store 185 | 186 | 187 | ############# 188 | ## Python 189 | ############# 190 | 191 | *.py[cod] 192 | 193 | # Packages 194 | *.egg 195 | *.egg-info 196 | dist/ 197 | build/ 198 | eggs/ 199 | parts/ 200 | var/ 201 | sdist/ 202 | develop-eggs/ 203 | .installed.cfg 204 | 205 | # Installer logs 206 | pip-log.txt 207 | 208 | # Unit test / coverage reports 209 | .coverage 210 | .tox 211 | 212 | #Translations 213 | *.mo 214 | 215 | #Mr Developer 216 | .mr.developer.cfg 217 | -------------------------------------------------------------------------------- /Button.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Button 3 | * Kleine Klasse zum Entprellen der Tasten. 4 | * 5 | * @mc Arduino/RBBB 6 | * @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 7 | * @version 1.7 8 | * @created 18.2.2011 9 | * @updated 16.2.2015 10 | * 11 | * Versionshistorie: 12 | * V 1.1: - Kompatibilitaet zu Arduino-IDE 1.0 hergestellt. 13 | * V 1.2: - Optimierung hinsichtlich Speicherbedarf. 14 | * V 1.3: - Verbessertes Debugging. 15 | * V 1.4: - Doppel-Tasten-Abfrage ermoeglicht. 16 | * V 1.5: - Ueberlauf in millis() beruecksichtigt. 17 | * V 1.6: - Schalten gegen LOW ermoeglicht. 18 | * V 1.7: - Unterstuetzung fuer die alte Arduino-IDE (bis 1.0.6) entfernt. 19 | */ 20 | #include "Button.h" 21 | 22 | // #define DEBUG 23 | #include "Debug.h" 24 | 25 | #include "Configuration.h" 26 | 27 | /** 28 | * Initialisierung mit dem Pin, an dem der Taster haengt. 29 | * 30 | * @param pin: der Pin, an dem der Taster haengt 31 | * pressedAgainst: wogegen schaltet der Taster? (HIGH/LOW) 32 | */ 33 | Button::Button(byte pin, byte pressedAgainst, uint16_t debounceTime) { 34 | _pin1 = pin; 35 | _lastPressTime = 0; 36 | _doubleMode = false; 37 | _pressedAgainst = pressedAgainst; 38 | _debounceTime = debounceTime; 39 | if (_pressedAgainst == HIGH) { 40 | pinMode(_pin1, INPUT); 41 | } else { 42 | pinMode(_pin1, INPUT_PULLUP); 43 | } 44 | } 45 | 46 | /** 47 | * Initialisierung mit den zwei Pins, an denen die Taster haengen, die man gleichzeitig abfragen moechte. 48 | * 49 | * @param pin1, pin2: die Pins, an dem der virtuelle Taster haengt 50 | * pressedAgainst: wogegen schalten die Taster? (HIGH/LOW) 51 | */ 52 | Button::Button(byte pin1, byte pin2, byte pressedAgainst, uint16_t debounceTime) { 53 | _pin1 = pin1; 54 | _pin2 = pin2; 55 | _lastPressTime = 0; 56 | _doubleMode = true; 57 | _pressedAgainst = pressedAgainst; 58 | _debounceTime = debounceTime; 59 | if (_pressedAgainst == HIGH) { 60 | pinMode(_pin1, INPUT); 61 | pinMode(_pin2, INPUT); 62 | } else { 63 | pinMode(_pin1, INPUT_PULLUP); 64 | pinMode(_pin2, INPUT_PULLUP); 65 | } 66 | } 67 | 68 | /** 69 | * Wurde der Taster gedrueckt? 70 | */ 71 | boolean Button::pressed() { 72 | boolean _retVal = false; 73 | 74 | if (!_doubleMode) { 75 | if ((digitalRead(_pin1) == _pressedAgainst) && (millis() - _lastPressTime > _debounceTime)) { 76 | _lastPressTime = millis(); 77 | _retVal = true; 78 | } 79 | } else { 80 | if ((digitalRead(_pin1) == _pressedAgainst) && (digitalRead(_pin2) == _pressedAgainst) && (millis() - _lastPressTime > _debounceTime)) { 81 | _lastPressTime = millis(); 82 | _retVal = true; 83 | } 84 | } 85 | 86 | return _retVal; 87 | } 88 | 89 | /** 90 | * Ist der Taster aktuell gedrueckt? 91 | */ 92 | boolean Button::pressedRaw() { 93 | boolean _retVal = false; 94 | 95 | if (!_doubleMode) { 96 | if (digitalRead(_pin1) == _pressedAgainst) { 97 | _retVal = true; 98 | } 99 | } else { 100 | if ((digitalRead(_pin1) == _pressedAgainst) && (digitalRead(_pin2) == _pressedAgainst)) { 101 | _retVal = true; 102 | } 103 | } 104 | 105 | return _retVal; 106 | } 107 | -------------------------------------------------------------------------------- /Button.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Button 3 | * Kleine Klasse zum Entprellen der Tasten. 4 | * 5 | * @mc Arduino/RBBB 6 | * @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 7 | * @version 1.7 8 | * @created 18.2.2011 9 | * @updated 16.2.2015 10 | * 11 | * Versionshistorie: 12 | * V 1.1: - Kompatibilitaet zu Arduino-IDE 1.0 hergestellt. 13 | * V 1.2: - Optimierung hinsichtlich Speicherbedarf. 14 | * V 1.3: - Verbessertes Debugging. 15 | * V 1.4: - Doppel-Tasten-Abfrage ermoeglicht. 16 | * V 1.5: - Ueberlauf in millis() beruecksichtigt. 17 | * V 1.6: - Schalten gegen LOW ermoeglicht. 18 | * V 1.7: - Unterstuetzung fuer die alte Arduino-IDE (bis 1.0.6) entfernt. 19 | */ 20 | #ifndef BUTTON_H 21 | #define BUTTON_H 22 | 23 | #include "Arduino.h" 24 | 25 | class Button { 26 | public: 27 | Button(byte pin, byte pressedAgainst, uint16_t debounceTime = 300); 28 | Button(byte pin1, byte pin2, byte pressedAgainst, uint16_t debounceTime = 300); 29 | 30 | boolean pressed(); 31 | boolean pressedRaw(); 32 | 33 | private: 34 | byte _pin1; 35 | byte _pin2; 36 | boolean _doubleMode; 37 | byte _pressedAgainst; 38 | unsigned long _lastPressTime; 39 | uint16_t _debounceTime; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /Colors.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Colors.h 3 | ******************************************************************************/ 4 | 5 | #ifndef COLORS_H 6 | #define COLORS_H 7 | 8 | struct color_s { 9 | uint8_t red; 10 | uint8_t green; 11 | uint8_t blue; 12 | }; 13 | 14 | const color_s defaultColors[] = { 15 | {0xFF, 0xFF, 0xFF}, // 00 White 16 | {0xFF, 0x00, 0x00}, // 01 Red 17 | {0x00, 0xFF, 0x00}, // 02 Green 18 | {0x00, 0x00, 0xFF}, // 03 Blue 19 | {0x00, 0xFF, 0xFF}, // 04 Cyan 20 | {0xFF, 0x00, 0xFF}, // 05 Magenta 21 | {0xFF, 0xFF, 0x00}, // 06 Yellow 22 | {0x99, 0x66, 0xCC}, // 07 Amethyst 23 | {0x00, 0xFF, 0xFF}, // 08 Aqua 24 | {0x8A, 0x2B, 0xE2}, // 09 BlueViolet 25 | {0xA5, 0x2A, 0x2A}, // 10 Brown 26 | {0xDE, 0xB8, 0x87}, // 11 BurlyWood 27 | {0x5F, 0x9E, 0xA0}, // 12 CadetBlue 28 | {0xFF, 0x7F, 0x50}, // 13 Coral 29 | {0xDC, 0x14, 0x3C}, // 14 Crimson 30 | {0x22, 0x8B, 0x22}, // 15 ForestGreen 31 | {0xFF, 0xD7, 0x00}, // 16 Gold 32 | {0xDA, 0xA5, 0x20}, // 17 Goldenrod 33 | {0xAD, 0xFF, 0x2F}, // 18 GreenYellow 34 | {0xFF, 0x69, 0xB4}, // 19 HotPink 35 | {0xCD, 0x5C, 0x5C}, // 20 IndianRed 36 | {0x4B, 0x00, 0x82}, // 21 Indigo 37 | {0x7C, 0xFC, 0x00}, // 22 LawnGreen 38 | {0x80, 0x00, 0x00}, // 23 Maroon 39 | {0x19, 0x19, 0x70}, // 24 MidnightBlue 40 | {0xFF, 0xA5, 0x00}, // 25 Orange 41 | {0xFF, 0x45, 0x00}, // 26 OrangeRed 42 | {0xDA, 0x70, 0xD6}, // 27 Orchid 43 | {0xDB, 0x70, 0x93}, // 28 PaleVioletRed 44 | {0x80, 0x00, 0x80}, // 29 Purple 45 | {0x41, 0x69, 0xE1}, // 30 RoyalBlue 46 | {0x2E, 0x8B, 0x57}, // 31 SeaGreen 47 | {0x00, 0xFF, 0x7F}, // 32 SpringGreen 48 | {0x46, 0x82, 0xB4}, // 33 SteelBlue 49 | {0x00, 0x80, 0x80}, // 34 Teal 50 | {0x40, 0xE0, 0xD0}, // 35 Turquoise 51 | {0xEE, 0x82, 0xEE} // 36 Violet 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /Configuration.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Configuration.h 3 | 4 | D0 = NodeMCU_LED 5 | D1 = PIN_WIRE_SCL 6 | D2 = PIN_WIRE_SDA 7 | D3 = PIN_IR_RECEIVER 8 | D4 = ESP8266_LED 9 | D5 = PIN_BUZZER 10 | D6 = nc 11 | D7 = PIN_LEDS_CLOCK 12 | D8 = PIN_LEDS_DATA 13 | A0 = PIN_LDR 14 | 15 | ******************************************************************************/ 16 | 17 | #ifndef CONFIGURATION_H 18 | #define CONFIGURATION_H 19 | 20 | #define CONFIG_WIFIVE 21 | //#define CONFIG_WIFIVE_MINI 22 | 23 | /****************************************************************************** 24 | * 25 | *****************************************************************************/ 26 | #ifdef CONFIG_WIFIVE 27 | 28 | #define HOSTNAME "QlockWiFive" 29 | #define OTA_PASS "1234" 30 | #define NTP_SERVER "pool.ntp.org" 31 | 32 | //#define SYSLOG_SERVER "192.168.0.1" 33 | //#define SYSLOG_FACILITY LOG_LOCAL0 34 | //#define SYSLOG_PORT 514 35 | 36 | #define RTC_BACKUP 37 | #define RTC_TEMP_OFFSET 0 38 | 39 | // #define BOARD_LED 40 | 41 | //#define NONE_TECHNICAL_ZERO 42 | 43 | #define LDR 44 | 45 | #define MIN_BRIGHTNESS 10 46 | #define MAX_BRIGHTNESS 255 47 | 48 | //#define TIMEZONE_PST 49 | //#define TIMEZONE_MST 50 | //#define TIMEZONE_CST 51 | //#define TIMEZONE_EST 52 | //#define TIMEZONE_GMT 53 | #define TIMEZONE_CET 54 | //#define TIMEZONE_AEST 55 | 56 | //#define IR_LETTER_OFF 57 | 58 | #define IR_REMOTE 59 | 60 | // HX1838 Remote 61 | #define IR_CODE_ONOFF 16769565 62 | #define IR_CODE_TIME 16753245 63 | #define IR_CODE_MODE 16736925 64 | #define IR_CODE_EXTMODE 16748655 65 | #define IR_CODE_PLUS 16754775 66 | #define IR_CODE_MINUS 16769055 67 | 68 | // #define LED_LAYOUT_HORIZONTAL 69 | #define LED_LAYOUT_VERTICAL 70 | 71 | // #define LED_RGB 72 | #define LED_RGBW 73 | #define MATRIX_XXL 74 | 75 | // #define LED_DRIVER_APA102 76 | // #define LED_DRIVER_APA104 77 | // #define LED_DRIVER_APA106 78 | // #define LED_DRIVER_DOTSTAR 79 | // #define LED_DRIVER_GW6205 80 | // #define LED_DRIVER_GW6205_400 81 | // #define LED_DRIVER_LPD1886 82 | // #define LED_DRIVER_LPD1886_8BIT 83 | // #define LED_DRIVER_LPD8806 84 | // #define LED_DRIVER_NEOPIXEL 85 | // #define LED_DRIVER_P9813 86 | // #define LED_DRIVER_PL9823 87 | #define LED_DRIVER_SK6812 88 | // #define LED_DRIVER_SK6822 89 | // #define LED_DRIVER_SK9822 90 | // #define LED_DRIVER_SM16716 91 | // #define LED_DRIVER_TM1803 92 | // #define LED_DRIVER_TM1804 93 | // #define LED_DRIVER_TM1809 94 | // #define LED_DRIVER_TM1812 95 | // #define LED_DRIVER_TM1829 96 | // #define LED_DRIVER_UCS1903 97 | // #define LED_DRIVER_UCS1903B 98 | // #define LED_DRIVER_UCS1904 99 | // #define LED_DRIVER_UCS2903 100 | // #define LED_DRIVER_WS2801 101 | // #define LED_DRIVER_WS2803 102 | // #define LED_DRIVER_WS2811 103 | // #define LED_DRIVER_WS2811_400 104 | // #define LED_DRIVER_WS2812 105 | // #define LED_DRIVER_WS2812B 106 | // #define LED_DRIVER_WS2813 107 | // #define LED_DRIVER_WS2852 108 | 109 | #define PIN_IR_RECEIVER D4 110 | #define PIN_LED D6 111 | #define PIN_BUZZER D8 112 | #define PIN_LEDS_CLOCK D5 113 | #define PIN_LEDS_DATA D7 114 | #define PIN_LDR A0 115 | 116 | #define SERIAL_SPEED 115200 117 | //#define DEBUG 118 | //#define DEBUG_MATRIX 119 | //#define DEBUG_FPS 120 | 121 | #endif // CONFIG_WIFIVE 122 | 123 | #ifdef CONFIG_WIFIVE_MINI 124 | 125 | #define HOSTNAME "QlockWiFiveMini" 126 | #define OTA_PASS "1234" 127 | #define NTP_SERVER "pool.ntp.org" 128 | //#define RTC_BACKUP 129 | //#define RTC_TEMP_OFFSET -5 130 | #define LDR 131 | #define MIN_BRIGHTNESS 5 132 | #define MAX_BRIGHTNESS 255 133 | #define TIMEZONE_CET 134 | #define IR_LETTER_OFF 135 | #define IR_REMOTE 136 | #define IR_CODE_ONOFF 16769055 137 | #define IR_CODE_TIME 16752735 138 | #define IR_CODE_MODE 16720095 139 | #define IR_CODE_EXTMODE 16736415 140 | #define IR_CODE_PLUS 16734375 141 | #define IR_CODE_MINUS 16730295 142 | #define LED_LAYOUT_VERTICAL 143 | #define LED_RGB 144 | #define LED_DRIVER_NEOPIXEL 145 | //#define BOARD_LED 146 | #define PIN_IR_RECEIVER D6 147 | //#define PIN_LED D4 148 | #define PIN_BUZZER D8 149 | #define PIN_LEDS_DATA D7 150 | #define PIN_LDR A0 151 | #define BUTTONS 152 | /* 153 | * Die Zeit in Millisekunden, innerhalb derer Prellungen der Taster nicht als Druecken zaehlen. 154 | * (Und damit auch die Tastaturwiederholrate) 155 | * Default: 300 156 | */ 157 | #define BUTTONS_PRESSING_AGAINST LOW 158 | #define PIN_M_PLUS D0 159 | #define PIN_H_PLUS D5 160 | #define PIN_MODE D4 161 | #define SERIAL_SPEED 115200 162 | 163 | #endif // CONFIG_WIFIVE_MINI 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /Debug.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Debug.cpp 3 | ******************************************************************************/ 4 | 5 | #include "Debug.h" 6 | 7 | Debug::Debug() { 8 | } 9 | 10 | // Screenbuffer in die Konsole schreiben 11 | void Debug::debugScreenBuffer(word ScreenBuffer[]) { 12 | const char buchstabensalat[][17] = { 13 | {"ESKISTAFUNF2"}, 14 | {"ZEHNZWANZIG1"}, 15 | {"DREIVIERTEL4"}, 16 | {"VORFUNKNACH3"}, 17 | {"HALBAELFUNFA"}, 18 | {"EINSXAMZWEI_"}, 19 | {"DREIPMJVIER_"}, 20 | {"SECHSNLACHT_"}, 21 | {"SIEBENZWOLF_"}, 22 | {"ZEHNEUNKUHR_"} 23 | }; 24 | Serial.println("\033[0;0H"); // Set cursor to 0, 0 position in console 25 | Serial.println(" -----------"); 26 | for (uint8_t zeile = 0; zeile < 10; zeile++) { 27 | word leds = ScreenBuffer[zeile]; 28 | char spalte[16]; 29 | for (int8_t i = 15; i >= 0; i--) { 30 | spalte[i] = ((leds & 1) ? buchstabensalat[zeile][i] : ' '); 31 | leds = leds >> 1; 32 | } 33 | Serial.print('|'); 34 | for (uint8_t i = 0; i < 11; i++) Serial.print(spalte[i]); 35 | Serial.print('|'); 36 | Serial.println(spalte[11]); // Corner LEDs 37 | } 38 | Serial.println(" -----------"); 39 | } 40 | 41 | // Zeit in die Konsole schreiben 42 | void Debug::debugTime(String label, time_t time) { 43 | Serial.print(label); 44 | Serial.printf(" %02d:%02d:%02d %02d.%02d.%04d\n\r", hour(time), minute(time), second(time), day(time), month(time), year(time)); 45 | } 46 | 47 | void Debug::debugFps() { 48 | frames++; 49 | if (millis() - lastFpsCheck > 1000) { 50 | Serial.print("FPS: "); 51 | Serial.println(frames); 52 | lastFpsCheck = millis(); 53 | frames = 0; 54 | } 55 | } -------------------------------------------------------------------------------- /Debug.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Debug.h 3 | ******************************************************************************/ 4 | 5 | #ifndef DEBUG_H 6 | #define DEBUG_H 7 | 8 | #include 9 | #include 10 | 11 | #ifdef DEBUG 12 | #define DEBUG_PRINT(x) Serial.print(x) 13 | //#define DEBUG_PRINT2(x, y) Serial.print(x, y) 14 | #define DEBUG_PRINTLN(x) Serial.println(x) 15 | //#define DEBUG_PRINTLN2(x, y) Serial.println(x, y) 16 | #define DEBUG_FLUSH() Serial.flush() 17 | #else 18 | #define DEBUG_PRINT(x) 19 | #define DEBUG_PRINT2(x, y) 20 | #define DEBUG_PRINTLN(x) 21 | #define DEBUG_PRINTLN2(x, y) 22 | #define DEBUG_FLUSH() 23 | #endif 24 | 25 | class Debug { 26 | public: 27 | Debug(); 28 | void debugScreenBuffer(word ScreenBuffer[]); 29 | void debugTime(String label, time_t time); 30 | void debugFps(); 31 | 32 | private: 33 | uint16_t frames = 0; 34 | uint32_t lastFpsCheck = 0; 35 | }; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Languages.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Languages.h 3 | ******************************************************************************/ 4 | 5 | #ifndef LANGUAGES_H 6 | #define LANGUAGES_H 7 | 8 | const String sLanguage[] = { 9 | "DE", // 00 10 | "DESW", // 01 11 | "DEBA", // 02 12 | "DESA", // 03 13 | "MKDE", // 04 14 | "MKSW", // 05 15 | "MKBA", // 06 16 | "MKSA", // 07 17 | "D3", // 08 18 | "CH", // 09 19 | "CHGS", // 10 20 | "EN", // 11 21 | "ES", // 12 22 | "FR", // 13 23 | "IT", // 14 24 | "NL" // 15 25 | }; 26 | 27 | enum eLanguage : uint8_t { 28 | LANGUAGE_DE_DE, 29 | LANGUAGE_DE_SW, 30 | LANGUAGE_DE_BA, 31 | LANGUAGE_DE_SA, 32 | LANGUAGE_DE_MKF_DE, 33 | LANGUAGE_DE_MKF_SW, 34 | LANGUAGE_DE_MKF_BA, 35 | LANGUAGE_DE_MKF_SA, 36 | LANGUAGE_D3, 37 | LANGUAGE_CH, 38 | LANGUAGE_CH_GS, 39 | LANGUAGE_EN, 40 | LANGUAGE_ES, 41 | LANGUAGE_FR, 42 | LANGUAGE_IT, 43 | LANGUAGE_NL, 44 | LANGUAGE_COUNT 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /LedDriver.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | LedDriver.cpp 3 | ******************************************************************************/ 4 | 5 | #include "LedDriver.h" 6 | 7 | LedDriver::LedDriver() { 8 | #ifdef LED_DRIVER_NEOPIXEL 9 | FastLED.addLeds(leds, NUM_LEDS); 10 | #endif 11 | #ifdef LED_DRIVER_TM1803 12 | FastLED.addLeds(leds, NUM_LEDS); 13 | #endif 14 | #ifdef LED_DRIVER_TM1804 15 | FastLED.addLeds(leds, NUM_LEDS); 16 | #endif 17 | #ifdef LED_DRIVER_TM1809 18 | FastLED.addLeds(leds, NUM_LEDS); 19 | #endif 20 | #ifdef LED_DRIVER_WS2811 21 | FastLED.addLeds(leds, NUM_LEDS); 22 | #endif 23 | #ifdef LED_DRIVER_WS2812 24 | FastLED.addLeds(leds, NUM_LEDS); 25 | #endif 26 | #ifdef LED_DRIVER_WS2812B 27 | FastLED.addLeds(leds, NUM_LEDS); 28 | #endif 29 | #ifdef LED_DRIVER_APA104 30 | FastLED.addLeds(leds, NUM_LEDS); 31 | #endif 32 | #ifdef LED_DRIVER_UCS1903 33 | FastLED.addLeds(leds, NUM_LEDS); 34 | #endif 35 | #ifdef LED_DRIVER_UCS1903B 36 | FastLED.addLeds(leds, NUM_LEDS); 37 | #endif 38 | #ifdef LED_DRIVER_GW6205 39 | FastLED.addLeds(leds, NUM_LEDS); 40 | #endif 41 | #ifdef LED_DRIVER_GW6205_400 42 | FastLED.addLeds(leds, NUM_LEDS); 43 | #endif 44 | #ifdef LED_DRIVER_WS2801 45 | FastLED.addLeds(leds, NUM_LEDS); 46 | #endif 47 | #ifdef LED_DRIVER_SM16716 48 | FastLED.addLeds(leds, NUM_LEDS); 49 | #endif 50 | #ifdef LED_DRIVER_LPD8806 51 | FastLED.addLeds(leds, NUM_LEDS); 52 | #endif 53 | #ifdef LED_DRIVER_P9813 54 | FastLED.addLeds(leds, NUM_LEDS); 55 | #endif 56 | #ifdef LED_DRIVER_APA102 57 | FastLED.addLeds(leds, NUM_LEDS); 58 | #endif 59 | #ifdef LED_DRIVER_DOTSTAR 60 | FastLED.addLeds(leds, NUM_LEDS); 61 | #endif 62 | #ifdef LED_DRIVER_SK9822 63 | FastLED.addLeds(leds, NUM_LEDS); 64 | #endif 65 | #ifdef LED_DRIVER_SK6822 66 | FastLED.addLeds(leds, NUM_LEDS); 67 | #endif 68 | #ifdef LED_DRIVER_SK6812 69 | FastLED.addLeds(leds, NUM_LEDS); 70 | #endif 71 | #ifdef LED_DRIVER_TM1829 72 | FastLED.addLeds(leds, NUM_LEDS); 73 | #endif 74 | #ifdef LED_DRIVER_UCS2903 75 | FastLED.addLeds(leds, NUM_LEDS); 76 | #endif 77 | #ifdef LED_DRIVER_UCS1904 78 | FastLED.addLeds(leds, NUM_LEDS); 79 | #endif 80 | #ifdef LED_DRIVER_PL9823 81 | FastLED.addLeds(leds, NUM_LEDS); 82 | #endif 83 | #ifdef LED_DRIVER_TM1812 84 | FastLED.addLeds(leds, NUM_LEDS); 85 | #endif 86 | #ifdef LED_DRIVER_WS2852 87 | FastLED.addLeds(leds, NUM_LEDS); 88 | #endif 89 | #ifdef LED_DRIVER_APA106 90 | FastLED.addLeds(leds, NUM_LEDS); 91 | #endif 92 | #ifdef LED_DRIVER_WS2813 93 | FastLED.addLeds(leds, NUM_LEDS); 94 | #endif 95 | #ifdef LED_DRIVER_WS2811_400 96 | FastLED.addLeds(leds, NUM_LEDS); 97 | #endif 98 | #ifdef LED_DRIVER_LPD1886 99 | FastLED.addLeds(leds, NUM_LEDS); 100 | #endif 101 | #ifdef LED_DRIVER_LPD1886_8BIT 102 | FastLED.addLeds(leds, NUM_LEDS); 103 | #endif 104 | #ifdef LED_DRIVER_DMXSIMPLE 105 | FastLED.addLeds(leds, NUM_LEDS); 106 | #endif 107 | #ifdef LED_DRIVER_WS2803 108 | FastLED.addLeds(leds, NUM_LEDS); 109 | #endif 110 | } 111 | 112 | void LedDriver::writeScreenBufferToLEDs(word matrix[16], uint8_t color) { 113 | FastLED.clear(); 114 | for (uint8_t y = 0; y < 10; y++) { 115 | for (uint8_t x = 5; x < 16; x++) { 116 | word t = 1 << x; 117 | if ((matrix[y] & t) == t) setPixel(15 - x, y, color); 118 | } 119 | } 120 | byte cornerLedCount[] = { 1, 0, 3, 2, 4 }; 121 | for (uint8_t i = 0; i < 5; i++) if ((matrix[cornerLedCount[i]] & 0b0000000000010000) > 0) setPixel(110 + i, color); 122 | FastLED.show(); 123 | } 124 | 125 | void LedDriver::setPixel(uint8_t x, uint8_t y, uint8_t color) { 126 | #ifdef LED_LAYOUT_HORIZONTAL 127 | setPixel(x + (y * 11), color); 128 | #endif 129 | #ifdef LED_LAYOUT_VERTICAL 130 | setPixel(y + (x * 10), color); 131 | #endif 132 | } 133 | 134 | void LedDriver::setPixel(uint8_t num, uint8_t color) { 135 | #if defined(LED_DRIVER_LPD8806) && defined(LED_RGBW) 136 | uint8_t red = defaultColors[color].red; 137 | uint8_t green = defaultColors[color].green; 138 | uint8_t blue = defaultColors[color].blue; 139 | uint8_t white = getWhite(red, green, blue); 140 | red -= white; 141 | green -= white; 142 | blue -= white; 143 | uint32_t ledColor_wbg = white * 0x010000 + blue * 0x000100 + green; 144 | uint32_t ledColor_r = red * 0x010000; 145 | #else 146 | uint8_t red = defaultColors[color].red; 147 | uint8_t green = defaultColors[color].green; 148 | uint8_t blue = defaultColors[color].blue; 149 | uint32_t ledColor_rgb = (red << 16) + (green << 8) + blue; 150 | #endif 151 | 152 | #ifdef CONFIG_WIFIVE 153 | #if defined(LED_RGBW) 154 | #ifdef LED_DRIVER_LPD8806 155 | uint8_t ledNum; 156 | if (num < 110) { 157 | if ((num / 10) % 2 == 0) { 158 | leds[num * 2] = ledColor_wbg; 159 | leds[num * 2 + 1] = ledColor_r; 160 | } 161 | else { 162 | leds[(((num / 10) * 10) + 9 - (num % 10)) * 2] = ledColor_wbg; 163 | leds[(((num / 10) * 10) + 9 - (num % 10)) * 2 + 1] = ledColor_r; 164 | } 165 | } 166 | else { 167 | switch (num) { 168 | case 110: 169 | leds[112 * 2] = ledColor_wbg; 170 | leds[112 * 2 + 1] = ledColor_r; 171 | break; 172 | case 111: 173 | leds[111 * 2] = ledColor_wbg; 174 | leds[111 * 2 + 1] = ledColor_r; 175 | break; 176 | case 112: 177 | leds[110 * 2] = ledColor_wbg; 178 | leds[110 * 2 + 1] = ledColor_r; 179 | break; 180 | case 113: 181 | leds[113 * 2] = ledColor_wbg; 182 | leds[113 * 2 + 1] = ledColor_r; 183 | break; 184 | case 114: 185 | leds[114 * 2] = ledColor_wbg; 186 | leds[114 * 2 + 1] = ledColor_r; 187 | break; 188 | default: 189 | break; 190 | } 191 | } 192 | #else // LED_DRIVER_LPD8806 193 | 194 | #endif // LED_DRIVER_LPD8806 195 | #else // LED_RGBW 196 | #ifdef MATRIX_XXL 197 | if (num < 110) { 198 | if ((num / 10) % 2 == 0) { 199 | leds[num * 2] = ledColor_rgb; 200 | leds[num * 2 + 1] = ledColor_rgb; 201 | } 202 | else { 203 | leds[(((num / 10) * 10) + 9 - (num % 10)) * 2] = ledColor_rgb; 204 | leds[(((num / 10) * 10) + 9 - (num % 10)) * 2 + 1] = ledColor_rgb; 205 | } 206 | } 207 | else { 208 | switch (num) { 209 | case 110: 210 | leds[222] = ledColor_rgb; 211 | break; 212 | case 111: 213 | leds[221] = ledColor_rgb; 214 | break; 215 | case 112: 216 | leds[220] = ledColor_rgb; 217 | break; 218 | case 113: 219 | leds[223] = ledColor_rgb; 220 | break; 221 | case 114: 222 | leds[224] = ledColor_rgb; 223 | break; 224 | default: 225 | break; 226 | } 227 | } 228 | #else 229 | if (num < 110) { 230 | if ((num / 10) % 2 == 0) { 231 | leds[num] = ledColor_rgb; 232 | } 233 | else { 234 | leds[((num / 10) * 10) + 9 - (num % 10)] = ledColor_rgb; 235 | } 236 | } 237 | else { 238 | switch (num) { 239 | case 110: 240 | leds[112] = ledColor_rgb; 241 | break; 242 | case 111: 243 | leds[111] = ledColor_rgb; 244 | break; 245 | case 112: 246 | leds[110] = ledColor_rgb; 247 | break; 248 | case 113: 249 | leds[113] = ledColor_rgb; 250 | break; 251 | case 114: 252 | leds[114] = ledColor_rgb; 253 | break; 254 | default: 255 | break; 256 | } 257 | } 258 | #endif 259 | #endif // LED_RGBW 260 | #endif 261 | 262 | 263 | #ifdef CONFIG_WIFIVE_MINI 264 | byte ledNum; 265 | if (num < 110) { 266 | if ((num / 10) % 2 == 0) { 267 | ledNum = num; 268 | } else { 269 | ledNum = ((num / 10) * 10) + 9 - (num % 10); 270 | } 271 | if (ledNum < 10) 272 | { 273 | leds[ledNum + 1] = ledColor_rgb; 274 | } 275 | else if (ledNum < 60) 276 | { 277 | leds[ledNum + 2] = ledColor_rgb; 278 | } 279 | else if (ledNum < 100) 280 | { 281 | leds[ledNum + 3] = ledColor_rgb; 282 | } 283 | else 284 | { 285 | leds[ledNum + 4] = ledColor_rgb; 286 | } 287 | } else { 288 | switch (num) { 289 | case 110: 290 | leds[0] = ledColor_rgb; 291 | break; 292 | case 111: 293 | leds[103] = ledColor_rgb; 294 | break; 295 | case 112: 296 | leds[114] = ledColor_rgb; 297 | break; 298 | case 113: 299 | leds[11] = ledColor_rgb; 300 | break; 301 | case 114: 302 | leds[62] = ledColor_rgb; 303 | break; 304 | default: 305 | ; 306 | } 307 | } 308 | #endif 309 | 310 | //#ifdef LED_LAYOUT_HORIZONTAL 311 | //#if defined(LED_DRIVER_LPD8806) && defined(LED_RGBW) 312 | // if (num < 110) { 313 | // if ((num / 11) % 2 == 0) { 314 | // leds[num * 2] = ledColor_wbg; 315 | // leds[num * 2 + 1] = ledColor_r; 316 | // } 317 | // else { 318 | // leds[(((num / 11) * 11) + 10 - (num % 11)) * 2] = ledColor_wbg; 319 | // leds[(((num / 11) * 11) + 10 - (num % 11)) * 2 + 1] = ledColor_r; 320 | // } 321 | // } 322 | // else { 323 | // switch (num) { 324 | // case 110: 325 | // leds[111 * 2] = ledColor_wbg; 326 | // leds[111 * 2 + 1] = ledColor_r; 327 | // break; 328 | // case 111: 329 | // leds[112 * 2] = ledColor_wbg; 330 | // leds[112 * 2 + 1] = ledColor_r; 331 | // break; 332 | // case 112: 333 | // leds[113 * 2] = ledColor_wbg; 334 | // leds[113 * 2 + 1] = ledColor_r; 335 | // break; 336 | // case 113: 337 | // leds[110 * 2] = ledColor_wbg; 338 | // leds[110 * 2 + 1] = ledColor_r; 339 | // break; 340 | // case 114: 341 | // leds[114 * 2] = ledColor_wbg; 342 | // leds[114 * 2 + 1] = ledColor_r; 343 | // break; 344 | // default: 345 | // break; 346 | // } 347 | // } 348 | //#else 349 | // if (num < 110) { 350 | // if ((num / 11) % 2 == 0) leds[num] = ledColor_rgb; 351 | // else leds[((num / 11) * 11) + 10 - (num % 11)] = ledColor_rgb; 352 | // } 353 | // else { 354 | // switch (num) { 355 | // case 110: 356 | // leds[111] = ledColor_rgb; 357 | // break; 358 | // case 111: 359 | // leds[112] = ledColor_rgb; 360 | // break; 361 | // case 112: 362 | // leds[113] = ledColor_rgb; 363 | // break; 364 | // case 113: 365 | // leds[110] = ledColor_rgb; 366 | // break; 367 | // case 114: 368 | // leds[114] = ledColor_rgb; 369 | // break; 370 | // default: 371 | // break; 372 | // } 373 | // } 374 | //#endif // LED_RGB 375 | //#endif // LED_LAYOUT_HORIZONTAL 376 | // 377 | //#ifdef LED_LAYOUT_VERTICAL 378 | //#if defined(LED_DRIVER_LPD8806) && defined(LED_RGBW) 379 | // uint8_t ledNum; 380 | // if (num < 110) { 381 | // if ((num / 10) % 2 == 0) ledNum = num; 382 | // else ledNum = ((num / 10) * 10) + 9 - (num % 10); 383 | // if (ledNum < 10) { 384 | // leds[(ledNum + 1) * 2] = ledColor_wbg; 385 | // leds[(ledNum + 1) * 2 + 1] = ledColor_r; 386 | // } 387 | // else { 388 | // if (ledNum < 100) { 389 | // leds[(ledNum + 2) * 2] = ledColor_wbg; 390 | // leds[(ledNum + 2) * 2 + 1] = ledColor_r; 391 | // } 392 | // else { 393 | // leds[(ledNum + 3) * 2] = ledColor_wbg; 394 | // leds[(ledNum + 3) * 2 + 1] = ledColor_r; 395 | // } 396 | // } 397 | // } 398 | // else { 399 | // switch (num) { 400 | // case 110: 401 | // leds[0 * 2] = ledColor_wbg; 402 | // leds[0 * 2 + 1] = ledColor_r; 403 | // break; 404 | // case 111: 405 | // leds[102 * 2] = ledColor_wbg; 406 | // leds[102 * 2 + 1] = ledColor_r; 407 | // break; 408 | // case 112: 409 | // leds[113 * 2] = ledColor_wbg; 410 | // leds[113 * 2 + 1] = ledColor_r; 411 | // break; 412 | // case 113: 413 | // leds[11 * 2] = ledColor_wbg; 414 | // leds[11 * 2 + 1] = ledColor_r; 415 | // break; 416 | // case 114: 417 | // leds[114 * 2] = ledColor_wbg; 418 | // leds[114 * 2 + 1] = ledColor_r; 419 | // break; 420 | // default: 421 | // break; 422 | // } 423 | // } 424 | //#else 425 | // uint8_t ledNum; 426 | // if (num < 110) { 427 | // if ((num / 10) % 2 == 0) ledNum = num; 428 | // else ledNum = ((num / 10) * 10) + 9 - (num % 10); 429 | // if (ledNum < 10) leds[ledNum + 1] = ledColor_rgb; 430 | // else if (ledNum < 100) leds[ledNum + 2] = ledColor_rgb; 431 | // else leds[ledNum + 3] = ledColor_rgb; 432 | // } 433 | // else { 434 | // switch (num) { 435 | // case 110: 436 | // leds[0] = ledColor_rgb; 437 | // break; 438 | // case 111: 439 | // leds[102] = ledColor_rgb; 440 | // break; 441 | // case 112: 442 | // leds[113] = ledColor_rgb; 443 | // break; 444 | // case 113: 445 | // leds[11] = ledColor_rgb; 446 | // break; 447 | // case 114: 448 | // leds[114] = ledColor_rgb; 449 | // break; 450 | // default: 451 | // break; 452 | // } 453 | // } 454 | //#endif // LED_RGB 455 | // 456 | //#endif // LED_LAYOUT_VERTICAL 457 | } 458 | 459 | void LedDriver::clear() { 460 | FastLED.clear(); 461 | } 462 | 463 | void LedDriver::setBrightness(uint8_t ledBrightness) { 464 | FastLED.setBrightness(ledBrightness); 465 | } 466 | 467 | void LedDriver::getBrightness() { 468 | FastLED.getBrightness(); 469 | } 470 | 471 | void LedDriver::show() { 472 | FastLED.show(); 473 | } 474 | 475 | // Calculate white 476 | uint8_t LedDriver::getWhite(uint8_t red, uint8_t green, uint8_t blue) { 477 | uint8_t low = min(red, min(green, blue)); 478 | uint8_t high = max(red, max(green, blue)); 479 | uint8_t saturation = round(100 * ((high - low) / high)); 480 | return (255 - saturation) / 255 * (red + green + blue) / 3; 481 | } 482 | -------------------------------------------------------------------------------- /LedDriver.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | LedDriver.h 3 | ******************************************************************************/ 4 | 5 | #ifndef LEDDRIVER_H 6 | #define LEDDRIVER_H 7 | 8 | #define FASTLED_ESP8266_RAW_PIN_ORDER 9 | #include 10 | 11 | #include 12 | #include "Colors.h" 13 | #include "Configuration.h" 14 | 15 | #ifdef LED_RGB 16 | #ifdef MATRIX_XXL 17 | #define NUM_LEDS 225 18 | #else 19 | #define NUM_LEDS 115 20 | #endif 21 | #endif 22 | 23 | #ifdef LED_RGBW 24 | #ifdef LED_DRIVER_LPD8806 25 | #ifdef MATRIX_XXL 26 | #define NUM_LEDS 460 27 | #else 28 | #define NUM_LEDS 230 29 | #endif 30 | #else 31 | #ifdef MATRIX_XXL 32 | #define NUM_LEDS 225 33 | #else 34 | #define NUM_LEDS 115 35 | #endif 36 | #endif 37 | #endif 38 | 39 | class LedDriver { 40 | public: 41 | LedDriver(); 42 | void writeScreenBufferToLEDs(word matrix[16], uint8_t color); 43 | void clear(); 44 | void setBrightness(uint8_t ledBrightness); 45 | void getBrightness(); 46 | void show(); 47 | void setPixel(uint8_t num, uint8_t color); 48 | 49 | private: 50 | void setPixel(uint8_t x, uint8_t y, uint8_t color); 51 | uint8_t getWhite(uint8_t red, uint8_t green, uint8_t blue); 52 | CRGB leds[NUM_LEDS]; 53 | 54 | }; 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /LedDriverBase.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * LedDriverBase 3 | * Abstrakte Klasse fuer einen LED-Treiber. Hiervon koennen andere Implementierungen 4 | * erben (75HC595, MAX7219, AS1130 etc.) 5 | * 6 | * @mc Arduino/RBBB 7 | * @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 8 | * @version 1.5 9 | * @created 18.1.2013 10 | * @updated 16.2.2015 11 | * 12 | * Versionshistorie: 13 | * V 1.0: - Erstellt. 14 | * V 1.1: - printSignature() eingefuehrt. 15 | * V 1.2: - Setzen und lesen von Pixel eingefuehrt. 16 | * V 1.3: - Anpassung auf Helligkeit in Prozent. 17 | * V 1.4: - Getter fuer Helligkeit eingefuehrt. 18 | * V 1.5: - Unterstuetzung fuer die alte Arduino-IDE (bis 1.0.6) entfernt. 19 | */ 20 | #include "LedDriverBase.h" 21 | 22 | void LedDriverBase::setColor(byte red, byte green, byte blue) { 23 | _red = red; 24 | _green = green; 25 | _blue = blue; 26 | } 27 | 28 | byte LedDriverBase::getRed() { 29 | return _red; 30 | } 31 | 32 | byte LedDriverBase::getGreen() { 33 | return _green; 34 | } 35 | 36 | byte LedDriverBase::getBlue() { 37 | return _blue; 38 | } 39 | 40 | void LedDriverBase::setPixelInScreenBuffer(byte x, byte y, word matrix[16]) { 41 | matrix[y] |= 0b1000000000000000 >> x; 42 | } 43 | 44 | boolean LedDriverBase::getPixelFromScreenBuffer(byte x, byte y, word matrix[16]) { 45 | return (matrix[y] & (0b1000000000000000 >> x)) == (0b1000000000000000 >> x); 46 | } 47 | -------------------------------------------------------------------------------- /LedDriverBase.h: -------------------------------------------------------------------------------- 1 | /** 2 | * LedDriver 3 | * Abstrakte Klasse fuer einen LED-Treiber. Hiervon koennen andere Implementierungen 4 | * erben (75HC595, MAX7219, AS1130 etc.) 5 | * 6 | * @mc Arduino/RBBB 7 | * @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 8 | * @version 1.5 9 | * @created 18.1.2013 10 | * @updated 16.2.2015 11 | * 12 | * Versionshistorie: 13 | * V 1.0: - Erstellt. 14 | * V 1.1: - printSignature() eingefuehrt. 15 | * V 1.2: - Setzen und lesen von Pixel eingefuehrt. 16 | * V 1.3: - Anpassung auf Helligkeit in Prozent. 17 | * V 1.4: - Getter fuer Helligkeit eingefuehrt. 18 | * V 1.5: - Unterstuetzung fuer die alte Arduino-IDE (bis 1.0.6) entfernt. 19 | */ 20 | #ifndef LEDDRIVER_H 21 | #define LEDDRIVER_H 22 | 23 | #include "Arduino.h" 24 | 25 | class LedDriverBase { 26 | public: 27 | virtual void init(); 28 | 29 | virtual void printSignature(); 30 | 31 | virtual void writeScreenBufferToLEDs(word matrix[16], uint8_t color); 32 | 33 | virtual void setBrightness(byte brightness); 34 | virtual byte getBrightness(); 35 | 36 | void setColor(byte red, byte green, byte blue); 37 | byte getRed(); 38 | byte getGreen(); 39 | byte getBlue(); 40 | 41 | virtual void setLinesToWrite(byte linesToWrite); 42 | 43 | virtual void shutDown(); 44 | virtual void wakeUp(); 45 | 46 | virtual void clearData(); 47 | 48 | void setPixelInScreenBuffer(byte x, byte y, word matrix[16]); 49 | boolean getPixelFromScreenBuffer(byte x, byte y, word matrix[16]); 50 | 51 | private: 52 | byte _red, _green, _blue; 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /LedDriverNeoPixel.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * LedDriverNeoPixel 3 | * Implementierung auf der Basis von WS2812B-Streifen wie sie die Adafruit-Neo-Pixel verwenden. 4 | * 5 | * Es lohnt sich in jedem Fall, den UeberGuide von Adafruit zu lesen: 6 | * https://learn.adafruit.com/adafruit-neopixel-uberguide/overview 7 | * 8 | * @mc Arduino/RBBB 9 | * @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 10 | * @version 1.2 11 | * @created 5.1.2015 12 | * @updated 16.2.2015 13 | * 14 | * Versionshistorie: 15 | * V 1.0: - Erstellt. 16 | * V 1.1: - Getter fuer Helligkeit nachgezogen. 17 | * V 1.2: - Unterstuetzung fuer die alte Arduino-IDE (bis 1.0.6) entfernt. 18 | * 19 | * Verkabelung: Einspeisung oben links, dann schlangenfoermig runter, 20 | * dann Ecke unten links, oben links, oben rechts, unten rechts. 21 | * 22 | */ 23 | #include "LedDriverNeoPixel.h" 24 | #include "Configuration.h" 25 | 26 | // #define DEBUG 27 | #include "Debug.h" 28 | 29 | #ifdef MATRIX_XXL 30 | #define NUM_PIXEL 225 31 | #else 32 | #define NUM_PIXEL 114 33 | #endif 34 | 35 | /** 36 | * Initialisierung. 37 | * 38 | * @param data Pin, an dem die Data-Line haengt. 39 | */ 40 | LedDriverNeoPixel::LedDriverNeoPixel(byte dataPin) { 41 | _dataPin = dataPin; 42 | _strip = new Adafruit_NeoPixel(NUM_PIXEL, _dataPin, NEO_GRBW + NEO_KHZ800); 43 | _strip->begin(); 44 | setColor(250, 255, 200); 45 | } 46 | 47 | /** 48 | * init() wird im Hauptprogramm in init() aufgerufen. 49 | * Hier sollten die LED-Treiber in eine definierten 50 | * Ausgangszustand gebracht werden. 51 | */ 52 | void LedDriverNeoPixel::init() { 53 | setBrightness(50); 54 | clearData(); 55 | wakeUp(); 56 | } 57 | 58 | void LedDriverNeoPixel::printSignature() { 59 | Serial.println(F("NeoPixel - WS2812B")); 60 | } 61 | 62 | /** 63 | * Den Bildschirm-Puffer auf die LED-Matrix schreiben. 64 | * 65 | * @param onChange: TRUE, wenn es Aenderungen in dem Bildschirm-Puffer gab, 66 | * FALSE, wenn es ein Refresh-Aufruf war. 67 | */ 68 | void LedDriverNeoPixel::writeScreenBufferToLEDs(word matrix[16], uint8_t color) { 69 | _strip->clear(); 70 | 71 | for (byte y = 0; y < 10; y++) { 72 | for (byte x = 5; x < 16; x++) { 73 | word t = 1 << x; 74 | if ((matrix[y] & t) == t) { 75 | _setPixel(15 - x, y, color); 76 | } 77 | } 78 | } 79 | 80 | byte cornerLedCount[] = { 1, 0, 3, 2, 4 }; 81 | for (uint8_t i = 0; i < 5; i++) if ((matrix[cornerLedCount[i]] & 0b0000000000010000) > 0) _setPixel(110 + i, color); 82 | 83 | _strip->show(); 84 | } 85 | 86 | /** 87 | * Die Helligkeit des Displays anpassen. 88 | * 89 | * @param brightnessInPercent Die Helligkeit. 90 | */ 91 | void LedDriverNeoPixel::setBrightness(byte brightness) { 92 | if (brightness != _brightness) { 93 | _brightness = brightness; 94 | } 95 | } 96 | 97 | /** 98 | * Die aktuelle Helligkeit bekommen. 99 | */ 100 | byte LedDriverNeoPixel::getBrightness() { 101 | return _brightness; 102 | } 103 | 104 | /** 105 | * Anpassung der Groesse des Bildspeichers. 106 | * 107 | * @param linesToWrite Wieviel Zeilen aus dem Bildspeicher sollen 108 | * geschrieben werden? 109 | */ 110 | void LedDriverNeoPixel::setLinesToWrite(byte linesToWrite) { 111 | } 112 | 113 | /** 114 | * Das Display ausschalten. 115 | */ 116 | void LedDriverNeoPixel::shutDown() { 117 | _strip->clear(); 118 | _strip->show(); 119 | } 120 | 121 | /** 122 | * Das Display einschalten. 123 | */ 124 | void LedDriverNeoPixel::wakeUp() { 125 | } 126 | 127 | /** 128 | * Den Dateninhalt des LED-Treibers loeschen. 129 | */ 130 | void LedDriverNeoPixel::clearData() { 131 | _strip->clear(); 132 | _strip->show(); 133 | } 134 | 135 | /** 136 | * Einen X/Y-koordinierten Pixel in der Matrix setzen. 137 | */ 138 | void LedDriverNeoPixel::_setPixel(byte x, byte y, uint32_t c) { 139 | #ifdef LED_LAYOUT_HORIZONTAL 140 | _setPixel(x + (y * 11), c); 141 | #endif 142 | #ifdef LED_LAYOUT_VERTICAL 143 | _setPixel(y + (x * 10), c); 144 | #endif 145 | } 146 | 147 | /** 148 | * Einen Pixel im Streifen setzten (die Eck-LEDs sind am Ende). 149 | */ 150 | void LedDriverNeoPixel::_setPixel(byte num, uint8_t color) { 151 | uint8_t red = defaultColors[color].red; 152 | uint8_t green = defaultColors[color].green; 153 | uint8_t blue = defaultColors[color].blue; 154 | uint32_t c = _strip->Color(_brightnessScaleColor(red), _brightnessScaleColor(green), _brightnessScaleColor(blue)); 155 | 156 | #ifdef MATRIX_XXL 157 | uint16_t ledNum; 158 | if (num < 110) { 159 | if ((num / 10) % 2 == 0) { 160 | ledNum = num * 2; 161 | _strip->setPixelColor(ledNum, c); 162 | ledNum++; 163 | _strip->setPixelColor(ledNum, c); 164 | } 165 | else { 166 | ledNum = (((num / 10) * 10) + 9 - (num % 10)) * 2; 167 | _strip->setPixelColor(ledNum, c); 168 | ledNum++; 169 | _strip->setPixelColor(ledNum, c); 170 | } 171 | } 172 | else { 173 | switch (num) { 174 | case 110: 175 | _strip->setPixelColor(222, c); 176 | break; 177 | case 111: 178 | _strip->setPixelColor(221, c); 179 | break; 180 | case 112: 181 | _strip->setPixelColor(220, c); 182 | break; 183 | case 113: 184 | _strip->setPixelColor(223, c); 185 | break; 186 | case 114: 187 | _strip->setPixelColor(224, c); 188 | break; 189 | default: 190 | break; 191 | } 192 | } 193 | #else 194 | if (num < 110) { 195 | if ((num / 11) % 2 == 0) { 196 | _strip->setPixelColor(num, c); 197 | } else { 198 | _strip->setPixelColor(((num / 11) * 11) + 10 - (num % 11), c); 199 | } 200 | } else { 201 | switch (num) { 202 | case 110: 203 | _strip->setPixelColor(111, c); 204 | break; 205 | case 111: 206 | _strip->setPixelColor(112, c); 207 | break; 208 | case 112: 209 | _strip->setPixelColor(113, c); 210 | break; 211 | case 113: 212 | _strip->setPixelColor(110, c); 213 | break; 214 | } 215 | } 216 | #endif 217 | } 218 | 219 | /** 220 | * Funktion fuer saubere 'Regenbogen'-Farben. 221 | * Kopiert aus den Adafruit-Beispielen (strand). 222 | */ 223 | uint32_t LedDriverNeoPixel::_wheel(byte wheelPos) { 224 | if (wheelPos < 85) { 225 | return _strip->Color(wheelPos * 3, 255 - wheelPos * 3, 0); 226 | } else if (wheelPos < 170) { 227 | wheelPos -= 85; 228 | return _strip->Color(255 - wheelPos * 3, 0, wheelPos * 3); 229 | } else { 230 | wheelPos -= 170; 231 | return _strip->Color(0, wheelPos * 3, 255 - wheelPos * 3); 232 | } 233 | } 234 | 235 | /** 236 | * Hilfsfunktion fuer das Skalieren der Farben. 237 | */ 238 | byte LedDriverNeoPixel::_brightnessScaleColor(byte colorPart) { 239 | return map(_brightness, 0, 255, 0, colorPart); 240 | } 241 | 242 | void LedDriverNeoPixel::show() { 243 | _strip->show(); 244 | } 245 | -------------------------------------------------------------------------------- /LedDriverNeoPixel.h: -------------------------------------------------------------------------------- 1 | /** 2 | * LedDriverNeoPixel 3 | * Implementierung auf der Basis von WS2812B-Streifen wie sie die Adafruit-Neo-Pixel verwenden. 4 | * 5 | * Es lohnt sich in jedem Fall, den UeberGuide von Adafruit zu lesen: 6 | * https://learn.adafruit.com/adafruit-neopixel-uberguide/overview 7 | * 8 | * @mc Arduino/RBBB 9 | * @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 10 | * @version 1.2 11 | * @created 5.1.2015 12 | * @updated 16.2.2015 13 | * 14 | * Versionshistorie: 15 | * V 1.0: - Erstellt. 16 | * V 1.1: - Getter fuer Helligkeit nachgezogen. 17 | * V 1.2: - Unterstuetzung fuer die alte Arduino-IDE (bis 1.0.6) entfernt. 18 | * 19 | * Verkabelung: Einspeisung oben links, dann schlangenfoermig runter, 20 | * dann Ecke unten links, oben links, oben rechts, unten rechts. 21 | * 22 | */ 23 | #ifndef LED_DRIVER_NEOPIXEL_H 24 | #define LED_DRIVER_NEOPIXEL_H 25 | 26 | #include "Arduino.h" 27 | #include "LedDriverBase.h" 28 | #include "Colors.h" 29 | #include 30 | 31 | class LedDriverNeoPixel : public LedDriverBase { 32 | public: 33 | LedDriverNeoPixel(byte dataPin); 34 | 35 | void init(); 36 | 37 | void printSignature(); 38 | 39 | void writeScreenBufferToLEDs(word matrix[16], uint8_t color); 40 | 41 | void setBrightness(byte brightness); 42 | byte getBrightness(); 43 | 44 | void setLinesToWrite(byte linesToWrite); 45 | 46 | void shutDown(); 47 | void wakeUp(); 48 | 49 | void show(); 50 | 51 | void clearData(); 52 | 53 | private: 54 | byte _brightness; 55 | 56 | void _setPixel(byte x, byte y, uint32_t c); 57 | void _setPixel(byte num, uint8_t color); 58 | 59 | uint32_t _wheel(byte wheelPos); 60 | 61 | byte _brightnessScaleColor(byte colorPart); 62 | 63 | byte _dataPin; 64 | Adafruit_NeoPixel *_strip; 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /Modes.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Modes.h 3 | ******************************************************************************/ 4 | 5 | #ifndef MODES_H 6 | #define MODES_H 7 | 8 | #include 9 | #include "Configuration.h" 10 | 11 | typedef enum eMode : uint8_t { 12 | STD_MODE_NORMAL, 13 | STD_MODE_AMPM, 14 | STD_MODE_SECONDS, 15 | STD_MODE_DATE, 16 | #ifdef RTC_BACKUP 17 | STD_MODE_TEMP, 18 | #endif 19 | STD_MODE_SET_TIMER, 20 | STD_MODE_TIMER, 21 | STD_MODE_ALARM_1, 22 | STD_MODE_SET_ALARM_1, 23 | STD_MODE_ALARM_2, 24 | STD_MODE_SET_ALARM_2, 25 | STD_MODE_BLANK, 26 | STD_MODE_COUNT, 27 | EXT_MODE_START, 28 | EXT_MODE_TEXT_MAIN = EXT_MODE_START, 29 | #ifdef LDR 30 | EXT_MODE_LDR, 31 | #endif 32 | EXT_MODE_BRIGHTNESS, 33 | EXT_MODE_COLOR, 34 | EXT_MODE_TIMEOUT, 35 | EXT_MODE_LANGUAGE, 36 | EXT_MODE_TEXT_TIME, 37 | EXT_MODE_TIMESET, 38 | EXT_MODE_IT_IS, 39 | EXT_MODE_DAYSET, 40 | EXT_MODE_MONTHSET, 41 | EXT_MODE_YEARSET, 42 | EXT_MODE_TEXT_NIGHTOFF, 43 | EXT_MODE_NIGHTOFF, 44 | EXT_MODE_TEXT_NIGHTON, 45 | EXT_MODE_NIGHTON, 46 | EXT_MODE_TEXT_TEST, 47 | EXT_MODE_TEST, 48 | EXT_MODE_COUNT 49 | } Mode; 50 | 51 | // Overload the ControlType++ operator 52 | inline Mode& operator++(Mode& eDOW, int) { 53 | const uint8_t i = static_cast(eDOW) + 1; 54 | eDOW = static_cast((i) % EXT_MODE_COUNT); 55 | return eDOW; 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /QlockWiFive.ino: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QLOCKWORK 3 | Eine Firmware der Selbstbau-QLOCKTWO. 4 | 5 | @mc ESP8266 6 | @created 01.02.2017 7 | ******************************************************************************/ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "Button.h" 23 | #include "Configuration.h" 24 | #include "Debug.h" 25 | #include "Modes.h" 26 | #include "Renderer.h" 27 | #include "Colors.h" 28 | #include "Languages.h" 29 | #if defined(LED_DRIVER_SK6812) && defined(LED_RGBW) 30 | #include "LedDriverNeopixel.h" 31 | #else 32 | #include "LedDriver.h" 33 | #endif 34 | #include "Settings.h" 35 | 36 | #define FIRMWARE_VERSION "qw20170401" 37 | 38 | /****************************************************************************** 39 | Init 40 | ******************************************************************************/ 41 | 42 | Renderer renderer; 43 | #if defined(LED_DRIVER_SK6812) && defined(LED_RGBW) 44 | LedDriverNeoPixel ledDriver(PIN_LEDS_DATA); 45 | #else 46 | LedDriver ledDriver; 47 | #endif 48 | 49 | Settings settings; 50 | WiFiUDP Udp; 51 | ESP8266WebServer server(80); 52 | Debug debug; 53 | #ifdef RTC_BACKUP 54 | RtcDS3231 Rtc(Wire); 55 | #endif 56 | #ifdef IR_REMOTE 57 | IRrecv irrecv(PIN_IR_RECEIVER); 58 | #endif 59 | #ifdef SYSLOG_SERVER 60 | Syslog syslog(Udp, SYSLOG_SERVER, SYSLOG_PORT, HOSTNAME, "", SYSLOG_FACILITY); 61 | #endif 62 | #ifdef BUTTONS 63 | Button minusButton(PIN_M_PLUS, BUTTONS_PRESSING_AGAINST); 64 | Button plusButton(PIN_H_PLUS, BUTTONS_PRESSING_AGAINST); 65 | Button extModeDoubleButton(PIN_M_PLUS, PIN_H_PLUS, (byte)BUTTONS_PRESSING_AGAINST); 66 | Button modeButton(PIN_MODE, BUTTONS_PRESSING_AGAINST); 67 | #endif 68 | 69 | word matrix[16]; 70 | boolean ScreenBufferNeedsUpdate = true; 71 | IPAddress timeServerIP; 72 | uint8_t packetBuffer[48]; 73 | Mode mode = STD_MODE_NORMAL; 74 | Mode lastMode = mode; 75 | uint8_t fallBackCounter = 0; 76 | uint8_t lastDay = 0; 77 | uint8_t lastHour = 0; 78 | uint8_t lastMinute = 0; 79 | uint8_t lastFiveMinute = 0; 80 | boolean timerSet = false; 81 | uint16_t timerMinutes = 0; 82 | time_t timer = 0; 83 | time_t lastTime = 0; 84 | uint8_t alarmOn = 0; 85 | uint8_t testColumn = 0; 86 | uint32_t lastBrightnessCheck = 0; 87 | uint8_t ledBrightness = 0; 88 | uint8_t lv = 0; 89 | uint16_t minBrightness = 1023; 90 | uint16_t maxBrightness = 0; 91 | uint16_t lastValue = 0; 92 | int8_t maxColor = sizeof(defaultColors) / 3 - 1; 93 | #ifdef IR_REMOTE 94 | decode_results irDecodeResults; 95 | #endif 96 | 97 | #ifdef TIMEZONE_PST 98 | TimeChangeRule usPDT = { "PDT", Second, dowSunday, Mar, 2, -420 }; 99 | TimeChangeRule usPST = { "PST", First, dowSunday, Nov, 2, -480 }; 100 | Timezone timeZone(usPDT, usPST); 101 | #endif 102 | #ifdef TIMEZONE_MST 103 | TimeChangeRule usMDT = { "MDT", Second, dowSunday, Mar, 2, -360 }; 104 | TimeChangeRule usMST = { "MST", First, dowSunday, Nov, 2, -420 }; 105 | Timezone timeZone(usMDT, usMST); 106 | #endif 107 | #ifdef TIMEZONE_CST 108 | TimeChangeRule usCDT = { "CDT", Second, dowSunday, Mar, 2, -300 }; 109 | TimeChangeRule usCST = { "CST", First, dowSunday, Nov, 2, -360 }; 110 | Timezone timeZone(usCDT, usCST); 111 | #endif 112 | #ifdef TIMEZONE_EST 113 | TimeChangeRule usEDT = { "EDT", Second, Sun, Mar, 2, -240 }; 114 | TimeChangeRule usEST = { "EST", First, Sun, Nov, 2, -300 }; 115 | Timezone timeZone(usEDT, usEST); 116 | #endif 117 | #ifdef TIMEZONE_GMT 118 | TimeChangeRule BST = { "BST", Last, Sun, Mar, 1, 60 }; 119 | TimeChangeRule GMT = { "GMT", Last, Sun, Oct, 2, 0 }; 120 | Timezone timeZone(BST, GMT); 121 | #endif 122 | #ifdef TIMEZONE_CET 123 | TimeChangeRule CEST = { "CEST", Last, Sun, Mar, 2, 120 }; 124 | TimeChangeRule CET = { "CET", Last, Sun, Oct, 3, 60 }; 125 | Timezone timeZone(CEST, CET); 126 | #endif 127 | #ifdef TIMEZONE_AEST 128 | TimeChangeRule aEDT = { "AEDT", First, Sun, Oct, 2, 660 }; 129 | TimeChangeRule aEST = { "AEST", First, Sun, Apr, 3, 600 }; 130 | Timezone timeZone(aEDT, aEST); 131 | #endif 132 | 133 | /****************************************************************************** 134 | setup() 135 | ******************************************************************************/ 136 | 137 | void setup() { 138 | 139 | // Seriellen Port initialisieren 140 | Serial.begin(SERIAL_SPEED); 141 | delay(1000); 142 | 143 | DEBUG_PRINTLN(); 144 | DEBUG_PRINTLN("QLOCKWORK"); 145 | DEBUG_PRINT("Firmware: "); 146 | DEBUG_PRINTLN(FIRMWARE_VERSION); 147 | 148 | // LDR, Buzzer und LED initialisieren 149 | DEBUG_PRINTLN("Stetting up LDR, Buzzer and LED."); 150 | pinMode(PIN_LDR, INPUT); 151 | pinMode(PIN_BUZZER, OUTPUT); 152 | #ifdef BOARD_LED 153 | pinMode(PIN_LED, OUTPUT); 154 | digitalWrite(PIN_LED, HIGH); 155 | #endif 156 | 157 | #ifdef IR_REMOTE 158 | // IR-Empfaenger initialisieren 159 | DEBUG_PRINTLN("Starting IR receiver."); 160 | irrecv.enableIRIn(); 161 | #endif 162 | 163 | // WiFi und Dienste initialisieren 164 | renderer.clearScreenBuffer(matrix); 165 | matrix[0] = 0b0000000000000000; 166 | matrix[1] = 0b0000111000000000; 167 | matrix[2] = 0b0011111110000000; 168 | matrix[3] = 0b1111111111100000; 169 | matrix[4] = 0b0111111111000000; 170 | matrix[5] = 0b0011111110000000; 171 | matrix[6] = 0b0001111100000000; 172 | matrix[7] = 0b0000111000000000; 173 | matrix[8] = 0b0000010000000000; 174 | matrix[9] = 0b0000000000000000; 175 | ledBrightness = settings.getBrightness(); 176 | ledDriver.setBrightness(100); 177 | ledDriver.writeScreenBufferToLEDs(matrix, 0); // Color 0: weiss 178 | delay(1000); 179 | 180 | WiFi.hostname(HOSTNAME); 181 | WiFiManager wifiManager; 182 | //wifiManager.resetSettings(); 183 | wifiManager.setTimeout(60); 184 | wifiManager.autoConnect(HOSTNAME); 185 | if (WiFi.status() != WL_CONNECTED) { 186 | DEBUG_PRINTLN("Error connecting to WiFi. Shutting down WiFi."); 187 | renderer.clearScreenBuffer(matrix); 188 | renderer.setSmallText("ER", Renderer::TEXT_POS_TOP, matrix); 189 | renderer.setSmallText("OR", Renderer::TEXT_POS_BOTTOM, matrix); 190 | ledDriver.writeScreenBufferToLEDs(matrix, 1); // Color 1: rot 191 | WiFi.mode(WIFI_OFF); 192 | digitalWrite(PIN_BUZZER, HIGH); 193 | delay(1500); 194 | digitalWrite(PIN_BUZZER, LOW); 195 | } 196 | else { 197 | DEBUG_PRINTLN("WiFi connected."); 198 | renderer.clearScreenBuffer(matrix); 199 | renderer.setSmallText("OK", Renderer::TEXT_POS_MIDDLE, matrix); 200 | ledDriver.writeScreenBufferToLEDs(matrix, 2); // Color 2: gruen 201 | for (uint8_t i = 0; i < 3; i++) { 202 | digitalWrite(PIN_BUZZER, HIGH); 203 | delay(100); 204 | digitalWrite(PIN_BUZZER, LOW); 205 | delay(100); 206 | } 207 | } 208 | DEBUG_PRINTLN("Starting mDNS responder."); 209 | MDNS.begin(HOSTNAME); 210 | DEBUG_PRINTLN("Starting WebServer on Port 80."); 211 | setupWebServer(); 212 | DEBUG_PRINTLN("Starting UDP on Port 2390."); 213 | Udp.begin(2390); 214 | DEBUG_PRINTLN("Starting Arduino-OTA service."); 215 | ArduinoOTA.setPassword((const char*)OTA_PASS); 216 | ArduinoOTA.begin(); 217 | DEBUG_PRINT("Free RAM: "); 218 | DEBUG_PRINTLN(system_get_free_heap_size()); 219 | #ifdef SYSLOG_SERVER 220 | syslog.log(LOG_INFO, "Firmware: " + String(FIRMWARE_VERSION)); 221 | syslog.log(LOG_DEBUG, "Free RAM: " + String(system_get_free_heap_size())); 222 | #endif 223 | 224 | // Zeitprovider setzen 225 | #ifdef RTC_BACKUP 226 | Rtc.Begin(); 227 | Rtc.SetIsRunning(true); 228 | if (WiFi.status() == WL_CONNECTED) { 229 | DEBUG_PRINTLN("Setting ESP from NTP with RTC backup."); 230 | setSyncProvider(getNtpTime); 231 | setSyncInterval(3600); 232 | } 233 | else { 234 | DEBUG_PRINTLN("Setting ESP from RTC."); 235 | setSyncProvider(getRtcTime); 236 | setSyncInterval(3600); 237 | } 238 | #else 239 | if (WiFi.status() == WL_CONNECTED) { 240 | DEBUG_PRINTLN("Setting ESP from NTP."); 241 | setSyncProvider(getNtpTime); 242 | setSyncInterval(3600); 243 | } 244 | else DEBUG_PRINTLN("No provider for setting the time found."); 245 | #endif 246 | 247 | // sonstiges 248 | lastDay = day(); 249 | lastHour = hour(); 250 | lastFiveMinute = minute() / 5; 251 | lastMinute = minute(); 252 | lastTime = now(); 253 | } 254 | 255 | /****************************************************************************** 256 | loop() 257 | ******************************************************************************/ 258 | 259 | void loop() { 260 | 261 | #ifdef DEBUG_FPS 262 | debug.debugFps(); 263 | #endif 264 | 265 | // Jeden Tag ausfuehren 266 | if (day() != lastDay) { 267 | lastDay = day(); 268 | DEBUG_PRINTLN("Neuen Tag erreicht."); 269 | #ifdef SYSLOG_SERVER 270 | syslog.log(LOG_DEBUG, "Free RAM: " + String(system_get_free_heap_size())); 271 | #endif 272 | //if (settings.getColor() < maxColor) settings.setColor(settings.getColor() + 1); 273 | //else settings.setColor(0); 274 | } 275 | 276 | // Jede Stunde ausfuehren 277 | if (hour() != lastHour) { 278 | lastHour = hour(); 279 | DEBUG_PRINTLN("Volle Stunde erreicht."); 280 | #if defined(RTC_BACKUP) && defined(SYSLOG_SERVER) 281 | syslog.log(LOG_INFO, "Temperature: " + String(Rtc.GetTemperature().AsFloat() + RTC_TEMP_OFFSET) + "C / " + String((Rtc.GetTemperature().AsFloat() + RTC_TEMP_OFFSET) * 1.8 + 32) + "F"); 282 | #endif 283 | } 284 | 285 | // Alle fuenf Minuten ausfuehren 286 | // lastFiveMinute ist vom Typ uint8_t. Dadurch werden die Nachkommastellen verworfen. 287 | if ((minute() / 5) != lastFiveMinute) { 288 | lastFiveMinute = minute() / 5; 289 | DEBUG_PRINTLN("Volle fuenf Minuten erreicht."); 290 | } 291 | 292 | // Jede Minute ausfuehren 293 | if (minute() != lastMinute) { 294 | lastMinute = minute(); 295 | #ifdef DEBUG 296 | debug.debugTime("Time:", now()); 297 | #endif 298 | if (mode == STD_MODE_NORMAL) ScreenBufferNeedsUpdate = true; 299 | } 300 | 301 | // Jede Sekunde ausfuehren 302 | if (now() != lastTime) { 303 | lastTime = now(); 304 | 305 | // Fallback zur Zeitanzeige runterzaehlen 306 | if (fallBackCounter > 1) fallBackCounter--; 307 | else if (fallBackCounter == 1) { 308 | fallBackCounter = 0; 309 | setMode(STD_MODE_NORMAL); 310 | } 311 | 312 | // Display braucht Sekundenupdate 313 | switch (mode) { 314 | case STD_MODE_SECONDS: 315 | #ifdef RTC_BACKUP 316 | case STD_MODE_TEMP: 317 | #endif 318 | case STD_MODE_SET_TIMER: 319 | case STD_MODE_TIMER: 320 | case STD_MODE_ALARM_1: 321 | case STD_MODE_SET_ALARM_1: 322 | case STD_MODE_ALARM_2: 323 | case STD_MODE_SET_ALARM_2: 324 | #ifdef LDR 325 | case EXT_MODE_LDR: 326 | #endif 327 | case EXT_MODE_COLOR: 328 | case EXT_MODE_TIMEOUT: 329 | case EXT_MODE_LANGUAGE: 330 | case EXT_MODE_TIMESET: 331 | case EXT_MODE_IT_IS: 332 | case EXT_MODE_DAYSET: 333 | case EXT_MODE_MONTHSET: 334 | case EXT_MODE_YEARSET: 335 | case EXT_MODE_NIGHTOFF: 336 | case EXT_MODE_NIGHTON: 337 | case EXT_MODE_TEST: 338 | ScreenBufferNeedsUpdate = true; 339 | break; 340 | default: 341 | break; 342 | } 343 | 344 | #ifdef BOARD_LED 345 | // LED auf dem Board blinken lassen 346 | if (digitalRead(PIN_LED) == LOW) digitalWrite(PIN_LED, HIGH); 347 | else digitalWrite(PIN_LED, LOW); 348 | #endif 349 | 350 | // Alarm 351 | if (settings.getAlarm1() && (hour() == hour(settings.getAlarmTime1())) && (minute() == minute(settings.getAlarmTime1())) && (second() == 0)) alarmOn = 60; 352 | if (settings.getAlarm2() && (hour() == hour(settings.getAlarmTime2())) && (minute() == minute(settings.getAlarmTime2())) && (second() == 0)) alarmOn = 60; 353 | 354 | // Timer 355 | if (timerSet && (now() == timer)) { 356 | setMode(STD_MODE_SET_TIMER); 357 | timerMinutes = 0; 358 | timerSet = false; 359 | alarmOn = 60; 360 | } 361 | 362 | // ggf. Laerm machen 363 | if (alarmOn) { 364 | if (second() % 2 == 0) digitalWrite(PIN_BUZZER, HIGH); 365 | else digitalWrite(PIN_BUZZER, LOW); 366 | alarmOn--; 367 | } 368 | else digitalWrite(PIN_BUZZER, LOW); 369 | 370 | // Nachtmodus ein/aus 371 | if ((hour() == hour(settings.getNightOffTime())) && (minute() == minute(settings.getNightOffTime())) && (second() == 0)) setMode(STD_MODE_BLANK); 372 | if ((hour() == hour(settings.getNightOnTime())) && (minute() == minute(settings.getNightOnTime())) && (second() == 0)) setMode(lastMode); 373 | } 374 | 375 | // Immer ausfuehren 376 | 377 | // HTTP- und OTA-Anfragen entgegennehmen 378 | server.handleClient(); 379 | ArduinoOTA.handle(); 380 | 381 | uint8_t ledBrightnessOld = ledBrightness; 382 | 383 | // LDR ggf. lesen und Helligkeit einstellen 384 | #ifdef LDR 385 | if (!settings.getUseLdr()) ledBrightness = settings.getBrightness(); 386 | else { 387 | if (millis() > (lastBrightnessCheck + 25)) { 388 | uint16_t val = (1023 - analogRead(PIN_LDR)); 389 | if ((val > (lastValue + 25)) || (val < (lastValue - 25))) { 390 | if (val < minBrightness) minBrightness = val; 391 | if (val > maxBrightness) maxBrightness = val + 1; 392 | lv = map(val, minBrightness, maxBrightness, 0, 255); 393 | lastValue = val; 394 | } 395 | if (ledBrightness < lv) ledBrightness++; 396 | if (ledBrightness > lv) ledBrightness--; 397 | lastBrightnessCheck = millis(); 398 | } 399 | } 400 | #else 401 | ledBrightness = settings.getBrightness(); 402 | #endif 403 | if(ledBrightness != ledBrightnessOld) { 404 | ledDriver.setBrightness(constrain(ledBrightness, MIN_BRIGHTNESS, MAX_BRIGHTNESS)); 405 | ScreenBufferNeedsUpdate = true; 406 | //ledDriver.show(); 407 | } 408 | 409 | #ifdef IR_REMOTE 410 | // IR-Empfaenger abfragen und ggf. reagieren 411 | if (irrecv.decode(&irDecodeResults)) { 412 | DEBUG_PRINT("IR signal: "); 413 | DEBUG_PRINTLN(irDecodeResults.value); 414 | remoteAction(irDecodeResults.value); 415 | irrecv.resume(); 416 | } 417 | #endif 418 | 419 | #ifdef BUTTONS 420 | // M+ und H+ im STD_MODE_BLANK gedrueckt? 421 | if ((mode == STD_MODE_BLANK) && extModeDoubleButton.pressed()) { 422 | doubleExtModePressed(); 423 | } 424 | 425 | // Taste Minuten++ (brighness++) gedrueckt? 426 | if (plusButton.pressed()) { 427 | buttonPlusPressed(); 428 | } 429 | 430 | // Taste Stunden++ (brightness--) gedrueckt? 431 | if (minusButton.pressed()) { 432 | buttonMinusPressed(); 433 | } 434 | 435 | // Taste Moduswechsel gedrueckt? 436 | if (modeButton.pressed()) { 437 | modePressed(); 438 | } 439 | #endif 440 | 441 | // Wenn noetig, den Screenbuffer neu erstellen und in die LEDs schreiben 442 | if (ScreenBufferNeedsUpdate) { 443 | ScreenBufferNeedsUpdate = false; 444 | switch (mode) { 445 | case STD_MODE_NORMAL: 446 | renderer.clearScreenBuffer(matrix); 447 | renderer.setTime(hour(), minute(), settings.getLanguage(), matrix); 448 | renderer.setCorners(minute(), matrix); 449 | if (!settings.getEsIst() && ((minute() / 5) % 6)) renderer.clearEntryWords(settings.getLanguage(), matrix); 450 | if (settings.getAlarm1() || settings.getAlarm2()) renderer.activateAlarmLed(matrix); 451 | break; 452 | case STD_MODE_AMPM: 453 | renderer.clearScreenBuffer(matrix); 454 | if (isAM()) renderer.setSmallText("AM", Renderer::TEXT_POS_MIDDLE, matrix); 455 | else renderer.setSmallText("PM", Renderer::TEXT_POS_MIDDLE, matrix); 456 | break; 457 | case STD_MODE_SECONDS: 458 | renderer.clearScreenBuffer(matrix); 459 | renderer.setCorners(minute(), matrix); 460 | for (uint8_t i = 0; i < 7; i++) { 461 | matrix[1 + i] |= (zahlenGross[second() / 10][i]) << 11; 462 | matrix[1 + i] |= (zahlenGross[second() % 10][i]) << 5; 463 | } 464 | break; 465 | case STD_MODE_DATE: 466 | renderer.clearScreenBuffer(matrix); 467 | if (day() < 10) renderer.setSmallText(("0" + String(day())), Renderer::TEXT_POS_TOP, matrix); 468 | else renderer.setSmallText(String(day()), Renderer::TEXT_POS_TOP, matrix); 469 | if (month() < 10) renderer.setSmallText(("0" + String(month())), Renderer::TEXT_POS_BOTTOM, matrix); 470 | else renderer.setSmallText(String(month()), Renderer::TEXT_POS_BOTTOM, matrix); 471 | renderer.setPixelInScreenBuffer(5, 4, matrix); 472 | renderer.setPixelInScreenBuffer(5, 9, matrix); 473 | break; 474 | #ifdef RTC_BACKUP 475 | case STD_MODE_TEMP: 476 | renderer.clearScreenBuffer(matrix); 477 | for (uint8_t i = 0; i < 7; i++) { 478 | matrix[1 + i] |= (zahlenGross[(Rtc.GetTemperature().AsWholeDegrees() + RTC_TEMP_OFFSET) / 10][i]) << 11; 479 | matrix[1 + i] |= (zahlenGross[(Rtc.GetTemperature().AsWholeDegrees() + RTC_TEMP_OFFSET) % 10][i]) << 5; 480 | } 481 | renderer.setPixelInScreenBuffer(4, 0, matrix); // LED rechts oben setzen als "Grad" 482 | DEBUG_PRINTLN(String(Rtc.GetTemperature().AsFloat() + RTC_TEMP_OFFSET)); 483 | break; 484 | #endif 485 | case STD_MODE_SET_TIMER: 486 | renderer.clearScreenBuffer(matrix); 487 | renderer.setSmallText("TR", Renderer::TEXT_POS_TOP, matrix); 488 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 489 | else renderer.setSmallText(String(timerMinutes), Renderer::TEXT_POS_BOTTOM, matrix); 490 | break; 491 | case STD_MODE_TIMER: 492 | renderer.clearScreenBuffer(matrix); 493 | renderer.setSmallText("TR", Renderer::TEXT_POS_TOP, matrix); 494 | renderer.setSmallText(String((timer - now() + 60) / 60), Renderer::TEXT_POS_BOTTOM, matrix); 495 | DEBUG_PRINTLN(String(timer - now())); 496 | break; 497 | case STD_MODE_ALARM_1: 498 | renderer.clearScreenBuffer(matrix); 499 | renderer.setSmallText("A1", Renderer::TEXT_POS_TOP, matrix); 500 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 501 | else { 502 | if (settings.getAlarm1()) { 503 | renderer.setSmallText("EN", Renderer::TEXT_POS_BOTTOM, matrix); 504 | renderer.activateAlarmLed(matrix); 505 | } 506 | else renderer.setSmallText("DA", Renderer::TEXT_POS_BOTTOM, matrix); 507 | } 508 | break; 509 | case STD_MODE_SET_ALARM_1: 510 | renderer.clearScreenBuffer(matrix); 511 | if (second() % 2 == 0) { 512 | renderer.setTime(hour(settings.getAlarmTime1()), minute(settings.getAlarmTime1()), settings.getLanguage(), matrix); 513 | renderer.clearEntryWords(settings.getLanguage(), matrix); 514 | renderer.setAMPM(hour(settings.getAlarmTime1()), settings.getLanguage(), matrix); 515 | renderer.activateAlarmLed(matrix); 516 | } 517 | break; 518 | case STD_MODE_ALARM_2: 519 | renderer.clearScreenBuffer(matrix); 520 | renderer.setSmallText("A2", Renderer::TEXT_POS_TOP, matrix); 521 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 522 | else { 523 | if (settings.getAlarm2()) { 524 | renderer.setSmallText("EN", Renderer::TEXT_POS_BOTTOM, matrix); 525 | renderer.activateAlarmLed(matrix); 526 | } 527 | else renderer.setSmallText("DA", Renderer::TEXT_POS_BOTTOM, matrix); 528 | } 529 | break; 530 | case STD_MODE_SET_ALARM_2: 531 | renderer.clearScreenBuffer(matrix); 532 | if (second() % 2 == 0) { 533 | renderer.setTime(hour(settings.getAlarmTime2()), minute(settings.getAlarmTime2()), settings.getLanguage(), matrix); 534 | renderer.clearEntryWords(settings.getLanguage(), matrix); 535 | renderer.setAMPM(hour(settings.getAlarmTime2()), settings.getLanguage(), matrix); 536 | renderer.activateAlarmLed(matrix); 537 | } 538 | break; 539 | case EXT_MODE_TEXT_MAIN: 540 | renderer.clearScreenBuffer(matrix); 541 | renderer.setSmallText("MA", Renderer::TEXT_POS_TOP, matrix); 542 | renderer.setSmallText("IN", Renderer::TEXT_POS_BOTTOM, matrix); 543 | break; 544 | #ifdef LDR 545 | case EXT_MODE_LDR: 546 | renderer.clearScreenBuffer(matrix); 547 | renderer.setSmallText("LD", Renderer::TEXT_POS_TOP, matrix); 548 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 549 | else { 550 | if (settings.getUseLdr()) renderer.setSmallText("EN", Renderer::TEXT_POS_BOTTOM, matrix); 551 | else renderer.setSmallText("DA", Renderer::TEXT_POS_BOTTOM, matrix); 552 | } 553 | break; 554 | #endif 555 | case EXT_MODE_BRIGHTNESS: 556 | renderer.clearScreenBuffer(matrix); 557 | for (uint8_t xb = 0; xb < map(settings.getBrightness(), 0, 255, 1, 10); xb++) { 558 | for (uint8_t yb = 0; yb <= xb; yb++) matrix[9 - yb] |= 1 << (14 - xb); 559 | } 560 | break; 561 | case EXT_MODE_COLOR: 562 | renderer.clearScreenBuffer(matrix); 563 | renderer.setSmallText("CO", Renderer::TEXT_POS_TOP, matrix); 564 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 565 | else renderer.setSmallText(String(settings.getColor()), Renderer::TEXT_POS_BOTTOM, matrix); 566 | break; 567 | case EXT_MODE_TIMEOUT: 568 | renderer.clearScreenBuffer(matrix); 569 | renderer.setSmallText("FB", Renderer::TEXT_POS_TOP, matrix); 570 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 571 | else renderer.setSmallText(String(settings.getTimeout()), Renderer::TEXT_POS_BOTTOM, matrix); 572 | break; 573 | case EXT_MODE_LANGUAGE: 574 | renderer.clearScreenBuffer(matrix); 575 | if (second() % 2 == 0) { 576 | if (sLanguage[settings.getLanguage()].length() == 2) renderer.setSmallText(sLanguage[settings.getLanguage()], Renderer::TEXT_POS_MIDDLE, matrix); 577 | else { 578 | renderer.setSmallText(sLanguage[settings.getLanguage()].substring(0, 2), Renderer::TEXT_POS_TOP, matrix); 579 | renderer.setSmallText(sLanguage[settings.getLanguage()].substring(2, 4), Renderer::TEXT_POS_BOTTOM, matrix); 580 | } 581 | } 582 | break; 583 | case EXT_MODE_TEXT_TIME: 584 | renderer.clearScreenBuffer(matrix); 585 | renderer.setSmallText("TI", Renderer::TEXT_POS_TOP, matrix); 586 | renderer.setSmallText("ME", Renderer::TEXT_POS_BOTTOM, matrix); 587 | break; 588 | case EXT_MODE_TIMESET: 589 | renderer.clearScreenBuffer(matrix); 590 | if (second() % 2 == 0) { 591 | renderer.setTime(hour(), minute(), settings.getLanguage(), matrix); 592 | renderer.setCorners(minute(), matrix); 593 | renderer.clearEntryWords(settings.getLanguage(), matrix); 594 | renderer.setAMPM(hour(), settings.getLanguage(), matrix); 595 | } 596 | break; 597 | case EXT_MODE_IT_IS: 598 | renderer.clearScreenBuffer(matrix); 599 | renderer.setSmallText("IT", Renderer::TEXT_POS_TOP, matrix); 600 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 601 | else { 602 | if (settings.getEsIst()) renderer.setSmallText("EN", Renderer::TEXT_POS_BOTTOM, matrix); 603 | else renderer.setSmallText("DA", Renderer::TEXT_POS_BOTTOM, matrix); 604 | } 605 | break; 606 | case EXT_MODE_DAYSET: 607 | renderer.clearScreenBuffer(matrix); 608 | renderer.setSmallText("DD", Renderer::TEXT_POS_TOP, matrix); 609 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 610 | else renderer.setSmallText(String(day()), Renderer::TEXT_POS_BOTTOM, matrix); 611 | break; 612 | case EXT_MODE_MONTHSET: 613 | renderer.clearScreenBuffer(matrix); 614 | renderer.setSmallText("MM", Renderer::TEXT_POS_TOP, matrix); 615 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 616 | else renderer.setSmallText(String(month()), Renderer::TEXT_POS_BOTTOM, matrix); 617 | break; 618 | case EXT_MODE_YEARSET: 619 | renderer.clearScreenBuffer(matrix); 620 | renderer.setSmallText("YY", Renderer::TEXT_POS_TOP, matrix); 621 | if (second() % 2 == 0) for (uint8_t i = 5; i < 10; i++) matrix[i] = 0; 622 | else renderer.setSmallText(String(year()).substring(2, 4), Renderer::TEXT_POS_BOTTOM, matrix); 623 | break; 624 | case EXT_MODE_TEXT_NIGHTOFF: 625 | renderer.clearScreenBuffer(matrix); 626 | renderer.setSmallText("NT", Renderer::TEXT_POS_TOP, matrix); 627 | renderer.setSmallText("OF", Renderer::TEXT_POS_BOTTOM, matrix); 628 | break; 629 | case EXT_MODE_NIGHTOFF: 630 | renderer.clearScreenBuffer(matrix); 631 | if (second() % 2 == 0) { 632 | renderer.setTime(hour(settings.getNightOffTime()), minute(settings.getNightOffTime()), settings.getLanguage(), matrix); 633 | renderer.clearEntryWords(settings.getLanguage(), matrix); 634 | renderer.setAMPM(hour(settings.getNightOffTime()), settings.getLanguage(), matrix); 635 | } 636 | break; 637 | case EXT_MODE_TEXT_NIGHTON: 638 | renderer.clearScreenBuffer(matrix); 639 | renderer.setSmallText("NT", Renderer::TEXT_POS_TOP, matrix); 640 | renderer.setSmallText("ON", Renderer::TEXT_POS_BOTTOM, matrix); 641 | break; 642 | case EXT_MODE_NIGHTON: 643 | renderer.clearScreenBuffer(matrix); 644 | if (second() % 2 == 0) { 645 | renderer.setTime(hour(settings.getNightOnTime()), minute(settings.getNightOnTime()), settings.getLanguage(), matrix); 646 | renderer.clearEntryWords(settings.getLanguage(), matrix); 647 | renderer.setAMPM(hour(settings.getNightOnTime()), settings.getLanguage(), matrix); 648 | } 649 | break; 650 | case EXT_MODE_TEXT_TEST: 651 | renderer.clearScreenBuffer(matrix); 652 | renderer.setSmallText("TE", Renderer::TEXT_POS_TOP, matrix); 653 | renderer.setSmallText("ST", Renderer::TEXT_POS_BOTTOM, matrix); 654 | break; 655 | case EXT_MODE_TEST: 656 | renderer.clearScreenBuffer(matrix); 657 | if (testColumn == 10) testColumn = 0; 658 | matrix[testColumn] = 0b1111111111110000; 659 | testColumn++; 660 | break; 661 | case STD_MODE_BLANK: 662 | renderer.clearScreenBuffer(matrix); 663 | break; 664 | default: 665 | break; 666 | } 667 | #if defined(IR_LETTER_OFF) 668 | // Die LED hinter dem IR-Sensor abschalten. 669 | renderer.unsetPixelInScreenBuffer(8, 9, matrix); 670 | #endif 671 | // Screenbuffer in die LEDs schreiben 672 | ledDriver.writeScreenBufferToLEDs(matrix, settings.getColor()); 673 | #ifdef DEBUG_MATRIX 674 | // Screenbuffer auf der Konsole ausgeben 675 | debug.debugScreenBuffer(matrix); 676 | #endif 677 | } 678 | } 679 | 680 | /****************************************************************************** 681 | "M+" & "H+" gedrueckt im BLANK MODE 682 | ******************************************************************************/ 683 | #ifdef BUTTONS 684 | void doubleExtModePressed() { 685 | DEBUG_PRINTLN(F("Minutes plus AND hours plus pressed in STD_MODE_BLANK...")); 686 | DEBUG_FLUSH(); 687 | unsigned long initialMillis = millis(); 688 | while (minusButton.pressedRaw() && plusButton.pressedRaw()) { 689 | } 690 | setMode(EXT_MODE_START); 691 | DEBUG_PRINT(F("Entering EXT_MODEs, mode is now ")); 692 | DEBUG_PRINT(mode); 693 | DEBUG_PRINTLN(F("...")); 694 | DEBUG_FLUSH(); 695 | } 696 | #endif 697 | 698 | /****************************************************************************** 699 | "Mode" gedrueckt 700 | ******************************************************************************/ 701 | 702 | void modePressed() { 703 | 704 | // Alarm abschalten 705 | if (alarmOn) { 706 | alarmOn = false; 707 | digitalWrite(PIN_BUZZER, LOW); 708 | return; 709 | } 710 | 711 | // Nachtmode abschalten 712 | if (mode == STD_MODE_BLANK) { 713 | setMode(STD_MODE_NORMAL); 714 | return; 715 | } 716 | 717 | // Mode weiterschalten und ggf. Fallback setzen 718 | setMode(mode++); 719 | switch (mode) { 720 | case STD_MODE_COUNT: 721 | case EXT_MODE_COUNT: 722 | setMode(STD_MODE_NORMAL); 723 | break; 724 | case STD_MODE_TIMER: 725 | if (!timerSet) setMode(mode++); 726 | break; 727 | case STD_MODE_SET_ALARM_1: 728 | if (!settings.getAlarm1()) setMode(mode++);; 729 | break; 730 | case STD_MODE_SET_ALARM_2: 731 | if (!settings.getAlarm2()) setMode(mode++);; 732 | break; 733 | #ifdef LDR 734 | case EXT_MODE_BRIGHTNESS: 735 | if (settings.getUseLdr()) setMode(mode++); 736 | break; 737 | #endif 738 | case EXT_MODE_TEST: 739 | testColumn = 0; 740 | return; 741 | case STD_MODE_AMPM: 742 | case STD_MODE_SECONDS: 743 | case STD_MODE_DATE: 744 | #ifdef RTC_BACKUP 745 | case STD_MODE_TEMP: 746 | #endif 747 | fallBackCounter = settings.getTimeout(); 748 | break; 749 | default: 750 | fallBackCounter = 0; 751 | break; 752 | } 753 | 754 | // Einstellungen sichern 755 | settings.saveToEEPROM(); 756 | 757 | #ifdef RTC_BACKUP 758 | // RTC stellen 759 | Rtc.SetDateTime(now()); 760 | #endif 761 | } 762 | 763 | /****************************************************************************** 764 | "+" gedrueckt 765 | ******************************************************************************/ 766 | 767 | void buttonPlusPressed() { 768 | DEBUG_PRINTLN("+ pressed."); 769 | ScreenBufferNeedsUpdate = true; 770 | switch (mode) { 771 | case STD_MODE_SET_TIMER: 772 | if (timerMinutes < 100) timerMinutes++; 773 | timer = now() + timerMinutes * 60; 774 | timerSet = true; 775 | break; 776 | case STD_MODE_ALARM_1: 777 | settings.toggleAlarm1(); 778 | break; 779 | case STD_MODE_SET_ALARM_1: 780 | settings.setAlarmTime1(settings.getAlarmTime1() + 3600); 781 | #ifdef DEBUG 782 | debug.debugTime("Alarm 1:", settings.getAlarmTime1()); 783 | #endif 784 | break; 785 | case STD_MODE_ALARM_2: 786 | settings.toggleAlarm2(); 787 | break; 788 | case STD_MODE_SET_ALARM_2: 789 | settings.setAlarmTime2(settings.getAlarmTime2() + 3600); 790 | #ifdef DEBUG 791 | debug.debugTime("Alarm 2:", settings.getAlarmTime2()); 792 | #endif 793 | break; 794 | case EXT_MODE_TEXT_MAIN: 795 | setMode(EXT_MODE_TEXT_TIME); 796 | break; 797 | #ifdef LDR 798 | case EXT_MODE_LDR: 799 | settings.toggleUseLdr(); 800 | break; 801 | #endif 802 | case EXT_MODE_BRIGHTNESS: 803 | settings.setBrightness(constrain(settings.getBrightness() + 10, 0, 255)); 804 | DEBUG_PRINTLN(settings.getBrightness()); 805 | break; 806 | case EXT_MODE_COLOR: 807 | if (settings.getColor() < maxColor) settings.setColor(settings.getColor() + 1); 808 | else settings.setColor(0); 809 | break; 810 | case EXT_MODE_TIMEOUT: 811 | if (settings.getTimeout() < 99) settings.setTimeout(settings.getTimeout() + 1); 812 | break; 813 | case EXT_MODE_LANGUAGE: 814 | if (settings.getLanguage() < LANGUAGE_COUNT - 1) settings.setLanguage(settings.getLanguage() + 1); 815 | else settings.setLanguage(0); 816 | break; 817 | case EXT_MODE_TEXT_TIME: 818 | setMode(EXT_MODE_TEXT_TEST); 819 | break; 820 | case EXT_MODE_TIMESET: 821 | setTime(hour() + 1, minute(), second(), day(), month(), year()); 822 | #ifdef DEBUG 823 | debug.debugTime("Time set:", now()); 824 | #endif 825 | break; 826 | case EXT_MODE_IT_IS: 827 | settings.toggleEsIst(); 828 | break; 829 | case EXT_MODE_DAYSET: 830 | setTime(hour(), minute(), second(), day() + 1, month(), year()); 831 | break; 832 | case EXT_MODE_MONTHSET: 833 | setTime(hour(), minute(), second(), day(), month() + 1, year()); 834 | break; 835 | case EXT_MODE_YEARSET: 836 | setTime(hour(), minute(), second(), day(), month(), year() + 1); 837 | break; 838 | case EXT_MODE_NIGHTOFF: 839 | settings.setNightOffTime(settings.getNightOffTime() + 3600); 840 | #ifdef DEBUG 841 | debug.debugTime("Night Off:", settings.getNightOffTime()); 842 | #endif 843 | break; 844 | case EXT_MODE_NIGHTON: 845 | settings.setNightOnTime(settings.getNightOnTime() + 3600); 846 | #ifdef DEBUG 847 | debug.debugTime("Night On:", settings.getNightOnTime()); 848 | #endif 849 | break; 850 | case EXT_MODE_TEXT_TEST: 851 | setMode(EXT_MODE_TEXT_MAIN); 852 | break; 853 | default: 854 | break; 855 | } 856 | } 857 | 858 | /****************************************************************************** 859 | "-" gedrueckt 860 | ******************************************************************************/ 861 | 862 | void buttonMinusPressed() { 863 | DEBUG_PRINTLN("- pressed."); 864 | ScreenBufferNeedsUpdate = true; 865 | switch (mode) { 866 | case STD_MODE_SET_TIMER: 867 | if (timerMinutes > 0) { 868 | timerMinutes--; 869 | if (timerMinutes == 0) timerSet = false; 870 | else { 871 | timer = now() + timerMinutes * 60; 872 | timerSet = true; 873 | } 874 | } 875 | break; 876 | case STD_MODE_ALARM_1: 877 | settings.toggleAlarm1(); 878 | break; 879 | case STD_MODE_SET_ALARM_1: 880 | settings.setAlarmTime1(settings.getAlarmTime1() + 300); 881 | #ifdef DEBUG 882 | debug.debugTime("Alarm 1:", settings.getAlarmTime1()); 883 | #endif 884 | break; 885 | case STD_MODE_ALARM_2: 886 | settings.toggleAlarm2(); 887 | break; 888 | case STD_MODE_SET_ALARM_2: 889 | settings.setAlarmTime2(settings.getAlarmTime2() + 300); 890 | #ifdef DEBUG 891 | debug.debugTime("Alarm 2:", settings.getAlarmTime2()); 892 | #endif 893 | break; 894 | case EXT_MODE_TEXT_MAIN: 895 | setMode(EXT_MODE_TEXT_TEST); 896 | break; 897 | #ifdef LDR 898 | case EXT_MODE_LDR: 899 | settings.toggleUseLdr(); 900 | break; 901 | #endif 902 | case EXT_MODE_BRIGHTNESS: 903 | settings.setBrightness(constrain(settings.getBrightness() - 10, 0, 255)); 904 | DEBUG_PRINTLN(settings.getBrightness()); 905 | break; 906 | case EXT_MODE_COLOR: 907 | if (settings.getColor() > 0) settings.setColor(settings.getColor() - 1); 908 | else settings.setColor(maxColor); 909 | break; 910 | case EXT_MODE_TIMEOUT: 911 | if (settings.getTimeout() > 0) settings.setTimeout(settings.getTimeout() - 1); 912 | break; 913 | case EXT_MODE_LANGUAGE: 914 | if (settings.getLanguage() > 0) settings.setLanguage(settings.getLanguage() - 1); 915 | else settings.setLanguage(LANGUAGE_COUNT - 1); 916 | break; 917 | case EXT_MODE_TEXT_TIME: 918 | setMode(EXT_MODE_TEXT_MAIN); 919 | break; 920 | case EXT_MODE_TIMESET: 921 | setTime(hour(), minute() + 1, 0, day(), month(), year()); 922 | #ifdef DEBUG 923 | debug.debugTime("Time set:", now()); 924 | #endif 925 | break; 926 | case EXT_MODE_IT_IS: 927 | settings.toggleEsIst(); 928 | break; 929 | case EXT_MODE_DAYSET: 930 | setTime(hour(), minute(), second(), day() - 1, month(), year()); 931 | break; 932 | case EXT_MODE_MONTHSET: 933 | setTime(hour(), minute(), second(), day(), month() - 1, year()); 934 | break; 935 | case EXT_MODE_YEARSET: 936 | setTime(hour(), minute(), second(), day(), month(), year() - 1); 937 | break; 938 | case EXT_MODE_NIGHTOFF: 939 | settings.setNightOffTime(settings.getNightOffTime() + 300); 940 | #ifdef DEBUG 941 | debug.debugTime("Night Off:", settings.getNightOffTime()); 942 | #endif 943 | break; 944 | case EXT_MODE_NIGHTON: 945 | settings.setNightOnTime(settings.getNightOnTime() + 300); 946 | #ifdef DEBUG 947 | debug.debugTime("Night On:", settings.getNightOnTime()); 948 | #endif 949 | break; 950 | case EXT_MODE_TEXT_TEST: 951 | setMode(EXT_MODE_TEXT_TIME); 952 | break; 953 | default: 954 | break; 955 | } 956 | } 957 | 958 | /****************************************************************************** 959 | IR empfangen 960 | ******************************************************************************/ 961 | 962 | #ifdef IR_REMOTE 963 | void remoteAction(uint32_t irDecodeResults) { 964 | switch (irDecodeResults) { 965 | case IR_CODE_ONOFF: 966 | setDisplayToToggle(); 967 | break; 968 | case IR_CODE_TIME: 969 | settings.saveToEEPROM(); 970 | #ifdef RTC_BACKUP 971 | Rtc.SetDateTime(now()); 972 | #endif 973 | if (alarmOn) { 974 | alarmOn = false; 975 | digitalWrite(PIN_BUZZER, LOW); 976 | } 977 | setMode(STD_MODE_NORMAL); 978 | break; 979 | case IR_CODE_MODE: 980 | modePressed(); 981 | break; 982 | case IR_CODE_EXTMODE: 983 | if (mode < EXT_MODE_START) setMode(EXT_MODE_START); 984 | else modePressed(); 985 | break; 986 | case IR_CODE_PLUS: 987 | buttonPlusPressed(); 988 | break; 989 | case IR_CODE_MINUS: 990 | buttonMinusPressed(); 991 | break; 992 | default: 993 | break; 994 | } 995 | } 996 | #endif 997 | 998 | /****************************************************************************** 999 | Sonstiges 1000 | ******************************************************************************/ 1001 | 1002 | // Mode setzen 1003 | void setMode(Mode newmode) { 1004 | DEBUG_PRINT("Mode: "); 1005 | DEBUG_PRINTLN(newmode); 1006 | ScreenBufferNeedsUpdate = true; 1007 | lastMode = mode; 1008 | mode = newmode; 1009 | } 1010 | 1011 | // LEDs ausschalten 1012 | void setLedsOff() { 1013 | DEBUG_PRINTLN("LEDs off."); 1014 | setMode(STD_MODE_BLANK); 1015 | } 1016 | 1017 | // LEDs einschalten 1018 | void setLedsOn() { 1019 | DEBUG_PRINTLN("LEDs on."); 1020 | setMode(lastMode); 1021 | } 1022 | 1023 | // LEDs toggeln 1024 | void setDisplayToToggle() { 1025 | if (mode != STD_MODE_BLANK) setLedsOff(); 1026 | else setLedsOn(); 1027 | } 1028 | 1029 | #ifdef RTC_BACKUP 1030 | // Zeit von RTC holen 1031 | time_t getRtcTime() { 1032 | DEBUG_PRINTLN("*** ESP set from RTC. ***"); 1033 | #ifdef SYSLOG_SERVER 1034 | syslog.log(LOG_DEBUG, "ESP set from RTC."); 1035 | #endif 1036 | return Rtc.GetDateTime(); 1037 | } 1038 | #endif 1039 | 1040 | // Zeit mit NTP holen 1041 | time_t getNtpTime() { 1042 | if (WiFi.status() == WL_CONNECTED) { 1043 | while (Udp.parsePacket() > 0); 1044 | WiFi.hostByName(NTP_SERVER, timeServerIP); 1045 | sendNTPpacket(timeServerIP); 1046 | uint32_t beginWait = millis(); 1047 | while (millis() - beginWait < 1500) { 1048 | int size = Udp.parsePacket(); 1049 | if (size >= 48) { 1050 | Udp.read(packetBuffer, 48); 1051 | unsigned long secsSince1900; 1052 | secsSince1900 = (unsigned long)packetBuffer[40] << 24; 1053 | secsSince1900 |= (unsigned long)packetBuffer[41] << 16; 1054 | secsSince1900 |= (unsigned long)packetBuffer[42] << 8; 1055 | secsSince1900 |= (unsigned long)packetBuffer[43]; 1056 | #ifdef RTC_BACKUP 1057 | DEBUG_PRINTLN("*** RTC set from NTP. ***"); 1058 | #ifdef SYSLOG_SERVER 1059 | syslog.log(LOG_DEBUG, "RTC set from NTP."); 1060 | #endif 1061 | Rtc.SetDateTime(timeZone.toLocal(secsSince1900 - 2208988800UL)); 1062 | #endif 1063 | DEBUG_PRINTLN("*** ESP set from NTP. ***"); 1064 | #ifdef SYSLOG_SERVER 1065 | syslog.log(LOG_DEBUG, "ESP set from NTP."); 1066 | #endif 1067 | return (timeZone.toLocal(secsSince1900 - 2208988800UL)); 1068 | } 1069 | } 1070 | DEBUG_PRINTLN("No NTP Response. :("); 1071 | #ifdef SYSLOG_SERVER 1072 | syslog.log(LOG_ERR, "No NTP Response."); 1073 | #endif 1074 | #ifdef RTC_BACKUP 1075 | return getRtcTime(); 1076 | #else 1077 | return now(); 1078 | #endif 1079 | } 1080 | DEBUG_PRINTLN("Wifi not connected. :("); 1081 | return now(); 1082 | } 1083 | 1084 | // NTP Paket senden 1085 | void sendNTPpacket(IPAddress & address) { 1086 | memset(packetBuffer, 0, 48); 1087 | packetBuffer[0] = 0b11100011; 1088 | packetBuffer[1] = 0; 1089 | packetBuffer[2] = 6; 1090 | packetBuffer[3] = 0xEC; 1091 | packetBuffer[12] = 49; 1092 | packetBuffer[13] = 0x4E; 1093 | packetBuffer[14] = 49; 1094 | packetBuffer[15] = 52; 1095 | Udp.beginPacket(address, 123); 1096 | Udp.write(packetBuffer, 48); 1097 | Udp.endPacket(); 1098 | } 1099 | 1100 | /****************************************************************************** 1101 | Webserver 1102 | ******************************************************************************/ 1103 | 1104 | // Setup 1105 | void setupWebServer() { 1106 | server.onNotFound(handleNotFound); 1107 | server.on("/", handleRoot); 1108 | server.on("/handle_TOGGLEBLANK", handle_TOGGLEBLANK); 1109 | server.on("/handle_BUTTON_TIME", handle_BUTTON_TIME); 1110 | server.on("/handle_BUTTON_MODE", handle_BUTTON_MODE); 1111 | server.on("/handle_BUTTON_EXTMODE", handle_BUTTON_EXTMODE); 1112 | server.on("/handle_BUTTON_PLUS", handle_BUTTON_PLUS); 1113 | server.on("/handle_BUTTON_MINUS", handle_BUTTON_MINUS); 1114 | server.begin(); 1115 | } 1116 | 1117 | // Seite 404 1118 | void handleNotFound() { 1119 | server.send(404, "text/plain", "404 - File Not Found."); 1120 | } 1121 | 1122 | // Seite / 1123 | void handleRoot() { 1124 | String message = ""; 1125 | message += ""; 1126 | message += ""; 1127 | message += ""; 1128 | message += ""; 1129 | message += HOSTNAME; 1130 | message += ""; 1131 | message += ""; 1135 | message += ""; 1136 | message += ""; 1137 | message += "

"; 1138 | message += HOSTNAME; 1139 | message += "

"; 1140 | message += ""; 1141 | message += ""; 1142 | message += "

"; 1143 | message += ""; 1144 | message += ""; 1145 | message += "

"; 1146 | message += ""; 1147 | message += ""; 1148 | message += "

"; 1149 | #ifdef RTC_BACKUP 1150 | message += "Temperature: " + String(Rtc.GetTemperature().AsFloat() + RTC_TEMP_OFFSET) + "°C / " + String((Rtc.GetTemperature().AsFloat() + RTC_TEMP_OFFSET) * 1.8 + 32) + "°F"; 1151 | message += "
"; 1152 | #endif 1153 | message += ""; 1154 | message += "Firmware: "; 1155 | message += FIRMWARE_VERSION; 1156 | message += ""; 1157 | message += ""; 1158 | message += ""; 1159 | server.send(200, "text/html", message); 1160 | } 1161 | 1162 | void handle_TOGGLEBLANK() { 1163 | String message = ""; 1164 | server.send(200, "text/html", message); 1165 | setDisplayToToggle(); 1166 | } 1167 | 1168 | void handle_BUTTON_TIME() { 1169 | String message = ""; 1170 | server.send(200, "text/html", message); 1171 | // Alarm abschalten 1172 | if (alarmOn) { 1173 | alarmOn = false; 1174 | digitalWrite(PIN_BUZZER, LOW); 1175 | } 1176 | settings.saveToEEPROM(); 1177 | #ifdef RTC_BACKUP 1178 | Rtc.SetDateTime(now()); 1179 | #endif 1180 | setMode(STD_MODE_NORMAL); 1181 | } 1182 | 1183 | void handle_BUTTON_MODE() { 1184 | String message = ""; 1185 | server.send(200, "text/html", message); 1186 | modePressed(); 1187 | } 1188 | 1189 | void handle_BUTTON_EXTMODE() { 1190 | String message = ""; 1191 | server.send(200, "text/html", message); 1192 | if (mode < EXT_MODE_START) setMode(EXT_MODE_START); 1193 | else modePressed(); 1194 | } 1195 | 1196 | void handle_BUTTON_PLUS() { 1197 | String message = ""; 1198 | server.send(200, "text/html", message); 1199 | buttonPlusPressed(); 1200 | } 1201 | 1202 | void handle_BUTTON_MINUS() { 1203 | String message = ""; 1204 | server.send(200, "text/html", message); 1205 | buttonMinusPressed(); 1206 | } 1207 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QLOCKWORK 2 | ### Eine Firmware der Selbstbau-QLOCKTWO. 3 | 4 | ### Features: 5 | ``` 6 | Almost no electronics needed. 7 | Only ESP8266 (NodeMCU or WeMos D1 mini) and an LED-stripe. 8 | Optional support for RTC, LDR, Buzzer and IR-remote. 9 | Supports more than 30 types of LED stripes. 10 | RGB and RGBW (experimental). 11 | Horizontal and vertial LED layout. 12 | 16 Languages. 13 | Timer. 14 | Alarm. 15 | NTP timesync. 16 | RTC timesync as backup. 17 | Timezones. 18 | DST. 19 | Webserver to controll the clock. 20 | OTA. 21 | WiFi manager for initial setup via accesspoint. 22 | Log to Syslog. 23 | (RGBW ist only tested with LPD8806 of the CLT2.) 24 | ``` 25 | ### Standard modes 26 | ``` 27 | Time. 28 | AM/PM. 29 | Seconds. 30 | Date. 31 | Temperature (with RTC only). 32 | Timer. 33 | Alarm 1. 34 | Alarm 2. 35 | ``` 36 | ### Extended modes 37 | ``` 38 | Brightnesscontrol. 39 | Color. 40 | Fallbacktime. 41 | Language. 42 | Set Time. 43 | "It is" on/off. 44 | Set Date. 45 | Nightmode on/off. 46 | Testmode. 47 | ``` 48 | ### Needed libraries: 49 | ``` 50 | via Arduino: 51 | WiFiManager by tzapu 52 | DNSServer by Kristijan Novoselic 53 | ArduinoOTA by Ivan Grokhotkov 54 | ESP8266WebServer by Ivan Grokhotkov 55 | ESP8266WiFi by Ivan Grokhotkov 56 | FastLED by Daniel Garcia 57 | RTC by Makuna 58 | IRremoteESP8266 by Sebastien Warin 59 | 60 | via Web: 61 | https://github.com/PaulStoffregen/Time 62 | https://github.com/JChristensen/Timezone 63 | https://github.com/arcao/Syslog 64 | 65 | There is a warning from FastLED about SPI when compiling. Just ignore it. 66 | ``` 67 | 68 | # QLOCKWORK 69 | ### Eine Firmware der Selbstbau-QLOCKTWO. 70 | 71 | Sie gleicht die Zeit jede Stunde per NTP mit einem Zeitserver im Internet ab. Auf der Web-Seite kann man die Uhr steuern. 72 | Updates sind OTA moeglich. Dazu im Arduino IDE den ESP als Port auswaehlen. 73 | 74 | WiFi Manager: Wenn die Uhr sich beim Start mit keinem WLAN verbinden kann, schaltet sie einen AccessPoint ein. Dann ein Handy oder Tablet mit diesem verbinden und die WLAN Daten eingeben. 75 | 76 | Die Firmware gibt es hier: https://github.com/ch570512/Qlockwork 77 | 78 | ### Standard Modi 79 | ``` 80 | Zeitanzeige: Der Standardmodus der Uhr. Er zeigt die Zeit an. :) 81 | Anzeige AM/PM: Zeigt an, ob es vormittags (AM) oder nachmittags (PM) ist. 82 | Sekunden: Anzeige der Sekunden. 83 | Datum: Anzeige des aktuellen Tages und Monats. 84 | Temperatur: Anzeige der gemessenen Temperatur. 85 | Timer Set: Setzt den Minuten-Timer. Null schaltet den Timer ab. 86 | Der Timer startet sofort mit dem Druck auf + oder -. 87 | Timer: Anzeige der Restzeit wenn ein Timer gesetzt ist. 88 | Alarm1 ein/aus 89 | Alarm1: Setzt den ersten 24-Stunden-Alarm wenn Alarm1 "ein" ist. 90 | Alarm2 ein/aus 91 | Alarm2: Setzt den zweiten 24-Stunden-Alarm wenn Alarm2 "ein" ist. 92 | ``` 93 | ### Erweiterte Modi 94 | ``` 95 | Titel MAIN: H+ und M+ druecken um direkt in die naechste oder vorhergehende Kategorie zu wechseln. 96 | Automatische Helligkeitsregelung ein/aus 97 | Helligkeitsregelung 98 | Farbe 99 | Ruecksprungverzoegerung (FB nn): Wie lange soll es dauern, bis z.B. aus der Sekundenanzeige wieder zurueck in die 100 | Zeitanzeige gewechselt wird. (0 = deaktiviert.) 101 | Sprache (DE/CH/EN/...): Die passende Sprache zur benutzten Front waehlen. 102 | 103 | Titel TIME: H+ und M+ druecken um direkt in die naechste oder vorhergehende Kategorie zu wechseln. 104 | Zeit einstellen: H+ und M+ druecken um die Zeit zu stellen. Die Sekunden springen mit jedem Druck auf Null. 105 | "Es ist" anzeigen oder nicht (IT EN/DA) 106 | Tag einstellen (DD nn): H+ und M+ druecken um den aktuellen Tag einzustellen. 107 | Monat einstellen (MM nn): H+ und M+ druecken um den aktuellen Monat einzustellen. 108 | Jahr einstellen (YY nn): H+ und M+ druecken um das aktuelle Jahr einzustellen. 109 | Nachtauschaltung (NI OF): H+ und M+ druecken um die Ausschaltzeit des Displays einzustellen. 110 | Nachtwiedereinschaltung (NI ON): H+ und M+ druecken um die Einschaltzeit des Displays einzustellen. 111 | 112 | Titel TEST: H+ und M+ druecken um direkt in die naechste oder vorhergehende Kategorie zu wechseln. 113 | LED-Test: Laesst einen waagerechten Streifen ueber das Display wandern. 114 | ``` 115 | ### Configuration.h 116 | ``` 117 | #define HOSTNAME Der Name der Uhr. 118 | #define OTA_PASS Kennwort fuer "Over the Air" Updates. 119 | #define NTP_SERVER Abzufragender NTP-Server. 120 | #define RTC_BACKUP Eine RTC als Backup verwenden. 121 | #define RTC_TEMP_OFFSET Gibt an, um wieviel Grad die gemessene Temperatur (+ oder -) korrigiert werden soll. 122 | Nur ganze Zahlen verwenden. 123 | #define BOARD_LED Zeigt mit Hilfe der LED auf dem ESP die Funktion an. Sie blinkt einmal pro Sekunde. 124 | #define NONE_TECHNICAL_ZERO Zeigt die Null ohne den diagonalen Strich. 125 | 126 | 127 | Die Zeitzone in der sich die Uhr befindet. Wichtig fuer den GMT-Versatz und die Sommer-/Winterzeitumstellung. 128 | 129 | #define TIMEZONE_PST 130 | #define TIMEZONE_MST 131 | #define TIMEZONE_CST 132 | #define TIMEZONE_EST 133 | #define TIMEZONE_GMT 134 | #define TIMEZONE_CET 135 | #define TIMEZONE_AEST 136 | 137 | 138 | #define LDR Einen LDR fuer die Helligkeitsregelung verwenden. 139 | 140 | 141 | #define MIN_BRIGHTNESS 10 Minimale Helligkeit der LEDs im Bereich von 0 bis 255. 142 | #define MAX_BRIGHTNESS 255 Maxmale Helligkeit der LEDs im Bereich von 0 bis 255. 143 | 144 | 145 | #define LED_LAYOUT_HORIZONTAL Waagerecht und Eck-LEDs am Ende des Stripes. (Von vorne gesehen.) 146 | 147 | 111 114 112 148 | 000 001 002 003 004 005 006 007 008 009 010 149 | 021 020 019 018 017 016 015 014 013 012 011 150 | 022 023 024 025 026 027 028 029 030 031 032 151 | 043 042 041 040 039 038 037 036 035 034 033 152 | 044 045 046 047 048 049 050 051 052 053 054 153 | 065 064 063 062 061 060 059 058 057 056 055 154 | 066 067 068 069 070 071 072 073 074 075 076 155 | 087 086 085 084 083 082 081 080 079 078 077 156 | 088 089 090 091 092 093 094 095 096 097 098 157 | 109 108 107 106 105 104 103 102 101 100 099 158 | 110 113 159 | 160 | #define LED_LAYOUT_VERTICAL Senkrecht und Eck-LEDs innerhalb des Stripes. (Von vorne gesehen.) 161 | 162 | 000 114 102 163 | 001 021 022 041 042 061 062 081 082 101 103 164 | 002 020 023 040 043 060 063 080 083 100 104 165 | 003 019 024 039 044 059 064 079 084 099 105 166 | 004 018 025 038 045 058 065 078 085 098 106 167 | 005 017 026 037 046 057 066 077 086 097 107 168 | 006 016 027 036 047 056 067 076 087 096 108 169 | 007 015 028 035 048 055 068 075 088 095 109 170 | 008 014 029 034 049 054 069 074 089 094 110 171 | 009 013 030 033 050 053 070 073 090 093 111 172 | 010 012 031 032 051 052 071 072 091 092 112 173 | 011 113 174 | 175 | 176 | #define LED_RGB 177 | #define LED_RGBW Da RGBW von FAST-LED (noch) nicht unterstuetzt wird, ist dies ein Hack welcher nur mit dem 178 | LPD8806 Treiber und dem Streifen der CLT2 getestet ist. Es ist zu vermuten, dass andere 179 | Streifen eine abweichende Ansteuerung verwenden und dehalb nicht korrekt funktionieren. 180 | 181 | 182 | Alle von FAST-LED unterstützten LED-Treiber koennen verwendet werden: 183 | APA102, APA104, APA106, DOTSTAR, GW6205, GW6205_400, LPD1886, LPD1886_8BIT, LPD8806, NEOPIXEL, 184 | P9813, PL9823, SK6812, SK6822, SK9822, SM16716, TM1803, TM1804, TM1809, TM1812, TM1829, UCS1903, 185 | UCS1903B, UCS1904, UCS2903, WS2801, WS2803, WS2811, WS2811_400, WS2812, WS2812B, WS2813, WS2852. 186 | 187 | 188 | #define IR_LETTER_OFF Schaltet die LED hinter dem IR-Sensor dauerhaft ab. Das verbessert den IR-Empfang. 189 | Hier das K vor Uhr. 190 | 191 | #define IR_REMOTE IR-Fernbedienung verwenden. 192 | 193 | Jede Fernbedienung kann verwendet werden. Es werden 6 Tasten unterstützt. 194 | Um die Fernbedienung anzulernen "#define DEBUG" einschalten und einen Knopf auf der Fernbedienung druecken. 195 | Den in der seriellen Konsole angezeigten Code dann in die Datei "Configuration.h" schreiben. 196 | 197 | #define IR_CODE_ONOFF 16769565 198 | #define IR_CODE_TIME 16753245 199 | #define IR_CODE_MODE 16736925 200 | #define IR_CODE_EXTMODE 16748655 201 | #define IR_CODE_PLUS 16754775 202 | #define IR_CODE_MINUS 16769055 203 | 204 | 205 | #define SERIAL_SPEED Geschwindigkeit der seriellen Schnittstelle fuer die serielle Konsole. 206 | #define DEBUG Gibt technische Informationen in der seriellen Konsole aus. 207 | #define DEBUG_MATRIX Rendert die Ausgabe der Matrix fuer die deutsche Front in der seriellen Konsole. 208 | #define DEBUG_FPS Durchlaeufe der loop() pro Sekunde. 209 | ``` 210 | -------------------------------------------------------------------------------- /Renderer.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Renderer.cpp 3 | ******************************************************************************/ 4 | 5 | #include "Renderer.h" 6 | 7 | Renderer::Renderer() { 8 | } 9 | 10 | // Zeit in den Screenbuffer schreiben 11 | void Renderer::setTime(uint8_t hours, uint8_t minutes, uint8_t language, word matrix[16]) { 12 | switch (language) { 13 | case LANGUAGE_DE_DE: 14 | case LANGUAGE_DE_SW: 15 | case LANGUAGE_DE_BA: 16 | case LANGUAGE_DE_SA: 17 | DE_ESIST; 18 | switch (minutes / 5) { 19 | case 0: 20 | // glatte Stunde 21 | setHours(hours, true, language, matrix); 22 | break; 23 | case 1: 24 | // 5 nach 25 | DE_FUENF; 26 | DE_NACH; 27 | setHours(hours, false, language, matrix); 28 | break; 29 | case 2: 30 | // 10 nach 31 | DE_ZEHN; 32 | DE_NACH; 33 | setHours(hours, false, language, matrix); 34 | break; 35 | case 3: 36 | // viertel nach 37 | if ((language == LANGUAGE_DE_SW) || (language == LANGUAGE_DE_SA)) { 38 | DE_VIERTEL; 39 | setHours(hours + 1, false, language, matrix); 40 | } 41 | else { 42 | DE_VIERTEL; 43 | DE_NACH; 44 | setHours(hours, false, language, matrix); 45 | } 46 | break; 47 | case 4: 48 | // 20 nach 49 | if (language == LANGUAGE_DE_SA) { 50 | DE_ZEHN; 51 | DE_VOR; 52 | DE_HALB; 53 | setHours(hours + 1, false, language, matrix); 54 | } 55 | else { 56 | DE_ZWANZIG; 57 | DE_NACH; 58 | setHours(hours, false, language, matrix); 59 | } 60 | break; 61 | case 5: 62 | // 5 vor halb 63 | DE_FUENF; 64 | DE_VOR; 65 | DE_HALB; 66 | setHours(hours + 1, false, language, matrix); 67 | break; 68 | case 6: 69 | // halb 70 | DE_HALB; 71 | setHours(hours + 1, false, language, matrix); 72 | break; 73 | case 7: 74 | // 5 nach halb 75 | DE_FUENF; 76 | DE_NACH; 77 | DE_HALB; 78 | setHours(hours + 1, false, language, matrix); 79 | break; 80 | case 8: 81 | // 20 vor 82 | if (language == LANGUAGE_DE_SA) { 83 | DE_ZEHN; 84 | DE_NACH; 85 | DE_HALB; 86 | setHours(hours + 1, false, language, matrix); 87 | } 88 | else { 89 | DE_ZWANZIG; 90 | DE_VOR; 91 | setHours(hours + 1, false, language, matrix); 92 | } 93 | break; 94 | case 9: 95 | // viertel vor 96 | if ((language == LANGUAGE_DE_SW) || (language == LANGUAGE_DE_BA) || (language == LANGUAGE_DE_SA)) { 97 | DE_DREIVIERTEL; 98 | setHours(hours + 1, false, language, matrix); 99 | } 100 | else { 101 | DE_VIERTEL; 102 | DE_VOR; 103 | setHours(hours + 1, false, language, matrix); 104 | } 105 | break; 106 | case 10: 107 | // 10 vor 108 | DE_ZEHN; 109 | DE_VOR; 110 | setHours(hours + 1, false, language, matrix); 111 | break; 112 | case 11: 113 | // 5 vor 114 | DE_FUENF; 115 | DE_VOR; 116 | setHours(hours + 1, false, language, matrix); 117 | break; 118 | default: 119 | ; 120 | } 121 | break; 122 | case LANGUAGE_DE_MKF_DE: 123 | case LANGUAGE_DE_MKF_SW: 124 | case LANGUAGE_DE_MKF_BA: 125 | case LANGUAGE_DE_MKF_SA: 126 | DE_MKF_ESIST; 127 | switch (minutes / 5) { 128 | case 0: 129 | // glatte Stunde 130 | setHours(hours, true, language, matrix); 131 | break; 132 | case 1: 133 | // 5 nach 134 | DE_MKF_FUENF; 135 | DE_MKF_NACH; 136 | setHours(hours, false, language, matrix); 137 | break; 138 | case 2: 139 | // 10 nach 140 | DE_MKF_ZEHN; 141 | DE_MKF_NACH; 142 | setHours(hours, false, language, matrix); 143 | break; 144 | case 3: 145 | // viertel nach 146 | if ((language == LANGUAGE_DE_MKF_SW) || (language == LANGUAGE_DE_MKF_SA)) { 147 | DE_MKF_VIERTEL; 148 | setHours(hours + 1, false, language, matrix); 149 | } 150 | else { 151 | DE_MKF_VIERTEL; 152 | DE_MKF_NACH; 153 | setHours(hours, false, language, matrix); 154 | } 155 | break; 156 | case 4: 157 | // 20 nach 158 | if (language == LANGUAGE_DE_MKF_SA) { 159 | DE_MKF_ZEHN; 160 | DE_MKF_VOR; 161 | DE_MKF_HALB; 162 | setHours(hours + 1, false, language, matrix); 163 | } 164 | else { 165 | DE_MKF_ZWANZIG; 166 | DE_MKF_NACH; 167 | setHours(hours, false, language, matrix); 168 | } 169 | break; 170 | case 5: 171 | // 5 vor halb 172 | DE_MKF_FUENF; 173 | DE_MKF_VOR; 174 | DE_MKF_HALB; 175 | setHours(hours + 1, false, language, matrix); 176 | break; 177 | case 6: 178 | // halb 179 | DE_MKF_HALB; 180 | setHours(hours + 1, false, language, matrix); 181 | break; 182 | case 7: 183 | // 5 nach halb 184 | DE_MKF_FUENF; 185 | DE_MKF_NACH; 186 | DE_MKF_HALB; 187 | setHours(hours + 1, false, language, matrix); 188 | break; 189 | case 8: 190 | // 20 vor 191 | if (language == LANGUAGE_DE_MKF_SA) { 192 | DE_MKF_ZEHN; 193 | DE_MKF_NACH; 194 | DE_MKF_HALB; 195 | setHours(hours + 1, false, language, matrix); 196 | } 197 | else { 198 | DE_MKF_ZWANZIG; 199 | DE_MKF_VOR; 200 | setHours(hours + 1, false, language, matrix); 201 | } 202 | break; 203 | case 9: 204 | // viertel vor 205 | if ((language == LANGUAGE_DE_MKF_SW) || (language == LANGUAGE_DE_MKF_BA) || (language == LANGUAGE_DE_MKF_SA)) { 206 | DE_MKF_DREIVIERTEL; 207 | setHours(hours + 1, false, language, matrix); 208 | } 209 | else { 210 | DE_MKF_VIERTEL; 211 | DE_MKF_VOR; 212 | setHours(hours + 1, false, language, matrix); 213 | } 214 | break; 215 | case 10: 216 | // 10 vor 217 | DE_MKF_ZEHN; 218 | DE_MKF_VOR; 219 | setHours(hours + 1, false, language, matrix); 220 | break; 221 | case 11: 222 | // 5 vor 223 | DE_MKF_FUENF; 224 | DE_MKF_VOR; 225 | setHours(hours + 1, false, language, matrix); 226 | break; 227 | default: 228 | ; 229 | } 230 | break; 231 | case LANGUAGE_D3: 232 | D3_ESISCH; 233 | switch (minutes / 5) { 234 | case 0: 235 | // glatte Stunde 236 | setHours(hours, true, language, matrix); 237 | break; 238 | case 1: 239 | // 5 nach 240 | D3_FUENF; 241 | D3_NACH; 242 | setHours(hours, false, language, matrix); 243 | break; 244 | case 2: 245 | // 10 nach 246 | D3_ZEHN; 247 | D3_NACH; 248 | setHours(hours, false, language, matrix); 249 | break; 250 | case 3: 251 | // viertl nach 252 | D3_VIERTL; 253 | setHours(hours + 1, false, language, matrix); 254 | break; 255 | case 4: 256 | // 10 vor halb 257 | D3_ZEHN; 258 | D3_VOR; 259 | D3_HALB; 260 | setHours(hours + 1, false, language, matrix); 261 | break; 262 | case 5: 263 | // 5 vor halb 264 | D3_FUENF; 265 | D3_VOR; 266 | D3_HALB; 267 | setHours(hours + 1, false, language, matrix); 268 | break; 269 | case 6: 270 | // halb 271 | D3_HALB; 272 | setHours(hours + 1, false, language, matrix); 273 | break; 274 | case 7: 275 | // 5 nach halb 276 | D3_FUENF; 277 | D3_NACH; 278 | D3_HALB; 279 | setHours(hours + 1, false, language, matrix); 280 | break; 281 | case 8: 282 | // 10 nach halb 283 | D3_ZEHN; 284 | D3_NACH; 285 | D3_HALB; 286 | setHours(hours + 1, false, language, matrix); 287 | break; 288 | case 9: 289 | // viertel vor 290 | D3_DREIVIERTL; 291 | setHours(hours + 1, false, language, matrix); 292 | break; 293 | case 10: 294 | // 10 vor 295 | D3_ZEHN; 296 | D3_VOR; 297 | setHours(hours + 1, false, language, matrix); 298 | break; 299 | case 11: 300 | // 5 vor 301 | D3_FUENF; 302 | D3_VOR; 303 | setHours(hours + 1, false, language, matrix); 304 | break; 305 | } 306 | break; 307 | case LANGUAGE_CH_GS: 308 | if (minutes % 5) CH_GSI; 309 | case LANGUAGE_CH: 310 | CH_ESISCH; 311 | switch (minutes / 5) { 312 | case 0: 313 | // glatte Stunde 314 | setHours(hours, true, language, matrix); 315 | break; 316 | case 1: 317 | // 5 ab 318 | CH_FUEF; 319 | CH_AB; 320 | setHours(hours, false, language, matrix); 321 | break; 322 | case 2: 323 | // 10 ab 324 | CH_ZAEAE; 325 | CH_AB; 326 | setHours(hours, false, language, matrix); 327 | break; 328 | case 3: 329 | // viertel ab 330 | CH_VIERTU; 331 | CH_AB; 332 | setHours(hours, false, language, matrix); 333 | break; 334 | case 4: 335 | // 20 ab 336 | CH_ZWAENZG; 337 | CH_AB; 338 | setHours(hours, false, language, matrix); 339 | break; 340 | case 5: 341 | // 5 vor halb 342 | CH_FUEF; 343 | CH_VOR; 344 | CH_HAUBI; 345 | setHours(hours + 1, false, language, matrix); 346 | break; 347 | case 6: 348 | // halb 349 | CH_HAUBI; 350 | setHours(hours + 1, false, language, matrix); 351 | break; 352 | case 7: 353 | // 5 ab halb 354 | CH_FUEF; 355 | CH_AB; 356 | CH_HAUBI; 357 | setHours(hours + 1, false, language, matrix); 358 | break; 359 | case 8: 360 | // 20 vor 361 | CH_ZWAENZG; 362 | CH_VOR; 363 | setHours(hours + 1, false, language, matrix); 364 | break; 365 | case 9: 366 | // viertel vor 367 | CH_VIERTU; 368 | CH_VOR; 369 | setHours(hours + 1, false, language, matrix); 370 | break; 371 | case 10: 372 | // 10 vor 373 | CH_ZAEAE; 374 | CH_VOR; 375 | setHours(hours + 1, false, language, matrix); 376 | break; 377 | case 11: 378 | // 5 vor 379 | CH_FUEF; 380 | CH_VOR; 381 | setHours(hours + 1, false, language, matrix); 382 | break; 383 | default: 384 | ; 385 | } 386 | break; 387 | case LANGUAGE_EN: 388 | EN_ITIS; 389 | switch (minutes / 5) { 390 | case 0: 391 | // glatte Stunde 392 | setHours(hours, true, language, matrix); 393 | break; 394 | case 1: 395 | // 5 nach 396 | EN_FIVE; 397 | EN_PAST; 398 | setHours(hours, false, language, matrix); 399 | break; 400 | case 2: 401 | // 10 nach 402 | EN_TEN; 403 | EN_PAST; 404 | setHours(hours, false, language, matrix); 405 | break; 406 | case 3: 407 | // viertel nach 408 | EN_A; 409 | EN_QUATER; 410 | EN_PAST; 411 | setHours(hours, false, language, matrix); 412 | break; 413 | case 4: 414 | // 20 nach 415 | EN_TWENTY; 416 | EN_PAST; 417 | setHours(hours, false, language, matrix); 418 | break; 419 | case 5: 420 | // 5 vor halb 421 | EN_TWENTY; 422 | EN_FIVE; 423 | EN_PAST; 424 | setHours(hours, false, language, matrix); 425 | break; 426 | case 6: 427 | // halb 428 | EN_HALF; 429 | EN_PAST; 430 | setHours(hours, false, language, matrix); 431 | break; 432 | case 7: 433 | // 5 nach halb 434 | EN_TWENTY; 435 | EN_FIVE; 436 | EN_TO; 437 | setHours(hours + 1, false, language, matrix); 438 | break; 439 | case 8: 440 | // 20 vor 441 | EN_TWENTY; 442 | EN_TO; 443 | setHours(hours + 1, false, language, matrix); 444 | break; 445 | case 9: 446 | // viertel vor 447 | EN_A; 448 | EN_QUATER; 449 | EN_TO; 450 | setHours(hours + 1, false, language, matrix); 451 | break; 452 | case 10: 453 | // 10 vor 454 | EN_TEN; 455 | EN_TO; 456 | setHours(hours + 1, false, language, matrix); 457 | break; 458 | case 11: 459 | // 5 vor 460 | EN_FIVE; 461 | EN_TO; 462 | setHours(hours + 1, false, language, matrix); 463 | break; 464 | } 465 | break; 466 | case LANGUAGE_ES: 467 | switch (minutes / 5) { 468 | case 0: 469 | // glatte Stunde 470 | ES_hours(hours, matrix); 471 | setHours(hours, false, language, matrix); 472 | break; 473 | case 1: 474 | // 5 nach 475 | ES_Y; 476 | ES_CINCO; 477 | ES_hours(hours, matrix); 478 | setHours(hours, false, language, matrix); 479 | break; 480 | case 2: 481 | // 10 nach 482 | ES_Y; 483 | ES_DIEZ; 484 | ES_hours(hours, matrix); 485 | setHours(hours, false, language, matrix); 486 | break; 487 | case 3: 488 | // viertel nach 489 | ES_Y; 490 | ES_CUARTO; 491 | ES_hours(hours, matrix); 492 | setHours(hours, false, language, matrix); 493 | break; 494 | case 4: 495 | // 20 nach 496 | ES_Y; 497 | ES_VEINTE; 498 | ES_hours(hours, matrix); 499 | setHours(hours, false, language, matrix); 500 | break; 501 | case 5: 502 | // 5 vor halb 503 | ES_Y; 504 | ES_VEINTICINCO; 505 | ES_hours(hours, matrix); 506 | setHours(hours, false, language, matrix); 507 | break; 508 | case 6: 509 | // halb 510 | ES_Y; 511 | ES_MEDIA; 512 | ES_hours(hours, matrix); 513 | setHours(hours, false, language, matrix); 514 | break; 515 | case 7: 516 | // 5 nach halb 517 | ES_MENOS; 518 | ES_VEINTICINCO; 519 | ES_hours(hours + 1, matrix); 520 | setHours(hours + 1, false, language, matrix); 521 | break; 522 | case 8: 523 | // 20 vor 524 | ES_MENOS; 525 | ES_VEINTE; 526 | ES_hours(hours + 1, matrix); 527 | setHours(hours + 1, false, language, matrix); 528 | break; 529 | case 9: 530 | // viertel vor 531 | ES_MENOS; 532 | ES_CUARTO; 533 | ES_hours(hours + 1, matrix); 534 | setHours(hours + 1, false, language, matrix); 535 | break; 536 | case 10: 537 | // 10 vor 538 | ES_MENOS; 539 | ES_DIEZ; 540 | ES_hours(hours + 1, matrix); 541 | setHours(hours + 1, false, language, matrix); 542 | break; 543 | case 11: 544 | // 5 vor 545 | ES_MENOS; 546 | ES_CINCO; 547 | ES_hours(hours + 1, matrix); 548 | setHours(hours + 1, false, language, matrix); 549 | break; 550 | } 551 | break; 552 | case LANGUAGE_FR: 553 | FR_ILEST; 554 | switch (minutes / 5) { 555 | case 0: 556 | // glatte Stunde 557 | setHours(hours, true, language, matrix); 558 | FR_hours(hours, matrix); 559 | break; 560 | case 1: 561 | // 5 nach 562 | setHours(hours, false, language, matrix); 563 | FR_hours(hours, matrix); 564 | FR_CINQ; 565 | break; 566 | case 2: 567 | // 10 nach 568 | setHours(hours, false, language, matrix); 569 | FR_hours(hours, matrix); 570 | FR_DIX; 571 | break; 572 | case 3: 573 | // viertel nach 574 | setHours(hours, false, language, matrix); 575 | FR_hours(hours, matrix); 576 | FR_ET; 577 | FR_QUART; 578 | break; 579 | case 4: 580 | // 20 nach 581 | setHours(hours, false, language, matrix); 582 | FR_hours(hours, matrix); 583 | FR_VINGT; 584 | break; 585 | case 5: 586 | // 5 vor halb 587 | setHours(hours, false, language, matrix); 588 | FR_hours(hours, matrix); 589 | FR_VINGT; 590 | FR_TRAIT; 591 | FR_CINQ; 592 | break; 593 | case 6: 594 | // halb 595 | setHours(hours, false, language, matrix); 596 | FR_hours(hours, matrix); 597 | FR_ET; 598 | FR_DEMIE; 599 | break; 600 | case 7: 601 | // 5 nach halb 602 | setHours(hours + 1, false, language, matrix); 603 | FR_hours(hours + 1, matrix); 604 | FR_MOINS; 605 | FR_VINGT; 606 | FR_TRAIT; 607 | FR_CINQ; 608 | break; 609 | case 8: 610 | // 20 vor 611 | setHours(hours + 1, false, language, matrix); 612 | FR_hours(hours + 1, matrix); 613 | FR_MOINS; 614 | FR_VINGT; 615 | break; 616 | case 9: 617 | // viertel vor 618 | setHours(hours + 1, false, language, matrix); 619 | FR_hours(hours + 1, matrix); 620 | FR_MOINS; 621 | FR_LE; 622 | FR_QUART; 623 | break; 624 | case 10: 625 | // 10 vor 626 | setHours(hours + 1, false, language, matrix); 627 | FR_hours(hours + 1, matrix); 628 | FR_MOINS; 629 | FR_DIX; 630 | break; 631 | case 11: 632 | // 5 vor 633 | setHours(hours + 1, false, language, matrix); 634 | FR_hours(hours + 1, matrix); 635 | FR_MOINS; 636 | FR_CINQ; 637 | break; 638 | } 639 | break; 640 | case LANGUAGE_IT: 641 | switch (minutes / 5) { 642 | case 0: 643 | // glatte Stunde 644 | setHours(hours, true, language, matrix); 645 | IT_hours(hours, matrix); 646 | break; 647 | case 1: 648 | // 5 nach 649 | IT_E2; 650 | IT_CINQUE; 651 | setHours(hours, false, language, matrix); 652 | IT_hours(hours, matrix); 653 | break; 654 | case 2: 655 | // 10 nach 656 | IT_E2; 657 | IT_DIECI; 658 | setHours(hours, false, language, matrix); 659 | IT_hours(hours, matrix); 660 | break; 661 | case 3: 662 | // viertel nach 663 | IT_E2; 664 | IT_UN; 665 | IT_QUARTO; 666 | setHours(hours, false, language, matrix); 667 | IT_hours(hours, matrix); 668 | break; 669 | case 4: 670 | // 20 nach 671 | IT_E2; 672 | IT_VENTI; 673 | setHours(hours, false, language, matrix); 674 | IT_hours(hours, matrix); 675 | break; 676 | case 5: 677 | // 5 vor halb 678 | IT_E2; 679 | IT_VENTI; 680 | IT_CINQUE; 681 | setHours(hours, false, language, matrix); 682 | IT_hours(hours, matrix); 683 | break; 684 | case 6: 685 | // halb 686 | IT_E2; 687 | IT_MEZZA; 688 | setHours(hours, false, language, matrix); 689 | IT_hours(hours, matrix); 690 | break; 691 | case 7: 692 | // 5 nach halb 693 | IT_MENO; 694 | IT_VENTI; 695 | IT_CINQUE; 696 | setHours(hours + 1, false, language, matrix); 697 | IT_hours(hours + 1, matrix); 698 | break; 699 | case 8: 700 | // 20 vor 701 | IT_MENO; 702 | IT_VENTI; 703 | setHours(hours + 1, false, language, matrix); 704 | IT_hours(hours + 1, matrix); 705 | break; 706 | case 9: 707 | // viertel vor 708 | IT_MENO; 709 | IT_UN; 710 | IT_QUARTO; 711 | setHours(hours + 1, false, language, matrix); 712 | IT_hours(hours + 1, matrix); 713 | break; 714 | case 10: 715 | // 10 vor 716 | IT_MENO; 717 | IT_DIECI; 718 | setHours(hours + 1, false, language, matrix); 719 | IT_hours(hours + 1, matrix); 720 | break; 721 | case 11: 722 | // 5 vor 723 | IT_MENO; 724 | IT_CINQUE; 725 | setHours(hours + 1, false, language, matrix); 726 | IT_hours(hours + 1, matrix); 727 | break; 728 | } 729 | break; 730 | case LANGUAGE_NL: 731 | NL_HETIS; 732 | switch (minutes / 5) { 733 | case 0: 734 | // glatte Stunde 735 | setHours(hours, true, language, matrix); 736 | break; 737 | case 1: 738 | // 5 nach 739 | NL_VIJF; 740 | NL_OVER; 741 | setHours(hours, false, language, matrix); 742 | break; 743 | case 2: 744 | // 10 nach 745 | NL_TIEN; 746 | NL_OVER; 747 | setHours(hours, false, language, matrix); 748 | break; 749 | case 3: 750 | // viertel nach 751 | NL_KWART; 752 | NL_OVER2; 753 | setHours(hours, false, language, matrix); 754 | break; 755 | case 4: 756 | // 10 vor halb 757 | NL_TIEN; 758 | NL_VOOR; 759 | NL_HALF; 760 | setHours(hours + 1, false, language, matrix); 761 | break; 762 | case 5: 763 | // 5 vor halb 764 | NL_VIJF; 765 | NL_VOOR; 766 | NL_HALF; 767 | setHours(hours + 1, false, language, matrix); 768 | break; 769 | case 6: 770 | // halb 771 | NL_HALF; 772 | setHours(hours + 1, false, language, matrix); 773 | break; 774 | case 7: 775 | // 5 nach halb 776 | NL_VIJF; 777 | NL_OVER; 778 | NL_HALF; 779 | setHours(hours + 1, false, language, matrix); 780 | break; 781 | case 8: 782 | // 20 vor 783 | NL_TIEN; 784 | NL_OVER; 785 | NL_HALF; 786 | setHours(hours + 1, false, language, matrix); 787 | break; 788 | case 9: 789 | // viertel vor 790 | NL_KWART; 791 | NL_VOOR2; 792 | setHours(hours + 1, false, language, matrix); 793 | break; 794 | case 10: 795 | // 10 vor 796 | NL_TIEN; 797 | NL_VOOR; 798 | setHours(hours + 1, false, language, matrix); 799 | break; 800 | case 11: 801 | // 5 vor 802 | NL_VIJF; 803 | NL_VOOR; 804 | setHours(hours + 1, false, language, matrix); 805 | break; 806 | } 807 | break; 808 | default: 809 | ; 810 | } 811 | } 812 | 813 | // Stunden in den Screenbuffer schreiben 814 | void Renderer::setHours(uint8_t hours, boolean glatt, uint8_t language, word matrix[16]) { 815 | switch (language) { 816 | case LANGUAGE_DE_DE: 817 | case LANGUAGE_DE_SW: 818 | case LANGUAGE_DE_BA: 819 | case LANGUAGE_DE_SA: 820 | if (glatt) { 821 | DE_UHR; 822 | } 823 | switch (hours) { 824 | case 0: 825 | case 12: 826 | case 24: 827 | DE_H_ZWOELF; 828 | break; 829 | case 1: 830 | case 13: 831 | if (glatt) { 832 | DE_H_EIN; 833 | } 834 | else { 835 | DE_H_EINS; 836 | } 837 | break; 838 | case 2: 839 | case 14: 840 | DE_H_ZWEI; 841 | break; 842 | case 3: 843 | case 15: 844 | DE_H_DREI; 845 | break; 846 | case 4: 847 | case 16: 848 | DE_H_VIER; 849 | break; 850 | case 5: 851 | case 17: 852 | DE_H_FUENF; 853 | break; 854 | case 6: 855 | case 18: 856 | DE_H_SECHS; 857 | break; 858 | case 7: 859 | case 19: 860 | DE_H_SIEBEN; 861 | break; 862 | case 8: 863 | case 20: 864 | DE_H_ACHT; 865 | break; 866 | case 9: 867 | case 21: 868 | DE_H_NEUN; 869 | break; 870 | case 10: 871 | case 22: 872 | DE_H_ZEHN; 873 | break; 874 | case 11: 875 | case 23: 876 | DE_H_ELF; 877 | break; 878 | default: 879 | ; 880 | } 881 | break; 882 | case LANGUAGE_DE_MKF_DE: 883 | case LANGUAGE_DE_MKF_SW: 884 | case LANGUAGE_DE_MKF_BA: 885 | case LANGUAGE_DE_MKF_SA: 886 | if (glatt) { 887 | DE_MKF_UHR; 888 | } 889 | switch (hours) { 890 | case 0: 891 | case 12: 892 | case 24: 893 | DE_MKF_H_ZWOELF; 894 | break; 895 | case 1: 896 | case 13: 897 | if (glatt) { 898 | DE_MKF_H_EIN; 899 | } 900 | else { 901 | DE_MKF_H_EINS; 902 | } 903 | break; 904 | case 2: 905 | case 14: 906 | DE_MKF_H_ZWEI; 907 | break; 908 | case 3: 909 | case 15: 910 | DE_MKF_H_DREI; 911 | break; 912 | case 4: 913 | case 16: 914 | DE_MKF_H_VIER; 915 | break; 916 | case 5: 917 | case 17: 918 | DE_MKF_H_FUENF; 919 | break; 920 | case 6: 921 | case 18: 922 | DE_MKF_H_SECHS; 923 | break; 924 | case 7: 925 | case 19: 926 | DE_MKF_H_SIEBEN; 927 | break; 928 | case 8: 929 | case 20: 930 | DE_MKF_H_ACHT; 931 | break; 932 | case 9: 933 | case 21: 934 | DE_MKF_H_NEUN; 935 | break; 936 | case 10: 937 | case 22: 938 | DE_MKF_H_ZEHN; 939 | break; 940 | case 11: 941 | case 23: 942 | DE_MKF_H_ELF; 943 | break; 944 | default: 945 | ; 946 | } 947 | break; 948 | case LANGUAGE_D3: 949 | switch (hours) { 950 | case 0: 951 | case 12: 952 | case 24: 953 | D3_H_ZWOELFE; 954 | break; 955 | case 1: 956 | case 13: 957 | D3_H_OISE; 958 | break; 959 | case 2: 960 | case 14: 961 | D3_H_ZWOIE; 962 | break; 963 | case 3: 964 | case 15: 965 | D3_H_DREIE; 966 | break; 967 | case 4: 968 | case 16: 969 | D3_H_VIERE; 970 | break; 971 | case 5: 972 | case 17: 973 | D3_H_FUENFE; 974 | break; 975 | case 6: 976 | case 18: 977 | D3_H_SECHSE; 978 | break; 979 | case 7: 980 | case 19: 981 | D3_H_SIEBNE; 982 | break; 983 | case 8: 984 | case 20: 985 | D3_H_ACHTE; 986 | break; 987 | case 9: 988 | case 21: 989 | D3_H_NEUNE; 990 | break; 991 | case 10: 992 | case 22: 993 | D3_H_ZEHNE; 994 | break; 995 | case 11: 996 | case 23: 997 | D3_H_ELFE; 998 | break; 999 | } 1000 | break; 1001 | case LANGUAGE_CH: 1002 | case LANGUAGE_CH_GS: 1003 | switch (hours) { 1004 | case 0: 1005 | case 12: 1006 | case 24: 1007 | CH_H_ZWOEUFI; 1008 | break; 1009 | case 1: 1010 | case 13: 1011 | CH_H_EIS; 1012 | break; 1013 | case 2: 1014 | case 14: 1015 | CH_H_ZWOEI; 1016 | break; 1017 | case 3: 1018 | case 15: 1019 | CH_H_DRUE; 1020 | break; 1021 | case 4: 1022 | case 16: 1023 | CH_H_VIER; 1024 | break; 1025 | case 5: 1026 | case 17: 1027 | CH_H_FUEFI; 1028 | break; 1029 | case 6: 1030 | case 18: 1031 | CH_H_SAECHSI; 1032 | break; 1033 | case 7: 1034 | case 19: 1035 | CH_H_SIEBNI; 1036 | break; 1037 | case 8: 1038 | case 20: 1039 | CH_H_ACHTI; 1040 | break; 1041 | case 9: 1042 | case 21: 1043 | CH_H_NUENI; 1044 | break; 1045 | case 10: 1046 | case 22: 1047 | CH_H_ZAENI; 1048 | break; 1049 | case 11: 1050 | case 23: 1051 | CH_H_EUFI; 1052 | break; 1053 | default: 1054 | ; 1055 | } 1056 | break; 1057 | case LANGUAGE_EN: 1058 | if (glatt) EN_OCLOCK; 1059 | switch (hours) { 1060 | case 0: 1061 | case 12: 1062 | case 24: 1063 | EN_H_TWELVE; 1064 | break; 1065 | case 1: 1066 | case 13: 1067 | EN_H_ONE; 1068 | break; 1069 | case 2: 1070 | case 14: 1071 | EN_H_TWO; 1072 | break; 1073 | case 3: 1074 | case 15: 1075 | EN_H_THREE; 1076 | break; 1077 | case 4: 1078 | case 16: 1079 | EN_H_FOUR; 1080 | break; 1081 | case 5: 1082 | case 17: 1083 | EN_H_FIVE; 1084 | break; 1085 | case 6: 1086 | case 18: 1087 | EN_H_SIX; 1088 | break; 1089 | case 7: 1090 | case 19: 1091 | EN_H_SEVEN; 1092 | break; 1093 | case 8: 1094 | case 20: 1095 | EN_H_EIGHT; 1096 | break; 1097 | case 9: 1098 | case 21: 1099 | EN_H_NINE; 1100 | break; 1101 | case 10: 1102 | case 22: 1103 | EN_H_TEN; 1104 | break; 1105 | case 11: 1106 | case 23: 1107 | EN_H_ELEVEN; 1108 | break; 1109 | } 1110 | break; 1111 | case LANGUAGE_ES: 1112 | switch (hours) { 1113 | case 0: 1114 | case 12: 1115 | case 24: 1116 | ES_H_DOCE; 1117 | break; 1118 | case 1: 1119 | case 13: 1120 | ES_H_UNA; 1121 | break; 1122 | case 2: 1123 | case 14: 1124 | ES_H_DOS; 1125 | break; 1126 | case 3: 1127 | case 15: 1128 | ES_H_TRES; 1129 | break; 1130 | case 4: 1131 | case 16: 1132 | ES_H_CUATRO; 1133 | break; 1134 | case 5: 1135 | case 17: 1136 | ES_H_CINCO; 1137 | break; 1138 | case 6: 1139 | case 18: 1140 | ES_H_SEIS; 1141 | break; 1142 | case 7: 1143 | case 19: 1144 | ES_H_SIETE; 1145 | break; 1146 | case 8: 1147 | case 20: 1148 | ES_H_OCHO; 1149 | break; 1150 | case 9: 1151 | case 21: 1152 | ES_H_NUEVE; 1153 | break; 1154 | case 10: 1155 | case 22: 1156 | ES_H_DIEZ; 1157 | break; 1158 | case 11: 1159 | case 23: 1160 | ES_H_ONCE; 1161 | break; 1162 | } 1163 | break; 1164 | case LANGUAGE_FR: 1165 | switch (hours) { 1166 | case 0: 1167 | case 24: 1168 | FR_H_MINUIT; 1169 | break; 1170 | case 12: 1171 | FR_H_MIDI; 1172 | break; 1173 | case 1: 1174 | case 13: 1175 | FR_H_UNE; 1176 | break; 1177 | case 2: 1178 | case 14: 1179 | FR_H_DEUX; 1180 | break; 1181 | case 3: 1182 | case 15: 1183 | FR_H_TROIS; 1184 | break; 1185 | case 4: 1186 | case 16: 1187 | FR_H_QUATRE; 1188 | break; 1189 | case 5: 1190 | case 17: 1191 | FR_H_CINQ; 1192 | break; 1193 | case 6: 1194 | case 18: 1195 | FR_H_SIX; 1196 | break; 1197 | case 7: 1198 | case 19: 1199 | FR_H_SEPT; 1200 | break; 1201 | case 8: 1202 | case 20: 1203 | FR_H_HUIT; 1204 | break; 1205 | case 9: 1206 | case 21: 1207 | FR_H_NEUF; 1208 | break; 1209 | case 10: 1210 | case 22: 1211 | FR_H_DIX; 1212 | break; 1213 | case 11: 1214 | case 23: 1215 | FR_H_ONZE; 1216 | break; 1217 | } 1218 | break; 1219 | case LANGUAGE_IT: 1220 | switch (hours) { 1221 | case 0: 1222 | case 12: 1223 | case 24: 1224 | IT_H_DODICI; 1225 | break; 1226 | case 1: 1227 | case 13: 1228 | IT_H_LUNA; 1229 | break; 1230 | case 2: 1231 | case 14: 1232 | IT_H_DUE; 1233 | break; 1234 | case 3: 1235 | case 15: 1236 | IT_H_TRE; 1237 | break; 1238 | case 4: 1239 | case 16: 1240 | IT_H_QUATTRO; 1241 | break; 1242 | case 5: 1243 | case 17: 1244 | IT_H_CINQUE; 1245 | break; 1246 | case 6: 1247 | case 18: 1248 | IT_H_SEI; 1249 | break; 1250 | case 7: 1251 | case 19: 1252 | IT_H_SETTE; 1253 | break; 1254 | case 8: 1255 | case 20: 1256 | IT_H_OTTO; 1257 | break; 1258 | case 9: 1259 | case 21: 1260 | IT_H_NOVE; 1261 | break; 1262 | case 10: 1263 | case 22: 1264 | IT_H_DIECI; 1265 | break; 1266 | case 11: 1267 | case 23: 1268 | IT_H_UNDICI; 1269 | break; 1270 | } 1271 | break; 1272 | case LANGUAGE_NL: 1273 | if (glatt) NL_UUR; 1274 | switch (hours) { 1275 | case 0: 1276 | case 12: 1277 | case 24: 1278 | NL_H_TWAALF; 1279 | break; 1280 | case 1: 1281 | case 13: 1282 | NL_H_EEN; 1283 | break; 1284 | case 2: 1285 | case 14: 1286 | NL_H_TWEE; 1287 | break; 1288 | case 3: 1289 | case 15: 1290 | NL_H_DRIE; 1291 | break; 1292 | case 4: 1293 | case 16: 1294 | NL_H_VIER; 1295 | break; 1296 | case 5: 1297 | case 17: 1298 | NL_H_VIJF; 1299 | break; 1300 | case 6: 1301 | case 18: 1302 | NL_H_ZES; 1303 | break; 1304 | case 7: 1305 | case 19: 1306 | NL_H_ZEVEN; 1307 | break; 1308 | case 8: 1309 | case 20: 1310 | NL_H_ACHT; 1311 | break; 1312 | case 9: 1313 | case 21: 1314 | NL_H_NEGEN; 1315 | break; 1316 | case 10: 1317 | case 22: 1318 | NL_H_TIEN; 1319 | break; 1320 | case 11: 1321 | case 23: 1322 | NL_H_ELF; 1323 | break; 1324 | } 1325 | break; 1326 | default: 1327 | ; 1328 | } 1329 | } 1330 | 1331 | void Renderer::clearEntryWords(uint8_t language, word matrix[16]) { 1332 | switch (language) { 1333 | case LANGUAGE_DE_DE: 1334 | case LANGUAGE_DE_SW: 1335 | case LANGUAGE_DE_BA: 1336 | case LANGUAGE_DE_SA: 1337 | matrix[0] &= 0b0010001111111111; // ES IST weg 1338 | break; 1339 | case LANGUAGE_DE_MKF_DE: 1340 | case LANGUAGE_DE_MKF_SW: 1341 | case LANGUAGE_DE_MKF_BA: 1342 | case LANGUAGE_DE_MKF_SA: 1343 | matrix[0] &= 0b0010001111111111; // ES IST weg 1344 | break; 1345 | case LANGUAGE_D3: 1346 | matrix[0] &= 0b0010000111111111; // ES ISCH weg 1347 | break; 1348 | case LANGUAGE_CH: 1349 | case LANGUAGE_CH_GS: 1350 | matrix[0] &= 0b0010000111111111; // ES ISCH weg 1351 | break; 1352 | case LANGUAGE_EN: 1353 | matrix[0] &= 0b0010011111111111; // IT IS weg 1354 | break; 1355 | case LANGUAGE_ES: 1356 | matrix[0] &= 0b1000100011111111; // SON LAS weg 1357 | matrix[0] &= 0b0011100111111111; // ES LA weg 1358 | break; 1359 | case LANGUAGE_FR: 1360 | matrix[0] &= 0b0010001111111111; // IL EST weg 1361 | break; 1362 | case LANGUAGE_IT: 1363 | matrix[0] &= 0b0000100111111111; // SONO LE weg 1364 | matrix[1] &= 0b0111111111111111; // E (L'UNA) weg 1365 | break; 1366 | case LANGUAGE_NL: 1367 | matrix[0] &= 0b0001001111111111; // HET IS weg 1368 | break; 1369 | default: 1370 | ; 1371 | } 1372 | } 1373 | 1374 | // AM oder PM einschalten 1375 | void Renderer::setAMPM(uint8_t hours, uint8_t language, word matrix[16]) { 1376 | switch (language) { 1377 | case LANGUAGE_DE_DE: 1378 | case LANGUAGE_DE_SW: 1379 | case LANGUAGE_DE_BA: 1380 | case LANGUAGE_DE_SA: 1381 | if (hours < 12) DE_AM; 1382 | else DE_PM; 1383 | break; 1384 | case LANGUAGE_DE_MKF_DE: 1385 | case LANGUAGE_DE_MKF_SW: 1386 | case LANGUAGE_DE_MKF_BA: 1387 | case LANGUAGE_DE_MKF_SA: 1388 | if (hours < 12) DE_MKF_AM; 1389 | else DE_MKF_PM; 1390 | break; 1391 | case LANGUAGE_D3: 1392 | if (hours < 12) D3_AM; 1393 | else D3_PM; 1394 | break; 1395 | case LANGUAGE_CH: 1396 | case LANGUAGE_CH_GS: 1397 | if (hours < 12) CH_AM; 1398 | else CH_PM; 1399 | break; 1400 | case LANGUAGE_EN: 1401 | if (hours < 12) EN_AM; 1402 | else EN_PM; 1403 | break; 1404 | case LANGUAGE_ES: 1405 | if (hours < 12) ES_AM; 1406 | else ES_PM; 1407 | break; 1408 | case LANGUAGE_FR: 1409 | if (hours < 12) FR_AM; 1410 | else FR_PM; 1411 | break; 1412 | case LANGUAGE_IT: 1413 | if (hours < 12) IT_AM; 1414 | else IT_PM; 1415 | break; 1416 | case LANGUAGE_NL: 1417 | if (hours < 12) NL_AM; 1418 | else NL_PM; 1419 | break; 1420 | default: 1421 | ; 1422 | } 1423 | } 1424 | 1425 | // Sonderfall ES 1426 | void Renderer::ES_hours(uint8_t hours, word matrix[16]) { 1427 | if ((hours == 1) || (hours == 13)) ES_ESLA; 1428 | else ES_SONLAS; 1429 | } 1430 | 1431 | // Sonderfall FR 1432 | void Renderer::FR_hours(uint8_t hours, word matrix[16]) { 1433 | if ((hours == 1) || (hours == 13)) FR_HEURE; 1434 | else if ((hours == 0) || (hours == 12) || (hours == 24)); 1435 | else FR_HEURES; 1436 | } 1437 | 1438 | // Sonderfall IT 1439 | void Renderer::IT_hours(uint8_t hours, word matrix[16]) { 1440 | if ((hours != 1) && (hours != 13)) IT_SONOLE; 1441 | else IT_E; 1442 | } 1443 | 1444 | // Minuten in den Screebuffer schreiben 1445 | void Renderer::setCorners(uint8_t minutes, word matrix[16]) { 1446 | uint8_t b_minutes = minutes % 5; 1447 | for (uint8_t i = 0; i < b_minutes; i++) { 1448 | uint8_t j; 1449 | j = (1 - i + 4) % 4; 1450 | bitSet(matrix[j], 4); 1451 | } 1452 | } 1453 | 1454 | // Alarm-LED setzen 1455 | void Renderer::activateAlarmLed(word matrix[16]) { 1456 | bitSet(matrix[4], 4); 1457 | } 1458 | 1459 | // Alarm-LED setzen 1460 | void Renderer::deactivateAlarmLed(word matrix[16]) { 1461 | bitClear(matrix[4], 4); 1462 | } 1463 | 1464 | // Menuetext in den Screenbuffer schreiben 1465 | void Renderer::setSmallText(String menuText, eTextPos textPos, word matrix[16]) { 1466 | if (menuText.length() == 2) { 1467 | for (uint8_t i = 0; i < 5; i++) { 1468 | for (uint8_t j = 0; j < menuText.length(); j++) { 1469 | if (!isNumber(menuText[j])) matrix[textPos + i] |= (staben[menuText[j] - 'A'][i]) << (5 + ((j + 1) % 2) * 6); 1470 | else matrix[textPos + i] |= (zahlenKlein[menuText[j] - '0'][i]) << (5 + ((j + 1) % 2) * 5); 1471 | } 1472 | } 1473 | } 1474 | else if (menuText.length() == 1) { 1475 | for (uint8_t i = 0; i < 5; i++) { 1476 | if (!isNumber(menuText[0])) matrix[textPos + i] |= (staben[menuText[0] - 'A'][i]) << 8; 1477 | else matrix[textPos + i] |= (zahlenKlein[menuText[0] - '0'][i]) << 8; 1478 | } 1479 | } 1480 | } 1481 | 1482 | // Test ob Zahl 1483 | boolean Renderer::isNumber(char symbol) { 1484 | if ((symbol >= '0') && (symbol <= '9')) return true; 1485 | else return false; 1486 | } 1487 | 1488 | // Einen Pixel in den Screenbuffer schreiben 1489 | void Renderer::setPixelInScreenBuffer(uint8_t x, uint8_t y, word matrix[16]) { 1490 | bitSet(matrix[y], x); 1491 | } 1492 | 1493 | // Einen Pixel aus dem Screenbuffer loeschen 1494 | void Renderer::unsetPixelInScreenBuffer(uint8_t x, uint8_t y, word matrix[16]) { 1495 | bitClear(matrix[y], x); 1496 | } 1497 | 1498 | // Screenbuffer loeschen 1499 | void Renderer::clearScreenBuffer(word matrix[16]) { 1500 | for (uint8_t i = 0; i < 16; i++) matrix[i] = 0b0000000000000000; 1501 | } 1502 | 1503 | // Screenbuffer komplett einschalten 1504 | void Renderer::setAllScreenBuffer(word matrix[16]) { 1505 | for (uint8_t i = 0; i < 16; i++) matrix[i] = 0b1111111111111111; 1506 | } 1507 | -------------------------------------------------------------------------------- /Renderer.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Renderer.h 3 | ******************************************************************************/ 4 | 5 | #ifndef RENDERER_H 6 | #define RENDERER_H 7 | 8 | #include 9 | #include "Woerter_DE.h" 10 | #include "Woerter_DE_MKF.h" 11 | #include "Woerter_D3.h" 12 | #include "Woerter_CH.h" 13 | #include "Woerter_EN.h" 14 | #include "Woerter_ES.h" 15 | #include "Woerter_FR.h" 16 | #include "Woerter_IT.h" 17 | #include "Woerter_NL.h" 18 | #include "Languages.h" 19 | #include "Staben.h" 20 | #include "Zahlen.h" 21 | 22 | class Renderer { 23 | public: 24 | enum eTextPos : uint8_t { 25 | TEXT_POS_TOP, 26 | TEXT_POS_MIDDLE = 2, 27 | TEXT_POS_BOTTOM = 5 28 | }; 29 | 30 | Renderer(); 31 | void setHours(uint8_t hours, boolean glatt, uint8_t language, word matrix[16]); 32 | void setTime(uint8_t hours, uint8_t minutes, uint8_t language, word matrix[16]); 33 | void setCorners(uint8_t minutes, word matrix[16]); 34 | void activateAlarmLed(word matrix[16]); 35 | void deactivateAlarmLed(word matrix[16]); 36 | void clearEntryWords(uint8_t language, word matrix[16]); 37 | void setSmallText(String menuText, eTextPos textPos, word matrix[16]); 38 | void setAMPM(uint8_t hours, uint8_t language, word matrix[16]); 39 | void setPixelInScreenBuffer(uint8_t x, uint8_t y, word matrix[16]); 40 | void unsetPixelInScreenBuffer(uint8_t x, uint8_t y, word matrix[16]); 41 | void clearScreenBuffer(word matrix[16]); 42 | void setAllScreenBuffer(word matrix[16]); 43 | 44 | private: 45 | boolean isNumber(char symbol); 46 | 47 | void FR_hours(uint8_t hours, word matrix[16]); 48 | void IT_hours(uint8_t hours, word matrix[16]); 49 | void ES_hours(uint8_t hours, word matrix[16]); 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /Settings.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Settings.cpp 3 | ******************************************************************************/ 4 | 5 | #include "Settings.h" 6 | 7 | Settings::Settings() { 8 | loadFromEEPROM(); 9 | } 10 | 11 | uint8_t Settings::getLanguage() { 12 | return mySettings.language; 13 | } 14 | 15 | void Settings::setLanguage(uint8_t language) { 16 | mySettings.language = language; 17 | } 18 | 19 | boolean Settings::getUseLdr() { 20 | return mySettings.useLdr; 21 | } 22 | 23 | void Settings::toggleUseLdr() { 24 | mySettings.useLdr = !mySettings.useLdr; 25 | } 26 | 27 | int16_t Settings::getBrightness() { 28 | return mySettings.brightness; 29 | } 30 | 31 | void Settings::setBrightness(int16_t ledBrightness) { 32 | mySettings.brightness = ledBrightness; 33 | } 34 | 35 | void Settings::setColor(uint8_t color) { 36 | mySettings.color = color; 37 | } 38 | 39 | uint8_t Settings::getColor() { 40 | return mySettings.color; 41 | } 42 | 43 | uint8_t Settings::getTimeout() { 44 | return mySettings.timeout; 45 | } 46 | 47 | void Settings::setTimeout(uint8_t timeout) { 48 | mySettings.timeout = timeout; 49 | } 50 | 51 | boolean Settings::getEsIst() { 52 | return mySettings.esIst; 53 | } 54 | 55 | void Settings::toggleEsIst() { 56 | mySettings.esIst = !mySettings.esIst; 57 | } 58 | 59 | boolean Settings::getAlarm1() { 60 | return mySettings.alarm1; 61 | } 62 | 63 | void Settings::toggleAlarm1() { 64 | mySettings.alarm1 = !mySettings.alarm1; 65 | } 66 | 67 | time_t Settings::getAlarmTime1() { 68 | return mySettings.alarmTime1; 69 | } 70 | 71 | void Settings::setAlarmTime1(time_t alarmTime) { 72 | mySettings.alarmTime1 = alarmTime; 73 | } 74 | 75 | boolean Settings::getAlarm2() { 76 | return mySettings.alarm2; 77 | } 78 | 79 | void Settings::toggleAlarm2() { 80 | mySettings.alarm2 = !mySettings.alarm2; 81 | } 82 | 83 | time_t Settings::getAlarmTime2() { 84 | return mySettings.alarmTime2; 85 | } 86 | 87 | void Settings::setAlarmTime2(time_t alarmTime) { 88 | mySettings.alarmTime2 = alarmTime; 89 | } 90 | 91 | time_t Settings::getNightOffTime() { 92 | return mySettings.nightOffTime; 93 | } 94 | 95 | void Settings::setNightOffTime(time_t nightOffTime) { 96 | mySettings.nightOffTime = nightOffTime; 97 | } 98 | 99 | time_t Settings::getNightOnTime() { 100 | return mySettings.nightOnTime; 101 | } 102 | 103 | void Settings::setNightOnTime(time_t nightOnTime) { 104 | mySettings.nightOnTime = nightOnTime; 105 | } 106 | 107 | 108 | // Setzt alle Werte auf Defaulteinstellungen 109 | void Settings::resetToDefault() { 110 | mySettings.magicNumber = SETTINGS_MAGIC_NUMBER; 111 | mySettings.version = SETTINGS_VERSION; 112 | mySettings.language = 0; 113 | mySettings.useLdr = false; 114 | mySettings.brightness = 128; 115 | mySettings.color = 0; 116 | mySettings.timeout = 5; 117 | mySettings.esIst = true; 118 | mySettings.alarm1 = false; 119 | mySettings.alarmTime1 = 0; 120 | mySettings.alarm2 = false; 121 | mySettings.alarmTime2 = 0; 122 | mySettings.nightOffTime = 0; 123 | mySettings.nightOnTime = 0; 124 | saveToEEPROM(); 125 | } 126 | 127 | // Einstellungen laden 128 | void Settings::loadFromEEPROM() { 129 | EEPROM.begin(512); 130 | EEPROM.get(0, mySettings); 131 | if ((mySettings.magicNumber != SETTINGS_MAGIC_NUMBER) || (mySettings.version != SETTINGS_VERSION)) resetToDefault(); 132 | } 133 | 134 | // Einstellungen speichern 135 | void Settings::saveToEEPROM() { 136 | EEPROM.begin(512); 137 | EEPROM.put(0, mySettings); 138 | EEPROM.commit(); 139 | } 140 | -------------------------------------------------------------------------------- /Settings.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Settings.h 3 | ******************************************************************************/ 4 | 5 | #ifndef SETTINGS_H 6 | #define SETTINGS_H 7 | 8 | #include 9 | #include 10 | 11 | #define SETTINGS_MAGIC_NUMBER 0x2A 12 | #define SETTINGS_VERSION 15 13 | 14 | struct MySettings { 15 | uint8_t magicNumber; 16 | uint8_t version; 17 | uint8_t language; 18 | boolean useLdr; 19 | int16_t brightness; 20 | uint8_t color; 21 | uint8_t timeout; 22 | boolean esIst; 23 | boolean alarm1; 24 | time_t alarmTime1; 25 | boolean alarm2; 26 | time_t alarmTime2; 27 | time_t nightOffTime; 28 | time_t nightOnTime; 29 | }; 30 | 31 | class Settings { 32 | public: 33 | Settings(); 34 | uint8_t getLanguage(); 35 | void setLanguage(uint8_t language); 36 | boolean getUseLdr(); 37 | void toggleUseLdr(); 38 | int16_t getBrightness(); 39 | void setBrightness(int16_t brightness); 40 | void setColor(uint8_t color); 41 | uint8_t getColor(); 42 | uint8_t getTimeout(); 43 | void setTimeout(uint8_t timeout); 44 | boolean getEsIst(); 45 | void toggleEsIst(); 46 | boolean getAlarm1(); 47 | void toggleAlarm1(); 48 | time_t getAlarmTime1(); 49 | void setAlarmTime1(time_t alarmTime); 50 | boolean getAlarm2(); 51 | void toggleAlarm2(); 52 | time_t getAlarmTime2(); 53 | void setAlarmTime2(time_t alarmTime); 54 | time_t getNightOffTime(); 55 | void setNightOffTime(time_t nightOffTime); 56 | time_t getNightOnTime(); 57 | void setNightOnTime(time_t nightOnTime); 58 | void resetToDefault(); 59 | void loadFromEEPROM(); 60 | void saveToEEPROM(); 61 | 62 | private: 63 | MySettings mySettings; 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /Staben.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Staben.h 3 | ******************************************************************************/ 4 | 5 | #ifndef STABEN_H 6 | #define STABEN_H 7 | 8 | const char staben[][6] = { 9 | { // 0:A 10 | 0b00001100, 11 | 0b00010010, 12 | 0b00011110, 13 | 0b00010010, 14 | 0b00010010, 15 | 1 16 | } 17 | , { // 1:B 18 | 0b00011100, 19 | 0b00010010, 20 | 0b00011100, 21 | 0b00010010, 22 | 0b00011100, 23 | 1 24 | } 25 | , { // 2:C 26 | 0b00001110, 27 | 0b00010000, 28 | 0b00010000, 29 | 0b00010000, 30 | 0b00001110, 31 | 1 32 | } 33 | , { // 3:D 34 | 0b00011100, 35 | 0b00010010, 36 | 0b00010010, 37 | 0b00010010, 38 | 0b00011100, 39 | 1 40 | } 41 | , { // 4:E 42 | 0b00011110, 43 | 0b00010000, 44 | 0b00011100, 45 | 0b00010000, 46 | 0b00011110, 47 | 1 48 | } 49 | , { // 5:F 50 | 0b00011110, 51 | 0b00010000, 52 | 0b00011100, 53 | 0b00010000, 54 | 0b00010000, 55 | 1 56 | } 57 | , { // 6:G 58 | 0b00001110, 59 | 0b00010000, 60 | 0b00010110, 61 | 0b00010010, 62 | 0b00001100, 63 | 1 64 | } 65 | , { // 7:H 66 | 0b00010010, 67 | 0b00010010, 68 | 0b00011110, 69 | 0b00010010, 70 | 0b00010010, 71 | 1 72 | } 73 | , { // 8:I 74 | 0b00000100, 75 | 0b00000100, 76 | 0b00000100, 77 | 0b00000100, 78 | 0b00000100, 79 | 4 80 | } 81 | , { // 9:J 82 | 0b00011110, 83 | 0b00000010, 84 | 0b00000010, 85 | 0b00010010, 86 | 0b00001100, 87 | 1 88 | } 89 | , { // 10:K 90 | 0b00010010, 91 | 0b00010100, 92 | 0b00011000, 93 | 0b00010100, 94 | 0b00010010, 95 | 1 96 | } 97 | , { // 11:L 98 | 0b00010000, 99 | 0b00010000, 100 | 0b00010000, 101 | 0b00010000, 102 | 0b00011110, 103 | 1 104 | } 105 | , { // 12:M 106 | 0b00010001, 107 | 0b00011011, 108 | 0b00010101, 109 | 0b00010001, 110 | 0b00010001, 111 | 0 112 | } 113 | , { // 13:N 114 | 0b00010001, 115 | 0b00011001, 116 | 0b00010101, 117 | 0b00010011, 118 | 0b00010001, 119 | 0 120 | } 121 | , { // 14:O 122 | 0b00011110, 123 | 0b00010010, 124 | 0b00010010, 125 | 0b00010010, 126 | 0b00011110, 127 | 1 128 | } 129 | , { // 15:P 130 | 0b00011100, 131 | 0b00010010, 132 | 0b00011100, 133 | 0b00010000, 134 | 0b00010000, 135 | 1 136 | } 137 | , { // 16:Q 138 | 0b00001100, 139 | 0b00010010, 140 | 0b00010010, 141 | 0b00001100, 142 | 0b00000010, 143 | 1 144 | } 145 | , { // 17:R 146 | 0b00011100, 147 | 0b00010010, 148 | 0b00011100, 149 | 0b00010100, 150 | 0b00010010, 151 | 1 152 | } 153 | , { // 18:S 154 | 0b00001110, 155 | 0b00010000, 156 | 0b00001100, 157 | 0b00000010, 158 | 0b00011100, 159 | 1 160 | } 161 | , { // 19:T 162 | 0b00011111, 163 | 0b00000100, 164 | 0b00000100, 165 | 0b00000100, 166 | 0b00000100, 167 | 0 168 | } 169 | , { // 20:U 170 | 0b00010001, 171 | 0b00010001, 172 | 0b00010001, 173 | 0b00010001, 174 | 0b00001110, 175 | 0 176 | } 177 | , { // 21:V 178 | 0b00010001, 179 | 0b00010001, 180 | 0b00010001, 181 | 0b00001010, 182 | 0b00000100, 183 | 0 184 | } 185 | , { // 22:W 186 | 0b00010001, 187 | 0b00010001, 188 | 0b00010101, 189 | 0b00011011, 190 | 0b00010001, 191 | 0 192 | } 193 | , { // 23:X 194 | 0b00010001, 195 | 0b00001010, 196 | 0b00000100, 197 | 0b00001010, 198 | 0b00010001, 199 | 0 200 | } 201 | , { // 24:Y 202 | 0b00010001, 203 | 0b00001010, 204 | 0b00000100, 205 | 0b00000100, 206 | 0b00000100, 207 | 0 208 | } 209 | , { // 25:Z 210 | 0b00011110, 211 | 0b00000010, 212 | 0b00000100, 213 | 0b00001000, 214 | 0b00011110, 215 | 1 216 | } 217 | }; 218 | 219 | //kompletter Zeichensatz 220 | const char stabenBig[][8] = { 221 | {0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 4}, // ASCII-Code 0x21 => ! (33) 222 | {0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 2}, // ASCII-Code 0x22 => " (34) 223 | {0x0a, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x0a, 0}, // ASCII-Code 0x23 => # (35) 224 | {0x04, 0x0f, 0x14, 0x0e, 0x05, 0x1e, 0x04, 0}, // ASCII-Code 0x24 => $ (36) 225 | {0x18, 0x19, 0x02, 0x04, 0x08, 0x13, 0x03, 0}, // ASCII-Code 0x25 => % (37) 226 | {0x0c, 0x12, 0x14, 0x08, 0x15, 0x12, 0x0d, 0}, // ASCII-Code 0x26 => & (38) 227 | {0x18, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 3}, // ASCII-Code 0x27 => ? (39) 228 | {0x04, 0x08, 0x10, 0x10, 0x10, 0x08, 0x04, 2}, // ASCII-Code 0x28 => { (40) 229 | {0x10, 0x08, 0x04, 0x04, 0x04, 0x08, 0x10, 2}, // ASCII-Code 0x29 => } (41) 230 | {0x00, 0x04, 0x15, 0x0e, 0x15, 0x04, 0x00, 0}, // ASCII-Code 0x2A => * (42) 231 | {0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x00, 0}, // ASCII-Code 0x2B => + (43) 232 | {0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x10, 3}, // ASCII-Code 0x2C => , (44) 233 | {0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0}, // ASCII-Code 0x2D => - (45) 234 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 3}, // ASCII-Code 0x2E => . (46) 235 | {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00, 0}, // ASCII-Code 0x2F => / (47) 236 | {0x0e, 0x11, 0x13, 0x15, 0x19, 0x11, 0x0e, 0}, // ASCII-Code 0x30 => 0 (48) 237 | {0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x1c, 2}, // ASCII-Code 0x31 => 1 (49) 238 | {0x0e, 0x11, 0x01, 0x02, 0x04, 0x08, 0x1f, 0}, // ASCII-Code 0x32 => 2 (50) 239 | {0x1f, 0x02, 0x04, 0x02, 0x01, 0x11, 0x0e, 0}, // ASCII-Code 0x33 => 3 (51) 240 | {0x02, 0x06, 0x0a, 0x12, 0x1f, 0x02, 0x02, 0}, // ASCII-Code 0x34 => 4 (52) 241 | {0x1f, 0x10, 0x1e, 0x01, 0x01, 0x11, 0x0e, 0}, // ASCII-Code 0x35 => 5 (53) 242 | {0x06, 0x08, 0x10, 0x1e, 0x11, 0x11, 0x0e, 0}, // ASCII-Code 0x36 => 6 (54) 243 | {0x1f, 0x01, 0x02, 0x04, 0x08, 0x08, 0x08, 0}, // ASCII-Code 0x37 => 7 (55) 244 | {0x0e, 0x11, 0x11, 0x0e, 0x11, 0x11, 0x0e, 0}, // ASCII-Code 0x38 => 8 (56) 245 | {0x0e, 0x11, 0x11, 0x0f, 0x01, 0x02, 0x0c, 0}, // ASCII-Code 0x39 => 9 (57) 246 | {0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 3}, // ASCII-Code 0x3A => : (58) 247 | {0x00, 0x18, 0x18, 0x00, 0x18, 0x08, 0x10, 3}, // ASCII-Code 0x3B => ; (59) 248 | {0x02, 0x04, 0x08, 0x10, 0x08, 0x04, 0x02, 1}, // ASCII-Code 0x3C => < (60) 249 | {0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0}, // ASCII-Code 0x3D => = (61) 250 | {0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 1}, // ASCII-Code 0x3E => > (62) 251 | {0x0e, 0x11, 0x01, 0x02, 0x04, 0x00, 0x04, 0}, // ASCII-Code 0x3F => ? (63) 252 | {0x0e, 0x11, 0x01, 0x0d, 0x15, 0x15, 0x0e, 0}, // ASCII-Code 0x40 => @ (64) 253 | {0x0e, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0}, // ASCII-Code 0x41 => A (65) 254 | {0x1e, 0x11, 0x11, 0x1e, 0x11, 0x11, 0x1e, 0}, // ASCII-Code 0x42 => B (66) 255 | {0x0e, 0x11, 0x10, 0x10, 0x10, 0x11, 0x0e, 0}, // ASCII-Code 0x43 => C (67) 256 | {0x1c, 0x12, 0x11, 0x11, 0x11, 0x12, 0x1c, 0}, // ASCII-Code 0x44 => D (68) 257 | {0x1f, 0x10, 0x10, 0x1e, 0x10, 0x10, 0x1f, 0}, // ASCII-Code 0x45 => E (69) 258 | {0x1f, 0x10, 0x10, 0x1e, 0x10, 0x10, 0x10, 0}, // ASCII-Code 0x46 => F (70) 259 | {0x0e, 0x11, 0x10, 0x16, 0x11, 0x11, 0x0e, 0}, // ASCII-Code 0x47 => G (71) 260 | {0x11, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0}, // ASCII-Code 0x48 => H (72) 261 | {0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 2}, // ASCII-Code 0x49 => I (73) 262 | {0x07, 0x02, 0x02, 0x02, 0x02, 0x12, 0x0c, 0}, // ASCII-Code 0x4A => J (74) 263 | {0x11, 0x12, 0x14, 0x18, 0x14, 0x12, 0x11, 0}, // ASCII-Code 0x4B => K (75) 264 | {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f, 0}, // ASCII-Code 0x4C => L (76) 265 | {0x11, 0x1b, 0x15, 0x15, 0x11, 0x11, 0x11, 0}, // ASCII-Code 0x4D => M (77) 266 | {0x11, 0x11, 0x19, 0x15, 0x13, 0x11, 0x11, 0}, // ASCII-Code 0x4E => N (78) 267 | {0x0e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0}, // ASCII-Code 0x4F => O (79) 268 | {0x1e, 0x11, 0x11, 0x1e, 0x10, 0x10, 0x10, 0}, // ASCII-Code 0x50 => P (80) 269 | {0x0e, 0x11, 0x11, 0x11, 0x15, 0x12, 0x0d, 0}, // ASCII-Code 0x51 => Q (81) 270 | {0x1e, 0x11, 0x11, 0x1e, 0x14, 0x12, 0x11, 0}, // ASCII-Code 0x52 => R (82) 271 | {0x0e, 0x11, 0x10, 0x0e, 0x01, 0x11, 0x0e, 0}, // ASCII-Code 0x53 => S (83) 272 | {0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0}, // ASCII-Code 0x54 => T (84) 273 | {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0e, 0}, // ASCII-Code 0x55 => U (85) 274 | {0x11, 0x11, 0x11, 0x11, 0x11, 0x0a, 0x04, 0}, // ASCII-Code 0x56 => V (86) 275 | {0x11, 0x11, 0x11, 0x15, 0x15, 0x15, 0x0a, 0}, // ASCII-Code 0x57 => W (87) 276 | {0x11, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0x11, 0}, // ASCII-Code 0x58 => X (88) 277 | {0x11, 0x11, 0x11, 0x0a, 0x04, 0x04, 0x04, 0}, // ASCII-Code 0x59 => Y (89) 278 | {0x1f, 0x01, 0x02, 0x04, 0x08, 0x10, 0x1f, 0}, // ASCII-Code 0x5A => Z (90) 279 | {0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 2}, // ASCII-Code 0x5B => [ (91) 280 | {0x00, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0}, // ASCII-Code 0x5C => \ (92) 281 | {0x1c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1c, 2}, // ASCII-Code 0x5D => ] (93) 282 | {0x04, 0x0a, 0x11, 0x00, 0x00, 0x00, 0x00, 0}, // ASCII-Code 0x5E => ^ (94) 283 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0}, // ASCII-Code 0x5F => _ (95) 284 | {0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 2}, // ASCII-Code 0x60 => ` (96) 285 | {0x00, 0x00, 0x0e, 0x01, 0x0f, 0x11, 0x0f, 0}, // ASCII-Code 0x61 => a (97) 286 | {0x10, 0x10, 0x10, 0x16, 0x19, 0x11, 0x1e, 0}, // ASCII-Code 0x62 => b (98) 287 | {0x00, 0x00, 0x0e, 0x10, 0x10, 0x11, 0x0e, 0}, // ASCII-Code 0x63 => c (99) 288 | {0x01, 0x01, 0x01, 0x0d, 0x13, 0x11, 0x0f, 0}, // ASCII-Code 0x64 => d (100) 289 | {0x00, 0x00, 0x0e, 0x11, 0x1f, 0x10, 0x0e, 0}, // ASCII-Code 0x65 => e (101) 290 | {0x06, 0x09, 0x08, 0x1c, 0x08, 0x08, 0x08, 0}, // ASCII-Code 0x66 => f (102) 291 | {0x00, 0x0f, 0x11, 0x11, 0x0f, 0x01, 0x0e, 0}, // ASCII-Code 0x67 => g (103) 292 | {0x10, 0x10, 0x16, 0x19, 0x11, 0x11, 0x11, 0}, // ASCII-Code 0x68 => h (104) 293 | {0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 4}, // ASCII-Code 0x69 => i (105) 294 | {0x02, 0x00, 0x06, 0x02, 0x02, 0x12, 0x0c, 1}, // ASCII-Code 0x6A => j (106) 295 | {0x10, 0x10, 0x12, 0x14, 0x18, 0x14, 0x12, 1}, // ASCII-Code 0x6B => k (107) 296 | {0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 2}, // ASCII-Code 0x6C => l (108) 297 | {0x00, 0x00, 0x1a, 0x15, 0x15, 0x11, 0x11, 0}, // ASCII-Code 0x6D => m (109) 298 | {0x00, 0x00, 0x16, 0x19, 0x11, 0x11, 0x11, 0}, // ASCII-Code 0x6E => n (110) 299 | {0x00, 0x00, 0x0e, 0x11, 0x11, 0x11, 0x0e, 0}, // ASCII-Code 0x6F => o (111) 300 | {0x00, 0x00, 0x1e, 0x11, 0x1e, 0x10, 0x10, 0}, // ASCII-Code 0x70 => p (112) 301 | {0x00, 0x00, 0x0d, 0x13, 0x0f, 0x01, 0x01, 0}, // ASCII-Code 0x71 => q (113) 302 | {0x00, 0x00, 0x16, 0x19, 0x10, 0x10, 0x10, 0}, // ASCII-Code 0x72 => r (114) 303 | {0x00, 0x00, 0x0e, 0x10, 0x0e, 0x01, 0x1e, 0}, // ASCII-Code 0x73 => s (115) 304 | {0x08, 0x08, 0x1c, 0x08, 0x08, 0x09, 0x06, 0}, // ASCII-Code 0x74 => t (116) 305 | {0x00, 0x00, 0x11, 0x11, 0x11, 0x13, 0x0d, 0}, // ASCII-Code 0x75 => u (117) 306 | {0x00, 0x00, 0x11, 0x11, 0x11, 0x0a, 0x04, 0}, // ASCII-Code 0x76 => v (118) 307 | {0x00, 0x00, 0x11, 0x11, 0x15, 0x15, 0x0a, 0}, // ASCII-Code 0x77 => w (119) 308 | {0x00, 0x00, 0x11, 0x0a, 0x04, 0x0a, 0x11, 0}, // ASCII-Code 0x78 => x (120) 309 | {0x00, 0x00, 0x11, 0x11, 0x0f, 0x01, 0x0e, 0}, // ASCII-Code 0x79 => y (121) 310 | {0x00, 0x00, 0x1f, 0x02, 0x04, 0x08, 0x1f, 0}, // ASCII-Code 0x7A => z (122) 311 | {0x04, 0x08, 0x08, 0x10, 0x08, 0x08, 0x04, 2}, // ASCII-Code 0x7B => { (123) 312 | {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 4}, // ASCII-Code 0x7C => | (124) 313 | {0x10, 0x08, 0x08, 0x04, 0x08, 0x08, 0x10, 2}, // ASCII-Code 0x7D => } (125) 314 | {0x00, 0x00, 0x00, 0x19, 0x26, 0x00, 0x00, 0} // ASCII-Code 0x7E => ~ (126) 315 | }; 316 | 317 | #endif 318 | 319 | -------------------------------------------------------------------------------- /Woerter_CH.h: -------------------------------------------------------------------------------- 1 | /** 2 | Woerter_CH 3 | Definition der schweizerischen Woerter fuer die Zeitansage. 4 | Die Woerter sind Bitmasken fuer die Matrix. 5 | 6 | 01234567890 7 | 0 ESKISCHAFÜF 8 | 1 VIERTUBFZÄÄ 9 | 2 ZWÄNZGSIVOR 10 | 3 ABOHAUBIEGE 11 | 4 EISZWÖISDRÜ 12 | 5 VIERIFÜFIQT 13 | 6 SÄCHSISIBNI 14 | 7 ACHTINÜNIEL 15 | 8 ZÄNIERBEUFI 16 | 9 ZWÖUFINAUHR 17 | 18 | @mc Arduino/RBBB 19 | @autor Thomas Schuler / thomas.schuler _AT_ vtg _DOT_ admin _DOT_ ch (Basis) 20 | @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com (Anpassung) 21 | @version 1.1 22 | @created 18.3.2012 23 | @updated 4.4.2013 24 | 25 | Version 1.1: - Layoutanpassung 26 | */ 27 | 28 | #ifndef WOERTER_CH_H 29 | #define WOERTER_CH_H 30 | 31 | /** 32 | Definition der Woerter 33 | */ 34 | #define CH_VOR matrix[2] |= 0b0000000011100000 35 | #define CH_AB matrix[3] |= 0b1100000000000000 36 | #define CH_ESISCH matrix[0] |= 0b1101111000000000 37 | #define CH_AM matrix[0] |= 0b1000000000000000 38 | #define CH_PM matrix[0] |= 0b0100000000000000 39 | 40 | #define CH_FUEF matrix[0] |= 0b0000000011100000 41 | #define CH_ZAEAE matrix[1] |= 0b0000000011100000 42 | #define CH_VIERTU matrix[1] |= 0b1111110000000000 43 | #define CH_ZWAENZG matrix[2] |= 0b1111110000000000 44 | #define CH_HAUBI matrix[3] |= 0b0001111100000000 45 | 46 | #define CH_H_EIS matrix[4] |= 0b1110000000000000 47 | #define CH_H_ZWOEI matrix[4] |= 0b0001111000000000 48 | #define CH_H_DRUE matrix[4] |= 0b0000000011100000 49 | #define CH_H_VIER matrix[5] |= 0b1111100000000000 50 | #define CH_H_FUEFI matrix[5] |= 0b0000011110000000 51 | #define CH_H_SAECHSI matrix[6] |= 0b1111110000000000 52 | #define CH_H_SIEBNI matrix[6] |= 0b0000001111100000 53 | #define CH_H_ACHTI matrix[7] |= 0b1111100000000000 54 | #define CH_H_NUENI matrix[7] |= 0b0000011110000000 55 | #define CH_H_ZAENI matrix[8] |= 0b1111000000000000 56 | #define CH_H_EUFI matrix[8] |= 0b0000000111100000 57 | #define CH_H_ZWOEUFI matrix[9] |= 0b1111110000000000 58 | 59 | #define CH_GSI matrix[9] |= 0b0000000011100000 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /Woerter_D3.h: -------------------------------------------------------------------------------- 1 | /** 2 | Woerter_D3 3 | Definition der schwaebischen Woerter fuer die Zeitansage. 4 | Die Woerter sind Bitmasken fuer die Matrix. 5 | 6 | 01234567890 7 | 0 ESKISCHFUNK 8 | 1 DREIVIERTLA 9 | 2 ZEHNBIEFUNF 10 | 3 NACHGERTVOR 11 | 4 HALBXFUNFEI 12 | 5 OISECHSELFE 13 | 6 ZWOIEACHTED 14 | 7 DREIEZWOLFE 15 | 8 ZEHNEUNEUHL 16 | 9 SIEBNEVIERE 17 | 18 | @mc Arduino/RBBB 19 | @autor Fisch0204 & Chriophs007 (Unter Vorlage von Christian Aschoff) 20 | @version 1.0 21 | @created 03.03.2016 22 | */ 23 | #ifndef WOERTER_D3_H 24 | #define WOERTER_D3_H 25 | 26 | /** 27 | Definition der Woerter 28 | */ 29 | #define D3_ESISCH matrix[0] |= 0b1101111000000000 30 | #define D3_VOR matrix[3] |= 0b0000000011100000 31 | #define D3_NACH matrix[3] |= 0b1111000000000000 32 | #define D3_AM matrix[0] |= 0b1000000000000000 33 | #define D3_PM matrix[0] |= 0b0100000000000000 34 | 35 | #define D3_FUENF matrix[2] |= 0b0000000111100000 36 | #define D3_ZEHN matrix[2] |= 0b1111000000000000 37 | #define D3_VIERTL matrix[1] |= 0b0000111111000000 38 | #define D3_HALB matrix[4] |= 0b1111000000000000 39 | #define D3_DREIVIERTL matrix[1] |= 0b1111111111000000 40 | 41 | #define D3_H_OISE matrix[5] |= 0b1111000000000000 42 | #define D3_H_ZWOIE matrix[6] |= 0b1111100000000000 43 | #define D3_H_DREIE matrix[7] |= 0b1111100000000000 44 | #define D3_H_VIERE matrix[9] |= 0b0000001111100000 45 | #define D3_H_FUENFE matrix[4] |= 0b0000011111000000 46 | #define D3_H_SECHSE matrix[5] |= 0b0011111100000000 47 | #define D3_H_SIEBNE matrix[9] |= 0b1111110000000000 48 | #define D3_H_ACHTE matrix[6] |= 0b0000011111000000 49 | #define D3_H_NEUNE matrix[8] |= 0b0001111100000000 50 | #define D3_H_ZEHNE matrix[8] |= 0b1111100000000000 51 | #define D3_H_ELFE matrix[5] |= 0b0000000111100000 52 | #define D3_H_ZWOELFE matrix[7] |= 0b0000011111100000 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /Woerter_DE.h: -------------------------------------------------------------------------------- 1 | /* 2 | Woerter_DE 3 | Definition der deutschen Woerter fuer die Zeitansage. 4 | Die Woerter sind Bitmasken fuer die Matrix. 5 | 6 | 01234567890 7 | 0 ESKISTAFUNF 8 | 1 ZEHNZWANZIG 9 | 2 DREIVIERTEL 10 | 3 VORFUNKNACH 11 | 4 HALBAELFUNF 12 | 5 EINSXAMZWEI 13 | 6 DREIPMJVIER 14 | 7 SECHSNLACHT 15 | 8 SIEBENZWOLF 16 | 9 ZEHNEUNKUHR 17 | 18 | @mc Arduino/RBBB 19 | @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 20 | @version 1.0 21 | @created 18.3.2012 22 | */ 23 | 24 | #ifndef WOERTER_DE_H 25 | #define WOERTER_DE_H 26 | 27 | /** 28 | Definition der Woerter 29 | */ 30 | #define DE_VOR matrix[3] |= 0b1110000000000000 31 | #define DE_NACH matrix[3] |= 0b0000000111100000 32 | #define DE_ESIST matrix[0] |= 0b1101110000000000 33 | #define DE_UHR matrix[9] |= 0b0000000011100000 34 | #define DE_AM matrix[5] |= 0b0000011000000000 35 | #define DE_PM matrix[6] |= 0b0000110000000000 36 | 37 | #define DE_FUENF matrix[0] |= 0b0000000111100000 38 | #define DE_ZEHN matrix[1] |= 0b1111000000000000 39 | #define DE_VIERTEL matrix[2] |= 0b0000111111100000 40 | #define DE_ZWANZIG matrix[1] |= 0b0000111111100000 41 | #define DE_HALB matrix[4] |= 0b1111000000000000 42 | #define DE_DREIVIERTEL matrix[2] |= 0b1111111111100000 43 | 44 | #define DE_H_EIN matrix[5] |= 0b1110000000000000 45 | #define DE_H_EINS matrix[5] |= 0b1111000000000000 46 | #define DE_H_ZWEI matrix[5] |= 0b0000000111100000 47 | #define DE_H_DREI matrix[6] |= 0b1111000000000000 48 | #define DE_H_VIER matrix[6] |= 0b0000000111100000 49 | #define DE_H_FUENF matrix[4] |= 0b0000000111100000 50 | #define DE_H_SECHS matrix[7] |= 0b1111100000000000 51 | #define DE_H_SIEBEN matrix[8] |= 0b1111110000000000 52 | #define DE_H_ACHT matrix[7] |= 0b0000000111100000 53 | #define DE_H_NEUN matrix[9] |= 0b0001111000000000 54 | #define DE_H_ZEHN matrix[9] |= 0b1111000000000000 55 | #define DE_H_ELF matrix[4] |= 0b0000011100000000 56 | #define DE_H_ZWOELF matrix[8] |= 0b0000001111100000 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /Woerter_DE_MKF.h: -------------------------------------------------------------------------------- 1 | /** 2 | Woerter_DE_MKF 3 | Definition der deutschen Woerter fuer die Zeitansage. 4 | Hier in einer anderen Variante nach der Matix von Gerog M. 5 | Sie entspricht dem Layout aus dem Mikrocontroller.net 6 | Die Woerter sind Bitmasken fuer die Matrix. 7 | 8 | 01234567890 9 | 0 ESKISTLFUNF 10 | 1 ZEHNZWANZIG 11 | 2 DREIVIERTEL 12 | 3 TGNACHVORJM 13 | 4 HALBQZWOLFP 14 | 5 ZWEINSIEBEN 15 | 6 KDREIRHFUNF 16 | 7 ELFNEUNVIER 17 | 8 WACHTZEHNRS 18 | 9 BSECHSFMUHR 19 | 20 | @mc Arduino/RBBB 21 | @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 22 | @version 1.0 23 | @created 28.10.2012 24 | */ 25 | #ifndef WOERTER_DE_MKF_H 26 | #define WOERTER_DE_MKF_H 27 | 28 | /** 29 | Definition der Woerter 30 | */ 31 | #define DE_MKF_VOR matrix[3] |= 0b0000001110000000 32 | #define DE_MKF_NACH matrix[3] |= 0b0011110000000000 33 | #define DE_MKF_ESIST matrix[0] |= 0b1101110000000000 34 | #define DE_MKF_UHR matrix[9] |= 0b0000000011100000 35 | #define DE_MKF_AM matrix[0] |= 0b1000000000000000 36 | #define DE_MKF_PM matrix[0] |= 0b0100000000000000 37 | 38 | #define DE_MKF_FUENF matrix[0] |= 0b0000000111100000 39 | #define DE_MKF_ZEHN matrix[1] |= 0b1111000000000000 40 | #define DE_MKF_VIERTEL matrix[2] |= 0b0000111111100000 41 | #define DE_MKF_ZWANZIG matrix[1] |= 0b0000111111100000 42 | #define DE_MKF_HALB matrix[4] |= 0b1111000000000000 43 | #define DE_MKF_DREIVIERTEL matrix[2] |= 0b1111111111100000 44 | 45 | #define DE_MKF_H_EIN matrix[5] |= 0b0011100000000000 46 | #define DE_MKF_H_EINS matrix[5] |= 0b0011110000000000 47 | #define DE_MKF_H_ZWEI matrix[5] |= 0b1111000000000000 48 | #define DE_MKF_H_DREI matrix[6] |= 0b0111100000000000 49 | #define DE_MKF_H_VIER matrix[7] |= 0b0000000111100000 50 | #define DE_MKF_H_FUENF matrix[6] |= 0b0000000111100000 51 | #define DE_MKF_H_SECHS matrix[9] |= 0b0111110000000000 52 | #define DE_MKF_H_SIEBEN matrix[5] |= 0b0000011111100000 53 | #define DE_MKF_H_ACHT matrix[8] |= 0b0111100000000000 54 | #define DE_MKF_H_NEUN matrix[7] |= 0b0001111000000000 55 | #define DE_MKF_H_ZEHN matrix[8] |= 0b0000011110000000 56 | #define DE_MKF_H_ELF matrix[7] |= 0b1110000000000000 57 | #define DE_MKF_H_ZWOELF matrix[4] |= 0b0000011111000000 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /Woerter_EN.h: -------------------------------------------------------------------------------- 1 | /** 2 | Woerter_EN 3 | Definition der englischen Woerter fuer die Zeitansage. 4 | Die Woerter sind Bitmasken fuer die Matrix. 5 | 6 | 01234567890 7 | 0 ITLISASTIME 8 | 1 ACQUARTERDC 9 | 2 TWENTYFIFEX 10 | 3 HALFBTENFTO 11 | 4 PASTERUNINE 12 | 5 ONESIXTHREE 13 | 6 FOURFIVETWO 14 | 7 EIGHTELEVEN 15 | 8 SEVENTWELVE 16 | 9 TENSEOCLOCK 17 | 18 | @mc Arduino/RBBB 19 | @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 20 | @version 1.0 21 | @created 17.12.2012 22 | */ 23 | 24 | #ifndef WOERTER_EN_H 25 | #define WOERTER_EN_H 26 | 27 | /** 28 | Definition der Woerter. 29 | */ 30 | #define EN_ITIS matrix[0] |= 0b1101100000000000 31 | #define EN_TIME matrix[0] |= 0b0000000111100000 32 | #define EN_A matrix[1] |= 0b1000000000000000 33 | #define EN_OCLOCK matrix[9] |= 0b0000011111100000 34 | #define EN_AM matrix[0] |= 0b0000000110000000 35 | #define EN_PM matrix[0] |= 0b0000000001100000 36 | 37 | #define EN_QUATER matrix[1] |= 0b0011111110000000 38 | #define EN_TWENTY matrix[2] |= 0b1111110000000000 39 | #define EN_FIVE matrix[2] |= 0b0000001111000000 40 | #define EN_HALF matrix[3] |= 0b1111000000000000 41 | #define EN_TEN matrix[3] |= 0b0000011100000000 42 | #define EN_TO matrix[3] |= 0b0000000001100000 43 | #define EN_PAST matrix[4] |= 0b1111000000000000 44 | 45 | #define EN_H_NINE matrix[4] |= 0b0000000111100000 46 | #define EN_H_ONE matrix[5] |= 0b1110000000000000 47 | #define EN_H_SIX matrix[5] |= 0b0001110000000000 48 | #define EN_H_THREE matrix[5] |= 0b0000001111100000 49 | #define EN_H_FOUR matrix[6] |= 0b1111000000000000 50 | #define EN_H_FIVE matrix[6] |= 0b0000111100000000 51 | #define EN_H_TWO matrix[6] |= 0b0000000011100000 52 | #define EN_H_EIGHT matrix[7] |= 0b1111100000000000 53 | #define EN_H_ELEVEN matrix[7] |= 0b0000011111100000 54 | #define EN_H_SEVEN matrix[8] |= 0b1111100000000000 55 | #define EN_H_TWELVE matrix[8] |= 0b0000011111100000 56 | #define EN_H_TEN matrix[9] |= 0b1110000000000000 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /Woerter_ES.h: -------------------------------------------------------------------------------- 1 | /** 2 | Woerter_ES 3 | Definition der spanischen Woerter fuer die Zeitansage. 4 | Die Woerter sind Bitmasken fuer die Matrix. 5 | 6 | 01234567890 7 | 0 ESONELASUNA 8 | 1 DOSITRESORE 9 | 2 CUATROCINCO 10 | 3 SEISASIETEN 11 | 4 OCHONUEVEYO 12 | 5 LADIEZSONCE 13 | 6 DOCELYMENOS 14 | 7 OVEINTEDIEZ 15 | 8 VEINTICINCO 16 | 9 MEDIACUARTO 17 | 18 | @mc Arduino/RBBB 19 | @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 20 | @version 1.0 21 | @created 17.12.2012 22 | @updated 13.5.2013 23 | */ 24 | 25 | #ifndef WOERTER_ES_H 26 | #define WOERTER_ES_H 27 | 28 | /** 29 | Definition der Woerter. 30 | */ 31 | // 0 ESONELASUNA 32 | #define ES_SONLAS matrix[0] |= 0b0111011100000000 33 | // 0 ESONELASUNA 34 | #define ES_ESLA matrix[0] |= 0b1100011000000000 35 | 36 | #define ES_AM matrix[0] |= 0b1000000000000000 37 | #define ES_PM matrix[0] |= 0b0100000000000000 38 | 39 | // 6 DOCELYMENOS 40 | #define ES_Y matrix[6] |= 0b0000010000000000 41 | // 6 DOCELYMENOS 42 | #define ES_MENOS matrix[6] |= 0b0000001111100000 43 | 44 | // 8 VEINTICINCO 45 | #define ES_CINCO matrix[8] |= 0b0000001111100000 46 | // 7 OVEINTEDIEZ 47 | #define ES_DIEZ matrix[7] |= 0b0000000111100000 48 | // 9 MEDIACUARTO 49 | #define ES_CUARTO matrix[9] |= 0b0000011111100000 50 | // 7 OVEINTEDIEZ 51 | #define ES_VEINTE matrix[7] |= 0b0111111000000000 52 | // 8 VEINTICINCO 53 | #define ES_VEINTICINCO matrix[8] |= 0b1111111111100000 54 | // 9 MEDIACUARTO 55 | #define ES_MEDIA matrix[9] |= 0b1111100000000000 56 | 57 | // 0 ESONELASUNA 58 | #define ES_H_UNA matrix[0] |= 0b0000000011100000 59 | // 1 DOSITRESORE 60 | #define ES_H_DOS matrix[1] |= 0b1110000000000000 61 | // 1 DOSITRESORE 62 | #define ES_H_TRES matrix[1] |= 0b0000111100000000 63 | // 2 CUATROCINCO 64 | #define ES_H_CUATRO matrix[2] |= 0b1111110000000000 65 | // 2 CUATROCINCO 66 | #define ES_H_CINCO matrix[2] |= 0b0000001111100000 67 | // 3 SEISASIETEN 68 | #define ES_H_SEIS matrix[3] |= 0b1111000000000000 69 | // 3 SEISASIETEN 70 | #define ES_H_SIETE matrix[3] |= 0b0000011111000000 71 | // 4 OCHONUEVEYO 72 | #define ES_H_OCHO matrix[4] |= 0b1111000000000000 73 | // 4 OCHONUEVEYO 74 | #define ES_H_NUEVE matrix[4] |= 0b0000111110000000 75 | // 5 LADIEZSONCE 76 | #define ES_H_DIEZ matrix[5] |= 0b0011110000000000 77 | // 5 LADIEZSONCE 78 | #define ES_H_ONCE matrix[5] |= 0b0000000111100000 79 | // 6 DOCELYMENOS 80 | #define ES_H_DOCE matrix[6] |= 0b1111000000000000 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /Woerter_FR.h: -------------------------------------------------------------------------------- 1 | /** 2 | Woerter_FR 3 | Definition der franzoesischen Woerter fuer die Zeitansage. 4 | Die Woerter sind Bitmasken fuer die Matrix. 5 | 6 | 01234567890 7 | 0 ILNESTODEUX 8 | 1 QUATRETROIS 9 | 2 NEUFUNESEPT 10 | 3 HUITSIXCINQ 11 | 4 MIDIXMINUIT 12 | 5 ONZERHEURES 13 | 6 MOINSOLEDIX 14 | 7 ETRQUARTPMD 15 | 8 VINGT-CINQU 16 | 9 ETSDEMIEPAM 17 | 18 | @mc Arduino/RBBB 19 | @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 20 | @version 1.0 21 | @created 12.12.2012 22 | */ 23 | 24 | #ifndef WOERTER_FR_H 25 | #define WOERTER_FR_H 26 | 27 | /** 28 | Definition der Woerter 29 | */ 30 | // Trait = Bindestrich (-) 31 | #define FR_TRAIT matrix[8] |= 0b0000010000000000 32 | #define FR_ET matrix[7] |= 0b1100000000000000 33 | #define FR_LE matrix[6] |= 0b0000001100000000 34 | #define FR_MOINS matrix[6] |= 0b1111100000000000 35 | #define FR_ILEST matrix[0] |= 0b1101110000000000 36 | #define FR_HEURE matrix[5] |= 0b0000011111000000 37 | #define FR_HEURES matrix[5] |= 0b0000011111100000 38 | #define FR_AM matrix[7] |= 0b0000000001100000 39 | #define FR_PM matrix[9] |= 0b0000000011000000 40 | 41 | #define FR_CINQ matrix[8] |= 0b0000001111000000 42 | #define FR_DIX matrix[6] |= 0b0000000011100000 43 | #define FR_QUART matrix[7] |= 0b0001111100000000 44 | #define FR_VINGT matrix[8] |= 0b1111100000000000 45 | #define FR_DEMIE matrix[9] |= 0b0001111100000000 46 | 47 | #define FR_H_UNE matrix[2] |= 0b0000111000000000 48 | #define FR_H_DEUX matrix[0] |= 0b0000000111100000 49 | #define FR_H_TROIS matrix[1] |= 0b0000001111100000 50 | #define FR_H_QUATRE matrix[1] |= 0b1111110000000000 51 | #define FR_H_CINQ matrix[3] |= 0b0000000111100000 52 | #define FR_H_SIX matrix[3] |= 0b0000111000000000 53 | #define FR_H_SEPT matrix[2] |= 0b0000000111100000 54 | #define FR_H_HUIT matrix[3] |= 0b1111000000000000 55 | #define FR_H_NEUF matrix[2] |= 0b1111000000000000 56 | #define FR_H_DIX matrix[4] |= 0b0011100000000000 57 | #define FR_H_ONZE matrix[5] |= 0b1111000000000000 58 | #define FR_H_MIDI matrix[4] |= 0b1111000000000000 59 | #define FR_H_MINUIT matrix[4] |= 0b0000011111100000 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /Woerter_IT.h: -------------------------------------------------------------------------------- 1 | /** 2 | Woerter_IT 3 | Definition der italienischen Woerter fuer die Zeitansage. 4 | Die Woerter sind Bitmasken fuer die Matrix. 5 | 6 | 01234567890 7 | 0 SONORLEBORE 8 | 1 ERLUNASDUEZ 9 | 2 TREOTTONOVE 10 | 3 DIECIUNDICI 11 | 4 DODICISETTE 12 | 5 QUATTROCSEI 13 | 6 CINQUESMENO 14 | 7 ECUNOQUARTO 15 | 8 VENTICINQUE 16 | 9 DIECIEMEZZA 17 | 18 | @mc Arduino/RBBB 19 | @autor Christian Aschoff / caschoff _AT_ mac _DOT_ com 20 | @version 1.0 21 | @created 17.12.2012 22 | */ 23 | 24 | #ifndef WOERTER_IT_H 25 | #define WOERTER_IT_H 26 | 27 | /** 28 | Definition der Woerter. 29 | */ 30 | #define IT_SONOLE matrix[0] |= 0b1111011000000000 31 | #define IT_LE matrix[0] |= 0b0000011000000000 32 | #define IT_ORE matrix[0] |= 0b0000000011100000 33 | #define IT_E matrix[1] |= 0b1000000000000000 34 | #define IT_AM matrix[0] |= 0b1000000000000000 35 | #define IT_PM matrix[0] |= 0b0100000000000000 36 | 37 | #define IT_H_LUNA matrix[1] |= 0b0011110000000000 38 | #define IT_H_DUE matrix[1] |= 0b0000000111000000 39 | #define IT_H_TRE matrix[2] |= 0b1110000000000000 40 | #define IT_H_OTTO matrix[2] |= 0b0001111000000000 41 | #define IT_H_NOVE matrix[2] |= 0b0000000111100000 42 | #define IT_H_DIECI matrix[3] |= 0b1111100000000000 43 | #define IT_H_UNDICI matrix[3] |= 0b0000011111100000 44 | #define IT_H_DODICI matrix[4] |= 0b1111110000000000 45 | #define IT_H_SETTE matrix[4] |= 0b0000001111100000 46 | #define IT_H_QUATTRO matrix[5] |= 0b1111111000000000 47 | #define IT_H_SEI matrix[5] |= 0b0000000011100000 48 | #define IT_H_CINQUE matrix[6] |= 0b1111110000000000 49 | 50 | #define IT_MENO matrix[6] |= 0b0000000111100000 51 | #define IT_E2 matrix[7] |= 0b1000000000000000 52 | #define IT_UN matrix[7] |= 0b0011000000000000 53 | #define IT_QUARTO matrix[7] |= 0b0000011111100000 54 | #define IT_VENTI matrix[8] |= 0b1111100000000000 55 | #define IT_CINQUE matrix[8] |= 0b0000011111100000 56 | #define IT_DIECI matrix[9] |= 0b1111100000000000 57 | #define IT_MEZZA matrix[9] |= 0b0000001111100000 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /Woerter_NL.h: -------------------------------------------------------------------------------- 1 | /** 2 | Woerter_NL 3 | Definition der niederlaendischen Woerter fuer die Zeitansage. 4 | Die Woerter sind Bitmasken fuer die Matrix. 5 | 6 | @mc Arduino/RBBB 7 | @autor Rudolf Klimesch (Vorlage: Christian Aschoff) 8 | @version 1.01 9 | @created 17.1.2013 10 | @update 29.9.2014 11 | 12 | Historie: 13 | V 1.01 - Falsches O bei ZEVEN behoben. 14 | 15 | */ 16 | 17 | #ifndef WOERTER_NL_H 18 | #define WOERTER_NL_H 19 | 20 | /* 21 | VORLAGE FUER DIE MATRIX 22 | 23 | H E T K I S A V I J F HET=ES, IS=IST, VIJF=FUNF 24 | T I E N B T Z V O O R TIEN=ZEHN, VOOR=VOR 25 | O V E R M E K W A R T OVER=NACH, KWART=VIERTEL 26 | H A L F S P W O V E R HALF=HALB, OVER=NACH 27 | V O O R T H G E E N S VOOR=VOR, EENS=EINS 28 | T W E E P V C D R I E TWEE=ZWEI, DRIE=DREI 29 | V I E R V I J F Z E S VIER=VIER, VIJF=FUNF, ZES=SECHS 30 | Z E V E N O N E G E N ZEVEN=SIEBEN, NEGEN=NEUN 31 | A C H T T I E N E L F ACHT=ACHT, TIEN=ZEHN, ELF=ELF 32 | T W A A L F B F U U R TWAALF=ZWOLF, UUR=STUNDE 33 | */ 34 | 35 | /** 36 | Definition der Woerter 37 | */ 38 | #define NL_VOOR matrix[1] |= 0b0000000111100000 // VOR 39 | #define NL_OVER matrix[2] |= 0b1111000000000000 // NACH 40 | #define NL_VOOR2 matrix[4] |= 0b1111000000000000 // VOR2 41 | #define NL_OVER2 matrix[3] |= 0b0000000111100000 // NACH2 42 | #define NL_HETIS matrix[0] |= 0b1110110000000000 // ESIST 43 | #define NL_UUR matrix[9] |= 0b0000000011100000 // UHR 44 | #define NL_AM matrix[0] |= 0b1000000000000000 45 | #define NL_PM matrix[0] |= 0b0100000000000000 46 | 47 | #define NL_VIJF matrix[0] |= 0b0000000111100000 // FUENF 48 | #define NL_TIEN matrix[1] |= 0b1111000000000000 // ZEHN 49 | #define NL_KWART matrix[2] |= 0b0000001111100000 // VIERTEL 50 | #define NL_ZWANZIG matrix[1] |= 0b0000111111100000 // ZWANZIG 51 | #define NL_HALF matrix[3] |= 0b1111000000000000 // HALB 52 | 53 | #define NL_H_EEN matrix[4] |= 0b0000000111000000 // H_EIN 54 | #define NL_H_EENS matrix[4] |= 0b0000000111100000 // H_EINS 55 | #define NL_H_TWEE matrix[5] |= 0b1111000000000000 // H_ZWEI 56 | #define NL_H_DRIE matrix[5] |= 0b0000000111100000 // H_DREI 57 | #define NL_H_VIER matrix[6] |= 0b1111000000000000 // H_VIER 58 | #define NL_H_VIJF matrix[6] |= 0b0000111100000000 // H_FUENF 59 | #define NL_H_ZES matrix[6] |= 0b0000000011100000 // H_SECHS 60 | #define NL_H_ZEVEN matrix[7] |= 0b1111100000000000 // H_SIEBEN 61 | #define NL_H_ACHT matrix[8] |= 0b1111000000000000 // H_ACHT 62 | #define NL_H_NEGEN matrix[7] |= 0b0000001111100000 // H_NEUN 63 | #define NL_H_TIEN matrix[8] |= 0b0000111100000000 // H_ZEHN 64 | #define NL_H_ELF matrix[8] |= 0b0000000011100000 // H_ELF 65 | #define NL_H_TWAALF matrix[9] |= 0b1111110000000000 // H_ZWOELF 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /Zahlen.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | Zahlen.h 3 | ******************************************************************************/ 4 | 5 | #ifndef ZAHLEN_H 6 | #define ZAHLEN_H 7 | 8 | const char zahlenKlein[][5] = { 9 | { // 0 10 | 0b00011110, 11 | 0b00010010, 12 | 0b00010010, 13 | 0b00010010, 14 | 0b00011110 15 | }, 16 | { // 1 17 | 0b00000100, 18 | 0b00001100, 19 | 0b00000100, 20 | 0b00000100, 21 | 0b00001110 22 | }, 23 | { // 2 24 | 0b00011110, 25 | 0b00000010, 26 | 0b00011110, 27 | 0b00010000, 28 | 0b00011110 29 | }, 30 | { // 3 31 | 0b00011110, 32 | 0b00000010, 33 | 0b00001110, 34 | 0b00000010, 35 | 0b00011110 36 | }, 37 | { // 4 38 | 0b00010010, 39 | 0b00010010, 40 | 0b00011110, 41 | 0b00000010, 42 | 0b00000010 43 | }, 44 | { // 5 45 | 0b00011110, 46 | 0b00010000, 47 | 0b00011110, 48 | 0b00000010, 49 | 0b00011110 50 | }, 51 | { // 6 52 | 0b00011110, 53 | 0b00010000, 54 | 0b00011110, 55 | 0b00010010, 56 | 0b00011110 57 | }, 58 | { // 7 59 | 0b00011110, 60 | 0b00000010, 61 | 0b00000100, 62 | 0b00000100, 63 | 0b00000100 64 | }, 65 | { // 8 66 | 0b00011110, 67 | 0b00010010, 68 | 0b00011110, 69 | 0b00010010, 70 | 0b00011110 71 | }, 72 | { // 9 73 | 0b00011110, 74 | 0b00010010, 75 | 0b00011110, 76 | 0b00000010, 77 | 0b00011110 78 | } 79 | }; 80 | 81 | const char zahlenGross[][7] = { 82 | { // 0 83 | #ifdef NONE_TECHNICAL_ZERO 84 | 0b00001110, 85 | 0b00010001, 86 | 0b00010001, 87 | 0b00010001, 88 | 0b00010001, 89 | 0b00010001, 90 | 0b00001110 91 | #else 92 | 0b00001110, 93 | 0b00010001, 94 | 0b00010011, 95 | 0b00010101, 96 | 0b00011001, 97 | 0b00010001, 98 | 0b00001110 99 | #endif 100 | }, 101 | { // 1 102 | 0b00000100, 103 | 0b00001100, 104 | 0b00000100, 105 | 0b00000100, 106 | 0b00000100, 107 | 0b00000100, 108 | 0b00001110 109 | }, 110 | { // 2 111 | 0b00001110, 112 | 0b00010001, 113 | 0b00000001, 114 | 0b00000010, 115 | 0b00000100, 116 | 0b00001000, 117 | 0b00011111 118 | }, 119 | { // 3 120 | 0b00011111, 121 | 0b00000010, 122 | 0b00000100, 123 | 0b00000010, 124 | 0b00000001, 125 | 0b00010001, 126 | 0b00001110 127 | }, 128 | { // 4 129 | 0b00000010, 130 | 0b00000110, 131 | 0b00001010, 132 | 0b00010010, 133 | 0b00011111, 134 | 0b00000010, 135 | 0b00000010 136 | }, 137 | { // 5 138 | 0b00011111, 139 | 0b00010000, 140 | 0b00011110, 141 | 0b00000001, 142 | 0b00000001, 143 | 0b00010001, 144 | 0b00001110 145 | }, 146 | { // 6 147 | 0b00000110, 148 | 0b00001000, 149 | 0b00010000, 150 | 0b00011110, 151 | 0b00010001, 152 | 0b00010001, 153 | 0b00001110 154 | }, 155 | { // 7 156 | 0b00011111, 157 | 0b00000001, 158 | 0b00000010, 159 | 0b00000100, 160 | 0b00001000, 161 | 0b00001000, 162 | 0b00001000 163 | }, 164 | { // 8 165 | 0b00001110, 166 | 0b00010001, 167 | 0b00010001, 168 | 0b00001110, 169 | 0b00010001, 170 | 0b00010001, 171 | 0b00001110 172 | }, 173 | { // 9 174 | 0b00001110, 175 | 0b00010001, 176 | 0b00010001, 177 | 0b00001111, 178 | 0b00000001, 179 | 0b00000010, 180 | 0b00001100 181 | } 182 | }; 183 | 184 | #endif 185 | -------------------------------------------------------------------------------- /_Schaltplan.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bracci/QlockWiFive/e23471ddd19c6a11608b0ac4d09ca57131952545/_Schaltplan.fzz -------------------------------------------------------------------------------- /_Schaltplan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bracci/QlockWiFive/e23471ddd19c6a11608b0ac4d09ca57131952545/_Schaltplan.png -------------------------------------------------------------------------------- /_Stueckliste.txt: -------------------------------------------------------------------------------- 1 | 1x 529618 Platine Hartpapier 5,45 CHF 2 | 1x eBay WeMos D1 mini 3,00 EUR 3 | 4 | 115x eBay WS2812 RGB-LED (Neopixel) 17,00 EUR 5 | 1x 567658 Schraubklemmblock Polzahl 4 0,60 CHF 6 | 7 | 1x eBay DS3231 RTC Modul 1,00 EUR (optional) 8 | 9 | 1x 145475 Fotowiderstand A9013 1,95 CHF (optional) 10 | 1x 405370 Kohleschicht-Widerstand 10kΩ 0,15 CHF (optional) 11 | 1x 567588 Schraubklemmblock Polzahl 2 0,30 CHF (optional) 12 | 13 | 1x eBay HX1838 IR-Remote 1,00 EUR (optional) 14 | 1x 171085 IR-Empfaenger TSOP31240 2,25 CHF (optional) 15 | 1x 567615 Schraubklemmblock Polzahl 3 0,45 CHF (optional) 16 | 17 | 1x 567588 Schraubklemmblock Polzahl 2 0,30 CHF 18 | 5V Stromanschluss 19 | --------------------------------------------------------------------------------