Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Millis() function is extremely inaccurate when playing audio on Feather M0 #50

Open
geekfactory opened this issue Jan 15, 2019 · 2 comments

Comments

@geekfactory
Copy link

geekfactory commented Jan 15, 2019

  • Arduino board: Feather M0 basic proto + Adafruit Music Maker Feather Wing
  • Arduino IDE version: 1.8.5
  • Problem: The millis function is very inaccurate when playing an audio file. I have a sketch which uses the millis function to blink a led once every 3 seconds, the led is on for only 300 mS. When the library is playing music the 300 mS time goes to 429 mS (that’s almost 150 %). The file is 320 kb/s MPEG Audio Layer ½, dual channel mono, 44100 Hz, 32 bits.

The millis function is also used on my program to keep track of time using Unix time (not only to blink leds), so it´s desirable to keep timings as accurate as possible.

I know this file is high bitrate, but we´re developing a prototype for a third party. It should be able to handle high bitrate files, because the final user might not be able to tell if an MP3 file is 128 or 320 kbps.

The problem seems to be related to how the code handles the DREQ interrupt, as this function takes several milliseconds to execute while the data is transferred from the SD card and then to the VS1053. In the mean time the Systick might not be handled correctly.

Possible solutions that I thought:

  • Raise the priority of the interrupt used for millis() so it can nest in the DREQ interrupt (not sure about the side effects of this and if it is even possible because of how NVIC is initialized, involves messing with the Arduino core).
  • Not use interrupts at all and handle all the data buffer feeding on the main loop.

Has anybody else experienced this problem, is there a workaround for this?

Thank you in advance.

@TheNitek
Copy link
Contributor

On my ESP8266 I do not use the interrupts and feed the buffer inside of the main loop. Works great (also I did not try 320kps MP3s yet) and my guess would be that it solves your problem, so why not give it a try? Should be an easy fix.

@geekfactory
Copy link
Author

Hi @TheNitek I tested by raising the interrupt priority for the SysTick on the arduino core initialization and lowered the priority for the external interrupts (used by the VS1053 library). Now the code works as expected but still not convinced of this because involves messing with the Arduino core.

Feeding the buffer inside the main loop is the easiest solution, but because most of the Arduino libraries implement some kind of blocking behavior (specially the networking ones). Doing the buffer on the main loop doesn´t looks like the best approach, especially on complex projects that might include such libraries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants