Browse Source

basecamp and mp3 demo

main
Hendrik Langer 7 years ago
parent
commit
7ce5d7a5eb
  1. 14
      platformio.ini
  2. 45
      src/main.cpp
  3. 2
      src/main.h
  4. 137
      src/mp3.cpp
  5. 39
      src/mp3.h
  6. 2
      src/password.txt

14
platformio.ini

@ -8,18 +8,22 @@
; Please visit documentation for the other options and examples
; http://docs.platformio.org/page/projectconf.html
[env:esp32thing]
platform = https://github.com/platformio/platform-espressif32.git#feature/stage
;platform = espressif32
board = esp32thing
[env:heltec_wifi_lora_32]
;platform = https://github.com/platformio/platform-espressif32.git#feature/stage
platform = espressif32
board = heltec_wifi_lora_32
board_f_cpu = 240000000L
board_f_flash = 80000000L
framework = arduino
build_flags = -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG
build_flags = -DLOG_LOCAL_LEVEL=ESP_LOG_INFO
lib_deps =
; Basecamp
https://github.com/merlinschumacher/Basecamp.git
u8g2
NTPClient
; ESP8266Audio
; https://github.com/earlephilhower/ESP8266Audio.git
https://github.com/h3ndrik/ESP8266Audio.git
https://github.com/Gianbacchio/ESP8266_Spiram.git
lib_ignore = ESPAsyncTCP

45
src/main.cpp

@ -19,6 +19,7 @@
#include <NTPClient.h>
#include "main.h"
#include "mp3.h"
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 15, /* data=*/ 4, /* reset=*/ 16);
@ -29,8 +30,10 @@ WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "de.pool.ntp.org", 3600, 60000);
char timeStr[20];
MP3 mp3;
//Variables for the sensor and the battery
static const int ResetPin = 35;
static const int ResetPin = 17;
static const int SensorPin = 32;
static const int BatteryPin = 34;
int sensorValue = 0;
@ -47,16 +50,6 @@ String statusTopic;
String batteryTopic;
String batteryValueTopic;
// Reset the configuration to factory defaults (all empty)
void resetToFactoryDefaults()
{
DEBUG_PRINTLN("Resetting to factory defaults");
Configuration config(String{"/basecamp.json"});
config.load();
config.reset();
config.save();
}
void setup() {
//configuration of the battery and sensor pins
pinMode(ResetPin, INPUT_PULLDOWN);
@ -66,19 +59,9 @@ void setup() {
//read the status of the doorsensor as soon as possible to determine the state that triggered it
sensorValue = digitalRead(SensorPin);
bool resetPressed = (digitalRead(ResetPin) == HIGH);
if (resetPressed)
{
resetToFactoryDefaults();
}
//Initialize Basecamp
iot.begin();
if (resetPressed) {
DEBUG_PRINTLN("**** CONFIG HAS BEEN MANUALLY RESET ****");
}
u8g2.begin();
delay(50);
u8g2.clearBuffer(); // clear the internal memory
@ -121,9 +104,12 @@ void setup() {
timeClient.getFormattedTime().toCharArray(timeStr, 50);
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_ncenB08_tr); // choose a suitable font
// u8g2.setDrawColor(2);
u8g2.drawStr(30, 30, timeStr);
u8g2.drawStr(30, 50, ipStr);
u8g2.sendBuffer();
mp3.begin();
}
@ -206,12 +192,23 @@ void suspendESP(uint16_t packetId) {
}
}
void loop()
{
timeClient.update();
timeClient.getFormattedTime().toCharArray(timeStr, 50);
u8g2.drawStr(30, 30, timeStr);
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_inb19_mf);
u8g2.drawStr(0, 20, timeStr);
char title1[32]; char title2[32];
strncpy(title1, titleStr, 22); title1[22] = '\0';
strncpy(title2, titleStr+22, 32); title2[31] = '\0';
u8g2.setFont(u8g2_font_prospero_bold_nbp_tf); // choose a suitable font
u8g2.drawUTF8(0, 45, title1);
u8g2.drawUTF8(0, 55, title2);
u8g2.sendBuffer();
delay(1000);
}
delay(500);
}

2
src/main.h

@ -1,3 +1,5 @@
#include "driver/i2s.h"
void resetToFactoryDefaults();
void setup();
void onMqttConnect(bool sessionPresent);

137
src/mp3.cpp

@ -0,0 +1,137 @@
#include "mp3.h"
#include <HTTPClient.h>
#include <SD.h>
#include "AudioFileSourceICYStream.h"
#include "AudioFileSourceBuffer.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"
//#include "driver/gpio.h"
//#include "driver/periph_ctrl.h"
//#include "soc/gpio_sig_map.h"
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s.h"
#include "esp_system.h"
#include <math.h>
char titleStr[64];
MP3::MP3() {}
/*gpio_set_direction(GPIO_NUM_13,GPIO_MODE_OUTPUT); // GPIO_MODE_DEF_OUTPUT
gpio_set_direction(GPIO_NUM_12,GPIO_MODE_OUTPUT);
gpio_set_direction(GPIO_NUM_22,GPIO_MODE_OUTPUT);
gpio_matrix_out(13, I2S0O_BCK_OUT_IDX, 0, 0);
gpio_matrix_out(12, I2S0O_WS_OUT_IDX, 0, 0);
gpio_matrix_out(22, I2S0O_DATA_OUT0_IDX, 0, 0);
//periph_module_reset( PERIPH_I2S0_MODULE );
periph_module_disable(PERIPH_I2S0_MODULE);
delay(100);
periph_module_enable(PERIPH_I2S0_MODULE);*/
void MP3::cTaskWrapper(void* parameters) {
static_cast<MP3*>(parameters)->mp3_decoder_task(NULL);
}
void MP3::mp3_decoder_task(void *pvParameters) {
while(true) {
if (mp3->isRunning()) {
if (millis()-lastms > 1000) {
lastms = millis();
Serial.printf("Running for %d ms...\n", lastms);
Serial.flush();
}
if (!mp3->loop()) mp3->stop();
} else {
Serial.printf("MP3 done\n");
delay(1000);
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL);
}
bool MP3::begin() {
strcpy(titleStr, "StreamTitle");
// First, preallocate all the memory needed for the buffering and codecs, never to be freed
preallocateBuffer = malloc(preallocateBufferSize);
preallocateCodec = malloc(preallocateCodecSize);
if (!preallocateBuffer || !preallocateCodec) {
Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize+preallocateCodecSize);
return false;
}
Serial.println("Starting mp3 playback");
file = new AudioFileSourceICYStream(URL);
file->RegisterMetadataCB(MDCallback, (void*)"ICY");
buff = new AudioFileSourceBuffer(file, preallocateBuffer, preallocateBufferSize);
buff->RegisterStatusCB(StatusCallback, (void*)"buffer");
out = new AudioOutputI2S(I2S_NUM_0, false);
out->SetPinout(12, 13, 23);
out->SetOutputModeMono(false);
out->SetRate(44100);
out->SetBitsPerSample(16);
out->SetChannels(2);
mp3 = new AudioGeneratorMP3(preallocateCodec, preallocateCodecSize);
mp3->RegisterStatusCB(StatusCallback, (void*)"mp3");
mp3->begin(buff, out);
out->SetGain(1.0);
/*
I2S0.clkm_conf.clka_en = 1; // was 0
I2S0.clkm_conf.clkm_div_a = 1; // was 63;
I2S0.clkm_conf.clkm_div_b = 0; // was clkmDecimals;
I2S0.clkm_conf.clkm_div_num = 1; // was clkmInteger;
// periph_module_enable(PERIPH_EMAC_MODULE);
// rtc_clk_apll_enable(1,0,73,7,8);
// i2s_set_clk((i2s_port_t)portNo, 44100, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_STEREO);
i2s_set_clk(I2S_NUM, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_STEREO);
*/
xTaskCreate(
&cTaskWrapper, /* Task function. */
"audioTask", /* String with name of task. */
2048, /* Stack size in words. */
this, /* Parameter passed as input of the task */
tskIDLE_PRIORITY+1, /* Priority of the task. */
&audioTaskHandle); /* Task handle. */
}
// Called when a metadata event occurs (i.e. an ID3 tag, an ICY block, etc.
void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
{
const char *ptr = reinterpret_cast<const char *>(cbData);
(void) isUnicode; // Punt this ball for now
// Note that the type and string may be in PROGMEM, so copy them to RAM for printf
char s1[32], s2[64];
strncpy_P(s1, type, sizeof(s1));
s1[sizeof(s1)-1]=0;
strncpy_P(s2, string, sizeof(s2));
s2[sizeof(s2)-1]=0;
Serial.printf("METADATA(%s) '%s' = '%s'\n", ptr, s1, s2);
Serial.flush();
if (strcmp("StreamTitle", type)==0) {
strncpy_P(titleStr, string, sizeof(titleStr));
s2[sizeof(s2)-1]=0;
}
}
// Called when there's a warning or error (like a buffer underflow or decode hiccup)
void StatusCallback(void *cbData, int code, const char *string)
{
const char *ptr = reinterpret_cast<const char *>(cbData);
// Note that the string may be in PROGMEM, so copy it to RAM for printf
char s1[64];
strncpy_P(s1, string, sizeof(s1));
s1[sizeof(s1)-1]=0;
Serial.printf("STATUS(%s) '%d' = '%s'\n", ptr, code, s1);
Serial.flush();
}

39
src/mp3.h

@ -0,0 +1,39 @@
#ifndef _MP3_H
#define _MP3_H
#include <HTTPClient.h>
#include <SD.h>
#include "AudioFileSourceICYStream.h"
#include "AudioFileSourceBuffer.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"
void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string);
void StatusCallback(void *cbData, int code, const char *string);
extern char titleStr[];
class MP3 {
public:
MP3();
bool begin(void);
//const char *URL="http://streaming.shoutcast.com/80sPlanet?lang=en-US";
const char *URL="http://swr-swr1-bw.cast.addradio.de/swr/swr1/bw/mp3/64/stream.mp3";
private:
AudioGeneratorMP3 *mp3;
AudioFileSourceICYStream *file;
AudioFileSourceBuffer *buff;
AudioOutputI2S *out;
TaskHandle_t audioTaskHandle;
void mp3_decoder_task(void*);
static void cTaskWrapper(void*);
static constexpr int preallocateBufferSize = 5*1024;
static constexpr int preallocateCodecSize = 29192; // MP3 codec max mem needed
void *preallocateBuffer = NULL;
void *preallocateCodec = NULL;
int lastms = 0;
};
#endif /* _MP3_H */

2
src/password.txt

@ -0,0 +1,2 @@
172.16.75.18
esp32-node QXLhCf9yXE
Loading…
Cancel
Save