Systeminfos werden via mp3-Dateien in /system abgespielt.
This commit is contained in:
parent
076a6993c7
commit
b2cf9d6277
178
README.md
178
README.md
@ -1,174 +1,8 @@
|
|||||||
# ESMP3
|
# ESMP3
|
||||||
|
|
||||||
## What you need
|
## Audio files
|
||||||
Please note: This list is a "things I used", neither
|
System messages are created using:
|
||||||
"these are the best things for this stuff" nor "you
|
* https://ttsmp3.com/
|
||||||
can only use these things". But please be aware that
|
* German / Vicki
|
||||||
using other stuff may lead to you having to make
|
* "Dies ist ein Text.<break time="1s"/>"
|
||||||
more or less easy modifications.
|
* Download as MP3.
|
||||||
|
|
||||||
Prizes are more or less the cheapest I could find on
|
|
||||||
Aliexpress.
|
|
||||||
|
|
||||||
| What? | For what? | Price (approx) |
|
|
||||||
|-------|-----------|----------------|
|
|
||||||
| ESP-32-WROOM-32D | Controlling everything | 4€ |
|
|
||||||
| WS1053B on a PCB with SD card slot | Play the MP3 files; provide an SD card slot | 5€ |
|
|
||||||
| MFRC522 | RFID reader | 1€ |
|
|
||||||
| 5V Amplifier(s) (e.g. 2x PAM-8302) | Single-channel Amplifier | 2€ |
|
|
||||||
| Speaker(s) matching your amp (e.g. 2pcs 4 Ohm 5W) | Enabling you to hear the sounds | 4€ |
|
|
||||||
| RFID tags (ISO14443A) - e.g. 10 cards | You can also get Keyfobs or stickers | 4€ |
|
|
||||||
| 4 buttons | Prev/Next track, Volume up/down | 1€ |
|
|
||||||
|
|
||||||
You'all also need an SD card, some breadboard(s), jumper cables and a soldering iron.
|
|
||||||
Also, some kind of box for the finished player.
|
|
||||||
|
|
||||||
## How to connect
|
|
||||||
|
|
||||||
Schematics coming soon...ish...
|
|
||||||
|
|
||||||
## How to install
|
|
||||||
|
|
||||||
Format your SD card with FAT32 and put files on it: Every album has
|
|
||||||
to go into its own folder in the root of the SD card. Folders and files
|
|
||||||
should not contain special characters (meaning stuff like äöüß). Spaces
|
|
||||||
and dashes an alike are okay. Put the SD card into the SD card slot.
|
|
||||||
|
|
||||||
Copy `include/config.sample.h` to `include/config.h`. Modify it to at
|
|
||||||
least contain the correct login details for your WiFi.
|
|
||||||
|
|
||||||
The code then should compile in PlatformIO without errors. Upload it
|
|
||||||
to your ESP32. After that, upload static files using PlatformIO's task
|
|
||||||
"Upload file system image".
|
|
||||||
|
|
||||||
The serial console in PlatformIO should give you more or less useful
|
|
||||||
messages about what's going on. There will also be a line saying
|
|
||||||
"WiFi connected. IP address: xxx.xxx.xxx.xxx" when the connection to
|
|
||||||
your WiFi succeeded.
|
|
||||||
|
|
||||||
In your browser, enter "http://xxx.xxx.xxx.xxx/" (using the IP address)
|
|
||||||
from above. From there you can define mappings between RFID tag IDs and
|
|
||||||
folders on the SD card.
|
|
||||||
|
|
||||||
## RFID-folder-mappings
|
|
||||||
|
|
||||||
### Via webinterface
|
|
||||||
|
|
||||||
To create a new mapping between an RFID tag and an folder, you can use
|
|
||||||
the web interface. Click the button with the cogs icon. After putting
|
|
||||||
your rfid tag on the reader (and possibly removing it again), its ID
|
|
||||||
will be shown in the dialog. Click the button with the arrows behind
|
|
||||||
the ID to start the mapping mode.
|
|
||||||
|
|
||||||
The dialog showing all folders with media files will be shown. Click the
|
|
||||||
button with the arrows behind the correct folder, to create the mapping.
|
|
||||||
|
|
||||||
### Manually
|
|
||||||
|
|
||||||
Mapping are stored on the SD card in the file `/_mapping.txt`. Every
|
|
||||||
mapping goes on its own line. Lines should be separated by \n (Unix-
|
|
||||||
style line endings); the last line should also end with a newline.
|
|
||||||
|
|
||||||
Format of a line is `<RFID id>=<folder>`. RFID id is the UID of an
|
|
||||||
RFID tag, expressed as 8 lowercase characters with leading 0 (if
|
|
||||||
necessary). Folder is the foldername to play; starting with a slash and
|
|
||||||
ending without one.
|
|
||||||
|
|
||||||
A valid `_mapping.txt` could look like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
1a2b3c4d=/Christmas Music Vol. 17
|
|
||||||
003aab7f=/Let it go
|
|
||||||
b691a22c=/Frozen Audiobook
|
|
||||||
22cb6ae9=/Let it go
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
(Yes, more than one tag can map to a folder.)
|
|
||||||
|
|
||||||
## Technical details
|
|
||||||
|
|
||||||
### Ports
|
|
||||||
|
|
||||||
| Device | Port | Connected to |
|
|
||||||
| ------ | ---- | ------------ |
|
|
||||||
| VS1053 | CS | 16 |
|
|
||||||
| VS1053 | MISO | 19 |
|
|
||||||
| VS1053 | MOSI | 23 |
|
|
||||||
| VS1053 | SCK | 18 |
|
|
||||||
| VS1053 | XCS | 4 |
|
|
||||||
| VS1053 | XRESET | 0 |
|
|
||||||
| VS1053 | XDCS | 2 |
|
|
||||||
| VS1053 | DREQ | 15 |
|
|
||||||
| RC522 | SDA | 17 |
|
|
||||||
| RC522 | SCK | 18 |
|
|
||||||
| RC522 | MOSI | 23 |
|
|
||||||
| RC522 | MISO | 19 |
|
|
||||||
| AMP_L | SD | 27 |
|
|
||||||
| AMP_R | SD | 26 |
|
|
||||||
| BTN_PREV | | 22 |
|
|
||||||
| BTN_NEXT | | 33 |
|
|
||||||
| BTN_VOL_UP | | 21 |
|
|
||||||
| BTN_VOL_DOWN | | 32 |
|
|
||||||
|
|
||||||
Buttons pull to GND if pushed -> Internal Pull-Up needed!
|
|
||||||
|
|
||||||
### RFID tags
|
|
||||||
The mapping of rfid tags to files uses the ID of the
|
|
||||||
tag. A file called `_mapping.txt` in the root folder of
|
|
||||||
the SD card defines the mappings between RFID tag ids and
|
|
||||||
folders to play.
|
|
||||||
|
|
||||||
The easiest way to create this file is to use the mapping
|
|
||||||
functionality of the webinterface.
|
|
||||||
|
|
||||||
#### Special modes
|
|
||||||
You can also save data on the tags to further manipulate
|
|
||||||
the system. Position of the data is irrelevant, the whole
|
|
||||||
tag will be searched.
|
|
||||||
|
|
||||||
Using `[random]` will play the files in a random order.
|
|
||||||
`[random:2]` will randomize everything except the first 2
|
|
||||||
files. This can be useful for having the favorite song of
|
|
||||||
your kids playing, but after that getting a bit of randomness.
|
|
||||||
|
|
||||||
Using `[lock]` will turn this key into a key for the locking
|
|
||||||
mode. Scanning the tag enables locking mode. The next album
|
|
||||||
started will keep running until the end. Removing the tag
|
|
||||||
will be deactivated, as are the buttons for prev and next
|
|
||||||
track. You can disable locking mode by again scanning the
|
|
||||||
lock tag again.
|
|
||||||
|
|
||||||
`[advent]` is used for christmas time. An album with this tag
|
|
||||||
will only play in December. On December 1st, only track 1
|
|
||||||
will play. On December 2nd, track 2 followed by track 1. On
|
|
||||||
December 3rd, tracks 3, 1 and 2. From December 24th on, track
|
|
||||||
24 followed by tracks 1-23. So your kid will get the "daily track"
|
|
||||||
first, followed by all previous tags in the right order.
|
|
||||||
|
|
||||||
#### API
|
|
||||||
You can send commands to ESMP3 using three different ways:
|
|
||||||
* Through a websocket connection to `ws://<IP>/ws`.
|
|
||||||
* Through the serial console using an USB cable.
|
|
||||||
* Via HTTP POST request to `http://<IP>/cmd`, having the
|
|
||||||
command in the variable `cmd`.
|
|
||||||
|
|
||||||
Supported commands are:
|
|
||||||
| Command | Action |
|
|
||||||
|---------|--------|
|
|
||||||
| `play <PATH>` | Starts playing the given path. Path may be a path on the
|
|
||||||
sd card or a http(s) URL of a webstream (direct links to mp3/4/ogg streams,
|
|
||||||
PLS files, M3U files or podcast XML feeds are supported). |
|
|
||||||
| `play` | Continues playing the previously played thing. |
|
|
||||||
| `stop` | Stops playing. |
|
|
||||||
| `volume=<X>` | Sets the volume to X (0-255). |
|
|
||||||
| `track_prev` | Starts the previous track, if available. |
|
|
||||||
| `track_next` | Starts the next track, if available. |
|
|
||||||
| `track=<X>` | Starts playing track no. X of the currently playing album. |
|
|
||||||
| `reset_vs1053` | Resets the VS1053 audio chip. |
|
|
||||||
| `reboot` | Reboots ESMP3. |
|
|
||||||
| `add_mapping=<ID>=<PATH>` | Adds a mapping between RFID card <ID> and path
|
|
||||||
<PATH>. See `play` for valid path formats. |
|
|
||||||
| `update` | Runs an update check. |
|
|
||||||
| `debug=<0|1>` | Enables / disables debug messages. This value is persisted across reboots. |
|
|
||||||
| `trace=<0|1>` | Enables / disables tracing messages. This value is also persisted across reboots. |
|
|
@ -27,5 +27,5 @@ class Controller {
|
|||||||
void play();
|
void play();
|
||||||
void play(String rfid_id, bool shuffle=false);
|
void play(String rfid_id, bool shuffle=false);
|
||||||
void stop();
|
void stop();
|
||||||
void eof_mp3();
|
void eof_mp3(String info);
|
||||||
};
|
};
|
@ -134,6 +134,9 @@ void Controller::play(String rfid_id, bool shuffle) {
|
|||||||
play();
|
play();
|
||||||
} else {
|
} else {
|
||||||
Serial.printf("There is no playlist for rfid_id %s\n", rfid_id.c_str());
|
Serial.printf("There is no playlist for rfid_id %s\n", rfid_id.c_str());
|
||||||
|
// This is working more or less, but downloading files is really, REALLY slow. (About 4 minutes for 10 MBytes).
|
||||||
|
//download_album(rfid_id);
|
||||||
|
audio.connecttoFS(SD, "/system/sys_unknown_card.mp3");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!audio.isRunning()) {
|
if (!audio.isRunning()) {
|
||||||
@ -150,6 +153,11 @@ void Controller::play() {
|
|||||||
audio.connecttoFS(SD, file.c_str(), current_playlist.get_current_time());
|
audio.connecttoFS(SD, file.c_str(), current_playlist.get_current_time());
|
||||||
} else if (file.startsWith("http")) {
|
} else if (file.startsWith("http")) {
|
||||||
log_i("Playing URL %s via connecttohost", file.c_str());
|
log_i("Playing URL %s via connecttohost", file.c_str());
|
||||||
|
audio.connecttoFS(SD, "/system/sys_connecting.mp3");
|
||||||
|
while (audio.isRunning()) {
|
||||||
|
yield();
|
||||||
|
audio.loop();
|
||||||
|
}
|
||||||
audio.connecttohost(file.c_str());
|
audio.connecttohost(file.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,8 +210,12 @@ bool Controller::is_button_pressed(uint8_t pin) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::eof_mp3() {
|
void Controller::eof_mp3(String info) {
|
||||||
log_d("Handling eof. Keep playing until the file is finished.");
|
log_d("Handling eof. Keep playing until the file is finished.");
|
||||||
while(audio.isRunning()) { audio.loop(); yield; }
|
while(audio.isRunning()) { audio.loop(); yield; }
|
||||||
|
if (info.startsWith("sys_")) {
|
||||||
|
log_d("File ending was a system audio file. Not running next_track.");
|
||||||
|
} else {
|
||||||
next_track();
|
next_track();
|
||||||
|
}
|
||||||
}
|
}
|
@ -94,6 +94,7 @@ void setup() {
|
|||||||
Serial.println("Setup finished.");
|
Serial.println("Setup finished.");
|
||||||
|
|
||||||
audio.setVolume(12);
|
audio.setVolume(12);
|
||||||
|
audio.connecttoFS(SD, "/system/sys_ready.mp3");
|
||||||
|
|
||||||
ftp.begin("", "");
|
ftp.begin("", "");
|
||||||
}
|
}
|
||||||
@ -113,7 +114,7 @@ void audio_id3data(const char *info){ //id3 metadata
|
|||||||
}
|
}
|
||||||
void audio_eof_mp3(const char *info){ //end of file
|
void audio_eof_mp3(const char *info){ //end of file
|
||||||
Serial.print("eof_mp3 ");Serial.println(info);
|
Serial.print("eof_mp3 ");Serial.println(info);
|
||||||
controller.eof_mp3();
|
controller.eof_mp3(info);
|
||||||
}
|
}
|
||||||
void audio_showstation(const char *info){
|
void audio_showstation(const char *info){
|
||||||
Serial.print("station ");Serial.println(info);
|
Serial.print("station ");Serial.println(info);
|
||||||
|
Loading…
Reference in New Issue
Block a user