WiFi remote for Volumio based on ESP32 and OLED

Thx 4 clarification. I will try and come back soon…

Maybe I should add a few information about the background:
All librarys (JSON, SocketIO, Deflate,…) are written by myself for this project, except the display (u8g2).
As the project is beta, so are the libraries.

Main reason to write them myself was fun and the possibility to design them as “stream”.
Deflate and JSON would otherwise need large amounts of RAM if used one after each other.
Stream means, data is not processed (unzipped, analyzed,…) in batches, but just in time when needed.

Function is as follows:

Communication to Volumio is established via Socket.IO, as described here:
https://volumio.github.io/docs/API/WebSocket_APIs
(the documentation is far from complete, had to use Wireshark on my pc to reverse-engineer some telegrams)

In the beginnning a HTTP-connection is establisthed and then upgraded to Websocket.
This allows Volumio to push status changes to the ESP32.
ESP only has to send some keep-alive-packages now and sthen (ping, all 25 seconds)
All packages are sent with a Socket.IO header. Smaller ones following clear text, formatted as JSON.
On larger packages (playlist, music library), the JSON is compressed with a “deflate-alggoritm” (same as *.zip files)

When receiving data from voulmio the ESP32 first reads the header and decides if it needs to inflate data or not. The data is forwarded to the JSON-parser as stream (uncompressing while reading). After the parser has read the first object (push-type), the Volumio-library analyzes it.
After that it tells the main program if there was a “push” and what type.
The main program then has to call a routine that reads the following data.
Status-update just needs one call, but If array data is pushed by volumio (library-push, queue-push,…), the main program has to read single items in a loop (track-info,…) until all data is read.

Idea is to only keep items in memory that are currently needed and drop everything else as fast as possible to keep buffers small. Otherwise big telegrams may cause an overflow and errors.
My music library is small, so there could be some other limitation that I havent thought of.
e.g. the menu is currently limited to 600 items (menu.h) .
In the beginning it was 200 and I ran into issues when loading the top 500 from webradio.

Actually playing around with my new color oled.
Hard work to get everything running with smooth fonts, but seems worth the effort.
I used Fontbuilder to convert Lato.ttf (Volumio’s font) to a grayscale pixel font.

Still a long way to go :wink:

Really really nice! I like it :wink:

Once running you can do nice things in color.


Very difficult to make good photos of OLED with smartphone camera :frowning:
Also screenshots do look a little different. The truth lies somewhere between.

2020_07_08_11_13_12 2020_07_08_11_13_36 2020_07_08_11_14_06 2020_07_08_11_14_19

1 Like

I ran a few test strings against my JSON-parser and it looks pretty stable, so maybe there is another issue. Could also be WiFi that gets stuck in a loop when trying to reconnect. As said, this thing is tricky to handle.
Maybe you want to program a message on screen when connection is lost.
I had this function in main.cpp, but deleted it accidentally when cleaning up for Rev0.2
(deleted display.firstPage() and “do-while”-loop)

Here is a working function:

void DisplayMessage(String Message)
{
  display.firstPage();
  display.setFont(MenuTextFont);

  display.setFontDirection(0);

  do
  {

	//Logo and single line (true) or 4 lines scrolling (false)
	if (true)
	{

	  display.drawXBM((DisplayWidth - logo_volumio_big_width) / 2, (DisplayHeight / 2 - logo_volumio_big_height) / 2, logo_volumio_big_width, logo_volumio_big_height, logo_volumio_big_bits);

	  //Draw message text
	  int w = display.getUTF8Width(Message.c_str());
	  display.drawUTF8((DisplayWidth - w) / 2, 3 * MenuItemHeight + MenuItemHeight - (MenuItemHeight - MenuTextHeight) / 2, Message.c_str());
	}
	else
	{
	  int msgcnt = 4;

	  messagebuffer[messageindex] = Message;

	  //Draw message texts
	  for (int i = 0; i < msgcnt; i++)
		display.drawUTF8(0, i * MenuItemHeight + MenuItemHeight - (MenuItemHeight - MenuTextHeight) / 2, messagebuffer[(messageindex - i + msgcnt) % msgcnt].c_str());

	  messageindex = (messageindex + 1) % msgcnt;
	}
  } while (display.nextPage());
}

Jens, there seems a much easier function to connect/reconnect WiFi:
Just tried and it works, letting ESP do the work :wink:

Setup:

//Initialize WiFi
WiFi.enableSTA(true);
WiFi.persistent(false);
WiFi.begin(ssid.c_str(), password.c_str());
WiFi.setAutoConnect(true);
WiFi.setAutoReconnect(true);
WiFi.mode(WIFI_STA);

Loop:

//Check if WiFi is connected. If not --> reconnect
while (WiFi.status() != WL_CONNECTED)
{
    DEBUG_PRINT("Main: WiFi: Status: ");
    DEBUG_PRINTLN(WiFiStatusString()); 
    DisplayMessage(locale.ESP.ConnectWiFi);
    delay(1000);
} 

Still not sure if this will make the thing more stable, but I assume the developer may know better than us.

Hi Jens

Enjoy your vacation. Just come back to me when you need support.
By the way: auto-reconnect seems to have the same issues, so maybe a problem in the firmware or WiFi library.
The problem seems to be common, there are multiple search results on google.

Also tried with:

WiFi.disconnect();
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid.c_str(), password.c_str());

And:

if (retrys++ > 10 && WiFi.status() != WL_CONNECTED)
{
    DEBUG_PRINT("Main: WiFi: Too many retrys, restarting ESP");
    ESP.restart();
}

But nothing seems to get 100% stable :frowning:

Hi,

Finally I received my ordered ESP32.
Iam using Arduino IDE which is configured to use with ESP32 boards, but I don’t understand how i can upload the code, the IDE expects an ino-file!

Any help/tips?

Harry

Hi Harry

I assume you should just rename the main.cpp to main.ino
Didnt use the Arduino IDE for a while, but you also may have to copy all library files to the same folder.

Maybe you want to take a look at Visual Studio Code with PlatformIO.
Compiler and IntelliSense is way more better and its also free.

Jakob

Jakob,

At frist I thought that it “MS Visual studio”
But it is a different program by Microsoft and also available for Linux so I Will give it a try!

Kind regards

Harry

@drvolcano Awesome Job! Really awesome!

Wonderfull job! very nice and clean

I recently started work on a similar project to control Volumio with rotary encoders and momentary button with an ESP8266 board so am happy to find this!

I imagine the code for the ESP32 will be close to what I need…since I have a small drawer full of Wemos D1 Mini Pro ESP8266 boards…

My project also includes coordinating with an Arduino Mega 2560 to control relays for managing charge-discharge cycles in a hybrid LifePo4-Ultracapacitor power supply system. If there’s interest in extending to this aspect I can share as it evolves.

Would be cool if you could share you project with us when you are done.

Hi!

i try to use your small oled settings code:
Modifications:

1.) i used a different display. I only had an oled 126x64, so i tried this and was successful :grinning:
#define PIN_SPI_SCL 22
#define PIN_SPI_SDA 21
U8G2_SSD1306_128X64_NONAME_1_SW_I2C display(U8G2_R2, /* clock=/ 22, / data=/ PIN_SPI_SDA, / reset=*/ U8X8_PIN_NONE);

but display doesnt work,
can you share your full config file source code?