diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 00000000..602da6ad --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,65 @@ +# This is the name of the workflow, visible on GitHub UI. +name: building + +# Here we tell GitHub to run the workflow when a commit +# is pushed or a Pull Request is opened. +on: [push, pull_request] + +# This is the list of jobs that will be run concurrently. +# Since we use a build matrix, the actual number of jobs +# started depends on how many configurations the matrix +# will produce. +jobs: + # This is the name of the job - can be whatever. + test-matrix: + + # Here we tell GitHub that the jobs must be determined + # dynamically depending on a matrix configuration. + strategy: + matrix: + # The matrix will produce one job for each configuration + # parameter of type `arduino-platform`, in this case a + # total of 2. + arduino-platform: ["arduino:avr"] + # This is usually optional but we need to statically define the + # FQBN of the boards we want to test for each platform. In the + # future the CLI might automatically detect and download the core + # needed to compile against a certain FQBN, at that point the + # following `include` section will be useless. + include: + # This works like this: when the platformn is "arduino:samd", the + # variable `fqbn` is set to "arduino:samd:nano_33_iot". + - arduino-platform: "arduino:avr" + fqbn: "arduino:avr:nano:cpu=atmega328old" + + # This is the platform GitHub will use to run our workflow, we + # pick Windows for no particular reason. + runs-on: ubuntu-latest + + # This is the list of steps this job will run. + steps: + # First of all, we clone the repo using the `checkout` action. + - name: Checkout + uses: actions/checkout@v2 + with: + ref: DEV + + # We use the `arduino/setup-arduino-cli` action to install and + # configure the Arduino CLI on the system. + - name: Setup Arduino CLI + uses: arduino/setup-arduino-cli@v1.0.0 + + - name: Install Python + uses: actions/setup-python@v1 + with: + python-version: 3.8 + + # We then install the platform, which one will be determined + # dynamically by the build matrix. + - name: Install platform + run: make install init + + # Finally, we compile the sketch, using the FQBN that was set + # in the build matrix. + - name: Test Sketch + run: make test diff --git a/.gitignore b/.gitignore index 0aab59b2..d424bc4a 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,9 @@ Temporary Items # TonUINO /tools/*.pyc +Tonuino + +# Platform.io +.pio/ +.vscode/ +platformio_local.ini diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..a53176ca --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,42 @@ +# Change Log + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] - Lokale Änderungen +- Unterstützung für GitHub Actions, um jede eingespielte Änderung zu testen (siehe Badge oben). +- Integration von PlatformIO inklusive initiale Unterstützung von Unit Tests und eigenen Konfigurationsdateien. +- Entfernung einiger [Compiler-Warnungen](https://github.com/xfjx/TonUINO/pull/54). +- Kleinen Fehler bei Erstinbetriebnahme [gefixt](http://discourse.voss.earth/t/version-2-1dev-lautstaerke-durch-langes-druecken-der-tasten-geht-nicht/4523/23). +- Verzögerung für Lautstärkeregelung [hinzugefügt](http://discourse.voss.earth/t/lautstaerke-kleinschrittiger-erhoehen/3022/5). +- Make-Datei hinzugefügt + +## [Unreleased] - 2.1dev +- Partymodus hat nun eine Queue -> jedes Lied kommt nur genau 1x vorkommt +- Neue Wiedergabe-Modi "Spezialmodus Von-Bis" - Hörspiel, Album und Party -> erlaubt z.B. verschiedene Alben in einem Ordner zu haben und je mit einer Karte zu verknüpfen +- Admin-Menü +- Maximale, Minimale und Initiale Lautstärke +- Karten werden nun über das Admin-Menü neu konfiguriert +- die Funktion der Lautstärketasten (lauter/leiser oder vor/zurück) kann im Adminmenü vertauscht werden +- Shortcuts können konfiguriert werden! +- Support für 5 Knöpfe hinzugefügt +- Reset der Einstellungen ins Adminmenü verschoben +- Modikationskarten (Sleeptimer, Tastensperre, Stopptanz, KiTa-Modus) +- Admin-Menü kann abgesichert werden + +## [2.0.1] - 2018-11-01 +- kleiner Fix um die Probleme beim Anlernen von Karten zu reduzieren + +## [2.0] - 2018-08-26 +- Lautstärke wird nun über einen langen Tastendruck geändert +- bei kurzem Tastendruck wird der nächste / vorherige Track abgespielt (je nach Wiedergabemodus nicht verfügbar) +- Während der Wiedergabe wird bei langem Tastendruck auf Play/Pause die Nummer des aktuellen Tracks angesagt +- Neuer Wiedergabemodus: **Einzelmodus** + Eine Karte kann mit einer einzelnen Datei aus einem Ordner verknüpft werden. Dadurch sind theoretisch 25000 verschiedene Karten für je eine Datei möglich +- Neuer Wiedergabemodus: **Hörbuch-Modus** + Funktioniert genau wie der Album-Modus. Zusätzlich wir der Fortschritt im EEPROM des Arduinos gespeichert und beim nächsten mal wird bei der jeweils letzten Datei neu gestartet. Leider kann nur der Track, nicht die Stelle im Track gespeichert werden +- Um mehr als 100 Karten zu unterstützen wird die Konfiguration der Karten nicht mehr im EEPROM gespeichert sondern direkt auf den Karten - die Karte muss daher beim Anlernen aufgelegt bleiben! +- Durch einen langen Druck auf Play/Pause kann **eine Karte neu konfiguriert** werden +- In den Auswahldialogen kann durch langen Druck auf die Lautstärketasten jeweils um 10 Ordner oder Dateien vor und zurück gesprungen werden +- Reset des MP3 Moduls beim Start entfernt - war nicht nötig und hat "Krach" gemacht + diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..509cfc89 --- /dev/null +++ b/Makefile @@ -0,0 +1,97 @@ +# +# TonUINO Makefile +# +# Author: Alexander Willner +# Date: 2020-01-03 + +# Config +## Arduino Nano (old bootloader) +MCU ?= arduino:avr:nano:cpu=atmega328old +BOARD ?= arduino:avr +SERIAL ?= /dev/cu.usbserial-1420 +## Main +SKETCH ?= Tonuino +## Helper +OS = $(shell uname -s) +.PHONY: help + +info: + $(info TonUINO Makefile) + $(info ================) + $(info ) + $(info Configured to use MCU "$(MCU)" attached to port "$(SERIAL)".) + $(info ) + $(info Available commands:) + $(info - help : get support from the community) + $(info - install : installation of required binaries (arduino-cli)) + $(info - init : initialize environment (arduino-cli)) + $(info - compile : create binary) + $(info - upload : store binary on board flash) + $(info - find : get information about the pluged-in board) + $(info - test : run some basic tests on the code) + $(info - clean : delete temporary files) + $(info - feedback : provide feedback and report issues) + @true + +help: + @python -m webbrowser "http://discourse.voss.earth" + +install: +ifeq ($(OS),Darwin) +ifeq (, $(shell which brew)) + $(error "No brew in PATH, consider installing http://brew.sh") +else + @brew install platformio arduino-cli +endif +endif +ifeq ($(OS),Linux) +ifeq (, $(shell which arduino-cli)) + @curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh +endif +ifeq (, $(shell which platformio)) + @pip install setuptools wheel + @pip install -U platformio +endif +endif + +init: + @arduino-cli config init + @arduino-cli core update-index + @arduino-cli core install $(BOARD) + @arduino-cli lib install "DFPlayer Mini Mp3 by Makuna" + @arduino-cli lib install "MFRC522" + @arduino-cli lib install "JC_Button" + @platformio lib install 1561 # DFPlayer Mini Mp3 by Makuna + @platformio lib install 2284 # EEPROM + @platformio lib install 77 # JC_Button + @platformio lib install 63 # MFRC522 + +prepare: + @mkdir -p "$(SKETCH)" ; echo "folder is only for backwards compatibility" > "$(SKETCH)/DO-NOT-EDIT" + @if [ "$(SKETCH)/$(SKETCH).ino" -nt "./$(SKETCH).ino" ]; then echo "ERROR: do not edit files in TonUINO/!"; exit 1; fi; + @cp -p "./$(SKETCH).ino" "$(SKETCH)/$(SKETCH).ino" + +compile: prepare *.ino + @arduino-cli compile --fqbn $(MCU) --warnings none "$(SKETCH)" + +find: + @arduino-cli board list + +upload: compile + @arduino-cli upload -p $(SERIAL) --fqbn $(MCU) --verify "$(SKETCH)" + +test: prepare + @arduino-cli compile --fqbn $(MCU) --warnings more "$(SKETCH)" +ifneq (, $(shell which pio)) + @pio test -e native +endif + +check: *.ino + @cppcheck --enable=all --std=c++20 --language=c++ *.ino *.h + +clean: + @rm -rf "$(SKETCH)" + @rm -rf ".pio/build/" + +feedback: + @python -m webbrowser "https://github.com/alexanderwillner/tonuino/issues" \ No newline at end of file diff --git a/README.md b/README.md index a9a56be3..0ccc177e 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,172 @@ # TonUINO -Die DIY Musikbox (nicht nur) für Kinder - - -# Change Log - -## Version 2.1 (xx.xx.xxxx) noch WIP -- Partymodus hat nun eine Queue -> jedes Lied kommt nur genau 1x vorkommt -- Neue Wiedergabe-Modi "Spezialmodus Von-Bis" - Hörspiel, Album und Party -> erlaubt z.B. verschiedene Alben in einem Ordner zu haben und je mit einer Karte zu verknüpfen -- Admin-Menü -- Maximale, Minimale und Initiale Lautstärke -- Karten werden nun über das Admin-Menü neu konfiguriert -- die Funktion der Lautstärketasten (lauter/leiser oder vor/zurück) kann im Adminmenü vertauscht werden -- Shortcuts können konfiguriert werden! -- Support für 5 Knöpfe hinzugefügt -- Reset der Einstellungen ins Adminmenü verschoben -- Modikationskarten (Sleeptimer, Tastensperre, Stopptanz, KiTa-Modus) -- Admin-Menü kann abgesichert werden - -## Version 2.01 (01.11.2018) -- kleiner Fix um die Probleme beim Anlernen von Karten zu reduzieren - -## Version 2.0 (26.08.2018) - -- Lautstärke wird nun über einen langen Tastendruck geändert -- bei kurzem Tastendruck wird der nächste / vorherige Track abgespielt (je nach Wiedergabemodus nicht verfügbar) -- Während der Wiedergabe wird bei langem Tastendruck auf Play/Pause die Nummer des aktuellen Tracks angesagt -- Neuer Wiedergabemodus: **Einzelmodus** - Eine Karte kann mit einer einzelnen Datei aus einem Ordner verknüpft werden. Dadurch sind theoretisch 25000 verschiedene Karten für je eine Datei möglich -- Neuer Wiedergabemodus: **Hörbuch-Modus** - Funktioniert genau wie der Album-Modus. Zusätzlich wir der Fortschritt im EEPROM des Arduinos gespeichert und beim nächsten mal wird bei der jeweils letzten Datei neu gestartet. Leider kann nur der Track, nicht die Stelle im Track gespeichert werden -- Um mehr als 100 Karten zu unterstützen wird die Konfiguration der Karten nicht mehr im EEPROM gespeichert sondern direkt auf den Karten - die Karte muss daher beim Anlernen aufgelegt bleiben! -- Durch einen langen Druck auf Play/Pause kann **eine Karte neu konfiguriert** werden -- In den Auswahldialogen kann durch langen Druck auf die Lautstärketasten jeweils um 10 Ordner oder Dateien vor und zurück gesprungen werden -- Reset des MP3 Moduls beim Start entfernt - war nicht nötig und hat "Krach" gemacht + +Die DIY Musikbox (nicht nur) für Kinder. + +[![GitHub Actions | AlexanderWillner/tonuino](https://github.com/AlexanderWillner/tonuino/workflows/building/badge.svg)](https://github.com/AlexanderWillner/tonuino/actions?workflow=building) [![license](https://img.shields.io/github/license/alexanderwillner/tonuino)](https://github.com/AlexanderWillner/TonUINO/blob/DEV/LICENSE) [![download](https://img.shields.io/github/downloads/AlexanderWillner/TonUINO/total)](https://github.com/AlexanderWillner/TonUINO/releases) + +- [TonUINO](#tonuino) + - [English Readers (für unsere englischsprachige Leserschaft)](#english-readers-f%c3%bcr-unsere-englischsprachige-leserschaft) + - [Zusammenfassung](#zusammenfassung) + - [Drei Bausteine](#drei-bausteine) + - [Mikrocontroller-Hardware](#mikrocontroller-hardware) + - [Notwendige Grundausstattung (ca. 30 EUR)](#notwendige-grundausstattung-ca-30-eur) + - [Optionale erweiterte Hardwareausstattung](#optionale-erweiterte-hardwareausstattung) + - [Systemnahe Programmierung](#systemnahe-programmierung) + - [Für Benutzer](#f%c3%bcr-benutzer) + - [Für Entwickler](#f%c3%bcr-entwickler) + - [Gehäusebau](#geh%c3%a4usebau) + - [Notwendige Grundausstattung](#notwendige-grundausstattung) + - [Optionale erweiterte Gehäuseausstattung](#optionale-erweiterte-geh%c3%a4useausstattung) + +## English Readers (für unsere englischsprachige Leserschaft) + +For various reasons, we've decided to write this guide in German only. However, you can copy the text from this web page and paste it to [DeepL](https://www.deepl.com/) to easily translate the whole documentation at once. + +## Zusammenfassung + +Kinder zu beschenken ist nie einfach. Das Ziel des Projektes [TonUINO](https://www.voss.earth/tonuino/) von [Thorsten Voss](https://www.voss.earth/ueber-mich/) ist es, eine “Musikbox (nicht nur) für Kinder” selbst zu bauen. Es macht einen riesigen Spaß, die meisten Kinder sind begeistert und diese Seite soll der großartigen Community etwas wieder geben. Denn so gut die [Webseite](https://www.voss.earth/tonuino/), das [Forum](http://discourse.voss.earth/) und die [Videos](https://www.youtube.com/channel/UCeXF2J1Pz8b1plIne-jQy1A) auch sind, der Bau der ersten Box(en) wäre mit weniger Zeitaufwand möglich. + +Insbesondere unterstützt diese Anleitung hier “Newbies” bei der Auswahl der Hardware, geht sequenzieller durch die notwendigen Schritte, beinhaltet Links zu den wichtigsten Informationsquellen und optimiert den Code für Softwareentwickler. Hoffentlich werden diese Anregungen hier irgendwann in die offizielle Dokumentation aufgenommen und machen diese Seite damit zukünftig überflüssig. Jede Art von [Pull Requests](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) oder [Issues](https://github.com/alexanderwillner/tonuino/issues), die die Dokumentation oder den Code gemeinsam verbessern, sind mehr als willkommen! + +## Drei Bausteine + +Es ist wichtig zu wissen, dass die Kunst ein TonUINO zu bauen grundsätzlich als ein Zusammenspiel von drei unterschiedlichen Disziplinen angesehen werden kann: [Mikrocontroller-Hardware](#mikrocontroller-hardware), [systemnahe Programmierung](#systemnahe-programmierung) und [Gehäusebau](#geh%c3%a4usebau). Im Folgenden wird für jeden der Bereiche die notwendige Grundausstattung und sinnvolle Erweiterungen sehr knapp vorgestellt. Das [Forum](http://discourse.voss.earth/) ist ein Quell vieler weiterer Ideen. + +### Mikrocontroller-Hardware + +Es muss gelötet werden. Wir gehen davon aus, dass Lötkolben, Lötzinn und Löterfahrung vorhanden sind. Eine sehr gute Anleitung gibt es bei [YouTube](https://www.youtube.com/watch?v=RmE09dsY-l0) und einen Schaltplan auf der [offiziellen Webseite](https://www.voss.earth/tonuino/). Da hier jedoch die genaue Orientierung der Pins nicht ersichtlich ist, hilft auch noch ein alternativer Schaltplan von [dieser Webseite](https://smarthomeyourself.de/anleitung-zum-selber-bauen/unabhaengige-projekte/tonuino-der-kinderfreundliche-rfid-audio-player/), um die richtigen Pins zu identifizieren. Auf Basis eines [Forum-Beitrages](http://discourse.voss.earth/t/einfacher-schaltplan/5021) im Folgenden eine tabellarische Übersicht: + +| Text | Pin | Gerät | Ardunio: Pin | Ardunio: Text | Ardunio: Text | Ardunio: Pin | Gerät | Pin | Test | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| | | | 01 | D0 | Vin | 30 | | | | +| | | | 02 | D1 | GND | 29 | RFID | 6 | GND | +| | | | 03 | | | 28 | | | | +| GND | 10 | MP3 | 04 | GND | 5V | 27 | | | | +| TX | 3 | MP3 | 05 | D2 | A7 | 26 | | | | +| RX | 2 | MP3 | 06 | D3 | A6 | 25 | | | | +| BSY | 16 | MP3 | 07 | D4 | A5 | 24 | | | | +| | | | 08 | D5 | A4 | 23 | | | | +| | | | 09 | D6 | A3 | 22 | | | | +| | | | 10 | D7 | A2 | 21 | Knopf | 3 | - | +| | | | 11 | D8 | A1 | 20 | Knopf | 2 | + | +| RST | 7 | RFID | 12 | D9 | A0 | 19 | Knopf | 1 | Play | +| SDA | 1 | RFID | 13 | D10 | REF | 18 | | | | +| MOSI | 3 | RFID | 14 | D11 | 3,3V | 17 | RFID | 8 | 3,3V | +| MISO | 4 | RFID | 15 | D12 | D13 | 16 | RFID | 2 | SCK | + +Die passenden Abbildungen: + +![PIN-Belegung](TonUINO_PINs.jpg) ![PIN-Schaltplan](TonUINO_Schaltplan.png) + +#### Notwendige Grundausstattung (ca. 30 EUR) + +Die notwendigen Komponenten können über Reichelt, Conrad, Amazon, E-Bay oder Alibaba bezogen werden. Meist lohnt sich jetzt schon die Planung von mehreren TonUINO-Boxen. Im Folgenden Amazon-Affiliate-Links von Komponenten, die Thorsten und andere aus der Community erfolgreich verbaut haben. In der [Community Hardware FAQ](https://discourse.voss.earth/t/faq-kategorie-hardware/926/2) gibt es weitere wertvolle Hinweise. + +| Anzahl | Produkt | Beschreibung | Hinweis | Kosten | +| --- | --- | --- | --- | --- | +| 1 | [TonUINO Set](https://amzn.to/2pHTJQ3) | Die Hauptkomponenten | Sollte das Set ausverkauft sein, im Folgenden die vier Komponenten | ca. xx EUR / Stück | +| (1)| [Arduino Nano](https://amzn.to/2mQNHaY) | Zum Ansteuern | Es können auch andere Arduino-Varianten gekauft werden | ca. 4 - 8 EUR / Stück | +| (1) | [DFPlayer Mini](https://amzn.to/2K2JavA) | Zum Abspielen der Musik | Dieser Player ist recht empfindlich was die genaue Bespielung der SD-Karte angeht | ca. 3-6 EUR / Stück | +| (1) | [RFID Kit RC522](http://amzn.to/2FnyHJj) | Zum Lesen und Beschreiben der NFC-Karten | | ca. 2-6 EUR / Stück | +| (4) | [RFID-Karten](https://amzn.to/2NXZQuL) | Zur Auswahl der Musik | müssen im 13,56 MHz Band funken | ca. 0,40 - 0,80 EUR / Stück | +| 1 | [Passiver Lautsprecher](https://amzn.to/381ama6) | Zum Anhören der Musik | z.B. ein Regallautsprecher oder etwas kleineres | ca. 2-50 EUR / Stück | +| 1 | [MicroSD-Karte](http://amzn.to/2oXOxDw) | Zum Speichern der Musik | Maximal 32 GB | ca. 4-6 EUR / Stück | +| 3 | [Knöpfe](https://amzn.to/2mRnyZC) | Zum starten/stoppen, lauter/leiser stellen, ... | Es gibt auch Varianten mit 5 Knöpfen. Knöpfe mit eingebauter LED haben weitere Vorteile. | ca. 0,50 EUR / Stück | +| 20 | [Kabel](https://amzn.to/3bL6M74) | Zum Verbinden | Der Bedarf an Kabeln kann schnell nach oben gehen (siehe Erweiterungen unten) | ca. 0,05 EUR / Stück | +| 1 | [1K Resistor](https://amzn.to/3bH3rWA) | zum X | Einzeln zu kaufen ggf. recht teuer | ca. 0,01 EUR / Stück | + +#### Optionale erweiterte Hardwareausstattung + +| Anzahl | Produkt | Beschreibung | Hinweis | Kosten | +| --- | --- | --- | --- | --- | +| 1 | [TonUINO-Platine](http://discourse.voss.earth/t/neue-platine-version-1-51/63) | Für weniger Kabelsalat. Enthält auch die o.g. Kabel und den Resistor. Wird auch in der o.g. YouTube-Anleitung genutzt. | Kann von Thorsten [per E-Mail](TonUINO@voss.earth) bestellt werden | ca. 10 EUR / Stück +| 1 | [Köpfhörer-Platine](http://discourse.voss.earth/t/kopfhoererbuchsenplatine/2463) | Zum Anschluss von Kopfhörern |Kann von Thorsten [per E-Mail](TonUINO@voss.earth) bestellt werden. Alternativ [der klassische Weg](https://discourse.voss.earth/t/kopfhoereranschluss-moeglich/96/84). | ca. 7,50 EUR / Stück +| 1 | [Akku](https://amzn.to/2Stuvki) | Zum Kabellosen Betrieb | Dazu gibt es einige [Diskussionen](http://discourse.voss.earth/c/stromversorgung/5) und Alternativen (z.B. Wemos Battery Shield). Gute Erfahrungen gibt es mit dem Hersteller RAVPower. Wichtige Eigenschaften: power pass trough, automatische Abschaltung. | ca. 15 EUR / Stück | +| 1 | [Micro-SD-Verlängerung](https://amzn.to/2Svbu0N) | Zum Austausch der SD-Karte von außen | Je nachdem wie das Gehäuse gebaut ist. Auch könnte eine externe USB-Buchse genutzt werden, [um MP3-Dateien aufzuspielen](http://discourse.voss.earth/t/daten-auf-sd-kopieren-ueber-usb-anschluss/2185/8). Das Kabel kann allerdings unter Umständen die [Autoabschaltung verhindern](https://discourse.voss.earth/t/sd-verlaengerungskabel-verhindert-poweroff/1780/4). | ca. 3 EUR / Stück | +| 1 | [USB-Buchse](https://amzn.to/37yji6e) | Zum Aufladen bei Akkubetrieb | [Kein einfaches Thema](http://discourse.voss.earth/t/micro-usb-buchse-fuer-das-gehaeuse/3280/14) und kann sowohl zum Aufladen als auch für ein [Firmware-Upgrade](http://discourse.voss.earth/t/benoetige-hilfe-bei-der-trennung-von-daten-und-strom-des-usb-kabels/975) oder zum [MP3-Aktualisieren](http://discourse.voss.earth/t/daten-auf-sd-kopieren-ueber-usb-anschluss/2185/8) gleichzeitig genutzt werden. | ca. 4-20 EUR / Stück | +| 1 | [Ein- und Ausschalter](https://amzn.to/37yiVsm) | Zum Strom sparen und Wiederbeleben bei Akkubetrieb | Ein Schalter mit Lichtindikator erscheint sinnvoll [für eine gewisse Grundlast](http://discourse.voss.earth/t/grundlast-erhoehen-um-powerbank-nicht-autom-abzuschalten/1899/9) | ca. 0,50-20 EUR / Stück| +| Mehrere | [Etiketten](https://amzn.to/2R0eHSL) | Zum Bekleben der NFC-Karten, denn diese müssen irgendwie auseinandergehalten werden | Es gibt ganz viele weitere Varianten zum Bedrucken. Am Ende sollte ein [DIN EN71-3 Klarlack](https://amzn.to/38t4xmM) aufgetragen werden. Ein einfacher Edding zum Beschriften reicht jedoch auch.| ca. 0,80 EUR / Stück| +| 1 | [Bluetooh-Sender](https://amzn.to/2SvbcqJ) | Zum Anschluss von kabellosen Kopfhörern | Details zum Anschluss im Forum [hier](http://discourse.voss.earth/t/hoerbuch-fuer-meine-frau/4344/3) oder [hier](http://discourse.voss.earth/t/erweiterung-anschluss-bluetooth-kopfhoerer-vorerst-theorie/3556/14). | ca. 19 EUR / Stück | + +Es gibt zahllose weitere Ergänzungen, wie [LED-Stripes](http://discourse.voss.earth/t/integration-led-strip-und-ring-mit-neopixel/2760) etc. pp. Positive Erfahrungen sollten gerne in diese Liste hier integriert werden. + +### Systemnahe Programmierung + +Es muss nicht unbedingt programmiert werden. Die Installation der Firmware auf den Arduino ist sehr einfach. Die Anleitung auf der [offiziellen Webseite](https://www.voss.earth/tonuino/) ist gut. Wenn jedoch mehr Knöpfe angesprochen werden sollen (siehe oben), muss die Software auch geringfügig angepasst werden. + +Es gibt zwar, wie bei jeder Software, ein paar kleine Software-Fehler, die jedoch in [unterschiedlichen Branches](https://github.com/xfjx/TonUINO/network) gefixt wurden. Ziel ist es, diese Änderungen in so wenigen Branches wie möglich pflegen zu müssen. + +#### Für Benutzer + +Als einfacher Benutzer sollte die Programmierung so einfach gestaltet sein wie möglich. Im Folgenden die notwendigen Schritte. Eine [Community Software FAQ](https://discourse.voss.earth/t/faq-kategorie-software/924) gibt weitere Hilfestellungen. Unten gibt es einen Ablauf als Video. + +1. Download [der aktuellen Firmware](https://github.com/AlexanderWillner/TonUINO/releases/latest/download/TonUINO.zip). +2. Die Datei `TonUINO.zip` landet dann im `Download`-Verzeichnis und muss mit einem Doppelklick entpackt werden. Es sollte dann ein Verzeichnis `TonUINO` existieren, in der sich die Datei `Tonuino.ino` befindet. +3. Anschließend muss die [Arduino GUI](https://www.arduino.cc/en/main/software) herunter geladen und installiert werden (unter macOS mit [Homebrew](http://brew.sh) einfach über `brew cask install arduino`). +4. Nach dem Starten der Arduino GUI muss die o.g. Datei geöffnet werden und notwendige Bibliotheken herunter geladen werden. Unter `Werkzeuge` und dann `Bibliotheken Verwalten` folgende Pakete suchen und installieren: + 1. `JC_Button` (von dem Entwickler `Jack Christiansen`) + 2. `DFPlayer Mini Mp3` (von dem Entwickler `Makuna`) + 3. `MFRC522` (von dem Entwickler `GitHubCommunity`) +5. Nun unter `Werkzeuge` und dann + 1. `Board` den Punkt `Arduino Nano` auswählen + 2. `Prozessor` den Punkt `ATmega328P (Old Bootloader)` auswählen + 3. `Port` den Punkt `/dev/cu.wchusbserial???` auswählen (je nach Betriebssystem könnte es anders aussehen) +6. Nun kann die Software unter `Sketch` und dann `Hochladen` auf den Arduino hoch geladen werden. + +Kurzanleitung zum Aufspielen der Firmware für Benutzer (auf das Video klicken): + +[![Kurzanleitung zum Aufspielen der Firmware für Benutzer](https://j.gifs.com/3Q0rM4.gif)](https://youtu.be/OxXnBpHxEyY) + +Darüber hinaus muss noch die SD-Karte vorbereitet werden: + +1. Die Karte mit FAT32 formatieren. +2. Die Ordner `mp3` und `advert` aus dem Ordner `sd-card` müssen auf die SD-Karte kopiert werden. Skripte wie `create-soundfiles.sh` brauchen gar nicht ausgeführt werden. +3. Auf der SD-Karte müssen die Ordner für die Musik erstellt werden (ohne Lücken beginnend mit `01`, dann ggf. `02`, ...) und die MP3-Dateien der Lieder müssen ohne Lücken nummeriert werden (mit `001`, dann ggf. `002`, ...). +4. Die Codierung der NFC-Karten und des Admin-Menüs wird durch [die Videos](https://www.youtube.com/channel/UCeXF2J1Pz8b1plIne-jQy1A) deutlich und sind weitestgehend selbsterklärend. + +#### Für Entwickler + +Der Ablauf für Entwickler sieht etwas anders aus und dieses Repository hat sich zum Ziel gesetzt, insbesondere diese Zielgruppe mit zu unterstützen. Insbesondere die Unterstützung von [Arduino CLI](https://github.com/arduino/arduino-cli),[PlatformIO](https://platformio.org) und [GitHub Actions](https://github.com/AlexanderWillner/tonuino/actions?workflow=building) wurde umgesetzt. Für diese Zielgruppe sollte insbesondere das `Makefile` eine Hilfe sein, die alle o.g. Punkte und weitere Aspekte automatisiert: + +```text + +$ make +TonUINO Makefile +================ + + Configured to use MCU "arduino:avr:nano:cpu=atmega328old" attached to port "/dev/cu.usbserial-1410". + +Available commands: +- help : get support from the community +- install : installation of required binaries (arduino-cli) +- init : initialize environment (arduino-cli) +- compile : create binary +- upload : store binary on board flash +- find : get information about the pluged-in board +- test : run some basic tests on the code +- clean : delete temporary files +- feedback : provide feedback and report issues +``` + +Kurzanleitung zum Aufspielen der Firmware für Entwickler: + +[![Kurzanleitung zum Aufspielen der Firmware für Entwickler](https://asciinema.org/a/yduPdLWRVGB7ZifyKckmnVFFu.png)](https://asciinema.org/a/yduPdLWRVGB7ZifyKckmnVFFu) + +Darüber hinaus gibt es + +- auf der [offiziellen Webseite](https://www.voss.earth/tonuino/) und im Repository noch einige nützliche Skripte, die noch nicht in das `Makefile` integriert sind +- [Firmware-Alternativen](https://github.com/seisfeld/TonUINO), die je nach Planung ggf. weitere notwendige Features unterstützen +- die [Fritzing GUI](https://fritzing.org/), um kompliziertere Aufbauten zunächst am Rechner zu visualisieren und zu planen (unter macOS mit [Homebrew](http://brew.sh) einfach über `brew cask install fritzing`) +- ein [change log](CHANGELOG.md), die Änderungen der Software dokumentiert + +### Gehäusebau + +Man sollte kreativ werden. Nach dem Zusammenbau der Hardware, dem Aufspielen der Firmware, dem Befüllen der SD-Karte und der Codierung der ersten NFC-Karte, kann man direkt loslegen. Allerdings ist so ein Kabelsalat weder hübsch noch Kind-gerecht. + +#### Notwendige Grundausstattung + +Eine stabile Pappschachtel (z.B. die Verpackung des Mobiltelefons oder eine Taschentuchbox) zusammen mit einem günstigen Lautsprecher oder eine fertige Lautsprecherbox aus Holz. Eine Heißklebepistole oder doppelseitiges Klebeband können zum besten Freund werden. + +#### Optionale erweiterte Gehäuseausstattung + +Es gibt erstaunliche Arbeiten, die z.B. in der [Gallerie](http://discourse.voss.earth/t/tonuino-gehaeuse-galerie/786/27) aufgeführt sind, und hier kommt die eigentliche Kreativität zum Einsatz ([Stofftiere](http://discourse.voss.earth/t/die-musikeule-ein-stofftier-mit-kick/2541), [Schatzkisten](http://discourse.voss.earth/t/vorstellung-musik-schatzkiste/2641), [LED-bestückte Jukeboxen](http://discourse.voss.earth/t/vorstellung-marabox-bambus-3d-druck-neopixel-ring/4608/22), ...). Hier kann mit einem 3D-Drucker kann das eigene Projekt natürlich noch auf eine ganz andere Ebene gehoben werden. diff --git a/TonUINO_PINs.jpg b/TonUINO_PINs.jpg new file mode 100644 index 00000000..1d72fd58 Binary files /dev/null and b/TonUINO_PINs.jpg differ diff --git a/TonUINO_Schaltplan.png b/TonUINO_Schaltplan.png new file mode 100644 index 00000000..a80f1a0c Binary files /dev/null and b/TonUINO_Schaltplan.png differ diff --git a/Tonuino.ino b/Tonuino.ino index ac359337..9b38e7a1 100644 --- a/Tonuino.ino +++ b/Tonuino.ino @@ -20,6 +20,12 @@ // uncomment the below line to enable five button support //#define FIVEBUTTONS +// uncomment the below line to stop playback when card is removed +//#define PAUSEONCARDREMOVAL + +// delay for volume buttons +#define LONG_PRESS_DELAY 300 + static const uint32_t cardCookie = 322417479; // DFPlayer Mini @@ -48,6 +54,9 @@ struct nfcTagObject { // uint8_t special2; }; +bool card_present = false; +bool card_present_prev = false; + // admin settings stored in eeprom struct adminSettings { uint32_t cookie; @@ -75,6 +84,7 @@ uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, bool preview = false, int previewFromFolder = 0, int defaultValue = 0, bool exitWithLongPress = false); bool isPlaying(); bool checkTwo ( uint8_t a[], uint8_t b[] ); +bool readCard(nfcTagObject *nfcTag); void writeCard(nfcTagObject nfcTag); void dump_byte_array(byte * buffer, byte bufferSize); void adminMenu(bool fromCard = false); @@ -156,7 +166,7 @@ void resetSettings() { mySettings.eq = 1; mySettings.locked = false; mySettings.standbyTimer = 0; - mySettings.invertVolumeButtons = true; + mySettings.invertVolumeButtons = false; mySettings.shortCuts[0].folder = 0; mySettings.shortCuts[1].folder = 0; mySettings.shortCuts[2].folder = 0; @@ -290,6 +300,8 @@ class SleepTimer: public Modifier { Serial.println(F("== SleepTimer::getActive()")); return 1; } + + virtual ~SleepTimer() {} }; class FreezeDance: public Modifier { @@ -705,7 +717,7 @@ bool isPlaying() { } void waitForTrackToFinish() { - long currentTime = millis(); + unsigned long currentTime = millis(); #define TIMEOUT 1000 do { mp3.loop(); @@ -753,7 +765,7 @@ void setup() { delay(2000); volume = mySettings.initVolume; mp3.setVolume(volume); - mp3.setEq(mySettings.eq - 1); + mp3.setEq(DfMp3_Eq(mySettings.eq - 1)); // Fix für das Problem mit dem Timeout (ist jetzt in Upstream daher nicht mehr nötig!) //mySoftwareSerial.setTimeout(10000); @@ -781,7 +793,7 @@ void setup() { if (digitalRead(buttonPause) == LOW && digitalRead(buttonUp) == LOW && digitalRead(buttonDown) == LOW) { Serial.println(F("Reset -> EEPROM wird gelöscht")); - for (int i = 0; i < EEPROM.length(); i++) { + for (unsigned int i = 0; i < EEPROM.length(); i++) { EEPROM.update(i, 0); } loadSettingsFromFlash(); @@ -811,6 +823,7 @@ void volumeUpButton() { if (volume < mySettings.maxVolume) { mp3.increaseVolume(); volume++; + delay(LONG_PRESS_DELAY); } Serial.println(volume); } @@ -824,6 +837,7 @@ void volumeDownButton() { if (volume > mySettings.minVolume) { mp3.decreaseVolume(); volume--; + delay(LONG_PRESS_DELAY); } Serial.println(volume); } @@ -944,7 +958,28 @@ void playShortCut(uint8_t shortCut) { } void loop() { + int _rfid_error_counter = 0; + do { + +#ifdef PAUSEONCARDREMOVAL + // auf Lesefehler des RFID Moduls prüfen + _rfid_error_counter += 1; + if(_rfid_error_counter > 2){ + card_present = false; + } + + // Ist eine Karte aufgelegt? + byte bufferATQA[2]; + byte bufferSize = sizeof(bufferATQA); + MFRC522::StatusCode result = mfrc522.PICC_RequestA(bufferATQA, &bufferSize); + + if(result == mfrc522.STATUS_OK){ + _rfid_error_counter = 0; + card_present = true; + } +#endif + checkStandbyAtMillis(); mp3.loop(); @@ -972,7 +1007,7 @@ void loop() { if (activeModifier != NULL) if (activeModifier->handlePause() == true) return; - if (ignorePauseButton == false) + if (ignorePauseButton == false) { if (isPlaying()) { mp3.pause(); setstandbyTimer(); @@ -981,6 +1016,7 @@ void loop() { mp3.start(); disablestandbyTimer(); } + } ignorePauseButton = false; } else if (pauseButton.pressedFor(LONG_PRESS) && ignorePauseButton == false) { @@ -1023,13 +1059,14 @@ void loop() { ignoreUpButton = true; #endif } else if (upButton.wasReleased()) { - if (!ignoreUpButton) + if (!ignoreUpButton) { if (!mySettings.invertVolumeButtons) { nextButton(); } else { volumeUpButton(); } + } ignoreUpButton = false; } @@ -1088,10 +1125,11 @@ void loop() { } #endif // Ende der Buttons - } while (!mfrc522.PICC_IsNewCardPresent()); +#ifndef PAUSEONCARDREMOVAL + } while (!mfrc522.PICC_IsNewCardPresent()); + // RFID Karte wurde aufgelegt - if (!mfrc522.PICC_ReadCardSerial()) return; @@ -1099,7 +1137,7 @@ void loop() { if (myCard.cookie == cardCookie && myCard.nfcFolderSettings.folder != 0 && myCard.nfcFolderSettings.mode != 0) { playFolder(); } - + // Neue Karte konfigurieren else if (myCard.cookie != cardCookie) { knownCard = false; @@ -1107,12 +1145,61 @@ void loop() { waitForTrackToFinish(); setupCard(); } + } + mfrc522.PICC_HaltA(); + mfrc522.PCD_StopCrypto1(); + +#endif +#ifdef PAUSEONCARDREMOVAL + // solange keine Karte aufgelegt oder heruntergenommen wird + } while ( !(!card_present && card_present_prev) && !(card_present && !card_present_prev) ); + + // RFID Karte wurde entfernt + if (!card_present && card_present_prev){ + card_present_prev = card_present; + // pausiere + if (activeModifier != NULL) + if (activeModifier->handlePause() == true) + return; + if (ignorePauseButton == false) + if (isPlaying()) { + mp3.pause(); + setstandbyTimer(); + } + else if (knownCard) { + mp3.start(); + disablestandbyTimer(); + } + ignorePauseButton = false; + return; + } + + // RFID Karte wurde aufgelegt + if (card_present && !card_present_prev){ + card_present_prev = card_present; + + if (!mfrc522.PICC_ReadCardSerial()) + return; + + if (readCard(&myCard) == true) { + if (myCard.cookie == cardCookie && myCard.nfcFolderSettings.folder != 0 && myCard.nfcFolderSettings.mode != 0) { + playFolder(); + } + + // Neue Karte konfigurieren + else if (myCard.cookie != cardCookie) { + knownCard = false; + mp3.playMp3FolderTrack(300); + waitForTrackToFinish(); + setupCard(); + } + } + mfrc522.PCD_StopCrypto1(); } - mfrc522.PICC_HaltA(); - mfrc522.PCD_StopCrypto1(); +#endif } -void adminMenu(bool fromCard = false) { +void adminMenu(bool fromCard) { disablestandbyTimer(); mp3.pause(); Serial.println(F("=== adminMenu()")); @@ -1187,7 +1274,7 @@ void adminMenu(bool fromCard = false) { else if (subMenu == 5) { // EQ mySettings.eq = voiceMenu(6, 920, 920, false, false, mySettings.eq); - mp3.setEq(mySettings.eq - 1); + mp3.setEq(DfMp3_Eq(mySettings.eq - 1)); } else if (subMenu == 6) { // create modifier card @@ -1295,7 +1382,7 @@ void adminMenu(bool fromCard = false) { } else if (subMenu == 11) { Serial.println(F("Reset -> EEPROM wird gelöscht")); - for (int i = 0; i < EEPROM.length(); i++) { + for (unsigned int i = 0; i < EEPROM.length(); i++) { EEPROM.update(i, 0); } resetSettings(); @@ -1311,7 +1398,7 @@ void adminMenu(bool fromCard = false) { mySettings.adminMenuLocked = 1; } else if (temp == 3) { - int8_t pin[4]; + uint8_t pin[4]; mp3.playMp3FolderTrack(991); if (askCode(pin)) { memcpy(mySettings.adminMenuPin, pin, 4); @@ -1344,7 +1431,7 @@ bool askCode(uint8_t *code) { } uint8_t voiceMenu(int numberOfOptions, int startMessage, int messageOffset, - bool preview = false, int previewFromFolder = 0, int defaultValue = 0, bool exitWithLongPress = false) { + bool preview, int previewFromFolder, int defaultValue, bool exitWithLongPress) { uint8_t returnValue = defaultValue; if (startMessage != 0) mp3.playMp3FolderTrack(startMessage); @@ -1705,8 +1792,6 @@ void writeCard(nfcTagObject nfcTag) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - byte size = sizeof(buffer); - mifareType = mfrc522.PICC_GetType(mfrc522.uid.sak); // Authenticate using key B diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 00000000..dd2cd77f --- /dev/null +++ b/platformio.ini @@ -0,0 +1,31 @@ +;PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[platformio] +src_dir = ./ +extra_configs = + platformio_local.ini + +[env:native] +platform = native + +[env:nanoatmega328] +platform = atmelavr +board = nanoatmega328 +framework = arduino + +monitor_speed = 115200 + +lib_deps = + 1561 + 2284 + 77 + 63 + diff --git a/test/test_Tonuino.cpp b/test/test_Tonuino.cpp new file mode 100644 index 00000000..284c55e2 --- /dev/null +++ b/test/test_Tonuino.cpp @@ -0,0 +1,10 @@ +#include + +int main(int argc, char **argv) { + UNITY_BEGIN(); + //todo add TonUINO tests here + UNITY_END(); + + return 0; +} +