├── .github └── FUNDING.yml ├── DOKU ├── 00_DOKU_Install_Arduino_IDE.md ├── 01_DOKU_Vorbereitung_ARDUINO_IDE.md ├── 02_DOKU_Bord_Auswahl.md ├── 03_DOKU_Sketch.md ├── 04_DOKU_Aufbau.md ├── 05_Bedienungsanleitung.md ├── 05_Bedienungsanleitung.pdf ├── Alarm_Screen_Raster.svg ├── Cheap │ ├── Fritzing_Schaltplan.png │ ├── Fritzing_Steckplatine.png │ └── cheap_radiowecker.fzz ├── Config_Screen_Raster.svg ├── Main_Screen_Raster.svg ├── Min │ ├── Fritzing_Schaltplan.png │ ├── Fritzing_Steckplatine.png │ └── min_radiowecker.fzz └── plan.png ├── README.md ├── radiowecker ├── 00_librarys.h ├── 00_pin_settings.h ├── 00_settings.h ├── 00_texte.h ├── 01_ziffern.ino ├── ArduinoJson.h ├── audio.ino ├── fonts.h ├── index.h ├── knoepfe.h ├── num_64_44.h ├── ota.ino ├── radiowecker.ino ├── stations.ino ├── symbole.h ├── tft_color_setting.h ├── tft_display.ino ├── weather.h ├── weather_icons.h ├── webserver.ino └── wlan.ino └── screenshot ├── alarm.jpg ├── info_tab.png ├── radio.jpg ├── result.jpg ├── settings.jpg ├── settings_color.png ├── website.png ├── website_2.png ├── website_3.png ├── website_4.png └── wetter.jpg /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: kunigunde 14 | thanks_dev: beabel 15 | custom: [paypal.me/pleissa] 16 | -------------------------------------------------------------------------------- /DOKU/00_DOKU_Install_Arduino_IDE.md: -------------------------------------------------------------------------------- 1 | # Arduino IDE Installation Guide 2 | 3 | ## Voraussetzungen 4 | Bevor du die Arduino IDE installierst, stelle sicher, dass du die folgenden Voraussetzungen erfüllst: 5 | - Ein kompatibles Betriebssystem: Windows, macOS oder Linux. 6 | - Eine Internetverbindung für den Download. 7 | 8 | ## Installation unter Windows 9 | 10 | 1. **Download der Arduino IDE** 11 | - Gehe zur offiziellen [Arduino Website](https://www.arduino.cc/en/software). 12 | - Wähle die **Windows Installer** Version aus und klicke auf **Download**. 13 | 14 | 2. **Installation** 15 | - Öffne die heruntergeladene `.exe`-Datei. 16 | - Akzeptiere die Lizenzbedingungen. 17 | - Klicke auf **Installieren** und warte, bis der Vorgang abgeschlossen ist. 18 | 19 | 3. **Abschluss** 20 | - Nach der Installation kannst du die Arduino IDE starten und dein erstes Projekt erstellen! 21 | -------------------------------------------------------------------------------- /DOKU/01_DOKU_Vorbereitung_ARDUINO_IDE.md: -------------------------------------------------------------------------------- 1 | # Arduino IDE Setup für ESP32 und benötigte Bibliotheken 2 | 3 | Nachdem die Arduino IDE installiert ist, folgen die Schritte zur Integration des ESP32 Boards und der benötigten Bibliotheken. 4 | 5 | ## 1. ESP32 Boardverwalter-URL hinzufügen 6 | 7 | 1. Öffne die **Arduino IDE**. 8 | 2. Gehe zu `Datei` > `Voreinstellungen` (oder drücke `Strg + ,`). 9 | 3. Im Fenster **Voreinstellungen** findest du das Feld **Zusätzliche Boardverwalter-URLs**. Füge die folgende URL in dieses Feld ein: 10 | ``` 11 | https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json 12 | ``` 13 | 4. Falls bereits andere URLs vorhanden sind, trenne sie mit einem Komma. 14 | 5. Klicke auf **OK**, um die Einstellungen zu speichern. 15 | 16 | ## 2. ESP32 Board installieren 17 | 18 | 1. Gehe zu `Werkzeuge` > `Board` > `Boardverwalter`. 19 | 2. Suche nach **ESP32** im Suchfeld. 20 | 3. Wähle **ESP32 by Espressif Systems** aus und klicke auf **Installieren**. 21 | 22 | > [!IMPORTANT] 23 | > **Hinweis:** Stelle sicher, dass du **Version 2.0.17** auswählst, da es zu Problemen mit größeren Versionen ab 3.x kommen kann.~~ 24 | 25 | |Boardverwalter Version|Sketchgröße| 26 | | ------------- | ------------- | 27 | |2.0.17|:white_check_mark: 1113105| 28 | |3.0.0|:x: 1288101| 29 | |3.0.5|:x: 1312869| 30 | 31 | Das Maximum sind 1310720 Bytes 32 | 33 | 4. Warte, bis die Installation abgeschlossen ist. 34 | 35 | Nach der Installation sollte **ESP32** unter `Werkzeuge` > `Board` auswählbar sein. 36 | 37 | 38 | ## 3. Benötigte Bibliotheken installieren 39 | 40 | Um die benötigten Bibliotheken zu installieren, befolge diese Schritte: 41 | 42 | ### 3.1 Adafruit_ILI9341 by Adafruit (Version 1.6.1) 43 | 44 | 1. Gehe zu `Sketch` > `Include Library` > `Library Manager`. 45 | 2. Suche nach **Adafruit_ILI9341**. 46 | 3. Wähle die **Version 1.6.1** aus dem Dropdown-Menü und klicke auf **Installieren**. 47 | 48 | ### 3.2 Adafruit_GFX by Adafruit (Version 1.12.00) 49 | 50 | 1. Im selben **Library Manager** suche nach **Adafruit_GFX**. 51 | 2. Wähle die **Version 1.12.00** und klicke auf **Installieren**. 52 | 53 | ### 3.3 XPT2046_Touchscreen by Paul Stoffregen (Version 1.4.0) 54 | 55 | 1. Im **Library Manager** suche nach **XPT2046_Touchscreen**. 56 | 2. Wähle die **Version 1.4.0** und klicke auf **Installieren**. 57 | 58 | ### 3.4 Touchevent by Gerald-Lechner (Version 1.3.0) 59 | 60 | 1. Im **Library Manager** suche nach **Touchevent**. 61 | 2. Wähle die **Version 1.3.0** und klicke auf **Installieren**. 62 | 63 | ### 3.5 ESP8266Audio by Earle F. Philhower (Version 2.0.0) 64 | 65 | 1. Im **Library Manager** suche nach **ESP8266Audio**. 66 | 2. Wähle die **Version 2.0.0** und klicke auf **Installieren**. 67 | 68 | ## 4. Abschluss 69 | 70 | Nach der Installation der Board-Verwaltung und Bibliotheken kannst du nun dein ESP32-Projekt starten. Wähle unter `Werkzeuge` > `Board` das ESP32-Board aus, das du verwendest, und beginne mit der Entwicklung! 71 | 72 | --- 73 | 74 | Für weitere Informationen und Unterstützung kannst du die offiziellen Dokumentationen der jeweiligen Bibliotheken oder das Arduino-Forum besuchen. 75 | -------------------------------------------------------------------------------- /DOKU/02_DOKU_Bord_Auswahl.md: -------------------------------------------------------------------------------- 1 | # Konfiguration der Arduino IDE für ESP32 2 | 3 | Nachdem alle Vorbereitungen abgeschlossen sind, folgt die Anleitung zur Auswahl des Boards, zum Finden des richtigen Ports und zur Installation des CH341-Treibers, falls notwendig. 4 | 5 | ## 1. Auswahl des ESP32-Boards 6 | 7 | 1. Öffne die **Arduino IDE**. 8 | 2. Gehe zu `Werkzeuge` > `Board` > `ESP32 Arduino`. 9 | 3. Wähle aus der Liste **"ESP32 Dev Module"** aus. 10 | 11 | Dies ist das Standard-Board, das für die meisten ESP32-Entwicklungsboards verwendet wird. 12 | 13 | ## 2. Den richtigen Port herausfinden 14 | 15 | Um den richtigen COM-Port zu finden, an dem dein ESP32-Board angeschlossen ist, folge diesen Schritten: 16 | 17 | 1. **COM-Port identifizieren:** 18 | - Gehe in der Arduino IDE zu `Werkzeuge` > `Port`. 19 | - Notiere dir die angezeigten Ports, bevor du dein Board anschließt. 20 | - Schließe dein ESP32-Board an und öffne das Menü `Werkzeuge` > `Port` erneut. Ein neuer Eintrag sollte erscheinen. 21 | - Wähle den neuen Port aus (dies ist der COM-Port deines ESP32-Boards). 22 | 23 | **Hinweis:** Wenn du unsicher bist, welcher Port korrekt ist, kannst du den Port im Gerätemanager überprüfen: 24 | - Öffne den **Gerätemanager** (Rechtsklick auf das Windows-Startsymbol > **Gerätemanager**). 25 | - Unter **Anschlüsse (COM & LPT)** siehst du den neuen Port, der erscheint, wenn du das ESP32-Board anschließt. Dies ist der richtige COM-Port. 26 | 27 | ## 3. Installation des CH341-Treibers (falls benötigt) 28 | 29 | Wenn dein ESP32-Board nach dem Anschließen keinen COM-Port anzeigt oder im Gerätemanager nicht erkannt wird, könnte es sein, dass du den CH341-Treiber installieren musst. Dies ist insbesondere für Boards notwendig, die den CH340/CH341-USB-zu-Seriell-Konverter verwenden. 30 | 31 | ### 3.1 CH341-Treiber herunterladen 32 | 33 | 1. Besuche die [offizielle CH341-Treiber-Seite](http://www.wch.cn/download/CH341SER_ZIP.html) oder lade den Treiber von einer vertrauenswürdigen Quelle herunter. 34 | 35 | 2. Lade die `.zip`-Datei herunter und entpacke sie. 36 | 37 | ### 3.2 Treiber installieren 38 | 39 | 1. Öffne die entpackte Datei und starte die `SETUP.exe`. 40 | 2. Folge den Anweisungen auf dem Bildschirm, um den Treiber zu installieren. 41 | 3. Nachdem die Installation abgeschlossen ist, verbinde das ESP32-Board erneut mit dem Computer. 42 | 43 | ### 3.3 Überprüfen der Installation 44 | 45 | 1. Öffne den **Gerätemanager** und überprüfe unter **Anschlüsse (COM & LPT)**, ob der CH340/CH341-Port korrekt angezeigt wird. 46 | 2. Gehe zurück zur Arduino IDE und wähle unter `Werkzeuge` > `Port` den entsprechenden COM-Port aus. 47 | 48 | ## 4. Abschluss 49 | 50 | Nun sollte dein ESP32-Board einsatzbereit sein: 51 | 52 | 1. Stelle sicher, dass unter `Werkzeuge` > `Board` das **ESP32 Dev Module** ausgewählt ist. 53 | 2. Wähle unter `Werkzeuge` > `Port` den richtigen COM-Port. 54 | 3. Du kannst nun mit der Programmierung deines ESP32-Boards beginnen und das erste Programm hochladen. 55 | 56 | --- 57 | 58 | Falls du auf Probleme stößt, überprüfe, ob alle Treiber korrekt installiert sind, und konsultiere die [offizielle Arduino-Hilfe](https://www.arduino.cc/en/Guide/Troubleshooting) für weitere Unterstützung. 59 | -------------------------------------------------------------------------------- /DOKU/03_DOKU_Sketch.md: -------------------------------------------------------------------------------- 1 | # Arduino Projekt "Radiowecker" aus GitHub herunterladen und öffnen 2 | 3 | Nachdem alle Vorbereitungen getroffen sind, folgt hier die Anleitung, wie du das Projekt aus dem GitHub-Repository herunterlädst und in der Arduino IDE öffnest. 4 | 5 | ## 1. GitHub-Repository herunterladen 6 | 7 | 1. **Besuche das GitHub-Repository:** 8 | - Gehe in deinem Browser auf die Seite des Repositories: [https://github.com/beabel/radiowecker](https://github.com/beabel/radiowecker). 9 | 10 | 2. **Projekt herunterladen:** 11 | - Klicke auf den grünen Button **Code**. 12 | - Wähle **Download ZIP** aus. Dies lädt das gesamte Repository als ZIP-Datei auf deinen Computer herunter. 13 | 14 | 3. **ZIP-Datei entpacken:** 15 | - Navigiere zu dem Ordner, in dem die ZIP-Datei heruntergeladen wurde. 16 | - Entpacke die ZIP-Datei, indem du mit der rechten Maustaste darauf klickst und **Alle extrahieren...** auswählst oder ein entsprechendes Entpack-Tool verwendest. 17 | - Der entpackte Ordner sollte denselben Namen wie das Repository haben (z.B. `radiowecker-main`). 18 | 19 | ## 2. Sketch in der Arduino IDE öffnen 20 | 21 | 1. **Sketch öffnen:** 22 | - Starte die **Arduino IDE**. 23 | - Gehe zu `Datei` > `Öffnen...`. 24 | - Navigiere zu dem entpackten Ordner `radiowecker-main/radiowecker`. 25 | - Wähle die Datei `radiowecker.ino` aus und klicke auf **Öffnen**. 26 | 27 | 2. **Überprüfung des Projekts:** 28 | - Sobald der Sketch in der Arduino IDE geöffnet ist, überprüfe, ob alle Bibliotheken, die im Sketch verwendet werden, bereits installiert sind (du kannst dies durch Kompilieren des Sketches prüfen, indem du auf das Häkchen-Symbol oben links klickst). 29 | - Falls Fehler auftreten, stelle sicher, dass alle benötigten Bibliotheken, die in den vorherigen Schritten installiert wurden, korrekt integriert sind. 30 | 31 | ## 3. Sketch hochladen 32 | 33 | 1. **Board und Port überprüfen:** 34 | - Stelle sicher, dass unter `Werkzeuge` > `Board` das **ESP32 Dev Module** ausgewählt ist. 35 | - Wähle unter `Werkzeuge` > `Port` den richtigen COM-Port aus, an dem dein ESP32-Board angeschlossen ist. 36 | 37 | 2. **Sketch hochladen:** 38 | - Klicke auf den **Hochladen**-Button (Pfeil-Symbol) in der Arduino IDE, um den Sketch auf dein ESP32-Board zu übertragen. 39 | 40 | ## 4. Abschluss 41 | 42 | Nachdem der Sketch erfolgreich hochgeladen wurde, sollte das Radiowecker-Projekt auf deinem ESP32-Board laufen. Du kannst jetzt den seriellen Monitor in der Arduino IDE öffnen, um Ausgaben zu beobachten und sicherzustellen, dass alles wie erwartet funktioniert. 43 | 44 | --- 45 | 46 | Für weitere Anpassungen oder Informationen zum Projekt kannst du das GitHub-Repository durchsuchen oder die Dokumentation des Projekts lesen. 47 | -------------------------------------------------------------------------------- /DOKU/04_DOKU_Aufbau.md: -------------------------------------------------------------------------------- 1 | # Aufbau des Radiowecker-Projekts 2 | 3 | Es gibt mehrere Möglichkeiten, das Radiowecker-Projekt aufzubauen. Hier sind die verschiedenen Optionen beschrieben, einschließlich der benötigten Komponenten und Schritte. 4 | 5 | ## 1. Option 1: Verwenden des AZ-Touch Sets von AZ-Delivery 6 | 7 | ### Komponenten: 8 | - **AZ-Touch Set** (inkl. ESP32 Dev Kit v4, 2.8" TFT-Display, Max98357A, Lautsprecher) 9 | - Dieses Set enthält alle notwendigen Komponenten und eine vorgefertigte Platine, sodass keine zusätzlichen Teile benötigt werden. 10 | 11 | ### Aufbau: 12 | 13 | 1. **Bestellen des Sets:** 14 | - Das AZ-Touch Set kann über diesen [Link](https://www.az-delivery.de/products/radiowecker-mit-dem-az-touch?_pos=2&_psq=az-touch&_ss=e&_v=1.0) erworben werden. 15 | 16 | 2. **Zusammenbau:** 17 | - Folge den Anweisungen, die im [hier](https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/internet-radiowecker-mit-touchscreen) enthalten sind. 18 | - Löte die Verbindungen, wie in der Anleitung beschrieben, um die Komponenten zu verbinden 19 | - Montiere das Display und die Lautsprecher in das Gehäuse des AZ-Touch. 20 | - Verbinde den ESP32 Dev Kit v4 mit der Platine im Gehäuse. 21 | 22 | 3. **Software hochladen:** 23 | - Nachdem der Aufbau abgeschlossen ist, lade den Sketch wie in den vorherigen Anleitungen beschrieben auf das ESP32-Board. 24 | 25 | 4. **Test:** 26 | - Stelle sicher, dass das Display, die Lautsprecher und alle anderen Komponenten ordnungsgemäß funktionieren. 27 | 28 | --- 29 | 30 | ## 2. Option 2: Verwenden einer fertigen Platine 31 | 32 | ### Komponenten: 33 | - **ESP32 Dev Kit v4** 34 | - **2.8" TFT-Display** 35 | - **2x Max98357A I2S Digital-Analog-Wandler** 36 | - **Lautsprecher** 37 | - **Fertige Platine nach dem Schaltplan auf EasyEDA** 38 | 39 | ### Aufbau: 40 | 41 | 1. **Platinenlayout:** 42 | - Besuche den Schaltplan auf EasyEDA: [EasyEDA Schaltplan](https://easyeda.com/editor#project_id=b7c90a5cbe554e4dbcf25dbf78662e11). 43 | - Du kannst die Platine entweder selbst herstellen oder bei einem PCB-Hersteller in Auftrag geben. 44 | 45 | 2. **Zusammenbau:** 46 | - Sobald die Platine fertig ist, montiere die Komponenten auf der Platine. 47 | - Löte die Verbindungen gemäß dem Schaltplan. 48 | 49 | 3. **Software hochladen:** 50 | - Nach dem Zusammenbau der Platine lade den Sketch wie zuvor beschrieben auf das ESP32-Board. 51 | 52 | 4. **Test:** 53 | - Prüfe, ob die Verbindungen korrekt sind und alle Komponenten funktionieren. 54 | 55 | --- 56 | 57 | ## 3. Option 3: Aufbau auf einem Steckbrett 58 | 59 | ### Komponenten: 60 | - **ESP32 Dev Kit v4** 61 | - **2.8" TFT-Display** 62 | - **2x Max98357A I2S Digital-Analog-Wandler** 63 | - **Lautsprecher** 64 | - **Steckbrett und Jumper-Kabel** 65 | 66 | ### Aufbau: 67 | 68 | 1. **Bestellen der Komponenten:** 69 | - Besorge dir die notwendigen Komponenten: 70 | - ESP32 Dev Kit v4 71 | - 2.8" TFT-Display 72 | - 2x Max98357A 73 | - Lautsprecher 74 | - Steckbrett und Jumper-Kabel 75 | 76 | 2. **Schaltplan und Verdrahtung:** 77 | - Verwende den Schaltplan auf [Github](https://github.com/beabel/radiowecker/blob/main/DOKU/Cheap/Fritzing_Steckplatine.png) als Referenz für die Verdrahtung. 78 | - Platziere die Komponenten auf dem Steckbrett und verbinde sie mit den Jumper-Kabeln. 79 | 80 | 3. **Verbindungen herstellen:** 81 | - **TFT-Display**: Verbinde die Pins des Displays entsprechend mit dem ESP32 Dev Kit. 82 | - **Max98357A**: Verbinde die zwei Max98357A-Module mit dem ESP32 für die Audio-Ausgabe. 83 | - **Lautsprecher**: Schließe die Lautsprecher an die Ausgänge der Max98357A-Module an. 84 | 85 | 4. **Software hochladen:** 86 | - Lade den Sketch auf das ESP32-Board hoch, wie in den vorherigen Anleitungen beschrieben. 87 | 88 | 5. **Test:** 89 | - Überprüfe die Verbindungen und teste die Funktionalität des Radioweckers. 90 | 91 | --- 92 | 93 | ## Abschluss 94 | 95 | Egal für welche Option du dich entscheidest, nach dem Aufbau und Hochladen der Software sollte dein Radiowecker funktionieren. Bei Problemen überprüfe alle Verbindungen und stelle sicher, dass alle Komponenten korrekt installiert sind. Viel Spaß beim Bauen und Programmieren! 96 | -------------------------------------------------------------------------------- /DOKU/05_Bedienungsanleitung.md: -------------------------------------------------------------------------------- 1 | # Bedienungsanleitung 2 | 3 | ## Erste Schritte und Verbindung zum WLAN 4 | 5 | 1. **Gerät einschalten** 6 | Nach dem ersten Start des DIY-Webradios oder wenn das Gerät kein bekanntes WLAN-Netzwerk findet, zeigt das Display die Meldung: 7 | 8 | ![IMG20240829222852](https://github.com/user-attachments/assets/b9cd9628-1b1a-47af-a4ec-16bbda20790b) 9 | 10 | 2. **Verbindung mit dem Konfigurations-WLAN herstellen** 11 | Auf deinem Smartphone, Tablet oder Computer öffnest du die WLAN-Einstellungen und suchst nach verfügbaren Netzwerken. Wähle das Netzwerk mit der SSID (Netzwerkname) `radioweckerconf` aus, um dich mit dem Radiowecker zu verbinden. Dies ist ein temporäres Netzwerk, das das Radio erstellt, um die Konfiguration zu ermöglichen. 12 | 13 | 3. **Zugriff auf das Einstellungsmenü** 14 | Sobald die Verbindung hergestellt ist, öffne einen Webbrowser (z. B. Chrome, Firefox, Safari) und gib in der Adressleiste die IP-Adresse `192.168.4.1` ein. Diese IP-Adresse führt dich zur Einstellungsseite des Radios. 15 | 16 | ![Screenshot_2024-08-29-23-22-25-22_40deb401b9ffe8e1df2f1cc5ba480b12](https://github.com/user-attachments/assets/bfbfbaba-883e-4363-8fa7-d76cd5086622) 17 | 18 | 4. **WLAN-Konfiguration** 19 | Auf der Einstellungsseite wirst du aufgefordert, das WLAN-Netzwerk auszuwählen, mit dem das Radio dauerhaft verbunden werden soll. Wähle dein gewünschtes WLAN-Netzwerk aus und gib das entsprechende Passwort ein. Speichere die Einstellungen. 20 | 21 | 5. **Neustart des Geräts** 22 | Nach der erfolgreichen Konfiguration wird der Radiowecker das temporäre Netzwerk `radioweckerconf` beenden und sich mit dem neu konfigurierten WLAN-Netzwerk verbinden. Das Radio sollte nun betriebsbereit sein und du kannst Sender auswählen und abspielen. 23 | 24 | ## Fehlerbehebung 25 | 26 | - **Verbindung fehlgeschlagen** 27 | Falls das DIY-Webradio nach der Konfiguration keine Verbindung zum gewünschten WLAN herstellen kann, wird erneut die Meldung "Nicht verbunden" angezeigt. In diesem Fall wiederhole den Verbindungsprozess. 28 | 29 | - **WLAN-Netzwerkwechsel** 30 | Solltest du das WLAN-Netzwerk wechseln müssen, kannst du das Gerät zurücksetzen oder einen ähnlichen Prozess durchlaufen, um das temporäre Netzwerk wiederherzustellen und eine neue Konfiguration vorzunehmen. 31 | 32 | ![IMG20240829222947](https://github.com/user-attachments/assets/173331b3-420c-48e5-8cce-321bdef13102) 33 | 34 | ## Anzeige auf dem TFT-Display 35 | 36 | 1. **Statusleiste (oben im Display):** 37 | - **Weckerstatus**: Ein Symbol zeigt an, ob der Wecker aktiviert oder deaktiviert ist. Ein Glockensymbol, das bei aktivem Wecker orange ist und die nächste Weckzeit anzeigt. Bei deaktiviertem Wecker ist ein rotes, durchgestrichenes Symbol sichtbar. 38 | - **Einschlaftimer**: Ein weiteres Symbol zeigt den Status des Einschlaftimers an. Ist der Timer aktiv, erscheint ein "Bett"-Symbol. Wenn der Timer nicht aktiv ist, ist dieses Symbol ausgeblendet. 39 | - **IP-Adresse**: Die aktuelle IP-Adresse des Geräts wird angezeigt, um bei Bedarf eine direkte Verbindung oder weitere Einstellungen zu ermöglichen. 40 | - **WLAN-Signalstärke**: Die Signalstärke des WLANs wird sowohl als numerischer Wert als auch als farbiges Symbol dargestellt: 41 | - **Grün**: Starkes Signal 42 | - **Gelb**: Mittelmäßiges Signal 43 | - **Rot**: Schwaches Signal 44 | 45 | 2. **Hauptanzeige (mittig im Display):** 46 | - **Aktuelle Uhrzeit**: Die aktuelle Uhrzeit wird prominent angezeigt, damit sie leicht ablesbar ist. 47 | - **Aktuelles Datum**: Unter der Uhrzeit wird das aktuelle Datum angezeigt, damit du sowohl die Zeit als auch das Datum im Blick hast. 48 | 49 | 3. **Lautstärkeregler (unten im Display):** 50 | - Ein Schieberegler für die Lautstärke befindet sich am unteren Rand des Displays. Du kannst den Regler nach links oder rechts schieben, um die Lautstärke des Webradios anzupassen. 51 | 52 | 4. **Radio:** 53 | - **Sendername und Titel**: Wenn ein Sender gerade läuft, werden hier die Informationen des Senders und des Titels angezeigt. 54 | - **Senderwechsel**: Ab Version 3.0.5 ist es möglich, rechts und links zum nächsten aktivierten Sender zu springen, ohne erst auf eine Unterseite schalten zu müssen. Dies erfolgt durch Berührung an den Seiten, 40px jeweils von den Rändern. 55 | 56 | 5. **Anzeige Einstellungs-Seiten:** 57 | - **Unterseiten**: Durch eine Berührung in die Mitte des Touchscreens wird die Unterseite Radio-Einstellungen angezeigt. Wenn keine Berührung mehr registriert wird, schaltet es automatisch zurück zur Hauptanzeige. 58 | 59 | ![Menu_Struktur_Bedienung](https://github.com/user-attachments/assets/11992ce4-75e4-4e49-ab48-89516053c784) 60 | 61 | -------------------------------------------------------------------------------- /DOKU/05_Bedienungsanleitung.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/DOKU/05_Bedienungsanleitung.pdf -------------------------------------------------------------------------------- /DOKU/Alarm_Screen_Raster.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 37 | 53 | 54 | 56 | 62 | 63 | 67 | 75 | 83 | 91 | 99 | 107 | 111 | 115 | 123 | 131 | 139 | 147 | 155 | 163 | 164 | 168 | 176 | 184 | 192 | 200 | 208 | 216 | 224 | 232 | 233 | 237 | 245 | 253 | 261 | 269 | 277 | 285 | 286 | 290 | 298 | 306 | 314 | 322 | 330 | 338 | 346 | 354 | 355 | 356 | 357 | -------------------------------------------------------------------------------- /DOKU/Cheap/Fritzing_Schaltplan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/DOKU/Cheap/Fritzing_Schaltplan.png -------------------------------------------------------------------------------- /DOKU/Cheap/Fritzing_Steckplatine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/DOKU/Cheap/Fritzing_Steckplatine.png -------------------------------------------------------------------------------- /DOKU/Cheap/cheap_radiowecker.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/DOKU/Cheap/cheap_radiowecker.fzz -------------------------------------------------------------------------------- /DOKU/Config_Screen_Raster.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 37 | 53 | 54 | 56 | 62 | 63 | 67 | 75 | 83 | 91 | 99 | 107 | 111 | 115 | 123 | 132 | 141 | 150 | 151 | 155 | 163 | 171 | 180 | 183 | 191 | 199 | 207 | 208 | 209 | 213 | 221 | 229 | 238 | 241 | 249 | 257 | 265 | 266 | 267 | 271 | 279 | 287 | 296 | 299 | 307 | 315 | 323 | 324 | 325 | 326 | 327 | -------------------------------------------------------------------------------- /DOKU/Main_Screen_Raster.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 36 | 52 | 53 | 55 | 61 | 62 | 66 | 70 | 78 | 86 | 94 | 124 | 128 | 136 | 144 | 152 | 160 | 168 | 176 | 184 | 192 | 200 | 208 | 216 | 224 | 232 | 240 | 248 | 249 | 257 | 261 | 269 | 277 | 285 | 293 | 301 | 302 | 305 | 313 | 321 | 329 | 337 | 345 | 353 | 354 | 355 | 356 | -------------------------------------------------------------------------------- /DOKU/Min/Fritzing_Schaltplan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/DOKU/Min/Fritzing_Schaltplan.png -------------------------------------------------------------------------------- /DOKU/Min/Fritzing_Steckplatine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/DOKU/Min/Fritzing_Steckplatine.png -------------------------------------------------------------------------------- /DOKU/Min/min_radiowecker.fzz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/DOKU/Min/min_radiowecker.fzz -------------------------------------------------------------------------------- /DOKU/plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/DOKU/plan.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | |[:skull:ISSUE](https://github.com/beabel/radiowecker/issues?q=is%3Aissue)|[:speech_balloon: Forum /Discussion](https://github.com/beabel/radiowecker/discussions?discussions_q=)|[:grey_question:WiKi](https://github.com/beabel/radiowecker/wiki)| 7 | |--|--|--| 8 | |![GitHub issues](https://img.shields.io/github/issues/beabel/radiowecker)![GitHub closed issues](https://img.shields.io/github/issues-closed/beabel/radiowecker)|![GitHub Discussions](https://img.shields.io/github/discussions/beabel/radiowecker)![GitHub User's stars](https://img.shields.io/github/stars/beabel)|![GitHub release (with filter)](https://img.shields.io/github/v/release/beabel/radiowecker) 9 | 10 | 11 |
12 | 13 | 14 | |This project is based on the blog article "[Internet clock radio with touchscreen](https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/internet-radiowecker-mit-touchscreen)" by Gerald Lechner / Az-Delivery. | Dieses Projekt basiert auf dem Blogartikel "[Internet Radiowecker mit Touchscreen](https://www.az-delivery.de/blogs/azdelivery-blog-fur-arduino-und-raspberry-pi/internet-radiowecker-mit-touchscreen)" von Gerald Lechner / Az-Delivery. | 15 | |--|--| 16 | 17 | > [!NOTE] 18 | > **Instruction / Anleitung** 19 | > Eine detailierte Anleitung befindet sich [hier](https://github.com/beabel/radiowecker/wiki). 20 | 21 | **Parts required: / Benötigte Teile:** 22 | 23 | ||Pro|Cheap|Minimal| 24 | |--|--|--|--| 25 | |[1 x AZ-Touch MOD mit 2,8" Touchscreen](https://amzn.to/3srKxjE)|:white_check_mark:|:ballot_box_with_check:[1xTFT](https://amzn.to/3MEtdyy)|:x:| 26 | |[1 x ESP-32 Dev Kit C V4](https://amzn.to/40ApxUA)|:white_check_mark:|:white_check_mark:|:white_check_mark:| 27 | |[2 x I2S 3W MAX98357A](https://amzn.to/3QSHtGF)|:white_check_mark:|:white_check_mark:|:white_check_mark:(1x)| 28 | |[1 x Lautsprecher Set](https://amzn.to/3SSyQNR)|:white_check_mark:|:white_check_mark:|:white_check_mark:| 29 | |[1 x Widerstand 470 kOhm](https://amzn.to/3Sw17cL)|:white_check_mark:|:white_check_mark:|:white_check_mark:(1x470kOhm)| 30 | |[DC Einbaubuchse](https://amzn.to/47it0ZY)|:white_check_mark:|:x:|:x:| 31 | |[1 x LDR](https://amzn.to/3FQYCKq)|:white_check_mark:|:x:|:x:| 32 | ||~95,-|~54,-|~37,-| 33 | 34 | [German Version below / Deutsche Version unten:point_down:](#german-version) 35 | ---- 36 | # Clock radio 37 | 38 | I have extended and adapted this project. 39 | 40 | 41 | At the time of publishing this blog article, a complete set was available for purchase from AZ-Delivery. Currently this is not offered, but all required parts can be ordered individually. 42 | 43 | 44 | **[Additional information::point_down:](#informationen)** 45 | 46 | ## [Screenshots:point_down:](#screenshots) 47 | 48 | ## German Version 49 | 50 | # Radiowecker 51 | 52 | Ich habe dieses Projekt erweitert und angepasst. 53 | 54 | Zum Zeitpunkt der Veröffentlichung des Blogartikels gab es ein vollständiges Set bei AZ-Delivery zu kaufen. Aktuell wird dies nicht angeboten, aber alle benötigten Teile können einzeln bestellt werden. 55 | 56 | # Informationen 57 | 58 | **Boardverwalter URL:** 59 | [https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json](https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json) 60 | - ESP32 von Espressif Systems 61 | 62 | > [!IMPORTANT] 63 | > **Hinweis:** Stelle sicher, dass du **Version 2.0.17** auswählst, da es zu Problemen mit größeren Versionen ab 3.x kommen kann.~~ 64 | 65 | |Boardverwalter Version|Sketchgröße| 66 | | ------------- | ------------- | 67 | |2.0.17|:white_check_mark: 1113105| 68 | |3.0.0|:x: 1288101| 69 | |3.0.5|:x: 1312869| 70 | 71 | **Bibliotheken:** 72 | - [Adafruit_ILI9341 by Adafruit Version 1.6.1](https://github.com/adafruit/Adafruit_ILI9341) 73 | - [Adafruit_GFX by Adafruit Version 1.12.00](https://github.com/adafruit/Adafruit-GFX-Library) 74 | - [XPT2046_Touchscreen by Paul Stoffregen Version 1.4.0](https://github.com/PaulStoffregen/XPT2046_Touchscreen) 75 | - [Touchevent by Gerald-Lechner Version 1.3.0](https://github.com/GerLech/TouchEvent) 76 | - [ESP8266Audio by Earle F. Philhower Version 2.0.0](https://github.com/earlephilhower/ESP8266Audio) 77 | 78 | # Screenshots 79 | 80 | ![Main Screen](screenshot/result.jpg?raw=true "Hauptbildschirm") 81 | 82 | ![Wetter Anzeige](screenshot/wetter.jpg?raw=true "Wetter Anzeige") 83 | 84 | ![Radio Screen](screenshot/radio.jpg?raw=true "Radiobildschirm") 85 | 86 | ![Setting Screen](screenshot/settings.jpg?raw=true "Einstellungen") 87 | 88 | ![Alarm Screen](screenshot/alarm.jpg?raw=true "Alarm Einstellungen") 89 | 90 | ![Color Setting](screenshot/settings_color.png?raw=true "Farbeinstellungen") 91 | 92 | ![Konfigurationswebsite](screenshot/website.png?raw=true "Musik") 93 | 94 | ![Konfigurationswebsite](screenshot/website_2.png?raw=true "Wecker") 95 | 96 | ![Konfigurationswebsite](screenshot/website_3.png?raw=true "Radio") 97 | 98 | ![Konfigurationswebsite](screenshot/website_4.png?raw=true "WLAN") 99 | 100 | ![Info Tab](screenshot/info_tab.png?raw=true "Info Tab") 101 | 102 | # Bedienungsanleitung 103 | 104 | ## Erste Schritte und Verbindung zum WLAN 105 | 106 | 1. **Gerät einschalten** 107 | Nach dem ersten Start des DIY-Webradios oder wenn das Gerät kein bekanntes WLAN-Netzwerk findet, zeigt das Display die Meldung: 108 | 109 | ![IMG20240829222852](https://github.com/user-attachments/assets/b9cd9628-1b1a-47af-a4ec-16bbda20790b) 110 | 111 | 2. **Verbindung mit dem Konfigurations-WLAN herstellen** 112 | Auf deinem Smartphone, Tablet oder Computer öffnest du die WLAN-Einstellungen und suchst nach verfügbaren Netzwerken. Wähle das Netzwerk mit der SSID (Netzwerkname) `radioweckerconf` aus, um dich mit dem Radiowecker zu verbinden. Dies ist ein temporäres Netzwerk, das das Radio erstellt, um die Konfiguration zu ermöglichen. 113 | 114 | 3. **Zugriff auf das Einstellungsmenü** 115 | Sobald die Verbindung hergestellt ist, öffne einen Webbrowser (z. B. Chrome, Firefox, Safari) und gib in der Adressleiste die IP-Adresse `192.168.4.1` ein. Diese IP-Adresse führt dich zur Einstellungsseite des Radios. 116 | 117 | ![Screenshot_2024-08-29-23-22-25-22_40deb401b9ffe8e1df2f1cc5ba480b12](https://github.com/user-attachments/assets/bfbfbaba-883e-4363-8fa7-d76cd5086622) 118 | 119 | 4. **WLAN-Konfiguration** 120 | Auf der Einstellungsseite wirst du aufgefordert, das WLAN-Netzwerk auszuwählen, mit dem das Radio dauerhaft verbunden werden soll. Wähle dein gewünschtes WLAN-Netzwerk aus und gib das entsprechende Passwort ein. Speichere die Einstellungen. 121 | 122 | 5. **Neustart des Geräts** 123 | Nach der erfolgreichen Konfiguration wird der Radiowecker das temporäre Netzwerk `radioweckerconf` beenden und sich mit dem neu konfigurierten WLAN-Netzwerk verbinden. Das Radio sollte nun betriebsbereit sein und du kannst Sender auswählen und abspielen. 124 | 125 | ## Fehlerbehebung 126 | 127 | - **Verbindung fehlgeschlagen** 128 | Falls das DIY-Webradio nach der Konfiguration keine Verbindung zum gewünschten WLAN herstellen kann, wird erneut die Meldung "Nicht verbunden" angezeigt. In diesem Fall wiederhole den Verbindungsprozess. 129 | 130 | - **WLAN-Netzwerkwechsel** 131 | Solltest du das WLAN-Netzwerk wechseln müssen, kannst du das Gerät zurücksetzen oder einen ähnlichen Prozess durchlaufen, um das temporäre Netzwerk wiederherzustellen und eine neue Konfiguration vorzunehmen. 132 | 133 | ![IMG20240829222947](https://github.com/user-attachments/assets/173331b3-420c-48e5-8cce-321bdef13102) 134 | 135 | ## Anzeige auf dem TFT-Display 136 | 137 | 1. **Statusleiste (oben im Display):** 138 | - **Weckerstatus**: Ein Symbol zeigt an, ob der Wecker aktiviert oder deaktiviert ist. Ein Glockensymbol, das bei aktivem Wecker orange ist und die nächste Weckzeit anzeigt. Bei deaktiviertem Wecker ist ein rotes, durchgestrichenes Symbol sichtbar. 139 | - **Einschlaftimer**: Ein weiteres Symbol zeigt den Status des Einschlaftimers an. Ist der Timer aktiv, erscheint ein "Bett"-Symbol. Wenn der Timer nicht aktiv ist, ist dieses Symbol ausgeblendet. 140 | - **IP-Adresse**: Die aktuelle IP-Adresse des Geräts wird angezeigt, um bei Bedarf eine direkte Verbindung oder weitere Einstellungen zu ermöglichen. 141 | - **WLAN-Signalstärke**: Die Signalstärke des WLANs wird sowohl als numerischer Wert als auch als farbiges Symbol dargestellt: 142 | - **Grün**: Starkes Signal 143 | - **Gelb**: Mittelmäßiges Signal 144 | - **Rot**: Schwaches Signal 145 | 146 | 2. **Hauptanzeige (mittig im Display):** 147 | - **Aktuelle Uhrzeit**: Die aktuelle Uhrzeit wird prominent angezeigt, damit sie leicht ablesbar ist. 148 | - **Aktuelles Datum**: Unter der Uhrzeit wird das aktuelle Datum angezeigt, damit du sowohl die Zeit als auch das Datum im Blick hast. 149 | 150 | 3. **Lautstärkeregler (unten im Display):** 151 | - Ein Schieberegler für die Lautstärke befindet sich am unteren Rand des Displays. Du kannst den Regler nach links oder rechts schieben, um die Lautstärke des Webradios anzupassen. 152 | 153 | 4. **Radio:** 154 | - **Sendername und Titel**: Wenn ein Sender gerade läuft, werden hier die Informationen des Senders und des Titels angezeigt. 155 | - **Senderwechsel**: Ab Version 3.0.5 ist es möglich, rechts und links zum nächsten aktivierten Sender zu springen, ohne erst auf eine Unterseite schalten zu müssen. Dies erfolgt durch Berührung an den Seiten, 40px jeweils von den Rändern. 156 | 157 | 5. **Anzeige Einstellungs-Seiten:** 158 | - **Unterseiten**: Durch eine Berührung in die Mitte des Touchscreens wird die Unterseite Radio-Einstellungen angezeigt. Wenn keine Berührung mehr registriert wird, schaltet es automatisch zurück zur Hauptanzeige. 159 | 160 | ![Menu_Struktur_Bedienung](https://github.com/user-attachments/assets/11992ce4-75e4-4e49-ab48-89516053c784) 161 | 162 | --- 163 | 164 | [![DJ Perry](https://github.com/user-attachments/assets/d750acc2-be60-44ec-8f23-0b9f69b249b6)](https://www.pulse107.com) 165 | [![Pulse 107](https://github.com/user-attachments/assets/02919e84-bc1d-4336-82cd-6e2b9bc36ce8)](https://www.pulse107.com/pulse-107) 166 | [![Strobe Radio](https://github.com/user-attachments/assets/a911f569-5a28-416c-8ecd-8053fa2392ae)](https://www.pulse107.com/the-strobe-radio) 167 | 168 | 169 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /radiowecker/00_librarys.h: -------------------------------------------------------------------------------- 1 | // Bibliotheken für WiFi und Over-the-Air (OTA) Updates 2 | #include 3 | #include 4 | 5 | // TFT & Touchscreen Bibliotheken 6 | #include // Basisbibliothek für Grafikanzeige 7 | #include // Treiberbibliothek für das ILI9341 TFT-Display 8 | #include // Treiberbibliothek für das XPT2046 Touchscreen 9 | #include // Bibliothek zur Analyse von Touchscreen-Ereignissen 10 | 11 | // ESP32 Bibliothek zum Speichern von Einstellungen im Flash-Speicher 12 | #include 13 | 14 | // Bibliothek für den eingebauten Webserver 15 | #include 16 | 17 | // Bibliotheken für Audio-Funktionen 18 | // Enthält Klassen für die Audiowiedergabe und -verarbeitung 19 | #include // Klasse für den Eingabestream von ICY (Internet Radio) Streams 20 | #include // Klasse für das Puffern von Audio-Daten 21 | #include // MP3-Decoder Klasse 22 | #include // Klasse für die Audioausgabe über I2S (Inter-IC Sound) Schnittstelle -------------------------------------------------------------------------------- /radiowecker/00_pin_settings.h: -------------------------------------------------------------------------------- 1 | // Pin-Definitionen für verschiedene Komponenten des Projekts 2 | 3 | // Pin für den Lichtsensor (LDR) 4 | #define LDR 36 5 | 6 | // Pin für den Buzzer auf dem originalen Az-Delivery TouchMod 7 | #define BEEPER 21 8 | 9 | // Audio-Pins 10 | #define LRCLK 25 // Left-Right Clock für die Audioausgabe 11 | #define BCLK 26 // Bit Clock für die Audioausgabe 12 | #define DOUT 33 // Daten-Ausgang für die Audioausgabe 13 | 14 | // Pins für den Touchscreen 15 | #define TOUCH_CS 14 // Chip Select für den Touchscreen 16 | #define TOUCH_IRQ 27 // Interrupt-Anschluss für den Touchscreen 17 | 18 | // Pins für das TFT-Display 19 | #define TFT_CS 5 // Chip Select für das TFT-Display 20 | #define TFT_DC 4 // Data/Command Pin für das TFT-Display 21 | #define TFT_RST 22 // Reset-Pin für das TFT-Display 22 | #define TFT_LED 15 // Hintergrundbeleuchtung des TFT-Displays 23 | #define LED_ON 0 // Logikpegel für die Hintergrundbeleuchtung (0 = Ein) -------------------------------------------------------------------------------- /radiowecker/00_settings.h: -------------------------------------------------------------------------------- 1 | // Instanzen der Preferences-Klasse für die Speicherung von Einstellungen 2 | Preferences pref; // Allgemeine Instanz für die Nutzung der Preferences 3 | Preferences sender; // Zusätzliche Instanz, möglicherweise für spezielle Konfigurationen 4 | 5 | // Struktur zur Speicherung der Stationsdaten 6 | typedef struct { 7 | char url[150]; // URL des Streams der Station 8 | char name[32]; // Name der Station 9 | uint8_t enabled; // Flag zur Aktivierung der Station (1 = aktiv, 0 = inaktiv) 10 | } Station; 11 | 12 | // Konstanten 13 | #define STATIONS 30 // Anzahl der Stationen in der Liste 14 | #define MINUTES_PER_DAY 1440 // Anzahl der Minuten in einem Tag (24 Stunden * 60 Minuten) 15 | 16 | // Globale Variablen 17 | Station stationlist[STATIONS]; // Liste der verfügbaren Stationen 18 | 19 | // Variablen zur Speicherung von Konfigurationsdaten 20 | String ssid = ""; // SSID für die WLAN-Verbindung 21 | String pkey = ""; // Passwort für die WLAN-Verbindung 22 | String ntp = "de.pool.ntp.org"; // URL des NTP-Servers zur Zeitabgleich 23 | uint8_t curStation = 0; // Index der aktuell ausgewählten Station in der stationlist 24 | uint8_t curGain = 200; // Aktuelle Lautstärke (Gain) 25 | uint8_t snoozeTime = 30; // Schlummerzeit in Minuten 26 | uint16_t alarm1 = 390; // Erste Alarmzeit (6:30 Uhr in Minuten nach Mitternacht) 27 | uint8_t alarmday1 = 0B00111110; // Gültige Wochentage für den ersten Alarm (Beispiel: 00111110 = Montag bis Freitag) 28 | uint16_t alarm2 = 480; // Zweite Alarmzeit (8:00 Uhr in Minuten nach Mitternacht) 29 | uint8_t alarmday2 = 0B01000001; // Gültige Wochentage für den zweiten Alarm (Beispiel: 01000001 = Sonntag und Samstag) 30 | uint8_t actStation = 0; // Index der aktuellen Station in der Liste, verwendet für das Streaming 31 | uint8_t bright = 25; // Helligkeit in Prozent. 0 bedeutet, dass der LDR die Helligkeit regelt 32 | 33 | // Weitere globale Variablen 34 | uint32_t lastchange = 0; // Zeitpunkt der letzten Auswahländerung 35 | uint32_t snoozeTimeEnd = 0; // Zeitpunkt zum Beenden des Schlummermodus 36 | uint16_t alarmtime = 0; // Nächste relevante Alarmzeit 37 | uint8_t alarmday = 8; // Wochentag für den nächsten relevanten Alarm oder 8 bedeutet Alarm deaktiviert 38 | char title[64]; // Zeichenarray zur Speicherung der Metadaten-Nachricht 39 | bool newTitle = false; // Flag zum Signalisieren eines neuen Titels 40 | uint32_t tick = 0; // Letzter Wert des Tick-Counters zur Auslösung zeitgesteuerter Ereignisse 41 | uint32_t discon = 0; // Tick-Counter-Wert zur Berechnung der Zeit der Trennung 42 | uint16_t minutes; // Aktuelle Anzahl der Minuten seit Mitternacht 43 | uint8_t weekday; // Aktueller Wochentag 44 | struct tm ti; // Zeitstruktur mit der aktuellen Zeit 45 | int16_t lastldr; // Letzter Wert vom LDR-Sensor zur Erkennung von Änderungen 46 | uint32_t start_conf; // Zeitpunkt des Betretens des Konfigurationsbildschirms 47 | boolean connected; // Flag zum Signalisieren einer aktiven Verbindung 48 | boolean reconnected = false; // Flag zum Signalisieren einer erfolgreichen Wiederverbindung 49 | boolean radio = false; // Flag zum Signalisieren der Radiowiedergabe 50 | boolean clockmode = true; // Flag zum Signalisieren, dass die Uhrzeit auf dem Bildschirm angezeigt wird 51 | boolean configpage = false; // Flag zum Signalisieren, dass die Konfigurationsseite angezeigt wird 52 | boolean radiopage = false; // Flag zum Signalisieren, dass die Radioauswahlseite angezeigt wird 53 | boolean alarmpage = false; // Flag zum Signalisieren, dass die Alarm-Einstellseite angezeigt wird 54 | unsigned long lastUpdate = 0; // Variable, um die letzte Anzeigeaktualisierung zu verfolgen 55 | uint16_t lastLedb = 0; // Globale Variable, um den zuletzt eingestellten Helligkeitswert zu speichern 56 | // Definitionen für die Textausrichtung 57 | #define ALIGNLEFT 0 // Textausrichtung: linksbündig 58 | #define ALIGNCENTER 1 // Textausrichtung: zentriert 59 | #define ALIGNRIGHT 2 // Textausrichtung: rechtsbündig 60 | 61 | // Definitionen für Schriftarten 62 | #define FNT9 &AT_Standard9pt7b // Schriftart 9pt 63 | #define FNT12 &AT_Bold12pt7b // Schriftart 12pt 64 | #define LS 23 // Zeilenabstand 65 | 66 | // WLAN-Konfiguration 67 | #define NETWORK_NAME "radioweckerlanname" // Definiert den Hostnamen 68 | #define AP_NAME "radioweckerconf" // Definiert den SSID-Namen des Soft-AP 69 | 70 | // Zeitzonen-Definition für Mitteleuropa (Deutschland, Frankreich, Italien, Spanien, etc.) 71 | #define TIME_ZONE "CET-1CEST,M3.5.0/02,M10.5.0/03" // Zeitzone für Mitteleuropa mit Sommerzeitregelung 72 | 73 | // OTA-Konfiguration 74 | #define OTA_HOSTNAME "radiowecker" // Definiert den Hostnamen für OTA Update 75 | #define OTA_PASSWORD "weckerupdate" // Definiert das Passwort für OTA Update 76 | //############## WETTER ############################################################## 77 | // Globale Variable, um den Zeitpunkt des letzten Wetterupdates zu speichern 78 | unsigned long lastWeatherUpdate = 0; 79 | const unsigned long weatherUpdateInterval = 60000; // 60 Sekunden 80 | // Definiere Latitude, Longitude und Zeitzone 81 | float LATITUDE = 52.520645; 82 | float LONGITUDE = 13.409779; 83 | String TIME_ZONE_IANA = "Europe/Berlin"; // Zeitzone dynamisch setzen -------------------------------------------------------------------------------- /radiowecker/00_texte.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXTE_H 2 | #define TEXTE_H 3 | 4 | #define TXT_DISCONNECT "Disconnect" 5 | #define TXT_SOFT_AP_DISCONNECT "Soft AP disconnect" 6 | #define TXT_SET_WLAN_MODE "Set WLAN Mode" 7 | #define TXT_CONNECTING_TO "Verbindung zu " 8 | #define TXT_CONNECTING_ESTABLISH " herstellen" 9 | #define TXT_NO_CONNECTION "Keine Verbindung! \nStarte Access-Point." 10 | #define TXT_IP_ADDRESS "IP-Adresse = " 11 | 12 | #define TXT_RECONNECTED "Reconnected" 13 | #define TXT_NOT_CONNECTED "Nicht verbunden" 14 | #define TXT_CONNECT_TO_AP "Verbinde dich mit SSID " 15 | #define TXT_CONFIG_IP "Einstellung auf IP: " 16 | 17 | #define TXT_OK "OK" 18 | 19 | //day and month names 20 | const char* const PROGMEM days[] = { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" }; 21 | const char* const PROGMEM days_short[] = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" }; 22 | const char* PROGMEM months[] = { "Jan.", "Feb.", "März", "April", "Mai", "Juni", "Juli", "Aug.", "Sept.", "Okt.", "Nov.", "Dez." }; 23 | 24 | #define TXT_NOW "Jetzt" 25 | #define TXT_TODAY "Heute" 26 | #define TXT_TOMMORROW "Morgen" 27 | 28 | #define TXT_TEMP "Temp:" 29 | #define TXT_FEELS "wie:" 30 | #define TXT_MIN "Min" 31 | #define TXT_MAX "Max" 32 | #endif // TEXTE_H -------------------------------------------------------------------------------- /radiowecker/audio.ino: -------------------------------------------------------------------------------- 1 | // Puffergröße für das Stream-Buffern 2 | const int preallocateBufferSize = 82 * 1024; // Größe des vorab zugewiesenen Puffers in Bytes 3 | const int preallocateCodecSize = 29192; // Maximal benötigter Speicher für den MP3-Codec in Bytes 4 | 5 | // Zeiger auf vorab zugewiesenen Speicher 6 | void *preallocateBuffer = NULL; // Zeiger auf den vorab zugewiesenen Puffer für die Daten 7 | void *preallocateCodec = NULL; // Zeiger auf den vorab zugewiesenen Puffer für den Codec 8 | 9 | // Instanzen für Audio-Komponenten 10 | AudioGenerator *decoder = NULL; // MP3-Decoder 11 | AudioFileSourceICYStream *file = NULL; // Eingabemodul für ICY-Streams aus dem Web 12 | AudioFileSourceBuffer *buff = NULL; // Puffer für den Eingabestream 13 | AudioOutputI2S *out; // Ausgabemodul zum Erzeugen von I2S-Signalen 14 | 15 | // Funktion für die gesamte erforderliche Einrichtung 16 | void setup_audio() { 17 | // Speicher für Decoder und Stream reservieren 18 | preallocateBuffer = malloc(preallocateBufferSize); // Speicher für den Stream-Dateipuffer anfordern 19 | preallocateCodec = malloc(preallocateCodecSize); // Speicher für den Decoder-Puffer anfordern 20 | delay(1000); // Warte 1 Sekunde, um sicherzustellen, dass der Speicher zugewiesen wurde 21 | 22 | // Überprüfen, ob der Speicher erfolgreich zugewiesen wurde 23 | if (!preallocateBuffer || !preallocateCodec) { 24 | Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize + preallocateCodecSize); 25 | while (1) { 26 | yield(); // Endlosschleife zur Behebung des Fehlers 27 | } 28 | } 29 | 30 | // I2S-Ausgabe erstellen, um sie mit dem Decoder zu verwenden 31 | out = new AudioOutputI2S(); // Neues AudioOutputI2S-Objekt erstellen 32 | out->SetPinout(BCLK, LRCLK, DOUT); // Pin-Konfiguration für I2S-Ausgabe festlegen 33 | } 34 | 35 | // Diese Funktion überprüft, ob der Decoder läuft 36 | void audio_loop() { 37 | // Überprüfen, ob der Decoder läuft 38 | if (decoder->isRunning()) { 39 | // Wenn der Decoder läuft, überprüfen, ob der Loop noch läuft 40 | if (!decoder->loop()) { 41 | // Wenn der Loop nicht mehr läuft, stoppen Sie den Decoder 42 | decoder->stop(); 43 | } 44 | } else { 45 | // Der Decoder hat gestoppt, was auf einen Fehler hindeutet 46 | Serial.printf("MP3 done\n"); 47 | // Um zu vermeiden, dass das gleiche Problem nach einem Neustart erneut auftritt, 48 | // wird die Station auf den ersten Eintrag in der Liste gesetzt. 49 | // Der erste Eintrag sollte eine stabile, funktionierende URL sein. 50 | // Verwenden Sie diesen ersten Eintrag nicht für Experimente. 51 | pref.putUShort("station", 0); 52 | 53 | // Warten Sie 10 Sekunden, bevor Sie das ESP neu starten 54 | delay(10000); 55 | 56 | // Neustart des ESP 57 | ESP.restart(); 58 | } 59 | } 60 | 61 | // Callback-Funktion, die aufgerufen wird, wenn Metadaten im Eingabestream gefunden werden 62 | void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string) { 63 | // Sicherstellen, dass die Zeiger gültig sind 64 | if (type == nullptr || string == nullptr) { 65 | Serial.println("Error: Null pointer encountered in MDCallback."); 66 | return; 67 | } 68 | 69 | // Hinweis: Der Typ und der String können im PROGMEM sein, daher Kopie ins RAM für printf 70 | char s1[32], s2[64]; 71 | strncpy_P(s1, type, sizeof(s1) - 1); 72 | s1[sizeof(s1) - 1] = 0; 73 | strncpy_P(s2, string, sizeof(s2) - 1); 74 | s2[sizeof(s2) - 1] = 0; 75 | 76 | // Verarbeiten von Metadaten-Typ "Title" 77 | if (strstr_P(s1, PSTR("Title"))) { 78 | strncpy(title, s2, sizeof(title)); 79 | title[sizeof(title) - 1] = 0; 80 | Serial.printf("Title: %s\n", title); 81 | // Zeige die Nachricht auf dem Display an 82 | newTitle = true; 83 | } else { 84 | // Nur den Typ und den String für generische Metadaten anzeigen 85 | Serial.printf("METADATA '%s' = '%s'\n", s1, s2); 86 | } 87 | 88 | // Serial.flush(); // Optional: Zum Flushing der Serial-Ausgabe, falls notwendig 89 | } 90 | 91 | // Stoppt das Abspielen des Eingabestreams, gibt den Speicher frei und löscht die Instanzen 92 | void stopPlaying() { 93 | if (decoder) { 94 | decoder->stop(); // Stoppt das Abspielen 95 | delete decoder; // Gibt den Decoder und seinen Speicher frei 96 | decoder = NULL; // Setzt den Zeiger auf NULL, um darauf hinzuweisen, dass der Speicher freigegeben wurde 97 | } 98 | 99 | if (buff) { 100 | buff->close(); // Schließt den Puffer 101 | delete buff; // Gibt den Puffer und seinen Speicher frei 102 | buff = NULL; // Setzt den Zeiger auf NULL 103 | } 104 | 105 | if (file) { // Und schließlich für den Stream 106 | file->close(); // Schließt den Stream 107 | delete file; // Gibt den Stream und seinen Speicher frei 108 | file = NULL; // Setzt den Zeiger auf NULL 109 | } 110 | } 111 | 112 | // Startet das Abspielen eines Streams von der angegebenen Station 113 | bool startUrl(String url) { 114 | bool ret = true; 115 | stopPlaying(); // Zuerst bestehende Streams schließen 116 | 117 | // Öffne die Eingabedatei für die ausgewählte URL 118 | Serial.printf("Active station %s\n", url.c_str()); 119 | file = new AudioFileSourceICYStream(); 120 | ret = file->open(url.c_str()); 121 | 122 | if (ret) { 123 | // Registriere Callback für Metadaten 124 | file->RegisterMetadataCB(MDCallback, NULL); 125 | 126 | // Erstelle einen neuen Puffer, der den vorab zugewiesenen Speicher verwendet 127 | buff = new AudioFileSourceBuffer(file, preallocateBuffer, preallocateBufferSize); 128 | Serial.printf_P(PSTR("sourcebuffer created - Free mem=%d\n"), ESP.getFreeHeap()); 129 | 130 | // Erstelle und starte einen neuen Decoder 131 | decoder = (AudioGenerator *)new AudioGeneratorMP3(preallocateCodec, preallocateCodecSize); 132 | Serial.printf_P(PSTR("created decoder\n")); 133 | Serial.printf_P("Decoder start...\n"); 134 | delay(1000); 135 | decoder->begin(buff, out); 136 | } else { 137 | delete file; // Wenn kein Erfolg, lösche die Datei 138 | file = NULL; 139 | } 140 | 141 | return ret; 142 | } 143 | 144 | // Ändert die Lautstärke auf den aktuellen Gain-Wert 145 | void setGain(float gain) { 146 | float v = gain / 100 * 0.5; // Berechnet die Lautstärke als Prozentsatz von 0,5 147 | out->SetGain(v); // Setzt die Lautstärke 148 | Serial.printf("New volume = %4.2f\n", v); // Gibt den neuen Lautstärkewert aus 149 | } 150 | -------------------------------------------------------------------------------- /radiowecker/knoepfe.h: -------------------------------------------------------------------------------- 1 | const unsigned char knopf_sym PROGMEM [9][512] = { 2 | {// [0] 'power_64', 64x64px 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5 | 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 7 | 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 8 | 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x0f, 0xf0, 0x07, 0x80, 0x00, 9 | 0x00, 0x03, 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x00, 0x00, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x00, 10 | 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x1f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf8, 0x00, 11 | 0x00, 0x3f, 0xf0, 0x0f, 0xf0, 0x0f, 0xfc, 0x00, 0x00, 0x7f, 0xe0, 0x0f, 0xf0, 0x07, 0xfe, 0x00, 12 | 0x00, 0x7f, 0xc0, 0x0f, 0xf0, 0x03, 0xfe, 0x00, 0x00, 0xff, 0x80, 0x0f, 0xf0, 0x01, 0xff, 0x00, 13 | 0x01, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0xff, 0x80, 0x01, 0xff, 0x00, 0x0f, 0xf0, 0x00, 0x7f, 0x80, 14 | 0x01, 0xfe, 0x00, 0x0f, 0xf0, 0x00, 0x7f, 0x80, 0x03, 0xfc, 0x00, 0x0f, 0xf0, 0x00, 0x3f, 0xc0, 15 | 0x03, 0xfc, 0x00, 0x0f, 0xf0, 0x00, 0x3f, 0xc0, 0x03, 0xf8, 0x00, 0x0f, 0xf0, 0x00, 0x1f, 0xc0, 16 | 0x07, 0xf8, 0x00, 0x0f, 0xf0, 0x00, 0x1f, 0xe0, 0x07, 0xf8, 0x00, 0x0f, 0xf0, 0x00, 0x1f, 0xe0, 17 | 0x07, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xe0, 0x07, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xe0, 18 | 0x07, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xe0, 0x07, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xe0, 19 | 0x07, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xe0, 20 | 0x07, 0xf0, 0x00, 0x07, 0xe0, 0x00, 0x0f, 0xe0, 0x07, 0xf0, 0x00, 0x07, 0xc0, 0x00, 0x0f, 0xe0, 21 | 0x07, 0xf0, 0x00, 0x00, 0x80, 0x00, 0x0f, 0xe0, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 22 | 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 23 | 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 24 | 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 25 | 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0x00, 26 | 0x00, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x03, 0xfe, 0x00, 27 | 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x1f, 0xfc, 0x00, 28 | 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x01, 0xff, 0xf0, 0x00, 29 | 0x00, 0x07, 0xff, 0xf0, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 30 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 31 | 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 32 | 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 33 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 35 | },{// [1] 'bed_64', 64x64px 36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 44 | 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 46 | 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x7c, 0x01, 0xff, 0xff, 0xfc, 0x00, 47 | 0x0f, 0xc1, 0xff, 0x03, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xc3, 0xff, 0x87, 0xff, 0xff, 0xff, 0x80, 48 | 0x0f, 0xc3, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xc7, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xe0, 49 | 0x0f, 0xc7, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xc7, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xe0, 50 | 0x0f, 0xc7, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xc7, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xf0, 51 | 0x0f, 0xc7, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xc3, 0xff, 0x87, 0xff, 0xff, 0xff, 0xf0, 52 | 0x0f, 0xc3, 0xff, 0x87, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xc0, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xf0, 53 | 0x0f, 0xc0, 0x38, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 54 | 0x0f, 0xc0, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 55 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 56 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 57 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 58 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 59 | 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 60 | 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 61 | 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 68 | },{// [2] 'bell_64', 64x64px 69 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 71 | 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 72 | 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 75 | 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 76 | 0x00, 0x00, 0x3f, 0xf8, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x03, 0xfc, 0x00, 0x00, 77 | 0x00, 0x00, 0x7f, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x7f, 0x00, 0x00, 78 | 0x00, 0x00, 0xfc, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x1f, 0x80, 0x00, 79 | 0x00, 0x01, 0xf8, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x0f, 0x80, 0x00, 80 | 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 81 | 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 82 | 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 83 | 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 84 | 0x00, 0x03, 0xe0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0xc0, 0x00, 85 | 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0xc0, 0x00, 86 | 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 87 | 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x03, 0xe0, 0x00, 88 | 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x03, 0xf0, 0x00, 89 | 0x00, 0x1f, 0x80, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x01, 0xfc, 0x00, 90 | 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 91 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 92 | 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 93 | 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 95 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 96 | 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 97 | 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 98 | 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 99 | 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 100 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 101 | },{// [3] 'bell_slash_64', 64x64px 102 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 103 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 104 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 105 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 106 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 107 | 0x07, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 108 | 0x07, 0xe0, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 109 | 0x03, 0xf8, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 110 | 0x00, 0x7f, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x81, 0xff, 0xff, 0x80, 0x00, 0x00, 111 | 0x00, 0x1f, 0xc3, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x07, 0xe7, 0xff, 0xff, 0xe0, 0x00, 0x00, 112 | 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 113 | 0x00, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x00, 114 | 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0x00, 115 | 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00, 116 | 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7f, 0xff, 0xfc, 0x00, 0x00, 117 | 0x00, 0x00, 0x30, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0f, 0xff, 0xfc, 0x00, 0x00, 118 | 0x00, 0x00, 0x3e, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x03, 0xff, 0xfc, 0x00, 0x00, 119 | 0x00, 0x00, 0x7f, 0x80, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x7f, 0xfe, 0x00, 0x00, 120 | 0x00, 0x00, 0xff, 0xf0, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x1f, 0xff, 0x80, 0x00, 121 | 0x00, 0x01, 0xff, 0xfc, 0x07, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0x03, 0xff, 0xc0, 0x00, 122 | 0x00, 0x07, 0xff, 0xff, 0x81, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x7f, 0xe0, 0x00, 123 | 0x00, 0x07, 0xff, 0xff, 0xe0, 0x3f, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x1f, 0xe0, 0x00, 124 | 0x00, 0x07, 0xff, 0xff, 0xfc, 0x0f, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xfe, 0x03, 0xf8, 0x00, 125 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 126 | 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x1f, 0xc0, 127 | 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x07, 0xe0, 128 | 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0xe0, 129 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 130 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 131 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 134 | },{// [4] 'radio_64', 64x64px 135 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 137 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 138 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xe0, 139 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 140 | 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 141 | 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf8, 0x00, 0x00, 142 | 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 143 | 0x00, 0x01, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 144 | 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 145 | 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 146 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 147 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 148 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 149 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 150 | 0x0f, 0xfe, 0x00, 0x7f, 0xff, 0xe3, 0xff, 0xf0, 0x0f, 0xf8, 0x00, 0x1f, 0xff, 0x00, 0xff, 0xf0, 151 | 0x0f, 0xf8, 0x00, 0x1f, 0xfc, 0x00, 0x3f, 0xf0, 0x0f, 0xfe, 0x00, 0x7f, 0xf8, 0x00, 0x1f, 0xf0, 152 | 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 153 | 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x0f, 0xf8, 0x00, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 154 | 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x07, 0xf0, 0x0f, 0xf0, 0x00, 0x0f, 0xf0, 0x00, 0x07, 0xf0, 155 | 0x0f, 0xf8, 0x00, 0x1f, 0xf0, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 156 | 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xf0, 157 | 0x0f, 0xfc, 0x00, 0x3f, 0xfc, 0x00, 0x3f, 0xf0, 0x0f, 0xf8, 0x00, 0x1f, 0xfe, 0x00, 0x7f, 0xf0, 158 | 0x0f, 0xf8, 0x00, 0x1f, 0xff, 0x00, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 159 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 160 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 161 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 162 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 163 | 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 164 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 165 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 167 | },{// [5] 'house_64', 64x64px 168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 170 | 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 171 | 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 172 | 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 173 | 0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 174 | 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 175 | 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 176 | 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 177 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 178 | 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 179 | 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 180 | 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 181 | 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 182 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 183 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 184 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 185 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 186 | 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 187 | 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 188 | 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 189 | 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x0f, 0xff, 0xfc, 0x00, 190 | 0x00, 0x3f, 0xff, 0xe0, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x07, 0xff, 0xfc, 0x00, 191 | 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 192 | 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 193 | 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 194 | 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 195 | 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 196 | 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x03, 0xff, 0xfc, 0x00, 197 | 0x00, 0x1f, 0xff, 0xc0, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x01, 0xff, 0xf8, 0x00, 198 | 0x00, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 200 | },{// [6] 'gear_64', 64x64px 201 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 202 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 203 | 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 204 | 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 205 | 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 206 | 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 207 | 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3e, 0x0f, 0xff, 0xff, 0xf0, 0x7e, 0x00, 208 | 0x00, 0x7f, 0xdf, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 209 | 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 210 | 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 211 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 212 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xe0, 213 | 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xc0, 214 | 0x01, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xfe, 0x00, 215 | 0x00, 0x7f, 0xff, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xfc, 0x00, 216 | 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xfc, 0x00, 217 | 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xfc, 0x00, 218 | 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0xff, 0xfe, 0x00, 219 | 0x00, 0x7f, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0x80, 220 | 0x03, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xe0, 221 | 0x07, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 222 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 223 | 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 224 | 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 225 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 226 | 0x00, 0x7f, 0x0f, 0xff, 0xff, 0xf0, 0x7c, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 227 | 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 228 | 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 229 | 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 230 | 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 231 | 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 233 | },{// [7] 'clock_64', 64x64px 234 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 235 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 236 | 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 237 | 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 238 | 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xe0, 0x0f, 0xff, 0xc0, 0x00, 239 | 0x00, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x3f, 0xf8, 0x00, 240 | 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x07, 0xfc, 0x00, 241 | 0x00, 0x7f, 0x80, 0x03, 0xc0, 0x03, 0xfe, 0x00, 0x00, 0xff, 0x00, 0x07, 0xe0, 0x00, 0xff, 0x00, 242 | 0x01, 0xfe, 0x00, 0x07, 0xe0, 0x00, 0x7f, 0x80, 0x01, 0xfc, 0x00, 0x07, 0xe0, 0x00, 0x7f, 0x80, 243 | 0x03, 0xf8, 0x00, 0x07, 0xe0, 0x00, 0x3f, 0xc0, 0x03, 0xf8, 0x00, 0x07, 0xe0, 0x00, 0x1f, 0xc0, 244 | 0x07, 0xf0, 0x00, 0x07, 0xe0, 0x00, 0x0f, 0xe0, 0x07, 0xf0, 0x00, 0x07, 0xe0, 0x00, 0x0f, 0xe0, 245 | 0x07, 0xe0, 0x00, 0x07, 0xe0, 0x00, 0x07, 0xf0, 0x0f, 0xe0, 0x00, 0x07, 0xe0, 0x00, 0x07, 0xf0, 246 | 0x0f, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x03, 0xf0, 0x0f, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x03, 0xf0, 247 | 0x1f, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x03, 0xf8, 248 | 0x1f, 0x80, 0x00, 0x07, 0xe0, 0x00, 0x01, 0xf8, 0x1f, 0x80, 0x00, 0x07, 0xe0, 0x00, 0x01, 0xf8, 249 | 0x1f, 0x80, 0x00, 0x07, 0xe0, 0x00, 0x01, 0xf8, 0x1f, 0x80, 0x00, 0x07, 0xf8, 0x00, 0x01, 0xf8, 250 | 0x1f, 0x80, 0x00, 0x07, 0xfc, 0x00, 0x01, 0xf8, 0x1f, 0x80, 0x00, 0x07, 0xff, 0x00, 0x01, 0xf8, 251 | 0x1f, 0x80, 0x00, 0x03, 0xff, 0x80, 0x01, 0xf8, 0x1f, 0x80, 0x00, 0x01, 0xff, 0xe0, 0x01, 0xf8, 252 | 0x1f, 0x80, 0x00, 0x00, 0x7f, 0xf0, 0x01, 0xf8, 0x1f, 0xc0, 0x00, 0x00, 0x3f, 0xf8, 0x03, 0xf8, 253 | 0x1f, 0xc0, 0x00, 0x00, 0x0f, 0xfc, 0x03, 0xf0, 0x0f, 0xc0, 0x00, 0x00, 0x07, 0xfc, 0x03, 0xf0, 254 | 0x0f, 0xe0, 0x00, 0x00, 0x01, 0xfc, 0x07, 0xf0, 0x0f, 0xe0, 0x00, 0x00, 0x00, 0xf8, 0x07, 0xf0, 255 | 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe0, 256 | 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 257 | 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 258 | 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x01, 0xfe, 0x00, 259 | 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x0f, 0xfc, 0x00, 260 | 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0xff, 0xf0, 0x00, 261 | 0x00, 0x07, 0xff, 0xe0, 0x0f, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 262 | 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 263 | 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 264 | 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 265 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 266 | },{// [8] 'floppy_disk_64', 64x64px 267 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 268 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 269 | 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 270 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 271 | 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 272 | 0x1f, 0xc7, 0xf0, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x1f, 0xc7, 0xf0, 0x00, 0x03, 0xff, 0xfe, 0x00, 273 | 0x1f, 0xc7, 0xf0, 0x00, 0x03, 0xfb, 0xff, 0x00, 0x1f, 0xc7, 0xf0, 0x00, 0x03, 0xf9, 0xff, 0x80, 274 | 0x1f, 0xc7, 0xf0, 0x00, 0x03, 0xf8, 0xff, 0xc0, 0x1f, 0xc7, 0xf0, 0x00, 0x03, 0xf8, 0x7f, 0xe0, 275 | 0x1f, 0xc7, 0xf0, 0x00, 0x03, 0xf8, 0x3f, 0xf0, 0x1f, 0xc7, 0xf0, 0x00, 0x03, 0xf8, 0x1f, 0xf0, 276 | 0x1f, 0xc7, 0xf0, 0x00, 0x03, 0xf8, 0x0f, 0xf8, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xf8, 277 | 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xf8, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xf8, 278 | 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xf8, 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xf8, 279 | 0x1f, 0xc7, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xf8, 0x1f, 0xc3, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xf8, 280 | 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 281 | 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 282 | 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 283 | 0x1f, 0xc0, 0x00, 0x0f, 0xf0, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x1f, 0xf8, 0x00, 0x03, 0xf8, 284 | 0x1f, 0xc0, 0x00, 0x3f, 0xfc, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x7f, 0xfe, 0x00, 0x03, 0xf8, 285 | 0x1f, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x03, 0xf8, 286 | 0x1f, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xf8, 287 | 0x1f, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xf8, 0x1f, 0xc0, 0x01, 0xff, 0xff, 0x80, 0x03, 0xf8, 288 | 0x1f, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0xff, 0xff, 0x00, 0x03, 0xf8, 289 | 0x1f, 0xc0, 0x00, 0xff, 0xfe, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x7f, 0xfe, 0x00, 0x03, 0xf8, 290 | 0x1f, 0xc0, 0x00, 0x3f, 0xfc, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x1f, 0xf8, 0x00, 0x03, 0xf8, 291 | 0x1f, 0xc0, 0x00, 0x07, 0xc0, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 292 | 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 293 | 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 294 | 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 295 | 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 296 | 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 297 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 298 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 299 | } 300 | }; 301 | -------------------------------------------------------------------------------- /radiowecker/num_64_44.h: -------------------------------------------------------------------------------- 1 | const unsigned char num_64_44 PROGMEM [10][360] = { 2 | {// '1_64_44, 64x44px 3 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 4 | 0x80, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 5 | 0x80, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x01, 6 | 0x80, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x01, 7 | 0x80, 0x00, 0x03, 0xff, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x01, 8 | 0x80, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x07, 0xe7, 0xe0, 0x00, 0x00, 0x01, 9 | 0x80, 0x00, 0x07, 0xc7, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 10 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 11 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 12 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 13 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 14 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 15 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 16 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 17 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 18 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 19 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 20 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 21 | 0x80, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x01, 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 22 | 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 23 | 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 24 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 25 | },{// '2_64_44, 64x44px 26 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 27 | 0x80, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x01, 28 | 0x80, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x01, 0x80, 0x00, 0x03, 0xff, 0xfe, 0x00, 0x00, 0x01, 29 | 0x80, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x01, 30 | 0x80, 0x00, 0x1f, 0xe0, 0x7f, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x3f, 0xc0, 0x1f, 0xc0, 0x00, 0x01, 31 | 0x80, 0x00, 0x3f, 0x80, 0x0f, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x0f, 0xe0, 0x00, 0x01, 32 | 0x80, 0x00, 0x3e, 0x00, 0x07, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x01, 33 | 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x01, 34 | 0x80, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x01, 35 | 0x80, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x01, 36 | 0x80, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x01, 37 | 0x80, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x01, 38 | 0x80, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x01, 39 | 0x80, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x01, 40 | 0x80, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x01, 41 | 0x80, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 42 | 0x80, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x01, 43 | 0x80, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x01, 44 | 0x80, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x01, 45 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x01, 46 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x01, 47 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 48 | },{// '3_64_44, 64x44px 49 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 50 | 0x80, 0x00, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x01, 51 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x00, 0x01, 52 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x01, 53 | 0x80, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x01, 54 | 0x80, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x01, 55 | 0x80, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x01, 56 | 0x80, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x01, 57 | 0x80, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x01, 58 | 0x80, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x01, 0x80, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x01, 59 | 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x01, 60 | 0x80, 0x00, 0x01, 0xff, 0xff, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x01, 61 | 0x80, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x01, 62 | 0x80, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 63 | 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 64 | 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 65 | 0x80, 0x00, 0x1c, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3e, 0x00, 0x01, 0xfc, 0x00, 0x01, 66 | 0x80, 0x00, 0x3f, 0x00, 0x03, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x80, 0x07, 0xf8, 0x00, 0x01, 67 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x01, 68 | 0x80, 0x00, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x01, 69 | 0x80, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x01, 70 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 71 | },{// '4_64_44, 64x44px 72 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 73 | 0x80, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 74 | 0x80, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, 75 | 0x80, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01, 76 | 0x80, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x01, 77 | 0x80, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0xf8, 0x01, 0xe0, 0x00, 0x01, 78 | 0x80, 0x00, 0x03, 0xf8, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x03, 0xf0, 0x03, 0xe0, 0x00, 0x01, 79 | 0x80, 0x00, 0x07, 0xf0, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x07, 0xe0, 0x03, 0xe0, 0x00, 0x01, 80 | 0x80, 0x00, 0x0f, 0xe0, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xc0, 0x03, 0xe0, 0x00, 0x01, 81 | 0x80, 0x00, 0x0f, 0xc0, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x1f, 0x80, 0x03, 0xe0, 0x00, 0x01, 82 | 0x80, 0x00, 0x1f, 0x80, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x03, 0xe0, 0x00, 0x01, 83 | 0x80, 0x00, 0x3f, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x7f, 0x00, 0x03, 0xe0, 0x00, 0x01, 84 | 0x80, 0x00, 0x7e, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0xfe, 0x00, 0x03, 0xe0, 0x00, 0x01, 85 | 0x80, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x01, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 86 | 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 87 | 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 88 | 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 89 | 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 90 | 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 91 | 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 92 | 0x80, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x01, 93 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 94 | },{// '5_64_44', 64x44px 95 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 96 | 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 97 | 0x80, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x01, 98 | 0x80, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x01, 99 | 0x80, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x01, 100 | 0x80, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x01, 101 | 0x80, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x01, 102 | 0x80, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x01, 103 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x01, 104 | 0x80, 0x00, 0x3f, 0xff, 0xfc, 0x00, 0x00, 0x01, 0x80, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x01, 105 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x00, 0x01, 106 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x01, 107 | 0x80, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x01, 108 | 0x80, 0x00, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 109 | 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 110 | 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x01, 111 | 0x80, 0x00, 0x1c, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3e, 0x00, 0x01, 0xfc, 0x00, 0x01, 112 | 0x80, 0x00, 0x3f, 0x00, 0x03, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x80, 0x07, 0xf8, 0x00, 0x01, 113 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x01, 114 | 0x80, 0x00, 0x1f, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x01, 115 | 0x80, 0x00, 0x03, 0xff, 0xff, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x01, 116 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 117 | },{// '6_64_44', 64x44px 118 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 119 | 0x80, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 120 | 0x80, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x01, 121 | 0x80, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x01, 122 | 0x80, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x01, 123 | 0x80, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x01, 124 | 0x80, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x01, 125 | 0x80, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x00, 0x01, 126 | 0x80, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 127 | 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xfc, 0x3f, 0xf0, 0x00, 0x01, 128 | 0x80, 0x00, 0x0f, 0xe0, 0x0f, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xc0, 0x03, 0xf8, 0x00, 0x01, 129 | 0x80, 0x00, 0x1f, 0x80, 0x01, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x80, 0x01, 0xfc, 0x00, 0x01, 130 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 131 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0x7c, 0x00, 0x01, 132 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 133 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x01, 0xfc, 0x00, 0x01, 134 | 0x80, 0x00, 0x1f, 0x80, 0x01, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xc0, 0x03, 0xf8, 0x00, 0x01, 135 | 0x80, 0x00, 0x1f, 0xe0, 0x07, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xf0, 0x1f, 0xf0, 0x00, 0x01, 136 | 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x01, 137 | 0x80, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 138 | 0x80, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x01, 139 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 140 | },{// '7_64_44', 64x44px 141 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 142 | 0x80, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x01, 143 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x01, 144 | 0x80, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0x01, 145 | 0x80, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x01, 146 | 0x80, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x01, 147 | 0x80, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x01, 148 | 0x80, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x01, 149 | 0x80, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x01, 150 | 0x80, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x01, 151 | 0x80, 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x01, 152 | 0x80, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x01, 153 | 0x80, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x01, 154 | 0x80, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x01, 155 | 0x80, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x01, 156 | 0x80, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x01, 157 | 0x80, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x01, 158 | 0x80, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x01, 159 | 0x80, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x01, 160 | 0x80, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x01, 161 | 0x80, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x01, 162 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 163 | },{// '8_64_44', 64x44px 164 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 165 | 0x80, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x01, 166 | 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 167 | 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 168 | 0x80, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xe0, 0x07, 0xf0, 0x00, 0x01, 169 | 0x80, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x1f, 0x80, 0x01, 0xf0, 0x00, 0x01, 170 | 0x80, 0x00, 0x1f, 0x80, 0x01, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x1f, 0x80, 0x01, 0xf8, 0x00, 0x01, 171 | 0x80, 0x00, 0x1f, 0x80, 0x01, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x0f, 0x80, 0x01, 0xf8, 0x00, 0x01, 172 | 0x80, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xe0, 0x07, 0xf0, 0x00, 0x01, 173 | 0x80, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 174 | 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 175 | 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x01, 176 | 0x80, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xe0, 0x07, 0xf8, 0x00, 0x01, 177 | 0x80, 0x00, 0x3f, 0x80, 0x01, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x80, 0x01, 0xfc, 0x00, 0x01, 178 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 179 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 180 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x80, 0x00, 0xfc, 0x00, 0x01, 181 | 0x80, 0x00, 0x3f, 0x80, 0x01, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xc0, 0x07, 0xf8, 0x00, 0x01, 182 | 0x80, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x01, 183 | 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 184 | 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 0x01, 185 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 186 | },{// '9_64_44', 64x44px 187 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 188 | 0x80, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x01, 189 | 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 0x80, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x01, 190 | 0x80, 0x00, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x01, 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 191 | 0x80, 0x00, 0x0f, 0xf8, 0x1f, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x1f, 0xe0, 0x07, 0xf8, 0x00, 0x01, 192 | 0x80, 0x00, 0x1f, 0xc0, 0x03, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x80, 0x01, 0xf8, 0x00, 0x01, 193 | 0x80, 0x00, 0x3f, 0x80, 0x01, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 194 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 195 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 196 | 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0x00, 0x01, 197 | 0x80, 0x00, 0x3f, 0x80, 0x01, 0xfc, 0x00, 0x01, 0x80, 0x00, 0x1f, 0x80, 0x01, 0xf8, 0x00, 0x01, 198 | 0x80, 0x00, 0x1f, 0xc0, 0x03, 0xf8, 0x00, 0x01, 0x80, 0x00, 0x0f, 0xe0, 0x07, 0xf0, 0x00, 0x01, 199 | 0x80, 0x00, 0x0f, 0xfc, 0x3f, 0xf0, 0x00, 0x01, 0x80, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x01, 200 | 0x80, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x01, 201 | 0x80, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x01, 0x80, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x01, 202 | 0x80, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x01, 203 | 0x80, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x01, 204 | 0x80, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x01, 205 | 0x80, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x01, 206 | 0x80, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x01, 207 | 0x80, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01, 208 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 209 | },{// '10_64_44', 64x44px 210 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 211 | 0x80, 0x00, 0x38, 0x00, 0x00, 0x7f, 0x00, 0x01, 0x80, 0x00, 0xfc, 0x00, 0x03, 0xff, 0xe0, 0x01, 212 | 0x80, 0x03, 0xfc, 0x00, 0x0f, 0xff, 0xf8, 0x01, 0x80, 0x07, 0xfc, 0x00, 0x1f, 0xff, 0xfc, 0x01, 213 | 0x80, 0x1f, 0xfc, 0x00, 0x3f, 0xff, 0xfe, 0x01, 0x80, 0x3f, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0x01, 214 | 0x80, 0x7f, 0xfc, 0x00, 0xff, 0x80, 0xff, 0x81, 0x80, 0xff, 0xfc, 0x00, 0xff, 0x00, 0x7f, 0x81, 215 | 0x80, 0xff, 0xfc, 0x01, 0xfc, 0x00, 0x1f, 0xc1, 0x80, 0xfc, 0xfc, 0x01, 0xfc, 0x00, 0x1f, 0xc1, 216 | 0x80, 0x78, 0xfc, 0x01, 0xf8, 0x00, 0x0f, 0xc1, 0x80, 0x00, 0xfc, 0x03, 0xf8, 0x00, 0x0f, 0xc1, 217 | 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 218 | 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 219 | 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 220 | 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 221 | 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 222 | 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 223 | 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 224 | 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 0x80, 0x00, 0xfc, 0x03, 0xf0, 0x00, 0x07, 0xe1, 225 | 0x80, 0x00, 0xfc, 0x01, 0xf8, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xfc, 0x01, 0xf8, 0x00, 0x0f, 0xc1, 226 | 0x80, 0x00, 0xfc, 0x01, 0xfc, 0x00, 0x1f, 0xc1, 0x80, 0x00, 0xfc, 0x01, 0xfc, 0x00, 0x1f, 0xc1, 227 | 0x80, 0x00, 0xfc, 0x00, 0xff, 0x00, 0x7f, 0x81, 0x80, 0x00, 0xfc, 0x00, 0xff, 0x80, 0xff, 0x81, 228 | 0x80, 0x3f, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xfe, 0x01, 229 | 0x80, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xfc, 0x01, 0x80, 0xff, 0xff, 0xfe, 0x0f, 0xff, 0xf8, 0x01, 230 | 0x80, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xe0, 0x01, 0x80, 0x7f, 0xff, 0xf8, 0x00, 0x7f, 0x00, 0x01, 231 | 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 232 | } 233 | }; 234 | -------------------------------------------------------------------------------- /radiowecker/ota.ino: -------------------------------------------------------------------------------- 1 | // Variable zur Verfolgung des Fortschritts der OTA-Aktualisierung 2 | uint32_t oldprc; 3 | 4 | // Funktion zur Vorbereitung der OTA-Aktualisierung 5 | void setup_ota() { 6 | // Setze den Hostnamen und das Passwort für OTA-Updates 7 | ArduinoOTA.setHostname(OTA_HOSTNAME); // Setzt den Hostnamen für OTA 8 | ArduinoOTA.setPassword(OTA_PASSWORD); // Setzt das Passwort für OTA 9 | 10 | // Registriere Callback-Routinen für OTA-Ereignisse 11 | ArduinoOTA.onStart(ota_onStart); // Callback, wenn die OTA-Aktualisierung beginnt 12 | ArduinoOTA.onEnd(ota_onEnd); // Callback, wenn die OTA-Aktualisierung endet 13 | ArduinoOTA.onProgress(ota_onProgress); // Callback zur Anzeige des Fortschritts 14 | ArduinoOTA.onError(ota_onError); // Callback bei einem Fehler während der OTA-Aktualisierung 15 | 16 | // Starte die OTA-Verarbeitung 17 | ArduinoOTA.begin(); // Beginnt die OTA-Aktualisierung 18 | } 19 | 20 | // Callback-Funktion, die aufgerufen wird, wenn die OTA-Aktualisierung beginnt 21 | void ota_onStart() { 22 | displayClear(); // Löscht das Display 23 | setBGLight(100); // Setzt die Hintergrundbeleuchtung auf 100% Helligkeit 24 | oldprc = 0; // Setzt den alten Fortschrittswert zurück 25 | String type; 26 | // Bestimme den Typ der Aktualisierung (Sketch oder Dateisystem) 27 | if (ArduinoOTA.getCommand() == U_FLASH) 28 | type = "sketch"; // Programm-Aktualisierung 29 | else // U_SPIFFS 30 | type = "filesystem"; // Dateisystem-Aktualisierung 31 | 32 | // Zeige eine Nachricht auf dem Display an, dass das Sketch aktualisiert wird 33 | displayMessage(5, 10, 310, 30, "Updating Sketch", ALIGNCENTER, true, ILI9341_YELLOW, ILI9341_BLACK, 1); 34 | showProgress(0); // Zeigt den Fortschritt (beginnend bei 0%) 35 | } 36 | 37 | // Callback-Funktion, die aufgerufen wird, wenn die OTA-Aktualisierung endet 38 | void ota_onEnd() { 39 | // Zeigt eine Nachricht auf dem Display an, dass die Aktualisierung abgeschlossen ist 40 | displayMessage(5, 120, 310, 30, "Done", ALIGNLEFT, true, ILI9341_GREEN, ILI9341_BLACK, 1); 41 | } 42 | 43 | // Callback-Funktion, die aufgerufen wird, um den Fortschritt der OTA-Aktualisierung anzuzeigen 44 | void ota_onProgress(unsigned int progress, unsigned int total) { 45 | uint32_t prc = progress / (total / 100); // Berechne den Fortschritt in Prozent 46 | char tmp[20]; 47 | // Wenn der Fortschritt gestiegen ist, aktualisiere die Fortschrittsanzeige 48 | if (prc > oldprc) { 49 | showProgress(prc); // Zeige den Fortschritt an 50 | oldprc = prc; // Speichere den aktuellen Fortschritt für die nächste Überprüfung 51 | } 52 | } 53 | 54 | // Callback-Funktion, die bei einem Fehler während der OTA-Aktualisierung aufgerufen wird 55 | void ota_onError(ota_error_t error) { 56 | char err[80]; 57 | // Formatierte Fehlermeldung 58 | sprintf(err, "Error[%u]: ", error); 59 | // Bestimme die spezifische Fehlermeldung basierend auf dem Fehlercode 60 | if (error == OTA_AUTH_ERROR) sprintf(err, "Error[%u]: Auth Failed", error); 61 | else if (error == OTA_BEGIN_ERROR) sprintf(err, "Error[%u] Begin Failed", error); 62 | else if (error == OTA_CONNECT_ERROR) sprintf(err, "Error[%u] Connect Failed", error); 63 | else if (error == OTA_RECEIVE_ERROR) sprintf(err, "Error[%u] Receive Failed", error); 64 | else if (error == OTA_END_ERROR) sprintf(err, "Error[%u] End Failed", error); 65 | 66 | // Zeige die Fehlermeldung auf dem Display an 67 | displayMessage(5, 200, 310, 30, err, ALIGNLEFT, false, ILI9341_RED); 68 | } -------------------------------------------------------------------------------- /radiowecker/radiowecker.ino: -------------------------------------------------------------------------------- 1 | #define RADIOVERSION "v4.0.2"; 2 | #include "00_librarys.h" //Lade alle benötigten Bibliotheken 3 | #include "00_pin_settings.h" //Einstellungen der genutzten Pins 4 | #include "00_settings.h" //einstellungen 5 | #include "00_texte.h" //Strings 6 | #include "weather.h" 7 | //predefined function from modul tft_display.ino 8 | void displayMessage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const char* text, uint8_t align = ALIGNLEFT, boolean big = false, uint16_t fc = ILI9341_WHITE, uint16_t bg = ILI9341_BLACK, uint8_t lines = 1); 9 | 10 | // Berechnet das Datum und die Uhrzeit für den nächsten erwarteten Alarm 11 | // Setzt `alarmtime` auf die Zeit des Tages und `alarmday` auf den Wochentag für den Alarm 12 | // oder auf 8, wenn kein Alarm vorhanden ist 13 | void findNextAlarm() { 14 | Serial.println("Search next alarm time"); 15 | int wd; // Variable für den aktuellen Wochentag 16 | uint8_t mask; // Maske zum Filtern von Wochentagen 17 | 18 | if (getLocalTime(&ti)) { // Hole das aktuelle Datum und die Uhrzeit 19 | wd = weekday; // Setze wd auf den aktuellen Wochentag 20 | alarmday = 8; // Setze alarmday auf 8, was bedeutet, dass kein Alarm vorhanden ist 21 | alarmtime = MINUTES_PER_DAY + 1; // Setze alarmtime auf einen Wert, der höher ist als der maximal mögliche Wert für Minuten pro Tag 22 | 23 | mask = 1 << wd; // Erstelle eine Maske für den aktuellen Wochentag 24 | 25 | // Überprüfe, ob die Alarmzeit 1 übereinstimmt und ob der Alarm vor der aktuellen Zeit liegt 26 | if (((alarmday1 & mask) != 0) && (alarm1 > minutes)) { 27 | alarmtime = alarm1; // Setze alarmtime auf alarm1 28 | alarmday = wd; // Setze alarmday auf den aktuellen Wochentag 29 | } 30 | 31 | // Überprüfe, ob die Alarmzeit 2 übereinstimmt und ob der Alarm vor alarm1 liegt 32 | if (((alarmday2 & mask) != 0) && (alarm2 > minutes) && (alarmtime > alarm2)) { 33 | alarmtime = alarm2; // Setze alarmtime auf alarm2 34 | alarmday = wd; // Setze alarmday auf den aktuellen Wochentag 35 | } 36 | 37 | // Wenn kein Alarm gefunden wurde, fahre fort mit der Suche nach dem nächsten Alarm in der kommenden Woche 38 | if (alarmday == 8) { // Wenn alarmday immer noch 8 ist (kein Alarm gefunden) 39 | do { 40 | wd++; // Gehe zum nächsten Wochentag 41 | if (wd > 7) wd = 0; // Wenn der Wochentag über 7 hinausgeht, setze ihn auf 0 (Sonntag) 42 | 43 | mask = 1 << wd; // Erstelle eine neue Maske für den aktuellen Wochentag 44 | 45 | // Überprüfe erneut Alarmzeit 1 46 | if ((alarmday1 & mask) != 0) { 47 | alarmtime = alarm1; // Setze alarmtime auf alarm1 48 | alarmday = wd; // Setze alarmday auf den aktuellen Wochentag 49 | } 50 | 51 | // Überprüfe erneut Alarmzeit 2 52 | if (((alarmday2 & mask) != 0) && (alarmtime > alarm2)) { 53 | alarmtime = alarm2; // Setze alarmtime auf alarm2 54 | alarmday = wd; // Setze alarmday auf den aktuellen Wochentag 55 | } 56 | 57 | } while ((alarmday == 8) && (wd != weekday)); // Wiederhole, bis ein gültiger Alarm gefunden wird oder eine Woche vorbei ist 58 | } 59 | Serial.printf("Next alarm %i on %i\n", alarmtime, alarmday); // Gib die nächste Alarmzeit und den Wochentag aus 60 | } 61 | } 62 | 63 | // Initialisierung des Systems 64 | void setup() { 65 | // Starte die serielle Kommunikation mit einer Baudrate von 115200 66 | Serial.begin(115200); 67 | Serial.println("Load preferences"); // Debug-Ausgabe: "Lade Einstellungen" 68 | 69 | title[0] = 0; // Setze das erste Zeichen des Titels auf 0 (leerer Titel) 70 | 71 | // Lade die gespeicherten Präferenzen aus dem EEPROM des ESP32 72 | // Die Präferenzen werden in zwei Themen gespeichert: "radio" und "senderliste" 73 | // Beide Themen werden hier geladen 74 | pref.begin("radio", false); 75 | sender.begin("senderlist", false); 76 | 77 | // Werte aus den gespeicherten Präferenzen abrufen, falls vorhanden 78 | if (pref.isKey("ssid")) ssid = pref.getString("ssid"); // SSID für WLAN-Verbindung 79 | if (pref.isKey("pkey")) pkey = pref.getString("pkey"); // Passkey für WLAN-Verbindung 80 | if (pref.isKey("ntp")) ntp = pref.getString("ntp"); // NTP-Server-URL für die Zeitabgleich 81 | if (pref.isKey("TIME_ZONE_IANA")) TIME_ZONE_IANA = pref.getString("TIME_ZONE_IANA"); // Zeitzone abrufen 82 | if (pref.isKey("LATITUDE")) LATITUDE = pref.getFloat("LATITUDE"); // Latitude für die Wetterdaten 83 | if (pref.isKey("LONGITUDE")) LONGITUDE = pref.getFloat("LONGITUDE"); // Longitude für die Wetterdaten 84 | 85 | 86 | curGain = 50; // Standardwert für Lautstärke 87 | if (pref.isKey("gain")) curGain = pref.getUShort("gain"); // Abrufen des Lautstärkewerts 88 | 89 | snoozeTime = 30; // Standardwert für Schlummerzeit in Minuten 90 | if (pref.isKey("snooze")) snoozeTime = pref.getUShort("snooze"); // Abrufen der Schlummerzeit 91 | 92 | bright = 80; // Standardwert für Helligkeit in Prozent 93 | if (pref.isKey("bright")) bright = pref.getUShort("bright"); // Abrufen des Helligkeitswerts 94 | 95 | alarm1 = 390; // Standardwert für die erste Alarmzeit (6:30) 96 | if (pref.isKey("alarm1")) alarm1 = pref.getUInt("alarm1"); // Abrufen der ersten Alarmzeit 97 | 98 | alarmday1 = 0B00111110; // Standardwert für die Tage (Mo-Fr) 99 | if (pref.isKey("alarmday1")) alarmday1 = pref.getUShort("alarmday1"); // Abrufen der Wochentage für den ersten Alarm 100 | 101 | alarm2 = 480; // Standardwert für die zweite Alarmzeit (8:00) 102 | if (pref.isKey("alarm2")) alarm2 = pref.getUInt("alarm2"); // Abrufen der zweiten Alarmzeit 103 | 104 | alarmday2 = 0B01000001; // Standardwert für die Tage (So, Sa) 105 | if (pref.isKey("alarmday2")) alarmday2 = pref.getUShort("alarmday2"); // Abrufen der Wochentage für den zweiten Alarm 106 | 107 | alarmtime = 0; // Startwert für die nächste Alarmzeit 108 | alarmday = 8; // Startwert für den nächsten Alarmtag (8 bedeutet, Alarm ist deaktiviert) 109 | 110 | curStation = 0; // Standardwert für die aktuelle Station 111 | // Setze die aktuelle Station auf den gespeicherten Wert, falls vorhanden 112 | if (pref.isKey("station")) curStation = pref.getUShort("station"); 113 | // Überprüfe, ob die aktuelle Station innerhalb des gültigen Bereichs liegt 114 | if (curStation >= STATIONS) curStation = 0; 115 | 116 | actStation = curStation; // Setze die aktive Station auf die aktuelle Station 117 | 118 | // Debug-Ausgabe der aktuellen Station, Lautstärke, SSID und NTP-Server 119 | Serial.printf("station %i, gain %i, ssid %s, ntp %s\n", curStation, curGain, ssid.c_str(), ntp.c_str()); 120 | 121 | // Führe die Setup-Funktionen für Audio, Display und Senderliste aus 122 | setup_audio(); // Initialisiere die Audio-Streams 123 | setup_display(); // Initialisiere die Display-Schnittstelle 124 | setup_senderList(); // Lade die Senderliste aus den Präferenzen 125 | setGain(0); // Setze die aktuelle Lautstärke 126 | 127 | // Versuche, eine WLAN-Verbindung herzustellen und zeige den Fortschritt auf dem Display an 128 | displayClear(); // Bildschirm löschen 129 | displayMessage(5, 10, 310, 30, TXT_CONNECTING_TO, ALIGNCENTER, true, ILI9341_YELLOW, ILI9341_BLACK, 1); // Zeige "Verbinden zu" auf dem Display an 130 | displayMessage(5, 50, 310, 30, ssid.c_str(), ALIGNCENTER, true, ILI9341_GREEN, ILI9341_BLACK, 1); // Zeige die SSID auf dem Display an 131 | Serial.println("Connect WiFi"); // Debug-Ausgabe: "Verbinde zu WiFi" 132 | 133 | // Versuche, sich mit dem WLAN zu verbinden 134 | connected = initWiFi(ssid, pkey); 135 | 136 | // Wenn die Verbindung erfolgreich war 137 | if (connected) { 138 | // Konfiguriere die Echtzeituhr mit der Zeitzone und dem NTP-Server 139 | configTzTime(TIME_ZONE, ntp.c_str()); 140 | 141 | // Zeige Datum und Uhrzeit sowie den Namen der Station an 142 | delay(500); // Kurze Verzögerung für die Anzeige 143 | // Fülle die Zeitstruktur ti, Minuten und Wochentag mit der aktuellen Zeit 144 | getLocalTime(&ti); 145 | minutes = ti.tm_hour * 60 + ti.tm_min; // Berechne Minuten seit Mitternacht 146 | weekday = ti.tm_wday; // Wochentag (0 = Sonntag, 1 = Montag, usw.) 147 | 148 | Serial.println("Start"); // Debug-Ausgabe: "Start" 149 | 150 | // Wenn der Alarm aktiviert ist, berechne das Datum und die Uhrzeit für den nächsten Alarm 151 | if (pref.isKey("alarmon") && pref.getBool("alarmon")) findNextAlarm(); 152 | 153 | // Zeige Uhrzeit und nächsten Alarm auf dem Display an 154 | showClock(); 155 | } else { // Wenn die Verbindung nicht erfolgreich war 156 | // Es konnte keine Verbindung hergestellt werden. Eine entsprechende Nachricht wird auf dem Display angezeigt 157 | displayClear(); // Bildschirm löschen 158 | displayMessage(5, 10, 310, 30, TXT_NOT_CONNECTED, ALIGNCENTER, true, ILI9341_RED, ILI9341_BLACK, 1); // Zeige "Nicht verbunden" auf dem Display an 159 | displayMessage(5, 50, 310, 30, TXT_CONNECT_TO_AP, ALIGNCENTER, true, ILI9341_WHITE, ILI9341_BLACK, 1); // Zeige "Verbinden zu AP" auf dem Display an 160 | displayMessage(5, 100, 310, 30, AP_NAME, ALIGNCENTER, true, ILI9341_GREEN, ILI9341_BLACK, 1); // Zeige "Ap Name" auf dem Display an 161 | displayMessage(5, 150, 310, 30, TXT_CONFIG_IP, ALIGNCENTER, true, ILI9341_WHITE, ILI9341_BLACK, 1); // Zeige "IP konfigurieren" auf dem Display an 162 | displayMessage(5, 200, 310, 30, "192.168.4.1", ALIGNCENTER, true, ILI9341_GREEN, ILI9341_BLACK, 1); // Zeige "IP " auf dem Display an 163 | 164 | // Merke den aktuellen Zeitstempel, um später nach 5 Minuten einen Retry zu ermöglichen 165 | discon = millis(); 166 | } 167 | 168 | Serial.println("Start webserver"); // Debug-Ausgabe: "Starte Webserver" 169 | 170 | // Initialisiere den Webserver und das OTA-Update 171 | setup_webserver(); // Initialisiere den Webserver 172 | setup_ota(); // Initialisiere das OTA-Update 173 | 174 | start_conf = 0; // Setze den Startwert für die Konfiguration 175 | } 176 | 177 | void loop() { 178 | long rssi = WiFi.RSSI(); // Hole das Signalstärke- (RSSI) Level des WiFi 179 | 180 | // Überprüfe und verarbeite mögliche OTA-Updates 181 | ArduinoOTA.handle(); 182 | 183 | // Verarbeite HTTP-Anfragen 184 | webserver_loop(); 185 | 186 | // Überprüfe Touch-Ereignisse 187 | touch_loop(); 188 | 189 | // Nach 10 Sekunden im Konfigurationsmodus, zurück zum Uhrmodus wechseln 190 | if (!clockmode && ((millis() - start_conf) > 10000)) { 191 | showClock(); // Zeige die Uhrzeit an 192 | clockmode = true; // Setze den Modus auf Uhr 193 | } 194 | 195 | // Zeige Metadaten an, wenn das Radio aktiv ist und wir im Uhrmodus sind 196 | if (newTitle && radio && clockmode) { 197 | showTitle(); // Zeige den Titel des aktuellen Radiosenders an 198 | newTitle = false; // Setze das Flag zurück 199 | } 200 | 201 | // Erkenne einen Verbindungsabbruch 202 | if (connected && (WiFi.status() != WL_CONNECTED)) { 203 | connected = false; // Setze die Verbindung auf false 204 | discon = millis(); // Merke den aktuellen Zeitstempel für einen automatischen Retry 205 | displayClear(); // Bildschirm löschen 206 | // Zeige eine Nachricht an, dass die Verbindung verloren gegangen ist 207 | displayMessage(5, 10, 310, 30, TXT_NOT_CONNECTED, ALIGNCENTER, true, ILI9341_RED, ILI9341_BLACK, 1); 208 | } 209 | 210 | // Erkenne eine Wiederverbindung 211 | if (!connected && (WiFi.status() == WL_CONNECTED)) { 212 | connected = true; // Setze die Verbindung auf true 213 | displayClear(); // Bildschirm löschen 214 | // Zeige eine Nachricht an, dass die Verbindung wiederhergestellt wurde 215 | displayMessage(5, 10, 310, 30, TXT_RECONNECTED, ALIGNCENTER, true, ILI9341_GREEN, ILI9341_BLACK, 1); 216 | reconnected = true; 217 | } 218 | 219 | // Wenn das Radio eingeschaltet ist, hole neue Stream-Daten 220 | if (connected && radio) { 221 | audio_loop(); // Verarbeite Audiodaten 222 | } 223 | 224 | // Wenn die Helligkeit auf 0 gesetzt ist, wird die Helligkeit durch das Umgebungslicht gesteuert 225 | if (bright == 0) { 226 | int16_t tmp = analogRead(LDR); // Lese den Wert vom Lichtsensor (LDR) 227 | int16_t diff = lastldr - tmp; // Berechne die Differenz zum vorherigen Wert 228 | diff = abs(diff); // Nehme den absoluten Wert der Differenz 229 | 230 | // Setze die Hintergrundbeleuchtung, wenn die Uhr angezeigt wird und eine signifikante Änderung des Umgebungslichts erkannt wurde 231 | if (clockmode && (diff > 50)) { 232 | setBGLight(bright); // Setze die Hintergrundbeleuchtung 233 | Serial.printf("ldr %i letzter %i\n", tmp, lastldr); // Debug-Ausgabe der aktuellen und letzten LDR-Werte 234 | lastldr = tmp; // Merke den aktuellen LDR-Wert für die nächste Messung 235 | } 236 | } 237 | 238 | // Wetterdaten beim ersten Durchlauf sofort abrufen (wenn lastWeatherUpdate == 0) oder alle 60 Sekunden 239 | if (millis() - lastWeatherUpdate > weatherUpdateInterval || lastWeatherUpdate == 0) { 240 | if (!radio && clockmode) { 241 | String weatherData = getWeatherData(LATITUDE, LONGITUDE, TIME_ZONE_IANA); 242 | displayWeather(weatherData); 243 | } 244 | lastWeatherUpdate = millis(); // Zeitstempel für das nächste Update 245 | } 246 | 247 | // Zeitgesteuertes Ereignis: Update der Anzeige alle 1 Sekunde 248 | if ((millis() - lastUpdate) > 1000) { 249 | lastUpdate = millis(); // Aktualisiere den Zeitstempel 250 | 251 | // Regelmäßige Prüfung der Schlummerzeit 252 | if (millis() > snoozeTimeEnd && snoozeTimeEnd > 0) { 253 | snoozeTimeEnd = 0; // Setze den Schlummermodus zurück 254 | toggleRadio(true); // Schalte das Radio aus 255 | showRadio(); // Zeige Radio-Status an 256 | } 257 | 258 | // Hole das Datum und die Uhrzeit 259 | if (connected && getLocalTime(&ti)) { 260 | minutes = ti.tm_hour * 60 + ti.tm_min; // Berechne Minuten seit Mitternacht 261 | weekday = ti.tm_wday; // Wochentag (0 = Sonntag, 1 = Montag, usw.) 262 | } 263 | // Setze die Hintergrundbeleuchtung, wenn die Uhr angezeigt wird 264 | if (connected && clockmode) { 265 | 266 | if(!reconnected){ 267 | setBGLight(bright); // Setze die Hintergrundbeleuchtung 268 | displayDateTime(); // Zeige Datum und Uhrzeit an ohne komplettes Display neu zu zeichnen 269 | }else{ 270 | showClock(); // Zeige Datum und Uhrzeit mit komplett neu zu zeichnen 271 | reconnected = false; 272 | } 273 | 274 | } 275 | 276 | // Wenn ein Alarm aktiviert ist, überprüfe den Tag und die Zeit 277 | if ((alarmday < 8) && getLocalTime(&ti)) { 278 | // Wenn der Alarmtag und die Zeit erreicht sind, schalte das Radio ein und berechne die Werte für den nächsten erwarteten Alarm 279 | if ((alarmday == weekday) && ((minutes == alarmtime) || (minutes == (alarmtime + 1)))) { 280 | // Test Beeper##################### 281 | 282 | // Test Beeper##################### 283 | toggleRadio(false); // Schalte das Radio an 284 | showRadio(); // Zeige Radio-Informationen an 285 | findNextAlarm(); // Berechne den nächsten Alarm 286 | showNextAlarm(); // Zeige den nächsten Alarm an 287 | } 288 | } 289 | } 290 | 291 | // Starte einen Neustart, wenn das Gerät mehr als 5 Minuten getrennt war 292 | if (!connected && ((millis() - discon) > 300000)) ESP.restart(); 293 | } 294 | -------------------------------------------------------------------------------- /radiowecker/stations.ino: -------------------------------------------------------------------------------- 1 | // Anzahl der Standardstationen in der Liste 2 | #define DEFAULTSTATIONS 26 3 | 4 | // Definition eines Sets getesteter Standardstationen, gespeichert im Flash-Speicher (PROGMEM) 5 | Station defstations[DEFAULTSTATIONS] PROGMEM = { 6 | { "http://stream01.zogl.net:8906/stream", "Radino", 1 }, 7 | { "http://radio.toggo.de/live/mp3-192/radio.toggo.de/", "Toggo", 1 }, 8 | { "http://streams.radiobob.de/bob-national/mp3-192/mediaplayer", "BOB", 1 }, 9 | { "http://stream.laut.fm/hoerspiel", "Hörspiele", 1 }, 10 | { "http://stream.laut.fm/jugend_radio", "Jugend", 1 }, 11 | { "http://646.cloudrad.io:8234", "Strobe", 1 }, 12 | { "http://646.cloudrad.io:8276", "Pulse107", 1 }, 13 | { "http://646.cloudrad.io:8314", "DJ Perry", 1 }, 14 | { "http://dispatcher.rndfnk.com/hr/hr3/suedhessen/high", "HR3", 1 }, 15 | { "http://stream.antenne.de/antenne", "Antenne Bayern", 1 }, 16 | { "http://stream.1a-webradio.de/saw-deutsch/", "1A Deutsche Hits", 1 }, 17 | { "http://1a-rock.radionetz.de:8000/1a-rock.mp3", "1A Rock", 1 }, 18 | { "http://1a-ndw.radionetz.de/1a-ndw.mp3", "1A NDW", 1 }, 19 | { "http://dispatcher.rndfnk.com/br/brklassik/live/mp3/low", "Bayern Klassik", 1 }, 20 | { "http://mdr-284280-1.cast.mdr.de/mdr/284280/1/mp3/low/stream.mp3", "MDR", 1 }, 21 | { "http://icecast.ndr.de/ndr/njoy/live/mp3/128/stream.mp3", "N-JOY", 1 }, 22 | { "http://dispatcher.rndfnk.com/rbb/rbb888/live/mp3/mid", "RBB", 1 }, 23 | { "http://dispatcher.rndfnk.com/rbb/antennebrandenburg/live/mp3/mid", "Antenne Brandenburg", 1 }, 24 | { "http://wdr-wdr3-live.icecastssl.wdr.de/wdr/wdr3/live/mp3/128/stream.mp3", "WDR3", 1 }, 25 | { "http://wdr-wdr2-aachenundregion.icecastssl.wdr.de/wdr/wdr2/aachenundregion/mp3/128/stream.mp3", "WDR 2", 1 }, 26 | { "http://rnrw.cast.addradio.de/rnrw-0182/deinschlager/low/stream.mp3", "NRW Schlagerradio", 1 }, 27 | { "http://rnrw.cast.addradio.de/rnrw-0182/deinrock/low/stream.mp3", "NRW Rockradio", 1 }, 28 | { "http://rnrw.cast.addradio.de/rnrw-0182/dein90er/low/stream.mp3", "NRW 90er", 1 }, 29 | { "http://rt1.radio/tu6h1", "RT1 Rock", 1 }, 30 | { "https://s10.streamingcloud.online:13552/radioluz320.mp3", "Spitalradio LuZ", 1 }, 31 | { "http://stream.streambase.ch/vrock/mp3-192/", "Virgin Radio", 1 } 32 | }; 33 | 34 | // Füllt die Stationenliste aus den gespeicherten Präferenzen. Wenn ein Eintrag nicht existiert, wird die Standardliste verwendet 35 | void setup_senderList() { 36 | char nkey[4]; // Schlüssel für den Namen 37 | char ukey[4]; // Schlüssel für die URL 38 | char fkey[4]; // Schlüssel für den Aktivierungsstatus 39 | 40 | // Schleife über alle möglichen Stationen 41 | for (uint8_t i = 0; i < STATIONS; i++) { 42 | // Erzeuge die Schlüssel für die aktuellen Index-Station 43 | sprintf(nkey, "n%i", i); 44 | sprintf(ukey, "u%i", i); 45 | sprintf(fkey, "f%i", i); 46 | 47 | if (i < DEFAULTSTATIONS) { 48 | // Wenn der Index innerhalb der Standardstationen liegt, lade die Daten aus den Präferenzen oder verwende Standardwerte 49 | strlcpy(stationlist[i].name, sender.getString(nkey, defstations[i].name).c_str(), 32); 50 | strlcpy(stationlist[i].url, sender.getString(ukey, defstations[i].url).c_str(), 150); 51 | stationlist[i].enabled = sender.getUChar(fkey, defstations[i].enabled); 52 | } else { 53 | // Wenn der Index außerhalb der Standardstationen liegt, lade die Daten aus den Präferenzen oder verwende leere Standardwerte 54 | strlcpy(stationlist[i].name, sender.getString(nkey, nkey).c_str(), 32); 55 | strlcpy(stationlist[i].url, sender.getString(ukey, "").c_str(), 150); 56 | stationlist[i].enabled = sender.getUChar(fkey, 0); 57 | } 58 | } 59 | } 60 | 61 | // Füllt die Stationenliste mit den Standardstationen und speichert sie in den Präferenzen 62 | void restore() { 63 | char nkey[4]; // Schlüssel für den Namen 64 | char ukey[4]; // Schlüssel für die URL 65 | char fkey[4]; // Schlüssel für den Aktivierungsstatus 66 | 67 | // Schleife über alle möglichen Stationen 68 | for (uint8_t i = 0; i < STATIONS; i++) { 69 | // Lösche die vorherigen Einträge in den Präferenzen 70 | sender.clear(); 71 | 72 | // Erzeuge die Schlüssel für den aktuellen Index 73 | sprintf(nkey, "n%i", i); 74 | sprintf(ukey, "u%i", i); 75 | sprintf(fkey, "f%i", i); 76 | 77 | if (i < DEFAULTSTATIONS) { 78 | // Wenn der Index innerhalb der Standardstationen liegt, verwende die Standardwerte 79 | strlcpy(stationlist[i].name, defstations[i].name, 32); 80 | sender.putString(nkey, defstations[i].name); 81 | strlcpy(stationlist[i].url, defstations[i].url, 150); 82 | sender.putString(ukey, defstations[i].url); 83 | stationlist[i].enabled = defstations[i].enabled; 84 | sender.putUChar(fkey, defstations[i].enabled); 85 | } else { 86 | // Wenn der Index außerhalb der Standardstationen liegt, speichere leere Werte 87 | strlcpy(stationlist[i].name, nkey, 32); 88 | sender.putString(nkey, nkey); 89 | strlcpy(stationlist[i].url, "", 150); 90 | sender.putString(ukey, ""); 91 | stationlist[i].enabled = 0; 92 | sender.putUChar(fkey, 0); 93 | } 94 | } 95 | } 96 | 97 | // Speichert die Stationenliste in den Präferenzen 98 | void saveList() { 99 | char nkey[4]; // Schlüssel für den Namen 100 | char ukey[4]; // Schlüssel für die URL 101 | char fkey[4]; // Schlüssel für den Aktivierungsstatus 102 | 103 | // Schleife über alle möglichen Stationen 104 | for (uint8_t i = 0; i < STATIONS; i++) { 105 | // Erzeuge die Schlüssel für den aktuellen Index 106 | sprintf(nkey, "n%i", i); 107 | sprintf(ukey, "u%i", i); 108 | sprintf(fkey, "f%i", i); 109 | 110 | // Speichere die Stationen-Daten in den Präferenzen 111 | sender.putString(nkey, stationlist[i].name); 112 | sender.putString(ukey, stationlist[i].url); 113 | sender.putUChar(fkey, stationlist[i].enabled); 114 | } 115 | } 116 | 117 | // Verschiebt eine Station innerhalb der Stationenliste von der alten Position zur neuen Position 118 | void reorder(uint8_t oldpos, uint8_t newpos) { 119 | Station temp; // Temporäre Variable zum Speichern der Station während des Verschiebens 120 | 121 | // Überprüfe, ob die alten und neuen Positionen innerhalb der gültigen Grenzen liegen 122 | if ((oldpos < STATIONS) && (newpos < STATIONS)) { 123 | if (oldpos > newpos) { 124 | // Verschieben nach oben in der Liste 125 | memcpy(&temp, &stationlist[oldpos], sizeof(Station)); // Speichere die Station vorübergehend 126 | for (uint8_t i = oldpos; i > newpos; i--) { 127 | memcpy(&stationlist[i], &stationlist[i - 1], sizeof(Station)); // Verschiebe die Stationen nach oben 128 | } 129 | memcpy(&stationlist[newpos], &temp, sizeof(Station)); // Setze die Station an die neue Position 130 | } else { 131 | // Verschieben nach unten in der Liste 132 | memcpy(&temp, &stationlist[oldpos], sizeof(Station)); // Speichere die Station vorübergehend 133 | for (uint8_t i = oldpos; i < newpos; i++) { 134 | memcpy(&stationlist[i], &stationlist[i + 1], sizeof(Station)); // Verschiebe die Stationen nach unten 135 | } 136 | memcpy(&stationlist[newpos], &temp, sizeof(Station)); // Setze die Station an die neue Position 137 | } 138 | } 139 | } -------------------------------------------------------------------------------- /radiowecker/symbole.h: -------------------------------------------------------------------------------- 1 | const unsigned char symbole PROGMEM [6][308] = { 2 | {// [0] 'wifi-solid_15, 17x17px 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x1f, 0xfc, 0x00, 0x70, 4 | 0x07, 0x00, 0x60, 0x03, 0x00, 0x03, 0xe0, 0x00, 0x0f, 0xf8, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 5 | 0x00, 0x01, 0x80, 0x00, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6 | 0x00, 0x00, 0x00 7 | },{ // [1] 'bed-solid_17, 17x17px 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xcc, 9 | 0xfe, 0x00, 0xde, 0xff, 0x00, 0xde, 0xff, 0x00, 0xdc, 0xff, 0x80, 0xc0, 0xff, 0x80, 0xff, 0xff, 10 | 0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 11 | 0x00, 0x00, 0x00 12 | },{// [2] 'bell_17, 17x17px 13 | 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x03, 0xe0, 0x00, 0x07, 0xf0, 0x00, 0x0c, 0x18, 0x00, 0x08, 14 | 0x08, 0x00, 0x08, 0x08, 0x00, 0x18, 0x0c, 0x00, 0x18, 0x0c, 0x00, 0x18, 0x0c, 0x00, 0x10, 0x04, 15 | 0x00, 0x30, 0x06, 0x00, 0x3f, 0xfe, 0x00, 0x1f, 0xfc, 0x00, 0x01, 0xc0, 0x00, 0x01, 0xc0, 0x00, 16 | 0x00, 0x80, 0x00 17 | },{// [3] 'bell-slash_17, 17x17px 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x00, 0x33, 0xe0, 0x00, 0x0f, 19 | 0xf0, 0x00, 0x07, 0xf0, 0x00, 0x03, 0xf0, 0x00, 0x04, 0xf0, 0x00, 0x0e, 0x78, 0x00, 0x0f, 0x38, 20 | 0x00, 0x1f, 0xdc, 0x00, 0x00, 0x04, 0x00, 0x01, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21 | 0x00, 0x00, 0x00 22 | },{// [4] 'angles_down_50_44', 50x44px 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 25 | 0x03, 0x80, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x1f, 0xc0, 26 | 0x00, 0x00, 0xff, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x7f, 0x80, 0x00, 0x00, 27 | 0x3f, 0xc0, 0x00, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x0f, 0xf0, 28 | 0x03, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x0f, 0xf0, 29 | 0x00, 0x00, 0x00, 0x01, 0xfe, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0xc0, 0x00, 0x00, 30 | 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 31 | 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 32 | 0x00, 0x00, 0x00, 0x00, 0x78, 0x03, 0xf0, 0x07, 0x80, 0x00, 0x00, 0xfc, 0x01, 0xe0, 0x0f, 0xc0, 33 | 0x00, 0x00, 0xfe, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 34 | 0x7f, 0x80, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xe0, 35 | 0x01, 0xfe, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x07, 0xf8, 36 | 0x00, 0x00, 0x00, 0x03, 0xfc, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x1f, 0xe0, 0x00, 0x00, 37 | 0x00, 0x00, 0xff, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 38 | 0x3f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 42 | 0x00, 0x00, 0x00, 0x00 43 | },{// [5] 'angles_up_50_44', 50x44px 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 48 | 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 49 | 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x0f, 0xf0, 50 | 0x00, 0x00, 0x00, 0x07, 0xf8, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0x00, 51 | 0x00, 0x1f, 0xe0, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0xff, 0x00, 0x00, 0x00, 0x7f, 52 | 0x80, 0x00, 0x7f, 0x80, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0xfe, 0x00, 0x00, 53 | 0x1f, 0xc0, 0x00, 0x00, 0xfc, 0x01, 0xe0, 0x0f, 0xc0, 0x00, 0x00, 0x78, 0x03, 0xf0, 0x07, 0x80, 54 | 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 55 | 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 56 | 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x1f, 0xe0, 57 | 0x00, 0x00, 0x00, 0x03, 0xfc, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x07, 0xf8, 0x00, 0x00, 58 | 0x00, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x3f, 59 | 0xc0, 0x00, 0xff, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x7f, 0x80, 0x00, 0x00, 0xff, 0x00, 0x00, 60 | 0x3f, 0xc0, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x0f, 0xc0, 61 | 0x00, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 | 0x00, 0x00, 0x00, 0x00 64 | } 65 | }; -------------------------------------------------------------------------------- /radiowecker/tft_color_setting.h: -------------------------------------------------------------------------------- 1 | // Colors for the Main Screen 2 | #define COLOR_WIFI_RSSI ILI9341_ORANGE 3 | #define COLOR_IP ILI9341_ORANGE 4 | #define COLOR_SLEEP_SYMBOL ILI9341_ORANGE 5 | #define COLOR_ALARM_SYMBOL ILI9341_ORANGE 6 | 7 | #define COLOR_SLIDER ILI9341_ORANGE 8 | #define COLOR_SLIDER_BG ILI9341_BLACK 9 | #define COLOR_SLIDER_BORDER ILI9341_RED 10 | 11 | #define COLOR_BG ILI9341_BLACK 12 | #define COLOR_DATE ILI9341_ORANGE 13 | #define COLOR_TIME ILI9341_ORANGE 14 | 15 | #define COLOR_NEXT_ALARM ILI9341_ORANGE 16 | 17 | #define COLOR_STATION_BOX_BG ILI9341_BLACK 18 | #define COLOR_STATION_BOX_BORDER ILI9341_WHITE 19 | 20 | #define COLOR_STATION_NAME ILI9341_YELLOW 21 | #define COLOR_STATION_TITLE ILI9341_WHITE 22 | // Colors for the Settings Page 23 | #define COLOR_SETTING_BG ILI9341_LIGHTGREY 24 | #define COLOR_SETTING_BORDER ILI9341_BLUE 25 | #define COLOR_SETTING_UP_DOWN ILI9341_BLUE 26 | 27 | #define COLOR_KNOEPFE ILI9341_BLUE 28 | #define COLOR_KNOEPFE_BG ILI9341_LIGHTGREY 29 | 30 | #define COLOR_FAV_BUTTONS ILI9341_BLUE 31 | #define COLOR_FAV_BUTTONS_BG ILI9341_LIGHTGREY 32 | #define COLOR_FAV_BUTTONS_AKTIV ILI9341_ORANGE 33 | // to be done 34 | // maybe later all the color settings from the Webpage adjustable 35 | -------------------------------------------------------------------------------- /radiowecker/weather.h: -------------------------------------------------------------------------------- 1 | #include "ArduinoJson.h" 2 | 3 | // Funktion zur Abfrage der Wetterdaten 4 | String getWeatherData(float latitude, float longitude, String timezone) { 5 | WiFiClient client; 6 | const char* host = "api.open-meteo.com"; 7 | const int httpPort = 80; 8 | 9 | String url = "/v1/forecast?latitude=" + String(latitude, 6) + 10 | "&longitude=" + String(longitude, 6) + 11 | "¤t=temperature_2m,apparent_temperature,weather_code" + 12 | "&daily=temperature_2m_min,temperature_2m_max,weathercode&timezone=" + timezone; 13 | 14 | String fullUrl = "http://" + String(host) + url; 15 | Serial.println("Überprüfe die folgende URL im Browser:"); 16 | Serial.println(fullUrl); 17 | 18 | if (!client.connect(host, httpPort)) { 19 | Serial.println("Verbindung zum Server fehlgeschlagen"); 20 | return ""; 21 | } 22 | 23 | Serial.println("Verbindung zum Server hergestellt."); 24 | 25 | client.print(String("GET ") + url + " HTTP/1.1\r\n" + 26 | "Host: " + host + "\r\n" + 27 | "Connection: close\r\n\r\n"); 28 | 29 | Serial.println("HTTP-Request gesendet."); 30 | 31 | String jsonResponse; 32 | bool isBody = false; // Flag, um anzuzeigen, ob wir im Response-Body sind 33 | 34 | // Warte auf die Antwort vom Server 35 | unsigned long timeout = millis() + 5000; // 5 Sekunden Timeout 36 | while (!client.available()) { 37 | if (millis() > timeout) { 38 | Serial.println("Timeout beim Warten auf die Antwort vom Server."); 39 | return ""; 40 | } 41 | delay(50); 42 | } 43 | 44 | Serial.println("Antwort vom Server verfügbar."); 45 | 46 | // Header und Body verarbeiten 47 | while (client.available()) { 48 | char c = client.read(); 49 | 50 | // Erkenne den Beginn des Response-Bodys (Überspringe die Header) 51 | if (c == '{' || c == '[') { 52 | isBody = true; // Wir befinden uns jetzt im Body 53 | } 54 | 55 | // Füge das Zeichen zur JSON-Antwort hinzu, wenn wir im Body sind 56 | if (isBody) { 57 | jsonResponse += c; 58 | } 59 | } 60 | 61 | if (jsonResponse.length() > 0) { 62 | Serial.println("Wetterdaten empfangen."); 63 | Serial.println(jsonResponse); // Gibt die empfangene JSON-Antwort aus 64 | } else { 65 | Serial.println("Keine Wetterdaten empfangen."); 66 | } 67 | 68 | return jsonResponse; // JSON-Daten als String zurückgeben 69 | } 70 | 71 | // Funktion zur Rückgabe des passenden Icon-Indexes basierend auf dem Wettercode 72 | int getWeatherIcon(int weather_code) { 73 | // Überprüfe die Wettercodes und gebe den entsprechenden Icon-Index zurück 74 | if (weather_code == 0) return 0; 75 | else if (weather_code == 45 || weather_code == 48) return 1; 76 | else if (weather_code == 1) return 2; 77 | else if (weather_code == 2) return 3; 78 | else if (weather_code == 3) return 4; 79 | else if (weather_code == 51 || weather_code == 53 || weather_code == 55 || weather_code == 80) return 5; 80 | else if (weather_code == 56 || weather_code == 57) return 6; 81 | else if (weather_code == 66 || weather_code == 67) return 7; 82 | else if (weather_code == 81 || weather_code == 82 || weather_code == 61 || weather_code == 63 || weather_code == 65) return 8; 83 | else if (weather_code == 95) return 9; 84 | else if (weather_code == 77 || weather_code == 85 || weather_code == 86 || weather_code == 71 || weather_code == 73 || weather_code == 75) return 10; 85 | else if (weather_code == 96 || weather_code == 99) return 11; 86 | else return -1; // Falls der Wettercode ungültig ist, -1 zurückgeben 87 | } -------------------------------------------------------------------------------- /radiowecker/weather_icons.h: -------------------------------------------------------------------------------- 1 | const unsigned char weather_icons PROGMEM [12][1536] = { 2 | {//[0] '0_clear', 30x25px 3 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 4 | 0x00, 0x03, 0x00, 0x00, 0x00, 0x83, 0x04, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x27, 0x90, 0x00, 5 | 0x00, 0x08, 0x40, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x30, 0x30, 0x00, 0x03, 0xf0, 0x3f, 0x00, 6 | 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x18, 0x60, 0x00, 0x00, 0x0f, 0xc0, 0x00, 7 | 0x00, 0x63, 0x18, 0x00, 0x00, 0xc3, 0x0c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 8 | 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 9 | 0x00, 0x00, 0x00, 0x00 10 | },{ //[1] '45_48_fog', 30x25px 11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x00, 13 | 0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 14 | 0x07, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17 | 0x00, 0x00, 0x00, 0x00 18 | },{//[2] '1_mostly-clear', 30x25px 19 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 20 | 0x00, 0x40, 0x08, 0x00, 0x00, 0x27, 0x90, 0x00, 0x00, 0x0d, 0xc0, 0x00, 0x00, 0x10, 0x20, 0x00, 21 | 0x00, 0x30, 0x30, 0x00, 0x03, 0xb0, 0x17, 0x00, 0x03, 0xa0, 0x37, 0x00, 0x00, 0x30, 0x78, 0x00, 22 | 0x00, 0x10, 0x86, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x26, 0x00, 0x80, 0x00, 0x48, 0x00, 0x40, 23 | 0x00, 0x88, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 0x0c, 0x00, 0xc0, 0x00, 0x03, 0xff, 0x80, 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x00, 0x00, 0x00, 0x00 26 | },{//[3] '2_partly-cloudy', 30x25px 27 | 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x00, 0x11, 0x10, 0x00, 0x00, 28 | 0x0f, 0xe7, 0xc0, 0x00, 0x0c, 0x6c, 0x30, 0x00, 0x08, 0x30, 0x1e, 0x00, 0xf8, 0x30, 0x0f, 0x00, 29 | 0x08, 0xe0, 0x01, 0x80, 0x0f, 0xc0, 0x00, 0xc0, 0x0e, 0x00, 0x00, 0x20, 0x1c, 0x00, 0x00, 0x10, 30 | 0x28, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x30, 31 | 0x04, 0x00, 0x00, 0x20, 0x03, 0x80, 0x01, 0xc0, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 33 | 0x00, 0x00, 0x00, 0x00 34 | },{//[4] '3_overcast-cloudy', 30x25px 35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xc3, 0x00, 36 | 0x00, 0x0f, 0x80, 0x80, 0x00, 0x38, 0x40, 0x40, 0x00, 0x60, 0x38, 0x20, 0x00, 0x40, 0x1c, 0x20, 37 | 0x03, 0xc0, 0x02, 0x20, 0x07, 0x80, 0x01, 0xc0, 0x08, 0x00, 0x00, 0xc0, 0x10, 0x00, 0x00, 0x60, 38 | 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x40, 39 | 0x08, 0x00, 0x00, 0xc0, 0x0e, 0x00, 0x03, 0x80, 0x03, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00 42 | },{//[5] '51_53_55_80_drizzle', 30x25px 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 44 | 0x00, 0x30, 0x60, 0x00, 0x00, 0x60, 0x3c, 0x00, 0x00, 0x40, 0x06, 0x00, 0x07, 0xc0, 0x03, 0x00, 45 | 0x0c, 0x00, 0x01, 0x80, 0x18, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 46 | 0x30, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x60, 0x10, 0x22, 0x00, 0x40, 0x08, 0x04, 0x00, 0xc0, 47 | 0x07, 0x80, 0x07, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 48 | 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00 50 | },{//[6] '56_57_freezingdrizzle', 30x25px 51 | 0x00, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x30, 0x70, 0x00, 0x00, 0x20, 0x38, 0x00, 52 | 0x01, 0xe0, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x80, 0x0c, 0x00, 0x01, 0x80, 53 | 0x0c, 0x00, 0x00, 0x80, 0x0c, 0x00, 0x00, 0x80, 0x04, 0x02, 0x01, 0x80, 0x02, 0x04, 0x03, 0x00, 54 | 0x03, 0xc8, 0x0e, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x7a, 0x40, 0x00, 0x00, 0x7a, 0x20, 0x00, 56 | 0x00, 0x7b, 0x18, 0x00, 0x00, 0x37, 0x0c, 0x00, 0x00, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 57 | 0x00, 0x00, 0x00, 0x00 58 | },{//[7] '66_67_sleet', 30x25px 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 60 | 0x00, 0x30, 0x60, 0x00, 0x00, 0x60, 0x3c, 0x00, 0x00, 0x40, 0x06, 0x00, 0x07, 0xc0, 0x03, 0x00, 61 | 0x0c, 0x00, 0x01, 0x80, 0x18, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 62 | 0x30, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x60, 0x10, 0x01, 0x00, 0x40, 0x08, 0x00, 0x40, 0xc0, 63 | 0x07, 0x80, 0x87, 0x00, 0x01, 0x18, 0x04, 0x00, 0x00, 0x3c, 0x90, 0x00, 0x00, 0x7c, 0x20, 0x00, 64 | 0x00, 0x3c, 0x44, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65 | 0x00, 0x00, 0x00, 0x00 66 | },{//[8] '81_82_61_63_65_rain', 30x25px 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 68 | 0x00, 0x30, 0x60, 0x00, 0x00, 0x60, 0x3c, 0x00, 0x00, 0x40, 0x06, 0x00, 0x07, 0xc0, 0x03, 0x00, 69 | 0x0c, 0x00, 0x01, 0x80, 0x18, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 70 | 0x30, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x60, 0x10, 0xcc, 0x80, 0x40, 0x08, 0x66, 0xc0, 0xc0, 71 | 0x07, 0xb6, 0x67, 0x00, 0x01, 0x13, 0x34, 0x00, 0x00, 0x19, 0xb0, 0x00, 0x00, 0x0c, 0x98, 0x00, 72 | 0x00, 0x06, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 0x00 74 | },{//[9] '95_lightning', 30x25px 75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 76 | 0x00, 0x30, 0x60, 0x00, 0x00, 0x60, 0x3c, 0x00, 0x00, 0x40, 0x06, 0x00, 0x07, 0xc0, 0x03, 0x00, 77 | 0x0c, 0x00, 0x01, 0x80, 0x18, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 78 | 0x30, 0x00, 0x00, 0x60, 0x10, 0x02, 0x00, 0x60, 0x10, 0x07, 0x00, 0x40, 0x08, 0x06, 0x00, 0xc0, 79 | 0x07, 0xee, 0x1f, 0x00, 0x01, 0xcf, 0x9c, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 80 | 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 81 | 0x00, 0x00, 0x00, 0x00 82 | },{//[10] '77_85_86_71_73_75_snow', 30x25px 83 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 84 | 0x00, 0x30, 0x60, 0x00, 0x00, 0x60, 0x3c, 0x00, 0x00, 0x40, 0x06, 0x00, 0x07, 0xc0, 0x03, 0x00, 85 | 0x0c, 0x00, 0x01, 0x80, 0x18, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x40, 0x60, 86 | 0x30, 0x00, 0xf0, 0x60, 0x10, 0x19, 0xf0, 0x60, 0x10, 0x3d, 0xf0, 0x40, 0x08, 0x7c, 0xf0, 0xc0, 87 | 0x07, 0xbc, 0x67, 0x00, 0x01, 0x3d, 0xc4, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0xe0, 0x00, 88 | 0x00, 0x03, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 89 | 0x00, 0x00, 0x00, 0x00 90 | },{//[11] '96_99_thunderstorm', 30x25px 91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 92 | 0x00, 0x36, 0x60, 0x00, 0x00, 0x6e, 0x3c, 0x00, 0x00, 0x4e, 0x06, 0x00, 0x07, 0xcc, 0x03, 0x00, 93 | 0x0c, 0x0f, 0x81, 0x80, 0x18, 0x1f, 0x00, 0x40, 0x10, 0x03, 0x00, 0x60, 0x30, 0x02, 0x00, 0x60, 94 | 0x30, 0x06, 0x00, 0x60, 0x10, 0x00, 0x00, 0x60, 0x10, 0xcc, 0x80, 0x40, 0x08, 0x66, 0xc0, 0xc0, 95 | 0x07, 0xb6, 0x67, 0x00, 0x01, 0x13, 0x34, 0x00, 0x00, 0x19, 0xb0, 0x00, 0x00, 0x0c, 0x98, 0x00, 96 | 0x00, 0x06, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 97 | 0x00, 0x00, 0x00, 0x00 98 | } 99 | }; -------------------------------------------------------------------------------- /radiowecker/webserver.ino: -------------------------------------------------------------------------------- 1 | //home page and templatefor options 2 | #include "index.h" 3 | #include "ArduinoJson.h" 4 | 5 | WebServer server(80); 6 | 7 | // Konfiguriert den Webserver und richtet die Routen für verschiedene HTTP-Anfragen ein 8 | void setup_webserver() { 9 | // Optional: Aktiviert CORS (Cross-Origin Resource Sharing) für den Server 10 | // server.enableCORS(); 11 | 12 | // Definiert die Route für die Root-URL, die auf die Funktion `handleRoot` verweist 13 | server.on("/", handleRoot); 14 | 15 | // Definiert die Routen für verschiedene AJAX-Befehle und verknüpft sie mit den entsprechenden Funktionen 16 | server.on("/cmd/stations", sendStations); // Ruft die Liste der verfügbaren Stationen ab 17 | server.on("/cmd/restorestations", restoreStations); // Stellt die gespeicherten Stationen wieder her 18 | server.on("/cmd/restart", restart); // Startet das System neu 19 | server.on("/cmd/setaccess", setAccessData); // Setzt die Zugangsdaten 20 | server.on("/cmd/getaccess", getAccessData); // Ruft die Zugangsdaten ab 21 | server.on("/cmd/getalarms", getAlarms); // Ruft die Alarmkonfiguration ab 22 | server.on("/cmd/setalarms", setAlarms); // Setzt die Alarmkonfiguration 23 | server.on("/cmd/getstation", getStationData); // Ruft die Daten der aktuellen Station ab 24 | server.on("/cmd/setstation", setStationData); // Setzt die Daten der aktuellen Station 25 | server.on("/cmd/teststation", testStation); // Testet die Verbindung zur aktuellen Station 26 | server.on("/cmd/endtest", endTest); // Beendet den Testmodus 27 | 28 | // Player-Tab: Definiert Routen für Steuerbefehle des Players 29 | server.on("/cmd/startPlay", startPlay); // Startet die Wiedergabe 30 | server.on("/cmd/stopPlay", stopPlay); // Stoppt die Wiedergabe 31 | server.on("/cmd/GainSlider", GainSlider); // Setzt den Wert des Lautstärkereglers 32 | server.on("/cmd/btnAlarm", btnAlarm); // Schaltet den Alarm ein oder aus 33 | server.on("/cmd/startSleep", startSleep); // Startet den Schlafmodus 34 | server.on("/cmd/beforeStation", beforeStation); // Wechselt zur vorherigen Station 35 | server.on("/cmd/nextStation", nextStation); // Wechselt zur nächsten Station 36 | server.on("/cmd/getCurrentStatus", getCurrentStatus); // Ruft den aktuellen Status ab 37 | 38 | // Info-Tab: Definiert die Route für das Abrufen von Systeminformationen 39 | server.on("/cmd/getInfo", getInfo); // Ruft allgemeine Systeminformationen ab 40 | 41 | // Startet den Webserver 42 | server.begin(); 43 | } 44 | 45 | // Wird aus der Hauptschleife aufgerufen, um eingehende HTTP-Anfragen zu verarbeiten 46 | void webserver_loop() { 47 | server.handleClient(); // Bearbeitet alle an den Webserver gesendeten Anfragen 48 | } 49 | 50 | // Bearbeitet Anfragen an die Wurzel-URL ("/") des Webservers 51 | void handleRoot() { 52 | if (connected) { 53 | // Wenn verbunden, sende die Hauptseite 54 | server.send(200, "text/html", MAIN_page); 55 | } else { 56 | // Wenn nicht verbunden, sende die Konfigurationsseite 57 | // Parameter werden als Argumente im HTML-Request übergeben 58 | Serial.println("Got config:"); 59 | uint8_t a = server.args(); // Anzahl der Argumente im Request 60 | Serial.print(a); 61 | Serial.println(" Arguments"); 62 | for (uint8_t i = 0; i < a; i++) Serial.println(server.arg(i)); // Ausgabe aller Argumente 63 | 64 | // Speichern der SSID in den Einstellungen, falls vorhanden 65 | if (server.hasArg("conf_ssid")) { 66 | pref.putString("ssid", server.arg("conf_ssid")); 67 | Serial.println(server.arg("conf_ssid")); 68 | } 69 | 70 | // Speichern des PKEY in den Einstellungen, falls vorhanden 71 | if (server.hasArg("conf_pkey")) { 72 | pref.putString("pkey", server.arg("conf_pkey")); 73 | Serial.println(server.arg("conf_pkey")); 74 | } 75 | 76 | // Falls das Reset-Argument vorhanden ist, starte das System neu 77 | if (server.hasArg("reset")) { 78 | Serial.println("Restart!"); 79 | ESP.restart(); 80 | } 81 | 82 | // Sende die Konfigurationsseite an den Client 83 | server.send(200, "text/html", CONFIG_page); 84 | } 85 | } 86 | 87 | // Bearbeitet AJAX-Befehle für "/cmd/stations" 88 | // Sendet eine Liste der verfügbaren Stationen als HTML-Optionen 89 | void sendStations() { 90 | char* s; // Variable für das Symbol vor dem Stationsnamen 91 | char* sel; // Variable für das 'selected'-Attribut der aktuellen Station 92 | char buf[100]; // Buffer für die HTML-Ausgabe 93 | 94 | // Bereite die HTML-Antwort vor 95 | server.setContentLength(CONTENT_LENGTH_UNKNOWN); 96 | server.send(200, "text/html", ""); 97 | 98 | // Sende alle Stationen als Optionsliste 99 | for (uint8_t i = 0; i < STATIONS; i++) { 100 | // Füge das 'selected'-Attribut hinzu, wenn die Station aktuell ist 101 | sel = ""; 102 | if (i == actStation) sel = "selected"; 103 | 104 | // Setze ein schwarzes Punkt-Symbol vor dem Stationsnamen, wenn aktiviert 105 | s = " "; 106 | if (stationlist[i].enabled) s = "●"; 107 | 108 | // Erstelle den Eintrag für die Option mit der Vorlage 109 | sprintf(buf, OPTION_entry, i, sel, s, stationlist[i].name); 110 | server.sendContent(buf); // Sende den Inhalt der Option 111 | } 112 | } 113 | 114 | // Bearbeitet AJAX-Befehle für "/cmd/setaccess" 115 | // Speichert Zugangsdaten in den Einstellungen 116 | void setAccessData() { 117 | // Der Befehl erwartet drei Argumente 118 | // Die Zugangsdaten werden in den Einstellungen gespeichert 119 | 120 | // Speichere die SSID, wenn vorhanden 121 | if (server.hasArg("ssid")) { 122 | ssid = server.arg("ssid"); 123 | pref.putString("ssid", ssid); 124 | } 125 | 126 | // Speichere den Pre-Shared Key (PKEY), wenn vorhanden 127 | if (server.hasArg("pkey")) { 128 | pkey = server.arg("pkey"); 129 | pref.putString("pkey", pkey); 130 | } 131 | 132 | // Speichere die NTP-Server-Adresse, wenn vorhanden 133 | if (server.hasArg("ntp")) { 134 | ntp = server.arg("ntp"); 135 | pref.putString("ntp", ntp); 136 | } 137 | 138 | // Speichere die Timezone, wenn vorhanden 139 | if (server.hasArg("TIME_ZONE_IANA")) { 140 | TIME_ZONE_IANA = server.arg("TIME_ZONE_IANA"); 141 | pref.putString("TIME_ZONE_IANA", TIME_ZONE_IANA); 142 | } 143 | 144 | // Speichere die Latitude, wenn sie vorhanden ist 145 | if (server.hasArg("LATITUDE")) { 146 | LATITUDE = server.arg("LATITUDE").toFloat(); 147 | pref.putFloat("LATITUDE", LATITUDE); 148 | } 149 | 150 | // Speichere die Longitude, wenn sie vorhanden ist 151 | if (server.hasArg("LONGITUDE")) { 152 | LONGITUDE = server.arg("LONGITUDE").toFloat(); 153 | pref.putFloat("LONGITUDE", LONGITUDE); 154 | } 155 | 156 | // Antworte mit "OK" 157 | server.send(200, "text/plain", "OK"); 158 | } 159 | 160 | // Bearbeitet AJAX-Befehle für "/cmd/getaccess" 161 | // Sendet Zugangsdaten als Textnachricht 162 | void getAccessData() { 163 | // Erstelle eine Nachricht mit den Zugangsdaten, getrennt durch Zeilenumbrüche 164 | String msg = String(ssid) + "\n" + String(pkey) + "\n" + String(ntp) + "\n" + String(TIME_ZONE_IANA) + "\n" + String(LATITUDE, 6) + "\n" + String(LONGITUDE, 6); 165 | 166 | // Antworte mit den Zugangsdaten 167 | server.send(200, "text/plain", msg); 168 | } 169 | 170 | 171 | // Bearbeitet AJAX-Befehle für "/cmd/getalarms" 172 | // Sendet die Alarmzeiten und die Wochentage für zwei Alarme als Textnachricht 173 | void getAlarms() { 174 | char buf[45]; 175 | uint8_t h, m, mask, i; 176 | 177 | // Konvertiere die Alarmzeiten in Stunden und Minuten und formatiere sie 178 | h = alarm1 / 60; 179 | m = alarm1 % 60; 180 | sprintf(buf, "%02i:%02i\n", h, m); 181 | 182 | h = alarm2 / 60; 183 | m = alarm2 % 60; 184 | sprintf(&buf[20], "%02i:%02i\n", h, m); 185 | 186 | // Füge die Wochentage für beide Alarme hinzu 187 | for (i = 0; i < 7; i++) { 188 | mask = 1 << i; 189 | buf[6 + i * 2] = ((alarmday1 & mask) != 0) ? '1' : '0'; 190 | buf[26 + i * 2] = ((alarmday2 & mask) != 0) ? '1' : '0'; 191 | buf[7 + i * 2] = '\n'; 192 | buf[27 + i * 2] = '\n'; 193 | } 194 | 195 | buf[40] = 0; // Null-Terminierung des Strings 196 | 197 | // Antwort mit den Alarmdaten als Textnachricht 198 | server.send(200, "text/plain", String(buf)); 199 | } 200 | 201 | // Berechnet die Gesamtanzahl der Minuten aus einer Stunden- und Minutenangabe im Format "HH:MM" 202 | // Gibt die Minuten als uint16_t zurück 203 | uint16_t stringToMinutes(String val) { 204 | uint8_t h, m; 205 | // Extrahiere die Stunden aus den ersten zwei Zeichen des Strings und konvertiere sie in eine Ganzzahl 206 | h = val.substring(0, 2).toInt(); 207 | // Extrahiere die Minuten aus den Zeichen nach dem Doppelpunkt und konvertiere sie in eine Ganzzahl 208 | m = val.substring(3).toInt(); 209 | // Berechne die Gesamtanzahl der Minuten und gebe sie zurück 210 | return h * 60 + m; 211 | } 212 | 213 | // Verarbeitet den AJAX-Befehl /cmd/setalarms zum Setzen der Alarmzeiten 214 | void setAlarms() { 215 | char txt[10]; 216 | uint8_t b; 217 | 218 | // Debug-Ausgabe: Beginn des Setzens der Alarme 219 | Serial.println("Set alarms start"); 220 | 221 | // Überprüfe, ob der Parameter "al0" vorhanden ist und setze alarm1 222 | if (server.hasArg("al0")) { 223 | alarm1 = stringToMinutes(server.arg("al0")); // Konvertiere die Zeit in Minuten 224 | Serial.print(server.arg("al0")); // Debug-Ausgabe der übergebenen Zeit 225 | Serial.printf(" = %i\n", alarm1); // Debug-Ausgabe des berechneten Alarmwerts 226 | pref.putUInt("alarm1", alarm1); // Speichere den Alarmwert in den Einstellungen 227 | } 228 | 229 | // Überprüfe, ob der Parameter "al8" vorhanden ist und setze alarm2 230 | if (server.hasArg("al8")) { 231 | alarm2 = stringToMinutes(server.arg("al8")); // Konvertiere die Zeit in Minuten 232 | Serial.print(server.arg("al8")); // Debug-Ausgabe der übergebenen Zeit 233 | Serial.printf(" = %i\n", alarm2); // Debug-Ausgabe des berechneten Alarmwerts 234 | pref.putUInt("alarm2", alarm2); // Speichere den Alarmwert in den Einstellungen 235 | } 236 | 237 | // Initialisiere die Wochentags-Flags für beide Alarme 238 | alarmday1 = 0; 239 | alarmday2 = 0; 240 | 241 | // Überprüfe die Wochentags-Parameter für alarmday1 und alarmday2 242 | for (uint8_t i = 0; i < 7; i++) { 243 | // Erstelle den Parameter-Namen für alarmday1 244 | sprintf(txt, "al%i", i + 1); 245 | if (server.hasArg(txt)) { 246 | if (server.arg(txt) == "1") alarmday1 = alarmday1 | (1 << i); // Setze das entsprechende Bit für alarmday1 247 | } 248 | 249 | // Erstelle den Parameter-Namen für alarmday2 250 | sprintf(txt, "al%i", i + 9); 251 | if (server.hasArg(txt)) { 252 | if (server.arg(txt) == "1") alarmday2 = alarmday2 | (1 << i); // Setze das entsprechende Bit für alarmday2 253 | } 254 | } 255 | 256 | // Speichere die Wochentags-Flags in den Einstellungen 257 | pref.putUShort("alarmday1", alarmday1); 258 | pref.putUShort("alarmday2", alarmday2); 259 | 260 | // Debug-Ausgabe der Wochentags-Flags 261 | Serial.printf("days1 %x days2 %x\n", alarmday1, alarmday2); 262 | 263 | // Finde den nächsten Alarm und zeige ihn an, falls der Clock-Modus aktiv ist 264 | findNextAlarm(); 265 | if (clockmode) showNextAlarm(); 266 | 267 | // Sende eine Bestätigung als Antwort 268 | server.send(200, "text/plain", "OK"); 269 | } 270 | 271 | // Verarbeitet den AJAX-Befehl /cmd/getstation, um Daten einer spezifischen Station abzurufen 272 | void getStationData() { 273 | // Überprüft, ob der Parameter "stationid" vorhanden ist 274 | if (server.hasArg("stationid")) { 275 | uint8_t i = server.arg("stationid").toInt(); // Liest die Station-ID aus der Anfrage 276 | 277 | // Wenn die Station-ID außerhalb des gültigen Bereichs liegt, setze sie auf die letzte Station 278 | if (i >= STATIONS) i = STATIONS - 1; 279 | 280 | // Erstelle eine Nachricht mit dem Namen, der URL und dem Aktivierungsstatus der Station, getrennt durch neue Zeilen 281 | String msg = String(stationlist[i].name) + "\n" + String(stationlist[i].url) + "\n" + String(stationlist[i].enabled) + "\n" + String(i + 1); 282 | 283 | // Sende die Nachricht als Antwort 284 | server.send(200, "text/plain", msg); 285 | } else { 286 | // Wenn der Parameter fehlt oder ungültig ist, sende eine Fehlermeldung 287 | server.send(200, "text/plain", "Invalid command"); 288 | } 289 | } 290 | 291 | // Verarbeitet den AJAX-Befehl /cmd/setstation, um Daten einer bestimmten Station zu setzen 292 | void setStationData() { 293 | // Erwartet eine gültige Station-ID als Argument 294 | // Daten werden ebenfalls als Argumente übermittelt: 295 | // name = Name der Station 296 | // url = URL der Station 297 | // enabled = Aktivierungsstatus 298 | // position = neue Position in der Liste 299 | char key[5]; 300 | 301 | // Überprüft, ob die Station-ID vorhanden ist und innerhalb des gültigen Bereichs liegt 302 | if ((server.hasArg("stationid")) && (server.arg("stationid").toInt() < STATIONS)) { 303 | uint8_t i = server.arg("stationid").toInt(); 304 | 305 | // Speichert die Werte aus den Argumenten in der Stationenliste 306 | if (server.hasArg("name")) { 307 | sprintf(key, "n%i", i); 308 | sender.putString(key, server.arg("name")); 309 | strlcpy(stationlist[i].name, server.arg("name").c_str(), 32); 310 | } 311 | if (server.hasArg("url")) { 312 | sprintf(key, "u%i", i); 313 | sender.putString(key, server.arg("url")); 314 | strlcpy(stationlist[i].url, server.arg("url").c_str(), 150); 315 | } 316 | if (server.hasArg("enabled")) { 317 | sprintf(key, "f%i", i); 318 | sender.putUChar(key, server.arg("enabled").toInt()); 319 | stationlist[i].enabled = server.arg("enabled").toInt(); 320 | } 321 | if (server.hasArg("position")) { 322 | int16_t newpos = server.arg("position").toInt(); 323 | newpos--; 324 | Serial.printf("Move %i to position %i\n", i + 1, newpos + 1); 325 | if ((i != newpos) && (newpos >= 0) && (newpos < STATIONS)) { 326 | reorder(i, newpos); // Ändert die Position der Station in der Liste 327 | saveList(); // Speichert die aktualisierte Liste 328 | } 329 | } 330 | 331 | // Sendet eine Bestätigung der erfolgreichen Verarbeitung zurück 332 | server.send(200, "text/plain", "OK"); 333 | } else { 334 | // Sendet eine Fehlermeldung zurück, wenn die Station-ID ungültig ist 335 | server.send(200, "text/plain", "Invalid station ID"); 336 | } 337 | } 338 | 339 | // Verarbeitet den AJAX-Befehl /cmd/teststation, um eine URL zu testen 340 | void testStation() { 341 | // Erwartet ein Argument mit der zu testenden URL 342 | bool ret = true; 343 | 344 | // Überprüft, ob das URL-Argument vorhanden ist 345 | if (server.hasArg("url")) { 346 | // Versucht, die URL zu starten und speichert das Ergebnis 347 | ret = startUrl(server.arg("url")); 348 | } 349 | 350 | // Sendet eine Bestätigung bei Erfolg oder eine Fehlermeldung bei Misserfolg 351 | if (ret) { 352 | // Bei Erfolg: Antwort "OK" senden 353 | server.send(200, "text/plain", "OK"); 354 | } else { 355 | // Bei Misserfolg: Wechselt zurück zur aktuellen Station und sendet "ERROR" 356 | startUrl(String(stationlist[actStation].url)); 357 | server.send(300, "text/plain", "ERROR"); 358 | } 359 | } 360 | 361 | // Verarbeitet den AJAX-Befehl /cmd/endtest, um den Test zu beenden 362 | void endTest() { 363 | // Wechselt zurück zur aktuellen Station, um den Test zu beenden 364 | startUrl(String(stationlist[actStation].url)); 365 | 366 | // Sendet eine Bestätigung, dass der Test beendet wurde 367 | server.send(200, "text/plain", "OK"); 368 | } 369 | 370 | // Verarbeitet den AJAX-Befehl /cmd/restorestations, um die Stationen wiederherzustellen 371 | void restoreStations() { 372 | restore(); // Stellt die Stationen aus dem Speicher wieder her 373 | 374 | // Sendet eine Bestätigung, dass die Wiederherstellung erfolgreich war 375 | server.send(200, "text/plain", "OK"); 376 | } 377 | 378 | // Verarbeitet den AJAX-Befehl /cmd/restart, um das Gerät neu zu starten 379 | void restart() { 380 | ESP.restart(); // Startet das Gerät neu 381 | } 382 | 383 | // Player Tab ###################### 384 | // Verarbeitet den AJAX-Befehl /cmd/startPlay, um das Radio zu starten 385 | void startPlay() { 386 | toggleRadio(false); // Schaltet das Radio ein 387 | server.send(200, "text/plain", "OK"); // Antwortet mit "OK" 388 | } 389 | 390 | // Verarbeitet den AJAX-Befehl /cmd/stopPlay, um das Radio zu stoppen 391 | void stopPlay() { 392 | toggleRadio(true); // Schaltet das Radio aus 393 | server.send(200, "text/plain", "OK"); // Antwortet mit "OK" 394 | } 395 | 396 | // Verarbeitet den AJAX-Befehl /cmd/GainSlider, um den Lautstärkewert zu setzen 397 | void GainSlider() { 398 | // Überprüft, ob der Parameter "GainValue" in der Anfrage vorhanden ist 399 | if (server.hasArg("GainValue")) { 400 | // Konvertiert den Wert des Parameters in einen float 401 | float floatWert = atof(server.arg("GainValue").c_str()); 402 | // Setzt den Lautstärkewert 403 | setGainValue(floatWert, "WEBSITE"); 404 | // Antwortet mit "OK" 405 | server.send(200, "text/plain", "OK"); 406 | 407 | // Gibt den Wert für Debugging-Zwecke aus 408 | Serial.print("GainValue: "); 409 | Serial.println(floatWert); 410 | } else { 411 | // Antwortet mit einem Fehlercode, wenn der Parameter fehlt 412 | server.send(400, "text/plain", "ERROR"); 413 | } 414 | } 415 | 416 | // Verarbeitet den AJAX-Befehl /cmd/btnAlarm, um den Alarm ein- oder auszuschalten 417 | void btnAlarm() { 418 | // Schaltet den Alarm um 419 | toggleAlarm(); 420 | // Antwortet mit "OK" 421 | server.send(200, "text/plain", "OK"); 422 | } 423 | 424 | // Verarbeitet den AJAX-Befehl /cmd/startSleep, um die Schlummerfunktion zu starten 425 | void startSleep() { 426 | // Startet die Schlummerfunktion 427 | startSnooze(); 428 | // Antwortet mit "OK" 429 | server.send(200, "text/plain", "OK"); 430 | } 431 | 432 | // Verarbeitet den AJAX-Befehl /cmd/beforeStation, um zur vorherigen "aktiven" Station zu wechseln 433 | void beforeStation() { 434 | // Zähle die Anzahl der Versuche, um Endlosschleifen zu vermeiden 435 | int attempts = 0; 436 | // Schleife, um die vorherige aktive Station zu finden 437 | do { 438 | // Verringert die aktuelle Station um eins 439 | curStation -= 1; 440 | // Wenn die aktuelle Station kleiner als 0 wird, setze sie auf die letzte Station 441 | if (curStation < 0) { 442 | curStation = STATIONS - 1; 443 | } 444 | // Erhöhe den Versuchszähler 445 | attempts++; 446 | // Wenn alle Stationen durchlaufen wurden und keine aktive gefunden wurde 447 | if (attempts >= STATIONS) { 448 | // Optional: Setze auf die letzte Station zurück (auch wenn sie deaktiviert ist) 449 | curStation = STATIONS - 1; 450 | // Debug-Ausgabe, dass keine aktive Station gefunden wurde 451 | Serial.println("Keine aktive Station gefunden."); 452 | // Antwortet mit einer Fehlermeldung 453 | server.send(200, "text/plain", "Keine aktive Station verfügbar."); 454 | return; // Beende die Funktion 455 | } 456 | } while (!stationlist[curStation].enabled); 457 | // Ändert die Station und zeigt die neue Station an 458 | changeStation(); 459 | // Debug-Ausgabe der aktuellen Station 460 | Serial.println(curStation); 461 | // Antwortet mit "OK" 462 | server.send(200, "text/plain", "OK"); 463 | } 464 | 465 | // Verarbeitet den AJAX-Befehl /cmd/nextStation, um zur nächsten "aktiven" Station zu wechseln 466 | void nextStation() { 467 | // Zähle die Anzahl der Versuche, um Endlosschleifen zu vermeiden 468 | int attempts = 0; 469 | // Schleife, um die nächste aktive Station zu finden 470 | do { 471 | // Erhöht die aktuelle Station um eins 472 | curStation += 1; 473 | // Wenn die aktuelle Station den Maximalwert überschreitet, setze sie auf die erste Station 474 | if (curStation >= STATIONS) { 475 | curStation = 0; 476 | } 477 | // Erhöhe den Versuchszähler 478 | attempts++; 479 | // Wenn alle Stationen durchlaufen wurden und keine aktive gefunden wurde 480 | if (attempts >= STATIONS) { 481 | // Optional: Setze auf die erste Station zurück (auch wenn sie deaktiviert ist) 482 | curStation = 0; 483 | // Debug-Ausgabe, dass keine aktive Station gefunden wurde 484 | Serial.println("Keine aktive Station gefunden."); 485 | // Antwortet mit einer Fehlermeldung 486 | server.send(200, "text/plain", "Keine aktive Station verfügbar."); 487 | return; // Beende die Funktion 488 | } 489 | } while (!stationlist[curStation].enabled); 490 | // Ändert die Station und zeigt die neue Station an 491 | changeStation(); 492 | // Debug-Ausgabe der aktuellen Station 493 | Serial.println(curStation); 494 | // Antwortet mit "OK" 495 | server.send(200, "text/plain", "OK"); 496 | } 497 | 498 | // AJAX-Befehl /cmd/getCurrentStatus 499 | // Diese Funktion wird aufgerufen, um den aktuellen Status des Systems zu ermitteln und als JSON-Daten zurückzugeben. 500 | // Die JSON-Antwort enthält Informationen über: 501 | // - Die Lautstärke des Radios 502 | // - Den Alarmstatus und die Alarmzeit 503 | // - Den aktuellen Radiosender und Titel (wenn das Radio aktiv ist) 504 | // - Datum und Uhrzeit 505 | // - Die WLAN-Signalstärke 506 | // - Den Status des Sleeptimers (ob aktiv oder nicht) 507 | void getCurrentStatus() { 508 | // Variablen zur Zeitberechnung 509 | uint8_t h, m; 510 | char txt[50] = ""; 511 | 512 | // Erstellen eines JSON-Dokuments für die Antwort 513 | StaticJsonDocument<200> jsonDoc; 514 | 515 | // Lautstärke des Radios 516 | jsonDoc["gain"] = curGain; 517 | 518 | // Status des Alarms 519 | if (alarmday < 8) { // Alarm ist aktiv 520 | h = alarmtime / 60; 521 | m = alarmtime % 60; 522 | sprintf(txt, "%s %02i:%02i", days_short[alarmday], h, m); 523 | jsonDoc["alarm"] = "1"; 524 | } else { // Alarm ist ausgeschaltet 525 | sprintf(txt, "AUS"); 526 | jsonDoc["alarm"] = "0"; 527 | } 528 | jsonDoc["alarmtime"] = txt; 529 | 530 | // Radio-Status 531 | if (radio) { 532 | jsonDoc["radioStation"] = stationlist[actStation].name; 533 | jsonDoc["radioTitle"] = title; 534 | } else { 535 | jsonDoc["radioStation"] = ""; 536 | jsonDoc["radioTitle"] = ""; 537 | } 538 | 539 | // Aktuelles Datum und Uhrzeit 540 | char tim[40]; 541 | if (getLocalTime(&ti)) { 542 | sprintf(tim, "%s %i. %s %i", days[ti.tm_wday], ti.tm_mday, months[ti.tm_mon], ti.tm_year + 1900); 543 | jsonDoc["Date"] = tim; 544 | strftime(tim, sizeof(tim), "%H:%M", &ti); 545 | jsonDoc["Time"] = tim; 546 | } 547 | 548 | // WLAN-Signalstärke 549 | jsonDoc["Rssi"] = WiFi.RSSI(); 550 | 551 | // Status des Sleeptimers 552 | jsonDoc["Sleep"] = snoozeTimeEnd != 0 ? 1 : 0; 553 | 554 | // Konvertieren des JSON-Dokuments in einen String 555 | String response; 556 | serializeJson(jsonDoc, response); 557 | 558 | // Senden der JSON-Antwort an den Client 559 | server.send(200, "application/json", response); 560 | } 561 | 562 | //################ Info Tab 563 | // AJAX-Befehl /cmd/getInfo 564 | // Diese Funktion wird aufgerufen, um detaillierte Systeminformationen als JSON-Daten zurückzugeben. 565 | // Die JSON-Antwort enthält: 566 | // - Die installierte Version des Radios 567 | // - Informationen zum aktuellen ESP8266/ESP32-Chip, einschließlich: 568 | // - Heap-Größe und freier Heap-Speicher 569 | // - Sketch-Größe und freier Sketch-Speicher 570 | // - Chip-Modell 571 | void getInfo() { 572 | // Erstellen eines JSON-Dokuments für die Antwort 573 | StaticJsonDocument<300> jsonDoc; 574 | 575 | // Installierte Radio-Version 576 | jsonDoc["radioversion"] = RADIOVERSION; 577 | 578 | // Erstellen eines Unterobjekts für ESP-Board-Informationen 579 | JsonObject ESP_INFO = jsonDoc.createNestedObject("ESP_INFO"); 580 | 581 | // HEAP-Informationen 582 | JsonObject HEAP = ESP_INFO.createNestedObject("HEAP"); 583 | HEAP["getHeapSize"] = ESP.getHeapSize(); // Gesamte Heap-Größe 584 | HEAP["getFreeHeap"] = ESP.getFreeHeap(); // Freier Heap-Speicher 585 | 586 | // SKETCH-Informationen 587 | JsonObject SKETCH = ESP_INFO.createNestedObject("SKETCH"); 588 | SKETCH["getSketchSize"] = ESP.getSketchSize(); // Gesamte Sketch-Größe 589 | SKETCH["getFreeSketchSpace"] = ESP.getFreeSketchSpace(); // Freier Sketch-Speicher 590 | 591 | // CHIP-Informationen 592 | JsonObject CHIP = ESP_INFO.createNestedObject("CHIP"); 593 | CHIP["getChipModel"] = ESP.getChipModel(); // Modell des verwendeten Chips 594 | 595 | // Konvertieren des JSON-Dokuments in einen String 596 | String response; 597 | serializeJson(jsonDoc, response); 598 | 599 | // Senden der JSON-Antwort an den Client 600 | server.send(200, "application/json", response); 601 | } -------------------------------------------------------------------------------- /radiowecker/wlan.ino: -------------------------------------------------------------------------------- 1 | // Initialisiert das WiFi-Modul mit den angegebenen SSID und Passkey 2 | boolean initWiFi(String ssid, String pkey) { 3 | boolean connected = false; // Variable zur Verfolgung des Verbindungsstatus 4 | 5 | // Zuerst trennen alle bestehenden Verbindungen 6 | Serial.print(TXT_DISCONNECT); // Debug-Ausgabe, dass die Verbindung getrennt wird 7 | WiFi.disconnect(); // Trennt die aktuelle WiFi-Verbindung 8 | Serial.print(TXT_SOFT_AP_DISCONNECT); // Debug-Ausgabe, dass der Soft-AP-Modus getrennt wird 9 | WiFi.softAPdisconnect(true); // Trennt den Soft-AP-Modus, falls aktiv 10 | 11 | // Setzt den WiFi-Modus auf Station (Client) und konfiguriert den Hostnamen 12 | Serial.print(TXT_SET_WLAN_MODE); // Debug-Ausgabe, dass der WLAN-Modus gesetzt wird 13 | WiFi.setHostname(NETWORK_NAME); // Setzt den Hostnamen für das Gerät 14 | WiFi.mode(WIFI_STA); // Setzt den WiFi-Modus auf Station (Client) 15 | 16 | Serial.print(TXT_CONNECTING_TO); // Debug-Ausgabe, dass eine Verbindung zu einer SSID aufgebaut wird 17 | Serial.print(ssid); // Gibt die SSID auf der Konsole aus 18 | Serial.println(TXT_CONNECTING_ESTABLISH); // Debug-Ausgabe, dass die Verbindung aufgebaut wird 19 | Serial.println(pkey); // Gibt den Passkey auf der Konsole aus (Hinweis: Passkey nicht sicher in der Konsole ausgeben) 20 | 21 | // Wenn eine SSID angegeben wurde, versuche eine Verbindung herzustellen 22 | if (ssid != "") { 23 | WiFi.begin(ssid.c_str(), pkey.c_str()); // Beginnt den Verbindungsversuch zur angegebenen SSID mit dem Passkey 24 | uint8_t cnt = 0; // Zähler für die Anzahl der Versuche 25 | // Versuche bis zu 20 Mal, sich zu verbinden 26 | while ((WiFi.status() != WL_CONNECTED) && (cnt < 20)) { 27 | delay(500); // Warte 500 Millisekunden 28 | Serial.print("."); // Zeigt Fortschritt auf der Konsole an 29 | cnt++; // Erhöhe den Zähler 30 | } 31 | Serial.println(); // Neue Zeile für saubere Konsolenausgabe 32 | // Wenn die Verbindung erfolgreich hergestellt wurde 33 | if (WiFi.status() == WL_CONNECTED) { 34 | Serial.print(TXT_IP_ADDRESS); // Debug-Ausgabe der IP-Adresse 35 | Serial.println(WiFi.localIP()); // Gibt die lokale IP-Adresse auf der Konsole aus 36 | connected = true; // Setzt den Verbindungsstatus auf true 37 | } 38 | } 39 | 40 | // Wenn keine Verbindung hergestellt werden konnte 41 | if (!connected) { 42 | Serial.println(TXT_NO_CONNECTION); // Debug-Ausgabe, dass keine Verbindung hergestellt werden konnte 43 | WiFi.mode(WIFI_AP); // Setzt den WiFi-Modus auf Access Point (AP) 44 | WiFi.softAP(AP_NAME, "", 1); // Startet den Access Point mit dem angegebenen Namen und ohne Passwort 45 | } 46 | 47 | return connected; // Gibt den Verbindungsstatus zurück (true, wenn verbunden, sonst false) 48 | } -------------------------------------------------------------------------------- /screenshot/alarm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/alarm.jpg -------------------------------------------------------------------------------- /screenshot/info_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/info_tab.png -------------------------------------------------------------------------------- /screenshot/radio.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/radio.jpg -------------------------------------------------------------------------------- /screenshot/result.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/result.jpg -------------------------------------------------------------------------------- /screenshot/settings.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/settings.jpg -------------------------------------------------------------------------------- /screenshot/settings_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/settings_color.png -------------------------------------------------------------------------------- /screenshot/website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/website.png -------------------------------------------------------------------------------- /screenshot/website_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/website_2.png -------------------------------------------------------------------------------- /screenshot/website_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/website_3.png -------------------------------------------------------------------------------- /screenshot/website_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/website_4.png -------------------------------------------------------------------------------- /screenshot/wetter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beabel/radiowecker/f4736b45edb06e1a302fbad1fbc28fd7676b7e6a/screenshot/wetter.jpg --------------------------------------------------------------------------------