Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
|
My original idea was to have an homemade portable mp3 player.
A device to bring with me during the day and to use at home in the night.
The device is built of 2 parts:
- the mp3 player itself with sony spresense: with a potentiometer for volume management, a button (to start/stop) and a button to go to next track
- an esp8266 connected to the mp3 part in order to talk with Amazon Echo
The mp3 is able to play all the mp3s files it found on the "/" folder.
So the device is activable with the hardware button.. or once dock at home with amazon echo
- "Alexa switch on Jukebox!" to start play mp3s
- "Alexa switch off Jukebox!" to stop the mp3
My project was mainly documented with videos:
- First Part: unpackaging and initial considerations:
- Second part: running some examples (failed! :D )
- Third part: playing the first mp3! volume control management
- 4th Part: start/stop mp3!
- Last Part: integration with Esp8266/Alexa, Play files in loop, Track Management
ESP8266 Side
ArduinoThe code to upload to nodemcu: this makes a bridge between spreesense and amazon echo.
Before upload the code to the nodemcu board: change the WIFI_SSID and WIFI_PASS
Before upload the code to the nodemcu board: change the WIFI_SSID and WIFI_PASS
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "fauxmoESP.h"
#define WIFI_SSID "YOURWIFIHERE"
#define WIFI_PASS "YOURWIFIPASSHERE"
#define SERIAL_BAUDRATE 115200
fauxmoESP fauxmo;
// -----------------------------------------------------------------------------
// Wifi
// -----------------------------------------------------------------------------
void wifiSetup() {
// Set WIFI module to STA mode
WiFi.mode(WIFI_STA);
// Connect
//Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);
// Wait
while (WiFi.status() != WL_CONNECTED) {
// Serial.print(".");
delay(100);
}
//Serial.println();
digitalWrite(LED_BUILTIN, HIGH);
// Connected!
//Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
// Init serial port and clean garbage
//Serial.begin(SERIAL_BAUDRATE);
//Serial.println("FauxMo demo sketch");
//Serial.println("After connection, ask Alexa/Echo to 'turn <devicename> on' or 'off'");
// Wifi
wifiSetup();
fauxmo.addDevice("jukebox");
fauxmo.setPort(80);
// Allow the FauxMo to be discovered
fauxmo.enable(true);
fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
//Serial.print(device_name);
if(state) {
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(D2,HIGH);
} else {
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(D2,LOW);
}
});
}
void loop() {
fauxmo.handle();
}
/*
*/
#include <SDHCI.h>
#include <Audio.h>
SDClass theSD;
AudioClass *theAudio;
File myFile;
bool ErrEnd = false;
int lastVolumeValue = 0;
const int STOPPING = 0;
const int PLAYING = 1;
const int SETUP = 2;
int MODE = SETUP;
unsigned long lastPressedButton = -1L;
int fileIdx = 0;
bool isAlexaControlled = false;
/**
* @brief Audio attention callback
*
* When audio internal error occurc, this function will be called back.
*/
static void audio_attention_cb(const ErrorAttentionParam *atprm)
{
puts("Attention!");
if (atprm->error_code >= AS_ATTENTION_CODE_WARNING)
{
ErrEnd = true;
}
}
/**
* @brief Setup audio player to play mp3 file
*
* Set clock mode to normal <br>
* Set output device to speaker <br>
* Set main player to decode stereo mp3. Stream sample rate is set to "auto detect" <br>
* System directory "/mnt/sd0/BIN" will be searched for MP3 decoder (MP3DEC file)
* Open "Sound.mp3" file <br>
* Set master volume to -16.0 dB
*/
void setup() {
Serial.begin(115200);
// start audio system
theAudio = AudioClass::getInstance();
theAudio->begin(audio_attention_cb);
puts("initialization Audio Library");
/* Set clock mode to normal */
theAudio->setRenderingClockMode(AS_CLKMODE_NORMAL);
theAudio->setPlayerMode(AS_SETPLAYER_OUTPUTDEVICE_SPHP, AS_SP_DRV_MODE_LINEOUT);
pinMode(2, INPUT); //NEXTBUTTON
pinMode(3, INPUT); //STOP/START current
pinMode(4, INPUT); //ALEXA
}
void playNextFile() {
/* Send first frames to be decoded */
err_t err = theAudio->initPlayer(AudioClass::Player0, AS_CODECTYPE_MP3, "/mnt/sd0/BIN", AS_SAMPLINGRATE_AUTO, AS_CHANNEL_STEREO);
/* Verify player initialize */
if (err != AUDIOLIB_ECODE_OK)
{
printf("Player0 initialize error\n");
exit(1);
}
lastVolumeValue = volumeControlValue();
theAudio->setVolume(lastVolumeValue); //more close to 0.. is HIGHER .. -300 is normal sound..
loadSDFile();
MODE = PLAYING;
myFile.seek(0);
err = theAudio->writeFrames(AudioClass::Player0, myFile);
if ((err != AUDIOLIB_ECODE_OK) && (err != AUDIOLIB_ECODE_FILEEND)) {
printf("File Read Error! =%d\n",err);
myFile.close();
exit(1);
}
theAudio->startPlayer(AudioClass::Player0);
}
void playCurrentFile(){
myFile.seek(0);
err_t err = theAudio->writeFrames(AudioClass::Player0, myFile);
if ((err != AUDIOLIB_ECODE_OK) && (err != AUDIOLIB_ECODE_FILEEND)) {
printf("File Read Error! =%d\n",err);
myFile.close();
exit(1);
}
theAudio->startPlayer(AudioClass::Player0);
}
int volumeControlValue() {
int sensorValue = analogRead(A0); // 0 and 1000 value.
return (-0.6 * sensorValue); //a value between -20 and -600
}
int checkButtons() {
int firstButton = digitalRead(2);
int secondButton = digitalRead(3);
int FROMALEXA = digitalRead(4);
//print out the value of the pushbutton
unsigned long currentTime = millis();
if ( currentTime - lastPressedButton > 1000L ) {
lastPressedButton = currentTime;
if ( firstButton == HIGH ) {
if ( MODE == PLAYING ) { //STOP IT
MODE = STOPPING;
} else if ( MODE == SETUP ){ //PLAY NEXT SONG
MODE = PLAYING;
myFile.seek(0);
playNextFile();
}
puts("pressed first button");
char z[10];
sprintf(z,"ACTUALMODE: %d",MODE);
puts(z);
}
if ( secondButton == HIGH ) {
if ( MODE == PLAYING ) { //STOP IT
MODE = STOPPING;
} else if ( MODE == SETUP ){ //PLAY AGAIN
MODE = PLAYING;
playCurrentFile();
}
}
if ( FROMALEXA == LOW) { //ALEXA SWITCHON!
isAlexaControlled = true;
if ( MODE == SETUP ) {
puts("ALEXA LOW");
MODE = PLAYING;
myFile.seek(0);
playNextFile();
}
} else {
if ( isAlexaControlled ) {
puts("ALEXA HIGH ");
if ( MODE == PLAYING ) { //STOP IT
MODE = STOPPING;
}
}
}
}
}
void loadSDFile() {
puts("Size\tFilename");
Serial.println("----\t--------");
File root = theSD.open("/");
int current = 0;
bool fileFound = false;
while (true) {
File entry = root.openNextFile();
if (!entry) {
break;
}
String fname = entry.name();
/*
738331 /song1.mp3
4096 /._song1.mp3
6010879 /song2.mp3
0 /BIN
*/
if( fname.charAt(1) != '.' && fname.endsWith(".mp3") ) { //only mp3 files..
Serial.print(entry.size(), DEC);
Serial.print("\t");
Serial.println(entry.name());
if ( current == fileIdx ) {
if( myFile != NULL )
myFile.close();
myFile = theSD.open(fname);
entry.close();
fileIdx = current + 1;
Serial.println("play this file.");
fileFound = true;
break;
} else {
current ++;
}
}
entry.close();
}
if ( fileFound == false ) { //read the first file..
fileIdx = 0;
loadSDFile();
Serial.println("Reading from the beginning...");
}
}
/**
* @brief Play stream
*
* Send new frames to decode in a loop until file ends
*/
void loop()
{
/* Send new frames to decode in a loop until file ends */
if( MODE == STOPPING ) { //STOP MODE
theAudio->stopPlayer(AudioClass::Player0,0);
MODE = SETUP;
return;
}
checkButtons();
if ( MODE == SETUP ) { //PLAY AGAIN
//maybe we can update LCD....
//we can do stuff here..
return;
}
//puts("loop");
int err = theAudio->writeFrames(AudioClass::Player0, myFile);
int tempVolume = volumeControlValue();
/* Tell when player file ends */
if (err == AUDIOLIB_ECODE_FILEEND){
printf("Main player File End!\n");
theAudio->stopPlayer(AudioClass::Player0,0);
myFile.close();
playNextFile();
return;
}
/* Show error code from player and stop */
if (err)
{
printf("Main player error code: %d\n", err);
//playNextFile();
}
if (ErrEnd)
{
printf("Error End\n");
goto stop_player;
}
if ( tempVolume != lastVolumeValue ) {
theAudio->setVolume(lastVolumeValue); //more close to 0.. is HIGHER .. -300 is normal sound..
lastVolumeValue = tempVolume;
}
/* This sleep is adjusted by the time to read the audio stream file.
Please adjust in according with the processing contents
being processed at the same time by Application.
*/
usleep(40000);
/* Don't go further and continue play */
return;
stop_player:
sleep(1);
theAudio->stopPlayer(AudioClass::Player0);
myFile.close();
exit(1);
}
Andrea De Gaetano
10 projects • 25 followers
Interested in iot, mobile and security
Love hackathons
This is my blog http://pestohacks.blogspot.com
Comments