Currently I'm working on a new Tonuino that is completely based on 3.3V. As uC-develboard a Lolin32 is used and it's (optionally) battery-powered. So stay tuned...
Currently I'm working on a new Tonuino that is completely based on 3.3V and makes use of an (optional) headphone-pcb. As uC-develboard a Lolin32 is used and it's (optionally) battery-powered. So stay tuned...
## Disclaimer
## 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/).
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/).
@ -16,26 +16,27 @@ The core of my implementation is based on the popular [ESP32 by Espressif](https
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.
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.
## Hardware-setup
## Hardware-setup
The heart of my project is an ESP32 on a development-board that more or less looks like [this](https://docs.zerynth.com/latest/official/board.zerynth.nodemcu_esp32/docs/index.html). 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.). If unsure have a look at eBay for "ESP32S" or "Lolin 32".
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.). If unsure have a look at eBay or Aliexpress for "Lolin 32".
* uSD-card: doesn't have to be a super-fast one; uC is limiting the throughput. Tested 32GB without any problems.
* uSD-card: doesn't have to be a super-fast one; uC is limiting the throughput. Tested 32GB without any problems.
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. I don't earn money with my links.
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
## Getting Started
I recommend Microsoft's [Visual Studio Code](https://code.visualstudio.com/) 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 (Lolin32 e.g.) 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.
I recommend Microsoft's [Visual Studio Code](https://code.visualstudio.com/) 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 (Lolin32 e.g.) 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 the upper section of main.cpp you can specify the modules that should be compiled into the code.
In the upper section of main.cpp you can specify the modules that should be compiled into the code.
Please note: if MQTT is enabled it's still possible to deactivate it via webgui.
Please note: if MQTT is enabled it's still possible to deactivate it via webgui.
## Wiring (2 SPI-instances)
## 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)!
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 but 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 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 set to GND, if there's no plug and vice versa. Using for example a MOSFET-circuit, this 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.
When using a develboard with for example SD-card-reader already integrated, the pinouts described above my not fit your needs. Additionaly some boards may use one or some of the GPIOs I used for internal purposes and 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. <br/>
When using a develboard with for example SD-card-reader already integrated, the pinouts described above my not fit your needs; 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. <br/>
Keep in mind the RFID-lib I used is intended for default-SPI-pins only (SCK, MISO, MOSI). [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.
Keep in mind the RFID-lib I used is intended for default-SPI-pins only (SCK, MISO, MOSI). [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.
#define NEOPIXEL_ENABLE // Don't forget configuration of NUM_LEDS if enabled
#define NEOPIXEL_ENABLE // Don't forget configuration of NUM_LEDS if enabled
#define NEOPIXEL_REVERSE_ROTATION // Some Neopixels are adressed/soldered counter-clockwise. This can be configured here.
#define NEOPIXEL_REVERSE_ROTATION // Some Neopixels are adressed/soldered counter-clockwise. This can be configured here.
#define LANGUAGE 1 // 1 = deutsch; 2 = english
#define LANGUAGE 1 // 1 = deutsch; 2 = english
//#define HEADPHONE_ADJUST_ENABLE // Used to adjust (lower) volume for optional headphone-pcb (refer maxVolumeSpeaker / maxVolumeHeadphone)
//#define SINGLE_SPI_ENABLE // If only one SPI-instance should be used instead of two
//#define SINGLE_SPI_ENABLE // If only one SPI-instance should be used instead of two
//#define SD_NOT_MANDATORY_ENABLE // Only for debugging-purposes: Tonuino will also start without mounted SD-card anyway (will only try once to mount it )
//#define SD_NOT_MANDATORY_ENABLE // Only for debugging-purposes: Tonuino will also start without mounted SD-card anyway (will only try once to mount it )
@ -77,7 +78,7 @@ char *logBuf = (char*) calloc(serialLoglength, sizeof(char)); // Buffer for all
#endif
#endif
// GPIOs (RFID-readercurrentRfidTagId)
// GPIOs (RFID-readercurrentRfidTagId)
#define RST_PIN 22
#define RST_PIN 99 // Not necessary but has to be set anyway; so let's use a dummy-number
#define RFID_CS 21
#define RFID_CS 21
#define RFID_MOSI 23
#define RFID_MOSI 23
#define RFID_MISO 19
#define RFID_MISO 19
@ -88,6 +89,14 @@ char *logBuf = (char*) calloc(serialLoglength, sizeof(char)); // Buffer for all
#define I2S_BCLK 27
#define I2S_BCLK 27
#define I2S_LRC 26
#define I2S_LRC 26
// GPIO to detect if headphone was plugged in (set to GND)
#ifdef HEADPHONE_ADJUST_ENABLE
#define HP_DETECT 22 // Detects if there's a plug in the headphone jack or not
boolheadphoneLastDetectionState;
uint32_theadphoneLastDetectionTimestamp=0;
uint16_theadphoneLastDetectionDebounce=1000;// Debounce-interval in ms when plugging in headphone
#endif
#ifdef BLUETOOTH_ENABLE
#ifdef BLUETOOTH_ENABLE
BluetoothA2DPSinka2dp_sink;
BluetoothA2DPSinka2dp_sink;
#endif
#endif
@ -199,9 +208,13 @@ bool enableMqtt = true;
#define RFID_SCAN_INTERVAL 300 // in ms
#define RFID_SCAN_INTERVAL 300 // in ms
uint8_tconstcardIdSize=4;// RFID
uint8_tconstcardIdSize=4;// RFID
// Volume
// Volume
uint8_tmaxVolume=21;// Maximum volume that can be adjusted (default; can be changed later via GUI)
uint8_tmaxVolume=21;// Current maximum volume that can be adjusted
uint8_tmaxVolumeSpeaker=21;// Maximum volume that can be adjusted in speaker-mode (default; can be changed later via GUI)
uint8_tminVolume=0;// Lowest volume that can be adjusted
uint8_tminVolume=0;// Lowest volume that can be adjusted
uint8_tinitVolume=3;// 0...21 (If not found in NVS, this one will be taken) (default; can be changed later via GUI)
uint8_tinitVolume=3;// 0...21 (If not found in NVS, this one will be taken) (default; can be changed later via GUI)
#ifdef HEADPHONE_ADJUST_ENABLE
uint8_tmaxVolumeHeadphone=11;// Maximum volume that can be adjusted in headphone-mode (default; can be changed later via GUI)
#endif
// Sleep
// Sleep
uint8_tmaxInactivityTime=10;// Time in minutes, after uC is put to deep sleep because of inactivity
uint8_tmaxInactivityTime=10;// Time in minutes, after uC is put to deep sleep because of inactivity
uint8_tsleepTimer=30;// Sleep timer in minutes that can be optionally used (and modified later via MQTT or RFID)
uint8_tsleepTimer=30;// Sleep timer in minutes that can be optionally used (and modified later via MQTT or RFID)