diff --git a/README.md b/README.md
index 8d1c556..ff45fd9 100755
--- a/README.md
+++ b/README.md
@@ -1,17 +1,21 @@
+-> [new version](https://github.com/n24bass/ESP32_MP3_Decoder/tree/OLED_WEB)
+
Modified for multi URL support by n24bass
-Add web interface.
+Add web interface. You can add (up to 10), change or remove URL of the internet radio station.
```
-http://address_of_ESP32/ - list stations
-http://address_of_ESP32/P - change to previous station
-http://address_of_ESP32/N - change to next station
-http://address_of_ESP32/[0..9] - select station
-http://address_of_ESP32/[0..]+URL - set station URL
-http://address_of_ESP32/[0..]-URL - remove station URL
+GET / - list stations
+GET /P - change to previous station
+GET /N - change to next station
+GET /0..9 - select station
+GET /0..9+URL - set station URL
+GET /0..-URL - remove station URL
```
-Push 'boot' switch to change next station.
+Push 'GPIO-16' (chaned from 'boot') switch to change next station.
+
+It starts up only web interface when GPIO-16 is keeped low level at boot time.
----
@@ -49,4 +53,4 @@ GPIO13 - SDA
More details can be found in the original author's explanation at
-https://github.com/MrBuddyCasino/ESP32_MP3_Decoder
\ No newline at end of file
+https://github.com/MrBuddyCasino/ESP32_MP3_Decoder
diff --git a/components/controls/controls.c b/components/controls/controls.c
index 1e1f03b..e5389e1 100755
--- a/components/controls/controls.c
+++ b/components/controls/controls.c
@@ -41,7 +41,7 @@ void controls_init(TaskFunction_t gpio_handler_task, const uint16_t usStackDepth
//interrupt of rising edge
io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
//bit mask of the pins, use GPIO0 here ("Boot" button)
- io_conf.pin_bit_mask = (1 << GPIO_NUM_0);
+ io_conf.pin_bit_mask = (1 << GPIO_NUM_16);
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//disable pull-down mode
@@ -63,15 +63,15 @@ void controls_init(TaskFunction_t gpio_handler_task, const uint16_t usStackDepth
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
// remove existing handler that may be present
- gpio_isr_handler_remove(GPIO_NUM_0);
+ gpio_isr_handler_remove(GPIO_NUM_16);
//hook isr handler for specific gpio pin
- gpio_isr_handler_add(GPIO_NUM_0, gpio_isr_handler, (void*) GPIO_NUM_0);
+ gpio_isr_handler_add(GPIO_NUM_16, gpio_isr_handler, (void*) GPIO_NUM_16);
}
void controls_destroy()
{
- gpio_isr_handler_remove(GPIO_NUM_0);
+ gpio_isr_handler_remove(GPIO_NUM_16);
vTaskDelete(gpio_task);
vQueueDelete(gpio_evt_queue);
// TODO: free gpio_handler_param_t params
diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild
index c2e2f5d..9582fb4 100755
--- a/main/Kconfig.projbuild
+++ b/main/Kconfig.projbuild
@@ -52,4 +52,10 @@ menuconfig BT_SPEAKER_MODE
Web radio streaming will be unavailable.
depends on CLASSIC_BT_ENABLED
+ config SSD1306_6432
+ help
+ only for Web radio mode
+ bool "use SSD1306_6432"
+
endmenu
+
diff --git a/main/app_main.c b/main/app_main.c
index ea1af3d..8221374 100644
--- a/main/app_main.c
+++ b/main/app_main.c
@@ -49,10 +49,9 @@
#define I2C_EXAMPLE_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_EXAMPLE_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */
-
const static char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
-const static char http_t[] = "
ESP32 PCM5102A webradioWeb radio station list
";
+const static char http_t[] = "ESP32 PCM5102A webradioESP32 PCM5102A webradio
Station list
";
const static char http_e[] = "
prev next";
/* */
@@ -62,6 +61,8 @@ const static char http_e[] = "
prev nex
#define MAXSTATION 10
static const char *preset_url = "http://wbgo.streamguys.net/wbgo96"; // preset station URL
+// static const char *preset_url = "http://wbgo-web.streamguys.net/audio/wbgo_8000.asx";
+// static const char *preset_url = "http://wbgo.streamguys.net/thejazzstream";
/*
"http://wbgo.streamguys.net/wbgo96",
"http://wbgo.streamguys.net/thejazzstream",
@@ -86,6 +87,9 @@ char *init_url(int d) {
esp_err_t e;
nvs_open(NVSNAME, NVS_READWRITE, &h);
+#if 0
+ nvs_erase_all(h);
+#endif
if (nvs_get_u8(h, key_n, &stno_max) != ESP_OK) {
stno = 0;
@@ -197,12 +201,64 @@ void erase_nvurl(int n) {
xSemaphoreHandle print_mux;
-void i2c_test(void)
+static char *surl = NULL;
+static char ip[16];
+static int x = 0;
+static int l = 0;
+
+#ifdef CONFIG_SSD1306_6432
+#define XOFFSET 31
+#define YOFFSET 32
+#define WIDTH 64
+#define HEIGHT 32
+#else
+#define WIDTH 128
+#define HEIGHT 64
+#define XOFFSET 0
+#define YOFFSET 0
+#endif
+
+void oled_scroll(void) {
+ if (surl == NULL) return;
+ while (l) {
+ vTaskDelay(20/portTICK_RATE_MS);
+ }
+ int w = strlen(surl) * 7;
+ if (w <= WIDTH) return;
+
+#ifdef CONFIG_SSD1306_6432
+ SSD1306_GotoXY(XOFFSET - x, YOFFSET + 10);
+ SSD1306_Puts(surl, &Font_7x10, SSD1306_COLOR_WHITE);
+ SSD1306_GotoXY(XOFFSET - x, YOFFSET + 20);
+ SSD1306_Puts(ip, &Font_7x10, SSD1306_COLOR_WHITE);
+#else
+ SSD1306_GotoXY(2 - x, 37);
+ SSD1306_Puts(surl, &Font_7x10, SSD1306_COLOR_WHITE);
+#endif
+
+ x++;
+ if (x > w) x = -WIDTH;
+ SSD1306_UpdateScreen();
+}
+
+void i2c_test(int mode)
{
char *url = get_url(); // play_url();
+ x = 0;
+ surl = url;
SSD1306_Fill(SSD1306_COLOR_BLACK); // clear screen
-
+#ifdef CONFIG_SSD1306_6432
+ SSD1306_GotoXY(XOFFSET + 2, YOFFSET); // 31, 32);
+ SSD1306_Puts("ESP32PICO", &Font_7x10, SSD1306_COLOR_WHITE);
+ SSD1306_GotoXY(XOFFSET - x, YOFFSET + 10);
+ SSD1306_Puts(surl, &Font_7x10, SSD1306_COLOR_WHITE);
+ SSD1306_GotoXY(XOFFSET - x, YOFFSET + 20);
+ tcpip_adapter_ip_info_t ip_info;
+ tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
+ strcpy(ip, ip4addr_ntoa(&ip_info.ip));
+ SSD1306_Puts(ip + 3, &Font_7x10, SSD1306_COLOR_WHITE);
+#else
SSD1306_GotoXY(40, 4);
SSD1306_Puts("ESP32", &Font_11x18, SSD1306_COLOR_WHITE);
@@ -218,35 +274,28 @@ void i2c_test(void)
#else ////////for webradio mode display////////////////
SSD1306_Puts("PCM5102A webradio", &Font_7x10, SSD1306_COLOR_WHITE);
SSD1306_GotoXY(2, 30);
-
- SSD1306_Puts(url, &Font_7x10, SSD1306_COLOR_WHITE);
- if (strlen(url) > 18) {
- SSD1306_GotoXY(2, 39);
- SSD1306_Puts(url + 18, &Font_7x10, SSD1306_COLOR_WHITE);
+ if (mode) {
+ SSD1306_Puts("web server is up.", &Font_7x10, SSD1306_COLOR_WHITE);
+ } else {
+ SSD1306_Puts(url, &Font_7x10, SSD1306_COLOR_WHITE);
+ if (strlen(url) > 18) {
+ SSD1306_GotoXY(2, 39);
+ SSD1306_Puts(url + 18, &Font_7x10, SSD1306_COLOR_WHITE);
+ }
+ SSD1306_GotoXY(16, 53);
}
- SSD1306_GotoXY(16, 53);
tcpip_adapter_ip_info_t ip_info;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
SSD1306_GotoXY(2, 53);
SSD1306_Puts("IP:", &Font_7x10, SSD1306_COLOR_WHITE);
- SSD1306_Puts(ip4addr_ntoa(&ip_info.ip), &Font_7x10, SSD1306_COLOR_WHITE);
+ SSD1306_Puts(ip4addr_ntoa(&ip_info.ip), &Font_7x10, SSD1306_COLOR_WHITE);
+#endif
#endif
-
/* Update screen, send changes to LCD */
SSD1306_UpdateScreen();
-
- // while (1) {
- // /* Invert pixels */
- // SSD1306_ToggleInvert();
-
- /* Update screen */
- // SSD1306_UpdateScreen();
-
- /* Make a little delay */
- // vTaskDelay(50);
- // }
-
+
+ l = 0;
}
/**
@@ -406,6 +455,8 @@ static void start_wifi()
ui_queue_event(UI_CONNECTED);
}
+static void http_server(void *pvParameters);
+
static renderer_config_t *create_renderer_config()
{
renderer_config_t *renderer_config = calloc(1, sizeof(renderer_config_t));
@@ -453,6 +504,12 @@ static void start_web_radio()
radio_config->url = get_url(); // play_url(); /* PLAY_URL; */
+ xTaskCreate(&http_server, "http_server", 2048, NULL, 5, NULL);
+ if (gpio_get_level(GPIO_NUM_0) == 0) {
+ while (1)
+ vTaskDelay(200/portTICK_RATE_MS);
+ }
+
// start radio
web_radio_init(radio_config);
web_radio_start(radio_config);
@@ -544,7 +601,7 @@ http_server_netconn_serve(struct netconn *conn)
get_nvurl(i, buf, length);
if (i == stno) netconn_write(conn, "", 3, NETCONN_NOCOPY);
netconn_write(conn, buf, strlen(buf), NETCONN_NOCOPY);
- if (i == stno) netconn_write(conn, " - now playing", 24, NETCONN_NOCOPY);
+ if (i == stno) netconn_write(conn, " - now playing", 18, NETCONN_NOCOPY);
netconn_write(conn, "", 9, NETCONN_NOCOPY);
}
netconn_write(conn, http_e, sizeof(http_e)-1, NETCONN_NOCOPY);
@@ -598,12 +655,20 @@ void app_main()
bt_speaker_start(create_renderer_config());
#else
start_wifi();
- start_web_radio();
-#endif
i2c_example_master_init();
SSD1306_Init();
- i2c_test();
+ i2c_test(1);
+
+ start_web_radio();
+
+ i2c_test(0);
+#endif
ESP_LOGI(TAG, "RAM left %d", esp_get_free_heap_size());
// ESP_LOGI(TAG, "app_main stack: %d\n", uxTaskGetStackHighWaterMark(NULL));
- xTaskCreate(&http_server, "http_server", 2048, NULL, 5, NULL);
+ while (1) {
+ vTaskDelay(40/portTICK_RATE_MS);
+#ifdef CONFIG_SSD1306_6432
+ oled_scroll();
+#endif
+ }
}
diff --git a/main/ssd1306.c b/main/ssd1306.c
index 003deec..d42b80f 100755
--- a/main/ssd1306.c
+++ b/main/ssd1306.c
@@ -7,8 +7,8 @@ static uint8_t SSD1306_Buffer[SSD1306_WIDTH * SSD1306_HEIGHT / 8];
/* Private SSD1306 structure */
typedef struct {
- uint16_t CurrentX;
- uint16_t CurrentY;
+ int16_t CurrentX;
+ int16_t CurrentY;
uint8_t Inverted;
uint8_t Initialized;
} SSD1306_t;
@@ -98,11 +98,8 @@ void SSD1306_Fill(SSD1306_COLOR_t color) {
memset(SSD1306_Buffer, (color == SSD1306_COLOR_BLACK) ? 0x00 : 0xFF, sizeof(SSD1306_Buffer));
}
-void SSD1306_DrawPixel(uint16_t x, uint16_t y, SSD1306_COLOR_t color) {
- if (
- x >= SSD1306_WIDTH ||
- y >= SSD1306_HEIGHT
- ) {
+void SSD1306_DrawPixel(int16_t x, int16_t y, SSD1306_COLOR_t color) {
+ if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT || x < 0 || y < 0) {
/* Error */
return;
}
@@ -120,7 +117,7 @@ void SSD1306_DrawPixel(uint16_t x, uint16_t y, SSD1306_COLOR_t color) {
}
}
-void SSD1306_GotoXY(uint16_t x, uint16_t y) {
+void SSD1306_GotoXY(int16_t x, int16_t y) {
/* Set write pointers */
SSD1306.CurrentX = x;
SSD1306.CurrentY = y;
@@ -130,10 +127,7 @@ char SSD1306_Putc(char ch, FontDef_t* Font, SSD1306_COLOR_t color) {
uint32_t i, b, j;
/* Check available space in LCD */
- if (
- SSD1306_WIDTH <= (SSD1306.CurrentX + Font->FontWidth) ||
- SSD1306_HEIGHT <= (SSD1306.CurrentY + Font->FontHeight)
- ) {
+ if (SSD1306_WIDTH <= SSD1306.CurrentX || SSD1306_HEIGHT <= SSD1306.CurrentY) {
/* Error */
return 0;
}
diff --git a/main/ssd1306.h b/main/ssd1306.h
index 926dd24..672a89e 100755
--- a/main/ssd1306.h
+++ b/main/ssd1306.h
@@ -75,7 +75,7 @@ void SSD1306_Fill(SSD1306_COLOR_t Color);
* @param color: Color to be used for screen fill. This parameter can be a value of @ref SSD1306_COLOR_t enumeration
* @retval None
*/
-void SSD1306_DrawPixel(uint16_t x, uint16_t y, SSD1306_COLOR_t color);
+void SSD1306_DrawPixel(int16_t x, int16_t y, SSD1306_COLOR_t color);
/**
* @brief Sets cursor pointer to desired location for strings
@@ -83,7 +83,7 @@ void SSD1306_DrawPixel(uint16_t x, uint16_t y, SSD1306_COLOR_t color);
* @param y: Y location. This parameter can be a value between 0 and SSD1306_HEIGHT - 1
* @retval None
*/
-void SSD1306_GotoXY(uint16_t x, uint16_t y);
+void SSD1306_GotoXY(int16_t x, int16_t y);
/**
* @brief Puts character to internal RAM
diff --git a/sdkconfig.defaults b/sdkconfig.defaults
index 2c31d85..3783637 100755
--- a/sdkconfig.defaults
+++ b/sdkconfig.defaults
@@ -7,3 +7,5 @@
CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160
+
+FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=n
\ No newline at end of file