mirror of
https://github.com/Crocmagnon/buzzer.git
synced 2024-11-24 00:48:03 +01:00
Refactor & split into multiple files
This commit is contained in:
parent
30e46ebfab
commit
a9ca2150d4
10 changed files with 536 additions and 339 deletions
11
src/config.cpp
Normal file
11
src/config.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <Adafruit_SSD1306.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <Audio.h>
|
||||
#include <Preferences.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||
AsyncWebServer server(80);
|
||||
Audio audio;
|
||||
Preferences preferences;
|
56
src/config.h
Normal file
56
src/config.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
// Uncomment to switch to AP mode.
|
||||
// Leave commented for wifi station mode.
|
||||
// #define B_WIFI_AP
|
||||
|
||||
// DAC
|
||||
#define I2S_DOUT 32
|
||||
#define I2S_BCLK 25
|
||||
#define I2S_LRC 27
|
||||
|
||||
// SD CARD
|
||||
#define SPI_MISO 18
|
||||
#define SPI_MOSI 19
|
||||
#define SPI_SCK 23
|
||||
#define SD_CS 5
|
||||
|
||||
// GPIO
|
||||
#define LED 2
|
||||
#define BUTTON 33
|
||||
|
||||
// Screen
|
||||
#define SSD1306_NO_SPLASH
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 64
|
||||
#define OLED_RESET -1
|
||||
#define SCREEN_ADDRESS 0x3C
|
||||
|
||||
#define SCREEN_MSG_X 0
|
||||
#define SCREEN_MSG_Y 24
|
||||
|
||||
#define LINE_LENGTH 21
|
||||
|
||||
// Volume
|
||||
#define VOLUME_MIN 0
|
||||
#define VOLUME_MAX 21
|
||||
|
||||
// Preference keys
|
||||
#define SELECTED_FILE "selectedFile"
|
||||
#define CURRENT_VOLUME "currentVolume"
|
||||
#define WIFI_IP "wifiIP"
|
||||
#define WIFI_SSID "wifiSSID"
|
||||
#define WIFI_PASSWORD "wifiPassword"
|
||||
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <Audio.h>
|
||||
#include <Preferences.h>
|
||||
|
||||
extern Adafruit_SSD1306 display;
|
||||
extern AsyncWebServer server;
|
||||
extern Audio audio;
|
||||
extern Preferences preferences;
|
||||
|
||||
#endif
|
|
@ -1,3 +1,6 @@
|
|||
// Copy to creds.h or creds_ap.h and edit
|
||||
#ifndef __CREDS_H__
|
||||
#define __CREDS_H__
|
||||
const char *ssid = "buzzer";
|
||||
const char *password = "123456789";
|
||||
#endif
|
||||
|
|
360
src/main.cpp
360
src/main.cpp
|
@ -1,361 +1,43 @@
|
|||
#include <Arduino.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <SPIFFS.h>
|
||||
#include <AsyncJson.h>
|
||||
#include <Audio.h>
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <Audio.h>
|
||||
#include <Preferences.h>
|
||||
#include <AsyncElegantOTA.h>
|
||||
|
||||
// Toggle on to switch to AP mode.
|
||||
// Leave commented for wifi station mode.
|
||||
// #define B_WIFI_AP
|
||||
|
||||
#ifdef B_WIFI_AP
|
||||
#include "creds_ap.h"
|
||||
#else
|
||||
#include "creds.h"
|
||||
#endif
|
||||
|
||||
// DAC
|
||||
#define I2S_DOUT 32
|
||||
#define I2S_BCLK 25
|
||||
#define I2S_LRC 27
|
||||
|
||||
// SD CARD
|
||||
#define SPI_MISO 18
|
||||
#define SPI_MOSI 19
|
||||
#define SPI_SCK 23
|
||||
#define SD_CS 5
|
||||
|
||||
#define LED 2
|
||||
#define BUTTON 33
|
||||
|
||||
#define SSD1306_NO_SPLASH
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 64
|
||||
#define OLED_RESET -1
|
||||
#define SCREEN_ADDRESS 0x3C
|
||||
|
||||
#define SCREEN_MSG_X 0
|
||||
#define SCREEN_MSG_Y 24
|
||||
|
||||
#define VOLUME_MIN 0
|
||||
#define VOLUME_MAX 21
|
||||
|
||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||
|
||||
String selectedFile = "";
|
||||
|
||||
AsyncWebServer server(80);
|
||||
Audio audio;
|
||||
Preferences preferences;
|
||||
#include "setup.h"
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
|
||||
byte buttonLastState = HIGH;
|
||||
byte currentVolume = 12;
|
||||
|
||||
bool fileIsValid(String fileName)
|
||||
{
|
||||
return !fileName.startsWith(".") && (fileName.endsWith(".mp3") || fileName.endsWith(".wav"));
|
||||
}
|
||||
|
||||
void clearMessageArea()
|
||||
{
|
||||
display.fillRect(SCREEN_MSG_X, SCREEN_MSG_Y, SCREEN_WIDTH - SCREEN_MSG_X, SCREEN_HEIGHT - SCREEN_MSG_Y, BLACK);
|
||||
display.setCursor(SCREEN_MSG_X, SCREEN_MSG_Y);
|
||||
}
|
||||
|
||||
void displayText(String text)
|
||||
{
|
||||
clearMessageArea();
|
||||
display.println(text);
|
||||
display.display();
|
||||
}
|
||||
|
||||
void play()
|
||||
{
|
||||
String path = "/" + selectedFile;
|
||||
Serial.println("Playing file: " + path);
|
||||
audio.stopSong();
|
||||
audio.connecttoFS(SD, path.c_str());
|
||||
}
|
||||
|
||||
void onStop(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println("Stop playing");
|
||||
audio.stopSong();
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void onPlay(AsyncWebServerRequest *request)
|
||||
{
|
||||
play();
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void onStatus(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println("Status");
|
||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||
|
||||
StaticJsonDocument<96> root;
|
||||
root["files"]["selected"] = selectedFile.c_str();
|
||||
|
||||
JsonObject volume = root.createNestedObject("volume");
|
||||
volume["current"] = currentVolume;
|
||||
volume["canDecrease"] = currentVolume > 0;
|
||||
volume["canIncrease"] = currentVolume < 21;
|
||||
|
||||
serializeJson(root, *response);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void onListFiles(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.print("List files cursor=");
|
||||
int cursor = 0;
|
||||
if (request->hasParam("cursor")) {
|
||||
String s_cursor = request->getParam("cursor")->value();
|
||||
cursor = s_cursor.toInt();
|
||||
}
|
||||
Serial.println(cursor);
|
||||
|
||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||
|
||||
StaticJsonDocument<512> root;
|
||||
root["next"] = -1;
|
||||
JsonArray files = root.createNestedArray("files");
|
||||
File music = SD.open("/");
|
||||
File file = music.openNextFile();
|
||||
int index = 0;
|
||||
while (file)
|
||||
{
|
||||
String fileName = file.name();
|
||||
if (fileIsValid(fileName))
|
||||
{
|
||||
index++;
|
||||
if (index >= cursor)
|
||||
files.add(fileName);
|
||||
}
|
||||
file.close();
|
||||
|
||||
if (root.overflowed())
|
||||
{
|
||||
root["next"] = index;
|
||||
break;
|
||||
}
|
||||
file = music.openNextFile();
|
||||
}
|
||||
if (root["next"] == -1) {
|
||||
root.remove("next");
|
||||
}
|
||||
|
||||
serializeJson(root, *response);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void onSelectFile(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.print("Select file: ");
|
||||
if (request->hasParam("fileName", true))
|
||||
{
|
||||
selectedFile = request->getParam("fileName", true)->value();
|
||||
preferences.putString("selectedFile", selectedFile);
|
||||
Serial.print(selectedFile);
|
||||
displayText("Selectionne : " + selectedFile);
|
||||
}
|
||||
Serial.println();
|
||||
onStatus(request);
|
||||
}
|
||||
|
||||
void onChangeVolume(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.print("Volume: ");
|
||||
if (request->hasParam("modifier", true))
|
||||
{
|
||||
String s_modifier = request->getParam("modifier", true)->value();
|
||||
int modifier = s_modifier.toInt();
|
||||
currentVolume += modifier;
|
||||
if (currentVolume > VOLUME_MAX)
|
||||
currentVolume = VOLUME_MAX;
|
||||
else if (currentVolume < VOLUME_MIN)
|
||||
currentVolume = VOLUME_MIN;
|
||||
preferences.putUChar("currentVolume", currentVolume);
|
||||
audio.setVolume(currentVolume);
|
||||
Serial.print(currentVolume);
|
||||
clearMessageArea();
|
||||
display.print("Volume : ");
|
||||
display.println(currentVolume);
|
||||
display.display();
|
||||
}
|
||||
Serial.println();
|
||||
onStatus(request);
|
||||
}
|
||||
|
||||
void onUpload(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println("onUpload");
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void onUploadFile(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)
|
||||
{
|
||||
if (!index)
|
||||
{
|
||||
Serial.printf("UploadStart: %s\n", filename.c_str());
|
||||
String filePath = "/" + filename;
|
||||
request->_tempFile = SD.open(filePath, FILE_WRITE);
|
||||
}
|
||||
if (!request->_tempFile)
|
||||
{
|
||||
Serial.println("Couldn't open file.");
|
||||
request->redirect("/");
|
||||
return;
|
||||
}
|
||||
if (len)
|
||||
{
|
||||
request->_tempFile.write(data, len);
|
||||
}
|
||||
|
||||
if (final)
|
||||
{
|
||||
Serial.printf("UploadEnd: %s, %u B\n", filename.c_str(), index + len);
|
||||
request->_tempFile.close();
|
||||
request->redirect("/");
|
||||
}
|
||||
}
|
||||
|
||||
void onNotFound(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println("not found");
|
||||
request->send(400);
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Setup serial
|
||||
Serial.begin(115200);
|
||||
// Setup GPIO
|
||||
pinMode(LED, OUTPUT);
|
||||
digitalWrite(LED, LOW);
|
||||
|
||||
preferences.begin("buzzer", false);
|
||||
|
||||
// Screen
|
||||
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
|
||||
{
|
||||
Serial.println("Display init failed");
|
||||
while (true);
|
||||
}
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(WHITE, BLACK);
|
||||
display.setCursor(0, 0);
|
||||
display.println("Chargement...");
|
||||
display.display();
|
||||
|
||||
pinMode(BUTTON, INPUT_PULLUP);
|
||||
buttonLastState = digitalRead(BUTTON);
|
||||
|
||||
// Setup SPIFFS
|
||||
if (!SPIFFS.begin())
|
||||
{
|
||||
Serial.println("SPIFFS error. Exiting.");
|
||||
display.println("Impossible d'acceder aux fichiers...");
|
||||
display.display();
|
||||
while (true);
|
||||
}
|
||||
Serial.begin(115200);
|
||||
Serial.println("Serial... OK");
|
||||
|
||||
pinMode(SD_CS, OUTPUT);
|
||||
digitalWrite(SD_CS, HIGH);
|
||||
SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||
preferences.begin("buzzer", false);
|
||||
Serial.println("Preferences... OK");
|
||||
|
||||
if (!SD.begin(SD_CS))
|
||||
{
|
||||
Serial.println("Error talking to SD card!");
|
||||
display.println("Impossible d'acceder a la carte SD...");
|
||||
display.display();
|
||||
while (true);
|
||||
}
|
||||
setupScreen();
|
||||
setupSPIFFS();
|
||||
setupSDCard();
|
||||
setupAudio();
|
||||
selectDefaultFile();
|
||||
setupWifi();
|
||||
setupWebServer();
|
||||
diagnosticPrintln("Configuration OK!");
|
||||
|
||||
selectedFile = preferences.getString("selectedFile", "");
|
||||
if (selectedFile == "" || !fileIsValid(selectedFile))
|
||||
{
|
||||
File root = SD.open("/");
|
||||
File file = root.openNextFile();
|
||||
while (file)
|
||||
{
|
||||
String fileName = file.name();
|
||||
if (fileIsValid(fileName))
|
||||
{
|
||||
selectedFile = fileName;
|
||||
Serial.println("Selected " + fileName);
|
||||
display.println("Selectionne : " + fileName);
|
||||
display.display();
|
||||
break;
|
||||
}
|
||||
file.close();
|
||||
file = root.openNextFile();
|
||||
}
|
||||
root.close();
|
||||
}
|
||||
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
// Wifi
|
||||
#ifdef B_WIFI_AP
|
||||
Serial.println("Setting up AP...");
|
||||
WiFi.softAP(ssid, password);
|
||||
String wifiIP = WiFi.softAPIP().toString();
|
||||
String wifiMode = "AP";
|
||||
display.print("Wifi: ");
|
||||
display.println(ssid);
|
||||
display.print("Pass: ");
|
||||
display.println(password);
|
||||
#else
|
||||
Serial.print("Connecting to wifi...");
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
Serial.print(".");
|
||||
delay(500);
|
||||
}
|
||||
Serial.println();
|
||||
String wifiIP = WiFi.localIP().toString();
|
||||
String wifiMode = "client";
|
||||
#endif
|
||||
String wifiMessage = wifiMode + " IP: " + wifiIP;
|
||||
Serial.println(wifiMessage);
|
||||
display.print("IP: ");
|
||||
display.println(wifiIP);
|
||||
display.display();
|
||||
|
||||
// Server
|
||||
server.on("/play", HTTP_GET, onPlay);
|
||||
server.on("/stop", HTTP_GET, onStop);
|
||||
server.on("/status", HTTP_GET, onStatus);
|
||||
server.on("/list-files", HTTP_GET, onListFiles);
|
||||
server.on("/select-file", HTTP_POST, onSelectFile);
|
||||
server.on("/change-volume", HTTP_POST, onChangeVolume);
|
||||
server.on("/upload", HTTP_POST, onUpload, onUploadFile);
|
||||
server.onNotFound(onNotFound);
|
||||
server.serveStatic("/", SPIFFS, "/www/").setDefaultFile("index.html");
|
||||
AsyncElegantOTA.begin(&server);
|
||||
server.begin();
|
||||
|
||||
Serial.println("Server ready!");
|
||||
clearMessageArea();
|
||||
display.println("Pret !");
|
||||
display.display();
|
||||
|
||||
// Audio
|
||||
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
|
||||
currentVolume = preferences.getUChar("currentVolume", 12);
|
||||
audio.setVolume(currentVolume);
|
||||
displayWifiCreds();
|
||||
displaySelectedFile();
|
||||
|
||||
// Setup is done, light up the LED
|
||||
Serial.println("All setup & ready to go!");
|
||||
digitalWrite(LED, HIGH);
|
||||
}
|
||||
|
||||
|
|
140
src/setup.cpp
Normal file
140
src/setup.cpp
Normal file
|
@ -0,0 +1,140 @@
|
|||
#include <SPIFFS.h>
|
||||
#include <Wire.h> // Required by display.begin
|
||||
#include <AsyncElegantOTA.h>
|
||||
#include <Audio.h>
|
||||
|
||||
#ifdef B_WIFI_AP
|
||||
#include "creds_ap.h"
|
||||
#else
|
||||
#include "creds.h"
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "utils.h"
|
||||
#include "webHandlers.h"
|
||||
|
||||
void setupScreen()
|
||||
{
|
||||
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
|
||||
{
|
||||
Serial.println("Display init failed");
|
||||
while (true);
|
||||
}
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(WHITE, BLACK);
|
||||
display.setCursor(0, 0);
|
||||
display.println("Ecran... OK");
|
||||
display.display();
|
||||
Serial.println("Ecran... OK");
|
||||
}
|
||||
|
||||
void setupSPIFFS()
|
||||
{
|
||||
diagnosticPrint("Fichiers... ");
|
||||
if (!SPIFFS.begin())
|
||||
{
|
||||
Serial.println("SPIFFS error. Exiting.");
|
||||
display.println("KO");
|
||||
display.display();
|
||||
while (true);
|
||||
}
|
||||
diagnosticPrintln("OK");
|
||||
}
|
||||
|
||||
void setupSDCard()
|
||||
{
|
||||
diagnosticPrint("Carte SD... ");
|
||||
pinMode(SD_CS, OUTPUT);
|
||||
digitalWrite(SD_CS, HIGH);
|
||||
SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||
|
||||
if (!SD.begin(SD_CS))
|
||||
{
|
||||
Serial.println("Error talking to SD card!");
|
||||
display.println("KO");
|
||||
display.display();
|
||||
while (true);
|
||||
}
|
||||
diagnosticPrintln("OK");
|
||||
}
|
||||
|
||||
void setupAudio()
|
||||
{
|
||||
diagnosticPrint("Audio... ");
|
||||
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
|
||||
byte volume = preferences.getUChar(CURRENT_VOLUME, 12);
|
||||
audio.setVolume(volume);
|
||||
diagnosticPrintln("OK");
|
||||
}
|
||||
|
||||
void selectDefaultFile()
|
||||
{
|
||||
String linePrefix = "Son: ";
|
||||
diagnosticPrint(linePrefix);
|
||||
String selectedFile = preferences.getString(SELECTED_FILE, "");
|
||||
if (selectedFile == "" || !fileIsValid(selectedFile) || !fileExists(selectedFile))
|
||||
{
|
||||
File root = SD.open("/");
|
||||
File file = root.openNextFile();
|
||||
while (file)
|
||||
{
|
||||
String fileName = file.name();
|
||||
if (fileIsValid(fileName))
|
||||
{
|
||||
Serial.println("Selected " + fileName);
|
||||
selectedFile = fileName;
|
||||
preferences.putString(SELECTED_FILE, fileName);
|
||||
break;
|
||||
}
|
||||
file.close();
|
||||
file = root.openNextFile();
|
||||
}
|
||||
root.close();
|
||||
}
|
||||
diagnosticPrintln(selectedFile.substring(0, LINE_LENGTH - linePrefix.length()));
|
||||
}
|
||||
|
||||
void setupWifi()
|
||||
{
|
||||
diagnosticPrint("Wifi...");
|
||||
preferences.putString(WIFI_SSID, ssid);
|
||||
preferences.putString(WIFI_PASSWORD, password);
|
||||
#ifdef B_WIFI_AP
|
||||
WiFi.softAP(ssid, password);
|
||||
String wifiIP = WiFi.softAPIP().toString();
|
||||
#else
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
Serial.print(".");
|
||||
delay(500);
|
||||
}
|
||||
String wifiIP = WiFi.localIP().toString();
|
||||
#endif
|
||||
diagnosticPrintln(" OK");
|
||||
Serial.print("IP: ");
|
||||
Serial.println(wifiIP);
|
||||
preferences.putString(WIFI_IP, wifiIP);
|
||||
}
|
||||
|
||||
void setupWebServer()
|
||||
{
|
||||
Serial.print("Server... ");
|
||||
display.print("Serveur... ");
|
||||
display.display();
|
||||
server.on("/play", HTTP_GET, onPlay);
|
||||
server.on("/stop", HTTP_GET, onStop);
|
||||
server.on("/status", HTTP_GET, onStatus);
|
||||
server.on("/list-files", HTTP_GET, onListFiles);
|
||||
server.on("/select-file", HTTP_POST, onSelectFile);
|
||||
server.on("/change-volume", HTTP_POST, onChangeVolume);
|
||||
server.on("/upload", HTTP_POST, onUpload, onUploadFile);
|
||||
server.onNotFound(onNotFound);
|
||||
server.serveStatic("/", SPIFFS, "/www/").setDefaultFile("index.html");
|
||||
AsyncElegantOTA.begin(&server);
|
||||
server.begin();
|
||||
Serial.println("OK");
|
||||
display.println("OK");
|
||||
display.display();
|
||||
}
|
17
src/setup.h
Normal file
17
src/setup.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef __SETUP_H__
|
||||
#define __SETUP_H__
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <Preferences.h>
|
||||
#include <Audio.h>
|
||||
|
||||
void setupScreen();
|
||||
void setupSPIFFS();
|
||||
void setupSDCard();
|
||||
void setupAudio();
|
||||
void selectDefaultFile();
|
||||
void setupWifi();
|
||||
void setupWebServer();
|
||||
|
||||
#endif
|
87
src/utils.cpp
Normal file
87
src/utils.cpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
#include <Arduino.h>
|
||||
#include <Audio.h>
|
||||
#include <Preferences.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <SD.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
bool fileIsValid(String fileName)
|
||||
{
|
||||
return !fileName.startsWith(".") && (fileName.endsWith(".mp3") || fileName.endsWith(".wav"));
|
||||
}
|
||||
|
||||
bool fileExists(String fileName)
|
||||
{
|
||||
return SD.exists("/" + fileName);
|
||||
}
|
||||
|
||||
void clearMessageArea()
|
||||
{
|
||||
display.fillRect(SCREEN_MSG_X, SCREEN_MSG_Y, SCREEN_WIDTH - SCREEN_MSG_X, SCREEN_HEIGHT - SCREEN_MSG_Y, BLACK);
|
||||
display.setCursor(SCREEN_MSG_X, SCREEN_MSG_Y);
|
||||
}
|
||||
|
||||
void displayText(String text)
|
||||
{
|
||||
clearMessageArea();
|
||||
display.println(text);
|
||||
display.display();
|
||||
}
|
||||
|
||||
void play()
|
||||
{
|
||||
String selectedFile = preferences.getString(SELECTED_FILE);
|
||||
String path = "/" + selectedFile;
|
||||
Serial.println("Playing file: " + path);
|
||||
audio.stopSong();
|
||||
audio.connecttoFS(SD, path.c_str());
|
||||
}
|
||||
|
||||
|
||||
void diagnosticPrint(String text)
|
||||
{
|
||||
Serial.print(text);
|
||||
display.print(text);
|
||||
display.display();
|
||||
}
|
||||
void diagnosticPrintln(String text)
|
||||
{
|
||||
Serial.println(text);
|
||||
display.println(text);
|
||||
display.display();
|
||||
}
|
||||
|
||||
void displayWifiCreds()
|
||||
{
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
|
||||
String ssid = preferences.getString(WIFI_SSID, "");
|
||||
display.print("Wifi: ");
|
||||
display.println(ssid);
|
||||
|
||||
display.print("Pass: ");
|
||||
#ifdef B_WIFI_AP
|
||||
String password = preferences.getString(WIFI_PASSWORD, "");
|
||||
display.println(password);
|
||||
#else
|
||||
display.println("****");
|
||||
#endif
|
||||
|
||||
display.print("IP: ");
|
||||
String ip = preferences.getString(WIFI_IP, "");
|
||||
display.println(ip);
|
||||
display.display();
|
||||
}
|
||||
|
||||
void displaySelectedFile()
|
||||
{
|
||||
String prefix = "Son: ";
|
||||
displayText(prefix + preferences.getString(SELECTED_FILE, "").substring(0, LINE_LENGTH - prefix.length()));
|
||||
}
|
||||
|
||||
void displayVolume() {
|
||||
String volume = String(preferences.getUChar(CURRENT_VOLUME));
|
||||
displayText("Volume: " + volume);
|
||||
}
|
20
src/utils.h
Normal file
20
src/utils.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef __UTILS_H__
|
||||
#define __UTILS_H__
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <Preferences.h>
|
||||
|
||||
bool fileIsValid(String fileName);
|
||||
bool fileExists(String fileName);
|
||||
void clearMessageArea();
|
||||
void displayText(String text);
|
||||
void play();
|
||||
|
||||
void displayWifiCreds();
|
||||
void displaySelectedFile();
|
||||
|
||||
void diagnosticPrint(String text);
|
||||
void diagnosticPrintln(String text);
|
||||
|
||||
#endif
|
161
src/webHandlers.cpp
Normal file
161
src/webHandlers.cpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
#include <Arduino.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <AsyncJson.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <Preferences.h>
|
||||
#include <SD.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "utils.h"
|
||||
|
||||
void onStop(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println("Stop playing");
|
||||
audio.stopSong();
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void onPlay(AsyncWebServerRequest *request)
|
||||
{
|
||||
play();
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void onStatus(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println("Status");
|
||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||
|
||||
StaticJsonDocument<96> root;
|
||||
root["files"]["selected"] = preferences.getString(SELECTED_FILE, "").c_str();
|
||||
|
||||
JsonObject volume = root.createNestedObject("volume");
|
||||
byte currentVolume = preferences.getUChar(CURRENT_VOLUME);
|
||||
volume["current"] = currentVolume;
|
||||
volume["canDecrease"] = currentVolume > 0;
|
||||
volume["canIncrease"] = currentVolume < 21;
|
||||
|
||||
serializeJson(root, *response);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void onListFiles(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.print("List files cursor=");
|
||||
int cursor = 0;
|
||||
if (request->hasParam("cursor")) {
|
||||
String s_cursor = request->getParam("cursor")->value();
|
||||
cursor = s_cursor.toInt();
|
||||
}
|
||||
Serial.println(cursor);
|
||||
|
||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||
|
||||
StaticJsonDocument<512> root;
|
||||
root["next"] = -1;
|
||||
JsonArray files = root.createNestedArray("files");
|
||||
File music = SD.open("/");
|
||||
File file = music.openNextFile();
|
||||
int index = 0;
|
||||
while (file)
|
||||
{
|
||||
String fileName = file.name();
|
||||
if (fileIsValid(fileName))
|
||||
{
|
||||
index++;
|
||||
if (index >= cursor)
|
||||
files.add(fileName);
|
||||
}
|
||||
file.close();
|
||||
|
||||
if (root.overflowed())
|
||||
{
|
||||
root["next"] = index;
|
||||
break;
|
||||
}
|
||||
file = music.openNextFile();
|
||||
}
|
||||
if (root["next"] == -1) {
|
||||
root.remove("next");
|
||||
}
|
||||
|
||||
serializeJson(root, *response);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
void onSelectFile(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.print("Select file: ");
|
||||
if (request->hasParam("fileName", true))
|
||||
{
|
||||
String selectedFile = request->getParam("fileName", true)->value();
|
||||
preferences.putString(SELECTED_FILE, selectedFile);
|
||||
Serial.print(selectedFile);
|
||||
displaySelectedFile();
|
||||
}
|
||||
Serial.println();
|
||||
onStatus(request);
|
||||
}
|
||||
|
||||
void onChangeVolume(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.print("Volume: ");
|
||||
if (request->hasParam("modifier", true))
|
||||
{
|
||||
String s_modifier = request->getParam("modifier", true)->value();
|
||||
int modifier = s_modifier.toInt();
|
||||
byte currentVolume = preferences.getUChar(CURRENT_VOLUME);
|
||||
currentVolume += modifier;
|
||||
if (currentVolume > VOLUME_MAX)
|
||||
currentVolume = VOLUME_MAX;
|
||||
else if (currentVolume < VOLUME_MIN)
|
||||
currentVolume = VOLUME_MIN;
|
||||
preferences.putUChar(CURRENT_VOLUME, currentVolume);
|
||||
audio.setVolume(currentVolume);
|
||||
Serial.print(currentVolume);
|
||||
String s_volume = String(currentVolume);
|
||||
displayText("Volume : " + s_volume);
|
||||
}
|
||||
Serial.println();
|
||||
onStatus(request);
|
||||
}
|
||||
|
||||
void onUpload(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println("onUpload");
|
||||
request->send(200);
|
||||
}
|
||||
|
||||
void onUploadFile(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)
|
||||
{
|
||||
if (!index)
|
||||
{
|
||||
Serial.printf("UploadStart: %s\n", filename.c_str());
|
||||
String filePath = "/" + filename;
|
||||
request->_tempFile = SD.open(filePath, FILE_WRITE);
|
||||
}
|
||||
if (!request->_tempFile)
|
||||
{
|
||||
Serial.println("Couldn't open file.");
|
||||
request->redirect("/");
|
||||
return;
|
||||
}
|
||||
if (len)
|
||||
{
|
||||
request->_tempFile.write(data, len);
|
||||
}
|
||||
|
||||
if (final)
|
||||
{
|
||||
Serial.printf("UploadEnd: %s, %u B\n", filename.c_str(), index + len);
|
||||
request->_tempFile.close();
|
||||
request->redirect("/");
|
||||
}
|
||||
}
|
||||
|
||||
void onNotFound(AsyncWebServerRequest *request)
|
||||
{
|
||||
Serial.println("not found");
|
||||
request->send(400);
|
||||
}
|
20
src/webHandlers.h
Normal file
20
src/webHandlers.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef __MAIN_H__
|
||||
#define __MAIN_H__
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <Preferences.h>
|
||||
|
||||
|
||||
void onStop(AsyncWebServerRequest *request);
|
||||
void onPlay(AsyncWebServerRequest *request);
|
||||
void onStatus(AsyncWebServerRequest *request);
|
||||
void onListFiles(AsyncWebServerRequest *request);
|
||||
void onSelectFile(AsyncWebServerRequest *request);
|
||||
void onChangeVolume(AsyncWebServerRequest *request);
|
||||
void onUpload(AsyncWebServerRequest *request);
|
||||
void onUploadFile(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
|
||||
void onNotFound(AsyncWebServerRequest *request);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue