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 webradio

Web radio station list

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