I am loooking for some guidance. I am fond of music; computers and dyi. As a result I decided to build my own music streamer a few months back. I manged to get a nice chassis in which I implemeted a mini itx board , an home made ppower supply and an arduino and an oled screen.
The idea was to install daphile on the pc part. this would provide the music streaming part. The arduino + OLED was aiming at displaying song and artist infos. To achieve this, I had to covince the developer of daphile to add an option to allow some port redirection to the serial port. After several emails exchanges and tests the option was integrated in the daphile code as a hidden option.
I had then to work with the arduino. First get the arduino and the OLED to work together (fighting with pins ). Once done, i could start developing a bit of code to retrieve the necessary infos from the serial port. Indeed when connected to the pc, ther arduino board appears as a TTYACMx. With the help of my son, who is way brighter than I will ever be...we managed to develop some code that in the end is somehow producing what we want 85% of the time.
85% is fine but there is room for improvment ! however, i think that i reached my limits in terms of programming...I am not a developper and all that we did, we achieved it reading all the different online helps and googling all over to figure out how to do it...
here is the latest version of the code that lsitens on the serial port and parses some infos then displays it.
daphile here
//version daphilePlayer2Test1 : addon list caracteres UTF8-rework affichetexte maj et min (virer integer, delay en dur a 250) compliled with IDE1.6.5
// include the library code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(6, 7, 8, 10, 11, 12, 13);
String playerId;
String statusRequest;
String artist;
String song;
int posArtist;
int posSong;
int dirArtist;
int dirSong;
String centered(String text)
{
int len = text.length(), numSpaces;
String centeredText;
if (len > 16)
{
return text;
}
numSpaces = (16 - len)/2;
centeredText.reserve(16);
centeredText = text;
for (int i = 0; i < numSpaces; i++)
{
centeredText = " " + centeredText + " ";
}
if (len % 2)
{
centeredText = centeredText + " ";
}
return centeredText;
}
void afficheTexte(String *lines)
{
String lgnHaut = centered(lines[0]);
String lgnBas = centered(lines[1]);
int len = 16;
for (int i = len; i >= 0; i--)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(lgnHaut.substring(i));
lcd.setCursor(0,1);
lcd.print(lgnBas.substring(i));
delay(300);
}
}
void setup()
{
delay(5000);
char serialAnswer[1024];
String initLines[] = { "V7", "DAPHILE PLAYER" }, lmsAnswer;
String DediLines[] = { " Arduino Code" , "by Thibault" };
String PlayLines[] = { " Let's listen to" , " some music now!"};
playerId.reserve(17);
lcd.begin(16, 2);
lcd.clear();
afficheTexte(initLines);
delay(4000);
afficheTexte(DediLines);
delay(2000);
afficheTexte(PlayLines);
delay(3000);
afficheTexte(initLines);
delay(4000);
Serial.begin(9600);
Serial.print("player id 0 ?\n");
while (!Serial.find("player id 0 ?\r\nplayer id 0 "))
{
delay(500);
}
Serial.readBytes(serialAnswer,27);
lmsAnswer = serialAnswer;
playerId = lmsAnswer.substring(0,27);
playerId.replace("%3A",":");
statusRequest = playerId + " status - 1 tags:a subscribe:0";
Serial.print(statusRequest + "\n");
statusRequest.replace(":","%3A");
}
void loop()
//After creating a setup() function, which initializes and sets the initial values, the loop() function does precisely what its name suggests, and loops consecutively, allowing your program to change and respond. Use it to actively control the Arduino board.
{
char request[51];
char statusUpdate[2048];
String statusUpdateString = "";
String time, artist, song, duration, title, durationDisplay;
String topline, bottomline;
statusRequest.toCharArray(request,51);
int len, posTime, posRate, posArtist, posSong, posDuration, posTitle, posCanSeek, durMin, durSec;
int artistlen, titlelen;
int myLongestLine = 0; // length of the longest line to display
int myStep = 0; // current step while looping
int myLength = 16;
while (!Serial.find(request) && !Serial.find("mode%3Aplay") && !Serial.find("time%3A"))
{
delay(500);
}
len = Serial.readBytesUntil('\n', statusUpdate, 2048);
statusUpdateString = statusUpdate;
statusUpdateString = statusUpdateString.substring(0,len);
posTime = statusUpdateString.indexOf("time%3A") + 7;
posRate = statusUpdateString.indexOf("rate%3A") - 1;
posDuration = statusUpdateString.indexOf("duration%3A") + 11;
posCanSeek = statusUpdateString.indexOf("can_seek%3A") - 1;
posTitle = statusUpdateString.indexOf("title%3A") + 8;
posArtist = statusUpdateString.indexOf("artist%3A");
time = statusUpdateString.substring(posTime, posRate);
duration = statusUpdateString.substring(posDuration, posCanSeek);
title = statusUpdateString.substring(posTitle, posArtist - 1);
//Returns the length of the String, in characters. (Note that this doesn't include a trailing null character.)
artistlen = artist.length();
titlelen = title.length();
title.replace("%20"," ");
title.replace("%21","!");
title.replace("%23","#");
title.replace("%24","$");
title.replace("%2C",",");
title.replace("%2D","-");
title.replace("%2E",".");
artist = statusUpdateString.substring(posArtist + 9);
artist.replace("%20"," ");
artist.replace("%21","!");
artist.replace("%C3%98","Ø");
artist.replace("%C3%99","Ù");
artist.replace("%C3%9A","Ú");
artist.replace("%C3%9B","Û");
artist.replace("%C3%9C","Ü");
artist.replace("%C3%9D","Ý");
artist.replace("%C3%9E","Þ");
artist.replace("%C3%9F","ß");
artist.replace("%C3%A0","À");
artist.replace("%C3%A1","Á");
artist.replace("%C3%A2","Â");
artist.replace("%C3%A3","Ã");
artist.replace("%C3%A4","Ä");
artist.replace("%C3%A5","Å");
artist.replace("%C3%A6","Æ");
artist.replace("%C3%A7","Ç");
artist.replace("%C3%A8","È");
artist.replace("%C3%A9","É");
artist.replace("%C3%AA","Ê");
artist.replace("%C3%AB","Ë");
artist.replace("%C3%AC","Ì");
artist.replace("%C3%AD","Í");
artist.replace("%C3%AE","Î");
artist.replace("%c3%bf","ÿ");
//Get a version of the String with any leading and trailing whitespace removed. As of 1.0, trim() modifies the string in place rather than returning a new one.
artist.trim();
title.trim();
lcd.clear();
if (artist.length() >= 16)
{
artist = artist.substring(0,10) + "...";
}
if (title.length() >=16)
{
title = title.substring(0,10) + "...";
}
String displayInfo[] = { artist, title };
{
afficheTexte(displayInfo);
}
}
note : I had to retrieve a lot of the replace lines as the it went beyond the 9000 caracters limit of the post. Consider that there are around 150 lines of replace
Now what kind of help do I need?
well any
What i really would like to achieve is the following:
Any time the arduino starts, it has to synch with the LMS and retrieve the infos (the display offers two lines 16*2) I use the top line for artist name and the bottom one for the song right now. But ultimately, I would love to display additionnal infos like sample rate that comes from the LMS cli.
I also get issues with UTF-8 caracters. That 's why I added the replace list in the end...It eats some memory and i saw that somehow it get the arduino to crash...so any code optimization is also welcome
I know it seems a lot but really I don't think I can go further and it is frustrating...
thanks for your help
pattdepanick