-
6.gitignore
-
9Hardware-Plaforms/ESP32-A1S-Audiokit/src/main.cpp
-
21PCBs/ESP32_Breakout_Carrier/Readme.md
-
337PCBs/ESP32_Breakout_Carrier/Tonuino-ESP32_2-cache.lib
-
2410PCBs/ESP32_Breakout_Carrier/Tonuino-ESP32_2.kicad_pcb
-
2383PCBs/ESP32_Breakout_Carrier/Tonuino-ESP32_2.kicad_pcb-bak
-
414PCBs/ESP32_Breakout_Carrier/Tonuino-ESP32_2.net
-
248PCBs/ESP32_Breakout_Carrier/Tonuino-ESP32_2.pro
-
585PCBs/ESP32_Breakout_Carrier/Tonuino-ESP32_2.sch
-
585PCBs/ESP32_Breakout_Carrier/Tonuino-ESP32_2.sch-bak
-
33PCBs/ESP32_Breakout_Carrier/_autosave-Tonuino-ESP32_2.pro
-
BINPCBs/ESP32_Breakout_Carrier/assembled.jpeg
-
1PCBs/ESP32_Breakout_Carrier/fp-info-cache
-
0PCBs/Headphone with PCM5102a and TDA1308/KiCad/Kicad-Files.zip
-
0PCBs/Headphone with PCM5102a and TDA1308/Pictures/3D-model_downside.jpeg
-
0PCBs/Headphone with PCM5102a and TDA1308/Pictures/3D-model_upside.jpeg
-
0PCBs/Headphone with PCM5102a and TDA1308/Pictures/Headphone-pcb.pdf
-
0PCBs/Headphone with PCM5102a and TDA1308/Pictures/Headphone-pcb_downside.jpg
-
0PCBs/Headphone with PCM5102a and TDA1308/Pictures/Headphone-pcb_upside.jpg
-
2PCBs/Headphone with PCM5102a and TDA1308/README.md
-
BINPCBs/Headphone with PCM5102a and TDA1308/gerber/gerber.zip
-
BINPCBs/Wemos Lolin D32/Gerber/gerber.zip
-
BINPCBs/Wemos Lolin D32/KiCad/KICad-Files.zip
-
BINPCBs/Wemos Lolin D32/Pictures/Schematics_D32.pdf
-
BINPCBs/Wemos Lolin D32/Pictures/Tonuino D32_downside.jpg
-
BINPCBs/Wemos Lolin D32/Pictures/Tonuino D32_upside.jpg
-
63PCBs/Wemos Lolin D32/README.md
-
BINPCBs/Wemos Lolin32/Gerber/gerber.zip
-
BINPCBs/Wemos Lolin32/KiCad/Kicad-files.zip
-
BINPCBs/Wemos Lolin32/Pictures/Soldered with peripherals1_rev1.jpg
-
BINPCBs/Wemos Lolin32/Pictures/Soldered with peripherals2_rev1.jpg
-
BINPCBs/Wemos Lolin32/Pictures/Soldered1_rev1.jpg
-
BINPCBs/Wemos Lolin32/Pictures/Soldered2_rev1.jpg
-
BINPCBs/Wemos Lolin32/Pictures/Tonuino V2-Schematics.pdf
-
BINPCBs/Wemos Lolin32/Pictures/Tonuino V2_down.jpg
-
BINPCBs/Wemos Lolin32/Pictures/Tonuino V2_up.jpg
-
66PCBs/Wemos Lolin32/README.md
-
BINPCBs/Wemos Lolin32/_Archiv/rev1/Gerber/gerber.zip
-
BINPCBs/Wemos Lolin32/_Archiv/rev1/KiCad/Kicad-files.zip
-
BINPCBs/Wemos Lolin32/_Archiv/rev1/Pictures/3d-Model downside.jpg
-
BINPCBs/Wemos Lolin32/_Archiv/rev1/Pictures/3d-Model upside.jpg
-
BINPCBs/Wemos Lolin32/_Archiv/rev1/Pictures/Soldered with peripherals1.jpg
-
BINPCBs/Wemos Lolin32/_Archiv/rev1/Pictures/Soldered with peripherals2.jpg
-
BINPCBs/Wemos Lolin32/_Archiv/rev1/Pictures/Soldered1.jpg
-
BINPCBs/Wemos Lolin32/_Archiv/rev1/Pictures/Soldered2.jpg
-
BINPCBs/Wemos Lolin32/_Archiv/rev1/Pictures/Tonuino-Lolin32-Schematics.pdf
-
256README.md
-
64html/accesspoint.html
-
64html/accesspoint_EN.html
-
727html/management.html
-
727html/management_EN.html
-
359html/website.html
-
23html/websiteBasic.html
-
23html/websiteBasic_EN.html
-
263html/websiteMgmt.h
-
359html/website_EN.html
-
BINpictures/Mgmt-GUI1.jpg
-
BINpictures/Mgmt-GUI2.jpg
-
BINpictures/Mgmt-GUI3.jpg
-
BINpictures/Mgmt-GUI4.jpg
-
BINpictures/Mgmt-GUI5.jpg
-
BINpictures/Mgmt-GUI6.jpg
-
BINpictures/Mgmt-GUI7.jpg
-
BINpictures/Mgmt-GUI_connection_broken.jpg
-
BINpictures/Mgmt_GUI_action_ok.jpg
-
55platformio.ini
-
101processHtml.py
-
65src/HTMLaccesspoint.h
-
2src/HTMLaccesspoint_EN.h
-
728src/HTMLmanagement.h
-
24src/HTMLmanagement_EN.h
-
28src/logmessages.h
-
26src/logmessages_EN.h
-
1058src/main.cpp
-
66src/settings-espa1s.h
-
61src/settings-lolin32.h
-
117src/settings.h
-
24src/websiteBasic.h
-
360src/websiteMgmt.h
@ -1,6 +1,12 @@ |
|||
.pio |
|||
venv/ |
|||
.vscode/.browse.c_cpp.db* |
|||
.vscode/c_cpp_properties.json |
|||
.vscode/launch.json |
|||
.vscode/ipch |
|||
.DS_Store |
|||
.idea/ |
|||
CMakeLists.txt |
|||
CMakeListsPrivate.txt |
|||
cmake-build-az-delivery-devkit-v4/ |
|||
cmake-build-debug/ |
@ -0,0 +1,21 @@ |
|||
## Disclaimer |
|||
This PCB was kindly provided by a user (@mariolukas) of my Tonuino-fork and I didn't test it myself. |
|||
## ESP32 I2S Breakout Carrier PCB |
|||
This is a simple PCB which makes wiring the whole stuff much easier. It contains connections for all components which are described in the projects wiring table. An ESP32 from AZ-Delivery was used but every pin-Compatible ESP32-board will do the job. |
|||
|
|||
 |
|||
The image shows my first boards which came with a litte wiring bug. The bug is fixed in the current version. I ordered my board at aisler.net, there is already and upload available. |
|||
|
|||
[https://aisler.net/p/YTYZJZMM](https://aisler.net/p/YTYZJZMM) |
|||
|
|||
## Todos |
|||
This PCB does not provide an option for charing or power-management (including step down/up). It provides a pinout for 5V-input. |
|||
|
|||
## Antenna-improvements |
|||
It is recommended to solder an external antenna to the ESP32 for preventing connection issues. Cheap ESP32 boards come with an antenna which is laying on the PCB. The newer ones provide an ESP32-board where the antenna-part protrudes over the edge. |
|||
|
|||
You can find some useful tips for soldering an antenna to the old ones here: |
|||
[https://community.home-assistant.io/t/how-to-add-an-external-antenna-to-an-esp-board/131601](https://community.home-assistant.io/t/how-to-add-an-external-antenna-to-an-esp-board/131601) |
|||
|
|||
## Disclaimer |
|||
PCB-circuit is provided 'as is' without warranty. It was made to keep wiring much simpler. However: it runs fine without any problems in my Tonuinos. |
@ -0,0 +1,337 @@ |
|||
EESchema-LIBRARY Version 2.4 |
|||
#encoding utf-8 |
|||
# |
|||
# Connector_Conn_01x02_Male |
|||
# |
|||
DEF Connector_Conn_01x02_Male J 0 40 Y N 1 F N |
|||
F0 "J" 0 100 50 H V C CNN |
|||
F1 "Connector_Conn_01x02_Male" 0 -200 50 H V C CNN |
|||
F2 "" 0 0 50 H I C CNN |
|||
F3 "" 0 0 50 H I C CNN |
|||
$FPLIST |
|||
Connector*:*_1x??_* |
|||
$ENDFPLIST |
|||
DRAW |
|||
S 34 -95 0 -105 1 1 6 F |
|||
S 34 5 0 -5 1 1 6 F |
|||
P 2 1 1 6 50 -100 34 -100 N |
|||
P 2 1 1 6 50 0 34 0 N |
|||
X Pin_1 1 200 0 150 L 50 50 1 1 P |
|||
X Pin_2 2 200 -100 150 L 50 50 1 1 P |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# Connector_Conn_01x03_Male |
|||
# |
|||
DEF Connector_Conn_01x03_Male J 0 40 Y N 1 F N |
|||
F0 "J" 0 200 50 H V C CNN |
|||
F1 "Connector_Conn_01x03_Male" 0 -200 50 H V C CNN |
|||
F2 "" 0 0 50 H I C CNN |
|||
F3 "" 0 0 50 H I C CNN |
|||
$FPLIST |
|||
Connector*:*_1x??_* |
|||
$ENDFPLIST |
|||
DRAW |
|||
S 34 -95 0 -105 1 1 6 F |
|||
S 34 5 0 -5 1 1 6 F |
|||
S 34 105 0 95 1 1 6 F |
|||
P 2 1 1 6 50 -100 34 -100 N |
|||
P 2 1 1 6 50 0 34 0 N |
|||
P 2 1 1 6 50 100 34 100 N |
|||
X Pin_1 1 200 100 150 L 50 50 1 1 P |
|||
X Pin_2 2 200 0 150 L 50 50 1 1 P |
|||
X Pin_3 3 200 -100 150 L 50 50 1 1 P |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# Connector_Conn_01x05_Male |
|||
# |
|||
DEF Connector_Conn_01x05_Male J 0 40 Y N 1 F N |
|||
F0 "J" 0 300 50 H V C CNN |
|||
F1 "Connector_Conn_01x05_Male" 0 -300 50 H V C CNN |
|||
F2 "" 0 0 50 H I C CNN |
|||
F3 "" 0 0 50 H I C CNN |
|||
$FPLIST |
|||
Connector*:*_1x??_* |
|||
$ENDFPLIST |
|||
DRAW |
|||
S 34 -195 0 -205 1 1 6 F |
|||
S 34 -95 0 -105 1 1 6 F |
|||
S 34 5 0 -5 1 1 6 F |
|||
S 34 105 0 95 1 1 6 F |
|||
S 34 205 0 195 1 1 6 F |
|||
P 2 1 1 6 50 -200 34 -200 N |
|||
P 2 1 1 6 50 -100 34 -100 N |
|||
P 2 1 1 6 50 0 34 0 N |
|||
P 2 1 1 6 50 100 34 100 N |
|||
P 2 1 1 6 50 200 34 200 N |
|||
X Pin_1 1 200 200 150 L 50 50 1 1 P |
|||
X Pin_2 2 200 100 150 L 50 50 1 1 P |
|||
X Pin_3 3 200 0 150 L 50 50 1 1 P |
|||
X Pin_4 4 200 -100 150 L 50 50 1 1 P |
|||
X Pin_5 5 200 -200 150 L 50 50 1 1 P |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# Connector_Conn_01x06_Male |
|||
# |
|||
DEF Connector_Conn_01x06_Male J 0 40 Y N 1 F N |
|||
F0 "J" 0 300 50 H V C CNN |
|||
F1 "Connector_Conn_01x06_Male" 0 -400 50 H V C CNN |
|||
F2 "" 0 0 50 H I C CNN |
|||
F3 "" 0 0 50 H I C CNN |
|||
$FPLIST |
|||
Connector*:*_1x??_* |
|||
$ENDFPLIST |
|||
DRAW |
|||
S 34 -295 0 -305 1 1 6 F |
|||
S 34 -195 0 -205 1 1 6 F |
|||
S 34 -95 0 -105 1 1 6 F |
|||
S 34 5 0 -5 1 1 6 F |
|||
S 34 105 0 95 1 1 6 F |
|||
S 34 205 0 195 1 1 6 F |
|||
P 2 1 1 6 50 -300 34 -300 N |
|||
P 2 1 1 6 50 -200 34 -200 N |
|||
P 2 1 1 6 50 -100 34 -100 N |
|||
P 2 1 1 6 50 0 34 0 N |
|||
P 2 1 1 6 50 100 34 100 N |
|||
P 2 1 1 6 50 200 34 200 N |
|||
X Pin_1 1 200 200 150 L 50 50 1 1 P |
|||
X Pin_2 2 200 100 150 L 50 50 1 1 P |
|||
X Pin_3 3 200 0 150 L 50 50 1 1 P |
|||
X Pin_4 4 200 -100 150 L 50 50 1 1 P |
|||
X Pin_5 5 200 -200 150 L 50 50 1 1 P |
|||
X Pin_6 6 200 -300 150 L 50 50 1 1 P |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# Connector_Conn_01x07_Male |
|||
# |
|||
DEF Connector_Conn_01x07_Male J 0 40 Y N 1 F N |
|||
F0 "J" 0 400 50 H V C CNN |
|||
F1 "Connector_Conn_01x07_Male" 0 -400 50 H V C CNN |
|||
F2 "" 0 0 50 H I C CNN |
|||
F3 "" 0 0 50 H I C CNN |
|||
$FPLIST |
|||
Connector*:*_1x??_* |
|||
$ENDFPLIST |
|||
DRAW |
|||
S 34 -295 0 -305 1 1 6 F |
|||
S 34 -195 0 -205 1 1 6 F |
|||
S 34 -95 0 -105 1 1 6 F |
|||
S 34 5 0 -5 1 1 6 F |
|||
S 34 105 0 95 1 1 6 F |
|||
S 34 205 0 195 1 1 6 F |
|||
S 34 305 0 295 1 1 6 F |
|||
P 2 1 1 6 50 -300 34 -300 N |
|||
P 2 1 1 6 50 -200 34 -200 N |
|||
P 2 1 1 6 50 -100 34 -100 N |
|||
P 2 1 1 6 50 0 34 0 N |
|||
P 2 1 1 6 50 100 34 100 N |
|||
P 2 1 1 6 50 200 34 200 N |
|||
P 2 1 1 6 50 300 34 300 N |
|||
X Pin_1 1 200 300 150 L 50 50 1 1 P |
|||
X Pin_2 2 200 200 150 L 50 50 1 1 P |
|||
X Pin_3 3 200 100 150 L 50 50 1 1 P |
|||
X Pin_4 4 200 0 150 L 50 50 1 1 P |
|||
X Pin_5 5 200 -100 150 L 50 50 1 1 P |
|||
X Pin_6 6 200 -200 150 L 50 50 1 1 P |
|||
X Pin_7 7 200 -300 150 L 50 50 1 1 P |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# Connector_Conn_01x08_Male |
|||
# |
|||
DEF Connector_Conn_01x08_Male J 0 40 Y N 1 F N |
|||
F0 "J" 0 400 50 H V C CNN |
|||
F1 "Connector_Conn_01x08_Male" 0 -500 50 H V C CNN |
|||
F2 "" 0 0 50 H I C CNN |
|||
F3 "" 0 0 50 H I C CNN |
|||
$FPLIST |
|||
Connector*:*_1x??_* |
|||
$ENDFPLIST |
|||
DRAW |
|||
S 34 -395 0 -405 1 1 6 F |
|||
S 34 -295 0 -305 1 1 6 F |
|||
S 34 -195 0 -205 1 1 6 F |
|||
S 34 -95 0 -105 1 1 6 F |
|||
S 34 5 0 -5 1 1 6 F |
|||
S 34 105 0 95 1 1 6 F |
|||
S 34 205 0 195 1 1 6 F |
|||
S 34 305 0 295 1 1 6 F |
|||
P 2 1 1 6 50 -400 34 -400 N |
|||
P 2 1 1 6 50 -300 34 -300 N |
|||
P 2 1 1 6 50 -200 34 -200 N |
|||
P 2 1 1 6 50 -100 34 -100 N |
|||
P 2 1 1 6 50 0 34 0 N |
|||
P 2 1 1 6 50 100 34 100 N |
|||
P 2 1 1 6 50 200 34 200 N |
|||
P 2 1 1 6 50 300 34 300 N |
|||
X Pin_1 1 200 300 150 L 50 50 1 1 P |
|||
X Pin_2 2 200 200 150 L 50 50 1 1 P |
|||
X Pin_3 3 200 100 150 L 50 50 1 1 P |
|||
X Pin_4 4 200 0 150 L 50 50 1 1 P |
|||
X Pin_5 5 200 -100 150 L 50 50 1 1 P |
|||
X Pin_6 6 200 -200 150 L 50 50 1 1 P |
|||
X Pin_7 7 200 -300 150 L 50 50 1 1 P |
|||
X Pin_8 8 200 -400 150 L 50 50 1 1 P |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# Device_R |
|||
# |
|||
DEF Device_R R 0 0 N Y 1 F N |
|||
F0 "R" 80 0 50 V V C CNN |
|||
F1 "Device_R" 0 0 50 V V C CNN |
|||
F2 "" -70 0 50 V I C CNN |
|||
F3 "" 0 0 50 H I C CNN |
|||
$FPLIST |
|||
R_* |
|||
$ENDFPLIST |
|||
DRAW |
|||
S -40 -100 40 100 0 1 10 N |
|||
X ~ 1 0 150 50 D 50 50 1 1 P |
|||
X ~ 2 0 -150 50 U 50 50 1 1 P |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# ESP32-DEVKITC-32U_ESP32-DEVKITC-32U |
|||
# |
|||
DEF ESP32-DEVKITC-32U_ESP32-DEVKITC-32U U 0 40 Y Y 1 L N |
|||
F0 "U" -601 1026 50 H V L BNN |
|||
F1 "ESP32-DEVKITC-32U_ESP32-DEVKITC-32U" -601 -1101 50 H V L BNN |
|||
F2 "MODULE_ESP32-DEVKITC-32U" 0 0 50 H I L BNN |
|||
F3 "Manufacturer Recommendations" 0 0 50 H I L BNN |
|||
F4 "ESPRESSIF" 0 0 50 H I L BNN |
|||
F5 "N/A" 0 0 50 H I L BNN |
|||
DRAW |
|||
P 2 0 0 10 -600 -1000 -600 1000 N |
|||
P 2 0 0 10 -600 1000 600 1000 N |
|||
P 2 0 0 10 600 -1000 -600 -1000 N |
|||
P 2 0 0 10 600 1000 600 -1000 N |
|||
X 3V3 1 -800 900 200 R 40 40 0 0 W |
|||
X IO26 10 -800 0 200 R 40 40 0 0 B |
|||
X IO27 11 -800 -100 200 R 40 40 0 0 B |
|||
X IO14 12 -800 -200 200 R 40 40 0 0 B |
|||
X IO12 13 -800 -300 200 R 40 40 0 0 B |
|||
X GND1 14 -800 -400 200 R 40 40 0 0 W |
|||
X IO13 15 -800 -500 200 R 40 40 0 0 B |
|||
X SD2 16 -800 -600 200 R 40 40 0 0 B |
|||
X SD3 17 -800 -700 200 R 40 40 0 0 B |
|||
X CMD 18 -800 -800 200 R 40 40 0 0 B |
|||
X EXT_5V 19 -800 -900 200 R 40 40 0 0 W |
|||
X EN 2 -800 800 200 R 40 40 0 0 I |
|||
X CLK 20 800 -900 200 L 40 40 0 0 I C |
|||
X SD0 21 800 -800 200 L 40 40 0 0 B |
|||
X SD1 22 800 -700 200 L 40 40 0 0 B |
|||
X IO15 23 800 -600 200 L 40 40 0 0 B |
|||
X IO2 24 800 -500 200 L 40 40 0 0 B |
|||
X IO0 25 800 -400 200 L 40 40 0 0 B |
|||
X IO4 26 800 -300 200 L 40 40 0 0 B |
|||
X IO16 27 800 -200 200 L 40 40 0 0 B |
|||
X IO17 28 800 -100 200 L 40 40 0 0 B |
|||
X IO5 29 800 0 200 L 40 40 0 0 B |
|||
X SENSOR_VP 3 -800 700 200 R 40 40 0 0 I |
|||
X IO18 30 800 100 200 L 40 40 0 0 B |
|||
X IO19 31 800 200 200 L 40 40 0 0 B |
|||
X GND2 32 800 300 200 L 40 40 0 0 W |
|||
X IO21 33 800 400 200 L 40 40 0 0 B |
|||
X RXD0 34 800 500 200 L 40 40 0 0 I |
|||
X TXD0 35 800 600 200 L 40 40 0 0 O |
|||
X IO22 36 800 700 200 L 40 40 0 0 B |
|||
X IO23 37 800 800 200 L 40 40 0 0 B |
|||
X GND3 38 800 900 200 L 40 40 0 0 W |
|||
X SENSOR_VN 4 -800 600 200 R 40 40 0 0 I |
|||
X IO34 5 -800 500 200 R 40 40 0 0 B |
|||
X IO35 6 -800 400 200 R 40 40 0 0 B |
|||
X IO32 7 -800 300 200 R 40 40 0 0 B |
|||
X IO33 8 -800 200 200 R 40 40 0 0 B |
|||
X IO25 9 -800 100 200 R 40 40 0 0 B |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# Transistor_BJT_BC337 |
|||
# |
|||
DEF Transistor_BJT_BC337 Q 0 0 Y N 1 F N |
|||
F0 "Q" 200 75 50 H V L CNN |
|||
F1 "Transistor_BJT_BC337" 200 0 50 H V L CNN |
|||
F2 "Package_TO_SOT_THT:TO-92_Inline" 200 -75 50 H I L CIN |
|||
F3 "" 0 0 50 H I L CNN |
|||
ALIAS BC546 BC548 BC549 BC550 BC337 BC338 |
|||
$FPLIST |
|||
TO?92* |
|||
$ENDFPLIST |
|||
DRAW |
|||
C 50 0 111 0 1 10 N |
|||
P 2 0 1 0 0 0 25 0 N |
|||
P 2 0 1 0 25 25 100 100 N |
|||
P 3 0 1 0 25 -25 100 -100 100 -100 N |
|||
P 3 0 1 20 25 75 25 -75 25 -75 N |
|||
P 5 0 1 0 50 -70 70 -50 90 -90 50 -70 50 -70 F |
|||
X C 1 100 200 100 D 50 50 1 1 P |
|||
X B 2 -200 0 200 R 50 50 1 1 I |
|||
X E 3 100 -200 100 U 50 50 1 1 P |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# Transistor_FET_IRF9540N |
|||
# |
|||
DEF Transistor_FET_IRF9540N Q 0 20 Y N 1 F N |
|||
F0 "Q" 200 75 50 H V L CNN |
|||
F1 "Transistor_FET_IRF9540N" 200 0 50 H V L CNN |
|||
F2 "Package_TO_SOT_THT:TO-220-3_Vertical" 200 -75 50 H I L CIN |
|||
F3 "" 0 0 50 H I L CNN |
|||
ALIAS IRF4905 FQP27P06 |
|||
$FPLIST |
|||
TO?220* |
|||
$ENDFPLIST |
|||
DRAW |
|||
C 65 0 110 0 1 10 N |
|||
C 100 -70 10 0 1 0 F |
|||
C 100 70 10 0 1 0 F |
|||
P 2 0 1 0 10 0 -100 0 N |
|||
P 2 0 1 10 10 75 10 -75 N |
|||
P 2 0 1 10 30 -50 30 -90 N |
|||
P 2 0 1 10 30 20 30 -20 N |
|||
P 2 0 1 10 30 90 30 50 N |
|||
P 2 0 1 0 100 100 100 70 N |
|||
P 3 0 1 0 100 -100 100 0 30 0 N |
|||
P 4 0 1 0 30 70 130 70 130 -70 30 -70 N |
|||
P 4 0 1 0 90 0 50 15 50 -15 90 0 F |
|||
P 4 0 1 0 110 -20 115 -15 145 -15 150 -10 N |
|||
P 4 0 1 0 130 -15 115 10 145 10 130 -15 N |
|||
X G 1 -200 0 100 R 50 50 1 1 I |
|||
X D 2 100 200 100 D 50 50 1 1 P |
|||
X S 3 100 -200 100 U 50 50 1 1 P |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# power_GND |
|||
# |
|||
DEF power_GND #PWR 0 0 Y Y 1 F P |
|||
F0 "#PWR" 0 -250 50 H I C CNN |
|||
F1 "power_GND" 0 -150 50 H V C CNN |
|||
F2 "" 0 0 50 H I C CNN |
|||
F3 "" 0 0 50 H I C CNN |
|||
DRAW |
|||
P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N |
|||
X GND 1 0 0 0 D 50 50 1 1 W N |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
# power_VCC |
|||
# |
|||
DEF power_VCC #PWR 0 0 Y Y 1 F P |
|||
F0 "#PWR" 0 -150 50 H I C CNN |
|||
F1 "power_VCC" 0 150 50 H V C CNN |
|||
F2 "" 0 0 50 H I C CNN |
|||
F3 "" 0 0 50 H I C CNN |
|||
DRAW |
|||
P 2 0 1 0 -30 50 0 100 N |
|||
P 2 0 1 0 0 0 0 100 N |
|||
P 2 0 1 0 0 100 30 50 N |
|||
X VCC 1 0 0 0 U 50 50 1 1 W N |
|||
ENDDRAW |
|||
ENDDEF |
|||
# |
|||
#End Library |
2410
PCBs/ESP32_Breakout_Carrier/Tonuino-ESP32_2.kicad_pcb
File diff suppressed because it is too large
View File
2383
PCBs/ESP32_Breakout_Carrier/Tonuino-ESP32_2.kicad_pcb-bak
File diff suppressed because it is too large
View File
@ -0,0 +1,414 @@ |
|||
(export (version D) |
|||
(design |
|||
(source /Users/mariolukas/Documents/KiCad/projects/Tonuino-ESP32_2/Tonuino-ESP32_2.sch) |
|||
(date "2020 October 11, Sunday 21:15:14") |
|||
(tool "Eeschema (5.1.7-0-10_14)") |
|||
(sheet (number 1) (name /) (tstamps /) |
|||
(title_block |
|||
(title) |
|||
(company) |
|||
(rev) |
|||
(date) |
|||
(source Tonuino-ESP32_2.sch) |
|||
(comment (number 1) (value "")) |
|||
(comment (number 2) (value "")) |
|||
(comment (number 3) (value "")) |
|||
(comment (number 4) (value ""))))) |
|||
(components |
|||
(comp (ref U1) |
|||
(value ESP32-DEVKITC-32U) |
|||
(footprint ESP32-DEVKITC-32U:MODULE_ESP32-DEVKITC-32U) |
|||
(datasheet "Manufacturer Recommendations") |
|||
(fields |
|||
(field (name Field4) ESPRESSIF) |
|||
(field (name Field5) N/A)) |
|||
(libsource (lib ESP32-DEVKITC-32U) (part ESP32-DEVKITC-32U) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F79096D)) |
|||
(comp (ref J4) |
|||
(value "Rotary Encode") |
|||
(footprint mod_s:PinHeader_1x05_P2.54mm_Vertical) |
|||
(libsource (lib Connector) (part Conn_01x05_Male) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F7BD0A2)) |
|||
(comp (ref J1) |
|||
(value "SD-Card Reader") |
|||
(footprint mod_s:PinHeader_1x06_P2.54mm_Vertical) |
|||
(libsource (lib Connector) (part Conn_01x06_Male) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F7ED32A)) |
|||
(comp (ref J3) |
|||
(value "Adafruit MAX98357") |
|||
(footprint mod_s:PinHeader_1x07_P2.54mm_Vertical) |
|||
(libsource (lib Connector) (part Conn_01x07_Male) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F81C714)) |
|||
(comp (ref J5) |
|||
(value Next) |
|||
(footprint mod_s:PinHeader_1x02_P2.54mm_Vertical) |
|||
(libsource (lib Connector) (part Conn_01x02_Male) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F9085EF)) |
|||
(comp (ref J6) |
|||
(value Prev) |
|||
(footprint mod_s:PinHeader_1x02_P2.54mm_Vertical) |
|||
(libsource (lib Connector) (part Conn_01x02_Male) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F90EAED)) |
|||
(comp (ref J7) |
|||
(value Pause) |
|||
(footprint mod_s:PinHeader_1x02_P2.54mm_Vertical) |
|||
(libsource (lib Connector) (part Conn_01x02_Male) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F90F726)) |
|||
(comp (ref J2) |
|||
(value RFID-RC522) |
|||
(footprint mod_s:PinHeader_1x08_P2.54mm_Vertical) |
|||
(libsource (lib Connector) (part Conn_01x08_Male) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F92011C)) |
|||
(comp (ref J8) |
|||
(value WS2812) |
|||
(footprint mod_s:PinHeader_1x03_P2.54mm_Vertical) |
|||
(libsource (lib Connector) (part Conn_01x03_Male) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F936A23)) |
|||
(comp (ref J9) |
|||
(value Power) |
|||
(footprint mod_s:PinHeader_1x02_P2.54mm_Vertical) |
|||
(libsource (lib Connector) (part Conn_01x02_Male) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F945F11)) |
|||
(comp (ref R5) |
|||
(value 4,7k) |
|||
(footprint adafruit:0207_9) |
|||
(libsource (lib Device) (part R) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F7995ED)) |
|||
(comp (ref R4) |
|||
(value 10k) |
|||
(footprint adafruit:0207_9) |
|||
(libsource (lib Device) (part R) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F798E7D)) |
|||
(comp (ref Q1) |
|||
(value BC337) |
|||
(footprint Package_TO_SOT_THT:TO-92_Inline_Wide) |
|||
(libsource (lib Transistor_BJT) (part BC337) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F78DA7C)) |
|||
(comp (ref Q2) |
|||
(value IRF9540N) |
|||
(footprint Package_TO_SOT_THT:TO-220-3_Vertical) |
|||
(libsource (lib Transistor_FET) (part IRF9540N) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F78F572)) |
|||
(comp (ref R1) |
|||
(value 10k) |
|||
(footprint adafruit:0207_9) |
|||
(libsource (lib Device) (part R) (description "")) |
|||
(sheetpath (names /) (tstamps /)) |
|||
(tstamp 5F79873B))) |
|||
(libparts |
|||
(libpart (lib Connector) (part Conn_01x02_Male) |
|||
(footprints |
|||
(fp Connector*:*_1x??_*)) |
|||
(fields |
|||
(field (name Reference) J) |
|||
(field (name Value) Conn_01x02_Male)) |
|||
(pins |
|||
(pin (num 1) (name Pin_1) (type passive)) |
|||
(pin (num 2) (name Pin_2) (type passive)))) |
|||
(libpart (lib Connector) (part Conn_01x03_Male) |
|||
(footprints |
|||
(fp Connector*:*_1x??_*)) |
|||
(fields |
|||
(field (name Reference) J) |
|||
(field (name Value) Conn_01x03_Male)) |
|||
(pins |
|||
(pin (num 1) (name Pin_1) (type passive)) |
|||
(pin (num 2) (name Pin_2) (type passive)) |
|||
(pin (num 3) (name Pin_3) (type passive)))) |
|||
(libpart (lib Connector) (part Conn_01x05_Male) |
|||
(footprints |
|||
(fp Connector*:*_1x??_*)) |
|||
(fields |
|||
(field (name Reference) J) |
|||
(field (name Value) Conn_01x05_Male)) |
|||
(pins |
|||
(pin (num 1) (name Pin_1) (type passive)) |
|||
(pin (num 2) (name Pin_2) (type passive)) |
|||
(pin (num 3) (name Pin_3) (type passive)) |
|||
(pin (num 4) (name Pin_4) (type passive)) |
|||
(pin (num 5) (name Pin_5) (type passive)))) |
|||
(libpart (lib Connector) (part Conn_01x06_Male) |
|||
(footprints |
|||
(fp Connector*:*_1x??_*)) |
|||
(fields |
|||
(field (name Reference) J) |
|||
(field (name Value) Conn_01x06_Male)) |
|||
(pins |
|||
(pin (num 1) (name Pin_1) (type passive)) |
|||
(pin (num 2) (name Pin_2) (type passive)) |
|||
(pin (num 3) (name Pin_3) (type passive)) |
|||
(pin (num 4) (name Pin_4) (type passive)) |
|||
(pin (num 5) (name Pin_5) (type passive)) |
|||
(pin (num 6) (name Pin_6) (type passive)))) |
|||
(libpart (lib Connector) (part Conn_01x07_Male) |
|||
(footprints |
|||
(fp Connector*:*_1x??_*)) |
|||
(fields |
|||
(field (name Reference) J) |
|||
(field (name Value) Conn_01x07_Male)) |
|||
(pins |
|||
(pin (num 1) (name Pin_1) (type passive)) |
|||
(pin (num 2) (name Pin_2) (type passive)) |
|||
(pin (num 3) (name Pin_3) (type passive)) |
|||
(pin (num 4) (name Pin_4) (type passive)) |
|||
(pin (num 5) (name Pin_5) (type passive)) |
|||
(pin (num 6) (name Pin_6) (type passive)) |
|||
(pin (num 7) (name Pin_7) (type passive)))) |
|||
(libpart (lib Connector) (part Conn_01x08_Male) |
|||
(footprints |
|||
(fp Connector*:*_1x??_*)) |
|||
(fields |
|||
(field (name Reference) J) |
|||
(field (name Value) Conn_01x08_Male)) |
|||
(pins |
|||
(pin (num 1) (name Pin_1) (type passive)) |
|||
(pin (num 2) (name Pin_2) (type passive)) |
|||
(pin (num 3) (name Pin_3) (type passive)) |
|||
(pin (num 4) (name Pin_4) (type passive)) |
|||
(pin (num 5) (name Pin_5) (type passive)) |
|||
(pin (num 6) (name Pin_6) (type passive)) |
|||
(pin (num 7) (name Pin_7) (type passive)) |
|||
(pin (num 8) (name Pin_8) (type passive)))) |
|||
(libpart (lib Device) (part R) |
|||
(footprints |
|||
(fp R_*)) |
|||
(fields |
|||
(field (name Reference) R) |
|||
(field (name Value) R)) |
|||
(pins |
|||
(pin (num 1) (name ~) (type passive)) |
|||
(pin (num 2) (name ~) (type passive)))) |
|||
(libpart (lib ESP32-DEVKITC-32U) (part ESP32-DEVKITC-32U) |
|||
(fields |
|||
(field (name Reference) U) |
|||
(field (name Value) ESP32-DEVKITC-32U) |
|||
(field (name Footprint) MODULE_ESP32-DEVKITC-32U) |
|||
(field (name Datasheet) "Manufacturer Recommendations") |
|||
(field (name Field4) ESPRESSIF) |
|||
(field (name Field5) N/A)) |
|||
(pins |
|||
(pin (num 1) (name 3V3) (type power_in)) |
|||
(pin (num 2) (name EN) (type input)) |
|||
(pin (num 3) (name SENSOR_VP) (type input)) |
|||
(pin (num 4) (name SENSOR_VN) (type input)) |
|||
(pin (num 5) (name IO34) (type BiDi)) |
|||
(pin (num 6) (name IO35) (type BiDi)) |
|||
(pin (num 7) (name IO32) (type BiDi)) |
|||
(pin (num 8) (name IO33) (type BiDi)) |
|||
(pin (num 9) (name IO25) (type BiDi)) |
|||
(pin (num 10) (name IO26) (type BiDi)) |
|||
(pin (num 11) (name IO27) (type BiDi)) |
|||
(pin (num 12) (name IO14) (type BiDi)) |
|||
(pin (num 13) (name IO12) (type BiDi)) |
|||
(pin (num 14) (name GND1) (type power_in)) |
|||
(pin (num 15) (name IO13) (type BiDi)) |
|||
(pin (num 16) (name SD2) (type BiDi)) |
|||
(pin (num 17) (name SD3) (type BiDi)) |
|||
(pin (num 18) (name CMD) (type BiDi)) |
|||
(pin (num 19) (name EXT_5V) (type power_in)) |
|||
(pin (num 20) (name CLK) (type input)) |
|||
(pin (num 21) (name SD0) (type BiDi)) |
|||
(pin (num 22) (name SD1) (type BiDi)) |
|||
(pin (num 23) (name IO15) (type BiDi)) |
|||
(pin (num 24) (name IO2) (type BiDi)) |
|||
(pin (num 25) (name IO0) (type BiDi)) |
|||
(pin (num 26) (name IO4) (type BiDi)) |
|||
(pin (num 27) (name IO16) (type BiDi)) |
|||
(pin (num 28) (name IO17) (type BiDi)) |
|||
(pin (num 29) (name IO5) (type BiDi)) |
|||
(pin (num 30) (name IO18) (type BiDi)) |
|||
(pin (num 31) (name IO19) (type BiDi)) |
|||
(pin (num 32) (name GND2) (type power_in)) |
|||
(pin (num 33) (name IO21) (type BiDi)) |
|||
(pin (num 34) (name RXD0) (type input)) |
|||
(pin (num 35) (name TXD0) (type output)) |
|||
(pin (num 36) (name IO22) (type BiDi)) |
|||
(pin (num 37) (name IO23) (type BiDi)) |
|||
(pin (num 38) (name GND3) (type power_in)))) |
|||
(libpart (lib Transistor_BJT) (part BC547) |
|||
(aliases |
|||
(alias BC546) |
|||
(alias BC548) |
|||
(alias BC549) |
|||
(alias BC550) |
|||
(alias BC337) |
|||
(alias BC338)) |
|||
(footprints |
|||
(fp TO?92*)) |
|||
(fields |
|||
(field (name Reference) Q) |
|||
(field (name Value) BC547) |
|||
(field (name Footprint) Package_TO_SOT_THT:TO-92_Inline)) |
|||
(pins |
|||
(pin (num 1) (name C) (type passive)) |
|||
(pin (num 2) (name B) (type input)) |
|||
(pin (num 3) (name E) (type passive)))) |
|||
(libpart (lib Transistor_FET) (part IRF9540N) |
|||
(aliases |
|||
(alias IRF4905) |
|||
(alias FQP27P06)) |
|||
(footprints |
|||
(fp TO?220*)) |
|||
(fields |
|||
(field (name Reference) Q) |
|||
(field (name Value) IRF9540N) |
|||
(field (name Footprint) Package_TO_SOT_THT:TO-220-3_Vertical)) |
|||
(pins |
|||
(pin (num 1) (name G) (type input)) |
|||
(pin (num 2) (name D) (type passive)) |
|||
(pin (num 3) (name S) (type passive))))) |
|||
(libraries |
|||
(library (logical Connector) |
|||
(uri /Users/mariolukas/Documents/KiCad/libs/Connector.lib)) |
|||
(library (logical Device) |
|||
(uri /Users/mariolukas/Documents/KiCad/libs/Device.lib)) |
|||
(library (logical ESP32-DEVKITC-32U) |
|||
(uri /Users/mariolukas/Documents/KiCad/libs/ESP32-DEVKITC-32U.lib)) |
|||
(library (logical Transistor_BJT) |
|||
(uri /Users/mariolukas/Documents/KiCad/libs/Transistor_BJT.lib)) |
|||
(library (logical Transistor_FET) |
|||
(uri /Users/mariolukas/Documents/KiCad/libs/Transistor_FET.lib))) |
|||
(nets |
|||
(net (code 1) (name "Net-(U1-Pad2)") |
|||
(node (ref U1) (pin 2))) |
|||
(net (code 2) (name "Net-(U1-Pad3)") |
|||
(node (ref U1) (pin 3))) |
|||
(net (code 3) (name "Net-(U1-Pad4)") |
|||
(node (ref U1) (pin 4))) |
|||
(net (code 4) (name "Net-(U1-Pad16)") |
|||
(node (ref U1) (pin 16))) |
|||
(net (code 5) (name "Net-(U1-Pad17)") |
|||
(node (ref U1) (pin 17))) |
|||
(net (code 6) (name "Net-(U1-Pad18)") |
|||
(node (ref U1) (pin 18))) |
|||
(net (code 7) (name "Net-(U1-Pad20)") |
|||
(node (ref U1) (pin 20))) |
|||
(net (code 8) (name "Net-(U1-Pad21)") |
|||
(node (ref U1) (pin 21))) |
|||
(net (code 9) (name "Net-(U1-Pad22)") |
|||
(node (ref U1) (pin 22))) |
|||
(net (code 10) (name "Net-(U1-Pad24)") |
|||
(node (ref U1) (pin 24))) |
|||
(net (code 11) (name "Net-(U1-Pad25)") |
|||
(node (ref U1) (pin 25))) |
|||
(net (code 12) (name "Net-(U1-Pad34)") |
|||
(node (ref U1) (pin 34))) |
|||
(net (code 13) (name "Net-(U1-Pad35)") |
|||
(node (ref U1) (pin 35))) |
|||
(net (code 14) (name "Net-(J3-Pad3)") |
|||
(node (ref J3) (pin 3))) |
|||
(net (code 15) (name "Net-(J3-Pad4)") |
|||
(node (ref J3) (pin 4))) |
|||
(net (code 16) (name GPIO-17) |
|||
(node (ref J2) (pin 1)) |
|||
(node (ref U1) (pin 28)) |
|||
(node (ref R5) (pin 2))) |
|||
(net (code 17) (name SWITCHED_VCC) |
|||
(node (ref J8) (pin 3)) |
|||
(node (ref J3) (pin 1)) |
|||
(node (ref J1) (pin 2)) |
|||
(node (ref Q2) (pin 2))) |
|||
(net (code 18) (name GND) |
|||
(node (ref U1) (pin 38)) |
|||
(node (ref J4) (pin 1)) |
|||
(node (ref Q1) (pin 3)) |
|||
(node (ref R4) (pin 2)) |
|||
(node (ref J1) (pin 1)) |
|||
(node (ref J9) (pin 1)) |
|||
(node (ref U1) (pin 32)) |
|||
(node (ref J3) (pin 2)) |
|||
(node (ref J8) (pin 1)) |
|||
(node (ref J2) (pin 3)) |
|||
(node (ref J7) (pin 1)) |
|||
(node (ref J6) (pin 1)) |
|||
(node (ref J5) (pin 1)) |
|||
(node (ref U1) (pin 14))) |
|||
(net (code 19) (name 3.3V) |
|||
(node (ref U1) (pin 1)) |
|||
(node (ref J4) (pin 2))) |
|||
(net (code 20) (name SD-CARD_MISO) |
|||
(node (ref J1) (pin 3)) |
|||
(node (ref U1) (pin 27))) |
|||
(net (code 21) (name SD-CARD_MOSI) |
|||
(node (ref U1) (pin 15)) |
|||
(node (ref J1) (pin 4))) |
|||
(net (code 22) (name SD-CARD_SCK) |
|||
(node (ref U1) (pin 12)) |
|||
(node (ref J1) (pin 5))) |
|||
(net (code 23) (name SD-CARD_CS) |
|||
(node (ref J1) (pin 6)) |
|||
(node (ref U1) (pin 23))) |
|||
(net (code 24) (name MAX98357_DIN) |
|||
(node (ref U1) (pin 9)) |
|||
(node (ref J3) (pin 5))) |
|||
(net (code 25) (name MAX98357_BLCK) |
|||
(node (ref J3) (pin 6)) |
|||
(node (ref U1) (pin 11))) |
|||
(net (code 26) (name MAX98357_LRC) |
|||
(node (ref U1) (pin 10)) |
|||
(node (ref J3) (pin 7))) |
|||
(net (code 27) (name ROTARY_CLR) |
|||
(node (ref U1) (pin 5)) |
|||
(node (ref J4) (pin 3))) |
|||
(net (code 28) (name ROTARY_DT) |
|||
(node (ref U1) (pin 6)) |
|||
(node (ref J4) (pin 4))) |
|||
(net (code 29) (name ROTARY_BUTTON) |
|||
(node (ref J4) (pin 5)) |
|||
(node (ref U1) (pin 7))) |
|||
(net (code 30) (name NEOPIXEL_DI) |
|||
(node (ref U1) (pin 13)) |
|||
(node (ref J8) (pin 2))) |
|||
(net (code 31) (name VCC) |
|||
(node (ref U1) (pin 19)) |
|||
(node (ref Q2) (pin 3)) |
|||
(node (ref R1) (pin 1)) |
|||
(node (ref J9) (pin 2))) |
|||
(net (code 32) (name BUTTON_PREVIOUS_PIN) |
|||
(node (ref J5) (pin 2)) |
|||
(node (ref U1) (pin 8))) |
|||
(net (code 33) (name BUTTON_NEXT_PIN) |
|||
(node (ref U1) (pin 26)) |
|||
(node (ref J6) (pin 2))) |
|||
(net (code 34) (name BUTTON_PLAY_PAUSE_PIN) |
|||
(node (ref U1) (pin 29)) |
|||
(node (ref J7) (pin 2))) |
|||
(net (code 35) (name RFID_RST) |
|||
(node (ref J2) (pin 2)) |
|||
(node (ref U1) (pin 36))) |
|||
(net (code 36) (name "Net-(J2-Pad4)") |
|||
(node (ref J2) (pin 4))) |
|||
(net (code 37) (name RFID_MISO) |
|||
(node (ref J2) (pin 5)) |
|||
(node (ref U1) (pin 31))) |
|||
(net (code 38) (name RFID_MOSI) |
|||
(node (ref J2) (pin 6)) |
|||
(node (ref U1) (pin 37))) |
|||
(net (code 39) (name RFID_SCK) |
|||
(node (ref J2) (pin 7)) |
|||
(node (ref U1) (pin 30))) |
|||
(net (code 40) (name RFID_SDA) |
|||
(node (ref J2) (pin 8)) |
|||
(node (ref U1) (pin 33))) |
|||
(net (code 41) (name "Net-(Q1-Pad2)") |
|||
(node (ref R4) (pin 1)) |
|||
(node (ref R5) (pin 1)) |
|||
(node (ref Q1) (pin 2))) |
|||
(net (code 42) (name "Net-(Q1-Pad1)") |
|||
(node (ref Q1) (pin 1)) |
|||
(node (ref Q2) (pin 1)) |
|||
(node (ref R1) (pin 2))))) |
@ -0,0 +1,248 @@ |
|||
update=2020 October 04, Sunday 16:49:12 |
|||
version=1 |
|||
last_client=kicad |
|||
[general] |
|||
version=1 |
|||
RootSch= |
|||
BoardNm= |
|||
[cvpcb] |
|||
version=1 |
|||
NetIExt=net |
|||
[eeschema] |
|||
version=1 |
|||
LibDir= |
|||
[eeschema/libraries] |
|||
[schematic_editor] |
|||
version=1 |
|||
PageLayoutDescrFile= |
|||
PlotDirectoryName= |
|||
SubpartIdSeparator=0 |
|||
SubpartFirstId=65 |
|||
NetFmtName=Pcbnew |
|||
SpiceAjustPassiveValues=0 |
|||
LabSize=50 |
|||
ERC_TestSimilarLabels=1 |
|||
[pcbnew] |
|||
version=1 |
|||
PageLayoutDescrFile= |
|||
LastNetListRead= |
|||
CopperLayerCount=2 |
|||
BoardThickness=1.6 |
|||
AllowMicroVias=0 |
|||
AllowBlindVias=0 |
|||
RequireCourtyardDefinitions=0 |
|||
ProhibitOverlappingCourtyards=1 |
|||
MinTrackWidth=0.2 |
|||
MinViaDiameter=0.4 |
|||
MinViaDrill=0.3 |
|||
MinMicroViaDiameter=0.2 |
|||
MinMicroViaDrill=0.09999999999999999 |
|||
MinHoleToHole=0.25 |
|||
TrackWidth1=0.4 |
|||
ViaDiameter1=0.8 |
|||
ViaDrill1=0.4 |
|||
dPairWidth1=0.2 |
|||
dPairGap1=0.25 |
|||
dPairViaGap1=0.25 |
|||
SilkLineWidth=0.12 |
|||
SilkTextSizeV=1 |
|||
SilkTextSizeH=1 |
|||
SilkTextSizeThickness=0.15 |
|||
SilkTextItalic=0 |
|||
SilkTextUpright=1 |
|||
CopperLineWidth=0.2 |
|||
CopperTextSizeV=1.5 |
|||
CopperTextSizeH=1.5 |
|||
CopperTextThickness=0.3 |
|||
CopperTextItalic=0 |
|||
CopperTextUpright=1 |
|||
EdgeCutLineWidth=0.05 |
|||
CourtyardLineWidth=0.05 |
|||
OthersLineWidth=0.15 |
|||
OthersTextSizeV=1 |
|||
OthersTextSizeH=1 |
|||
OthersTextSizeThickness=0.15 |
|||
OthersTextItalic=0 |
|||
OthersTextUpright=1 |
|||
SolderMaskClearance=0 |
|||
SolderMaskMinWidth=0 |
|||
SolderPasteClearance=0 |
|||
SolderPasteRatio=-0 |
|||
[pcbnew/Layer.F.Cu] |
|||
Name=F.Cu |
|||
Type=0 |
|||
Enabled=1 |
|||
[pcbnew/Layer.In1.Cu] |
|||
Name=In1.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In2.Cu] |
|||
Name=In2.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In3.Cu] |
|||
Name=In3.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In4.Cu] |
|||
Name=In4.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In5.Cu] |
|||
Name=In5.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In6.Cu] |
|||
Name=In6.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In7.Cu] |
|||
Name=In7.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In8.Cu] |
|||
Name=In8.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In9.Cu] |
|||
Name=In9.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In10.Cu] |
|||
Name=In10.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In11.Cu] |
|||
Name=In11.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In12.Cu] |
|||
Name=In12.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In13.Cu] |
|||
Name=In13.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In14.Cu] |
|||
Name=In14.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In15.Cu] |
|||
Name=In15.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In16.Cu] |
|||
Name=In16.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In17.Cu] |
|||
Name=In17.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In18.Cu] |
|||
Name=In18.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In19.Cu] |
|||
Name=In19.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In20.Cu] |
|||
Name=In20.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In21.Cu] |
|||
Name=In21.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In22.Cu] |
|||
Name=In22.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In23.Cu] |
|||
Name=In23.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In24.Cu] |
|||
Name=In24.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In25.Cu] |
|||
Name=In25.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In26.Cu] |
|||
Name=In26.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In27.Cu] |
|||
Name=In27.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In28.Cu] |
|||
Name=In28.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In29.Cu] |
|||
Name=In29.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.In30.Cu] |
|||
Name=In30.Cu |
|||
Type=0 |
|||
Enabled=0 |
|||
[pcbnew/Layer.B.Cu] |
|||
Name=B.Cu |
|||
Type=0 |
|||
Enabled=1 |
|||
[pcbnew/Layer.B.Adhes] |
|||
Enabled=1 |
|||
[pcbnew/Layer.F.Adhes] |
|||
Enabled=1 |
|||
[pcbnew/Layer.B.Paste] |
|||
Enabled=1 |
|||
[pcbnew/Layer.F.Paste] |
|||
Enabled=1 |
|||
[pcbnew/Layer.B.SilkS] |
|||
Enabled=1 |
|||
[pcbnew/Layer.F.SilkS] |
|||
Enabled=1 |
|||
[pcbnew/Layer.B.Mask] |
|||
Enabled=1 |
|||
[pcbnew/Layer.F.Mask] |
|||
Enabled=1 |
|||
[pcbnew/Layer.Dwgs.User] |
|||
Enabled=1 |
|||
[pcbnew/Layer.Cmts.User] |
|||
Enabled=1 |
|||
[pcbnew/Layer.Eco1.User] |
|||
Enabled=1 |
|||
[pcbnew/Layer.Eco2.User] |
|||
Enabled=1 |
|||
[pcbnew/Layer.Edge.Cuts] |
|||
Enabled=1 |
|||
[pcbnew/Layer.Margin] |
|||
Enabled=1 |
|||
[pcbnew/Layer.B.CrtYd] |
|||
Enabled=1 |
|||
[pcbnew/Layer.F.CrtYd] |
|||
Enabled=1 |
|||
[pcbnew/Layer.B.Fab] |
|||
Enabled=1 |
|||
[pcbnew/Layer.F.Fab] |
|||
Enabled=1 |
|||
[pcbnew/Layer.Rescue] |
|||
Enabled=0 |
|||
[pcbnew/Netclasses] |
|||
[pcbnew/Netclasses/Default] |
|||
Name=Default |
|||
Clearance=0.2 |
|||
TrackWidth=0.4 |
|||
ViaDiameter=0.8 |
|||
ViaDrill=0.4 |
|||
uViaDiameter=0.3 |
|||
uViaDrill=0.1 |
|||
dPairWidth=0.2 |
|||
dPairGap=0.25 |
|||
dPairViaGap=0.25 |
@ -0,0 +1,585 @@ |
|||
EESchema Schematic File Version 4 |
|||
EELAYER 30 0 |
|||
EELAYER END |
|||
$Descr A4 11693 8268 |
|||
encoding utf-8 |
|||
Sheet 1 1 |
|||
Title "" |
|||
Date "" |
|||
Rev "" |
|||
Comp "" |
|||
Comment1 "" |
|||
Comment2 "" |
|||
Comment3 "" |
|||
Comment4 "" |
|||
$EndDescr |
|||
$Comp |
|||
L ESP32-DEVKITC-32U:ESP32-DEVKITC-32U U1 |
|||
U 1 1 5F79096D |
|||
P 8100 2650 |
|||
F 0 "U1" H 8100 3817 50 0000 C CNN |
|||
F 1 "ESP32-DEVKITC-32U" H 8100 3726 50 0000 C CNN |
|||
F 2 "ESP32-DEVKITC-32U:MODULE_ESP32-DEVKITC-32U" H 8100 2650 50 0001 L BNN |
|||
F 3 "Manufacturer Recommendations" H 8100 2650 50 0001 L BNN |
|||
F 4 "ESPRESSIF" H 8100 2650 50 0001 L BNN "Field4" |
|||
F 5 "N/A" H 8100 2650 50 0001 L BNN "Field5" |
|||
1 8100 2650 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x05_Male J4 |
|||
U 1 1 5F7BD0A2 |
|||
P 2550 6550 |
|||
F 0 "J4" H 2658 6931 50 0000 C CNN |
|||
F 1 "Rotary Encode" H 2658 6840 50 0000 C CNN |
|||
F 2 "mod_s:PinHeader_1x05_P2.54mm_Vertical" H 2550 6550 50 0001 C CNN |
|||
F 3 "" H 2550 6550 50 0001 C CNN |
|||
1 2550 6550 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x06_Male J1 |
|||
U 1 1 5F7ED32A |
|||
P 6250 4700 |
|||
F 0 "J1" V 6312 4944 50 0000 L CNN |
|||
F 1 "SD-Card Reader" V 6403 4944 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x06_P2.54mm_Vertical" H 6250 4700 50 0001 C CNN |
|||
F 3 "" H 6250 4700 50 0001 C CNN |
|||
1 6250 4700 |
|||
0 1 1 0 |
|||
$EndComp |
|||
Text Notes 4200 4300 0 197 ~ 0 |
|||
Breakout Boards\n |
|||
Text Notes 850 4300 0 197 ~ 0 |
|||
Inputs Interfaces |
|||
Text Notes 850 1400 0 197 ~ 0 |
|||
Switched 5V (Deep Sleep)\n |
|||
Text Notes 7500 1250 0 197 ~ 0 |
|||
ESP-32\n |
|||
$Comp |
|||
L Connector:Conn_01x07_Male J3 |
|||
U 1 1 5F81C714 |
|||
P 4650 6450 |
|||
F 0 "J3" V 4485 6428 50 0000 C CNN |
|||
F 1 "Adafruit MAX98357" V 4576 6428 50 0000 C CNN |
|||
F 2 "mod_s:PinHeader_1x07_P2.54mm_Vertical" H 4650 6450 50 0001 C CNN |
|||
F 3 "" H 4650 6450 50 0001 C CNN |
|||
1 4650 6450 |
|||
0 1 1 0 |
|||
$EndComp |
|||
Text GLabel 9050 2750 2 50 Input ~ 0 |
|||
GPIO-17 |
|||
Wire Wire Line |
|||
4950 6850 4950 6650 |
|||
Text GLabel 6350 5050 3 50 Input ~ 0 |
|||
SWITCHED_VCC |
|||
Wire Wire Line |
|||
6350 5050 6350 4900 |
|||
$Comp |
|||
L power:GND #PWR0103 |
|||
U 1 1 5F829524 |
|||
P 6600 5100 |
|||
F 0 "#PWR0103" H 6600 4850 50 0001 C CNN |
|||
F 1 "GND" H 6605 4927 50 0000 C CNN |
|||
F 2 "" H 6600 5100 50 0001 C CNN |
|||
F 3 "" H 6600 5100 50 0001 C CNN |
|||
1 6600 5100 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Wire Wire Line |
|||
6600 5100 6450 5100 |
|||
Wire Wire Line |
|||
6450 5100 6450 4900 |
|||
Text GLabel 7050 1750 0 50 Input ~ 0 |
|||
3.3V |
|||
Wire Wire Line |
|||
7300 1750 7050 1750 |
|||
Wire Wire Line |
|||
8900 2750 9050 2750 |
|||
Text GLabel 5050 5250 3 50 Input ~ 0 |
|||
GPIO-17 |
|||
$Comp |
|||
L power:GND #PWR0104 |
|||
U 1 1 5F82B98B |
|||
P 4850 5250 |
|||
F 0 "#PWR0104" H 4850 5000 50 0001 C CNN |
|||
F 1 "GND" H 4855 5077 50 0000 C CNN |
|||
F 2 "" H 4850 5250 50 0001 C CNN |
|||
F 3 "" H 4850 5250 50 0001 C CNN |
|||
1 4850 5250 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Text GLabel 6250 5050 3 50 Input ~ 0 |
|||
SD-CARD_MISO |
|||
Text GLabel 6150 5050 3 50 Input ~ 0 |
|||
SD-CARD_MOSI |
|||
Wire Wire Line |
|||
6250 5050 6250 4900 |
|||
Wire Wire Line |
|||
6150 5050 6150 4900 |
|||
Text GLabel 6050 5050 3 50 Input ~ 0 |
|||
SD-CARD_SCK |
|||
Text GLabel 5950 5050 3 50 Input ~ 0 |
|||
SD-CARD_CS |
|||
Wire Wire Line |
|||
6050 5050 6050 4900 |
|||
Wire Wire Line |
|||
5950 5050 5950 4900 |
|||
Text GLabel 4950 5250 3 50 Input ~ 0 |
|||
RFID_RST |
|||
Text GLabel 4350 5250 3 50 Input ~ 0 |
|||
RFID_SDA |
|||
Text GLabel 4450 5250 3 50 Input ~ 0 |
|||
RFID_SCK |
|||
Text GLabel 4550 5250 3 50 Input ~ 0 |
|||
RFID_MOSI |
|||
Text GLabel 4650 5250 3 50 Input ~ 0 |
|||
RFID_MISO |
|||
Wire Wire Line |
|||
4850 6750 4850 6650 |
|||
Text GLabel 4550 6850 3 50 Input ~ 0 |
|||
MAX98357_DIN |
|||
Wire Wire Line |
|||
4550 6850 4550 6650 |
|||
Text GLabel 4450 6850 3 50 Input ~ 0 |
|||
MAX98357_BLCK |
|||
Wire Wire Line |
|||
4450 6850 4450 6650 |
|||
Text GLabel 4350 6850 3 50 Input ~ 0 |
|||
MAX98357_LRC |
|||
Wire Wire Line |
|||
4350 6850 4350 6650 |
|||
Text GLabel 2550 6900 3 50 Input ~ 0 |
|||
ROTARY_CLR |
|||
Text GLabel 2450 6900 3 50 Input ~ 0 |
|||
ROTARY_DT |
|||
Text GLabel 2350 6900 3 50 Input ~ 0 |
|||
ROTARY_BUTTON |
|||
Text GLabel 2650 6900 3 50 Input ~ 0 |
|||
3.3V |
|||
Wire Wire Line |
|||
2750 6900 2750 6750 |
|||
Wire Wire Line |
|||
2650 6900 2650 6750 |
|||
Wire Wire Line |
|||
2450 6900 2450 6750 |
|||
Text GLabel 2500 5100 3 50 Input ~ 0 |
|||
BUTTON_PLAY_PAUSE_PIN |
|||
Text GLabel 2100 5100 3 50 Input ~ 0 |
|||
BUTTON_NEXT_PIN |
|||
Text GLabel 1600 5100 3 50 Input ~ 0 |
|||
BUTTON_PREVIOUS_PIN |
|||
$Comp |
|||
L power:GND #PWR0106 |
|||
U 1 1 5F842383 |
|||
P 1700 5100 |
|||
F 0 "#PWR0106" H 1700 4850 50 0001 C CNN |
|||
F 1 "GND" H 1705 4927 50 0000 C CNN |
|||
F 2 "" H 1700 5100 50 0001 C CNN |
|||
F 3 "" H 1700 5100 50 0001 C CNN |
|||
1 1700 5100 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0107 |
|||
U 1 1 5F8429CB |
|||
P 2200 5100 |
|||
F 0 "#PWR0107" H 2200 4850 50 0001 C CNN |
|||
F 1 "GND" H 2205 4927 50 0000 C CNN |
|||
F 2 "" H 2200 5100 50 0001 C CNN |
|||
F 3 "" H 2200 5100 50 0001 C CNN |
|||
1 2200 5100 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0108 |
|||
U 1 1 5F843BDD |
|||
P 2600 5100 |
|||
F 0 "#PWR0108" H 2600 4850 50 0001 C CNN |
|||
F 1 "GND" H 2605 4927 50 0000 C CNN |
|||
F 2 "" H 2600 5100 50 0001 C CNN |
|||
F 3 "" H 2600 5100 50 0001 C CNN |
|||
1 2600 5100 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Text GLabel 5750 6900 3 50 Input ~ 0 |
|||
NEOPIXEL_DI |
|||
Wire Wire Line |
|||
5650 6900 5650 6750 |
|||
Wire Wire Line |
|||
5750 6900 5750 6750 |
|||
Wire Wire Line |
|||
5850 6900 5850 6750 |
|||
Text GLabel 9050 1950 2 50 Input ~ 0 |
|||
RFID_RST |
|||
Wire Wire Line |
|||
8900 1950 9050 1950 |
|||
Text GLabel 9050 2250 2 50 Input ~ 0 |
|||
RFID_SDA |
|||
Wire Wire Line |
|||
8900 2250 9050 2250 |
|||
Text GLabel 9050 1850 2 50 Input ~ 0 |
|||
RFID_MOSI |
|||
Wire Wire Line |
|||
8900 1850 9050 1850 |
|||
Text GLabel 9050 2450 2 50 Input ~ 0 |
|||
RFID_MISO |
|||
Wire Wire Line |
|||
9050 2450 8900 2450 |
|||
Text GLabel 9050 2550 2 50 Input ~ 0 |
|||
RFID_SCK |
|||
Wire Wire Line |
|||
8900 2550 9050 2550 |
|||
$Comp |
|||
L power:GND #PWR0110 |
|||
U 1 1 5F85DB8C |
|||
P 9050 1750 |
|||
F 0 "#PWR0110" H 9050 1500 50 0001 C CNN |
|||
F 1 "GND" V 9050 1600 50 0000 R CNN |
|||
F 2 "" H 9050 1750 50 0001 C CNN |
|||
F 3 "" H 9050 1750 50 0001 C CNN |
|||
1 9050 1750 |
|||
0 -1 -1 0 |
|||
$EndComp |
|||
Wire Wire Line |
|||
8900 2350 9050 2350 |
|||
Wire Wire Line |
|||
9050 1750 8900 1750 |
|||
Text GLabel 7050 2550 0 50 Input ~ 0 |
|||
MAX98357_DIN |
|||
Text GLabel 7050 2750 0 50 Input ~ 0 |
|||
MAX98357_BLCK |
|||
Text GLabel 7050 2650 0 50 Input ~ 0 |
|||
MAX98357_LRC |
|||
Wire Wire Line |
|||
7050 2550 7300 2550 |
|||
Wire Wire Line |
|||
7050 2650 7300 2650 |
|||
Wire Wire Line |
|||
7050 2750 7300 2750 |
|||
Text GLabel 9050 3250 2 50 Input ~ 0 |
|||
SD-CARD_CS |
|||
Text GLabel 7050 2850 0 50 Input ~ 0 |
|||
SD-CARD_SCK |
|||
Text GLabel 7050 3150 0 50 Input ~ 0 |
|||
SD-CARD_MOSI |
|||
Text GLabel 9050 2850 2 50 Input ~ 0 |
|||
SD-CARD_MISO |
|||
Wire Wire Line |
|||
9050 2850 8900 2850 |
|||
Wire Wire Line |
|||
9050 3250 8900 3250 |
|||
Wire Wire Line |
|||
7300 3150 7050 3150 |
|||
Wire Wire Line |
|||
7050 2850 7300 2850 |
|||
Text GLabel 7050 2450 0 50 Input ~ 0 |
|||
BUTTON_PREVIOUS_PIN |
|||
Text GLabel 9050 2950 2 50 Input ~ 0 |
|||
BUTTON_NEXT_PIN |
|||
Text GLabel 9050 2650 2 50 Input ~ 0 |
|||
BUTTON_PLAY_PAUSE_PIN |
|||
Wire Wire Line |
|||
8900 2650 9050 2650 |
|||
Wire Wire Line |
|||
8900 2950 9050 2950 |
|||
Wire Wire Line |
|||
7300 2450 7050 2450 |
|||
Text GLabel 7050 2150 0 50 Input ~ 0 |
|||
ROTARY_CLR |
|||
Text GLabel 7050 2250 0 50 Input ~ 0 |
|||
ROTARY_DT |
|||
Text GLabel 7050 2350 0 50 Input ~ 0 |
|||
ROTARY_BUTTON |
|||
Wire Wire Line |
|||
7050 2350 7300 2350 |
|||
Wire Wire Line |
|||
7050 2250 7300 2250 |
|||
Wire Wire Line |
|||
7050 2150 7300 2150 |
|||
Text GLabel 7050 2950 0 50 Input ~ 0 |
|||
NEOPIXEL_DI |
|||
Wire Wire Line |
|||
7050 2950 7300 2950 |
|||
$Comp |
|||
L power:VCC #PWR0112 |
|||
U 1 1 5F87B792 |
|||
P 7000 3550 |
|||
F 0 "#PWR0112" H 7000 3400 50 0001 C CNN |
|||
F 1 "VCC" H 7015 3723 50 0000 C CNN |
|||
F 2 "" H 7000 3550 50 0001 C CNN |
|||
F 3 "" H 7000 3550 50 0001 C CNN |
|||
1 7000 3550 |
|||
0 -1 -1 0 |
|||
$EndComp |
|||
Wire Wire Line |
|||
7300 3550 7000 3550 |
|||
Text GLabel 5650 6900 3 50 Input ~ 0 |
|||
SWITCHED_VCC |
|||
$Comp |
|||
L power:VCC #PWR0114 |
|||
U 1 1 5F8848E9 |
|||
P 8750 4900 |
|||
F 0 "#PWR0114" H 8750 4750 50 0001 C CNN |
|||
F 1 "VCC" H 8765 5073 50 0000 C CNN |
|||
F 2 "" H 8750 4900 50 0001 C CNN |
|||
F 3 "" H 8750 4900 50 0001 C CNN |
|||
1 8750 4900 |
|||
-1 0 0 1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0115 |
|||
U 1 1 5F885DD6 |
|||
P 8850 4900 |
|||
F 0 "#PWR0115" H 8850 4650 50 0001 C CNN |
|||
F 1 "GND" H 8855 4727 50 0000 C CNN |
|||
F 2 "" H 8850 4900 50 0001 C CNN |
|||
F 3 "" H 8850 4900 50 0001 C CNN |
|||
1 8850 4900 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Text Notes 7750 4300 0 197 ~ 0 |
|||
Power Supply\n |
|||
Wire Wire Line |
|||
2550 6900 2550 6750 |
|||
Wire Wire Line |
|||
2350 6900 2350 6750 |
|||
$Comp |
|||
L power:GND #PWR0105 |
|||
U 1 1 5F872A11 |
|||
P 9050 2350 |
|||
F 0 "#PWR0105" H 9050 2100 50 0001 C CNN |
|||
F 1 "GND" V 9055 2222 50 0000 R CNN |
|||
F 2 "" H 9050 2350 50 0001 C CNN |
|||
F 3 "" H 9050 2350 50 0001 C CNN |
|||
1 9050 2350 |
|||
0 -1 -1 0 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0109 |
|||
U 1 1 5F8787E6 |
|||
P 2750 6900 |
|||
F 0 "#PWR0109" H 2750 6650 50 0001 C CNN |
|||
F 1 "GND" V 2750 6750 50 0000 R CNN |
|||
F 2 "" H 2750 6900 50 0001 C CNN |
|||
F 3 "" H 2750 6900 50 0001 C CNN |
|||
1 2750 6900 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0111 |
|||
U 1 1 5F878CF4 |
|||
P 7300 3050 |
|||
F 0 "#PWR0111" H 7300 2800 50 0001 C CNN |
|||
F 1 "GND" V 7300 2900 50 0000 R CNN |
|||
F 2 "" H 7300 3050 50 0001 C CNN |
|||
F 3 "" H 7300 3050 50 0001 C CNN |
|||
1 7300 3050 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0117 |
|||
U 1 1 5F885952 |
|||
P 4850 6750 |
|||
F 0 "#PWR0117" H 4850 6500 50 0001 C CNN |
|||
F 1 "GND" V 4850 6600 50 0000 R CNN |
|||
F 2 "" H 4850 6750 50 0001 C CNN |
|||
F 3 "" H 4850 6750 50 0001 C CNN |
|||
1 4850 6750 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0118 |
|||
U 1 1 5F8874D1 |
|||
P 5850 6900 |
|||
F 0 "#PWR0118" H 5850 6650 50 0001 C CNN |
|||
F 1 "GND" V 5850 6750 50 0000 R CNN |
|||
F 2 "" H 5850 6900 50 0001 C CNN |
|||
F 3 "" H 5850 6900 50 0001 C CNN |
|||
1 5850 6900 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Text GLabel 4950 6850 3 50 Input ~ 0 |
|||
SWITCHED_VCC |
|||
$Comp |
|||
L Connector:Conn_01x02_Male J5 |
|||
U 1 1 5F9085EF |
|||
P 1700 4900 |
|||
F 0 "J5" V 1762 4944 50 0000 L CNN |
|||
F 1 "Next" V 1853 4944 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x02_P2.54mm_Vertical" H 1700 4900 50 0001 C CNN |
|||
F 3 "" H 1700 4900 50 0001 C CNN |
|||
1 1700 4900 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x02_Male J6 |
|||
U 1 1 5F90EAED |
|||
P 2200 4900 |
|||
F 0 "J6" V 2262 4944 50 0000 L CNN |
|||
F 1 "Prev" V 2353 4944 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x02_P2.54mm_Vertical" H 2200 4900 50 0001 C CNN |
|||
F 3 "" H 2200 4900 50 0001 C CNN |
|||
1 2200 4900 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x02_Male J7 |
|||
U 1 1 5F90F726 |
|||
P 2600 4900 |
|||
F 0 "J7" V 2662 4944 50 0000 L CNN |
|||
F 1 "Pause" V 2753 4944 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x02_P2.54mm_Vertical" H 2600 4900 50 0001 C CNN |
|||
F 3 "" H 2600 4900 50 0001 C CNN |
|||
1 2600 4900 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x08_Male J2 |
|||
U 1 1 5F92011C |
|||
P 4750 5050 |
|||
F 0 "J2" V 4585 4978 50 0000 C CNN |
|||
F 1 "RFID-RC522" V 4676 4978 50 0000 C CNN |
|||
F 2 "mod_s:PinHeader_1x08_P2.54mm_Vertical" H 4750 5050 50 0001 C CNN |
|||
F 3 "" H 4750 5050 50 0001 C CNN |
|||
1 4750 5050 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x03_Male J8 |
|||
U 1 1 5F936A23 |
|||
P 5750 6550 |
|||
F 0 "J8" V 5812 6694 50 0000 L CNN |
|||
F 1 "WS2812" V 5903 6694 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x03_P2.54mm_Vertical" H 5750 6550 50 0001 C CNN |
|||
F 3 "" H 5750 6550 50 0001 C CNN |
|||
1 5750 6550 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x02_Male J9 |
|||
U 1 1 5F945F11 |
|||
P 8850 4700 |
|||
F 0 "J9" V 8912 4744 50 0000 L CNN |
|||
F 1 "Power" V 9003 4744 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x02_P2.54mm_Vertical" H 8850 4700 50 0001 C CNN |
|||
F 3 "" H 8850 4700 50 0001 C CNN |
|||
1 8850 4700 |
|||
0 1 1 0 |
|||
$EndComp |
|||
Wire Wire Line |
|||
1600 2850 1850 2850 |
|||
Text GLabel 1600 2850 0 50 Input ~ 0 |
|||
GPIO-17 |
|||
Wire Wire Line |
|||
2300 2400 2300 2550 |
|||
$Comp |
|||
L power:GND #PWR0102 |
|||
U 1 1 5F7B65C3 |
|||
P 2300 2400 |
|||
F 0 "#PWR0102" H 2300 2150 50 0001 C CNN |
|||
F 1 "GND" H 2305 2227 50 0000 C CNN |
|||
F 2 "" H 2300 2400 50 0001 C CNN |
|||
F 3 "" H 2300 2400 50 0001 C CNN |
|||
1 2300 2400 |
|||
-1 0 0 1 |
|||
$EndComp |
|||
Connection ~ 2300 2850 |
|||
Wire Wire Line |
|||
2300 2850 2150 2850 |
|||
Wire Wire Line |
|||
2450 2850 2300 2850 |
|||
$Comp |
|||
L Device:R R5 |
|||
U 1 1 5F7995ED |
|||
P 2000 2850 |
|||
F 0 "R5" H 2070 2896 50 0000 L CNN |
|||
F 1 "4,7k" H 2070 2805 50 0000 L CNN |
|||
F 2 "adafruit:0207_9" V 1930 2850 50 0001 C CNN |
|||
F 3 "" H 2000 2850 50 0001 C CNN |
|||
1 2000 2850 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Device:R R4 |
|||
U 1 1 5F798E7D |
|||
P 2300 2700 |
|||
F 0 "R4" H 2370 2746 50 0000 L CNN |
|||
F 1 "10k" H 2370 2655 50 0000 L CNN |
|||
F 2 "adafruit:0207_9" V 2230 2700 50 0001 C CNN |
|||
F 3 "" H 2300 2700 50 0001 C CNN |
|||
1 2300 2700 |
|||
-1 0 0 1 |
|||
$EndComp |
|||
$Comp |
|||
L Transistor_BJT:BC337 Q1 |
|||
U 1 1 5F78DA7C |
|||
P 2650 2850 |
|||
F 0 "Q1" H 2841 2896 50 0000 L CNN |
|||
F 1 "BC337" H 2841 2805 50 0000 L CNN |
|||
F 2 "Package_TO_SOT_THT:TO-92_Inline_Wide" H 2850 2775 50 0001 L CIN |
|||
F 3 "" H 2650 2850 50 0001 L CNN |
|||
1 2650 2850 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0101 |
|||
U 1 1 5F7B5A15 |
|||
P 2750 3300 |
|||
F 0 "#PWR0101" H 2750 3050 50 0001 C CNN |
|||
F 1 "GND" H 2755 3127 50 0000 C CNN |
|||
F 2 "" H 2750 3300 50 0001 C CNN |
|||
F 3 "" H 2750 3300 50 0001 C CNN |
|||
1 2750 3300 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Wire Wire Line |
|||
2750 3050 2750 3300 |
|||
$Comp |
|||
L Transistor_FET:IRF9540N Q2 |
|||
U 1 1 5F78F572 |
|||
P 2750 2100 |
|||
F 0 "Q2" H 2954 2146 50 0000 L CNN |
|||
F 1 "IRF9540N" H 2954 2055 50 0000 L CNN |
|||
F 2 "Package_TO_SOT_THT:TO-220-3_Vertical" H 2950 2025 50 0001 L CIN |
|||
F 3 "" H 2750 2100 50 0001 L CNN |
|||
1 2750 2100 |
|||
0 -1 -1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Device:R R1 |
|||
U 1 1 5F79873B |
|||
P 3050 2150 |
|||
F 0 "R1" H 3120 2196 50 0000 L CNN |
|||
F 1 "10k" H 3120 2105 50 0000 L CNN |
|||
F 2 "adafruit:0207_9" V 2980 2150 50 0001 C CNN |
|||
F 3 "" H 3050 2150 50 0001 C CNN |
|||
1 3050 2150 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Wire Wire Line |
|||
3050 2000 2950 2000 |
|||
Wire Wire Line |
|||
2750 2300 3050 2300 |
|||
Wire Wire Line |
|||
3300 2000 3050 2000 |
|||
$Comp |
|||
L power:VCC #PWR0113 |
|||
U 1 1 5F87F1D8 |
|||
P 3300 2000 |
|||
F 0 "#PWR0113" H 3300 1850 50 0001 C CNN |
|||
F 1 "VCC" V 3315 2127 50 0000 L CNN |
|||
F 2 "" H 3300 2000 50 0001 C CNN |
|||
F 3 "" H 3300 2000 50 0001 C CNN |
|||
1 3300 2000 |
|||
0 1 1 0 |
|||
$EndComp |
|||
Text GLabel 2350 2000 0 50 Input ~ 0 |
|||
SWITCHED_VCC |
|||
Wire Wire Line |
|||
2350 2000 2550 2000 |
|||
Connection ~ 3050 2000 |
|||
Wire Wire Line |
|||
2750 2300 2750 2650 |
|||
Connection ~ 2750 2300 |
|||
$EndSCHEMATC |
@ -0,0 +1,585 @@ |
|||
EESchema Schematic File Version 4 |
|||
EELAYER 30 0 |
|||
EELAYER END |
|||
$Descr A4 11693 8268 |
|||
encoding utf-8 |
|||
Sheet 1 1 |
|||
Title "" |
|||
Date "" |
|||
Rev "" |
|||
Comp "" |
|||
Comment1 "" |
|||
Comment2 "" |
|||
Comment3 "" |
|||
Comment4 "" |
|||
$EndDescr |
|||
$Comp |
|||
L ESP32-DEVKITC-32U:ESP32-DEVKITC-32U U1 |
|||
U 1 1 5F79096D |
|||
P 8100 2650 |
|||
F 0 "U1" H 8100 3817 50 0000 C CNN |
|||
F 1 "ESP32-DEVKITC-32U" H 8100 3726 50 0000 C CNN |
|||
F 2 "ESP32-DEVKITC-32U:MODULE_ESP32-DEVKITC-32U" H 8100 2650 50 0001 L BNN |
|||
F 3 "Manufacturer Recommendations" H 8100 2650 50 0001 L BNN |
|||
F 4 "ESPRESSIF" H 8100 2650 50 0001 L BNN "Field4" |
|||
F 5 "N/A" H 8100 2650 50 0001 L BNN "Field5" |
|||
1 8100 2650 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x05_Male J4 |
|||
U 1 1 5F7BD0A2 |
|||
P 2550 6550 |
|||
F 0 "J4" H 2658 6931 50 0000 C CNN |
|||
F 1 "Rotary Encode" H 2658 6840 50 0000 C CNN |
|||
F 2 "mod_s:PinHeader_1x05_P2.54mm_Vertical" H 2550 6550 50 0001 C CNN |
|||
F 3 "" H 2550 6550 50 0001 C CNN |
|||
1 2550 6550 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x06_Male J1 |
|||
U 1 1 5F7ED32A |
|||
P 6250 4700 |
|||
F 0 "J1" V 6312 4944 50 0000 L CNN |
|||
F 1 "SD-Card Reader" V 6403 4944 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x06_P2.54mm_Vertical" H 6250 4700 50 0001 C CNN |
|||
F 3 "" H 6250 4700 50 0001 C CNN |
|||
1 6250 4700 |
|||
0 1 1 0 |
|||
$EndComp |
|||
Text Notes 4200 4300 0 197 ~ 0 |
|||
Breakout Boards\n |
|||
Text Notes 850 4300 0 197 ~ 0 |
|||
Inputs Interfaces |
|||
Text Notes 850 1400 0 197 ~ 0 |
|||
Switched 5V (Deep Sleep)\n |
|||
Text Notes 7500 1250 0 197 ~ 0 |
|||
ESP-32\n |
|||
$Comp |
|||
L Connector:Conn_01x07_Male J3 |
|||
U 1 1 5F81C714 |
|||
P 4650 6450 |
|||
F 0 "J3" V 4485 6428 50 0000 C CNN |
|||
F 1 "Adafruit MAX98357" V 4576 6428 50 0000 C CNN |
|||
F 2 "mod_s:PinHeader_1x07_P2.54mm_Vertical" H 4650 6450 50 0001 C CNN |
|||
F 3 "" H 4650 6450 50 0001 C CNN |
|||
1 4650 6450 |
|||
0 1 1 0 |
|||
$EndComp |
|||
Text GLabel 9050 2750 2 50 Input ~ 0 |
|||
GPIO-17 |
|||
Wire Wire Line |
|||
4950 6850 4950 6650 |
|||
Text GLabel 6350 5050 3 50 Input ~ 0 |
|||
SWITCHED_VCC |
|||
Wire Wire Line |
|||
6350 5050 6350 4900 |
|||
$Comp |
|||
L power:GND #PWR0103 |
|||
U 1 1 5F829524 |
|||
P 6600 5100 |
|||
F 0 "#PWR0103" H 6600 4850 50 0001 C CNN |
|||
F 1 "GND" H 6605 4927 50 0000 C CNN |
|||
F 2 "" H 6600 5100 50 0001 C CNN |
|||
F 3 "" H 6600 5100 50 0001 C CNN |
|||
1 6600 5100 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Wire Wire Line |
|||
6600 5100 6450 5100 |
|||
Wire Wire Line |
|||
6450 5100 6450 4900 |
|||
Text GLabel 7050 1750 0 50 Input ~ 0 |
|||
3.3V |
|||
Wire Wire Line |
|||
7300 1750 7050 1750 |
|||
Wire Wire Line |
|||
8900 2750 9050 2750 |
|||
Text GLabel 5050 5250 3 50 Input ~ 0 |
|||
GPIO-17 |
|||
$Comp |
|||
L power:GND #PWR0104 |
|||
U 1 1 5F82B98B |
|||
P 4850 5250 |
|||
F 0 "#PWR0104" H 4850 5000 50 0001 C CNN |
|||
F 1 "GND" H 4855 5077 50 0000 C CNN |
|||
F 2 "" H 4850 5250 50 0001 C CNN |
|||
F 3 "" H 4850 5250 50 0001 C CNN |
|||
1 4850 5250 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Text GLabel 6250 5050 3 50 Input ~ 0 |
|||
SD-CARD_MISO |
|||
Text GLabel 6150 5050 3 50 Input ~ 0 |
|||
SD-CARD_MOSI |
|||
Wire Wire Line |
|||
6250 5050 6250 4900 |
|||
Wire Wire Line |
|||
6150 5050 6150 4900 |
|||
Text GLabel 6050 5050 3 50 Input ~ 0 |
|||
SD-CARD_SCK |
|||
Text GLabel 5950 5050 3 50 Input ~ 0 |
|||
SD-CARD_CS |
|||
Wire Wire Line |
|||
6050 5050 6050 4900 |
|||
Wire Wire Line |
|||
5950 5050 5950 4900 |
|||
Text GLabel 4950 5250 3 50 Input ~ 0 |
|||
RFID_RST |
|||
Text GLabel 4350 5250 3 50 Input ~ 0 |
|||
RFID_SDA |
|||
Text GLabel 4450 5250 3 50 Input ~ 0 |
|||
RFID_SCK |
|||
Text GLabel 4550 5250 3 50 Input ~ 0 |
|||
RFID_MOSI |
|||
Text GLabel 4650 5250 3 50 Input ~ 0 |
|||
RFID_MISO |
|||
Wire Wire Line |
|||
4850 6750 4850 6650 |
|||
Text GLabel 4550 6850 3 50 Input ~ 0 |
|||
MAX98357_DIN |
|||
Wire Wire Line |
|||
4550 6850 4550 6650 |
|||
Text GLabel 4450 6850 3 50 Input ~ 0 |
|||
MAX98357_BLCK |
|||
Wire Wire Line |
|||
4450 6850 4450 6650 |
|||
Text GLabel 4350 6850 3 50 Input ~ 0 |
|||
MAX98357_LRC |
|||
Wire Wire Line |
|||
4350 6850 4350 6650 |
|||
Text GLabel 2550 6900 3 50 Input ~ 0 |
|||
ROTARY_CLR |
|||
Text GLabel 2450 6900 3 50 Input ~ 0 |
|||
ROTARY_DT |
|||
Text GLabel 2350 6900 3 50 Input ~ 0 |
|||
ROTARY_BUTTON |
|||
Text GLabel 2650 6900 3 50 Input ~ 0 |
|||
3.3V |
|||
Wire Wire Line |
|||
2750 6900 2750 6750 |
|||
Wire Wire Line |
|||
2650 6900 2650 6750 |
|||
Wire Wire Line |
|||
2450 6900 2450 6750 |
|||
Text GLabel 2500 5100 3 50 Input ~ 0 |
|||
BUTTON_PLAY_PAUSE_PIN |
|||
Text GLabel 2100 5100 3 50 Input ~ 0 |
|||
BUTTON_NEXT_PIN |
|||
Text GLabel 1600 5100 3 50 Input ~ 0 |
|||
BUTTON_PREVIOUS_PIN |
|||
$Comp |
|||
L power:GND #PWR0106 |
|||
U 1 1 5F842383 |
|||
P 1700 5100 |
|||
F 0 "#PWR0106" H 1700 4850 50 0001 C CNN |
|||
F 1 "GND" H 1705 4927 50 0000 C CNN |
|||
F 2 "" H 1700 5100 50 0001 C CNN |
|||
F 3 "" H 1700 5100 50 0001 C CNN |
|||
1 1700 5100 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0107 |
|||
U 1 1 5F8429CB |
|||
P 2200 5100 |
|||
F 0 "#PWR0107" H 2200 4850 50 0001 C CNN |
|||
F 1 "GND" H 2205 4927 50 0000 C CNN |
|||
F 2 "" H 2200 5100 50 0001 C CNN |
|||
F 3 "" H 2200 5100 50 0001 C CNN |
|||
1 2200 5100 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0108 |
|||
U 1 1 5F843BDD |
|||
P 2600 5100 |
|||
F 0 "#PWR0108" H 2600 4850 50 0001 C CNN |
|||
F 1 "GND" H 2605 4927 50 0000 C CNN |
|||
F 2 "" H 2600 5100 50 0001 C CNN |
|||
F 3 "" H 2600 5100 50 0001 C CNN |
|||
1 2600 5100 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Text GLabel 5750 6900 3 50 Input ~ 0 |
|||
NEOPIXEL_DI |
|||
Wire Wire Line |
|||
5650 6900 5650 6750 |
|||
Wire Wire Line |
|||
5750 6900 5750 6750 |
|||
Wire Wire Line |
|||
5850 6900 5850 6750 |
|||
Text GLabel 9050 1950 2 50 Input ~ 0 |
|||
RFID_RST |
|||
Wire Wire Line |
|||
8900 1950 9050 1950 |
|||
Text GLabel 9050 2250 2 50 Input ~ 0 |
|||
RFID_SDA |
|||
Wire Wire Line |
|||
8900 2250 9050 2250 |
|||
Text GLabel 9050 1850 2 50 Input ~ 0 |
|||
RFID_MOSI |
|||
Wire Wire Line |
|||
8900 1850 9050 1850 |
|||
Text GLabel 9050 2450 2 50 Input ~ 0 |
|||
RFID_MISO |
|||
Wire Wire Line |
|||
9050 2450 8900 2450 |
|||
Text GLabel 9050 2550 2 50 Input ~ 0 |
|||
RFID_SCK |
|||
Wire Wire Line |
|||
8900 2550 9050 2550 |
|||
$Comp |
|||
L power:GND #PWR0110 |
|||
U 1 1 5F85DB8C |
|||
P 9050 1750 |
|||
F 0 "#PWR0110" H 9050 1500 50 0001 C CNN |
|||
F 1 "GND" V 9050 1600 50 0000 R CNN |
|||
F 2 "" H 9050 1750 50 0001 C CNN |
|||
F 3 "" H 9050 1750 50 0001 C CNN |
|||
1 9050 1750 |
|||
0 -1 -1 0 |
|||
$EndComp |
|||
Wire Wire Line |
|||
8900 2350 9050 2350 |
|||
Wire Wire Line |
|||
9050 1750 8900 1750 |
|||
Text GLabel 7050 2550 0 50 Input ~ 0 |
|||
MAX98357_DIN |
|||
Text GLabel 7050 2750 0 50 Input ~ 0 |
|||
MAX98357_BLCK |
|||
Text GLabel 7050 2650 0 50 Input ~ 0 |
|||
MAX98357_LRC |
|||
Wire Wire Line |
|||
7050 2550 7300 2550 |
|||
Wire Wire Line |
|||
7050 2650 7300 2650 |
|||
Wire Wire Line |
|||
7050 2750 7300 2750 |
|||
Text GLabel 9050 3250 2 50 Input ~ 0 |
|||
SD-CARD_CS |
|||
Text GLabel 7050 2850 0 50 Input ~ 0 |
|||
SD-CARD_SCK |
|||
Text GLabel 7050 3150 0 50 Input ~ 0 |
|||
SD-CARD_MOSI |
|||
Text GLabel 9050 2850 2 50 Input ~ 0 |
|||
SD-CARD_MISO |
|||
Wire Wire Line |
|||
9050 2850 8900 2850 |
|||
Wire Wire Line |
|||
9050 3250 8900 3250 |
|||
Wire Wire Line |
|||
7300 3150 7050 3150 |
|||
Wire Wire Line |
|||
7050 2850 7300 2850 |
|||
Text GLabel 7050 2450 0 50 Input ~ 0 |
|||
BUTTON_PREVIOUS_PIN |
|||
Text GLabel 9050 2950 2 50 Input ~ 0 |
|||
BUTTON_NEXT_PIN |
|||
Text GLabel 9050 2650 2 50 Input ~ 0 |
|||
BUTTON_PLAY_PAUSE_PIN |
|||
Wire Wire Line |
|||
8900 2650 9050 2650 |
|||
Wire Wire Line |
|||
8900 2950 9050 2950 |
|||
Wire Wire Line |
|||
7300 2450 7050 2450 |
|||
Text GLabel 7050 2150 0 50 Input ~ 0 |
|||
ROTARY_CLR |
|||
Text GLabel 7050 2250 0 50 Input ~ 0 |
|||
ROTARY_DT |
|||
Text GLabel 7050 2350 0 50 Input ~ 0 |
|||
ROTARY_BUTTON |
|||
Wire Wire Line |
|||
7050 2350 7300 2350 |
|||
Wire Wire Line |
|||
7050 2250 7300 2250 |
|||
Wire Wire Line |
|||
7050 2150 7300 2150 |
|||
Text GLabel 7050 2950 0 50 Input ~ 0 |
|||
NEOPIXEL_DI |
|||
Wire Wire Line |
|||
7050 2950 7300 2950 |
|||
$Comp |
|||
L power:VCC #PWR0112 |
|||
U 1 1 5F87B792 |
|||
P 7000 3550 |
|||
F 0 "#PWR0112" H 7000 3400 50 0001 C CNN |
|||
F 1 "VCC" H 7015 3723 50 0000 C CNN |
|||
F 2 "" H 7000 3550 50 0001 C CNN |
|||
F 3 "" H 7000 3550 50 0001 C CNN |
|||
1 7000 3550 |
|||
0 -1 -1 0 |
|||
$EndComp |
|||
Wire Wire Line |
|||
7300 3550 7000 3550 |
|||
Text GLabel 5650 6900 3 50 Input ~ 0 |
|||
SWITCHED_VCC |
|||
$Comp |
|||
L power:VCC #PWR0114 |
|||
U 1 1 5F8848E9 |
|||
P 8750 4900 |
|||
F 0 "#PWR0114" H 8750 4750 50 0001 C CNN |
|||
F 1 "VCC" H 8765 5073 50 0000 C CNN |
|||
F 2 "" H 8750 4900 50 0001 C CNN |
|||
F 3 "" H 8750 4900 50 0001 C CNN |
|||
1 8750 4900 |
|||
-1 0 0 1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0115 |
|||
U 1 1 5F885DD6 |
|||
P 8850 4900 |
|||
F 0 "#PWR0115" H 8850 4650 50 0001 C CNN |
|||
F 1 "GND" H 8855 4727 50 0000 C CNN |
|||
F 2 "" H 8850 4900 50 0001 C CNN |
|||
F 3 "" H 8850 4900 50 0001 C CNN |
|||
1 8850 4900 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Text Notes 7750 4300 0 197 ~ 0 |
|||
Power Supply\n |
|||
Wire Wire Line |
|||
2550 6900 2550 6750 |
|||
Wire Wire Line |
|||
2350 6900 2350 6750 |
|||
$Comp |
|||
L power:GND #PWR0105 |
|||
U 1 1 5F872A11 |
|||
P 9050 2350 |
|||
F 0 "#PWR0105" H 9050 2100 50 0001 C CNN |
|||
F 1 "GND" V 9055 2222 50 0000 R CNN |
|||
F 2 "" H 9050 2350 50 0001 C CNN |
|||
F 3 "" H 9050 2350 50 0001 C CNN |
|||
1 9050 2350 |
|||
0 -1 -1 0 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0109 |
|||
U 1 1 5F8787E6 |
|||
P 2750 6900 |
|||
F 0 "#PWR0109" H 2750 6650 50 0001 C CNN |
|||
F 1 "GND" V 2750 6750 50 0000 R CNN |
|||
F 2 "" H 2750 6900 50 0001 C CNN |
|||
F 3 "" H 2750 6900 50 0001 C CNN |
|||
1 2750 6900 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0111 |
|||
U 1 1 5F878CF4 |
|||
P 7300 3050 |
|||
F 0 "#PWR0111" H 7300 2800 50 0001 C CNN |
|||
F 1 "GND" V 7300 2900 50 0000 R CNN |
|||
F 2 "" H 7300 3050 50 0001 C CNN |
|||
F 3 "" H 7300 3050 50 0001 C CNN |
|||
1 7300 3050 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0117 |
|||
U 1 1 5F885952 |
|||
P 4850 6750 |
|||
F 0 "#PWR0117" H 4850 6500 50 0001 C CNN |
|||
F 1 "GND" V 4850 6600 50 0000 R CNN |
|||
F 2 "" H 4850 6750 50 0001 C CNN |
|||
F 3 "" H 4850 6750 50 0001 C CNN |
|||
1 4850 6750 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0118 |
|||
U 1 1 5F8874D1 |
|||
P 5850 6900 |
|||
F 0 "#PWR0118" H 5850 6650 50 0001 C CNN |
|||
F 1 "GND" V 5850 6750 50 0000 R CNN |
|||
F 2 "" H 5850 6900 50 0001 C CNN |
|||
F 3 "" H 5850 6900 50 0001 C CNN |
|||
1 5850 6900 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Text GLabel 4950 6850 3 50 Input ~ 0 |
|||
SWITCHED_VCC |
|||
$Comp |
|||
L Connector:Conn_01x02_Male J5 |
|||
U 1 1 5F9085EF |
|||
P 1700 4900 |
|||
F 0 "J5" V 1762 4944 50 0000 L CNN |
|||
F 1 "Next" V 1853 4944 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x02_P2.54mm_Vertical" H 1700 4900 50 0001 C CNN |
|||
F 3 "" H 1700 4900 50 0001 C CNN |
|||
1 1700 4900 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x02_Male J6 |
|||
U 1 1 5F90EAED |
|||
P 2200 4900 |
|||
F 0 "J6" V 2262 4944 50 0000 L CNN |
|||
F 1 "Prev" V 2353 4944 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x02_P2.54mm_Vertical" H 2200 4900 50 0001 C CNN |
|||
F 3 "" H 2200 4900 50 0001 C CNN |
|||
1 2200 4900 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x02_Male J7 |
|||
U 1 1 5F90F726 |
|||
P 2600 4900 |
|||
F 0 "J7" V 2662 4944 50 0000 L CNN |
|||
F 1 "Pause" V 2753 4944 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x02_P2.54mm_Vertical" H 2600 4900 50 0001 C CNN |
|||
F 3 "" H 2600 4900 50 0001 C CNN |
|||
1 2600 4900 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x08_Male J2 |
|||
U 1 1 5F92011C |
|||
P 4750 5050 |
|||
F 0 "J2" V 4585 4978 50 0000 C CNN |
|||
F 1 "RFID-RC522" V 4676 4978 50 0000 C CNN |
|||
F 2 "mod_s:PinHeader_1x08_P2.54mm_Vertical" H 4750 5050 50 0001 C CNN |
|||
F 3 "" H 4750 5050 50 0001 C CNN |
|||
1 4750 5050 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x03_Male J8 |
|||
U 1 1 5F936A23 |
|||
P 5750 6550 |
|||
F 0 "J8" V 5812 6694 50 0000 L CNN |
|||
F 1 "WS2812" V 5903 6694 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x03_P2.54mm_Vertical" H 5750 6550 50 0001 C CNN |
|||
F 3 "" H 5750 6550 50 0001 C CNN |
|||
1 5750 6550 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Connector:Conn_01x02_Male J9 |
|||
U 1 1 5F945F11 |
|||
P 8850 4700 |
|||
F 0 "J9" V 8912 4744 50 0000 L CNN |
|||
F 1 "Power" V 9003 4744 50 0000 L CNN |
|||
F 2 "mod_s:PinHeader_1x02_P2.54mm_Vertical" H 8850 4700 50 0001 C CNN |
|||
F 3 "" H 8850 4700 50 0001 C CNN |
|||
1 8850 4700 |
|||
0 1 1 0 |
|||
$EndComp |
|||
Wire Wire Line |
|||
1600 2850 1850 2850 |
|||
Text GLabel 1600 2850 0 50 Input ~ 0 |
|||
GPIO-17 |
|||
Wire Wire Line |
|||
2300 2400 2300 2550 |
|||
$Comp |
|||
L power:GND #PWR0102 |
|||
U 1 1 5F7B65C3 |
|||
P 2300 2400 |
|||
F 0 "#PWR0102" H 2300 2150 50 0001 C CNN |
|||
F 1 "GND" H 2305 2227 50 0000 C CNN |
|||
F 2 "" H 2300 2400 50 0001 C CNN |
|||
F 3 "" H 2300 2400 50 0001 C CNN |
|||
1 2300 2400 |
|||
-1 0 0 1 |
|||
$EndComp |
|||
Connection ~ 2300 2850 |
|||
Wire Wire Line |
|||
2300 2850 2150 2850 |
|||
Wire Wire Line |
|||
2450 2850 2300 2850 |
|||
$Comp |
|||
L Device:R R5 |
|||
U 1 1 5F7995ED |
|||
P 2000 2850 |
|||
F 0 "R5" H 2070 2896 50 0000 L CNN |
|||
F 1 "4,7k" H 2070 2805 50 0000 L CNN |
|||
F 2 "adafruit:0207_9" V 1930 2850 50 0001 C CNN |
|||
F 3 "" H 2000 2850 50 0001 C CNN |
|||
1 2000 2850 |
|||
0 1 1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Device:R R4 |
|||
U 1 1 5F798E7D |
|||
P 2300 2700 |
|||
F 0 "R4" H 2370 2746 50 0000 L CNN |
|||
F 1 "10k" H 2370 2655 50 0000 L CNN |
|||
F 2 "adafruit:0207_9" V 2230 2700 50 0001 C CNN |
|||
F 3 "" H 2300 2700 50 0001 C CNN |
|||
1 2300 2700 |
|||
-1 0 0 1 |
|||
$EndComp |
|||
$Comp |
|||
L Transistor_BJT:BC337 Q1 |
|||
U 1 1 5F78DA7C |
|||
P 2650 2850 |
|||
F 0 "Q1" H 2841 2896 50 0000 L CNN |
|||
F 1 "BC337" H 2841 2805 50 0000 L CNN |
|||
F 2 "Package_TO_SOT_THT:TO-92_Inline_Wide" H 2850 2775 50 0001 L CIN |
|||
F 3 "" H 2650 2850 50 0001 L CNN |
|||
1 2650 2850 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
$Comp |
|||
L power:GND #PWR0101 |
|||
U 1 1 5F7B5A15 |
|||
P 2750 3300 |
|||
F 0 "#PWR0101" H 2750 3050 50 0001 C CNN |
|||
F 1 "GND" H 2755 3127 50 0000 C CNN |
|||
F 2 "" H 2750 3300 50 0001 C CNN |
|||
F 3 "" H 2750 3300 50 0001 C CNN |
|||
1 2750 3300 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Wire Wire Line |
|||
2750 3050 2750 3300 |
|||
$Comp |
|||
L Transistor_FET:IRF9540N Q2 |
|||
U 1 1 5F78F572 |
|||
P 2750 2100 |
|||
F 0 "Q2" H 2954 2146 50 0000 L CNN |
|||
F 1 "IRF9540N" H 2954 2055 50 0000 L CNN |
|||
F 2 "Package_TO_SOT_THT:TO-220-3_Vertical" H 2950 2025 50 0001 L CIN |
|||
F 3 "" H 2750 2100 50 0001 L CNN |
|||
1 2750 2100 |
|||
0 -1 -1 0 |
|||
$EndComp |
|||
$Comp |
|||
L Device:R R1 |
|||
U 1 1 5F79873B |
|||
P 3050 2150 |
|||
F 0 "R1" H 3120 2196 50 0000 L CNN |
|||
F 1 "10k" H 3120 2105 50 0000 L CNN |
|||
F 2 "adafruit:0207_9" V 2980 2150 50 0001 C CNN |
|||
F 3 "" H 3050 2150 50 0001 C CNN |
|||
1 3050 2150 |
|||
1 0 0 -1 |
|||
$EndComp |
|||
Wire Wire Line |
|||
3050 2000 2950 2000 |
|||
Wire Wire Line |
|||
2750 2300 3050 2300 |
|||
Wire Wire Line |
|||
3300 2000 3050 2000 |
|||
$Comp |
|||
L power:VCC #PWR0113 |
|||
U 1 1 5F87F1D8 |
|||
P 3300 2000 |
|||
F 0 "#PWR0113" H 3300 1850 50 0001 C CNN |
|||
F 1 "VCC" V 3315 2127 50 0000 L CNN |
|||
F 2 "" H 3300 2000 50 0001 C CNN |
|||
F 3 "" H 3300 2000 50 0001 C CNN |
|||
1 3300 2000 |
|||
0 1 1 0 |
|||
$EndComp |
|||
Text GLabel 2350 2000 0 50 Input ~ 0 |
|||
SWITCHED_VCC |
|||
Wire Wire Line |
|||
2350 2000 2550 2000 |
|||
Connection ~ 3050 2000 |
|||
Wire Wire Line |
|||
2750 2300 2750 2650 |
|||
Connection ~ 2750 2300 |
|||
$EndSCHEMATC |
@ -0,0 +1,33 @@ |
|||
update=22/05/2015 07:44:53 |
|||
version=1 |
|||
last_client=kicad |
|||
[general] |
|||
version=1 |
|||
RootSch= |
|||
BoardNm= |
|||
[pcbnew] |
|||
version=1 |
|||
LastNetListRead= |
|||
UseCmpFile=1 |
|||
PadDrill=0.600000000000 |
|||
PadDrillOvalY=0.600000000000 |
|||
PadSizeH=1.500000000000 |
|||
PadSizeV=1.500000000000 |
|||
PcbTextSizeV=1.500000000000 |
|||
PcbTextSizeH=1.500000000000 |
|||
PcbTextThickness=0.300000000000 |
|||
ModuleTextSizeV=1.000000000000 |
|||
ModuleTextSizeH=1.000000000000 |
|||
ModuleTextSizeThickness=0.150000000000 |
|||
SolderMaskClearance=0.000000000000 |
|||
SolderMaskMinWidth=0.000000000000 |
|||
DrawSegmentWidth=0.200000000000 |
|||
BoardOutlineThickness=0.100000000000 |
|||
ModuleOutlineThickness=0.150000000000 |
|||
[cvpcb] |
|||
version=1 |
|||
NetIExt=net |
|||
[eeschema] |
|||
version=1 |
|||
LibDir= |
|||
[eeschema/libraries] |
After Width: 1600 | Height: 1200 | Size: 182 KiB |
@ -0,0 +1 @@ |
|||
0 |
Before Width: 1272 | Height: 883 | Size: 270 KiB After Width: 1272 | Height: 883 | Size: 270 KiB |
Before Width: 1272 | Height: 883 | Size: 290 KiB After Width: 1272 | Height: 883 | Size: 290 KiB |
Before Width: 2048 | Height: 1796 | Size: 1.1 MiB After Width: 2048 | Height: 1796 | Size: 1.1 MiB |
Before Width: 3024 | Height: 3024 | Size: 1.6 MiB After Width: 3024 | Height: 3024 | Size: 1.6 MiB |
@ -1,6 +1,6 @@ |
|||
# Headphone-PCB |
|||
This is a pcb, that was kindly provided by a user of my Tonuino-fork. It makes use of a DAC named 'PCM5102A' with a TDA1308 as amp. PCM5102A supports I2S, so it can connected in parallel to MAX98357a to the I2S-pins BCLK, LRC and DIN. Of course, it needs 3.3V and GND, too. Please note that SMD-technique is used. <br /> |
|||
The 6th pin of connector J1 is used to indicate whether there's a plug or not. That means if there is a plug, this pin is pulled to GND and therefore can be used to connect to MAX98357.SD. Doing so will mute MAX's amp and vice versa. Off course you need a special [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) to use this feature. Additionaly this 6th pin can be connected to the ESP32 in order to make use of the feature `HEADPHONE_ADJUST_ENABLE`. Doing so can optionally limit the headphone's maximum volume (configureable via GUI). <br /> |
|||
The 6th pin of connector J1 is used to indicate whether there's a plug or not. That means if there is a plug, this pin is pulled to GND and therefore can be used to connect to MAX98357.SD. Doing so will mute MAX's amp and vice versa. Of course you need a special [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) to use this feature. Additionaly this 6th pin can be connected to the ESP32 in order to make use of the feature `HEADPHONE_ADJUST_ENABLE`. Doing so can optionally limit the headphone's maximum volume (configureable via GUI). <br /> |
|||
|
|||
## Disclaimer |
|||
PCB-circuit is provided 'as is' without warranty. As previously stated it was kindly provided by a user and I only can give limited support to it. However: it runs fine without any problems in my Tonuinos. |
After Width: 1438 | Height: 799 | Size: 45 KiB |
After Width: 1438 | Height: 799 | Size: 55 KiB |
@ -0,0 +1,63 @@ |
|||
# Tonuino-PCB based on Wemos' Lolin D32 |
|||
|
|||
## Attention |
|||
* In rev1 I made a mistake that leads to a short circuit. Hopefully nobody ordered it :-( Current revision is 1.1 |
|||
* This PCB is not yet tested! |
|||
|
|||
## Features |
|||
* Fits Wemos Lolin D32 (not Lolin32, Lolin D32 pro or Lolin 32 lite!) |
|||
* 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 |
|||
* All peripherals are solely driven at 3.3V! Keep this especially in mind when choosing uSD-reader. If in doubts use one without voltage-regulator (link below). |
|||
* If [headphone-pcb](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Headphone%20with%20PCM5102a%20and%20TDA1308) is used, MAX98357a is automatically muted when there's a headphone plugged in and vice versa. |
|||
* If `HEADPHONE_ADJUST_ENABLE` is set and a headphone is plugged in, an alternative maximum volume is activated. I added this feature because [headphone-pcb](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Headphone%20with%20PCM5102a%20and%20TDA1308) makes use of an amp that (probably) "allows" children to damage ears. This maximum volume can be set and re-adjusted via webgui. |
|||
* Reset-button |
|||
|
|||
## Prerequisites |
|||
* If no [headphone-pcb](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Headphone%20with%20PCM5102a%20and%20TDA1308) is connected, make sure `HEADPHONE_ADJUST_ENABLE` is not active. |
|||
* Make sure to change values of voltage divider's restors. They can be configured in `settings.h` as `rdiv1` and `rdiv2` and need to be set to 100k/100k. |
|||
* Change `VOLTAGE_READ_PIN` to 35. |
|||
|
|||
## Things to mention |
|||
* Better don't solder Lolin D32 directly to the PCB. I recommend to make use of female connectors instead (link below). |
|||
* When ordering a LiPo-battery, make sure to use [one](https://www.eremit.de/p/eremit-3-7v-2500mah-lipo-104050-jst-ph-2-0mm) with deep discharge protection! This is really really really important!!! |
|||
* Doesn't (currently) support SD-MMC and RFID-reader PN5180 |
|||
|
|||
## Hardware-setup |
|||
The heart of my project is an ESP32 on a [Wemos Lolin D32 development-board](https://de.aliexpress.com/item/32808551116.html). 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 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) |
|||
* [Neopixel-ring](https://de.aliexpress.com/item/32673883645.html) |
|||
* [Rotary Encoder](https://de.aliexpress.com/item/33041814942.html) |
|||
* [Buttons](https://de.aliexpress.com/item/32896285438.html) |
|||
* [Speaker](https://www.visaton.de/de/produkte/chassiszubehoer/breitband-systeme/fr-7-4-ohm) |
|||
* uSD-card: doesn't have to be a super-fast one; uC is limiting the throughput. Tested 32GB without any problems. |
|||
* [JSP PH-2.0-connectors](https://de.aliexpress.com/item/32968344273.html) |
|||
* [Female connector](https://de.aliexpress.com/item/32724478308.html) |
|||
* [(optional) IDC-connector female 6pin for headphone-pcb](https://de.aliexpress.com/item/33029492417.html) |
|||
* [(optional) IDC-connector male 6pin for headphone-pcb](https://de.aliexpress.com/item/1005001400147026.html) |
|||
* [LiPo-battery (2500 mAh) with connector JST PH 2.0mm](https://www.eremit.de/p/eremit-3-7v-2500mah-lipo-104050-jst-ph-2-0mm) |
|||
|
|||
## Parts |
|||
* 1x IRF530NPbF (N-channel MOSFET) |
|||
* 1x NDP6020P (P-channel MOSFET) |
|||
* 1x 1k resistor |
|||
* 1x 10k resistor |
|||
* 2x 100k resistor |
|||
* 4x JST-PH2.0-connector (2 Pins) |
|||
* 3x JST-PH2.0-connector (3 Pins) |
|||
* 1x JST-PH2.0-connector (5 Pins) |
|||
* Female connector as socket for Lolin32, uSD-reader and MAX98357a |
|||
* (optional for headphone-PCB) 1x IDC-connecor female (6pin) |
|||
* (optional for headphone-PCB) 1x IDC-connecor male (6pin) |
|||
|
|||
## Where to order? |
|||
* I ordered my PCBs at [jlcpcb](https://jlcpcb.com/). You have to order at least 5 pcs, which is only at 2$ + shipping. It took two weeks to arrive. If you want to have a look at the PCBs first (without having KiCad installed), visit [Gerberlook](https://www.gerblook.org/) and upload `gerber.zip` from the Gerberfiles-folder. |
|||
* Enter 31 x 31mm as dimensions in JLCPCB's order-form. |
|||
|
|||
## Do I need to install KiCad? |
|||
Unless you don't want to change anything: no! All you need to provide are the gerberfiles (`gerber.zip`) to your manufactur (e.g. [jlcpcb](https://jlcpcb.com/)). However, all Kicad-files used are provided as well. |
After Width: 2048 | Height: 1152 | Size: 916 KiB |
After Width: 2048 | Height: 1152 | Size: 824 KiB |
After Width: 2048 | Height: 1152 | Size: 677 KiB |
After Width: 2048 | Height: 1152 | Size: 789 KiB |
After Width: 1438 | Height: 799 | Size: 52 KiB |
After Width: 1438 | Height: 799 | Size: 62 KiB |
@ -0,0 +1,66 @@ |
|||
# Tonuino-PCB based on Wemos' Lolin32 |
|||
|
|||
## Introduction |
|||
After I've been asked many times to provide a PCB, I finally did so :-) It makes use of Wemos' Lolin32 which is the predecessor of Lolin D32. D32's advantage over Lolin32 is especially, that a voltage-divider for measuring battery's voltage is already integrated (fixed-wired to GPIO 35). However, as I wasn't aware of that when buying Lolin32 and because of now, that multiple Lolin32 are here on my desk, my reasonable intention was to use them. So things would have been a bit easier with D32 but in the end it works the same way with Lolin32. As per rev2 of the PCB, I added a 10 uF-capacitor to smoothen the battery-measurement. Ii's optional but be advised values measured are a bit more volatile without capacitor-stabilization. |
|||
|
|||
## Features |
|||
* Fits Wemos Lolin32 (not Lolin D32, Lolin D32 pro or Lolin 32 lite!) |
|||
* Outer diameter: 56 x 93mm |
|||
* JST-PH 2.0-connectors for buttons, rotary encoder, Neopixel, RFID, reset and battery (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 |
|||
* All peripherals are solely driven at 3.3V! Keep this especially in mind when choosing uSD-reader. If in doubts use one without voltage-regulator (link below). |
|||
* If [headphone-pcb](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Headphone%20with%20PCM5102a%20and%20TDA1308) is used, MAX98357a is automatically muted when there's a headphone plugged in and vice versa. |
|||
* If `HEADPHONE_ADJUST_ENABLE` is enabled and a headphone is plugged in, an alternative maximum volume is activated. I added this feature because [headphone-pcb](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Headphone%20with%20PCM5102a%20and%20TDA1308) makes use of an amp that (probably) "allows" children to damage ears. This maximum volume can be set and re-adjusted via webgui. |
|||
* rev2: Reset-pinheader added. Can be used to connect e.g. a [micro switch](https://www.ebay.de/itm/10x-Mini-Taster-Drucktaster-klein-Mikroschalter-6x6x5mm-Arduino-Raspberry-Pi/333273061003) to it, so you can reset Tonuino even in battery-mode from the outside of the enclosure. Micro switch can be placed somewhat hidden at the enclosure. |
|||
|
|||
## Prerequisites |
|||
* If no [headphone-pcb](https://github.com/biologist79/Tonuino-ESP32-I2S/tree/master/PCBs/Headphone%20with%20PCM5102a%20and%20TDA1308) is connected, make sure `HEADPHONE_ADJUST_ENABLE` is not active. |
|||
* I used 390/130 kOhms-resistors as voltage-divider. However, make sure to use a multimeter to determine their exact values in order to achieve a better battery-measurement. They can be configured in `settings.h` as `rdiv1` and `rdiv2`. Hint: for Lolin D32's battery-measurement 100k+100k were used. However, I decided to change the ratio from 50/50% to 25/75% to have a "better" signal. 100/100 might be work as well; didn't test it. |
|||
|
|||
## Things to mention |
|||
* RFID: In order to avoid buying a 6pin-JST-PH-connector I used 2x3pin instead. This is because I already had ten of them (see link below). |
|||
* In contrast to Lolin D32, Lolin32 doesn't feature an integrated voltage-divider. That's why on the lower left there's a JST-PH2.0-connector to connect the LiPo-battery. Make sure to connect (+) to the left und GND to the right. From there you need to solder two short wires (5cm or so) onto the pcb with a JST-PH2.0-connector attached on the other side. This one needs to be plugged into Lolin32 (see pictures-folder). Please note: Lolin's JST-PH2.0-connector needs (+) left side and GND right side. Don't be confused if black/red-colouring of the JST-wires used seems "weird" because is reversed (black => (+); red => GND). |
|||
* Better don't solder Lolin32 directly to the PCB. I recommend to make use of female connectors instead (link below). |
|||
* When ordering a LiPo-battery, make sure to use [one](https://www.eremit.de/p/eremit-3-7v-2500mah-lipo-104050-jst-ph-2-0mm) with deep discharge protection! This is really really really important!!! |
|||
* Doesn't (currently) support SD-MMC and RFID-reader PN5180 |
|||
|
|||
## 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). 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 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) |
|||
* [Neopixel-ring](https://de.aliexpress.com/item/32673883645.html) |
|||
* [Rotary Encoder](https://de.aliexpress.com/item/33041814942.html) |
|||
* [Buttons](https://de.aliexpress.com/item/32896285438.html) |
|||
* [Speaker](https://www.visaton.de/de/produkte/chassiszubehoer/breitband-systeme/fr-7-4-ohm) |
|||
* uSD-card: doesn't have to be a super-fast one; uC is limiting the throughput. Tested 32GB without any problems. |
|||
* [JSP PH-2.0-connectors](https://de.aliexpress.com/item/32968344273.html) |
|||
* [Female connector](https://de.aliexpress.com/item/32724478308.html) |
|||
* [(optional) IDC-connector female 6pin for headphone-pcb](https://de.aliexpress.com/item/33029492417.html) |
|||
* [(optional) IDC-connector male 6pin for headphone-pcb](https://de.aliexpress.com/item/1005001400147026.html) |
|||
* [(optional) Mikro switch](https://www.ebay.de/itm/10x-Mini-Taster-Drucktaster-klein-Mikroschalter-6x6x5mm-Arduino-Raspberry-Pi/333273061003) |
|||
* [LiPo-battery (2500 mAh) with connector JST PH 2.0mm](https://www.eremit.de/p/eremit-3-7v-2500mah-lipo-104050-jst-ph-2-0mm) |
|||
|
|||
## Parts |
|||
* 1x IRF530NPbF (N-channel MOSFET) |
|||
* 1x NDP6020P (P-channel MOSFET) |
|||
* 1x 1k resistor |
|||
* 1x 10k resistor |
|||
* 2x 100k resistor |
|||
* 1x 130k resistor (can be replaced by 100k) |
|||
* 1x 390k resistor (can be replaced by 100k) |
|||
* 5x JST-PH2.0-connector (2 Pins) |
|||
* 3x JST-PH2.0-connector (3 Pins) |
|||
* 1x JST-PH2.0-connector (5 Pins) |
|||
* Female connector as socket for Lolin32, uSD-reader and MAX98357a |
|||
* (optional for headphone-PCB) 1x IDC-connecor female (6pin) |
|||
* (optional for headphone-PCB) 1x IDC-connecor male (6pin) |
|||
* rev2: (optional) 1x 10 uF capacitor (2.0mm-pitch) |
|||
|
|||
## Where to order? |
|||
I ordered my PCBs at [jlcpcb](https://jlcpcb.com/). You have to order at least 5 pcs, which is only at 2$ + shipping. It took two weeks to arrive. If you want to have a look at the PCBs first (without having KiCad installed), visit [Gerberlook](https://www.gerblook.org/) and upload `gerber.zip` from the Gerberfiles-folder. |
|||
|
|||
## Do I need to install KiCad? |
|||
Unless you don't want to change anything: no! All you need to provide are the gerberfiles (`gerber.zip`) to your manufactur (e.g. [jlcpcb](https://jlcpcb.com/)). However, all Kicad-files used are provided as well. |
After Width: 1438 | Height: 799 | Size: 53 KiB |
After Width: 1438 | Height: 799 | Size: 65 KiB |
After Width: 2048 | Height: 1152 | Size: 916 KiB |
After Width: 2048 | Height: 1152 | Size: 824 KiB |
After Width: 2048 | Height: 1152 | Size: 677 KiB |
After Width: 2048 | Height: 1152 | Size: 789 KiB |
@ -0,0 +1,64 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<title>WLAN-Einrichtung</title> |
|||
<style> |
|||
input { |
|||
width: 90%; |
|||
height: 44px; |
|||
border-radius: 4px; |
|||
margin: 10px auto; |
|||
font-size: 15px; |
|||
background: #f1f1f1; |
|||
border: 0; |
|||
padding: 0 15px |
|||
} |
|||
input { |
|||
|
|||
} |
|||
body { |
|||
background: #007bff; |
|||
font-family: sans-serif; |
|||
font-size: 14px; |
|||
color: #777 |
|||
} |
|||
.box { |
|||
background: #fff; |
|||
max-width: 258px; |
|||
margin: 75px auto; |
|||
padding: 30px; |
|||
border-radius: 5px; |
|||
text-align: center |
|||
} |
|||
.btn { |
|||
background: #3498db; |
|||
color: #fff; |
|||
cursor: pointer; |
|||
width: 90%; |
|||
height: 44px; |
|||
border-radius: 4px; |
|||
margin: 10px auto; |
|||
font-size: 15px; |
|||
} |
|||
.rebootmsg { |
|||
display: none; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<form id="settings" action="/init" class="box" method="POST"> |
|||
<h1>WLAN-Einrichtung</h1> |
|||
<label for="ssid">SSID:</label><br> |
|||
<input type="text" id="ssid" name="ssid" placeholder="SSID" required><br> |
|||
<label for="pwd">Passwort:</label><br> |
|||
<input type="password" id="pwd" name="pwd" autocomplete="off" required><br> |
|||
<label for="hostname">Tonuino-Name (Hostname):</label><br> |
|||
<input type="text" id="hostname" name="hostname" placeholder="Tonuino" required><br><br> |
|||
<input class="btn" type="submit" id="save-button" value="Save"> |
|||
</form> |
|||
<form action="/restart" class="box"> |
|||
<h1>Fertig?</h1> |
|||
<input class="btn" type="submit" id="restart-button" value="Reboot"> |
|||
</form> |
|||
</body> |
|||
</html> |
@ -0,0 +1,64 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<title>WiFi-configuration</title> |
|||
<style> |
|||
input { |
|||
width: 90%; |
|||
height: 44px; |
|||
border-radius: 4px; |
|||
margin: 10px auto; |
|||
font-size: 15px; |
|||
background: #f1f1f1; |
|||
border: 0; |
|||
padding: 0 15px |
|||
} |
|||
input { |
|||
|
|||
} |
|||
body { |
|||
background: #007bff; |
|||
font-family: sans-serif; |
|||
font-size: 14px; |
|||
color: #777 |
|||
} |
|||
.box { |
|||
background: #fff; |
|||
max-width: 258px; |
|||
margin: 75px auto; |
|||
padding: 30px; |
|||
border-radius: 5px; |
|||
text-align: center |
|||
} |
|||
.btn { |
|||
background: #3498db; |
|||
color: #fff; |
|||
cursor: pointer; |
|||
width: 90%; |
|||
height: 44px; |
|||
border-radius: 4px; |
|||
margin: 10px auto; |
|||
font-size: 15px; |
|||
} |
|||
.rebootmsg { |
|||
display: none; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<form id="settings" action="/init" class="box" method="POST"> |
|||
<h1>WiFi-configuration</h1> |
|||
<label for="ssid">SSID:</label><br> |
|||
<input type="text" id="ssid" name="ssid" placeholder="SSID" required><br> |
|||
<label for="pwd">Password:</label><br> |
|||
<input type="password" id="pwd" name="pwd" autocomplete="off" required><br> |
|||
<label for="hostname">Tonuino's name (hostname):</label><br> |
|||
<input type="text" id="hostname" name="hostname" placeholder="Tonuino" required><br><br> |
|||
<input class="btn" type="submit" id="save-button" value="Save"> |
|||
</form> |
|||
<form action="/restart" class="box"> |
|||
<h1>Ready to go?</h1> |
|||
<input class="btn" type="submit" id="restart-button" value="Reboot"> |
|||
</form> |
|||
</body> |
|||
</html> |
@ -0,0 +1,727 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="de"> |
|||
<head> |
|||
<title>ESPuino-Konfiguration</title> |
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
<link rel="stylesheet" href="https://ts-cs.de/tonuino/css/bootstrap.min.css"> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css"/> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"/> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css"/> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/11.0.2/css/bootstrap-slider.min.css" /> |
|||
<script src="https://ts-cs.de/tonuino/js/jquery.min.js"></script> |
|||
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script> |
|||
<script src="https://ts-cs.de/tonuino/js/popper.min.js"></script> |
|||
<script src="https://ts-cs.de/tonuino/js/bootstrap.min.js"></script> |
|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script> |
|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script> |
|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/11.0.2/bootstrap-slider.min.js"></script> |
|||
<style type="text/css"> |
|||
.filetree { |
|||
border: 1px solid black; |
|||
height: 200px; |
|||
margin: 0em 0em 1em 0em; |
|||
overflow-y: scroll; |
|||
} |
|||
.slider.slider-horizontal { |
|||
width: 60%; |
|||
margin-left: 1em; |
|||
margin-right: 1em; |
|||
|
|||
} |
|||
.slider-handle{ |
|||
height: 30px; |
|||
width: 30px; |
|||
top: -5px; |
|||
} |
|||
|
|||
legend.scheduler-border { |
|||
width:inherit; /* Or auto */ |
|||
padding:0 10px; /* To give a bit of padding on the left and right */ |
|||
border-bottom:none; |
|||
} |
|||
|
|||
.icon-pos{ |
|||
top: 0.3em; |
|||
position: relative; |
|||
} |
|||
.reboot{ |
|||
color:white; |
|||
} |
|||
.reboot:hover{ |
|||
color: orange; |
|||
} |
|||
|
|||
.fa-sync:hover { |
|||
color: #666666; |
|||
} |
|||
|
|||
.clickForRefresh { |
|||
text-align: center; |
|||
color: gray; |
|||
cursor: pointer; |
|||
margin-top: 5em; |
|||
} |
|||
|
|||
.clickForRefresh:hover { |
|||
color: darkgray; |
|||
} |
|||
|
|||
.filetree-container { |
|||
position: relative; |
|||
} |
|||
|
|||
.indexing-progress { |
|||
width: 100%; |
|||
height: 100%; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
opacity: 0.7; |
|||
display: none; |
|||
} |
|||
|
|||
.refreshAction{ |
|||
text-align: right; |
|||
font-size: 0.8em; |
|||
} |
|||
|
|||
.refreshAction:hover{ |
|||
cursor: pointer; |
|||
color: darkgray; |
|||
} |
|||
|
|||
.overlay { |
|||
z-index: 9; |
|||
opacity: 0.8; |
|||
background: #1a1919; |
|||
height: 200px; |
|||
display: none; |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<nav class="navbar navbar-expand-sm bg-primary navbar-dark"> |
|||
<div class="col-md-12"> |
|||
<a class="float-left navbar-brand"> |
|||
<img src="https://raw.githubusercontent.com/biologist79/Tonuino-ESP32-I2S/master/html/tonuino_logo.png" |
|||
width="30" height="30" class="d-inline-block align-top" alt=""/> |
|||
Tonuino |
|||
</a> |
|||
|
|||
<a class="reboot float-right nav-link" href="/restart"><i class="fas fa-power-off"></i> Neustart</a> |
|||
</div> |
|||
</nav> |
|||
<br/> |
|||
<nav> |
|||
<div class="container nav nav-tabs" id="nav-tab" role="tablist"> |
|||
<a class="nav-item nav-link active" id="nav-rfid-tab" data-toggle="tab" href="#nav-rfid" role="tab" aria-controls="nav-rfid" aria-selected="true"><i class="fas fa-dot-circle"></i> RFID</a> |
|||
<a class="nav-item nav-link" id="nav-wifi-tab" data-toggle="tab" href="#nav-wifi" role="tab" aria-controls="nav-wifi" aria-selected="false"><i class="fas fa-wifi"></i><span class=".d-sm-none .d-md-block"> WLAN</span></a> |
|||
<a class="nav-item nav-link" id="nav-mqtt-tab" data-toggle="tab" href="#nav-mqtt" role="tab" aria-controls="nav-mqtt" aria-selected="false"><i class="fas fa-network-wired"></i> MQTT</a> |
|||
<a class="nav-item nav-link" id="nav-ftp-tab" data-toggle="tab" href="#nav-ftp" role="tab" aria-controls="nav-ftp" aria-selected="false"><i class="fas fa-folder"></i> FTP</a> |
|||
<a class="nav-item nav-link" id="nav-general-tab" data-toggle="tab" href="#nav-general" role="tab" aria-controls="nav-general" aria-selected="false"><i class="fas fa-sliders-h"></i> Allgemein</a> |
|||
<a class="nav-item nav-link" id="nav-tools-tab" data-toggle="tab" href="#nav-tools" role="tab" aria-controls="nav-tools" aria-selected="false"><i class="fas fa-wrench"></i> Tools</a> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="tab-content" id="nav-tabContent"> |
|||
<div class="tab-pane fade" id="nav-wifi" role="tabpanel" aria-labelledby="nav-wifi-tab"> |
|||
<div class="container" id="wifiConfig"> |
|||
<form action="#wifiConfig" method="POST" onsubmit="wifiConfig('wifiConfig'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<label for="ssid">WLAN-Name (SSID):</label> |
|||
<input type="text" class="form-control" id="ssid" placeholder="SSID" name="ssid" required> |
|||
<div class="invalid-feedback"> |
|||
Bitte SSID des WLANs eintragen. |
|||
</div> |
|||
<label for="pwd">Passwort:</label> |
|||
<input type="password" class="form-control" id="pwd" placeholder="Passwort" name="pwd" required> |
|||
<label for="hostname">Tonuino-Name (Hostname):</label> |
|||
<input type="text" class="form-control" id="hostname" placeholder="tonuino" name="hostname" |
|||
value="%HOSTNAME%" pattern="^[^-\.]{2,32}" required> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
<div class="tab-pane fade show active" id="nav-rfid" role="tabpanel" aria-labelledby="nav-rfid-tab"> |
|||
<div class="container" id="rfidMusicTags"> |
|||
<fieldset> |
|||
<legend>RFID-Zuweisungen</legend> |
|||
<form action="#rfidMusicTags" method="POST" onsubmit="rfidAssign('rfidMusicTags'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<label for="rfidIdMusic">RFID-Chip-Nummer (12-stellig)</label> |
|||
<input type="text" class="form-control" id="rfidIdMusic" maxlength="12" pattern="[0-9]{12}" |
|||
placeholder="%RFID_TAG_ID%" name="rfidIdMusic" required> |
|||
<label for="fileOrUrl">Datei, Verzeichnis oder URL (^ und # als Zeichen nicht erlaubt)</label> |
|||
<input type="text" class="form-control" id="fileOrUrl" maxlength="255" placeholder="z.B. /mp3/Hoerspiele/Yakari/Yakari_und_seine_Freunde.mp3" pattern="^[^\^#]+$" name="fileOrUrl" required> |
|||
<div class="filetree-container"> |
|||
<div id="filebrowser"> |
|||
<div class="filetree demo" id="filetree"></div> |
|||
<div class="refreshAction"> |
|||
<span id="refreshAction" data-toggle="tooltip" data-placement="top" title="Datei Liste aktualisieren."><i class="fas fa-sync fa-1x"></i> Dateiliste aktualisieren</span> |
|||
</div> |
|||
</div> |
|||
<div id="indexing-progress" class="indexing-progress overlay"> |
|||
<div style="text-align: center; color:white; margin-top:2em;"> |
|||
<div><i class="fas fa-sync fa-spin fa-2x"></i> <br><br> Der Prozess kann mehrere Minuten dauern...</div> |
|||
<div id="currentProcessedFile"></div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<label for="playMode">Abspielmodus</label> |
|||
<select class="form-control" id="playMode" name="playMode"> |
|||
<option class="option-file" value="1">Einzelner Titel</option> |
|||
<option class="option-file" value="2">Einzelner Titel (Endlosschleife)</option> |
|||
<option class="option-file-and-folder" value="3">Hörbuch</option> |
|||
<option class="option-file-and-folder" value="4">Hörbuch (Endlosschleife)</option> |
|||
<option class="option-folder" value="5">Alle Titel eines Verzeichnis (sortiert)</option> |
|||
<option class="option-folder" value="6">Alle Titel eines Verzeichnis (zufällig)</option> |
|||
<option class="option-folder" value="7">Alle Titel eines Verzeichnis (sortiert, Endlosschleife)</option> |
|||
<option class="option-folder" value="9">Alle Titel eines Verzeichnis (zufällig, Endlosschleife)</option> |
|||
<option class="option-stream" value="8">Webradio</option> |
|||
</select> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</div> |
|||
</form> |
|||
</fieldset> |
|||
</div> |
|||
|
|||
<br> |
|||
<br> |
|||
<div class="container" id="rfidModTags"> |
|||
<fieldset> |
|||
<legend>RFID-Modifkationen</legend> |
|||
<form class="needs-validation" action="#rfidModTags" method="POST" onsubmit="rfidMods('rfidModTags'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<label for="rfidIdMod">RFID-Chip-Nummer (12-stellig)</label> |
|||
<input type="text" class="form-control" id="rfidIdMod" maxlength="12" pattern="[0-9]{12}" |
|||
placeholder="%RFID_TAG_ID%" name="rfidIdMod" required> |
|||
<div class="invalid-feedback"> |
|||
Bitte eine 12-stellige Zahl eingeben. |
|||
</div> |
|||
<label for="modId">Konfiguraiton</label> |
|||
<select class="form-control" id="modId" name="modId"> |
|||
<option value="100">Tastensperre</option> |
|||
<option value="101">Schlafen nach 15 Minuten</option> |
|||
<option value="102">Schlafen nach 30 Minuten</option> |
|||
<option value="103">Schlafen nach 1 Stunde</option> |
|||
<option value="104">Schlafen nach 2 Stunden</option> |
|||
<option value="105">Schlafen nach Ende des Titels</option> |
|||
<option value="106">Schlafen nach Ende der Playlist</option> |
|||
<option value="107">Schlafen nach fünf Titeln</option> |
|||
<option value="110">Wiederhole Playlist (endlos)</option> |
|||
<option value="111">Wiederhole Titel (endlos)</option> |
|||
<option value="112">Dimme LEDs (Nachtmodus)</option> |
|||
<option value="130">Aktiviere/deaktive WLAN</option> |
|||
</select> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</div> |
|||
</form> |
|||
</fieldset> |
|||
</div> |
|||
</div> |
|||
<div class="tab-pane fade" id="nav-mqtt" role="tabpanel" aria-labelledby="nav-mqtt-tab"> |
|||
<div class="container" id="mqttConfig"> |
|||
|
|||
<form class="needs-validation" action="#mqttConfig" method="POST" |
|||
onsubmit="mqttSettings('mqttConfig'); return false"> |
|||
<div class="form-check col-md-12"> |
|||
<input class="form-check-input" type="checkbox" value="1" id="mqttEnable" name="mqttEnable" %MQTT_ENABLE%> |
|||
<label class="form-check-label" for="mqttEnable"> |
|||
MQTT aktivieren |
|||
</label> |
|||
</div> |
|||
<div class="form-group my-2 col-md-12"> |
|||
<label for="mqttServer">MQTT-Server</label> |
|||
<input type="text" class="form-control" id="mqttServer" minlength="7" maxlength="%MQTT_SERVER_LENGTH%" |
|||
placeholder="z.B. 192.168.2.89" name="mqttServer" value="%MQTT_SERVER%"> |
|||
<label for="mqttUser">MQTT-Benutzername (optional):</label> |
|||
<input type="text" class="form-control" id="mqttUser" maxlength="%MQTT_USER_LENGTH%" |
|||
placeholder="Benutzername" name="mqttUser" value="%MQTT_USER%"> |
|||
<label for="mqttPwd">MQTT-Passwort (optional):</label> |
|||
<input type="password" class="form-control" id="mqttPwd" maxlength="%MQTT_PWD_LENGTH%" |
|||
placeholder="Passwort" name="mqttPwd" value="%MQTT_PWD%"> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
<div class="tab-pane fade" id="nav-ftp" role="tabpanel" aria-labelledby="nav-ftp-tab"> |
|||
<div class="container" id="ftpConfig"> |
|||
|
|||
<form action="#ftpConfig" method="POST" onsubmit="ftpSettings('ftpConfig'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<label for="ftpUser">FTP-Benutzername:</label> |
|||
<input type="text" class="form-control" id="ftpUser" maxlength="%FTP_USER_LENGTH%" |
|||
placeholder="Benutzername" name="ftpUser" value="%FTP_USER%" required> |
|||
<label for="pwd">FTP-Passwort:</label> |
|||
<input type="password" class="form-control" id="ftpPwd" maxlength="%FTP_PWD_LENGTH%" placeholder="Passwort" |
|||
name="ftpPwd" value="%FTP_PWD%" required> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="tab-pane fade" id="nav-general" role="tabpanel" aria-labelledby="nav-general-tab"> |
|||
<div class="container" id="generalConfig"> |
|||
|
|||
<form action="#generalConfig" method="POST" onsubmit="genSettings('generalConfig'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<fieldset> |
|||
<legend class="w-auto">Lautstärke</legend> |
|||
<label for="initialVolume">Nach dem Einschalten</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-volume-down fa-2x .icon-pos"></i> <input data-provide="slider" type="number" data-slider-min="1" data-slider-max="21" min="1" max="21" class="form-control" id="initialVolume" name="initialVolume" |
|||
data-slider-value="%INIT_VOLUME%" value="%INIT_VOLUME%" required> <i class="fas fa-volume-up fa-2x .icon-pos"></i></div> |
|||
<br> |
|||
<label for="maxVolumeSpeaker">Maximal (Lautsprecher)</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-volume-down fa-2x .icon-pos"></i> <input data-provide="slider" type="number" data-slider-min="1" data-slider-max="21" min="1" max="21" class="form-control" id="maxVolumeSpeaker" name="maxVolumeSpeaker" |
|||
data-slider-value="%MAX_VOLUME_SPEAKER%" value="%MAX_VOLUME_SPEAKER%" required> <i class="fas fa-volume-up fa-2x .icon-pos"></i> |
|||
</div> |
|||
<br> |
|||
<label for="maxVolumeHeadphone">Maximal (Kopfhörer)</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-volume-down fa-2x .icon-pos"></i> <input data-provide="slider" type="number" data-slider-min="1" data-slider-max="21" min="1" max="21" class="form-control" id="maxVolumeHeadphone" name="maxVolumeHeadphone" |
|||
data-slider-value="%MAX_VOLUME_HEADPHONE%" value="%MAX_VOLUME_HEADPHONE%" required> <i class="fas fa-volume-up fa-2x .icon-pos"></i> |
|||
</div> |
|||
</fieldset> |
|||
</div> |
|||
<br> |
|||
<div class="form-group col-md-12"> |
|||
<fieldset > |
|||
<legend class="w-auto">Neopixel (Helligkeit)</legend> |
|||
<label for="initBrightness">Nach dem Einschalten:</label> |
|||
<div class="text-center"> |
|||
<i class="far fa-sun fa-2x .icon-pos"></i> |
|||
<input data-provide="slider" type="number" data-slider-min="0" data-slider-max="255" min="0" max="255" class="form-control" id="initBrightness" name="initBrightness" |
|||
data-slider-value="%INIT_LED_BRIGHTNESS%" value="%INIT_LED_BRIGHTNESS%" required><i class="fas fa-sun fa-2x .icon-pos"></i> |
|||
</div> |
|||
|
|||
<label for="nightBrightness">Im Nachtmodus</label> |
|||
<div class="text-center"> |
|||
<i class="far fa-sun fa-2x .icon-pos"></i><input data-provide="slider" type="number" data-slider-min="0" data-slider-max="255" min="0" max="255" class="form-control" id="nightBrightness" name="nightBrightness" data-slider-value="%NIGHT_LED_BRIGHTNESS%" value="%NIGHT_LED_BRIGHTNESS%" required><i class="fas fa-sun fa-2x .icon-pos"></i> |
|||
</div> |
|||
</fieldset> |
|||
</div> |
|||
<br> |
|||
<div class="form-group col-md-12"> |
|||
<fieldset> |
|||
<legend>Deep Sleep</legend> |
|||
|
|||
<label for="inactivityTime">Inaktivität nach (in Minuten)</label> |
|||
<div class="text-center"><i class="fas fa-hourglass-start fa-2x .icon-pos"></i> <input type="number" data-provide="slider" data-slider-min="0" data-slider-max="30" min="1" max="120" class="form-control" id="inactivityTime" name="inactivityTime" |
|||
data-slider-value="%MAX_INACTIVITY%" value="%MAX_INACTIVITY%" required><i class="fas fa-hourglass-end fa-2x .icon-pos"></i></div> |
|||
</fieldset> |
|||
</div> |
|||
<br> |
|||
|
|||
<div class="form-group col-md-12"> |
|||
<fieldset> |
|||
<legend>Batterie</legend> |
|||
<div>Status über Neopixel anzeigen</div> |
|||
<br> |
|||
<label for="warningLowVoltage">Unter dieser Spannung wird eine Warnung angezeit. |
|||
</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-battery-quarter fa-2x .icon-pos"></i> <input data-provide="slider" data-slider-step="0.1" data-slider-min="3.0" data-slider-max="5.0" min="3.0" max="5.0" type="text" class="form-control" id="warningLowVoltage" name="warningLowVoltage" |
|||
data-slider-value="%WARNING_LOW_VOLTAGE%" value="%WARNING_LOW_VOLTAGE%" pattern="^\d{1,2}(\.\d{1,3})?" required> <i class="fas fa-battery-three-quarters fa-2x .icon-pos" fa-2x .icon-pos></i> |
|||
</div> |
|||
<br> |
|||
<label for="voltageIndicatorLow">Eine LED leuchtet bei dieser Spannung |
|||
</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-battery-quarter fa-2x .icon-pos"></i> <input data-provide="slider" min="2.0" data-slider-step="0.1" data-slider-min="2.0" data-slider-max="5.0" max="5.0"type="text" class="form-control" id="voltageIndicatorLow" name="voltageIndicatorLow" |
|||
data-slider-value="%VOLTAGE_INDICATOR_LOW%" value="%VOLTAGE_INDICATOR_LOW%" pattern="^\d{1,2}(\.\d{1,3})?" required> <i class="fas fa-battery-three-quarters fa-2x .icon-pos" fa-2x .icon-pos></i> |
|||
</div> |
|||
<br> |
|||
<label for="voltageIndicatorHigh">Alle LEDs leuchten bei dieser Spannung</label> |
|||
|
|||
<div class="text-center"> |
|||
<i class="fas fa-battery-quarter fa-2x .icon-pos"></i><input data-provide="slider" data-slider-step="0.1" data-slider-min="2.0" data-slider-max="5.0" min="2.0" max="5.0" type="text" class="form-control" id="voltageIndicatorHigh" name="voltageIndicatorHigh" |
|||
data-slider-value="%VOLTAGE_INDICATOR_HIGH%" value="%VOLTAGE_INDICATOR_HIGH%" pattern="^\d{1,2}(\.\d{1,3})?" required> <i class="fas fa-battery-three-quarters fa-2x .icon-pos" fa-2x .icon-pos></i> |
|||
</div> |
|||
|
|||
<br> |
|||
<label for="voltageCheckInterval">Zeitabstand der Messung (in Minuten)</label> |
|||
<div class="text-center"><i class="fas fa-hourglass-start fa-2x .icon-pos"></i> |
|||
<input data-provide="slider" data-slider-min="1" data-slider-max="60" type="number" min="1" max="60" class="form-control" id="voltageCheckInterval" |
|||
data-slider-value="%VOLTAGE_CHECK_INTERVAL%" name="voltageCheckInterval" value="%VOLTAGE_CHECK_INTERVAL%" required><i class="fas fa-hourglass-end fa-2x .icon-pos"></i> |
|||
</div> |
|||
|
|||
</fieldset> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
<div class="tab-pane fade" id="nav-tools" role="tabpanel" aria-labelledby="nav-tools-tab"> |
|||
<div class="container my-5" id="importNvs"> |
|||
<h2>NVS-Importer</h2> |
|||
<form action="/upload" enctype="multipart/form-data" method="POST"> |
|||
<div class="form-group"> |
|||
<label for="nvsUpload">Hier kann eine Backup-Datei importiert werden.</label> |
|||
<input type="file" class="form-control-file" id="nvsUpload" name="nvsUpload" accept=".txt"> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<script type="text/javascript"> |
|||
var DEBUG = false; |
|||
var lastIdclicked = ''; |
|||
var host = $(location).attr('hostname'); |
|||
|
|||
if (DEBUG) { |
|||
host = "192.168.178.114"; |
|||
} |
|||
|
|||
toastr.options = { |
|||
"closeButton": false, |
|||
"debug": false, |
|||
"newestOnTop": false, |
|||
"progressBar": false, |
|||
"positionClass": "toast-top-right", |
|||
"preventDuplicates": false, |
|||
"onclick": null, |
|||
"showDuration": "300", |
|||
"hideDuration": "1000", |
|||
"timeOut": "5000", |
|||
"extendedTimeOut": "1000", |
|||
"showEasing": "swing", |
|||
"hideEasing": "linear", |
|||
"showMethod": "fadeIn", |
|||
"hideMethod": "fadeOut" |
|||
}; |
|||
|
|||
function postRendering(event, data) { |
|||
Object.keys(data.instance._model.data).forEach(function (key, index) { |
|||
|
|||
var cur = data.instance.get_node(data.instance._model.data[key]); |
|||
var lastFolder = cur['id'].split('/').filter(function (el) { |
|||
return el.trim().length > 0; |
|||
}).pop(); |
|||
if ((/\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|flac|FLAC)$/i).test(lastFolder)) { |
|||
data.instance.set_type(data.instance._model.data[key], 'audio'); |
|||
} else { |
|||
if (data.instance._model.data[key]['type'] == "file") { |
|||
data.instance.disable_node(data.instance._model.data[key]); |
|||
} |
|||
} |
|||
data.instance.rename_node(data.instance._model.data[key], lastFolder); |
|||
}); |
|||
} |
|||
|
|||
function renderFileTree() { |
|||
|
|||
var filesURI = "/files"; |
|||
if (DEBUG) { |
|||
filesURI = "http://" + host + "/files"; |
|||
} |
|||
$('#filetree').jstree({ |
|||
'core': { |
|||
'check_callback': true, |
|||
'data': { |
|||
url: filesURI, |
|||
error: function (XMLHttpRequest, textStatus, errorThrown) { |
|||
$('#j1_loading').hide(); |
|||
$("#refreshAction").hide(); |
|||
$('#filetree').html("<div class='clickForRefresh' ><i class='fas fa-sync fa-1x'><span id='#clickForRefresh' > Dateien suchen.</span></div>"); |
|||
$('#filetree').on("click", function () { |
|||
refreshFileList(); |
|||
}); |
|||
toastr.error("Die Verzeichnis-Liste konnte nicht geladen werden."); |
|||
} |
|||
}, |
|||
|
|||
}, |
|||
'types': { |
|||
'folder': { |
|||
'icon': "fa fa-folder" |
|||
}, |
|||
'file': { |
|||
'icon': "fa fa-file" |
|||
}, |
|||
'audio': { |
|||
'icon': "fa fa-file-audio" |
|||
}, |
|||
'default': { |
|||
'icon': "fa fa-folder" |
|||
} |
|||
}, |
|||
'plugins': ["themes", "types"] |
|||
}).bind('loaded.jstree', function (event, data) { |
|||
postRendering(event, data); |
|||
if ((data.instance._model.data['#']['children'].length == 0)) { |
|||
toastr.info("Der SD-Karten-Index muss erzeugt werden."); |
|||
} |
|||
}).bind('refresh.jstree', function (event, data) { |
|||
postRendering(event, data); |
|||
}); |
|||
} |
|||
|
|||
$('#filetree').on('select_node.jstree', function (e, data) { |
|||
$('input[name=fileOrUrl]').val(data.node.id); |
|||
|
|||
if (data.node.type == "folder") { |
|||
$('.option-folder').show(); |
|||
$('.option-file').hide(); |
|||
$('#playMode option').removeAttr('selected').filter('[value=3]').attr('selected', true); |
|||
} |
|||
|
|||
if (data.node.type == "audio") { |
|||
$('.option-file').show(); |
|||
$('.option-folder').hide(); |
|||
$('#playMode option').removeAttr('selected').filter('[value=1]').attr('selected', true); |
|||
} |
|||
}); |
|||
|
|||
$('#refreshAction').on("click", function () { |
|||
refreshFileList(); |
|||
$("#indexing-progress").show(); |
|||
$("#refreshAction").hide(); |
|||
}); |
|||
|
|||
$('#playMode').on("change", function () { |
|||
if (this.value == 8) { |
|||
$('#filebrowser').slideUp(); |
|||
} else { |
|||
$('#filebrowser').slideDown(); |
|||
} |
|||
}); |
|||
|
|||
function showFileIndexingState() { |
|||
$("#indexing-progress").show(); |
|||
$("#refreshAction").hide(); |
|||
} |
|||
|
|||
function hideFileIndexingState() { |
|||
$("#indexing-progress").hide(); |
|||
$("#refreshAction").show(); |
|||
} |
|||
|
|||
var socket = undefined; |
|||
var tm; |
|||
|
|||
function connect() { |
|||
socket = new WebSocket("ws://" + host + "/ws"); |
|||
|
|||
socket.onopen = function () { |
|||
setInterval(ping, 15000); |
|||
}; |
|||
|
|||
socket.onclose = function (e) { |
|||
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason); |
|||
socket = null; |
|||
setTimeout(function () { |
|||
connect(); |
|||
}, 5000); |
|||
}; |
|||
|
|||
socket.onerror = function (err) { |
|||
console.error('Socket encountered error: ', err.message, 'Closing socket'); |
|||
}; |
|||
|
|||
socket.onmessage = function(event) { |
|||
console.log(event.data); |
|||
var socketMsg = JSON.parse(event.data); |
|||
if (socketMsg.rfidId != null) { |
|||
document.getElementById('rfidIdMod').value = socketMsg.rfidId; |
|||
document.getElementById('rfidIdMusic').value = socketMsg.rfidId; |
|||
toastr.info("RFID Tag mit "+ socketMsg.rfidId + " erkannt." ); |
|||
|
|||
$("#rfidIdMusic").effect("highlight", {color:"#abf5af"}, 3000); |
|||
$("#rfidIdMod").effect("highlight", {color:"#abf5af"}, 3000); |
|||
|
|||
} if ("status" in socketMsg) { |
|||
if (socketMsg.status == "ok") { |
|||
toastr.success("Aktion erfolgreich ausgeführt." ); |
|||
} |
|||
} if ("pong" in socketMsg) { |
|||
if (socketMsg.pong == 'pong') { |
|||
pong(); |
|||
} |
|||
} if ("refreshFileList" in socketMsg) { |
|||
hideFileIndexingState(); |
|||
toastr.info("Die Dateiliste wurde neu erzeugt!"); |
|||
$('#filetree').jstree(true).refresh(); |
|||
|
|||
} |
|||
if ("indexingState" in socketMsg) { |
|||
if(socketMsg.indexingState != null) { |
|||
$("#currentProcessedFile").text(socketMsg.indexingState); |
|||
console.log(socketMsg.indexingState); |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
|
|||
function ping() { |
|||
var myObj = { |
|||
"ping": { |
|||
ping: 'ping' |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
tm = setTimeout(function () { |
|||
toastr.warning('Die Verbindung zum Tonuino ist unterbrochen! Bitte Seite neu laden.'); |
|||
}, 5000); |
|||
} |
|||
|
|||
function pong() { |
|||
clearTimeout(tm); |
|||
} |
|||
|
|||
function refreshFileList(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"refreshFileList": true |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
$("#refreshAction").hide(); |
|||
socket.send(myJSON); |
|||
showFileIndexingState(); |
|||
}; |
|||
|
|||
function genSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"general": { |
|||
iVol: document.getElementById('initialVolume').value, |
|||
mVolSpeaker: document.getElementById('maxVolumeSpeaker').value, |
|||
mVolHeadphone: document.getElementById('maxVolumeHeadphone').value, |
|||
iBright: document.getElementById('initBrightness').value, |
|||
nBright: document.getElementById('nightBrightness').value, |
|||
iTime: document.getElementById('inactivityTime').value, |
|||
vWarning: document.getElementById('warningLowVoltage').value, |
|||
vIndLow: document.getElementById('voltageIndicatorLow').value, |
|||
vIndHi: document.getElementById('voltageIndicatorHigh').value, |
|||
vInt: document.getElementById('voltageCheckInterval').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function ftpSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"ftp": { |
|||
ftpUser: document.getElementById('ftpUser').value, |
|||
ftpPwd: document.getElementById('ftpPwd').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function mqttSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var val; |
|||
if (document.getElementById('mqttEnable').checked) { |
|||
val = document.getElementById('mqttEnable').value; |
|||
} else { |
|||
val = 0; |
|||
} |
|||
var myObj = { |
|||
"mqtt": { |
|||
mqttEnable: val, |
|||
mqttServer: document.getElementById('mqttServer').value, |
|||
mqttUser: document.getElementById('mqttUser').value, |
|||
mqttPwd: document.getElementById('mqttPwd').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function rfidMods(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"rfidMod": { |
|||
rfidIdMod: document.getElementById('rfidIdMod').value, |
|||
modId: document.getElementById('modId').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function removeTrSlash(str) { |
|||
if (str.substr(-1) === '/') { |
|||
return str.substr(0, str.length - 1); |
|||
} |
|||
return str; |
|||
} |
|||
|
|||
function rfidAssign(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"rfidAssign": { |
|||
rfidIdMusic: document.getElementById('rfidIdMusic').value, |
|||
fileOrUrl: removeTrSlash(document.getElementById('fileOrUrl').value), |
|||
playMode: document.getElementById('playMode').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function wifiConfig(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"wifiConfig": { |
|||
ssid: document.getElementById('ssid').value, |
|||
pwd: document.getElementById('pwd').value, |
|||
hostname: document.getElementById('hostname').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
$(document).ready(function () { |
|||
connect(); |
|||
renderFileTree(); |
|||
|
|||
console.log(parseInt(document.getElementById('warningLowVoltage').value)); |
|||
$(function () { |
|||
$('[data-toggle="tooltip"]').tooltip(); |
|||
}); |
|||
|
|||
}); |
|||
</script> |
|||
</body> |
|||
</html> |
@ -0,0 +1,727 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="de"> |
|||
<head> |
|||
<title>ESPuino-configuration</title> |
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
<link rel="stylesheet" href="https://ts-cs.de/tonuino/css/bootstrap.min.css"> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css"/> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"/> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css"/> |
|||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/11.0.2/css/bootstrap-slider.min.css" /> |
|||
<script src="https://ts-cs.de/tonuino/js/jquery.min.js"></script> |
|||
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script> |
|||
<script src="https://ts-cs.de/tonuino/js/popper.min.js"></script> |
|||
<script src="https://ts-cs.de/tonuino/js/bootstrap.min.js"></script> |
|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script> |
|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script> |
|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/11.0.2/bootstrap-slider.min.js"></script> |
|||
<style type="text/css"> |
|||
.filetree { |
|||
border: 1px solid black; |
|||
height: 200px; |
|||
margin: 0em 0em 1em 0em; |
|||
overflow-y: scroll; |
|||
} |
|||
.slider.slider-horizontal { |
|||
width: 60%; |
|||
margin-left: 1em; |
|||
margin-right: 1em; |
|||
|
|||
} |
|||
.slider-handle{ |
|||
height: 30px; |
|||
width: 30px; |
|||
top: -5px; |
|||
} |
|||
|
|||
legend.scheduler-border { |
|||
width:inherit; /* Or auto */ |
|||
padding:0 10px; /* To give a bit of padding on the left and right */ |
|||
border-bottom:none; |
|||
} |
|||
|
|||
.icon-pos{ |
|||
top: 0.3em; |
|||
position: relative; |
|||
} |
|||
.reboot{ |
|||
color:white; |
|||
} |
|||
.reboot:hover{ |
|||
color: orange; |
|||
} |
|||
|
|||
.fa-sync:hover { |
|||
color: #666666; |
|||
} |
|||
|
|||
.clickForRefresh { |
|||
text-align: center; |
|||
color: gray; |
|||
cursor: pointer; |
|||
margin-top: 5em; |
|||
} |
|||
|
|||
.clickForRefresh:hover { |
|||
color: darkgray; |
|||
} |
|||
|
|||
.filetree-container { |
|||
position: relative; |
|||
} |
|||
|
|||
.indexing-progress { |
|||
width: 100%; |
|||
height: 100%; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
opacity: 0.7; |
|||
display: none; |
|||
} |
|||
|
|||
.refreshAction{ |
|||
text-align: right; |
|||
font-size: 0.8em; |
|||
} |
|||
|
|||
.refreshAction:hover{ |
|||
cursor: pointer; |
|||
color: darkgray; |
|||
} |
|||
|
|||
.overlay { |
|||
z-index: 9; |
|||
opacity: 0.8; |
|||
background: #1a1919; |
|||
height: 200px; |
|||
display: none; |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<nav class="navbar navbar-expand-sm bg-primary navbar-dark"> |
|||
<div class="col-md-12"> |
|||
<a class="float-left navbar-brand"> |
|||
<img src="https://raw.githubusercontent.com/biologist79/Tonuino-ESP32-I2S/master/html/tonuino_logo.png" |
|||
width="30" height="30" class="d-inline-block align-top" alt=""/> |
|||
Tonuino |
|||
</a> |
|||
|
|||
<a class="reboot float-right nav-link" href="/restart"><i class="fas fa-power-off"></i> Neustart</a> |
|||
</div> |
|||
</nav> |
|||
<br/> |
|||
<nav> |
|||
<div class="container nav nav-tabs" id="nav-tab" role="tablist"> |
|||
<a class="nav-item nav-link active" id="nav-rfid-tab" data-toggle="tab" href="#nav-rfid" role="tab" aria-controls="nav-rfid" aria-selected="true"><i class="fas fa-dot-circle"></i> RFID</a> |
|||
<a class="nav-item nav-link" id="nav-wifi-tab" data-toggle="tab" href="#nav-wifi" role="tab" aria-controls="nav-wifi" aria-selected="false"><i class="fas fa-wifi"></i><span class=".d-sm-none .d-md-block"> WiFi</span></a> |
|||
<a class="nav-item nav-link" id="nav-mqtt-tab" data-toggle="tab" href="#nav-mqtt" role="tab" aria-controls="nav-mqtt" aria-selected="false"><i class="fas fa-network-wired"></i> MQTT</a> |
|||
<a class="nav-item nav-link" id="nav-ftp-tab" data-toggle="tab" href="#nav-ftp" role="tab" aria-controls="nav-ftp" aria-selected="false"><i class="fas fa-folder"></i> FTP</a> |
|||
<a class="nav-item nav-link" id="nav-general-tab" data-toggle="tab" href="#nav-general" role="tab" aria-controls="nav-general" aria-selected="false"><i class="fas fa-sliders-h"></i> General</a> |
|||
<a class="nav-item nav-link" id="nav-tools-tab" data-toggle="tab" href="#nav-tools" role="tab" aria-controls="nav-tools" aria-selected="false"><i class="fas fa-wrench"></i> Tools</a> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="tab-content" id="nav-tabContent"> |
|||
<div class="tab-pane fade" id="nav-wifi" role="tabpanel" aria-labelledby="nav-wifi-tab"> |
|||
<div class="container" id="wifiConfig"> |
|||
<form action="#wifiConfig" method="POST" onsubmit="wifiConfig('wifiConfig'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<label for="ssid">Wifi (SSID):</label> |
|||
<input type="text" class="form-control" id="ssid" placeholder="SSID" name="ssid" required> |
|||
<div class="invalid-feedback"> |
|||
Please enter WiFi's SSID. |
|||
</div> |
|||
<label for="pwd">Password:</label> |
|||
<input type="password" class="form-control" id="pwd" placeholder="Passwort" name="pwd" required> |
|||
<label for="hostname">tonuino-name (Hostname):</label> |
|||
<input type="text" class="form-control" id="hostname" placeholder="tonuino" name="hostname" |
|||
value="%HOSTNAME%" pattern="^[^-\.]{2,32}" required> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
<div class="tab-pane fade show active" id="nav-rfid" role="tabpanel" aria-labelledby="nav-rfid-tab"> |
|||
<div class="container" id="rfidMusicTags"> |
|||
<fieldset> |
|||
<legend>RFID-assignments</legend> |
|||
<form action="#rfidMusicTags" method="POST" onsubmit="rfidAssign('rfidMusicTags'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<label for="rfidIdMusic">RFID-tag-ID (12-digits)</label> |
|||
<input type="text" class="form-control" id="rfidIdMusic" maxlength="12" pattern="[0-9]{12}" |
|||
placeholder="%RFID_TAG_ID%" name="rfidIdMusic" required> |
|||
<label for="fileOrUrl">File, directory or URL (^ and # not allowed as characters)</label> |
|||
<input type="text" class="form-control" id="fileOrUrl" maxlength="255" placeholder="z.B. /mp3/Hoerspiele/Yakari/Yakari_und_seine_Freunde.mp3" pattern="^[^\^#]+$" name="fileOrUrl" required> |
|||
<div class="filetree-container"> |
|||
<div id="filebrowser"> |
|||
<div class="filetree demo" id="filetree"></div> |
|||
<div class="refreshAction"> |
|||
<span id="refreshAction" data-toggle="tooltip" data-placement="top" title="Refresh indexfile."><i class="fas fa-sync fa-1x"></i> Refresh indexfile</span> |
|||
</div> |
|||
</div> |
|||
<div id="indexing-progress" class="indexing-progress overlay"> |
|||
<div style="text-align: center; color:white; margin-top:2em;"> |
|||
<div><i class="fas fa-sync fa-spin fa-2x"></i> <br><br> This could take while...</div> |
|||
<div id="currentProcessedFile"></div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<label for="playMode">Playmode</label> |
|||
<select class="form-control" id="playMode" name="playMode"> |
|||
<option class="option-file" value="1">Single track</option> |
|||
<option class="option-file" value="2">Single track (loop)</option> |
|||
<option class="option-file-and-folder" value="3">Audiobook</option> |
|||
<option class="option-file-and-folder" value="4">Audiobook (loop)</option> |
|||
<option class="option-folder" value="5">All tracks of directory (alph. sorted)</option> |
|||
<option class="option-folder" value="6">All tracks of directory (random, loop)</option> |
|||
<option class="option-folder" value="7">All tracks of directory (alph. sorted, loop)</option> |
|||
<option class="option-folder" value="9">All tracks of directory (random)</option> |
|||
<option class="option-stream" value="8">Webstream</option> |
|||
</select> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</div> |
|||
</form> |
|||
</fieldset> |
|||
</div> |
|||
|
|||
<br> |
|||
<br> |
|||
<div class="container" id="rfidModTags"> |
|||
<fieldset> |
|||
<legend>RFID-modifications</legend> |
|||
<form class="needs-validation" action="#rfidModTags" method="POST" onsubmit="rfidMods('rfidModTags'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<label for="rfidIdMod">RFID-tag-ID (12-digits)</label> |
|||
<input type="text" class="form-control" id="rfidIdMod" maxlength="12" pattern="[0-9]{12}" |
|||
placeholder="%RFID_TAG_ID%" name="rfidIdMod" required> |
|||
<div class="invalid-feedback"> |
|||
Please enter 12-digits-number. |
|||
</div> |
|||
<label for="modId">Configuration</label> |
|||
<select class="form-control" id="modId" name="modId"> |
|||
<option value="100">Keylock</option> |
|||
<option value="101">Auto-sleep after 15 minutes</option> |
|||
<option value="102">Auto-sleep after 30 minutes</option> |
|||
<option value="103">Auto-sleep after 1 hour</option> |
|||
<option value="104">Auto-sleep after 2 hours</option> |
|||
<option value="105">Auto-sleep after after end of current track</option> |
|||
<option value="106">Auto-sleep after after end of current playlist</option> |
|||
<option value="107">Auto-sleep after after five tracks</option> |
|||
<option value="110">Loop current playlist</option> |
|||
<option value="111">Loop current track</option> |
|||
<option value="112">Dimm LEDs (nightmode)</option> |
|||
<option value="130">Enable/disable (toggle) WiFi</option> |
|||
</select> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</div> |
|||
</form> |
|||
</fieldset> |
|||
</div> |
|||
</div> |
|||
<div class="tab-pane fade" id="nav-mqtt" role="tabpanel" aria-labelledby="nav-mqtt-tab"> |
|||
<div class="container" id="mqttConfig"> |
|||
|
|||
<form class="needs-validation" action="#mqttConfig" method="POST" |
|||
onsubmit="mqttSettings('mqttConfig'); return false"> |
|||
<div class="form-check col-md-12"> |
|||
<input class="form-check-input" type="checkbox" value="1" id="mqttEnable" name="mqttEnable" %MQTT_ENABLE%> |
|||
<label class="form-check-label" for="mqttEnable"> |
|||
Enable MQTT |
|||
</label> |
|||
</div> |
|||
<div class="form-group my-2 col-md-12"> |
|||
<label for="mqttServer">MQTT-server</label> |
|||
<input type="text" class="form-control" id="mqttServer" minlength="7" maxlength="%MQTT_SERVER_LENGTH%" |
|||
placeholder="z.B. 192.168.2.89" name="mqttServer" value="%MQTT_SERVER%"> |
|||
<label for="mqttUser">MQTT-username (optional):</label> |
|||
<input type="text" class="form-control" id="mqttUser" maxlength="%MQTT_USER_LENGTH%" |
|||
placeholder="Benutzername" name="mqttUser" value="%MQTT_USER%"> |
|||
<label for="mqttPwd">MQTT-password (optional):</label> |
|||
<input type="password" class="form-control" id="mqttPwd" maxlength="%MQTT_PWD_LENGTH%" |
|||
placeholder="Passwort" name="mqttPwd" value="%MQTT_PWD%"> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
<div class="tab-pane fade" id="nav-ftp" role="tabpanel" aria-labelledby="nav-ftp-tab"> |
|||
<div class="container" id="ftpConfig"> |
|||
|
|||
<form action="#ftpConfig" method="POST" onsubmit="ftpSettings('ftpConfig'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<label for="ftpUser">FTP-username:</label> |
|||
<input type="text" class="form-control" id="ftpUser" maxlength="%FTP_USER_LENGTH%" |
|||
placeholder="Benutzername" name="ftpUser" value="%FTP_USER%" required> |
|||
<label for="pwd">FTP-password:</label> |
|||
<input type="password" class="form-control" id="ftpPwd" maxlength="%FTP_PWD_LENGTH%" placeholder="Passwort" |
|||
name="ftpPwd" value="%FTP_PWD%" required> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="tab-pane fade" id="nav-general" role="tabpanel" aria-labelledby="nav-general-tab"> |
|||
<div class="container" id="generalConfig"> |
|||
|
|||
<form action="#generalConfig" method="POST" onsubmit="genSettings('generalConfig'); return false"> |
|||
<div class="form-group col-md-12"> |
|||
<fieldset> |
|||
<legend class="w-auto">Volume</legend> |
|||
<label for="initialVolume">After power on</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-volume-down fa-2x .icon-pos"></i> <input data-provide="slider" type="number" data-slider-min="1" data-slider-max="21" min="1" max="21" class="form-control" id="initialVolume" name="initialVolume" |
|||
data-slider-value="%INIT_VOLUME%" value="%INIT_VOLUME%" required> <i class="fas fa-volume-up fa-2x .icon-pos"></i></div> |
|||
<br> |
|||
<label for="maxVolumeSpeaker">Maximum (speaker)</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-volume-down fa-2x .icon-pos"></i> <input data-provide="slider" type="number" data-slider-min="1" data-slider-max="21" min="1" max="21" class="form-control" id="maxVolumeSpeaker" name="maxVolumeSpeaker" |
|||
data-slider-value="%MAX_VOLUME_SPEAKER%" value="%MAX_VOLUME_SPEAKER%" required> <i class="fas fa-volume-up fa-2x .icon-pos"></i> |
|||
</div> |
|||
<br> |
|||
<label for="maxVolumeHeadphone">Maximum (headphones)</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-volume-down fa-2x .icon-pos"></i> <input data-provide="slider" type="number" data-slider-min="1" data-slider-max="21" min="1" max="21" class="form-control" id="maxVolumeHeadphone" name="maxVolumeHeadphone" |
|||
data-slider-value="%MAX_VOLUME_HEADPHONE%" value="%MAX_VOLUME_HEADPHONE%" required> <i class="fas fa-volume-up fa-2x .icon-pos"></i> |
|||
</div> |
|||
</fieldset> |
|||
</div> |
|||
<br> |
|||
<div class="form-group col-md-12"> |
|||
<fieldset > |
|||
<legend class="w-auto">Neopixel (brightness)</legend> |
|||
<label for="initBrightness">After power on:</label> |
|||
<div class="text-center"> |
|||
<i class="far fa-sun fa-2x .icon-pos"></i> |
|||
<input data-provide="slider" type="number" data-slider-min="0" data-slider-max="255" min="0" max="255" class="form-control" id="initBrightness" name="initBrightness" |
|||
data-slider-value="%INIT_LED_BRIGHTNESS%" value="%INIT_LED_BRIGHTNESS%" required><i class="fas fa-sun fa-2x .icon-pos"></i> |
|||
</div> |
|||
|
|||
<label for="nightBrightness">In nightmode</label> |
|||
<div class="text-center"> |
|||
<i class="far fa-sun fa-2x .icon-pos"></i><input data-provide="slider" type="number" data-slider-min="0" data-slider-max="255" min="0" max="255" class="form-control" id="nightBrightness" name="nightBrightness" data-slider-value="%NIGHT_LED_BRIGHTNESS%" value="%NIGHT_LED_BRIGHTNESS%" required><i class="fas fa-sun fa-2x .icon-pos"></i> |
|||
</div> |
|||
</fieldset> |
|||
</div> |
|||
<br> |
|||
<div class="form-group col-md-12"> |
|||
<fieldset> |
|||
<legend>Deep Sleep</legend> |
|||
|
|||
<label for="inactivityTime">Inactivity (minutes)</label> |
|||
<div class="text-center"><i class="fas fa-hourglass-start fa-2x .icon-pos"></i> <input type="number" data-provide="slider" data-slider-min="0" data-slider-max="30" min="1" max="120" class="form-control" id="inactivityTime" name="inactivityTime" |
|||
data-slider-value="%MAX_INACTIVITY%" value="%MAX_INACTIVITY%" required><i class="fas fa-hourglass-end fa-2x .icon-pos"></i></div> |
|||
</fieldset> |
|||
</div> |
|||
<br> |
|||
|
|||
<div class="form-group col-md-12"> |
|||
<fieldset> |
|||
<legend>Battery</legend> |
|||
<div>Status via Neopixel</div> |
|||
<br> |
|||
<label for="warningLowVoltage">LED-warning will appear below this voltage. |
|||
</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-battery-quarter fa-2x .icon-pos"></i> <input data-provide="slider" data-slider-step="0.1" data-slider-min="3.0" data-slider-max="5.0" min="3.0" max="5.0" type="text" class="form-control" id="warningLowVoltage" name="warningLowVoltage" |
|||
data-slider-value="%WARNING_LOW_VOLTAGE%" value="%WARNING_LOW_VOLTAGE%" pattern="^\d{1,2}(\.\d{1,3})?" required> <i class="fas fa-battery-three-quarters fa-2x .icon-pos" fa-2x .icon-pos></i> |
|||
</div> |
|||
<br> |
|||
<label for="voltageIndicatorLow">One LED lights at this voltage |
|||
</label> |
|||
<div class="text-center"> |
|||
<i class="fas fa-battery-quarter fa-2x .icon-pos"></i> <input data-provide="slider" min="2.0" data-slider-step="0.1" data-slider-min="2.0" data-slider-max="5.0" max="5.0"type="text" class="form-control" id="voltageIndicatorLow" name="voltageIndicatorLow" |
|||
data-slider-value="%VOLTAGE_INDICATOR_LOW%" value="%VOLTAGE_INDICATOR_LOW%" pattern="^\d{1,2}(\.\d{1,3})?" required> <i class="fas fa-battery-three-quarters fa-2x .icon-pos" fa-2x .icon-pos></i> |
|||
</div> |
|||
<br> |
|||
<label for="voltageIndicatorHigh">All LEDs light at this voltage</label> |
|||
|
|||
<div class="text-center"> |
|||
<i class="fas fa-battery-quarter fa-2x .icon-pos"></i><input data-provide="slider" data-slider-step="0.1" data-slider-min="2.0" data-slider-max="5.0" min="2.0" max="5.0" type="text" class="form-control" id="voltageIndicatorHigh" name="voltageIndicatorHigh" |
|||
data-slider-value="%VOLTAGE_INDICATOR_HIGH%" value="%VOLTAGE_INDICATOR_HIGH%" pattern="^\d{1,2}(\.\d{1,3})?" required> <i class="fas fa-battery-three-quarters fa-2x .icon-pos" fa-2x .icon-pos></i> |
|||
</div> |
|||
|
|||
<br> |
|||
<label for="voltageCheckInterval">Interval of measurement (minutes)</label> |
|||
<div class="text-center"><i class="fas fa-hourglass-start fa-2x .icon-pos"></i> |
|||
<input data-provide="slider" data-slider-min="1" data-slider-max="60" type="number" min="1" max="60" class="form-control" id="voltageCheckInterval" |
|||
data-slider-value="%VOLTAGE_CHECK_INTERVAL%" name="voltageCheckInterval" value="%VOLTAGE_CHECK_INTERVAL%" required><i class="fas fa-hourglass-end fa-2x .icon-pos"></i> |
|||
</div> |
|||
|
|||
</fieldset> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
<div class="tab-pane fade" id="nav-tools" role="tabpanel" aria-labelledby="nav-tools-tab"> |
|||
<div class="container my-5" id="importNvs"> |
|||
<h2>NVS-Importer</h2> |
|||
<form action="/upload" enctype="multipart/form-data" method="POST"> |
|||
<div class="form-group"> |
|||
<label for="nvsUpload">Select backup-file for import.</label> |
|||
<input type="file" class="form-control-file" id="nvsUpload" name="nvsUpload" accept=".txt"> |
|||
</div> |
|||
<br> |
|||
<div class="text-center"> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<script type="text/javascript"> |
|||
var DEBUG = false; |
|||
var lastIdclicked = ''; |
|||
var host = $(location).attr('hostname'); |
|||
|
|||
if (DEBUG) { |
|||
host = "192.168.178.114"; |
|||
} |
|||
|
|||
toastr.options = { |
|||
"closeButton": false, |
|||
"debug": false, |
|||
"newestOnTop": false, |
|||
"progressBar": false, |
|||
"positionClass": "toast-top-right", |
|||
"preventDuplicates": false, |
|||
"onclick": null, |
|||
"showDuration": "300", |
|||
"hideDuration": "1000", |
|||
"timeOut": "5000", |
|||
"extendedTimeOut": "1000", |
|||
"showEasing": "swing", |
|||
"hideEasing": "linear", |
|||
"showMethod": "fadeIn", |
|||
"hideMethod": "fadeOut" |
|||
}; |
|||
|
|||
function postRendering(event, data) { |
|||
Object.keys(data.instance._model.data).forEach(function (key, index) { |
|||
|
|||
var cur = data.instance.get_node(data.instance._model.data[key]); |
|||
var lastFolder = cur['id'].split('/').filter(function (el) { |
|||
return el.trim().length > 0; |
|||
}).pop(); |
|||
if ((/\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|flac|FLAC)$/i).test(lastFolder)) { |
|||
data.instance.set_type(data.instance._model.data[key], 'audio'); |
|||
} else { |
|||
if (data.instance._model.data[key]['type'] == "file") { |
|||
data.instance.disable_node(data.instance._model.data[key]); |
|||
} |
|||
} |
|||
data.instance.rename_node(data.instance._model.data[key], lastFolder); |
|||
}); |
|||
} |
|||
|
|||
function renderFileTree() { |
|||
|
|||
var filesURI = "/files"; |
|||
if (DEBUG) { |
|||
filesURI = "http://" + host + "/files"; |
|||
} |
|||
$('#filetree').jstree({ |
|||
'core': { |
|||
'check_callback': true, |
|||
'data': { |
|||
url: filesURI, |
|||
error: function (XMLHttpRequest, textStatus, errorThrown) { |
|||
$('#j1_loading').hide(); |
|||
$("#refreshAction").hide(); |
|||
$('#filetree').html("<div class='clickForRefresh' ><i class='fas fa-sync fa-1x'><span id='#clickForRefresh' > Refresh fileindex.</span></div>"); |
|||
$('#filetree').on("click", function () { |
|||
refreshFileList(); |
|||
}); |
|||
toastr.error("Unable to fetch directory-list."); |
|||
} |
|||
}, |
|||
|
|||
}, |
|||
'types': { |
|||
'folder': { |
|||
'icon': "fa fa-folder" |
|||
}, |
|||
'file': { |
|||
'icon': "fa fa-file" |
|||
}, |
|||
'audio': { |
|||
'icon': "fa fa-file-audio" |
|||
}, |
|||
'default': { |
|||
'icon': "fa fa-folder" |
|||
} |
|||
}, |
|||
'plugins': ["themes", "types"] |
|||
}).bind('loaded.jstree', function (event, data) { |
|||
postRendering(event, data); |
|||
if ((data.instance._model.data['#']['children'].length == 0)) { |
|||
toastr.info("SD-card-index needs to be refreshed."); |
|||
} |
|||
}).bind('refresh.jstree', function (event, data) { |
|||
postRendering(event, data); |
|||
}); |
|||
} |
|||
|
|||
$('#filetree').on('select_node.jstree', function (e, data) { |
|||
$('input[name=fileOrUrl]').val(data.node.id); |
|||
|
|||
if (data.node.type == "folder") { |
|||
$('.option-folder').show(); |
|||
$('.option-file').hide(); |
|||
$('#playMode option').removeAttr('selected').filter('[value=3]').attr('selected', true); |
|||
} |
|||
|
|||
if (data.node.type == "audio") { |
|||
$('.option-file').show(); |
|||
$('.option-folder').hide(); |
|||
$('#playMode option').removeAttr('selected').filter('[value=1]').attr('selected', true); |
|||
} |
|||
}); |
|||
|
|||
$('#refreshAction').on("click", function () { |
|||
refreshFileList(); |
|||
$("#indexing-progress").show(); |
|||
$("#refreshAction").hide(); |
|||
}); |
|||
|
|||
$('#playMode').on("change", function () { |
|||
if (this.value == 8) { |
|||
$('#filebrowser').slideUp(); |
|||
} else { |
|||
$('#filebrowser').slideDown(); |
|||
} |
|||
}); |
|||
|
|||
function showFileIndexingState() { |
|||
$("#indexing-progress").show(); |
|||
$("#refreshAction").hide(); |
|||
} |
|||
|
|||
function hideFileIndexingState() { |
|||
$("#indexing-progress").hide(); |
|||
$("#refreshAction").show(); |
|||
} |
|||
|
|||
var socket = undefined; |
|||
var tm; |
|||
|
|||
function connect() { |
|||
socket = new WebSocket("ws://" + host + "/ws"); |
|||
|
|||
socket.onopen = function () { |
|||
setInterval(ping, 15000); |
|||
}; |
|||
|
|||
socket.onclose = function (e) { |
|||
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason); |
|||
socket = null; |
|||
setTimeout(function () { |
|||
connect(); |
|||
}, 5000); |
|||
}; |
|||
|
|||
socket.onerror = function (err) { |
|||
console.error('Socket encountered error: ', err.message, 'Closing socket'); |
|||
}; |
|||
|
|||
socket.onmessage = function(event) { |
|||
console.log(event.data); |
|||
var socketMsg = JSON.parse(event.data); |
|||
if (socketMsg.rfidId != null) { |
|||
document.getElementById('rfidIdMod').value = socketMsg.rfidId; |
|||
document.getElementById('rfidIdMusic').value = socketMsg.rfidId; |
|||
toastr.info("RFID Tag mit "+ socketMsg.rfidId + " erkannt." ); |
|||
|
|||
$("#rfidIdMusic").effect("highlight", {color:"#abf5af"}, 3000); |
|||
$("#rfidIdMod").effect("highlight", {color:"#abf5af"}, 3000); |
|||
|
|||
} if ("status" in socketMsg) { |
|||
if (socketMsg.status == "ok") { |
|||
toastr.success("Action completed successfully." ); |
|||
} |
|||
} if ("pong" in socketMsg) { |
|||
if (socketMsg.pong == 'pong') { |
|||
pong(); |
|||
} |
|||
} if ("refreshFileList" in socketMsg) { |
|||
hideFileIndexingState(); |
|||
toastr.info("SD-card-index has been refreshed!"); |
|||
$('#filetree').jstree(true).refresh(); |
|||
|
|||
} |
|||
if ("indexingState" in socketMsg) { |
|||
if(socketMsg.indexingState != null) { |
|||
$("#currentProcessedFile").text(socketMsg.indexingState); |
|||
console.log(socketMsg.indexingState); |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
|
|||
function ping() { |
|||
var myObj = { |
|||
"ping": { |
|||
ping: 'ping' |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
tm = setTimeout(function () { |
|||
toastr.warning('Connection to Tonuino is broken. Please refresh.'); |
|||
}, 5000); |
|||
} |
|||
|
|||
function pong() { |
|||
clearTimeout(tm); |
|||
} |
|||
|
|||
function refreshFileList(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"refreshFileList": true |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
$("#refreshAction").hide(); |
|||
socket.send(myJSON); |
|||
showFileIndexingState(); |
|||
}; |
|||
|
|||
function genSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"general": { |
|||
iVol: document.getElementById('initialVolume').value, |
|||
mVolSpeaker: document.getElementById('maxVolumeSpeaker').value, |
|||
mVolHeadphone: document.getElementById('maxVolumeHeadphone').value, |
|||
iBright: document.getElementById('initBrightness').value, |
|||
nBright: document.getElementById('nightBrightness').value, |
|||
iTime: document.getElementById('inactivityTime').value, |
|||
vWarning: document.getElementById('warningLowVoltage').value, |
|||
vIndLow: document.getElementById('voltageIndicatorLow').value, |
|||
vIndHi: document.getElementById('voltageIndicatorHigh').value, |
|||
vInt: document.getElementById('voltageCheckInterval').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function ftpSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"ftp": { |
|||
ftpUser: document.getElementById('ftpUser').value, |
|||
ftpPwd: document.getElementById('ftpPwd').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function mqttSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var val; |
|||
if (document.getElementById('mqttEnable').checked) { |
|||
val = document.getElementById('mqttEnable').value; |
|||
} else { |
|||
val = 0; |
|||
} |
|||
var myObj = { |
|||
"mqtt": { |
|||
mqttEnable: val, |
|||
mqttServer: document.getElementById('mqttServer').value, |
|||
mqttUser: document.getElementById('mqttUser').value, |
|||
mqttPwd: document.getElementById('mqttPwd').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function rfidMods(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"rfidMod": { |
|||
rfidIdMod: document.getElementById('rfidIdMod').value, |
|||
modId: document.getElementById('modId').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function removeTrSlash(str) { |
|||
if (str.substr(-1) === '/') { |
|||
return str.substr(0, str.length - 1); |
|||
} |
|||
return str; |
|||
} |
|||
|
|||
function rfidAssign(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"rfidAssign": { |
|||
rfidIdMusic: document.getElementById('rfidIdMusic').value, |
|||
fileOrUrl: removeTrSlash(document.getElementById('fileOrUrl').value), |
|||
playMode: document.getElementById('playMode').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function wifiConfig(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"wifiConfig": { |
|||
ssid: document.getElementById('ssid').value, |
|||
pwd: document.getElementById('pwd').value, |
|||
hostname: document.getElementById('hostname').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
$(document).ready(function () { |
|||
connect(); |
|||
renderFileTree(); |
|||
|
|||
console.log(parseInt(document.getElementById('warningLowVoltage').value)); |
|||
$(function () { |
|||
$('[data-toggle="tooltip"]').tooltip(); |
|||
}); |
|||
|
|||
}); |
|||
</script> |
|||
</body> |
|||
</html> |
@ -1,359 +0,0 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="de"> |
|||
<head> |
|||
<title>ESPuino-Konfiguration</title> |
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
<link rel="stylesheet" href="https://ts-cs.de/tonuino/css/bootstrap.min.css"> |
|||
<script src="https://ts-cs.de/tonuino/js/jquery.min.js"></script> |
|||
<script src="https://ts-cs.de/tonuino/js/popper.min.js"></script> |
|||
<script src="https://ts-cs.de/tonuino/js/bootstrap.min.js"></script> |
|||
</head> |
|||
<body> |
|||
<nav class="navbar navbar-expand-sm bg-primary navbar-dark"> |
|||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> |
|||
<span class="navbar-toggler-icon"></span> |
|||
</button> |
|||
<a class="navbar-brand"> |
|||
<img src="https://raw.githubusercontent.com/biologist79/Tonuino-ESP32-I2S/master/html/tonuino_logo.png" width="30" height="30" class="d-inline-block align-top" alt="" /> |
|||
Tonuino |
|||
</a> |
|||
<div class="collapse navbar-collapse" id="collapsibleNavbar"> |
|||
<ul class="navbar-nav mr-auto"> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#wifiConfig">WLAN</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#rfidMusicTags">RFID-Zuweisungen</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#rfidModTags">RFID-Modifikationen</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#mqttConfig">MQTT</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#ftpConfig">FTP</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#generalConfig">Allgemein</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#importNvs">NVS-Importer</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="/restart" style="color: orange">Neustart Tonuino</a> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
</nav> |
|||
<br /> |
|||
<div class="container" id="wifiConfig"> |
|||
<h2>WLAN-Konfiguration</h2> |
|||
<form action="#wifiConfig" method="POST" onsubmit="wifiConfig('wifiConfig'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="ssid">WLAN-Name (SSID):</label> |
|||
<input type="text" class="form-control" id="ssid" placeholder="SSID" name="ssid" required> |
|||
<div class="invalid-feedback"> |
|||
Bitte SSID des WLANs eintragen. |
|||
</div> |
|||
<label for="pwd">Passwort:</label> |
|||
<input type="password" class="form-control" id="pwd" placeholder="Passwort" name="pwd" required> |
|||
<label for="hostname">Tonuino-Name (Hostname):</label> |
|||
<input type="text" class="form-control" id="hostname" placeholder="tonuino" name="hostname" value="%HOSTNAME%" pattern="^[^-\.]{2,32}" required> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="rfidMusicTags"> |
|||
<h2>RFID-Zuweisungen</h2> |
|||
<form action="#rfidMusicTags" method="POST" onsubmit="rfidAssign('rfidMusicTags'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="rfidIdMusic">RFID-Chip-Nummer (12-stellig)</label> |
|||
<input type="text" class="form-control" id="rfidIdMusic" maxlength="12" pattern="[0-9]{12}" placeholder="%RFID_TAG_ID%" name="rfidIdMusic" required> |
|||
<label for="fileOrUrl">Datei, Verzeichnis oder URL (^ und # als Zeichen nicht erlaubt)</label> |
|||
<input type="text" class="form-control" id="fileOrUrl" maxlength="255" placeholder="z.B. /mp3/Hoerspiele/Yakari/Yakari_und_seine_Freunde.mp3" pattern="^[^\^#]+$" name="fileOrUrl" required> |
|||
<label for="playMode">Abspielmodus</label> |
|||
<select class="form-control" id="playMode" name="playMode"> |
|||
<option value="1">Einzelner Titel</option> |
|||
<option value="2">Einzelner Titel (Endlosschleife)</option> |
|||
<option value="3">Hörbuch</option> |
|||
<option value="4">Hörbuch (Endlosschleife)</option> |
|||
<option value="5">Alle Titel eines Verzeichnis (sortiert)</option> |
|||
<option value="6">Alle Titel eines Verzeichnis (zufällig)</option> |
|||
<option value="7">Alle Titel eines Verzeichnis (sortiert, Endlosschleife)</option> |
|||
<option value="9">Alle Titel eines Verzeichnis (zufällig, Endlosschleife)</option> |
|||
<option value="8">Webradio</option> |
|||
</select> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="rfidModTags"> |
|||
<h2>RFID-Modifkationen</h2> |
|||
<form class="needs-validation" action="#rfidModTags" method="POST" onsubmit="rfidMods('rfidModTags'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="rfidIdMod">RFID-Chip-Nummer (12-stellig)</label> |
|||
<input type="text" class="form-control" id="rfidIdMod" maxlength="12" pattern="[0-9]{12}" placeholder="%RFID_TAG_ID%" name="rfidIdMod" required> |
|||
<div class="invalid-feedback"> |
|||
Bitte eine 12-stellige Zahl eingeben. |
|||
</div> |
|||
<label for="modId">Abspielmodus</label> |
|||
<select class="form-control" id="modId" name="modId"> |
|||
<option value="100">Tastensperre</option> |
|||
<option value="101">Schlafen nach 15 Minuten</option> |
|||
<option value="102">Schlafen nach 30 Minuten</option> |
|||
<option value="103">Schlafen nach 1 Stunde</option> |
|||
<option value="104">Schlafen nach 2 Stunden</option> |
|||
<option value="105">Schlafen nach Ende des Titels</option> |
|||
<option value="106">Schlafen nach Ende der Playlist</option> |
|||
<option value="107">Schlafen nach fünf Titeln</option> |
|||
<option value="110">Wiederhole Playlist (endlos)</option> |
|||
<option value="111">Wiederhole Titel (endlos)</option> |
|||
<option value="112">Dimme LEDs (Nachtmodus)</option> |
|||
<option value="130">Aktiviere/deaktive WLAN</option> |
|||
</select> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="mqttConfig"> |
|||
<h2>MQTT-Konfiguration</h2> |
|||
<form class="needs-validation" action="#mqttConfig" method="POST" onsubmit="mqttSettings('mqttConfig'); return false"> |
|||
<div class="form-check col-md-6"> |
|||
<input class="form-check-input" type="checkbox" value="1" id="mqttEnable" name="mqttEnable" %MQTT_ENABLE%> |
|||
<label class="form-check-label" for="mqttEnable"> |
|||
MQTT aktivieren |
|||
</label> |
|||
</div> |
|||
<div class="form-group my-2 col-md-6"> |
|||
<label for="mqttServer">MQTT-Server</label> |
|||
<input type="text" class="form-control" id="mqttServer" minlength="7" maxlength="%MQTT_SERVER_LENGTH%" placeholder="z.B. 192.168.2.89" name="mqttServer" value="%MQTT_SERVER%"> |
|||
<label for="mqttUser">MQTT-Benutzername (optional):</label> |
|||
<input type="text" class="form-control" id="mqttUser" maxlength="%MQTT_USER_LENGTH%" placeholder="Benutzername" name="mqttUser" value="%MQTT_USER%"> |
|||
<label for="mqttPwd">Passwort (optional):</label> |
|||
<input type="password" class="form-control" id="mqttPwd" maxlength="%MQTT_PWD_LENGTH%" placeholder="Passwort" name="mqttPwd" value="%MQTT_PWD%"> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container" id="ftpConfig"> |
|||
<h2>FTP-Konfiguration</h2> |
|||
<form action="#ftpConfig" method="POST" onsubmit="ftpSettings('ftpConfig'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="ftpUser">FTP-Benutzername:</label> |
|||
<input type="text" class="form-control" id="ftpUser" maxlength="%FTP_USER_LENGTH%" placeholder="Benutzername" name="ftpUser" value="%FTP_USER%" required> |
|||
<label for="pwd">Passwort:</label> |
|||
<input type="password" class="form-control" id="ftpPwd" maxlength="%FTP_PWD_LENGTH%" placeholder="Passwort" name="ftpPwd" value="%FTP_PWD%" required> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="generalConfig"> |
|||
<h2>Allgemeine Konfiguration</h2> |
|||
<form action="#generalConfig" method="POST" onsubmit="genSettings('generalConfig'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="initialVolume">Lautstärke nach dem Einschalten</label> |
|||
<input type="number" min="1" max="21" class="form-control" id="initialVolume" name="initialVolume" value="%INIT_VOLUME%" required> |
|||
<label for="maxVolumeSpeaker">Maximale Lautstärke (Lautsprecher)</label> |
|||
<input type="number" min="1" max="21" class="form-control" id="maxVolumeSpeaker" name="maxVolumeSpeaker" value="%MAX_VOLUME_SPEAKER%" required> |
|||
<label for="maxVolumeHeadphone">Maximale Lautstärke (Kopfhörer)</label> |
|||
<input type="number" min="1" max="21" class="form-control" id="maxVolumeHeadphone" name="maxVolumeHeadphone" value="%MAX_VOLUME_HEADPHONE%" required> |
|||
</div> |
|||
<div class="form-group col-md-6"> |
|||
<label for="initBrightness">Neopixel-Helligkeit nach dem Einschalten</label> |
|||
<input type="number" min="0" max="255" class="form-control" id="initBrightness" name="initBrightness" value="%INIT_LED_BRIGHTNESS%" required> |
|||
<label for="nightBrightness">Neopixel-Helligkeit im Nachtmodus</label> |
|||
<input type="number" min="0" max="255" class="form-control" id="nightBrightness" name="nightBrightness" value="%NIGHT_LED_BRIGHTNESS%" required> |
|||
</div> |
|||
<div class="form-group col-md-6"> |
|||
<label for="inactivityTime">Deep-Sleep nach Inaktivität (Minuten)</label> |
|||
<input type="number" min="1" max="1440" class="form-control" id="inactivityTime" name="inactivityTime" value="%MAX_INACTIVITY%" required> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="importNvs"> |
|||
<h2>NVS-Importer</h2> |
|||
<form action="/upload" enctype="multipart/form-data" method="POST"> |
|||
<div class="form-group"> |
|||
<label for="nvsUpload">Hier kann eine Backup-Datei importiert werden.</label> |
|||
<input type="file" class="form-control-file" id="nvsUpload" name="nvsUpload" accept=".txt"> |
|||
</div> |
|||
<button type="submit" class="btn btn-primary">Absenden</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<script> |
|||
var lastIdclicked = ''; |
|||
var errorBox = '<div class="alert alert-danger alert-dismissible fade show" role="alert">Es ist ein Fehler aufgetreten!<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button></div>'; |
|||
var okBox = '<div class="alert alert-success alert-dismissible fade show" role="alert">Aktion erfolgreich ausgeführt.<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button></div>'; |
|||
|
|||
var socket = new WebSocket("ws://%IPv4%/ws"); |
|||
|
|||
function connect() { |
|||
socket = new WebSocket("ws://%IPv4%/ws"); |
|||
} |
|||
|
|||
function ping() { |
|||
var myObj = { |
|||
"ping": { |
|||
ping: 'ping' |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
tm = setTimeout(function () { |
|||
alert("Die Verbindung zum Tonuino ist unterbrochen!\\nBitte Seite neu laden."); |
|||
}, 5000); |
|||
} |
|||
|
|||
function pong() { |
|||
clearTimeout(tm); |
|||
} |
|||
|
|||
socket.onopen = function () { |
|||
setInterval(ping, 15000); |
|||
}; |
|||
|
|||
socket.onclose = function(e) { |
|||
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason); |
|||
setTimeout(function() { |
|||
connect(); |
|||
}, 5000); |
|||
}; |
|||
|
|||
socket.onerror = function(err) { |
|||
console.error('Socket encountered error: ', err.message, 'Closing socket'); |
|||
socket.close(); |
|||
}; |
|||
|
|||
socket.onmessage = function(event) { |
|||
console.log(event.data); |
|||
var socketMsg = JSON.parse(event.data); |
|||
if (socketMsg.rfidId != null) { |
|||
document.getElementById('rfidIdMod').value = socketMsg.rfidId; |
|||
document.getElementById('rfidIdMusic').value = socketMsg.rfidId; |
|||
$("#rfidIdMusic").fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500); |
|||
$("#rfidIdMod").fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500); |
|||
|
|||
} if (socketMsg.status != null) { |
|||
if (socketMsg.status == 'ok') { |
|||
$("#" + lastIdclicked).find('.messages').html(okBox); |
|||
} else { |
|||
$("#" + lastIdclicked).find('.messages').html(errorBox); |
|||
} |
|||
} if (socketMsg.pong != null) { |
|||
if (socketMsg.pong == 'pong') { |
|||
pong(); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
function genSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"general": { |
|||
iVol: document.getElementById('initialVolume').value, |
|||
mVolSpeaker: document.getElementById('maxVolumeSpeaker').value, |
|||
mVolHeadphone: document.getElementById('maxVolumeHeadphone').value, |
|||
iBright: document.getElementById('initBrightness').value, |
|||
nBright: document.getElementById('nightBrightness').value, |
|||
iTime: document.getElementById('inactivityTime').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function ftpSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"ftp": { |
|||
ftpUser: document.getElementById('ftpUser').value, |
|||
ftpPwd: document.getElementById('ftpPwd').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function mqttSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var val; |
|||
if (document.getElementById('mqttEnable').checked) { |
|||
val = document.getElementById('mqttEnable').value; |
|||
} else { |
|||
val = 0; |
|||
} |
|||
var myObj = { |
|||
"mqtt": { |
|||
mqttEnable: val, |
|||
mqttServer: document.getElementById('mqttServer').value, |
|||
mqttUser: document.getElementById('mqttUser').value, |
|||
mqttPwd: document.getElementById('mqttPwd').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function rfidMods(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"rfidMod": { |
|||
rfidIdMod: document.getElementById('rfidIdMod').value, |
|||
modId: document.getElementById('modId').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function removeTrSlash(str) { |
|||
if(str.substr(-1) === '/') { |
|||
return str.substr(0, str.length - 1); |
|||
} |
|||
return str; |
|||
} |
|||
|
|||
function rfidAssign(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"rfidAssign": { |
|||
rfidIdMusic: document.getElementById('rfidIdMusic').value, |
|||
fileOrUrl: removeTrSlash(document.getElementById('fileOrUrl').value), |
|||
playMode: document.getElementById('playMode').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function wifiConfig(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"wifiConfig": { |
|||
ssid: document.getElementById('ssid').value, |
|||
pwd: document.getElementById('pwd').value, |
|||
hostname: document.getElementById('hostname').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
</script> |
|||
</body> |
|||
</html> |
@ -1,23 +0,0 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<title>WLAN-Einrichtung</title> |
|||
</head> |
|||
<body> |
|||
<form action="/init" method="POST"> |
|||
<fieldset> |
|||
<legend>Initiale WLAN-Einrichtung</legend> |
|||
<label for="ssid">SSID:</label><br> |
|||
<input type="text" id="ssid" name="ssid" placeholder="SSID" required><br> |
|||
<label for="pwd">Passwort:</label><br> |
|||
<input type="password" id="pwd" name="pwd" autocomplete="off" required><br> |
|||
<label for="hostname">Tonuino-Name (Hostname):</label><br> |
|||
<input type="text" id="hostname" name="hostname" required><br><br> |
|||
<input type="submit" value="Absenden"> |
|||
</fieldset> |
|||
</form> |
|||
<form action="/restart"> |
|||
<button type="submit">Neustart</button> |
|||
</form> |
|||
</body> |
|||
</html> |
@ -1,23 +0,0 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<title>Wifi-configuration</title> |
|||
</head> |
|||
<body> |
|||
<form action="/init" method="POST"> |
|||
<fieldset> |
|||
<legend>Basic wifi-setup</legend> |
|||
<label for="ssid">SSID:</label><br> |
|||
<input type="text" id="ssid" name="ssid" placeholder="SSID" required><br> |
|||
<label for="pwd">Password:</label><br> |
|||
<input type="password" id="pwd" name="pwd" autocomplete="off" required><br> |
|||
<label for="hostname">Tonuino-name (hostname):</label><br> |
|||
<input type="text" id="hostname" name="hostname" required><br><br> |
|||
<input type="submit" value="Submit"> |
|||
</fieldset> |
|||
</form> |
|||
<form action="/restart"> |
|||
<button type="submit">Reboot</button> |
|||
</form> |
|||
</body> |
|||
</html> |
@ -1,263 +0,0 @@ |
|||
static const char mgtWebsite[] PROGMEM = "<!DOCTYPE html>\ |
|||
<html lang=\"de\">\ |
|||
<head>\ |
|||
<title>ESPuino-Konfiguration</title>\ |
|||
<meta charset=\"utf-8\">\ |
|||
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\ |
|||
<link rel=\"stylesheet\" href=\"https://ts-cs.de/css/bootstrap.min.css\">\ |
|||
<script src=\"https://ts-cs.de/js/jquery.min.js\"></script>\ |
|||
<script src=\"https://ts-cs.de/js/popper.min.js\"></script>\ |
|||
<script src=\"https://ts-cs.de/js/bootstrap.min.js\"></script>\ |
|||
</head>\ |
|||
<body>\ |
|||
<nav class=\"navbar navbar-expand-sm bg-primary navbar-dark\">\ |
|||
<button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#navbarSupportedContent\" aria-controls=\"navbarSupportedContent\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\ |
|||
<span class=\"navbar-toggler-icon\"></span>\ |
|||
</button>\ |
|||
<a class=\"navbar-brand\">\ |
|||
<img src=\"./tonuino_logo.png\" width=\"30\" height=\"30\" class=\"d-inline-block align-top\" alt=\"\" />\ |
|||
Tonuino\ |
|||
</a>\ |
|||
<div class=\"collapse navbar-collapse\" id=\"collapsibleNavbar\">\ |
|||
<ul class=\"navbar-nav mr-auto\">\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#wifiConfig\">WLAN</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#rfidMusicTags\">RFID-Zuweisungen</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#rfidModTags\">RFID-Modifikationen</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#mqttConfig\">MQTT</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#ftpConfig\">FTP</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#generalConfig\">Allgemein</a>\ |
|||
</li>\ |
|||
</ul>\ |
|||
</div>\ |
|||
</nav>\ |
|||
<br />\ |
|||
<div class=\"container\" id=\"wifiConfig\">\ |
|||
<h2>WLAN-Konfiguration</h2>\ |
|||
<form action=\"#wifiConfig\" method=\"GET\">\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"SSID\">WLAN-Name (SSID):</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"SSID\" placeholder=\"SSID\" name=\"SSID\" required>\ |
|||
<div class=\"invalid-feedback\">\ |
|||
Bitte SSID des WLANs eintragen.\ |
|||
</div>\ |
|||
<label for=\"pwd\">Passwort:</label>\ |
|||
<input type=\"password\" class=\"form-control\" id=\"pwd\" placeholder=\"Passwort\" name=\"pwd\" required>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\" onclick=\"wifiConfig()\">Absenden</button>\ |
|||
</form>\ |
|||
</div>\ |
|||
<div class=\"container my-5\" id=\"rfidMusicTags\">\ |
|||
<h2>RFID-Zuweisungen</h2>\ |
|||
<form action=\"#rfidMusicTags\" method=\"GET\">\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"rfidIdMusic\">RFID-Chip-Nummer</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"rfidIdMusic\" maxlength=\"12\" pattern=\"[0-9]{12}\" placeholder=\"012345678912\" name=\"rfidIdMusic\" required>\ |
|||
<label for=\"fileOrUrl\">Datei, Verzeichnis oder URL (URL nur für Webradio)</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"fileOrUrl\" maxlength=\"255\" placeholder=\"z.B. /mp3/Hoerspiele/Yakari/Yakari_und_seine_Freunde.mp3\" name=\"fileOrUrl\" required>\ |
|||
<label for=\"playMode\">Abspielmodus</label>\ |
|||
<select class=\"form-control\" id=\"playMode\" name=\"playMode\">\ |
|||
<option value=\"1\">Einzelner Titel</option>\ |
|||
<option value=\"2\">Einzelner Titel (Endlosschleife)</option>\ |
|||
<option value=\"3\">Hörbuch</option>\ |
|||
<option value=\"4\">Hörbuch (Endlosschleife)</option>\ |
|||
<option value=\"5\">Alle Titel eines Verzeichnis (sortiert)</option>\ |
|||
<option value=\"6\">Alle Titel eines Verzeichnis (zufällig)</option>\ |
|||
<option value=\"7\">Alle Titel eines Verzeichnis (sortiert, Endlosschleife)</option>\ |
|||
<option value=\"8\">Alle Titel eines Verzeichnis (zufällig, Endlosschleife)</option>\ |
|||
<option value=\"9\">Webradio</option>\ |
|||
</select>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\" onclick=\"rfidAssign()\">Absenden</button>\ |
|||
</form>\ |
|||
</div>\ |
|||
<div class=\"container my-5\" id=\"rfidModTags\">\ |
|||
<h2>RFID-Modifkationen</h2>\ |
|||
<form class=\"needs-validation\" action=\"#rfidModTags\" method=\"GET\" novalidate>\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"rfidIdMod\">RFID-Chip-Nummer</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"rfidIdMod\" maxlength=\"12\" pattern=\"[0-9]{12}\" placeholder=\"012345678912\" name=\"rfidIdMod\" required>\ |
|||
<div class=\"invalid-feedback\">\ |
|||
Bitte eine 12-stellige Zahl eingeben.\ |
|||
</div>\ |
|||
<label for=\"modId\">Abspielmodus</label>\ |
|||
<select class=\"form-control\" id=\"modId\" name=\"modId\">\ |
|||
<option value=\"100\">Tastensperre</option>\ |
|||
<option value=\"101\">Schlafen nach 15 Minuten</option>\ |
|||
<option value=\"102\">Schlafen nach 30 Minuten</option>\ |
|||
<option value=\"103\">Schlafen nach 1 Stunde</option>\ |
|||
<option value=\"104\">Schlafen nach 2 Stunden</option>\ |
|||
<option value=\"105\">Schlafen nach Ende des Titels</option>\ |
|||
<option value=\"106\">Schlafen nach Ende der Playlist</option>\ |
|||
<option value=\"110\">Wiederhole Playlist (endlos)</option>\ |
|||
<option value=\"111\">Wiederhole Titel (endlos)</option>\ |
|||
<option value=\"112\">Dimme LEDs (Nachtmodus)</option>\ |
|||
</select>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\" onclick=\"rfidMods()\">Absenden</button>\ |
|||
</form>\ |
|||
</div>\ |
|||
<div class=\"container my-5\" id=\"mqttConfig\">\ |
|||
<h2>MQTT-Konfiguration</h2>\ |
|||
<form class=\"needs-validation\" action=\"#mqttConfig\" method=\"GET\" novalidate>\ |
|||
<div class=\"form-check col-md-6\">\ |
|||
<input class=\"form-check-input\" type=\"checkbox\" value=\"1\" id=\"mqttEnable\" name=\"mqttEnable\" %MQTT_ENABLE%>\ |
|||
<label class=\"form-check-label\" for=\"mqttEnable\">\ |
|||
MQTT aktivieren\ |
|||
</label>\ |
|||
</div>\ |
|||
<div class=\"form-group my-2 col-md-6\">\ |
|||
<label for=\"mqttServer\">MQTT-Server (IP-Adresse)</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"mqttServer\" pattern=\"^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$\" minlength=\"7\" maxlength=\"15\" placeholder=\"z.B. 192.168.2.89\" name=\"mqttServer\" value=\"%MQTT_SERVER%\">\ |
|||
<div class=\"invalid-feedback\">\ |
|||
Bitte eine gültige IPv4-Adresse eingeben, z.B. 192.168.2.89.\ |
|||
</div>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\" onclick=\"mqttSettings()\">Absenden</button>\ |
|||
</form>\ |
|||
</div>\ |
|||
<div class=\"container\" id=\"ftpConfig\">\ |
|||
<h2>FTP-Konfiguration</h2>\ |
|||
<form action=\"#ftpConfig\" method=\"GET\">\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"ftpUser\">FTP-Benutzername:</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"ftpUser\" maxlength=\"32\" placeholder=\"Benutzername\" name=\"ftpUser\" value=\"%FTP_USER%\" required>\ |
|||
<label for=\"pwd\">Passwort:</label>\ |
|||
<input type=\"password\" class=\"form-control\" id=\"ftpPwd\" maxlength=\"32\" placeholder=\"Passwort\" name=\"ftpPwd\" value=\"%FTP_PWD%\" required>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\" onClick=\"ftpSettings()\">Absenden</button>\ |
|||
</form>\ |
|||
</div>\ |
|||
<div class=\"container my-5\" id=\"generalConfig\">\ |
|||
<h2>Allgemeine Konfiguration</h2>\ |
|||
<form action=\"#generalConfig\" method=\"GET\">\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"initialVolume\">Lautstärke nach dem Einschalten</label>\ |
|||
<input type=\"number\" min=\"1\" max=\"21\" class=\"form-control\" id=\"initialVolume\" name=\"initialVolume\" value=\"%INIT_VOLUME%\" required>\ |
|||
<label for=\"maxVolume\">Maximale Lautstärke</label>\ |
|||
<input type=\"number\" min=\"1\" max=\"21\" class=\"form-control\" id=\"maxVolume\" name=\"maxVolume\" value=\"%MAX_VOLUME%\" required>\ |
|||
</div>\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"initBrightness\">Neopixel-Helligkeit nach dem Einschalten</label>\ |
|||
<input type=\"number\" min=\"0\" max=\"255\" class=\"form-control\" id=\"initBrightness\" name=\"initBrightness\" value=\"%INIT_LED_BRIGHTBESS%\" required>\ |
|||
<label for=\"nightBrightness\">Neopixel-Helligkeit im Nachtmodus</label>\ |
|||
<input type=\"number\" min=\"0\" max=\"255\" class=\"form-control\" id=\"nightBrightness\" name=\"nightBrightness\" value=\"%NIGHT_LED_BRIGHTBESS%\" required>\ |
|||
</div>\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"inactivityTime\">Deep-Sleep nach Inaktivität (Minuten)</label>\ |
|||
<input type=\"number\" min=\"1\" max=\"1440\" class=\"form-control\" id=\"inactivityTime\" name=\"inactivityTime\" value=\"%MAX_INACTIVITY%\" required>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\" onClick=\"genSettings()\">Absenden</button>\ |
|||
</form>\ |
|||
<script>\ |
|||
(function() {\ |
|||
'use strict';\ |
|||
window.addEventListener('load', function() {\ |
|||
// Fetch all the forms we want to apply custom Bootstrap validation styles to\ |
|||
var forms = document.getElementsByClassName('needs-validation');\ |
|||
// Loop over them and prevent submission\ |
|||
var validation = Array.prototype.filter.call(forms, function(form) {\ |
|||
form.addEventListener('submit', function(event) {\ |
|||
if (form.checkValidity() === false) {\ |
|||
event.preventDefault();\ |
|||
event.stopPropagation();\ |
|||
}\ |
|||
form.classList.add('was-validated');\ |
|||
}, false);\ |
|||
});\ |
|||
}, false);\ |
|||
});\ |
|||
\ |
|||
let socket = new WebSocket(\"ws://%IPv4%:81/ws\");\ |
|||
\ |
|||
function genSettings() {\ |
|||
\ |
|||
var myObj = {\ |
|||
\"general\": {\ |
|||
iVol: document.getElementById('initialVolume').value,\ |
|||
mVol: document.getElementById('maxVolume').value,\ |
|||
iBright: document.getElementById('initBrightness').value,\ |
|||
nBright: document.getElementById('nightBrightness').value,\ |
|||
iTime: document.getElementById('inactivityTime').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function ftpSettings() {\ |
|||
var myObj = {\ |
|||
\"ftp\": {\ |
|||
ftpUser: document.getElementById('ftpUser').value,\ |
|||
ftpPwd: document.getElementById('ftpPwd').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function mqttSettings() {\ |
|||
var myObj = {\ |
|||
\"mqtt\": {\ |
|||
enable: document.getElementById('mqttEnable').value,\ |
|||
server: document.getElementById('mqttServer').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function rfidMods() {\ |
|||
var myObj = {\ |
|||
\"rfidMod\": {\ |
|||
rfidId: document.getElementById('rfidIdMod').value,\ |
|||
modId: document.getElementById('modId').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function rfidAssign() {\ |
|||
var myObj = {\ |
|||
\"rfidAssign\": {\ |
|||
rfidId: document.getElementById('rfidIdMusic').value,\ |
|||
fileOrUrl: document.getElementById('fileOrUrl').value,\ |
|||
playmode: document.getElementById('playMode').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function wifiConfig() {\ |
|||
var myObj = {\ |
|||
\"wifiConfig\": {\ |
|||
ssid: document.getElementById('SSID').value,\ |
|||
pwd: document.getElementById('pwd').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
</script>\ |
|||
</div>\ |
|||
</body>\ |
|||
</html>\ |
|||
"; |
@ -1,359 +0,0 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="de"> |
|||
<head> |
|||
<title>ESPuino-configuration</title> |
|||
<meta charset="utf-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
<link rel="stylesheet" href="https://ts-cs.de/tonuino/css/bootstrap.min.css"> |
|||
<script src="https://ts-cs.de/tonuino/js/jquery.min.js"></script> |
|||
<script src="https://ts-cs.de/tonuino/js/popper.min.js"></script> |
|||
<script src="https://ts-cs.de/tonuino/js/bootstrap.min.js"></script> |
|||
</head> |
|||
<body> |
|||
<nav class="navbar navbar-expand-sm bg-primary navbar-dark"> |
|||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> |
|||
<span class="navbar-toggler-icon"></span> |
|||
</button> |
|||
<a class="navbar-brand"> |
|||
<img src="https://raw.githubusercontent.com/biologist79/Tonuino-ESP32-I2S/master/html/tonuino_logo.png" width="30" height="30" class="d-inline-block align-top" alt="" /> |
|||
Tonuino |
|||
</a> |
|||
<div class="collapse navbar-collapse" id="collapsibleNavbar"> |
|||
<ul class="navbar-nav mr-auto"> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#wifiConfig">Wifi</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#rfidMusicTags">RFID-assignments</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#rfidModTags">RFID-modifications</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#mqttConfig">MQTT</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#ftpConfig">FTP</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#generalConfig">General</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="#importNvs">NVS-importer</a> |
|||
</li> |
|||
<li class="nav-item"> |
|||
<a class="nav-link" href="/restart" style="color: orange">Reboot Tonuino</a> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
</nav> |
|||
<br /> |
|||
<div class="container" id="wifiConfig"> |
|||
<h2>Wifi-configuration</h2> |
|||
<form action="#wifiConfig" method="POST" onsubmit="wifiConfig('wifiConfig'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="ssid">Wifi-name (SSID):</label> |
|||
<input type="text" class="form-control" id="ssid" placeholder="SSID" name="ssid" required> |
|||
<div class="invalid-feedback"> |
|||
Please enter name of wifi (SSID). |
|||
</div> |
|||
<label for="pwd">Password:</label> |
|||
<input type="password" class="form-control" id="pwd" placeholder="Passwort" name="pwd" required> |
|||
<label for="hostname">Tonuino-name (hostname):</label> |
|||
<input type="text" class="form-control" id="hostname" placeholder="tonuino" name="hostname" value="%HOSTNAME%" pattern="^[^-\.]{2,32}" required> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="rfidMusicTags"> |
|||
<h2>RFID-assignments</h2> |
|||
<form action="#rfidMusicTags" method="POST" onsubmit="rfidAssign('rfidMusicTags'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="rfidIdMusic">RFID-chip-ID (12 digits)</label> |
|||
<input type="text" class="form-control" id="rfidIdMusic" maxlength="12" pattern="[0-9]{12}" placeholder="%RFID_TAG_ID%" name="rfidIdMusic" required> |
|||
<label for="fileOrUrl">File, directory or URL (^ und # are not allowed)</label> |
|||
<input type="text" class="form-control" id="fileOrUrl" maxlength="255" placeholder="z.B. /mp3/Hoerspiele/Yakari/Yakari_und_seine_Freunde.mp3" pattern="^[^\^#]+$" name="fileOrUrl" required> |
|||
<label for="playMode">Playmode</label> |
|||
<select class="form-control" id="playMode" name="playMode"> |
|||
<option value="1">Single track</option> |
|||
<option value="2">Single track (infinite loop)</option> |
|||
<option value="3">Audiobook</option> |
|||
<option value="4">Audiobook (infinite loop)</option> |
|||
<option value="5">All tracks of directory (sorted)</option> |
|||
<option value="6">All tracks of directory (random)</option> |
|||
<option value="7">All tracks of directory (sorted, inf. loop)</option> |
|||
<option value="9">All tracks of directory (random, inf. loop)</option> |
|||
<option value="8">Webradio</option> |
|||
</select> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="rfidModTags"> |
|||
<h2>RFID-modifications</h2> |
|||
<form class="needs-validation" action="#rfidModTags" method="POST" onsubmit="rfidMods('rfidModTags'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="rfidIdMod">RFID-chip-ID (12 digits)</label> |
|||
<input type="text" class="form-control" id="rfidIdMod" maxlength="12" pattern="[0-9]{12}" placeholder="%RFID_TAG_ID%" name="rfidIdMod" required> |
|||
<div class="invalid-feedback"> |
|||
Please enter a number with 12 digits. |
|||
</div> |
|||
<label for="modId">Abspielmodus</label> |
|||
<select class="form-control" id="modId" name="modId"> |
|||
<option value="100">Lock keys</option> |
|||
<option value="101">Sleep after 15 minutes</option> |
|||
<option value="102">Sleep after 30 minutes</option> |
|||
<option value="103">Sleep after 1 hour</option> |
|||
<option value="104">Sleep after 1 hours</option> |
|||
<option value="105">Sleep after end of track</option> |
|||
<option value="106">Sleep after end of playlist</option> |
|||
<option value="107">Sleep after five tracks</option> |
|||
<option value="110">Repeat playlist (inf. loop)</option> |
|||
<option value="111">Repeat track (inf. loop)</option> |
|||
<option value="112">Dimm LEDs (nightmode)</option> |
|||
<option value="130">Toggle WiFi-status</option> |
|||
</select> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="mqttConfig"> |
|||
<h2>MQTT-configuration</h2> |
|||
<form class="needs-validation" action="#mqttConfig" method="POST" onsubmit="mqttSettings('mqttConfig'); return false"> |
|||
<div class="form-check col-md-6"> |
|||
<input class="form-check-input" type="checkbox" value="1" id="mqttEnable" name="mqttEnable" %MQTT_ENABLE%> |
|||
<label class="form-check-label" for="mqttEnable"> |
|||
Enable MQTT |
|||
</label> |
|||
</div> |
|||
<div class="form-group my-2 col-md-6"> |
|||
<label for="mqttServer">MQTT-server</label> |
|||
<input type="text" class="form-control" id="mqttServer" minlength="7" maxlength="%MQTT_SERVER_LENGTH%" placeholder="z.B. 192.168.2.89" name="mqttServer" value="%MQTT_SERVER%"> |
|||
<label for="mqttUser">MQTT-username (optional):</label> |
|||
<input type="text" class="form-control" id="mqttUser" maxlength="%MQTT_USER_LENGTH%" placeholder="Benutzername" name="mqttUser" value="%MQTT_USER%"> |
|||
<label for="mqttPwd">Password (optional):</label> |
|||
<input type="password" class="form-control" id="mqttPwd" maxlength="%MQTT_PWD_LENGTH%" placeholder="Passwort" name="mqttPwd" value="%MQTT_PWD%"> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container" id="ftpConfig"> |
|||
<h2>FTP-configuration</h2> |
|||
<form action="#ftpConfig" method="POST" onsubmit="ftpSettings('ftpConfig'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="ftpUser">FTP-username:</label> |
|||
<input type="text" class="form-control" id="ftpUser" maxlength="%FTP_USER_LENGTH%" placeholder="Benutzername" name="ftpUser" value="%FTP_USER%" required> |
|||
<label for="pwd">password:</label> |
|||
<input type="password" class="form-control" id="ftpPwd" maxlength="%FTP_PWD_LENGTH%" placeholder="Passwort" name="ftpPwd" value="%FTP_PWD%" required> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="generalConfig"> |
|||
<h2>General configuration</h2> |
|||
<form action="#generalConfig" method="POST" onsubmit="genSettings('generalConfig'); return false"> |
|||
<div class="form-group col-md-6"> |
|||
<label for="initialVolume">Volume after start</label> |
|||
<input type="number" min="1" max="21" class="form-control" id="initialVolume" name="initialVolume" value="%INIT_VOLUME%" required> |
|||
<label for="maxVolumeSpeaker">Maximum volume (speaker)</label> |
|||
<input type="number" min="1" max="21" class="form-control" id="maxVolumeSpeaker" name="maxVolumeSpeaker" value="%MAX_VOLUME_SPEAKER%" required> |
|||
<label for="maxVolumeHeadphone">Maximum volume (headphone)</label> |
|||
<input type="number" min="1" max="21" class="form-control" id="maxVolumeHeadphone" name="maxVolumeHeadphone" value="%MAX_VOLUME_HEADPHONE%" required> |
|||
</div> |
|||
<div class="form-group col-md-6"> |
|||
<label for="initBrightness">Neopixel-brightness after start</label> |
|||
<input type="number" min="0" max="255" class="form-control" id="initBrightness" name="initBrightness" value="%INIT_LED_BRIGHTNESS%" required> |
|||
<label for="nightBrightness">Neopixel-brightness in nightmode</label> |
|||
<input type="number" min="0" max="255" class="form-control" id="nightBrightness" name="nightBrightness" value="%NIGHT_LED_BRIGHTNESS%" required> |
|||
</div> |
|||
<div class="form-group col-md-6"> |
|||
<label for="inactivityTime">Deepsleep after inactivity (minutes)</label> |
|||
<input type="number" min="1" max="1440" class="form-control" id="inactivityTime" name="inactivityTime" value="%MAX_INACTIVITY%" required> |
|||
</div> |
|||
<button type="reset" class="btn btn-secondary">Reset</button> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<div class="container my-5" id="importNvs"> |
|||
<h2>NVS-importer</h2> |
|||
<form action="/upload" enctype="multipart/form-data" method="POST"> |
|||
<div class="form-group"> |
|||
<label for="nvsUpload">Backup-files can be imported here.</label> |
|||
<input type="file" class="form-control-file" id="nvsUpload" name="nvsUpload" accept=".txt"> |
|||
</div> |
|||
<button type="submit" class="btn btn-primary">Submit</button> |
|||
</form> |
|||
<div class="messages col-md-6 my-2"></div> |
|||
</div> |
|||
<script> |
|||
var lastIdclicked = ''; |
|||
var errorBox = '<div class="alert alert-danger alert-dismissible fade show" role="alert">Error occured!<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button></div>'; |
|||
var okBox = '<div class="alert alert-success alert-dismissible fade show" role="alert">Action successful.<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button></div>'; |
|||
|
|||
var socket = new WebSocket("ws://%IPv4%/ws"); |
|||
|
|||
function connect() { |
|||
socket = new WebSocket("ws://%IPv4%/ws"); |
|||
} |
|||
|
|||
function ping() { |
|||
var myObj = { |
|||
"ping": { |
|||
ping: 'ping' |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
tm = setTimeout(function () { |
|||
alert("Connection to tonuino is broken!\\nPlease refresh this website."); |
|||
}, 5000); |
|||
} |
|||
|
|||
function pong() { |
|||
clearTimeout(tm); |
|||
} |
|||
|
|||
socket.onopen = function () { |
|||
setInterval(ping, 15000); |
|||
}; |
|||
|
|||
socket.onclose = function(e) { |
|||
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason); |
|||
setTimeout(function() { |
|||
connect(); |
|||
}, 5000); |
|||
}; |
|||
|
|||
socket.onerror = function(err) { |
|||
console.error('Socket encountered error: ', err.message, 'Closing socket'); |
|||
socket.close(); |
|||
}; |
|||
|
|||
socket.onmessage = function(event) { |
|||
console.log(event.data); |
|||
var socketMsg = JSON.parse(event.data); |
|||
if (socketMsg.rfidId != null) { |
|||
document.getElementById('rfidIdMod').value = socketMsg.rfidId; |
|||
document.getElementById('rfidIdMusic').value = socketMsg.rfidId; |
|||
$("#rfidIdMusic").fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500); |
|||
$("#rfidIdMod").fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500); |
|||
|
|||
} if (socketMsg.status != null) { |
|||
if (socketMsg.status == 'ok') { |
|||
$("#" + lastIdclicked).find('.messages').html(okBox); |
|||
} else { |
|||
$("#" + lastIdclicked).find('.messages').html(errorBox); |
|||
} |
|||
} if (socketMsg.pong != null) { |
|||
if (socketMsg.pong == 'pong') { |
|||
pong(); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
function genSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"general": { |
|||
iVol: document.getElementById('initialVolume').value, |
|||
mVolSpeaker: document.getElementById('maxVolumeSpeaker').value, |
|||
mVolHeadphone: document.getElementById('maxVolumeHeadphone').value, |
|||
iBright: document.getElementById('initBrightness').value, |
|||
nBright: document.getElementById('nightBrightness').value, |
|||
iTime: document.getElementById('inactivityTime').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function ftpSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"ftp": { |
|||
ftpUser: document.getElementById('ftpUser').value, |
|||
ftpPwd: document.getElementById('ftpPwd').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function mqttSettings(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var val; |
|||
if (document.getElementById('mqttEnable').checked) { |
|||
val = document.getElementById('mqttEnable').value; |
|||
} else { |
|||
val = 0; |
|||
} |
|||
var myObj = { |
|||
"mqtt": { |
|||
mqttEnable: val, |
|||
mqttServer: document.getElementById('mqttServer').value, |
|||
mqttUser: document.getElementById('mqttUser').value, |
|||
mqttPwd: document.getElementById('mqttPwd').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function rfidMods(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"rfidMod": { |
|||
rfidIdMod: document.getElementById('rfidIdMod').value, |
|||
modId: document.getElementById('modId').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function removeTrSlash(str) { |
|||
if(str.substr(-1) === '/') { |
|||
return str.substr(0, str.length - 1); |
|||
} |
|||
return str; |
|||
} |
|||
|
|||
function rfidAssign(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"rfidAssign": { |
|||
rfidIdMusic: document.getElementById('rfidIdMusic').value, |
|||
fileOrUrl: removeTrSlash(document.getElementById('fileOrUrl').value), |
|||
playMode: document.getElementById('playMode').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
|
|||
function wifiConfig(clickedId) { |
|||
lastIdclicked = clickedId; |
|||
var myObj = { |
|||
"wifiConfig": { |
|||
ssid: document.getElementById('ssid').value, |
|||
pwd: document.getElementById('pwd').value, |
|||
hostname: document.getElementById('hostname').value |
|||
} |
|||
}; |
|||
var myJSON = JSON.stringify(myObj); |
|||
socket.send(myJSON); |
|||
} |
|||
</script> |
|||
</body> |
|||
</html> |
Before Width: 1080 | Height: 1856 | Size: 336 KiB After Width: 1080 | Height: 1847 | Size: 310 KiB |
Before Width: 1080 | Height: 1223 | Size: 188 KiB After Width: 1080 | Height: 1844 | Size: 222 KiB |
Before Width: 1080 | Height: 1644 | Size: 240 KiB After Width: 1080 | Height: 1847 | Size: 252 KiB |
Before Width: 1080 | Height: 1471 | Size: 245 KiB After Width: 1080 | Height: 1847 | Size: 197 KiB |
Before Width: 1080 | Height: 602 | Size: 81 KiB After Width: 1080 | Height: 1847 | Size: 287 KiB |
After Width: 1080 | Height: 1752 | Size: 230 KiB |
After Width: 1080 | Height: 1849 | Size: 217 KiB |
Before Width: 1080 | Height: 1853 | Size: 242 KiB After Width: 1080 | Height: 1851 | Size: 364 KiB |
Before Width: 1080 | Height: 1843 | Size: 268 KiB After Width: 1032 | Height: 1280 | Size: 137 KiB |
@ -1,57 +1,74 @@ |
|||
# -*- coding: utf-8 -*- |
|||
#!/usr/bin/python |
|||
### |
|||
# Use this script for creating PROGMEM header files from html files. |
|||
# needs pip install requests |
|||
## |
|||
# html file base names |
|||
import requests |
|||
import argparse |
|||
|
|||
content = '' |
|||
content2 = '' |
|||
contentEN = '' |
|||
content2EN = '' |
|||
def str2bool(v): |
|||
if isinstance(v, bool): |
|||
return v |
|||
if v.lower() in ('yes', 'true', 't', 'y', '1'): |
|||
return True |
|||
elif v.lower() in ('no', 'false', 'f', 'n', '0'): |
|||
return False |
|||
else: |
|||
raise argparse.ArgumentTypeError('Boolean value expected.') |
|||
|
|||
with open('html/website.html', 'r') as r: |
|||
data = r.read().replace('\n', '\\\n') |
|||
data = data.replace('\"', '\\"') |
|||
data = data.replace('\\d', '\\\d') |
|||
data = data.replace('\\.', '\\\.') |
|||
data = data.replace('\\^', '\\\\^') |
|||
content += data |
|||
HTML_FILES = ["management","management_EN", "accesspoint", "accesspoint_EN"] |
|||
|
|||
with open('src/websiteMgmt.h', 'w') as w: |
|||
w.write("static const char mgtWebsite[] PROGMEM = \"") |
|||
w.write(content) |
|||
w.write("\";") |
|||
class htmlHeaderProcessor(object): |
|||
|
|||
with open('html/website_EN.html', 'r') as ren: |
|||
data = ren.read().replace('\n', '\\\n') |
|||
""" |
|||
Returns a minified HTML string, uses html-minifier.com api. |
|||
""" |
|||
def minifyHTML(self, filename): |
|||
with open('html/' + filename + '.html', 'r') as r: |
|||
data = r.read() |
|||
return requests.post('https://html-minifier.com/raw', data=dict(input=data)).text.encode('utf8') |
|||
|
|||
def escape_html(self, data): |
|||
data = data.replace('\n', '\\\n') |
|||
data = data.replace('\"', '\\"') |
|||
data = data.replace('\\d', '\\\d') |
|||
data = data.replace('\\.', '\\\.') |
|||
data = data.replace('\\^', '\\\\^') |
|||
contentEN += data |
|||
data = data.replace('%;', '%%;') |
|||
return data |
|||
|
|||
with open('src/websiteMgmt_EN.h', 'w') as wen: |
|||
wen.write("static const char mgtWebsite[] PROGMEM = \"") |
|||
wen.write(contentEN) |
|||
wen.write("\";") |
|||
def html_to_c_header(self, filename): |
|||
content = "" |
|||
with open('html/' + filename + '.html', 'r') as r: |
|||
data = r.read() |
|||
content += self.escape_html(data) |
|||
return content |
|||
|
|||
with open('html/websiteBasic.html', 'r') as r2: |
|||
data = r2.read().replace('\n', '\\\n') |
|||
data = data.replace('\"', '\\"') |
|||
content2 += data |
|||
|
|||
with open('src/websiteBasic.h', 'w') as w2: |
|||
w2.write("static const char basicWebsite[] PROGMEM = \"") |
|||
w2.write(content2) |
|||
w2.write("\";") |
|||
def write_header_file(self, filename, content): |
|||
with open('src/HTML' + filename + '.h', 'w') as w: |
|||
varname = filename.split('_')[0] |
|||
w.write("static const char " + varname + "_HTML[] PROGMEM = \"") |
|||
w.write(content) |
|||
w.write("\";") |
|||
|
|||
def main(self): |
|||
parser = argparse.ArgumentParser(description='Create c code PROGMEM header files from HTML files.') |
|||
parser.add_argument("--minify", type=str2bool, nargs='?', |
|||
const=True, default=False, |
|||
help="Minify HTML Code") |
|||
args = parser.parse_args() |
|||
|
|||
with open('html/websiteBasic_EN.html', 'r') as r2en: |
|||
data = r2en.read().replace('\n', '\\\n') |
|||
data = data.replace('\"', '\\"') |
|||
content2EN += data |
|||
for file in HTML_FILES: |
|||
if args.minify: |
|||
|
|||
with open('src/websiteBasic_EN.h', 'w') as w2en: |
|||
w2en.write("static const char basicWebsite[] PROGMEM = \"") |
|||
w2en.write(content2EN) |
|||
w2en.write("\";") |
|||
self.header_file_content = self.minifyHTML(file) |
|||
self.header_file_content = self.escape_html(self.header_file_content) |
|||
else: |
|||
self.header_file_content = self.html_to_c_header(file) |
|||
self.write_header_file(file, self.header_file_content) |
|||
|
|||
r.close() |
|||
w.close() |
|||
r2.close() |
|||
w2.close() |
|||
if __name__ == '__main__': |
|||
htmlHeaderProcessor().main() |
@ -0,0 +1,65 @@ |
|||
static const char accesspoint_HTML[] PROGMEM = "<!DOCTYPE html>\ |
|||
<html>\ |
|||
<head>\ |
|||
<title>WLAN-Einrichtung</title>\ |
|||
<style>\ |
|||
input {\ |
|||
width: 90%%;\ |
|||
height: 44px;\ |
|||
border-radius: 4px;\ |
|||
margin: 10px auto;\ |
|||
font-size: 15px;\ |
|||
background: #f1f1f1;\ |
|||
border: 0;\ |
|||
padding: 0 15px\ |
|||
}\ |
|||
input {\ |
|||
\ |
|||
}\ |
|||
body {\ |
|||
background: #007bff;\ |
|||
font-family: sans-serif;\ |
|||
font-size: 14px;\ |
|||
color: #777\ |
|||
}\ |
|||
.box {\ |
|||
background: #fff;\ |
|||
max-width: 258px;\ |
|||
margin: 75px auto;\ |
|||
padding: 30px;\ |
|||
border-radius: 5px;\ |
|||
text-align: center\ |
|||
}\ |
|||
.btn {\ |
|||
background: #3498db;\ |
|||
color: #fff;\ |
|||
cursor: pointer;\ |
|||
width: 90%%;\ |
|||
height: 44px;\ |
|||
border-radius: 4px;\ |
|||
margin: 10px auto;\ |
|||
font-size: 15px;\ |
|||
}\ |
|||
.rebootmsg {\ |
|||
display: none;\ |
|||
}\ |
|||
</style>\ |
|||
</head>\ |
|||
<body>\ |
|||
<form id=\"settings\" action=\"/init\" class=\"box\" method=\"POST\">\ |
|||
<h1>WiFi Configuration</h1>\ |
|||
<label for=\"ssid\">SSID:</label><br>\ |
|||
<input type=\"text\" id=\"ssid\" name=\"ssid\" placeholder=\"SSID\" required><br>\ |
|||
<label for=\"pwd\">Passwort:</label><br>\ |
|||
<input type=\"password\" id=\"pwd\" name=\"pwd\" autocomplete=\"off\" required><br>\ |
|||
<label for=\"hostname\">Tonuino-Name (Hostname):</label><br>\ |
|||
<input type=\"text\" id=\"hostname\" name=\"hostname\" placeholder=\"Tonuino\" required><br><br>\ |
|||
<input class=\"btn\" type=\"submit\" id=\"save-button\" value=\"Save\">\ |
|||
</form>\ |
|||
<form action=\"/restart\" class=\"box\">\ |
|||
<h1>Ready to go?</h1>\ |
|||
<input class=\"btn\" type=\"submit\" id=\"restart-button\" value=\"Reboot\">\ |
|||
</form>\ |
|||
\ |
|||
</body>\ |
|||
</html>"; |
@ -1,4 +1,4 @@ |
|||
static const char basicWebsite[] PROGMEM = "<!DOCTYPE html>\ |
|||
static const char accesspoint_HTML[] PROGMEM = "<!DOCTYPE html>\ |
|||
<html>\ |
|||
<head>\ |
|||
<title>Wifi-configuration</title>\ |
@ -0,0 +1,728 @@ |
|||
static const char management_HTML[] PROGMEM = "<!DOCTYPE html>\ |
|||
<html lang=\"de\">\ |
|||
<head>\ |
|||
<title>ESPuino-Konfiguration</title>\ |
|||
<meta charset=\"utf-8\">\ |
|||
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\ |
|||
<link rel=\"stylesheet\" href=\"https://ts-cs.de/tonuino/css/bootstrap.min.css\">\ |
|||
<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css\"/>\ |
|||
<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css\"/>\ |
|||
<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css\"/>\ |
|||
<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/11.0.2/css/bootstrap-slider.min.css\" />\ |
|||
<script src=\"https://ts-cs.de/tonuino/js/jquery.min.js\"></script>\ |
|||
<script src=\"https://code.jquery.com/ui/1.12.0/jquery-ui.min.js\"></script>\ |
|||
<script src=\"https://ts-cs.de/tonuino/js/popper.min.js\"></script>\ |
|||
<script src=\"https://ts-cs.de/tonuino/js/bootstrap.min.js\"></script>\ |
|||
<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js\"></script>\ |
|||
<script src=\"https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js\"></script>\ |
|||
<script src=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/11.0.2/bootstrap-slider.min.js\"></script>\ |
|||
<style type=\"text/css\">\ |
|||
.filetree {\ |
|||
border: 1px solid black;\ |
|||
height: 200px;\ |
|||
margin: 0em 0em 1em 0em;\ |
|||
overflow-y: scroll;\ |
|||
}\ |
|||
.slider.slider-horizontal {\ |
|||
width: 60%%;\ |
|||
margin-left: 1em;\ |
|||
margin-right: 1em;\ |
|||
\ |
|||
}\ |
|||
.slider-handle{\ |
|||
height: 30px;\ |
|||
width: 30px;\ |
|||
top: -5px;\ |
|||
}\ |
|||
\ |
|||
legend.scheduler-border {\ |
|||
width:inherit; /* Or auto */\ |
|||
padding:0 10px; /* To give a bit of padding on the left and right */\ |
|||
border-bottom:none;\ |
|||
}\ |
|||
\ |
|||
.icon-pos{\ |
|||
top: 0.3em;\ |
|||
position: relative;\ |
|||
}\ |
|||
.reboot{\ |
|||
color:white;\ |
|||
}\ |
|||
.reboot:hover{\ |
|||
color: orange;\ |
|||
}\ |
|||
\ |
|||
.fa-sync:hover {\ |
|||
color: #666666;\ |
|||
}\ |
|||
\ |
|||
.clickForRefresh {\ |
|||
text-align: center;\ |
|||
color: gray;\ |
|||
cursor: pointer;\ |
|||
margin-top: 5em;\ |
|||
}\ |
|||
\ |
|||
.clickForRefresh:hover {\ |
|||
color: darkgray;\ |
|||
}\ |
|||
\ |
|||
.filetree-container {\ |
|||
position: relative;\ |
|||
}\ |
|||
\ |
|||
.indexing-progress {\ |
|||
width: 100%%;\ |
|||
height: 100%%;\ |
|||
position: absolute;\ |
|||
top: 0;\ |
|||
left: 0;\ |
|||
opacity: 0.7;\ |
|||
display: none;\ |
|||
}\ |
|||
\ |
|||
.refreshAction{\ |
|||
text-align: right;\ |
|||
font-size: 0.8em;\ |
|||
}\ |
|||
\ |
|||
.refreshAction:hover{\ |
|||
cursor: pointer;\ |
|||
color: darkgray;\ |
|||
}\ |
|||
\ |
|||
.overlay {\ |
|||
z-index: 9;\ |
|||
opacity: 0.8;\ |
|||
background: #1a1919;\ |
|||
height: 200px;\ |
|||
display: none;\ |
|||
width: 100%%;\ |
|||
}\ |
|||
</style>\ |
|||
</head>\ |
|||
<body>\ |
|||
<nav class=\"navbar navbar-expand-sm bg-primary navbar-dark\">\ |
|||
<div class=\"col-md-12\">\ |
|||
<a class=\"float-left navbar-brand\">\ |
|||
<img src=\"https://raw.githubusercontent.com/biologist79/Tonuino-ESP32-I2S/master/html/tonuino_logo.png\"\ |
|||
width=\"30\" height=\"30\" class=\"d-inline-block align-top\" alt=\"\"/>\ |
|||
Tonuino\ |
|||
</a>\ |
|||
\ |
|||
<a class=\"reboot float-right nav-link\" href=\"/restart\"><i class=\"fas fa-power-off\"></i> Neustart</a>\ |
|||
</div>\ |
|||
</nav>\ |
|||
<br/>\ |
|||
<nav>\ |
|||
<div class=\"container nav nav-tabs\" id=\"nav-tab\" role=\"tablist\">\ |
|||
<a class=\"nav-item nav-link active\" id=\"nav-rfid-tab\" data-toggle=\"tab\" href=\"#nav-rfid\" role=\"tab\" aria-controls=\"nav-rfid\" aria-selected=\"true\"><i class=\"fas fa-dot-circle\"></i> RFID</a>\ |
|||
<a class=\"nav-item nav-link\" id=\"nav-wifi-tab\" data-toggle=\"tab\" href=\"#nav-wifi\" role=\"tab\" aria-controls=\"nav-wifi\" aria-selected=\"false\"><i class=\"fas fa-wifi\"></i><span class=\".d-sm-none .d-md-block\"> WLAN</span></a>\ |
|||
<a class=\"nav-item nav-link\" id=\"nav-mqtt-tab\" data-toggle=\"tab\" href=\"#nav-mqtt\" role=\"tab\" aria-controls=\"nav-mqtt\" aria-selected=\"false\"><i class=\"fas fa-network-wired\"></i> MQTT</a>\ |
|||
<a class=\"nav-item nav-link\" id=\"nav-ftp-tab\" data-toggle=\"tab\" href=\"#nav-ftp\" role=\"tab\" aria-controls=\"nav-ftp\" aria-selected=\"false\"><i class=\"fas fa-folder\"></i> FTP</a>\ |
|||
<a class=\"nav-item nav-link\" id=\"nav-general-tab\" data-toggle=\"tab\" href=\"#nav-general\" role=\"tab\" aria-controls=\"nav-general\" aria-selected=\"false\"><i class=\"fas fa-sliders-h\"></i> Allgemein</a>\ |
|||
<a class=\"nav-item nav-link\" id=\"nav-tools-tab\" data-toggle=\"tab\" href=\"#nav-tools\" role=\"tab\" aria-controls=\"nav-tools\" aria-selected=\"false\"><i class=\"fas fa-wrench\"></i> Tools</a>\ |
|||
</div>\ |
|||
</nav>\ |
|||
<br>\ |
|||
<div class=\"tab-content\" id=\"nav-tabContent\">\ |
|||
<div class=\"tab-pane fade\" id=\"nav-wifi\" role=\"tabpanel\" aria-labelledby=\"nav-wifi-tab\">\ |
|||
<div class=\"container\" id=\"wifiConfig\">\ |
|||
<form action=\"#wifiConfig\" method=\"POST\" onsubmit=\"wifiConfig('wifiConfig'); return false\">\ |
|||
<div class=\"form-group col-md-12\">\ |
|||
<label for=\"ssid\">WLAN-Name (SSID):</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"ssid\" placeholder=\"SSID\" name=\"ssid\" required>\ |
|||
<div class=\"invalid-feedback\">\ |
|||
Bitte SSID des WLANs eintragen.\ |
|||
</div>\ |
|||
<label for=\"pwd\">Passwort:</label>\ |
|||
<input type=\"password\" class=\"form-control\" id=\"pwd\" placeholder=\"Passwort\" name=\"pwd\" required>\ |
|||
<label for=\"hostname\">Tonuino-Name (Hostname):</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"hostname\" placeholder=\"tonuino\" name=\"hostname\"\ |
|||
value=\"%HOSTNAME%\" pattern=\"^[^-\\.]{2,32}\" required>\ |
|||
</div>\ |
|||
<br>\ |
|||
<div class=\"text-center\">\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</div>\ |
|||
</form>\ |
|||
</div>\ |
|||
</div>\ |
|||
<div class=\"tab-pane fade show active\" id=\"nav-rfid\" role=\"tabpanel\" aria-labelledby=\"nav-rfid-tab\">\ |
|||
<div class=\"container\" id=\"rfidMusicTags\">\ |
|||
<fieldset>\ |
|||
<legend>RFID-Zuweisungen</legend>\ |
|||
<form action=\"#rfidMusicTags\" method=\"POST\" onsubmit=\"rfidAssign('rfidMusicTags'); return false\">\ |
|||
<div class=\"form-group col-md-12\">\ |
|||
<label for=\"rfidIdMusic\">RFID-Chip-Nummer (12-stellig)</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"rfidIdMusic\" maxlength=\"12\" pattern=\"[0-9]{12}\"\ |
|||
placeholder=\"%RFID_TAG_ID%\" name=\"rfidIdMusic\" required>\ |
|||
<label for=\"fileOrUrl\">Datei, Verzeichnis oder URL (^ und # als Zeichen nicht erlaubt)</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"fileOrUrl\" maxlength=\"255\" placeholder=\"z.B. /mp3/Hoerspiele/Yakari/Yakari_und_seine_Freunde.mp3\" pattern=\"^[^\\^#]+$\" name=\"fileOrUrl\" required>\ |
|||
<div class=\"filetree-container\">\ |
|||
<div id=\"filebrowser\">\ |
|||
<div class=\"filetree demo\" id=\"filetree\"></div>\ |
|||
<div class=\"refreshAction\">\ |
|||
<span id=\"refreshAction\" data-toggle=\"tooltip\" data-placement=\"top\" title=\"Datei Liste aktualisieren.\"><i class=\"fas fa-sync fa-1x\"></i> Dateiliste aktualisieren</span>\ |
|||
</div>\ |
|||
</div>\ |
|||
<div id=\"indexing-progress\" class=\"indexing-progress overlay\">\ |
|||
<div style=\"text-align: center; color:white; margin-top:2em;\">\ |
|||
<div><i class=\"fas fa-sync fa-spin fa-2x\"></i> <br><br> Der Prozess kann mehrere Minuten dauern...</div>\ |
|||
<div id=\"currentProcessedFile\"></div>\ |
|||
</div>\ |
|||
</div>\ |
|||
</div>\ |
|||
<label for=\"playMode\">Abspielmodus</label>\ |
|||
<select class=\"form-control\" id=\"playMode\" name=\"playMode\">\ |
|||
<option class=\"option-file\" value=\"1\">Einzelner Titel</option>\ |
|||
<option class=\"option-file\" value=\"2\">Einzelner Titel (Endlosschleife)</option>\ |
|||
<option class=\"option-file-and-folder\" value=\"3\">Hörbuch</option>\ |
|||
<option class=\"option-file-and-folder\" value=\"4\">Hörbuch (Endlosschleife)</option>\ |
|||
<option class=\"option-folder\" value=\"5\">Alle Titel eines Verzeichnis (sortiert)</option>\ |
|||
<option class=\"option-folder\" value=\"6\">Alle Titel eines Verzeichnis (zufällig)</option>\ |
|||
<option class=\"option-folder\" value=\"7\">Alle Titel eines Verzeichnis (sortiert, Endlosschleife)</option>\ |
|||
<option class=\"option-folder\" value=\"9\">Alle Titel eines Verzeichnis (zufällig, Endlosschleife)</option>\ |
|||
<option class=\"option-stream\" value=\"8\">Webradio</option>\ |
|||
</select>\ |
|||
</div>\ |
|||
<br>\ |
|||
<div class=\"text-center\">\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</div>\ |
|||
</form>\ |
|||
</fieldset>\ |
|||
</div>\ |
|||
\ |
|||
<br>\ |
|||
<br>\ |
|||
<div class=\"container\" id=\"rfidModTags\">\ |
|||
<fieldset>\ |
|||
<legend>RFID-Modifkationen</legend>\ |
|||
<form class=\"needs-validation\" action=\"#rfidModTags\" method=\"POST\" onsubmit=\"rfidMods('rfidModTags'); return false\">\ |
|||
<div class=\"form-group col-md-12\">\ |
|||
<label for=\"rfidIdMod\">RFID-Chip-Nummer (12-stellig)</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"rfidIdMod\" maxlength=\"12\" pattern=\"[0-9]{12}\"\ |
|||
placeholder=\"%RFID_TAG_ID%\" name=\"rfidIdMod\" required>\ |
|||
<div class=\"invalid-feedback\">\ |
|||
Bitte eine 12-stellige Zahl eingeben.\ |
|||
</div>\ |
|||
<label for=\"modId\">Konfiguraiton</label>\ |
|||
<select class=\"form-control\" id=\"modId\" name=\"modId\">\ |
|||
<option value=\"100\">Tastensperre</option>\ |
|||
<option value=\"101\">Schlafen nach 15 Minuten</option>\ |
|||
<option value=\"102\">Schlafen nach 30 Minuten</option>\ |
|||
<option value=\"103\">Schlafen nach 1 Stunde</option>\ |
|||
<option value=\"104\">Schlafen nach 2 Stunden</option>\ |
|||
<option value=\"105\">Schlafen nach Ende des Titels</option>\ |
|||
<option value=\"106\">Schlafen nach Ende der Playlist</option>\ |
|||
<option value=\"107\">Schlafen nach fünf Titeln</option>\ |
|||
<option value=\"110\">Wiederhole Playlist (endlos)</option>\ |
|||
<option value=\"111\">Wiederhole Titel (endlos)</option>\ |
|||
<option value=\"112\">Dimme LEDs (Nachtmodus)</option>\ |
|||
<option value=\"130\">Aktiviere/deaktive WLAN</option>\ |
|||
</select>\ |
|||
</div>\ |
|||
<br>\ |
|||
<div class=\"text-center\">\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</div>\ |
|||
</form>\ |
|||
</fieldset>\ |
|||
</div>\ |
|||
</div>\ |
|||
<div class=\"tab-pane fade\" id=\"nav-mqtt\" role=\"tabpanel\" aria-labelledby=\"nav-mqtt-tab\">\ |
|||
<div class=\"container\" id=\"mqttConfig\">\ |
|||
\ |
|||
<form class=\"needs-validation\" action=\"#mqttConfig\" method=\"POST\"\ |
|||
onsubmit=\"mqttSettings('mqttConfig'); return false\">\ |
|||
<div class=\"form-check col-md-12\">\ |
|||
<input class=\"form-check-input\" type=\"checkbox\" value=\"1\" id=\"mqttEnable\" name=\"mqttEnable\" %MQTT_ENABLE%>\ |
|||
<label class=\"form-check-label\" for=\"mqttEnable\">\ |
|||
MQTT aktivieren\ |
|||
</label>\ |
|||
</div>\ |
|||
<div class=\"form-group my-2 col-md-12\">\ |
|||
<label for=\"mqttServer\">MQTT-Server</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"mqttServer\" minlength=\"7\" maxlength=\"%MQTT_SERVER_LENGTH%\"\ |
|||
placeholder=\"z.B. 192.168.2.89\" name=\"mqttServer\" value=\"%MQTT_SERVER%\">\ |
|||
<label for=\"mqttUser\">MQTT-Benutzername (optional):</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"mqttUser\" maxlength=\"%MQTT_USER_LENGTH%\"\ |
|||
placeholder=\"Benutzername\" name=\"mqttUser\" value=\"%MQTT_USER%\">\ |
|||
<label for=\"mqttPwd\">Passwort (optional):</label>\ |
|||
<input type=\"password\" class=\"form-control\" id=\"mqttPwd\" maxlength=\"%MQTT_PWD_LENGTH%\"\ |
|||
placeholder=\"Passwort\" name=\"mqttPwd\" value=\"%MQTT_PWD%\">\ |
|||
</div>\ |
|||
<br>\ |
|||
<div class=\"text-center\">\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</div>\ |
|||
</form>\ |
|||
</div>\ |
|||
</div>\ |
|||
<div class=\"tab-pane fade\" id=\"nav-ftp\" role=\"tabpanel\" aria-labelledby=\"nav-ftp-tab\">\ |
|||
<div class=\"container\" id=\"ftpConfig\">\ |
|||
\ |
|||
<form action=\"#ftpConfig\" method=\"POST\" onsubmit=\"ftpSettings('ftpConfig'); return false\">\ |
|||
<div class=\"form-group col-md-12\">\ |
|||
<label for=\"ftpUser\">FTP-Benutzername:</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"ftpUser\" maxlength=\"%FTP_USER_LENGTH%\"\ |
|||
placeholder=\"Benutzername\" name=\"ftpUser\" value=\"%FTP_USER%\" required>\ |
|||
<label for=\"pwd\">Passwort:</label>\ |
|||
<input type=\"password\" class=\"form-control\" id=\"ftpPwd\" maxlength=\"%FTP_PWD_LENGTH%\" placeholder=\"Passwort\"\ |
|||
name=\"ftpPwd\" value=\"%FTP_PWD%\" required>\ |
|||
</div>\ |
|||
<br>\ |
|||
<div class=\"text-center\">\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</div>\ |
|||
</form>\ |
|||
</div>\ |
|||
</div>\ |
|||
\ |
|||
<div class=\"tab-pane fade\" id=\"nav-general\" role=\"tabpanel\" aria-labelledby=\"nav-general-tab\">\ |
|||
<div class=\"container\" id=\"generalConfig\">\ |
|||
\ |
|||
<form action=\"#generalConfig\" method=\"POST\" onsubmit=\"genSettings('generalConfig'); return false\">\ |
|||
<div class=\"form-group col-md-12\">\ |
|||
<fieldset>\ |
|||
<legend class=\"w-auto\">Lautstärke</legend>\ |
|||
<label for=\"initialVolume\">Nach dem Einschalten</label>\ |
|||
<div class=\"text-center\">\ |
|||
<i class=\"fas fa-volume-down fa-2x .icon-pos\"></i> <input data-provide=\"slider\" type=\"number\" data-slider-min=\"1\" data-slider-max=\"21\" min=\"1\" max=\"21\" class=\"form-control\" id=\"initialVolume\" name=\"initialVolume\"\ |
|||
data-slider-value=\"%INIT_VOLUME%\" value=\"%INIT_VOLUME%\" required> <i class=\"fas fa-volume-up fa-2x .icon-pos\"></i></div>\ |
|||
<br>\ |
|||
<label for=\"maxVolumeSpeaker\">Maximal Lautsprecher</label>\ |
|||
<div class=\"text-center\">\ |
|||
<i class=\"fas fa-volume-down fa-2x .icon-pos\"></i> <input data-provide=\"slider\" type=\"number\" data-slider-min=\"1\" data-slider-max=\"21\" min=\"1\" max=\"21\" class=\"form-control\" id=\"maxVolumeSpeaker\" name=\"maxVolumeSpeaker\"\ |
|||
data-slider-value=\"%MAX_VOLUME_SPEAKER%\" value=\"%MAX_VOLUME_SPEAKER%\" required> <i class=\"fas fa-volume-up fa-2x .icon-pos\"></i>\ |
|||
</div>\ |
|||
<br>\ |
|||
<label for=\"maxVolumeHeadphone\">Maximal Kopfhörer</label>\ |
|||
<div class=\"text-center\">\ |
|||
<i class=\"fas fa-volume-down fa-2x .icon-pos\"></i> <input data-provide=\"slider\" type=\"number\" data-slider-min=\"1\" data-slider-max=\"21\" min=\"1\" max=\"21\" class=\"form-control\" id=\"maxVolumeHeadphone\" name=\"maxVolumeHeadphone\"\ |
|||
data-slider-value=\"%MAX_VOLUME_HEADPHONE%\" value=\"%MAX_VOLUME_HEADPHONE%\" required> <i class=\"fas fa-volume-up fa-2x .icon-pos\"></i>\ |
|||
</div>\ |
|||
</fieldset>\ |
|||
</div>\ |
|||
<br>\ |
|||
<div class=\"form-group col-md-12\">\ |
|||
<fieldset >\ |
|||
<legend class=\"w-auto\">Neopixel (Helligkeit)</legend>\ |
|||
<label for=\"initBrightness\">Nach dem Einschalten:</label>\ |
|||
<div class=\"text-center\">\ |
|||
<i class=\"far fa-sun fa-2x .icon-pos\"></i>\ |
|||
<input data-provide=\"slider\" type=\"number\" data-slider-min=\"0\" data-slider-max=\"255\" min=\"0\" max=\"255\" class=\"form-control\" id=\"initBrightness\" name=\"initBrightness\"\ |
|||
data-slider-value=\"%INIT_LED_BRIGHTNESS%\" value=\"%INIT_LED_BRIGHTNESS%\" required><i class=\"fas fa-sun fa-2x .icon-pos\"></i>\ |
|||
</div>\ |
|||
\ |
|||
<label for=\"nightBrightness\">Im Nachtmodus</label>\ |
|||
<div class=\"text-center\">\ |
|||
<i class=\"far fa-sun fa-2x .icon-pos\"></i><input data-provide=\"slider\" type=\"number\" data-slider-min=\"0\" data-slider-max=\"255\" min=\"0\" max=\"255\" class=\"form-control\" id=\"nightBrightness\" name=\"nightBrightness\" data-slider-value=\"%NIGHT_LED_BRIGHTNESS%\" value=\"%NIGHT_LED_BRIGHTNESS%\" required><i class=\"fas fa-sun fa-2x .icon-pos\"></i>\ |
|||
</div>\ |
|||
</fieldset>\ |
|||
</div>\ |
|||
<br>\ |
|||
<div class=\"form-group col-md-12\">\ |
|||
<fieldset>\ |
|||
<legend>Deep Sleep</legend>\ |
|||
\ |
|||
<label for=\"inactivityTime\">Inaktivität nach (in Minuten)</label>\ |
|||
<div class=\"text-center\"><i class=\"fas fa-hourglass-start fa-2x .icon-pos\"></i> <input type=\"number\" data-provide=\"slider\" data-slider-min=\"0\" data-slider-max=\"30\" min=\"1\" max=\"120\" class=\"form-control\" id=\"inactivityTime\" name=\"inactivityTime\"\ |
|||
data-slider-value=\"%MAX_INACTIVITY%\" value=\"%MAX_INACTIVITY%\" required><i class=\"fas fa-hourglass-end fa-2x .icon-pos\"></i></div>\ |
|||
</fieldset>\ |
|||
</div>\ |
|||
<br>\ |
|||
\ |
|||
<div class=\"form-group col-md-12\">\ |
|||
<fieldset>\ |
|||
<legend>Batterie</legend>\ |
|||
<div>Status über Neopixel anzeigen</div>\ |
|||
<br>\ |
|||
<label for=\"warningLowVoltage\">Spannungsgrenze für Status Anzeige.\ |
|||
</label>\ |
|||
<div class=\"text-center\">\ |
|||
<i class=\"fas fa-battery-quarter fa-2x .icon-pos\"></i> <input data-provide=\"slider\" data-slider-step=\"0.1\" data-slider-min=\"3.0\" data-slider-max=\"5.0\" min=\"3.0\" max=\"5.0\" type=\"text\" class=\"form-control\" id=\"warningLowVoltage\" name=\"warningLowVoltage\"\ |
|||
data-slider-value=\"%WARNING_LOW_VOLTAGE%\" value=\"%WARNING_LOW_VOLTAGE%\" pattern=\"^\\d{1,2}(\\.\\d{1,3})?\" required> <i class=\"fas fa-battery-three-quarters fa-2x .icon-pos\" fa-2x .icon-pos></i>\ |
|||
</div>\ |
|||
<br>\ |
|||
<label for=\"voltageIndicatorLow\">Unterer Akkuspannungslevel\ |
|||
</label>\ |
|||
<div class=\"text-center\">\ |
|||
<i class=\"fas fa-battery-quarter fa-2x .icon-pos\"></i> <input data-provide=\"slider\" min=\"2.0\" data-slider-step=\"0.1\" data-slider-min=\"2.0\" data-slider-max=\"5.0\" max=\"5.0\"type=\"text\" class=\"form-control\" id=\"voltageIndicatorLow\" name=\"voltageIndicatorLow\"\ |
|||
data-slider-value=\"%VOLTAGE_INDICATOR_LOW%\" value=\"%VOLTAGE_INDICATOR_LOW%\" pattern=\"^\\d{1,2}(\\.\\d{1,3})?\" required> <i class=\"fas fa-battery-three-quarters fa-2x .icon-pos\" fa-2x .icon-pos></i>\ |
|||
</div>\ |
|||
<br>\ |
|||
<label for=\"voltageIndicatorHigh\">Oberer Akkuspannungslevel</label>\ |
|||
\ |
|||
<div class=\"text-center\">\ |
|||
<i class=\"fas fa-battery-quarter fa-2x .icon-pos\"></i><input data-provide=\"slider\" data-slider-step=\"0.1\" data-slider-min=\"2.0\" data-slider-max=\"5.0\" min=\"2.0\" max=\"5.0\" type=\"text\" class=\"form-control\" id=\"voltageIndicatorHigh\" name=\"voltageIndicatorHigh\"\ |
|||
data-slider-value=\"%VOLTAGE_INDICATOR_HIGH%\" value=\"%VOLTAGE_INDICATOR_HIGH%\" pattern=\"^\\d{1,2}(\\.\\d{1,3})?\" required> <i class=\"fas fa-battery-three-quarters fa-2x .icon-pos\" fa-2x .icon-pos></i>\ |
|||
</div>\ |
|||
\ |
|||
<br>\ |
|||
<label for=\"voltageCheckInterval\"> Interval der Messung (in Minuten)</label>\ |
|||
<div class=\"text-center\"><i class=\"fas fa-hourglass-start fa-2x .icon-pos\"></i>\ |
|||
<input data-provide=\"slider\" data-slider-min=\"1\" data-slider-max=\"60\" type=\"number\" min=\"1\" max=\"60\" class=\"form-control\" id=\"voltageCheckInterval\"\ |
|||
data-slider-value=\"%VOLTAGE_CHECK_INTERVAL%\" name=\"voltageCheckInterval\" value=\"%VOLTAGE_CHECK_INTERVAL%\" required><i class=\"fas fa-hourglass-end fa-2x .icon-pos\"></i>\ |
|||
</div>\ |
|||
\ |
|||
</fieldset>\ |
|||
</div>\ |
|||
<br>\ |
|||
<div class=\"text-center\">\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</div>\ |
|||
</form>\ |
|||
</div>\ |
|||
</div>\ |
|||
<div class=\"tab-pane fade\" id=\"nav-tools\" role=\"tabpanel\" aria-labelledby=\"nav-tools-tab\">\ |
|||
<div class=\"container my-5\" id=\"importNvs\">\ |
|||
<h2>NVS-Importer</h2>\ |
|||
<form action=\"/upload\" enctype=\"multipart/form-data\" method=\"POST\">\ |
|||
<div class=\"form-group\">\ |
|||
<label for=\"nvsUpload\">Hier kann eine Backup-Datei importiert werden.</label>\ |
|||
<input type=\"file\" class=\"form-control-file\" id=\"nvsUpload\" name=\"nvsUpload\" accept=\".txt\">\ |
|||
</div>\ |
|||
<br>\ |
|||
<div class=\"text-center\">\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</div>\ |
|||
</form>\ |
|||
</div>\ |
|||
</div>\ |
|||
</div>\ |
|||
<script type=\"text/javascript\">\ |
|||
var DEBUG = false;\ |
|||
var lastIdclicked = '';\ |
|||
var host = $(location).attr('hostname');\ |
|||
\ |
|||
if (DEBUG) {\ |
|||
host = \"192.168.178.114\";\ |
|||
}\ |
|||
\ |
|||
toastr.options = {\ |
|||
\"closeButton\": false,\ |
|||
\"debug\": false,\ |
|||
\"newestOnTop\": false,\ |
|||
\"progressBar\": false,\ |
|||
\"positionClass\": \"toast-top-right\",\ |
|||
\"preventDuplicates\": false,\ |
|||
\"onclick\": null,\ |
|||
\"showDuration\": \"300\",\ |
|||
\"hideDuration\": \"1000\",\ |
|||
\"timeOut\": \"5000\",\ |
|||
\"extendedTimeOut\": \"1000\",\ |
|||
\"showEasing\": \"swing\",\ |
|||
\"hideEasing\": \"linear\",\ |
|||
\"showMethod\": \"fadeIn\",\ |
|||
\"hideMethod\": \"fadeOut\"\ |
|||
};\ |
|||
\ |
|||
function postRendering(event, data) {\ |
|||
Object.keys(data.instance._model.data).forEach(function (key, index) {\ |
|||
\ |
|||
var cur = data.instance.get_node(data.instance._model.data[key]);\ |
|||
var lastFolder = cur['id'].split('/').filter(function (el) {\ |
|||
return el.trim().length > 0;\ |
|||
}).pop();\ |
|||
if ((/\\.(mp3|MP3|ogg|wav|WAV|OGG|wma|WMA|acc|ACC|flac|FLAC)$/i).test(lastFolder)) {\ |
|||
data.instance.set_type(data.instance._model.data[key], 'audio');\ |
|||
} else {\ |
|||
if (data.instance._model.data[key]['type'] == \"file\") {\ |
|||
data.instance.disable_node(data.instance._model.data[key]);\ |
|||
}\ |
|||
}\ |
|||
data.instance.rename_node(data.instance._model.data[key], lastFolder);\ |
|||
});\ |
|||
}\ |
|||
\ |
|||
function renderFileTree() {\ |
|||
\ |
|||
var filesURI = \"/files\";\ |
|||
if (DEBUG) {\ |
|||
filesURI = \"http://\" + host + \"/files\";\ |
|||
}\ |
|||
$('#filetree').jstree({\ |
|||
'core': {\ |
|||
'check_callback': true,\ |
|||
'data': {\ |
|||
url: filesURI,\ |
|||
error: function (XMLHttpRequest, textStatus, errorThrown) {\ |
|||
$('#j1_loading').hide();\ |
|||
$(\"#refreshAction\").hide();\ |
|||
$('#filetree').html(\"<div class='clickForRefresh' ><i class='fas fa-sync fa-1x'><span id='#clickForRefresh' > Dateien suchen.</span></div>\");\ |
|||
$('#filetree').on(\"click\", function () {\ |
|||
refreshFileList();\ |
|||
});\ |
|||
toastr.error(\"Die Verzeichnis-Liste konnte nicht geladen werden.\");\ |
|||
}\ |
|||
},\ |
|||
\ |
|||
},\ |
|||
'types': {\ |
|||
'folder': {\ |
|||
'icon': \"fa fa-folder\"\ |
|||
},\ |
|||
'file': {\ |
|||
'icon': \"fa fa-file\"\ |
|||
},\ |
|||
'audio': {\ |
|||
'icon': \"fa fa-file-audio\"\ |
|||
},\ |
|||
'default': {\ |
|||
'icon': \"fa fa-folder\"\ |
|||
}\ |
|||
},\ |
|||
'plugins': [\"themes\", \"types\"]\ |
|||
}).bind('loaded.jstree', function (event, data) {\ |
|||
postRendering(event, data);\ |
|||
if ((data.instance._model.data['#']['children'].length == 0)) {\ |
|||
toastr.info(\"Der SD-Karten-Index muss erzeugt werden.\");\ |
|||
}\ |
|||
}).bind('refresh.jstree', function (event, data) {\ |
|||
postRendering(event, data);\ |
|||
});\ |
|||
}\ |
|||
\ |
|||
$('#filetree').on('select_node.jstree', function (e, data) {\ |
|||
$('input[name=fileOrUrl]').val(data.node.id);\ |
|||
\ |
|||
if (data.node.type == \"folder\") {\ |
|||
$('.option-folder').show();\ |
|||
$('.option-file').hide();\ |
|||
$('#playMode option').removeAttr('selected').filter('[value=3]').attr('selected', true);\ |
|||
}\ |
|||
\ |
|||
if (data.node.type == \"audio\") {\ |
|||
$('.option-file').show();\ |
|||
$('.option-folder').hide();\ |
|||
$('#playMode option').removeAttr('selected').filter('[value=1]').attr('selected', true);\ |
|||
}\ |
|||
});\ |
|||
\ |
|||
$('#refreshAction').on(\"click\", function () {\ |
|||
refreshFileList();\ |
|||
$(\"#indexing-progress\").show();\ |
|||
$(\"#refreshAction\").hide();\ |
|||
});\ |
|||
\ |
|||
$('#playMode').on(\"change\", function () {\ |
|||
if (this.value == 8) {\ |
|||
$('#filebrowser').slideUp();\ |
|||
} else {\ |
|||
$('#filebrowser').slideDown();\ |
|||
}\ |
|||
});\ |
|||
\ |
|||
function showFileIndexingState() {\ |
|||
$(\"#indexing-progress\").show();\ |
|||
$(\"#refreshAction\").hide();\ |
|||
}\ |
|||
\ |
|||
function hideFileIndexingState() {\ |
|||
$(\"#indexing-progress\").hide();\ |
|||
$(\"#refreshAction\").show();\ |
|||
}\ |
|||
\ |
|||
var socket = undefined;\ |
|||
var tm;\ |
|||
\ |
|||
function connect() {\ |
|||
socket = new WebSocket(\"ws://\" + host + \"/ws\");\ |
|||
\ |
|||
socket.onopen = function () {\ |
|||
setInterval(ping, 15000);\ |
|||
};\ |
|||
\ |
|||
socket.onclose = function (e) {\ |
|||
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);\ |
|||
socket = null;\ |
|||
setTimeout(function () {\ |
|||
connect();\ |
|||
}, 5000);\ |
|||
};\ |
|||
\ |
|||
socket.onerror = function (err) {\ |
|||
console.error('Socket encountered error: ', err.message, 'Closing socket');\ |
|||
};\ |
|||
\ |
|||
socket.onmessage = function(event) {\ |
|||
console.log(event.data);\ |
|||
var socketMsg = JSON.parse(event.data);\ |
|||
if (socketMsg.rfidId != null) {\ |
|||
document.getElementById('rfidIdMod').value = socketMsg.rfidId;\ |
|||
document.getElementById('rfidIdMusic').value = socketMsg.rfidId;\ |
|||
toastr.info(\"RFID Tag mit \"+ socketMsg.rfidId + \" erkannt.\" );\ |
|||
\ |
|||
$(\"#rfidIdMusic\").effect(\"highlight\", {color:\"#abf5af\"}, 3000);\ |
|||
$(\"#rfidIdMod\").effect(\"highlight\", {color:\"#abf5af\"}, 3000);\ |
|||
\ |
|||
} if (\"status\" in socketMsg) {\ |
|||
if (socketMsg.status == \"ok\") {\ |
|||
toastr.success(\"Aktion erfolgreich ausgeführt.\" );\ |
|||
}\ |
|||
} if (\"pong\" in socketMsg) {\ |
|||
if (socketMsg.pong == 'pong') {\ |
|||
pong();\ |
|||
}\ |
|||
} if (\"refreshFileList\" in socketMsg) {\ |
|||
hideFileIndexingState();\ |
|||
toastr.info(\"Die Dateiliste wurde neu erzeugt!\");\ |
|||
$('#filetree').jstree(true).refresh();\ |
|||
\ |
|||
}\ |
|||
if (\"indexingState\" in socketMsg) {\ |
|||
if(socketMsg.indexingState != null) {\ |
|||
$(\"#currentProcessedFile\").text(socketMsg.indexingState);\ |
|||
console.log(socketMsg.indexingState);\ |
|||
}\ |
|||
}\ |
|||
};\ |
|||
}\ |
|||
\ |
|||
function ping() {\ |
|||
var myObj = {\ |
|||
\"ping\": {\ |
|||
ping: 'ping'\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
tm = setTimeout(function () {\ |
|||
toastr.warning('Die Verbindung zum Tonuino ist unterbrochen! Bitte Seite neu laden.');\ |
|||
}, 5000);\ |
|||
}\ |
|||
\ |
|||
function pong() {\ |
|||
clearTimeout(tm);\ |
|||
}\ |
|||
\ |
|||
function refreshFileList(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"refreshFileList\": true\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
$(\"#refreshAction\").hide();\ |
|||
socket.send(myJSON);\ |
|||
showFileIndexingState();\ |
|||
};\ |
|||
\ |
|||
function genSettings(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"general\": {\ |
|||
iVol: document.getElementById('initialVolume').value,\ |
|||
mVolSpeaker: document.getElementById('maxVolumeSpeaker').value,\ |
|||
mVolHeadphone: document.getElementById('maxVolumeHeadphone').value,\ |
|||
iBright: document.getElementById('initBrightness').value,\ |
|||
nBright: document.getElementById('nightBrightness').value,\ |
|||
iTime: document.getElementById('inactivityTime').value,\ |
|||
vWarning: document.getElementById('warningLowVoltage').value,\ |
|||
vIndLow: document.getElementById('voltageIndicatorLow').value,\ |
|||
vIndHi: document.getElementById('voltageIndicatorHigh').value,\ |
|||
vInt: document.getElementById('voltageCheckInterval').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function ftpSettings(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"ftp\": {\ |
|||
ftpUser: document.getElementById('ftpUser').value,\ |
|||
ftpPwd: document.getElementById('ftpPwd').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function mqttSettings(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var val;\ |
|||
if (document.getElementById('mqttEnable').checked) {\ |
|||
val = document.getElementById('mqttEnable').value;\ |
|||
} else {\ |
|||
val = 0;\ |
|||
}\ |
|||
var myObj = {\ |
|||
\"mqtt\": {\ |
|||
mqttEnable: val,\ |
|||
mqttServer: document.getElementById('mqttServer').value,\ |
|||
mqttUser: document.getElementById('mqttUser').value,\ |
|||
mqttPwd: document.getElementById('mqttPwd').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function rfidMods(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"rfidMod\": {\ |
|||
rfidIdMod: document.getElementById('rfidIdMod').value,\ |
|||
modId: document.getElementById('modId').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function removeTrSlash(str) {\ |
|||
if (str.substr(-1) === '/') {\ |
|||
return str.substr(0, str.length - 1);\ |
|||
}\ |
|||
return str;\ |
|||
}\ |
|||
\ |
|||
function rfidAssign(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"rfidAssign\": {\ |
|||
rfidIdMusic: document.getElementById('rfidIdMusic').value,\ |
|||
fileOrUrl: removeTrSlash(document.getElementById('fileOrUrl').value),\ |
|||
playMode: document.getElementById('playMode').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function wifiConfig(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"wifiConfig\": {\ |
|||
ssid: document.getElementById('ssid').value,\ |
|||
pwd: document.getElementById('pwd').value,\ |
|||
hostname: document.getElementById('hostname').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
$(document).ready(function () {\ |
|||
connect();\ |
|||
renderFileTree();\ |
|||
\ |
|||
console.log(parseInt(document.getElementById('warningLowVoltage').value));\ |
|||
$(function () {\ |
|||
$('[data-toggle=\"tooltip\"]').tooltip();\ |
|||
});\ |
|||
\ |
|||
});\ |
|||
</script>\ |
|||
</body>\ |
|||
</html>\ |
|||
"; |
1058
src/main.cpp
File diff suppressed because it is too large
View File
@ -0,0 +1,66 @@ |
|||
#include "Arduino.h" |
|||
|
|||
//################## GPIO-configuration ############################## |
|||
#ifdef SD_MMC_1BIT_MODE |
|||
#define SPISD_CS 15 // GPIO for chip select (SD) |
|||
// uSD-card-reader (via SD-MMC 1Bit) |
|||
// |
|||
// SD_MMC uses fixed pins |
|||
// MOSI 15 |
|||
// SCKK 14 |
|||
// MISO 2 // hardware pullup may required |
|||
#else |
|||
// uSD-card-reader (via SPI) |
|||
#define SPISD_CS 15 // GPIO for chip select (SD) |
|||
#ifndef SINGLE_SPI_ENABLE |
|||
#define SPISD_MOSI 13 // GPIO for master out slave in (SD) => not necessary for single-SPI |
|||
#define SPISD_MISO 16 // GPIO for master in slave ou (SD) => not necessary for single-SPI |
|||
#define SPISD_SCK 14 // GPIO for clock-signal (SD) => not necessary for single-SPI |
|||
#endif |
|||
#endif |
|||
|
|||
|
|||
#define MFRC522_RST_PIN 12 // needed for i2c-comm MTDI on JTAG |
|||
#define MFRC522_ADDR 0x28 // default Address of MFRC522 |
|||
#define ext_IIC_CLK 23 // 14-pin-header |
|||
#define ext_IIC_DATA 18 // 14-pin-header |
|||
|
|||
// I2S (DAC) |
|||
#define I2S_DOUT 25 // Digital out (I2S) |
|||
#define I2S_BCLK 27 // BCLK (I2S) |
|||
#define I2S_LRC 26 // LRC (I2S) |
|||
|
|||
// I2C (AC101) |
|||
#define IIC_CLK 32 // internal |
|||
#define IIC_DATA 33 // internal |
|||
|
|||
// Amp enable |
|||
#define GPIO_PA_EN GPIO_NUM_21 // internal |
|||
#define GPIO_SEL_PA_EN GPIO_SEL_21 |
|||
|
|||
// Rotary encoder |
|||
#define DREHENCODER_CLK 5 // If you want to reverse encoder's direction, just switch GPIOs of CLK with DT (in software or hardware) |
|||
#define DREHENCODER_DT 18 // Info: Lolin D32 / Lolin D32 pro 35 are using 35 for battery-voltage-monitoring! |
|||
#define DREHENCODER_BUTTON 4 // Button is used to switch Tonuino on and off |
|||
|
|||
// Control-buttons |
|||
#define PAUSEPLAY_BUTTON 36 // GPIO to detect pause/play |
|||
#define NEXT_BUTTON 199 // GPIO to detect next |
|||
#define PREVIOUS_BUTTON 198 // GPIO to detect previous (Important: as of 19.11.2020 changed from 33 to 2) |
|||
|
|||
// Power-control |
|||
#define POWER 19 // GPIO used to drive transistor-circuit, that switches off peripheral devices while ESP32-deepsleep |
|||
|
|||
// (optional) Neopixel |
|||
#define LED_PIN 23 // GPIO for Neopixel-signaling |
|||
|
|||
// (optinal) Headphone-detection |
|||
#ifdef HEADPHONE_ADJUST_ENABLE |
|||
#define HP_DETECT 39 // GPIO that detects, if there's a plug in the headphone jack or not |
|||
#endif |
|||
|
|||
// (optional) Monitoring of battery-voltage via ADC |
|||
#ifdef MEASURE_BATTERY_VOLTAGE |
|||
#define VOLTAGE_READ_PIN 33 // GPIO used to monitor battery-voltage. Change to 35 if you're using Lolin D32 or Lolin D32 pro as it's hard-wired there! |
|||
#endif |
|||
|
@ -0,0 +1,61 @@ |
|||
#include "Arduino.h" |
|||
|
|||
//################## GPIO-configuration ############################## |
|||
#ifdef SD_MMC_1BIT_MODE |
|||
// uSD-card-reader (via SD-MMC 1Bit) |
|||
// |
|||
// SD_MMC uses fixed pins |
|||
// MOSI 15 |
|||
// SCKK 14 |
|||
// MISO 2 // hardware pullup may required |
|||
#else |
|||
// uSD-card-reader (via SPI) |
|||
#define SPISD_CS 15 // GPIO for chip select (SD) |
|||
#ifndef SINGLE_SPI_ENABLE |
|||
#define SPISD_MOSI 13 // GPIO for master out slave in (SD) => not necessary for single-SPI |
|||
#define SPISD_MISO 16 // GPIO for master in slave ou (SD) => not necessary for single-SPI |
|||
#define SPISD_SCK 14 // GPIO for clock-signal (SD) => not necessary for single-SPI |
|||
#endif |
|||
#endif |
|||
|
|||
// RFID (via SPI) |
|||
#define RST_PIN 99 // Not necessary but has to be set anyway; so let's use a dummy-number |
|||
#define RFID_CS 21 // GPIO for chip select (RFID) |
|||
#define RFID_MOSI 23 // GPIO for master out slave in (RFID) |
|||
#define RFID_MISO 19 // GPIO for master in slave out (RFID) |
|||
#define RFID_SCK 18 // GPIO for clock-signal (RFID) |
|||
|
|||
#ifdef RFID_READER_TYPE_PN5180 |
|||
#define RFID_BUSY 16 // PN5180 BUSY PIN |
|||
#define RFID_RST 22 // PN5180 RESET PIN |
|||
#endif |
|||
// I2S (DAC) |
|||
#define I2S_DOUT 25 // Digital out (I2S) |
|||
#define I2S_BCLK 27 // BCLK (I2S) |
|||
#define I2S_LRC 26 // LRC (I2S) |
|||
|
|||
// Rotary encoder |
|||
#define DREHENCODER_CLK 34 // If you want to reverse encoder's direction, just switch GPIOs of CLK with DT (in software or hardware) |
|||
#define DREHENCODER_DT 35 // Info: Lolin D32 / Lolin D32 pro 35 are using 35 for battery-voltage-monitoring! |
|||
#define DREHENCODER_BUTTON 32 // Button is used to switch Tonuino on and off |
|||
|
|||
// Control-buttons |
|||
#define PAUSEPLAY_BUTTON 5 // GPIO to detect pause/play |
|||
#define NEXT_BUTTON 4 // GPIO to detect next |
|||
#define PREVIOUS_BUTTON 2 // GPIO to detect previous (Important: as of 19.11.2020 changed from 33 to 2) |
|||
|
|||
// (optional) Power-control |
|||
#define POWER 17 // GPIO used to drive transistor-circuit, that switches off peripheral devices while ESP32-deepsleep |
|||
|
|||
// (optional) Neopixel |
|||
#define LED_PIN 12 // GPIO for Neopixel-signaling |
|||
|
|||
// (optinal) Headphone-detection |
|||
#ifdef HEADPHONE_ADJUST_ENABLE |
|||
#define HP_DETECT 22 // GPIO that detects, if there's a plug in the headphone jack or not |
|||
#endif |
|||
|
|||
// (optional) Monitoring of battery-voltage via ADC |
|||
#ifdef MEASURE_BATTERY_VOLTAGE |
|||
#define VOLTAGE_READ_PIN 33 // GPIO used to monitor battery-voltage. Change to 35 if you're using Lolin D32 or Lolin D32 pro as it's hard-wired there! |
|||
#endif |
@ -0,0 +1,117 @@ |
|||
#include "Arduino.h" |
|||
|
|||
//########################## MODULES ################################# |
|||
//#define MDNS_ENABLE // When enabled, you don't have to handle with Tonuino's IP-address. If hostname is set to "tonuino", you can reach it via tonuino.local |
|||
//#define MQTT_ENABLE // Make sure to configure mqtt-server and (optionally) username+pwd |
|||
//#define FTP_ENABLE // Enables FTP-server; DON'T FORGET TO ACTIVATE AFTER BOOT BY PRESSING PAUSE + NEXT-BUTTONS (IN PARALLEL)! |
|||
//#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 LANGUAGE 1 // 1 = deutsch; 2 = english |
|||
//#define HEADPHONE_ADJUST_ENABLE // Used to adjust (lower) volume for optional headphone-pcb (refer maxVolumeSpeaker / maxVolumeHeadphone) |
|||
#define SHUTDOWN_IF_SD_BOOT_FAILS // Will put ESP to deepsleep if boot fails due to SD. Really recommend this if there's in battery-mode no other way to restart ESP! Interval adjustable via deepsleepTimeAfterBootFails. |
|||
//#define MEASURE_BATTERY_VOLTAGE // Enables battery-measurement via GPIO (ADC) and voltage-divider |
|||
//#define PLAY_LAST_RFID_AFTER_REBOOT // When restarting Tonuino, the last RFID that was active before, is recalled and played |
|||
|
|||
//#define BLUETOOTH_ENABLE // Doesn't work currently (so don't enable) as there's not enough DRAM available |
|||
|
|||
//################## select SD card mode ############################# |
|||
#define SD_MMC_1BIT_MODE // run SD card in SD-MMC 1Bit mode |
|||
#define SINGLE_SPI_ENABLE // If only one SPI-instance should be used instead of two (not yet working!) (Works on ESP32-A1S with RFID via I2C) |
|||
|
|||
//################## select RFID reader ############################## |
|||
//#define RFID_READER_TYPE_MFRC522_SPI // use MFRC522 via SPI |
|||
#define RFID_READER_TYPE_MFRC522_I2C // use MFRC522 via I2C |
|||
//#define RFID_READER_TYPE_PN5180 |
|||
|
|||
//################## select Hardware Platform ############################## |
|||
// #define HAL 2 // HAL 1 = LoLin32, 2 = AI AudioKit - no need to define when using platformIO BuildProcess |
|||
|
|||
|
|||
//#################### Various settings ############################## |
|||
// Loglevels available (don't change!) |
|||
#define LOGLEVEL_ERROR 1 // only errors |
|||
#define LOGLEVEL_NOTICE 2 // errors + important messages |
|||
#define LOGLEVEL_INFO 3 // infos + errors + important messages |
|||
#define LOGLEVEL_DEBUG 4 // almost everything |
|||
|
|||
// Serial-logging-configuration |
|||
const uint8_t serialDebug = LOGLEVEL_DEBUG; // Current loglevel for serial console |
|||
|
|||
// Buttons (better leave unchanged if in doubts :-)) |
|||
uint8_t buttonDebounceInterval = 50; // Interval in ms to software-debounce buttons |
|||
uint16_t intervalToLongPress = 700; // Interval in ms to distinguish between short and long press of previous/next-button |
|||
|
|||
// RFID |
|||
#define RFID_SCAN_INTERVAL 300 // Interval-time in ms (how often is RFID read?) |
|||
|
|||
// Automatic restart |
|||
#ifdef SHUTDOWN_IF_SD_BOOT_FAILS |
|||
uint32_t deepsleepTimeAfterBootFails = 20; // Automatic restart takes place if boot was not successful after this period (in seconds) |
|||
#endif |
|||
|
|||
// FTP |
|||
// Nothing to be configured here... |
|||
// Default user/password is esp32/esp32 but can be changed via webgui |
|||
|
|||
// Tonuino will create a WiFi if joing existing WiFi was not possible. Name can be configured here. |
|||
static const char accessPointNetworkSSID[] PROGMEM = "Tonuino"; // Access-point's SSID |
|||
|
|||
// Where to store the backup-file for NVS-records |
|||
static const char backupFile[] PROGMEM = "/backup.txt"; // File is written every time a (new) RFID-assignment via GUI is done |
|||
|
|||
// (webgui) File Browser |
|||
uint8_t FS_DEPTH = 5; // Max. recursion-depth of file tree |
|||
const char *DIRECTORY_INDEX_FILE = "/files.json"; // Filename of files.json index file |
|||
|
|||
//#################### Settings for optional Modules############################## |
|||
// (optinal) Neopixel |
|||
#ifdef NEOPIXEL_ENABLE |
|||
#define NUM_LEDS 24 // number of LEDs |
|||
#define CHIPSET WS2812B // type of Neopixel |
|||
#define COLOR_ORDER GRB |
|||
#endif |
|||
|
|||
// (optional) Default-voltages for battery-monitoring via Neopixel |
|||
float warningLowVoltage = 3.4; // If battery-voltage is >= this value, a cyclic warning will be indicated by Neopixel (can be changed via GUI!) |
|||
uint8_t voltageCheckInterval = 10; // How of battery-voltage is measured (in minutes) (can be changed via GUI!) |
|||
float voltageIndicatorLow = 3.0; // Lower range for Neopixel-voltage-indication (0 leds) (can be changed via GUI!) |
|||
float voltageIndicatorHigh = 4.2; // Upper range for Neopixel-voltage-indication (all leds) (can be changed via GUI!) |
|||
|
|||
// (optinal) For measuring battery-voltage a voltage-divider is necessary. Their values need to be configured here. |
|||
#ifdef MEASURE_BATTERY_VOLTAGE |
|||
uint8_t rdiv1 = 129; // Rdiv1 of voltage-divider (kOhms) (measure exact value with multimeter!) |
|||
uint16_t rdiv2 = 389; // Rdiv2 of voltage-divider (kOhms) (measure exact value with multimeter!) => used to measure voltage via ADC! |
|||
#endif |
|||
|
|||
// (optinal) Headphone-detection (leave unchanged if in doubts...) |
|||
#ifdef HEADPHONE_ADJUST_ENABLE |
|||
uint16_t headphoneLastDetectionDebounce = 1000; // Debounce-interval in ms when plugging in headphone |
|||
#endif |
|||
|
|||
// (optional) Topics for MQTT |
|||
#ifdef MQTT_ENABLE |
|||
uint16_t mqttRetryInterval = 15; // Try to reconnect to MQTT-server every (n) seconds if connection is broken |
|||
uint8_t mqttMaxRetriesPerInterval = 1; // Number of retries per time-interval (mqttRetryInterval). mqttRetryInterval 15 / mqttMaxRetriesPerInterval 1 => once every 15s |
|||
#define DEVICE_HOSTNAME "ESP32-Tonuino" // Name that that is used for MQTT |
|||
static const char topicSleepCmnd[] PROGMEM = "Cmnd/Tonuino/Sleep"; |
|||
static const char topicSleepState[] PROGMEM = "State/Tonuino/Sleep"; |
|||
static const char topicTrackCmnd[] PROGMEM = "Cmnd/Tonuino/Track"; |
|||
static const char topicTrackState[] PROGMEM = "State/Tonuino/Track"; |
|||
static const char topicTrackControlCmnd[] PROGMEM = "Cmnd/Tonuino/TrackControl"; |
|||
static const char topicLoudnessCmnd[] PROGMEM = "Cmnd/Tonuino/Loudness"; |
|||
static const char topicLoudnessState[] PROGMEM = "State/Tonuino/Loudness"; |
|||
static const char topicSleepTimerCmnd[] PROGMEM = "Cmnd/Tonuino/SleepTimer"; |
|||
static const char topicSleepTimerState[] PROGMEM = "State/Tonuino/SleepTimer"; |
|||
static const char topicState[] PROGMEM = "State/Tonuino/State"; |
|||
static const char topicCurrentIPv4IP[] PROGMEM = "State/Tonuino/IPv4"; |
|||
static const char topicLockControlsCmnd[] PROGMEM ="Cmnd/Tonuino/LockControls"; |
|||
static const char topicLockControlsState[] PROGMEM ="State/Tonuino/LockControls"; |
|||
static const char topicPlaymodeState[] PROGMEM = "State/Tonuino/Playmode"; |
|||
static const char topicRepeatModeCmnd[] PROGMEM = "Cmnd/Tonuino/RepeatMode"; |
|||
static const char topicRepeatModeState[] PROGMEM = "State/Tonuino/RepeatMode"; |
|||
static const char topicLedBrightnessCmnd[] PROGMEM = "Cmnd/Tonuino/LedBrightness"; |
|||
static const char topicLedBrightnessState[] PROGMEM = "State/Tonuino/LedBrightness"; |
|||
#ifdef MEASURE_BATTERY_VOLTAGE |
|||
static const char topicBatteryVoltage[] PROGMEM = "State/Tonuino/Voltage"; |
|||
#endif |
|||
#endif |
@ -1,24 +0,0 @@ |
|||
static const char basicWebsite[] PROGMEM = "<!DOCTYPE html>\ |
|||
<html>\ |
|||
<head>\ |
|||
<title>WLAN-Einrichtung</title>\ |
|||
</head>\ |
|||
<body>\ |
|||
<form action=\"/init\" method=\"POST\">\ |
|||
<fieldset>\ |
|||
<legend>Initiale WLAN-Einrichtung</legend>\ |
|||
<label for=\"ssid\">SSID:</label><br>\ |
|||
<input type=\"text\" id=\"ssid\" name=\"ssid\" placeholder=\"SSID\" required><br>\ |
|||
<label for=\"pwd\">Passwort:</label><br>\ |
|||
<input type=\"password\" id=\"pwd\" name=\"pwd\" autocomplete=\"off\" required><br>\ |
|||
<label for=\"hostname\">Tonuino-Name (Hostname):</label><br>\ |
|||
<input type=\"text\" id=\"hostname\" name=\"hostname\" required><br><br>\ |
|||
<input type=\"submit\" value=\"Absenden\">\ |
|||
</fieldset>\ |
|||
</form>\ |
|||
<form action=\"/restart\">\ |
|||
<button type=\"submit\">Neustart</button>\ |
|||
</form>\ |
|||
</body>\ |
|||
</html>\ |
|||
"; |
@ -1,360 +0,0 @@ |
|||
static const char mgtWebsite[] PROGMEM = "<!DOCTYPE html>\ |
|||
<html lang=\"de\">\ |
|||
<head>\ |
|||
<title>ESPuino-Konfiguration</title>\ |
|||
<meta charset=\"utf-8\">\ |
|||
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\ |
|||
<link rel=\"stylesheet\" href=\"https://ts-cs.de/tonuino/css/bootstrap.min.css\">\ |
|||
<script src=\"https://ts-cs.de/tonuino/js/jquery.min.js\"></script>\ |
|||
<script src=\"https://ts-cs.de/tonuino/js/popper.min.js\"></script>\ |
|||
<script src=\"https://ts-cs.de/tonuino/js/bootstrap.min.js\"></script>\ |
|||
</head>\ |
|||
<body>\ |
|||
<nav class=\"navbar navbar-expand-sm bg-primary navbar-dark\">\ |
|||
<button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\"#navbarSupportedContent\" aria-controls=\"navbarSupportedContent\" aria-expanded=\"false\" aria-label=\"Toggle navigation\">\ |
|||
<span class=\"navbar-toggler-icon\"></span>\ |
|||
</button>\ |
|||
<a class=\"navbar-brand\">\ |
|||
<img src=\"https://raw.githubusercontent.com/biologist79/Tonuino-ESP32-I2S/master/html/tonuino_logo.png\" width=\"30\" height=\"30\" class=\"d-inline-block align-top\" alt=\"\" />\ |
|||
Tonuino\ |
|||
</a>\ |
|||
<div class=\"collapse navbar-collapse\" id=\"collapsibleNavbar\">\ |
|||
<ul class=\"navbar-nav mr-auto\">\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#wifiConfig\">WLAN</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#rfidMusicTags\">RFID-Zuweisungen</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#rfidModTags\">RFID-Modifikationen</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#mqttConfig\">MQTT</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#ftpConfig\">FTP</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#generalConfig\">Allgemein</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"#importNvs\">NVS-Importer</a>\ |
|||
</li>\ |
|||
<li class=\"nav-item\">\ |
|||
<a class=\"nav-link\" href=\"/restart\" style=\"color: orange\">Neustart Tonuino</a>\ |
|||
</li>\ |
|||
</ul>\ |
|||
</div>\ |
|||
</nav>\ |
|||
<br />\ |
|||
<div class=\"container\" id=\"wifiConfig\">\ |
|||
<h2>WLAN-Konfiguration</h2>\ |
|||
<form action=\"#wifiConfig\" method=\"POST\" onsubmit=\"wifiConfig('wifiConfig'); return false\">\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"ssid\">WLAN-Name (SSID):</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"ssid\" placeholder=\"SSID\" name=\"ssid\" required>\ |
|||
<div class=\"invalid-feedback\">\ |
|||
Bitte SSID des WLANs eintragen.\ |
|||
</div>\ |
|||
<label for=\"pwd\">Passwort:</label>\ |
|||
<input type=\"password\" class=\"form-control\" id=\"pwd\" placeholder=\"Passwort\" name=\"pwd\" required>\ |
|||
<label for=\"hostname\">Tonuino-Name (Hostname):</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"hostname\" placeholder=\"tonuino\" name=\"hostname\" value=\"%HOSTNAME%\" pattern=\"^[^-\\.]{2,32}\" required>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</form>\ |
|||
<div class=\"messages col-md-6 my-2\"></div>\ |
|||
</div>\ |
|||
<div class=\"container my-5\" id=\"rfidMusicTags\">\ |
|||
<h2>RFID-Zuweisungen</h2>\ |
|||
<form action=\"#rfidMusicTags\" method=\"POST\" onsubmit=\"rfidAssign('rfidMusicTags'); return false\">\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"rfidIdMusic\">RFID-Chip-Nummer (12-stellig)</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"rfidIdMusic\" maxlength=\"12\" pattern=\"[0-9]{12}\" placeholder=\"%RFID_TAG_ID%\" name=\"rfidIdMusic\" required>\ |
|||
<label for=\"fileOrUrl\">Datei, Verzeichnis oder URL (^ und # als Zeichen nicht erlaubt)</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"fileOrUrl\" maxlength=\"255\" placeholder=\"z.B. /mp3/Hoerspiele/Yakari/Yakari_und_seine_Freunde.mp3\" pattern=\"^[^\\^#]+$\" name=\"fileOrUrl\" required>\ |
|||
<label for=\"playMode\">Abspielmodus</label>\ |
|||
<select class=\"form-control\" id=\"playMode\" name=\"playMode\">\ |
|||
<option value=\"1\">Einzelner Titel</option>\ |
|||
<option value=\"2\">Einzelner Titel (Endlosschleife)</option>\ |
|||
<option value=\"3\">Hörbuch</option>\ |
|||
<option value=\"4\">Hörbuch (Endlosschleife)</option>\ |
|||
<option value=\"5\">Alle Titel eines Verzeichnis (sortiert)</option>\ |
|||
<option value=\"6\">Alle Titel eines Verzeichnis (zufällig)</option>\ |
|||
<option value=\"7\">Alle Titel eines Verzeichnis (sortiert, Endlosschleife)</option>\ |
|||
<option value=\"9\">Alle Titel eines Verzeichnis (zufällig, Endlosschleife)</option>\ |
|||
<option value=\"8\">Webradio</option>\ |
|||
</select>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</form>\ |
|||
<div class=\"messages col-md-6 my-2\"></div>\ |
|||
</div>\ |
|||
<div class=\"container my-5\" id=\"rfidModTags\">\ |
|||
<h2>RFID-Modifkationen</h2>\ |
|||
<form class=\"needs-validation\" action=\"#rfidModTags\" method=\"POST\" onsubmit=\"rfidMods('rfidModTags'); return false\">\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"rfidIdMod\">RFID-Chip-Nummer (12-stellig)</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"rfidIdMod\" maxlength=\"12\" pattern=\"[0-9]{12}\" placeholder=\"%RFID_TAG_ID%\" name=\"rfidIdMod\" required>\ |
|||
<div class=\"invalid-feedback\">\ |
|||
Bitte eine 12-stellige Zahl eingeben.\ |
|||
</div>\ |
|||
<label for=\"modId\">Abspielmodus</label>\ |
|||
<select class=\"form-control\" id=\"modId\" name=\"modId\">\ |
|||
<option value=\"100\">Tastensperre</option>\ |
|||
<option value=\"101\">Schlafen nach 15 Minuten</option>\ |
|||
<option value=\"102\">Schlafen nach 30 Minuten</option>\ |
|||
<option value=\"103\">Schlafen nach 1 Stunde</option>\ |
|||
<option value=\"104\">Schlafen nach 2 Stunden</option>\ |
|||
<option value=\"105\">Schlafen nach Ende des Titels</option>\ |
|||
<option value=\"106\">Schlafen nach Ende der Playlist</option>\ |
|||
<option value=\"107\">Schlafen nach fünf Titeln</option>\ |
|||
<option value=\"110\">Wiederhole Playlist (endlos)</option>\ |
|||
<option value=\"111\">Wiederhole Titel (endlos)</option>\ |
|||
<option value=\"112\">Dimme LEDs (Nachtmodus)</option>\ |
|||
<option value=\"130\">Aktiviere/deaktive WLAN</option>\ |
|||
</select>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</form>\ |
|||
<div class=\"messages col-md-6 my-2\"></div>\ |
|||
</div>\ |
|||
<div class=\"container my-5\" id=\"mqttConfig\">\ |
|||
<h2>MQTT-Konfiguration</h2>\ |
|||
<form class=\"needs-validation\" action=\"#mqttConfig\" method=\"POST\" onsubmit=\"mqttSettings('mqttConfig'); return false\">\ |
|||
<div class=\"form-check col-md-6\">\ |
|||
<input class=\"form-check-input\" type=\"checkbox\" value=\"1\" id=\"mqttEnable\" name=\"mqttEnable\" %MQTT_ENABLE%>\ |
|||
<label class=\"form-check-label\" for=\"mqttEnable\">\ |
|||
MQTT aktivieren\ |
|||
</label>\ |
|||
</div>\ |
|||
<div class=\"form-group my-2 col-md-6\">\ |
|||
<label for=\"mqttServer\">MQTT-Server</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"mqttServer\" minlength=\"7\" maxlength=\"%MQTT_SERVER_LENGTH%\" placeholder=\"z.B. 192.168.2.89\" name=\"mqttServer\" value=\"%MQTT_SERVER%\">\ |
|||
<label for=\"mqttUser\">MQTT-Benutzername (optional):</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"mqttUser\" maxlength=\"%MQTT_USER_LENGTH%\" placeholder=\"Benutzername\" name=\"mqttUser\" value=\"%MQTT_USER%\">\ |
|||
<label for=\"mqttPwd\">Passwort (optional):</label>\ |
|||
<input type=\"password\" class=\"form-control\" id=\"mqttPwd\" maxlength=\"%MQTT_PWD_LENGTH%\" placeholder=\"Passwort\" name=\"mqttPwd\" value=\"%MQTT_PWD%\">\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</form>\ |
|||
<div class=\"messages col-md-6 my-2\"></div>\ |
|||
</div>\ |
|||
<div class=\"container\" id=\"ftpConfig\">\ |
|||
<h2>FTP-Konfiguration</h2>\ |
|||
<form action=\"#ftpConfig\" method=\"POST\" onsubmit=\"ftpSettings('ftpConfig'); return false\">\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"ftpUser\">FTP-Benutzername:</label>\ |
|||
<input type=\"text\" class=\"form-control\" id=\"ftpUser\" maxlength=\"%FTP_USER_LENGTH%\" placeholder=\"Benutzername\" name=\"ftpUser\" value=\"%FTP_USER%\" required>\ |
|||
<label for=\"pwd\">Passwort:</label>\ |
|||
<input type=\"password\" class=\"form-control\" id=\"ftpPwd\" maxlength=\"%FTP_PWD_LENGTH%\" placeholder=\"Passwort\" name=\"ftpPwd\" value=\"%FTP_PWD%\" required>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</form>\ |
|||
<div class=\"messages col-md-6 my-2\"></div>\ |
|||
</div>\ |
|||
<div class=\"container my-5\" id=\"generalConfig\">\ |
|||
<h2>Allgemeine Konfiguration</h2>\ |
|||
<form action=\"#generalConfig\" method=\"POST\" onsubmit=\"genSettings('generalConfig'); return false\">\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"initialVolume\">Lautstärke nach dem Einschalten</label>\ |
|||
<input type=\"number\" min=\"1\" max=\"21\" class=\"form-control\" id=\"initialVolume\" name=\"initialVolume\" value=\"%INIT_VOLUME%\" required>\ |
|||
<label for=\"maxVolumeSpeaker\">Maximale Lautstärke (Lautsprecher)</label>\ |
|||
<input type=\"number\" min=\"1\" max=\"21\" class=\"form-control\" id=\"maxVolumeSpeaker\" name=\"maxVolumeSpeaker\" value=\"%MAX_VOLUME_SPEAKER%\" required>\ |
|||
<label for=\"maxVolumeHeadphone\">Maximale Lautstärke (Kopfhörer)</label>\ |
|||
<input type=\"number\" min=\"1\" max=\"21\" class=\"form-control\" id=\"maxVolumeHeadphone\" name=\"maxVolumeHeadphone\" value=\"%MAX_VOLUME_HEADPHONE%\" required>\ |
|||
</div>\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"initBrightness\">Neopixel-Helligkeit nach dem Einschalten</label>\ |
|||
<input type=\"number\" min=\"0\" max=\"255\" class=\"form-control\" id=\"initBrightness\" name=\"initBrightness\" value=\"%INIT_LED_BRIGHTNESS%\" required>\ |
|||
<label for=\"nightBrightness\">Neopixel-Helligkeit im Nachtmodus</label>\ |
|||
<input type=\"number\" min=\"0\" max=\"255\" class=\"form-control\" id=\"nightBrightness\" name=\"nightBrightness\" value=\"%NIGHT_LED_BRIGHTNESS%\" required>\ |
|||
</div>\ |
|||
<div class=\"form-group col-md-6\">\ |
|||
<label for=\"inactivityTime\">Deep-Sleep nach Inaktivität (Minuten)</label>\ |
|||
<input type=\"number\" min=\"1\" max=\"1440\" class=\"form-control\" id=\"inactivityTime\" name=\"inactivityTime\" value=\"%MAX_INACTIVITY%\" required>\ |
|||
</div>\ |
|||
<button type=\"reset\" class=\"btn btn-secondary\">Reset</button>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</form>\ |
|||
<div class=\"messages col-md-6 my-2\"></div>\ |
|||
</div>\ |
|||
<div class=\"container my-5\" id=\"importNvs\">\ |
|||
<h2>NVS-Importer</h2>\ |
|||
<form action=\"/upload\" enctype=\"multipart/form-data\" method=\"POST\">\ |
|||
<div class=\"form-group\">\ |
|||
<label for=\"nvsUpload\">Hier kann eine Backup-Datei importiert werden.</label>\ |
|||
<input type=\"file\" class=\"form-control-file\" id=\"nvsUpload\" name=\"nvsUpload\" accept=\".txt\">\ |
|||
</div>\ |
|||
<button type=\"submit\" class=\"btn btn-primary\">Absenden</button>\ |
|||
</form>\ |
|||
<div class=\"messages col-md-6 my-2\"></div>\ |
|||
</div>\ |
|||
<script>\ |
|||
var lastIdclicked = '';\ |
|||
var errorBox = '<div class=\"alert alert-danger alert-dismissible fade show\" role=\"alert\">Es ist ein Fehler aufgetreten!<button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-label=\"Close\"><span aria-hidden=\"true\">×</span></button></div>';\ |
|||
var okBox = '<div class=\"alert alert-success alert-dismissible fade show\" role=\"alert\">Aktion erfolgreich ausgeführt.<button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-label=\"Close\"><span aria-hidden=\"true\">×</span></button></div>';\ |
|||
\ |
|||
var socket = new WebSocket(\"ws://%IPv4%/ws\");\ |
|||
\ |
|||
function connect() {\ |
|||
socket = new WebSocket(\"ws://%IPv4%/ws\");\ |
|||
}\ |
|||
\ |
|||
function ping() {\ |
|||
var myObj = {\ |
|||
\"ping\": {\ |
|||
ping: 'ping'\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
tm = setTimeout(function () {\ |
|||
alert(\"Die Verbindung zum Tonuino ist unterbrochen!\\nBitte Seite neu laden.\");\ |
|||
}, 5000);\ |
|||
}\ |
|||
\ |
|||
function pong() {\ |
|||
clearTimeout(tm);\ |
|||
}\ |
|||
\ |
|||
socket.onopen = function () {\ |
|||
setInterval(ping, 15000);\ |
|||
};\ |
|||
\ |
|||
socket.onclose = function(e) {\ |
|||
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);\ |
|||
setTimeout(function() {\ |
|||
connect();\ |
|||
}, 5000);\ |
|||
};\ |
|||
\ |
|||
socket.onerror = function(err) {\ |
|||
console.error('Socket encountered error: ', err.message, 'Closing socket');\ |
|||
socket.close();\ |
|||
};\ |
|||
\ |
|||
socket.onmessage = function(event) {\ |
|||
console.log(event.data);\ |
|||
var socketMsg = JSON.parse(event.data);\ |
|||
if (socketMsg.rfidId != null) {\ |
|||
document.getElementById('rfidIdMod').value = socketMsg.rfidId;\ |
|||
document.getElementById('rfidIdMusic').value = socketMsg.rfidId;\ |
|||
$(\"#rfidIdMusic\").fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500);\ |
|||
$(\"#rfidIdMod\").fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500).fadeOut(500).fadeIn(500);\ |
|||
\ |
|||
} if (socketMsg.status != null) {\ |
|||
if (socketMsg.status == 'ok') {\ |
|||
$(\"#\" + lastIdclicked).find('.messages').html(okBox);\ |
|||
} else {\ |
|||
$(\"#\" + lastIdclicked).find('.messages').html(errorBox);\ |
|||
}\ |
|||
} if (socketMsg.pong != null) {\ |
|||
if (socketMsg.pong == 'pong') {\ |
|||
pong();\ |
|||
}\ |
|||
}\ |
|||
};\ |
|||
\ |
|||
function genSettings(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"general\": {\ |
|||
iVol: document.getElementById('initialVolume').value,\ |
|||
mVolSpeaker: document.getElementById('maxVolumeSpeaker').value,\ |
|||
mVolHeadphone: document.getElementById('maxVolumeHeadphone').value,\ |
|||
iBright: document.getElementById('initBrightness').value,\ |
|||
nBright: document.getElementById('nightBrightness').value,\ |
|||
iTime: document.getElementById('inactivityTime').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function ftpSettings(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"ftp\": {\ |
|||
ftpUser: document.getElementById('ftpUser').value,\ |
|||
ftpPwd: document.getElementById('ftpPwd').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function mqttSettings(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var val;\ |
|||
if (document.getElementById('mqttEnable').checked) {\ |
|||
val = document.getElementById('mqttEnable').value;\ |
|||
} else {\ |
|||
val = 0;\ |
|||
}\ |
|||
var myObj = {\ |
|||
\"mqtt\": {\ |
|||
mqttEnable: val,\ |
|||
mqttServer: document.getElementById('mqttServer').value,\ |
|||
mqttUser: document.getElementById('mqttUser').value,\ |
|||
mqttPwd: document.getElementById('mqttPwd').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function rfidMods(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"rfidMod\": {\ |
|||
rfidIdMod: document.getElementById('rfidIdMod').value,\ |
|||
modId: document.getElementById('modId').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function removeTrSlash(str) {\ |
|||
if(str.substr(-1) === '/') {\ |
|||
return str.substr(0, str.length - 1);\ |
|||
}\ |
|||
return str;\ |
|||
}\ |
|||
\ |
|||
function rfidAssign(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"rfidAssign\": {\ |
|||
rfidIdMusic: document.getElementById('rfidIdMusic').value,\ |
|||
fileOrUrl: removeTrSlash(document.getElementById('fileOrUrl').value),\ |
|||
playMode: document.getElementById('playMode').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
\ |
|||
function wifiConfig(clickedId) {\ |
|||
lastIdclicked = clickedId;\ |
|||
var myObj = {\ |
|||
\"wifiConfig\": {\ |
|||
ssid: document.getElementById('ssid').value,\ |
|||
pwd: document.getElementById('pwd').value,\ |
|||
hostname: document.getElementById('hostname').value\ |
|||
}\ |
|||
};\ |
|||
var myJSON = JSON.stringify(myObj);\ |
|||
socket.send(myJSON);\ |
|||
}\ |
|||
</script>\ |
|||
</body>\ |
|||
</html>\ |
|||
"; |