Serial read code

Hy, I want to read serial, filename of playing song specificly. If I use short filenames like "test1.mp3" for example, names get displayed correctly, if I use longer filenames I get "error1" from return "error1"; function.

I dont quite understand what this code is doing exactly. I know that error1 is returned if code didn`t manage to do its thing in 1000miliseconds and I know that \n\r breaks the code (thats good).
Can someone please explain the code, I need to change something, to avoid errors.

Serial input should look like that: "MF+filename.mp3 \n\r"

String DFRobot_BT401::readAck(uint8_t len)
{
  String str="                             ";
  size_t offset = 0,left = len;
  long long curr = millis();
  if(len == 0){
    while(1) {
      if(_s->available()) {
        str[offset]= _s->read();
        left--;
        offset++;
      }
      if(str[offset - 1] == '\n' && str[offset - 2] == '\r') break;
      if(millis() - curr > 1000) {
        return "error1";
        break;
      }
    }
  } else {
    while(left) {
      DBG(left);
      if(_s->available()) {
         str[offset]= _s->read();
        left--;
        DBG(str[offset]);
        offset++;
      }
      if(millis() - curr > 1000) {
        return "error2";
        
      }
  }
  str[len]=0;
  }
  DBG(str);
  delay(1);
  return str;
}

Did you write the code? What part of it you do and do not understand?

If you are referring to this line:

if(str[offset - 1] == '\n' && str[offset - 2] == '\r') break;

what it does is it breaks out of the while loop when it sees a string terminated by a DOS-style line break (i.e. a newline character '\n' plus a carriage return character '\r'). This is bad practice, by the way, because this won't work with *NIX line breaks (a '\n' by itself). What OS is your computer running?

This code is part of the library. Im not interfacing with computer, but DF robot bt401 bluetooth / usb / tf card mp3 player module.
I send AF+MF command to it and it`s response is MF+"filename"\n\r

My problem is that if I have a file with long name I get error1.

I dont understand exactly how code forms a string str that gets returned, what happens when time expires and error1 returns...
Code was intended to read short messages like "\n\r", "OK" and telephone numbers...
And I need to find a reason why it doesn`t work with longer messages.

Does the input upstream actually output all the chars in the name? It looks like they are truncated at n chars, before the carriage return is reached. Do you have spaces or special characters in your filenames? Get rid of those and try again. Does it work if you use a static c-string buffer longer than the longest input you are expecting?

I dont know if it outputs all the chars, will try with basic serial.read command, I need to setup software serial and use usb-ttl to diagnose.... But board should output it corectly.
I have spaces and characters like ( ) - ,... They are names of actual songs and I would need it to work with actual song names as this is part of my usb integration in bmw e39 radio...
I tried to make buffer longer and result is the same.

This is a bad idea all by itself. Special characters and spaces in filenames sometimes work and sometimes don't. Safe ASCII chars always do work. Sanitize your names and you'll have one less thing to worry about.

The proper way to display a song name is to look into the file's metadata (the ID3 tag in your case), not to parse the filename itself. Make the filename just a rough imitation of the title for your convenience, but don't encode actual information in it.

Will do some digging when I get home from work...
I never liked the metadata concept of displaying filenames.

Any particular reason why? Metadata, by the way, has nothing to do with filenames. The two can, and should be kept separate, because they are used for different purposes altogether. Metadata is meant to display information about the audio file such as the title, the artist, the album... I'm sure you are familiar with the concept, are you not? Using the filename itself to encode that stuff is a dirty hack that will come back to haunt you sooner or later (and it looks like it already did).

Yes, I always prefered filename to be shown... It's just the way I like it, no need to care if file has metadata or not when loading 150 songs on flash drive.
The mp3 decoder board also cant query metadata, just filenames.

Your choice. However, things are not quite working for the time being, are they?

What board are you using?

I will make it work.

I`m using bt201 board by DF Robot.

You were totaly right.
If I name a song without spaces it works and buffer must be longer than the song name.

I would die for metadata support right now, but as it is not supported I will have to rename songs using _ instead of spaces...

Good, I see that I've made a new convert :wink:

This seems weird to me: MP3 is an ancient format and the ID3 tag, either in version 1.1 or 2.3, is widely supported across devices. As a last resort, you can try to implement ID3 support yourself by parsing the MP3 binary file itself. The format is extremely well documented all over the web, so it shouldn't be a problem. Try to go for ID3 v. 2.3 first if you can, because it can hold more info and also, it sits at the head of the file, as opposed to the tail, like is the case with v. 1.1, so you don't have to parse the whole audio data to reach it.

Another solution, of course, would be to replace your contraption by a single board computer (like a Raspberry or a Banana Pi) that will be able to take care of everything and read many more formats besides MP3, like FLAC, Vorbis, APE, WavePack, Opus and what have you.

Board communicates with cmd AT commands, I have no direct access to files. I only have option to send AT command and listen for the ack response.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.