Skip to content

Commit

Permalink
Feat/audio (#7)
Browse files Browse the repository at this point in the history
* change sketch

* change sketch

* add audio libs

* auto change settings

* extend flash size

* change version number

* update libraries

* remove AsyncElegantOTA

* change partition

* separate configs for OTA and COM upload; update libraries

* fix missing external libraries on build

* stop autoplay of stream; add TODOs

* add API endpoints for player

* fix typing

* add documentation for player API

* remove unused columns

* create settings-file if not exists

* update wiring of audio interface

* remove unused include

* switch to ESP32-audioI2S library
  • Loading branch information
coding-lemur authored Feb 13, 2023
1 parent 3589279 commit 5907c1b
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 48 deletions.
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"system_error": "cpp"
"system_error": "cpp",
"array": "cpp",
"string_view": "cpp",
"initializer_list": "cpp",
"regex": "cpp"
}
}
Binary file modified docs/beed-room-clock-sketch.fzz
Binary file not shown.
Binary file modified docs/beed-room-clock-sketch_bb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 24 additions & 24 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,36 @@
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp32doit-devkit-v1]
[platformio]
default_envs = esp32_com

[env]
platform = [email protected]
board = esp32doit-devkit-v1
framework = arduino

board_build.partitions = min_spiffs.csv
monitor_speed = 115200
monitor_filters = esp32_exception_decoder

upload_speed = 921600
upload_port = COM3 # /dev/ttyUSB0
#upload_port = 192.168.178.83
#upload_protocol = espota
#upload_flags =
# --auth=waaatering
lib_deps =
juerd/ESP-WiFiSettings @ ~3.8.0
teckel12/NewPing @ ^1.9.6
ottowinter/ESPAsyncWebServer-esphome @ ^3.0.0
bblanchon/StreamUtils @ ^1.7.0
adafruit/Adafruit SSD1306 @ ^2.5.7
adafruit/Adafruit GFX Library @ ^1.11.5
adafruit/DHT sensor library @ ^1.4.3
adafruit/Adafruit Unified Sensor @ ^1.1.7
https://github.com/schreibfaul1/ESP32-audioI2S.git#3.0.0
bblanchon/ArduinoJson@^6.20.1

#build_type = debug
#build_flags = -DCORE_DEBUG_LEVEL=5 # verbose

lib_deps =
juerd/ESP-WiFiSettings @ ~3.8.0
teckel12/NewPing @ ^1.9.4
ottowinter/ESPAsyncWebServer-esphome @ ^3.0.0
ayushsharma82/AsyncElegantOTA @ ^2.2.7
bblanchon/ArduinoJson @ ^6.19.4
bblanchon/StreamUtils @ ^1.6.3

#SSD1306
adafruit/Adafruit SSD1306 @ ^2.5.7
adafruit/Adafruit GFX Library @ ^1.11.3
[env:esp32_com]
upload_speed = 921600
upload_port = COM3

# DHT22
adafruit/DHT sensor library @ ^1.4.3
adafruit/Adafruit Unified Sensor @ ^1.1.5
[env:esp32_ota]
upload_port = 192.168.178.83
upload_protocol = espota
upload_flags =
--auth=waaatering
81 changes: 64 additions & 17 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ You can put this device in your bedroom and you won't be disturbed by the light

### Ultra Sonic Sensor (HC-SR04)

| Pin on Sensor | description | Pin on ESP32 |
| ------------- | ----------- | ------------ |
| VCC | | VIN (5V) |
| TRIG | | GPIO 5 |
| ECHO | | GPIO 18 |
| GND | | GND |
| Pin on Sensor | Pin on ESP32 |
| ------------- | ------------ |
| VCC | VIN (5V) |
| TRIG | GPIO 5 |
| ECHO | GPIO 18 |
| GND | GND |

### OLED Display (SSD1306 128x64) via SPI

Expand All @@ -56,12 +56,24 @@ You can put this device in your bedroom and you won't be disturbed by the light

### DHT22

| Pin on Sensor | description | Pin on ESP32 |
| ------------- | ----------- | --------------- |
| 1 | | 3V3 (3V) |
| 2 | | GPIO 4 (analog) |
| 3 | | - |
| 4 | | GND |
| Pin on Sensor | Pin on ESP32 |
| ------------- | --------------- |
| 1 | 3V3 (3V) |
| 2 | GPIO 4 (analog) |
| 3 | - |
| 4 | GND |

### MAX 98357A (Audio Interface)

| Pin on Sensor | Pin on ESP32 |
| ------------- | --------------- |
| LRC | GPIO 25 |
| BCLK | GPIO 26 |
| DIN | GPIO 22 |
| GAIN | - |
| SD | - |
| GND | GND |
| Vin | Vin (5V) |

## Timezone configuration

Expand All @@ -71,7 +83,9 @@ Later I will include this setting also to the dashboard.

## REST API endpoint

### Get info
### General

#### Get info

```http
GET /api/info
Expand Down Expand Up @@ -101,15 +115,15 @@ Returning an JSON object with following data:
}
```

### Get settings
#### Get settings

```http
GET /api/settings
```

Return the settings.json

### Change settings
#### Change settings

```http
POST /api/settings
Expand All @@ -124,13 +138,13 @@ Send payload as JSON in body.
| screenOnDistance | number (0 - 255) | 18 cm | Specifies the distance from the ultrasonic sensor in centimeters from when the display should be switched on. |
| screenOnInterval | number | 8000 ms | Specifies the time in milliseconds that the display stays on after motion detection. |

### Restart device
#### Restart device

```http
POST /api/restart
```

### Factory reset
#### Factory reset

```http
POST /api/hard-reset
Expand All @@ -139,3 +153,36 @@ POST /api/hard-reset
Reset device to factory settings.

**Warning**: all files (~settings) will removed from the device. Need setup for connecting to your WiFi.

### Audio-Player

#### Start Stream

```http
POST /api/player/start
```

Payload

| field | type | default | description |
| ---------------- | ---------------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| source | string | | URL of the MP3 streaming source
| volume | number (between 0 and 11) | | volume level |

#### Change Volume

```http
POST /api/player/volume
```

Payload

| field | type | default | description |
| ---------------- | ---------------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| volume | number (between 0 and 11) | | volume level |

#### Stop Stream

```http
POST /api/player/stop
```
99 changes: 93 additions & 6 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,33 @@
#include <AsyncJson.h>
#include <ESPAsyncWebServer.h>

#include <AsyncElegantOTA.h>
#include <ESPAsyncTunnel.h>
#include <ESPmDNS.h>

#include "Audio.h"

#include "config.h"

const String version = "1.4.1";
const String version = "1.5.0";

NewPing sonar(GPIO_NUM_5, GPIO_NUM_18);
Adafruit_SSD1306 ssd1306(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
DHT dht(DHT_PIN, DHT_TYPE);
AsyncWebServer server(80);

const char *ntpServer = "pool.ntp.org"; // TODO move to settings
const char *timeZone = "CET-1CEST,M3.5.0,M10.5.0/3"; // TODO move to settings
// TODO move to settings
const char *ntpServer = "pool.ntp.org";
const char *timeZone = "CET-1CEST,M3.5.0,M10.5.0/3";

// TODO move to settings
const char *externalBaseUrl = "https://coding-lemur.github.io";
const char *indexPath = "/bed-room-clock-dashboard/index.html";

// TODO move to settings
const char *streamUrls[] = {"http://www.radioeins.de/livemp3"};

Audio audio;

bool isPortalActive = false;
float lastTemperature = -100;
float lastHumidity = -100;
Expand Down Expand Up @@ -157,6 +164,7 @@ void loadSettings()
{
if (!SPIFFS.exists(SETTINGS_FILENAME))
{
saveSettings();
return;
}

Expand All @@ -168,6 +176,7 @@ void loadSettings()
if (error)
{
Serial.println("error on deserializing 'auto-starts' file: ");
saveSettings();
return;
}

Expand Down Expand Up @@ -208,6 +217,13 @@ void loadSettings()
setBrightness();
}

void setVolume(uint8_t volume)
{
volume = volume > 21 ? 21 : volume < 0 ? 0
: volume;
audio.setVolume(volume);
}

// TODO move to library
String getDeviceId()
{
Expand Down Expand Up @@ -327,6 +343,60 @@ void onChangeSettings(AsyncWebServerRequest *request, JsonVariant &json)
request->send(400); // bad request
}

void onStartPlayer(AsyncWebServerRequest *request, JsonVariant &json)
{
StaticJsonDocument<200> data = json.as<JsonObject>();

bool isDirty = false;

if (data.containsKey("source"))
{
const char *sourceUrl = data["source"].as<const char *>();
audio.connecttohost(sourceUrl);

isDirty = true;
}

if (data.containsKey("volume"))
{
uint8_t volume = data["volume"].as<uint8_t>();
setVolume(volume);

isDirty = true;
}

if (isDirty)
{
request->send(200);
return;
}

request->send(400); // bad request
}

void onChangeVolume(AsyncWebServerRequest *request, JsonVariant &json)
{
StaticJsonDocument<200> data = json.as<JsonObject>();

bool isDirty = false;

if (data.containsKey("volume"))
{
uint8_t volume = data["volume"].as<uint8_t>();
setVolume(volume);

isDirty = true;
}

if (isDirty)
{
request->send(200);
return;
}

request->send(400); // bad request
}

void setupWebserver()
{
// rewrites
Expand Down Expand Up @@ -377,7 +447,16 @@ void setupWebserver()

server.addHandler(new AsyncCallbackJsonWebHandler("/api/settings", onChangeSettings));

AsyncElegantOTA.begin(&server);
// player stuff
server.addHandler(new AsyncCallbackJsonWebHandler("/api/player/start", onStartPlayer));
server.addHandler(new AsyncCallbackJsonWebHandler("/api/player/volume", onChangeVolume));
server.on("/api/player/stop", HTTP_POST, [](AsyncWebServerRequest *request)
{
request->send(200);

delay(1000);
audio.stopSong(); });

server.begin();
}

Expand Down Expand Up @@ -538,6 +617,12 @@ void setupWifiSettings()
WiFiSettings.connect();
}

void setupAudio()
{
audio.setPinout(GPIO_NUM_26, GPIO_NUM_25, GPIO_NUM_22);
audio.setVolume(11); // default 0...21
}

void setup()
{
Serial.begin(115200);
Expand All @@ -549,13 +634,13 @@ void setup()
loadSettings();

setupDisplay();
setupMDns();
setupWifiSettings();
setupMDns();
setupWebserver();
setupOta();
setupNtp();
setupDht();
setupAudio();
}

void loop()
Expand Down Expand Up @@ -592,6 +677,8 @@ void loop()
uint8_t command = isDisplayOff ? SSD1306_DISPLAYOFF : SSD1306_DISPLAYON;
ssd1306.ssd1306_command(command);

audio.loop();

if (!isDisplayOff && shouldUpdateScreen)
{
struct tm timeinfo;
Expand Down

0 comments on commit 5907c1b

Please sign in to comment.