diff --git a/Hardware-Plaforms/ESP32-A1S-Audiokit/src/main.cpp b/Hardware-Plaforms/ESP32-A1S-Audiokit/src/main.cpp index c126e15..8b70014 100644 --- a/Hardware-Plaforms/ESP32-A1S-Audiokit/src/main.cpp +++ b/Hardware-Plaforms/ESP32-A1S-Audiokit/src/main.cpp @@ -1521,8 +1521,6 @@ void rfidScanner(void *parameter) { //static MFRC522 mfrc522(MFRC522_CS_PIN, MFRC522_RST_PIN); //static MFRC522 mfrc522(RFID_CS, RST_PIN); //SPI.begin(); - pinMode(MFRC522_CS_PIN, OUTPUT); - digitalWrite(MFRC522_CS_PIN, HIGH); mfrc522.PCD_Init(); mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader detail delay(4); @@ -3054,6 +3052,11 @@ void setup() { prefsRfid.begin((char *) FPSTR(prefsRfidNamespace)); prefsSettings.begin((char *) FPSTR(prefsSettingsNamespace)); + pinMode(SD_CS, OUTPUT); + digitalWrite(SD_CS, HIGH); + pinMode(MFRC522_CS_PIN, OUTPUT); + digitalWrite(MFRC522_CS_PIN, HIGH); + SPI_MFRC.begin(SPI_SCK, SPI_MISO, SPI_MOSI); SPI_MFRC.setFrequency(1000000); @@ -3094,8 +3097,6 @@ void setup() { #endif // Init uSD-SPI - pinMode(SD_CS, OUTPUT); - digitalWrite(SD_CS, HIGH); /*SPI_MFRC.begin(SPI_SCK, SPI_MISO, SPI_MOSI); SPI_MFRC.setFrequency(1000000);*/ while (!SD.begin(SD_CS, SPI_MFRC)) { diff --git a/PCBs/Wemos Lolin D32/Gerber/gerber.zip b/PCBs/Wemos Lolin D32/Gerber/gerber.zip index 29597eb..240f804 100644 Binary files a/PCBs/Wemos Lolin D32/Gerber/gerber.zip and b/PCBs/Wemos Lolin D32/Gerber/gerber.zip differ diff --git a/PCBs/Wemos Lolin D32/KiCad/KICad-Files.zip b/PCBs/Wemos Lolin D32/KiCad/KICad-Files.zip index 0d29735..32ffeb0 100644 Binary files a/PCBs/Wemos Lolin D32/KiCad/KICad-Files.zip and b/PCBs/Wemos Lolin D32/KiCad/KICad-Files.zip differ diff --git a/PCBs/Wemos Lolin D32/README.md b/PCBs/Wemos Lolin D32/README.md index b203ff1..53490ee 100644 --- a/PCBs/Wemos Lolin D32/README.md +++ b/PCBs/Wemos Lolin D32/README.md @@ -6,7 +6,7 @@ ## Features * Fits Wemos Lolin D32 (not Lolin32, Lolin D32 pro or Lolin 32 lite!) -* Outer diameter: 55 x 81mm +* Outer diameter: 53 x 81mm * JST-PH 2.0-connectors for buttons, rotary encoder, Neopixel, RFID and reset (not 2.54mm pitch!) * 2.54mm-connectors for MAX98357a and uSD-card-reader * Mosfet-circuit that switches off MAX98357a, Neopixel, headphone-pcb and uSD-card-reader automatically when deepsleep is active diff --git a/README.md b/README.md index 490a8fc..a36ef07 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,14 @@ Finally, the long announced Tonuino-PCB for Wemos' Lolin32 is [there](https://gi * 05.12.2020: Moved all user-relevant settings to src/settings.h * 06.12.2020: Added PCB for Wemos Lolin32 * 08.12.2020: Reworked MQTT-timeout-Management -* 09.12.2020: mDND-feature added. If tonuino's name is "tonuino", you can use `tonuino.local` instead it's of IP-address. -* 11.12.2020: Revised GUI-design + (untested) PCB added for Wemos Lolin D32 + gerberfiles for headphone-PCB -* 13.12.2020: Add SD-MMC 1 Bit mode: This mode needs one PIN less and has almost double speed than SPI mode -* 13.12.2020: Add support for the PN5180 reader. The PN5180 has better RFID range/sensitivity and can read ISO-15693 / iCode SLIX2 tags aka Tonies -More to come... +* 09.12.2020: mDNS-feature added. If tonuino's name is "tonuino", you can use `tonuino.local` instead it's of IP-address. +* 11.12.2020: Revised GUI-design (thanks @mariolukas for contribution!) + (untested) PCB added for Wemos Lolin D32 + gerberfiles for headphone-PCB +* 18.12.2020: Added SD-MMC 1 Bit mode: This mode needs one PIN less and has almost double speed than SPI mode (thanks @tueddy for contribution!) +* 18.12.2020: Added support for the PN5180 reader. The PN5180 has better RFID range/sensitivity and can read ISO-15693 / iCode SLIX2 tags aka Tonies (thanks @tueddy for contribution!) +
More to come... ## Known bugs -* Currently, when re-learning a RFID-tag, Tonuino restarts. Almost certainly it's a memory-issue. Still have to point out. +* Some webstreams don't run. Guess it's a combination of saturated connection-pool and lack of heap-memory. Works probably better if ESP32-WROVER is used, as this chip has PSRAM. ## Disclaimer This is a **fork** of the popular [Tonuino-project](https://github.com/xfjx/TonUINO) which means, that it only shares the basic concept of controlling a music-player by RFID-tags and buttons. **Said this I want to rule out, that the code-basis is completely different and developed by myself**. So there might be features, that are supported by my fork whereas others are missing or implemented differently. For sure both share that it's non-profit, DIY and developed on [Arduino](https://www.arduino.cc/). @@ -33,15 +33,14 @@ This is a **fork** of the popular [Tonuino-project](https://github.com/xfjx/TonU ## What's different (basically)? The original project makes use of microcontrollers (uC) like Arduino nano (which is the [Microchip AVR-platform](https://de.wikipedia.org/wiki/Microchip_AVR) behind the scenes). Music-decoding is done in hardware using [DFPlayer mini](https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299) which offers a uSD-card-slot and an integrated amp as well. Control of this unit is done by a serial-interconnect with a uC using the API provided. -The core of my implementation is based on the popular [ESP32 by Espressif](https://www.espressif.com/en/products/hardware/esp32/overview). Having WiFi-support out-of-the-box makes it possible to provide further features like an integrated FTP-server (to feed the player with music), smarthome-integration via MQTT, webradio and administration via webgui. However, my primary focus was to port the project to a modular base. Said this mp3-decoding is done in software with a dedicated uSD-card-slot and music-output is done via I2S-protocol. I did all my tests on [Adafruit's MAX98357A](https://learn.adafruit.com/adafruit-max98357-i2s-class-d-mono-amp/pinouts). Hopefully, not only in theory, other DACs that support I2S can be used as well. +The core of my implementation is based on the popular [ESP32 by Espressif](https://www.espressif.com/en/products/hardware/esp32/overview). Having WiFi-support out-of-the-box makes it possible to provide further features like an integrated FTP-server (to feed the player with music), smarthome-integration via MQTT, webradio and administration via webgui. However, my primary focus was to port the project to a modular base. Said this mp3-decoding is done in software with a dedicated uSD-card-slot and music-output is done via I2S-protocol. I did all my tests on [Adafruit's MAX98357A](https://learn.adafruit.com/adafruit-max98357-i2s-class-d-mono-amp/pinouts), [UDA1334](https://www.adafruit.com/product/3678) and [headphone-pcb](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Headphone%20with%20PCM5102a%20and%20TDA1308). Hopefully, not only in theory, other DACs that support I2S can be used as well. -## Basic concept/handling -The basic idea of Tonuino (and my fork, respectively) is to provide a way, to use the Arduino-platform for a music-control-concept that supports locally stored music-files instead of being fully cloud-dependend. This basically means that RFID-tags are used to direct a music-player. Even for kids this concept is simple: place an RFID-object (card, character) on top of a box and the music starts to play. Place another RFID-object on it and anything else is played. Simple as that. +## Basic concept/handling of Tonuino +The basic idea of Tonuino is to provide a way, to use the Arduino-platform for a music-control-concept that supports locally stored music-files without DRM-restrictions. This basically means that RFID-tags are used to direct a music-player. Even for kids this concept is simple: place an RFID-object (card, character) on top of a box and the music starts to play. Place another RFID-object on it and anything else is played. Simple as that. ## Hardware-setup The heart of my project is an ESP32 on a [Wemos Lolin32 development-board](https://www.ebay.de/itm/4MB-Flash-WEMOS-Lolin32-V1-0-0-WIFI-Bluetooth-Card-Based-ESP-32-ESP-WROOM-32/162716855489). If ordered in China (Aliexpress, eBay e.g.) it's pretty cheap (around 4€) but even in Europe it's only around 8€. Make sure to install the drivers for the USB/Serial-chip (CP2102 e.g.). * [MAX98357A (like Adafruit's)](https://de.aliexpress.com/item/32999952454.html) -* [uSD-card-reader 3.3V + 5V](https://www.amazon.de/AZDelivery-Reader-Speicher-Memory-Arduino/dp/B077MB17JB) * [uSD-card-reader 3.3V only](https://www.ebay.de/itm/Micro-SPI-Kartenleser-Card-Reader-2GB-SD-8GB-SDHC-Card-3-3V-ESP8266-Arduino-NEU/333796577968) * [RFID-reader](https://www.amazon.de/AZDelivery-Reader-Arduino-Raspberry-gratis/dp/B074S8MRQ7) * [RFID-tags](https://www.amazon.de/AZDelivery-Keycard-56MHz-Schlüsselkarte-Karte/dp/B07TVJPTM7) @@ -54,16 +53,44 @@ The heart of my project is an ESP32 on a [Wemos Lolin32 development-board](https * optional replace the RFID-reader with a the better one: PN5180 comes with better RFID range, less power consumption and support for ISO-15693 / iCode SLIX2 tags (https://www.bing.com/shop?q=pn5180&FORM=SHOPTB) Most of them can be ordered cheaper directly in China. It's just a give an short impression of the hardware; feel free to order where ever you want to. These are not affiliate-links. + ## Getting Started -I recommend Microsoft's [Visual Studio Code](https://code.visualstudio.com/) or [Atom](https://atom.io/) alongside with [Platformio Plugin](https://platformio.org/install/ide?install=vscode). Since my project on Github contains [platformio.ini](platformio.ini), libraries used should be fetched automatically. Please note: if you use another ESP32-develboard (different to Lolin32) you might have to change "env:" in platformio.ini to the corresponding value. Documentation can be found [here](https://docs.platformio.org/en/latest/projectconf.html). After that it might be necessary to adjust the names of the GPIO-pins in the upper #define-section of my code. -In src/settings.h you have to specify the modules that should be compiled into the code and all the user-relevant config-parameters as well. -Please note: if MQTT is enabled it's still possible to deactivate it via webgui. +* Arduino-IDE can be used but you need to satisfy dependencies for all the libraries listed in `platformio.ini` yourself. +* Instead I recommend to install Microsoft's [Visual Studio Code](https://code.visualstudio.com/). This is a popular and powerful IDE that gives you the ability to install tons of plugins. +* Install [Platformio Plugin](https://platformio.org/install/ide?install=vscode) into [Visual Studio Code](https://code.visualstudio.com/) and make sure to have a look at the [documentation](https://docs.platformio.org/en/latest/integration/ide/pioide.html). +* Install [Git](https://git-scm.com/downloads) and make a copy ("clone") my repository to your local computer using `git clone https://github.com/biologist79/Tonuino-ESP32-I2S.git`. Using git you can keep your local repository easily up to date without doing copy'n'paste. +* Now, that the git-repository is saved locally, import this folder into Platformio as a project. +* There's a file called `platformio.ini`, that contains the configuration of the develboard (e.g. env:lolin32). Platformio supports hundrets of boards out of the box. So probably, you need to change that configuration. Guess Lolin32 is described in platformio.ini but you need Lolin D32, then lookup Platformio's [documentation](https://docs.platformio.org/en/latest/boards/espressif32/lolin_d32.html) to know what to change. +* Depending on your operating system (Windows, Mac OS, Linux), you probably need to change `upload_port`and `monitor_port` as well. +* Edit `src/settings.h` according your needs. Especially GPIO-configuration is really important. +* Connect your develboard via USB, click the alien-head to the left and run `Upload and Monitor`. All libraries necessary should be fetched in background now followed by code-compilation. After that, your ESP32 is flashed with the firmware. +* Now have a look at the serial-output at the bottom of Visual Studio Code's windows. +* If everything ran fine, at the first run, Tonuino should open an access-point with the name "Tonuino". Connect to this WiFi with your computer (or mobile) and enter `192.168.4.1` to your webbrowser. Enter WiFi-credentials and the hostname. After saving the configuraton, restart Tonuino. +* Now Tonuino tries to join your WiFi. If that was successful, an IP is shown in the serial-console of Visual Studio Code. You can call Tonuino's GUI via this IP. If mDNS-feature is active in `src/settings.h`, you can use the hostname configured extended by .local. So if you configured `tonuino` as hostname, you can use `tonuino.local` for webgui and FTP. +* Via FTP you can upload data (don't expect it to be super fast). It's round about 185 kb/s if SD is in SPI-mode and 300 kB/s if SD is in MMC-mode (this feature will be released soon) +* Via webbrowser you can configure various settings and pair RFID-tags with actions. -## Wiring (2 SPI-instances) -A lot of wiring is necessary to get ESP32-Tonuino working. After my first experiments I soldered the stuff on a board in order to avoid wild-west-cabling. Especially for the interconnect between uC and uSD-card-reader make sure to use short wires (like 10cm or so)! Important: you can easily connect another I2S-DACs by just connecting them in parallel to the I2S-pins (DIN, BCLK, LRC). This is true for example if you plan to integrate a [line/headphone-pcb](https://www.adafruit.com/product/3678). In general, this runs fine. But unfortunately especially this board lacks of a headphone jack, that takes note if a plug is inserted or not. Best way is to use a [headphone jack](https://www.conrad.de/de/p/cliff-fcr1295-klinken-steckverbinder-3-5-mm-buchse-einbau-horizontal-polzahl-3-stereo-schwarz-1-st-705830.html) that has a pin that is pulled to GND, if there's no plug and vice versa. Using for example a MOSFET-circuit, this GND-signal can be inverted in a way, that MAX98357.SD is pulled down to GND if there's a plug. Doing that will turn off the speaker immediately if there's a plug and vice versa. Have a look at the PCB-folder in order to view the detailed solution. Here's an example for such a [headphone-pcb](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Headphone%20with%20PCM5102a%20and%20TDA1308) that makes use of GND.
-Have a look at my PCB in the subfolder Hardware-Platforms/Wemos Lolin32. Probably this makes things easier. +## Prerequisites / tipps +* Open settings.h +* choose if optional modules (e.g. MQTT, FTP, Neopixel) should be compiled/enabled +* For debugging-purposes serialDebug can be set to ERROR, NOTICE, INFO or DEBUG. +* If MQTT=yes, set the IP or hostname of the MQTT-server accordingly and check the MQTT-topics (states and commands) +* If Neopixel enabled: set NUM_LEDS to the LED-number of your Neopixel-ring and define the Neopixel-type using `#define CHIPSET` +* If you're using Arduino-IDE please make sure to change ESP32's partition-layout to `No OTA (2MB APP/2MB Spiffs)` as otherwise the sketch won't fit into the flash-memory. +* If you want to monitor battery's voltage, make sure to enable `MEASURE_BATTERY_VOLTAGE`. Use a voltage-divider as voltage of a LiPo is way too high for ESP32 (only 3.3V supported!). For my tests I connected VBat with a serial connection of 130k + 390k resistors (VBat(+)--130k--X--390k--VBat(-)). X is the measure-point where to connect the GPIO to. If using Lolin D32 or Lolin D32 pro, make sure to adjust both values to 100k each and change GPIO to 35 as this is already integrated and wired fixed. +Please note: via GUI upper and lower voltage cut-offs for visualisation of battery-voltage (Neopixel) is available. Additional GUI-configurable values are interval (in minutes) for checking battery voltage and the cut off-voltage below whose a warning is shown via Neopixel. +* If you're using a headphone-pcb with a [headphone jack](https://www.conrad.de/de/p/cliff-fcr1295-klinken-steckverbinder-3-5-mm-buchse-einbau-horizontal-polzahl-3-stereo-schwarz-1-st-705830.html) that has a pin to indicate if there's a plug, you can use this signal along with the feature `HEADPHONE_ADJUST_ENABLE` to limit the maximum headphone-voltage automatically. As per default you have to invert this signal (with a P-channel MOSFET) and connect it to GPIO22. +* Enabling `SHUTDOWN_IF_SD_BOOT_FAILS` is really recommended if you run your Tonuino in battery-mode without having a restart-button exposed to the outside of Tonuino's enclosure. Because otherwise there's no way to restart your Tonuino and the error-state will remain until battery is empty (or you open the enclosure, hehe). +* Enabling `PLAY_LAST_RFID_AFTER_REBOOT` will tell Tonuino to remember the last RFID-tag played after next reboot. So rebooting Tonuino will end up in autoplay. +* If `MDNS_ENABLE` is enabled, your Tonuino is reachable via hostname.local. So if your Tonuino's hostname is 'tonuino', the address is `tonuino.local`. +## Wiring (general) +Depending on the develboard you're using and the needs you have, there are different options available. +A lot of wiring is necessary to get ESP32-Tonuino working. After my first experiments on a breadboard I soldered all the stuff onto a board in order to avoid wild-west-cabling. Especially for the interconnect between uC and uSD-card-reader make sure to use short wires (like 10cm or so)! As of my experience with a breadbord, male/male-connectors are better than female/female-connectors. Important: you can easily connect another I2S-DACs by just connecting them in parallel to the I2S-pins (DIN, BCLK, LRC). This is true for example if you plan to integrate a [line/headphone-pcb](https://www.adafruit.com/product/3678). In general, this runs fine. But unfortunately especially this board lacks of a headphone jack, that takes note if a plug is inserted or not. Best way is to use a [headphone jack](https://www.conrad.de/de/p/cliff-fcr1295-klinken-steckverbinder-3-5-mm-buchse-einbau-horizontal-polzahl-3-stereo-schwarz-1-st-705830.html) that has a pin that is pulled to GND, if there's no plug and vice versa. Using for example a MOSFET-circuit, this GND-signal can be inverted in a way, that MAX98357.SD is pulled down to GND if there's a plug. Doing that will turn off the speaker immediately if there's a plug and vice versa. Have a look at the PCB-folder in order to view the detailed solution. Here's an example for such a [headphone-pcb](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Headphone%20with%20PCM5102a%20and%20TDA1308) that makes use of GND.
+Have a look at my PCB in the subfolder Hardware-Platforms/Wemos Lolin32. Probably this makes things easier for you. +## Wiring (2 SPI-instances) +Uses two SPI-instances. The first one for the RFID-reader and the second for SD-card-reader. This is also the [setup, I personally use](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Wemos%20Lolin32).
| ESP32 (GPIO) | Hardware | Pin | Comment | | ------------- | --------------------- | ------ | ------------------------------------------------------------ | | 5 V | SD-reader | VCC | Connect to p-channel MOSFET for power-saving when uC is off | @@ -84,8 +111,8 @@ Have a look at my PCB in the subfolder Hardware-Platforms/Wemos Lolin32. Probabl | 27 | MAX98357 | BCLK | | | 26 | MAX98357 | LRC | | | --- | MAX98357 | SD | Info: if pulled down to GND amp will turn off | -| 34 | Rotary encoder | CLR | Invert CLR with DT if you want to change the direction of RE | -| 35 | Rotary encoder | DT | Invert CLR with DT if you want to change the direction of RE | +| 34 | Rotary encoder | CLR | Change CLR with DT if you want to change the direction of RE | +| 35 | Rotary encoder | DT | Change CLR with DT if you want to change the direction of RE | | 32 | Rotary encoder | BUTTON | | | 3.3 V | Rotary encoder | + | | | GND | Rotary encoder | GND | | @@ -97,15 +124,14 @@ Have a look at my PCB in the subfolder Hardware-Platforms/Wemos Lolin32. Probabl | GND | Button (pause/play) | | | | 5 V | Neopixel | 5 V | Connect to p-channel MOSFET for power-saving when uC is off | | GND | Neopixel | GND | | -| 12 | Neopixel | DI | Might be necessary to use a logic-converter 3.3 => 5V | -| 17 | (e.g.) BC337 (via R5) | Base | Don't forget R5! | +| 12 | Neopixel | DI | | +| 17 | N-channel Mosfet | Gate | | | 33 | Voltage-divider / BAT | | Optional: voltage-divider to monitor battery-voltage | | 22 | Headphone jack | | Optional: if pulled to ground, headphone-volume is set | -Optionally, GPIO 17 can be used to drive a NPN-transistor (BC337-40) that pulls a p-channel MOSFET (IRF9520) to GND in order to switch on/off 5V-current. Transistor-circuit is described [here](https://dl6gl.de/schalten-mit-transistoren.html): Just have a look at Abb. 4. Values of the resistors I used: R1: 10k, R2: omitted(!), R4: 10k, R5: 4,7k.
-This also works for a 3.3V-setup with IRF530NPBF (N-channel MOSFET) and NDP6020P (P-channel MOSFET). Resistor-values: R1: 100k, R2: omitted(!), R4: 100k, R5: 1k. A 3.3V-setup is helpful if you want to battery-power your Tonuino and 5V is not available in battery-mode. For example this is the case when using Wemos Lolin32 with only having LiPo connected. Please refer the schematics for my [Lolin32-PCB](https://github.com/biologist79/Tonuino-ESP32-I2S/blob/master/PCBs/Wemos%20Lolin32/Pictures/Tonuino-Lolin32-Schematics.pdf) for further informations.
-Advice: When powering a SD-card-reader solely with 3.3V, make sure to use one WITHOUT a voltage regulator. Or at least one with a pin dedicated for 3.3V (bypassing voltage regulator). This is because if 3.3V go through the voltage regulator a small voltage-drop will be introduced, which may lead to SD-malfunction as the resulting voltage is a bit too low. Vice versa if you want to connect your reader solely to 5V, make sure to have one WITH a voltage regulator :-). +Optionally, GPIO 17 can be used to drive a Mosfet-circuit in order to switch off peripherals (SD, Neopixel, RFID and MAX98357a) if ESP32 is in deepsleep. lease refer the schematics for my [Lolin32-PCB](https://github.com/biologist79/Tonuino-ESP32-I2S/blob/master/PCBs/Wemos%20Lolin32/Pictures/Tonuino-Lolin32-Schematics.pdf) for further informations. If you need further informations on transistor-circuits visit this [website](https://dl6gl.de/schalten-mit-transistoren.html).
+In general I recommend using a [uSD-card-reader](https://www.ebay.de/itm/Micro-SPI-Kartenleser-Card-Reader-2GB-SD-8GB-SDHC-Card-3-3V-ESP8266-Arduino-NEU/333796577968) that can be run solely with 3.3V (doesn't have a voltage-regulator). This is because if 3.3V go through the voltage regulator a small voltage-drop will be introduced, which may lead to SD-malfunction as the resulting voltage is a bit too low. Vice versa if you want to connect your reader solely to 5V, make sure to have one WITH a voltage regulator :-). And by the way: when LiPo-battery is connected, there's no 5V. That's why I designed my [Lolin32-PCB](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Wemos%20Lolin32) with 3.3V only. ## Wiring (SD card in 1 Bit SD-MMC mode) different to above | ESP32 (GPIO) | Hardware | Pin | Comment | @@ -121,7 +147,7 @@ Advice: Double check that above PIN's not used in otherway (PREVIOUS_BUTTON is m ## Wiring (1 SPI-instance) [EXPERIMENTAL, maybe not working!] Basically the same as using 2 SPI-instances but... -In this case RFID-reader + SD-reader share SPI's SCK, MISO and MOSI. But make sure to use different CS-pins. +In this case RFID-reader + SD-reader share SPI's SCK, MISO and MOSI. But make sure to use different CS-pins. Have to admit I had some problems to get this running. Seems to be connected properly, but nothing happens when an RFID-tag is applied. Maybe anybody else wants to point out :-) | ESP32 (GPIO) | Hardware | Pin | Comment | | ------------- | --------------------- | ------ | ------------------------------------------------------------ | @@ -140,8 +166,8 @@ In this case RFID-reader + SD-reader share SPI's SCK, MISO and MOSI. But make su | 27 | MAX98357 | BCLK | | | 26 | MAX98357 | LRC | | | --- | MAX98357 | SD | Info: if pulled down to GND amp will turn off | -| 34 | Rotary encoder | CLR | Invert CLR with DT if you want to change the direction of RE | -| 35 | Rotary encoder | DT | Invert CLR with DT if you want to change the direction of RE | +| 34 | Rotary encoder | CLR | Change CLR with DT if you want to change the direction of RE | +| 35 | Rotary encoder | DT | Change CLR with DT if you want to change the direction of RE | | 32 | Rotary encoder | BUTTON | | | 3.3 V | Rotary encoder | + | | | GND | Rotary encoder | GND | | @@ -153,9 +179,9 @@ In this case RFID-reader + SD-reader share SPI's SCK, MISO and MOSI. But make su | GND | Button (pause/play) | | | | 5 V | Neopixel | 5 V | Connect to p-channel MOSFET for power-saving when uC is off | | GND | Neopixel | GND | | -| 12 | Neopixel | DI | Might be necessary to use a logic-converter 3.3 => 5V | -| 17 | (e.g.) BC337 (via R5) | Base | Don't forget R5! | -| 33 | Voltage-divider / BAT | | Optional: Voltage-divider to monitor battery-voltage | +| 12 | Neopixel | DI | | +| 17 | N-channel Mosfet | Gate | | +| 33 | Voltage-divider / BAT | | Optional: voltage-divider to monitor battery-voltage | | 22 | Headphone jack | | Optional: if pulled to ground, headphone-volume is set | @@ -173,38 +199,15 @@ PN5180 reader needs two more PIN's, RESET and BUSY. Double check PIN conflicts! | 16 | PN5180 RFID-reader | BUSY | be aware of SD MISO if running in SPI mode | | 22 | PN5180 RFID-reader | RST | be aware of Headphone jack PIN | - - ## Wiring (custom) / different pinout -When using a develboard with for example SD-card-reader already integrated (Lolin D32 Pro), the pinouts described above my not fit; feel free to change them according your needs. Additionaly some boards may use one or some of the GPIOs I used for their internal purposes and that reason for are maybe not exposed via pin-headers. However, having them exposed doesn't mean they can be used without limits. This is because some GPIOs have to be logical LOW or HIGH at start for example and this is probably not the case when connecting stuff to it. Feel free to adjust the GPIOs proposed by me (but be adviced it could take a while to get it running). If you encounter problems please refer the board's manual first.
-[Here](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/Hardware-Plaforms/ESP32-A1S-Audiokit) I described a solution for a board with many GPIOs used internally and a very limited number of GPIOs exposed. That's why I had to use different SPI-GPIOs for RFID as well. Please note I used a slightly modified [RFID-lib](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/Hardware-Plaforms/ESP32-A1S-Audiokit/lib/MFRC522) there. - -## Prerequisites / tipps -* Open settings.h -* choose if optional modules (MQTT, FTP, Neopixel) should be compiled/enabled -* For debugging-purposes serialDebug can be set to ERROR, NOTICE, INFO or DEBUG. -* If MQTT=yes, set the IP or hostname of the MQTT-server accordingly and check the MQTT-topics (states and commands) -* If Neopixel enabled: set NUM_LEDS to the LED-number of your Neopixel-ring and define the Neopixel-type using `#define CHIPSET` -* If you're using Arduino-IDE please make sure to change ESP32's partition-layout to `No OTA (2MB APP/2MB Spiffs)` as otherwise the sketch won't fit into the flash-memory. -* Please keep in mind that working SD is mandatory. Unless `SD_NOT_MANDATORY_ENABLE` is not set, Tonuino will never fully start up if SD is not working. Only use `SD_NOT_MANDATORY_ENABLE` for debugging as for normal operational mode, not having SD working doesn't make sense. Even if only webradio-mode is intended, SD would be used to backup RFID-tag-learnings (/backup.txt) or JSON-file-index (files.json). -* If you want to monitor battery's voltage, make sure to enable `MEASURE_BATTERY_VOLTAGE`. Use a voltage-divider as voltage of a LiPo is way too high for ESP32 (only 3.3V supported!). For my tests I connected VBat with a serial connection of 130k + 390k resistors (VBat(+)--130k--X--390k--VBat(-)). X is the measure-point where to connect the GPIO to. If using Lolin D32 or Lolin D32 pro, make sure to adjust both values to 100k each and change GPIO to 35 as this is already integrated and wired fixed. -Please note: via GUI upper and lower voltage cut-offs for visualisation of battery-voltage (Neopixel) is available. Additional GUI-configurable values are interval (in minutes) for checking battery voltage and the cut off-voltage below whose a warning is shown via Neopixel. -* If you're using a headphone-pcb with a [headphone jack](https://www.conrad.de/de/p/cliff-fcr1295-klinken-steckverbinder-3-5-mm-buchse-einbau-horizontal-polzahl-3-stereo-schwarz-1-st-705830.html) that has a pin to indicate if there's a plug, you can use this signal along with the feature `HEADPHONE_ADJUST_ENABLE` to limit the maximum headphone-voltage automatically. As per default you have to invert this signal (with a P-channel MOSFET) and connect it to GPIO22. -* Enabling `SHUTDOWN_IF_SD_BOOT_FAILS` is really recommended if you run your Tonuino in battery-mode without having a restart-button exposed to the outside of Tonuino's enclosure. Because otherwise there's no way to restart your Tonuino and the error-state will remain until battery is empty (or you open the enclosure, hehe). -* Enabling `PLAY_LAST_RFID_AFTER_REBOOT` will tell Tonuino to remember the last RFID-tag played after next reboot. So rebooting Tonuino will end up in autoplay. -* If `MDNS_ENABLE` is enabled, your Tonuino is reachable via hostname.local. So if your Tonuino's hostname is 'tonuino', the address is `tonuino.local`. -* If you want to use the SD card in SD-MMC mode (double upload speed for FTP) use `SD_MMC_1BIT_MODE` and double check these PIN's are not used by other periperal -* Compile and upload the sketch. - -## Starting Tonuino-ESP32 first time -After plugging in it takes a few seconds until neopixel indicates that Tonuino is ready (by four (slow) rotating LEDs; white if Wifi enabled and blue if disabled). If uC was not able to connect to WiFi, an access-point (named Tonuino) is opened and after connecting this WiFi, a [configuration-Interface](http://192.168.4.1) is available via webbrowser. Enter WiFI-credentials + the hostname (Tonuio's name), save them and restart the uC. Then reconnect to your "regular" WiFi. Now you're ready to go: start learning RFID-tags via GUI. To reach the GUI enter the IP stated in the serial console or use the hostname. For example if you're using a Fritzbox as router and entered tonuino as hostname in the previous configuration-step, in your webbrowser tonuino.fritz.box should work (or tonuino.local if `MDNS_ENABLE` is enabled). After doing rfid-learnings, place your RFID-tag next to the RFID-reader and the music (or whatever else you choosed) should start to play. While the playlist is generated/processed, fast-rotating LEDs are shown to indicate that Tonuino is busy. The more tracks a playlist/directory contains the longer this step will take.
-Please note: hostname can be used to call webgui or FTP-server. I tested it with a Fritzbox 7490 and worked fine. Make sure you don't use a name that already exists in you local network (LAN). +When using a develboard with SD-card-reader already integrated (Lolin D32 Pro, several TTGO-boards), the pinouts described above my not fit. Feel free to change them according your needs. Additionaly some boards may use one or some of the GPIOs I used for their internal purposes and that reason for are maybe not exposed via pin-headers. However, having them exposed doesn't mean they can be used without limits. This is because some GPIOs have to be logical LOW or HIGH at start/boot for example and this is probably not the case when connecting stuff to it. Feel free to adjust the GPIOs proposed by me (but be adviced it could take a while to get it running). If you encounter problems please refer the board's manual first.
+[Here](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/Hardware-Plaforms/ESP32-A1S-Audiokit) I described a solution for a board with many GPIOs used internally and a very limited number of GPIOs exposed. That's why I had to use different SPI-GPIOs for RFID as well. Please note I used a slightly modified [RFID-lib](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/Hardware-Plaforms/ESP32-A1S-Audiokit/lib/MFRC522) there. Please note: the code-basis is outdated. Will need to re-integrate it into my master-branch... ## WiFi WiFi is mandatory for webgui, FTP and MQTT. However, WiFi can be temporarily or permanently disabled. There are two ways to do that: * Use a special modification-card that can be configured via webgui * Press previous-key (and keep it pressed) + press next-button in parallel shortly. Now release both. -This toggles the current WiFi-status which means: if it's currently enabled, it will be disabled instantly and vice versa. Please note: this WiFi-status will remain until you change it again, which means, that Tonuino will remember this state after the next reboot. Having Wifi enabled is indicated in idle-mode (no playlist active) with four *white* slow rotating LEDs whereas disabled WiFi is represented by those ones coloured *blue*. +This toggles the current WiFi-status: if it's currently enabled, it will be disabled instantly and vice versa. Please note: this WiFi-status will remain until you change it again, which means, that Tonuino will remember this state after the next reboot. Having Wifi enabled is indicated in idle-mode (no playlist active) with four *white* slow rotating LEDs whereas disabled WiFi is represented by those ones coloured *blue*. ## After Tonuino-ESP32 is connected to your WiFi After bringing Tonuino part of your LAN/WiFi, the 'regular' webgui is available at the IP assigned by your router (or the configured hostname). Using this GUI, you can configure: * WiFi @@ -242,14 +245,14 @@ Webgui: action ok: Please note: as you apply a RFID-tag to the RFID-reader, the corresponding ID is pushed to the GUI. So there's no need to enter such IDs manually (unless you want to). Filepath can be filled out by selecting a file/directory in the tree. -IMPORTANT: Every time you add, delete or rename stuff on the SD-card, it's necessary to re-index. Simply click on the refresh-button below the filetree and wait until it's done. +IMPORTANT: Every time you add, delete or rename stuff on the SD-card, it's necessary to re-index the json-indexfile. Simply click on the refresh-button below the filetree and wait until it's done. This is because all operations of the filebrowser rely on this file in order to provide a fast way to access all the files and directories. ## Interacting with Tonuino ### Playmodes It's not just simply playing music; different playmodes are supported: * single track * single track (loop) -* audiobook (single file or playlist; last play-position (file and playlist) is saved and re-used next time) +* audiobook (single file or playlist/folder; last play-position (file and playlist) is saved and re-used next time) * audiobook (loop) * folder/playlist (alph. sorted) * folder/playlist (random order) @@ -302,7 +305,7 @@ Some buttons have different actions if pressed long or short. Minimum duration f * rotary encoder (turning): vol +/- * rotary encoder (button long): switch off (only when on) * rotary encoder (button short): switch on (when switched off) -* rotary encoder (button short): show battery-voltage (when switched on and `MEASURE_BATTERY_VOLTAGE` is active) +* rotary encoder (button short): show battery-voltage via Neopixel (when switched on and `MEASURE_BATTERY_VOLTAGE` is active) * previous (long; keep pressed) + next (short) + release (both): toggle WiFi enabled/disabled ### Music-play @@ -333,7 +336,7 @@ After having Tonuino running on your ESP32 in your local WiFi, the webinterface- In order to avoid exposing uSD-card or disassembling the Tonuino all the time for adding new music, it's possible to transfer music onto the uSD-card using FTP. Please make sure to set the max. number of parallel connections to ONE in your FTP-client. My recommendation is [Filezilla](https://filezilla-project.org/). But don't expect fast data-transfer. Initially it was around 145 kB/s but after modifying ftp-server-lib (changing from 4 kB static-buffer to 16 kB heap-buffer) I saw rates improving to around 185 kB/s. Please note: if music is played in parallel, this rate decrases dramatically! So better stop playback when doing a FTP-transfer. However, playback sounds normal if a FTP-upload is performed in parallel. Default-user and password are set to `esp32` / `esp32` but can be changed later via GUI. ### Files / ID3-tags (IMPORTANT!) -Make sure to not use filenames that contain German 'Umlaute'. I've been told this is also true for mp3's ID3-tags. +Make sure to not use filenames that contain German 'Umlaute'. I've been told this is also true for mp3's ID3-tags. Also better remove coverarts from the files. ### Energy saving As already described in the modify-section, there are different sleepmodes available. Additionaly uC will be put into deepsleep after 10 minutes of inactivity (configurable my maxInactivityTime) unless Tonuino doesn't play music, has a FTP-client connected and any input via buttons. Every button-interaction resets the counter to the initial value. diff --git a/src/main.cpp b/src/main.cpp index 4701882..5c33633 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -311,6 +311,7 @@ QueueHandle_t trackQueue; QueueHandle_t trackControlQueue; QueueHandle_t rfidCardQueue; +bool pauseNeopixel = false; // Used to pause Neopixel-signalisation (while NVS-writes as this leads to exceptions; don't know why) // Prototypes void accessPointStart(const char *SSID, IPAddress ip, IPAddress netmask); @@ -1367,6 +1368,7 @@ char ** returnPlaylistFromSD(File _fileOrDirectory) { /* Wraps putString for writing settings into NVS for RFID-cards. Returns number of characters written. */ size_t nvsRfidWriteWrapper (const char *_rfidCardId, const char *_track, const uint32_t _playPosition, const uint8_t _playMode, const uint16_t _trackLastPlayed, const uint16_t _numberOfTracks) { + pauseNeopixel = true; // Workaround to prevent exceptions due to Neopixel-signalisation while NVS-write char prefBuf[275]; char trackBuf[255]; snprintf(trackBuf, sizeof(trackBuf) / sizeof(trackBuf[0]), _track); @@ -1388,6 +1390,7 @@ size_t nvsRfidWriteWrapper (const char *_rfidCardId, const char *_track, const u snprintf(logBuf, serialLoglength, "Schreibe '%s' in NVS für RFID-Card-ID %s mit playmode %d und letzter Track %u\n", prefBuf, _rfidCardId, _playMode, _trackLastPlayed); logger(logBuf, LOGLEVEL_INFO); loggerNl(prefBuf, LOGLEVEL_INFO); + pauseNeopixel = false; return prefsRfid.putString(_rfidCardId, prefBuf); } @@ -1967,6 +1970,16 @@ void showLed(void *parameter) { FastLED.setBrightness(ledBrightness); for (;;) { + if (pauseNeopixel) { // Workaround to prevent exceptions while NVS-writes take place + vTaskDelay(portTICK_RATE_MS*10); + continue; + } + /*#ifdef FTP_ENABLE + if (ftpSrv.isConnected()) { // Workaround: after moving Neopixel's task to 2nd cpu-core, FTP-transfer-rate decreased. By disabling Neopixel-animation, this can be rescued a bit + vTaskDelay(portTICK_RATE_MS*100); + continue; + } + #endif*/ if (!bootComplete) { // Rotates orange unless boot isn't complete FastLED.clear(); for (uint8_t led = 0; led < NUM_LEDS; led++) { @@ -2300,7 +2313,7 @@ void showLed(void *parameter) { vTaskDelay(portTICK_RATE_MS * 5); } } - vTaskDelay(portTICK_RATE_MS * 10); + //vTaskDelay(portTICK_RATE_MS * 10); esp_task_wdt_reset(); } vTaskDelete(NULL); @@ -3552,6 +3565,7 @@ void webserverStart(void) { // Dumps all RFID-entries from NVS into a file on SD-card bool dumpNvsToSd(char *_namespace, char *_destFile) { + pauseNeopixel = true; esp_partition_iterator_t pi; // Iterator for find const esp_partition_t* nvs; // Pointer to partition struct esp_err_t result = ESP_OK; @@ -3615,12 +3629,14 @@ void webserverStart(void) { } backupFile.close(); + pauseNeopixel = false; return true; } // Handles uploaded backup-file and writes valid entries into NVS void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) { + pauseNeopixel = true; char ebuf[290]; uint16_t j=0; char *token; @@ -3653,6 +3669,7 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, } } } + pauseNeopixel = false; } @@ -3697,6 +3714,7 @@ void setup() { NULL, /* Task input parameter */ 1 | portPRIVILEGE_BIT, /* Priority of the task */ &LED, /* Task handle. */ +// 1 /* Core where the task should run */ 0 /* Core where the task should run */ ); #endif