Forum: Mikrocontroller und Digitale Elektronik Arduino Nano, SD Card, PCM


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Mr D. (Gast)


Lesenswert?

Hallöchen

Ich benutze ein Arduino Nano für eine PCM Ausgabe Port (Pin 3),
die Ausgabe wird mittels Timer 1 auf 8 kHz eingestellt und via Timer2 
auf den PWM Port ausgegeben. Das Ganze wird via I2C Angesteuert (Pin 
A4/A5) um den Sound auszuwählen.

Das funktioniert so weit so gut...
Nun wollte ich einen SD Card die via SPI angesteuert wird (Adafruit SD) 
hinzufügen, damit man die PCM RAW Dateien via SD Card ausgeben kann, da 
im Memory leider kein Platz ist für alle Dateien.

Das Problem ist nun das die SD Card irgendetwas mit Timer 2 zu tun hat 
und / oder CLI STI befehle verwendet. Dadurch wird der Sound 
zerstückelt, funktioniert zwar alles aber man hört leider die 
Unterbrüche.

Weiss jemand dafür eine Lösung oder kann mir jemand sagen wo ich genau 
suchen muss. Bei den SD Dateien bin ich nicht fündig geworden.

Würde mich freuen, wenn mir jemand helfen könnte oder eine andere Idee 
hat wie ich das Problem möglichst günstig lösen kann.

(Ich habe mir mal einen Adafruit DAC Bestellt der via I2C läuft, evtl. 
bekomme ich es damit in den Griff, da dieser interne Buffer hat und mit 
anderen Prozessoren, ausser Arduino, bis 200khz funktioniert).

Bin offen für Vorschläge oder Hinweise.
Gruss

von Falk B. (falk)


Lesenswert?

Dein Board gibt es fix und fertig für wenig Geld zu kaufen, 
Micro-SD-Karte + AVR für Soundausgabe.

Google wave player avr

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Da der Mikrocontroller auf dem Arduino Nano Board weder einen DMA 
Controller noch einen Audo-Ausgang mit FiFo Puffer hat, kann er nur 
abwechselnd das PCM Signal erzeugen und auf die SD Karte zugreifen.

Beides Gleichzeitig wäre mit einem aufwendigen Kunstgriff in der 
Software machbar, aber dann musst du die Treiber für die SD Karte und 
die PCM Ausgabe selber neu schreiben und zu einer kooperativen Einheit 
verschmelzen.

Für diese Anwendung würde ich lieber einen Mikrocontroller nehmen, der 
ein ordentliches SDIO Interface und einen DMA Controller hat. Zum 
beispiel den STM32F103C8T6, der auch von Arduino unterstützt wird und 
als Modul ähnliche Abmessungen hat, wie der Arduino Nano.

Allerdings weiss ich nicht, ob das Arduino Framework den DMA Controller 
im Sinne deiner Anwendung unterstützt. Eventuell wirst du bevorzugen, 
ihn "zu Fuß" zu programmieren (ohne Libraries) oder mit Hilfe der Cube 
HAL vom Chiphersteller anstatt des Arduino Frameworks.

> Ich habe mir mal einen Adafruit DAC Bestellt der via I2C läuft, evtl.
> bekomme ich es damit in den Griff, da dieser interne Buffer hat

Der Buffer würde vermutlich dein Problem lösen, wenn er groß genug ist. 
Ich würde es nochmal damit versuchen.

von Falk B. (falk)


Lesenswert?

@Stefan Us (stefanus)

>Da der Mikrocontroller auf dem Arduino Nano Board weder einen DMA
>Controller noch einen Audo-Ausgang mit FiFo Puffer hat, kann er nur
>abwechselnd das PCM Signal erzeugen und auf die SD Karte zugreifen.

So ein Unfug! Schon mal was von Hardware-PWM und Interrupt gehört?

>Software machbar, aber dann musst du die Treiber für die SD Karte und
>die PCM Ausgabe selber neu schreiben und zu einer kooperativen Einheit
>verschmelzen.

Nö, siehe oben.

>Für diese Anwendung würde ich lieber einen Mikrocontroller nehmen, der
>ein ordentliches SDIO Interface und einen DMA Controller hat.

Braucht man nicht, wie mehrere Projekte seit Jahren beweisen.

http://elm-chan.org/works/sd8p/report.html

Vom (fernen) Osten lernen heißt siegen (programmieren) lernen. ;-)

von Stefan F. (Gast)


Lesenswert?

> Braucht man nicht, wie mehrere Projekte seit Jahren beweisen.

Das weis ich, aber es ist kompliziert.

von Falk B. (falk)


Lesenswert?

@Stefan Us (stefanus)

>> Braucht man nicht, wie mehrere Projekte seit Jahren beweisen.

>Das weis ich, aber es ist kompliziert.

Wenn dir das Nachladen einer PWM in einem dazugehörigem Interrupt zu 
kompliziert ist, sehe ich für dein Hobby Elektronik/uC eher schwarz.

von Mr D. (Gast)


Lesenswert?

Genau, es ist bekannt das es funktioniert, das zeigen mehrere Projekte.

Leider habe ich den Trick noch nicht raus warum der SD.read() diese 
Löcher verursacht.

Bei anderen funktioniert das ja und ja es wird bereits jetzt (wie ich 
oben ja geschrieben habe) in einem Timer 2 Interrupt nachgeladen, resp. 
von der SD Card gelesen. Puffer ist nicht möglich der Grösser als 256 
Bytes ist, da der Speicher sehr begrenzt ist.

Timer1: 8khz (isr call)
Timer2 = PWM: nach laden

Werde dann sehen wenn ich den DAC bekomme ob das mit diesem 
funktioniert.
Zeti mässig müsste es gehen, aber ich denke das Problem liegt an den CLI 
und STI der SD classe, oder ich initialisiere SD falsch mit begin()...
Konnte leider keine genaue Anleitung / Beschreibung zu SD Library 
finden.

Aber anscheinend gibt es mehre Möglichkeiten diese zu initialisieren.

Dank und Gruss!

von Stefan F. (Gast)


Lesenswert?

Du musst nicht unbedingt die Library benutzen. Kannst die SPI 
schnittstelle auch selbst "zu Fuß" ansprechen.

von yesitsme (Gast)


Lesenswert?

Ich seh jetzt keinen Quellcode von dem problematischen Projekt...

Von daher: in Zeile 42 ist der Fehler.

von Mr D. (Gast)


Lesenswert?

Also das mit dem MCP4725 klappt nicht so wie gedacht.

Der Sound ist zwar massiv besser als mit dem PWM Ausgang.

Jedoch wird Wire im ISR benutzt, dazu musste ich die Interrupts wieder 
gezielt in ISR ein- ausschalten und die routine mit einem Flags 
aushandeln damit die andern ISR laufen können...

Vorteil 4725: besserer Sound und nur noch ein Interrupt, der für den PWM 
fällt weg. Zudem ist der Chip bis 12bit (0-4096). (8 Bit muss ich mit 4 
multiplizieren, damit ich wieder die 5 Volt habe).

Leider ist der Unterbruch immer noch, und wird von der SD Carte selber 
verursacht.

Keinen Plan wie ich das beheben kann.

von Stefan F. (Gast)


Lesenswert?

> Leider ist der Unterbruch immer noch, und wird von der SD Carte
> selber verursacht.

Vermutlich durch einen richtig großen Pufferspeicher. Soviel RAM haben 
die AVRs alle nicht (intern).

von Mr D. (Gast)


Lesenswert?

Stefan U. schrieb:
>> Leider ist der Unterbruch immer noch, und wird von der SD Carte
>> selber verursacht.
>
> Vermutlich durch einen richtig großen Pufferspeicher. Soviel RAM haben
> die AVRs alle nicht (intern).


Ja habe gerade einen Test gemacht mit dem DUE und dem internen DAC mit 
einem Timer zu Ausgabe.

Alle 512 Lesungen (Bytes) gibt es eine Lesung mit 2000 - 4500 micros...
Genau das sind die Drops die es dann gibt... sieht so nach Sektoren 
aus...

Frage mich warum diese Adafruit SD Card solche massiven Timeouts hat.
Und warum es anscheinend bei anderen funktioniert...

von Stefan F. (Gast)


Lesenswert?

> Frage mich warum diese Adafruit SD Card solche massiven Timeouts hat.

Das ist bei allen SD Karten so. Aussetzer bis zu 500ms werden als 
"normal" betrachtet. In der Zeit wollen sie aber getaktet werden. Sonst 
wartest du noch länger. Deswegen eignen sich SD karten als 
Massenspeicher an kleinen µC eben nur bedingt.

von Falk B. (falk)


Lesenswert?

@Mr Des (mrdes)

>Alle 512 Lesungen (Bytes) gibt es eine Lesung mit 2000 - 4500 micros...
>Genau das sind die Drops die es dann gibt... sieht so nach Sektoren
>aus...

Sind es auch.

>Frage mich warum diese Adafruit SD Card solche massiven Timeouts hat.

Hat sie das?

>Und warum es anscheinend bei anderen funktioniert...

Weil die ein besseres Programmkonzept haben. Es reicht NICHT, einen 
Puffer immer mal zu füllen, man muss schon nachladen, wenn der Puffer 
noch eher halb voll ist. Im einfachsten Fall würde man 2x512 Bytes 
nutzen, das ist genau ein Sektor und das ist einfach machbar. Die Puffer 
werden im Wechsel gelesen (PWM-Ausgabe) und geschrieben (SD-Karte). Das 
Ganze geht natürlich auch mit weniger, wenn gleich dann bisweilen der 
SD-Zugriff ineffizienter wird. Außerdem puffern die allermeisten, 
gescheiten SD-Bibliotheken so oder so 1 kompletten Sektor im RAM.

Wenn man es richtig macht (tm), ist die Audioausgabe unterbrechungsfrei. 
Denn Lesen von der SD-Karte ist recht deterministisch und schnell, da 
gibt es keine großen, undefinierten Wartezeiten, im Gegensatz zum 
Schreibzugriff.

von Falk B. (falk)


Lesenswert?

@ Stefan Us (stefanus)

> Frage mich warum diese Adafruit SD Card solche massiven Timeouts hat.

>Das ist bei allen SD Karten so. Aussetzer bis zu 500ms werden als
>"normal" betrachtet.

Stefan, tu dir und vor allem uns den Gefallen und lass deine 
"Expertentipps" einfach stecken. Ich mach mal den Nuhr

"Wenn man keine Ahnung hat, einfach mal Fresse halten."

>wartest du noch länger. Deswegen eignen sich SD karten als
>Massenspeicher an kleinen µC eben nur bedingt.

Unfug! Siehe oben! Der Original-PCM-Player von Elm CHAN läuft auf einem 
Attiny85! Der hat nur 512Bytes RAM!

http://elm-chan.org/works/sd8p/report.html

"Using the memory cards on the embedded projects means that the firmware 
needs to support FAT file system. I used Petit-FatFs module branched 
from full featured FatFs module. The Petit-FatFs was developped for very 
small memory system with RAM size is less than 512 bytes. It is suitable 
for tiny AVRs and PICs."

Das Petit-FatFS ist in C geschrieben, der Player somit also auch!

von Mr D. (Gast)


Lesenswert?

Falk B. schrieb:

> Weil die ein besseres Programmkonzept haben. Es reicht NICHT, einen
> Puffer immer mal zu füllen, man muss schon nachladen, wenn der Puffer
> noch eher halb voll ist. Im einfachsten Fall würde man 2x512 Bytes
> nutzen, das ist genau ein Sektor und das ist einfach machbar. Die Puffer
> werden im Wechsel gelesen (PWM-Ausgabe) und geschrieben (SD-Karte). Das
> Ganze geht natürlich auch mit weniger, wenn gleich dann bisweilen der
> SD-Zugriff ineffizienter wird. Außerdem puffern die allermeisten,
> gescheiten SD-Bibliotheken so oder so 1 kompletten Sektor im RAM.

Sorry ich lese keinen Buffer
ich lese immer ein Byte und wenn ein Byte zwischen den Samples, bereits 
solche drops verursacht, würde ich mich niemals getrauen einen Buffer 
einzulesen... der würde bestimmt 2x solche drops verursachen wenn ich 
1024 Bytes lesen würde.

Wird es mal mit einfacher FAT ausprobieren.
Danke.

von Falk B. (falk)


Lesenswert?

@Mr Des (mrdes)

>Sorry ich lese keinen Buffer

Fehler 1

>ich lese immer ein Byte und wenn ein Byte zwischen den Samples, bereits

Fehler 2

>solche drops verursacht, würde ich mich niemals getrauen einen Buffer
>einzulesen... der würde bestimmt 2x solche drops verursachen wenn ich
>1024 Bytes lesen würde.

Fehler 3

>Wird es mal mit einfacher FAT ausprobieren.

Fehler 4

Ergo. Dein Konzept ist unbrauchbar. Ich wage die Behauptung, daß man es 
auch mit der einfachen SD-Bibliothek von Adafruit hinbekommt, wenn der 
Rest stimmt.

von batman (Gast)


Lesenswert?

Die Massenspeicher arbeiten intern immer blockweise und haben 
entsprechende Zugriffszeiten. Auch wenn du nur 1 Byte liest, muß der 
ganze Sektor erstmal adressiert und geladen werden, wenn nicht schon 
geschehen. Das ist vermutlich das Knacken, was du hörst. Das kann so 
nicht funktionieren.

von Stefan F. (Gast)


Lesenswert?

Falk, wir beide sind schon zu alt um uns gegenseitig auf diese 
herablassende Art zu belehren. Damit wirst du bei mir keine Gegenliebe 
erwirken, schon gar nicht dass ich deine Ausführungen bereitwillig 
annehme.

Ich habe NICHT geschrieben, dass SD Karten und µC zusammen nicht 
funktionieren. Ich habe auch nicht behauptet, dass man damit keine MP3 
Player bauen kann.

Mein Aussage, dass sie nur bedingt geeignet sind zeigt sich doch schon 
in den zahlreichen Problemberichten in diesem Forum. Jeder zweite 
Programmierer zeigt sich über die Verzögerungszeiten überrascht.

> "Wenn man keine Ahnung hat, einfach mal Fresse halten."
Ja, und der Ton macht die Musik.

Dennoch sind wir uns wohl alle einig, dass das Lesen von der Karte in 
größeren Blöcken (vielfache von 512), sowie Pufferung der Daten der Weg 
zur Lösung sind.

von Falk B. (falk)


Lesenswert?

@Stefan Us (stefanus)

>Falk, wir beide sind schon zu alt um uns gegenseitig auf diese
>herablassende Art zu belehren.

Wahre Worte sind nicht schön, schöne Worte sind nicht wahr.

Laotse

> Damit wirst du bei mir keine Gegenliebe
>erwirken, schon gar nicht dass ich deine Ausführungen bereitwillig
>annehme.

Hab ich gar nicht vor. Die Welt ist voller Ignoranten, einer mehr oder 
weniger spielt keine Rolle.

>Ich habe NICHT geschrieben, dass SD Karten und µC zusammen nicht
>funktionieren. Ich habe auch nicht behauptet, dass man damit keine MP3
>Player bauen kann.

Das hat auch gar keiner behauptet ;-)

>Mein Aussage, dass sie nur bedingt geeignet sind zeigt sich doch schon
>in den zahlreichen Problemberichten in diesem Forum. Jeder zweite
>Programmierer zeigt sich über die Verzögerungszeiten überrascht.

Falsch! Diese Verzögerungszeiten gibt es beim LESEN NICHT! Und das hast 
du, warum auch immer, unterschlagen.
Deine Beiträge in dieser Diskussion sind nix als Bedenkenträgerei.
Du malst den Teufel an die Wand und siehst überall nur Probleme. Das 
geht mir schlicht und ergreifend auf den Keks.

Suche Lösungen, keine Fehler!

Henry Ford

DAS ist MEIN Motto. Jeden Tag.

>> "Wenn man keine Ahnung hat, einfach mal Fresse halten."
>Ja, und der Ton macht die Musik.

Es ist ein klassisches Zitat, und das ist mit voller Absicht nicht 
butterweich.

>Dennoch sind wir uns wohl alle einig, dass das Lesen von der Karte in
>größeren Blöcken (vielfache von 512), sowie Pufferung der Daten der Weg
>zur Lösung sind.

Das war nie die Frage.

von Stefan F. (Gast)


Lesenswert?

> Falsch! Diese Verzögerungszeiten gibt es beim LESEN NICHT! Und
> das hast du, warum auch immer, unterschlagen.

Worum geht es dann in diesem Thread? Fragen wir doch mal Mr Des:

>Alle 512 Lesungen (Bytes) gibt es eine Lesung mit 2000 - 4500 micros...

Es geht um Verzögerungszeiten. Und glaube mir, ich habe auch größere 
sporadische Aussetzer gesehen, sonst würde ich das hier nicht schreiben.

von Falk B. (falk)


Lesenswert?

@ Stefan Us (stefanus)

>> Falsch! Diese Verzögerungszeiten gibt es beim LESEN NICHT! Und
>> das hast du, warum auch immer, unterschlagen.

>Worum geht es dann in diesem Thread? Fragen wir doch mal Mr Des:

>>Alle 512 Lesungen (Bytes) gibt es eine Lesung mit 2000 - 4500 micros...

Es geht darum, daß der OP ein paar wesentliche Dinge, welche man für so 
ein Unterfangen braucht, noch nicht verstanden hat.

>Es geht um Verzögerungszeiten.

Jaja, die liebe Besserwisserei. Jetz komm mir am besten noch damit, daß 
auch 1us eine Verzögerung ist.

> Und glaube mir, ich habe auch größere
>sporadische Aussetzer gesehen, sonst würde ich das hier nicht schreiben.

Soso? Wie groß denn? Ganz sicher KEINE 500ms, die du hier genannt hast.
Und nur weil hier irgendjemand was "sieht", heißt das noch lange nicht, 
daß der Effekt echt ist. Meist sind es Meß- oder Anwenderfehler, die vor 
allem von der Masse der hier anwesenden Hobbybastler gemacht werden. Der 
2. Fehler liegt dann darin, daß als Gesetzmäßigkeit zu interpretieren.

von Mr D. (Gast)


Lesenswert?

Also ich habe mit dem internen SD auf einem DUE Board welches ja mit 84M 
getakted wird, einen Test gemacht.

Datei öffen,
lesen von einem Byte
zähler erhöhen
MICROSEKUNDEN ausgeben
z = micros();
x = file.read();
printf(micros() - z);
while bis alle gelesen.

Ergebnis, alle read haben ca. 5-7 mikros
alle 512 bytes sind es 2500 - 4500 mikros.

Und das sind TATSACHEN!

Es kann sein, dass wenn man mit read einen Bereich einliest, die 5 dann 
vielleicht 10 mikros sind, nur das Problem ist ich habe kein memory, 
also muss ich das mit read und einem byte lösen, das ganze soll ja auf 
einem nano laufen und nicht auf einem due

Die Samples sind 8khz, das sind 125 uS, also wird ja bei 3000uS mehrere 
Samples unterbrochen, das kann ja gar nie funktionieren!
Ausser man kann das ganze so drehen wenn man den SD treiber selber neu 
schreibt mit nur den nötigen sachen.

SPI benutzt immer den gleichen Taktfrequenz, leider kann man diese auch 
nicht ändern... habe jedenfalls nichts dazu gefunden.

Ich denke wir lassen das mal so stehen, da es leider bereits wieder 
streit gibt hier. ich weiss jedenfalls das es nicht an meinem Programm 
liegt, ansonsten ja ein reines lesen schon bereits viel schneller 
wäre...

von Stefan F. (Gast)


Lesenswert?

>> Und glaube mir, ich habe auch größere
>> sporadische Aussetzer gesehen, sonst würde ich das hier nicht schreiben.

> Soso? Wie groß denn? Ganz sicher KEINE 500ms

Richtig, beim lesen hatte ich nur wenige Millisekunden. Ich weiss den 
konkreten Wert nicht mehr, aber es waren auf jeden Fall weit unter 100ms 
jedoch mehr als 1ms.

> also wird ja bei 3000uS mehrere
> Samples unterbrochen, das kann ja gar nie funktionieren!

Richtig, so wie du es implementiert hast, kann es nicht funktionieren.

Die SD Karte wird mit sehr hoher Wahrscheinlich in 512k Blöcken gelesen. 
jedenfalls sollte man so tun - oder gar ein Vielfaches davon. Du hast 
4,5ms im worst case gemessen. Dass heisst, dass du alle 4,5ms 512 Bytes 
lesen kannst.

Das sind etwas mehr als 1 Megabit pro Sekunde. Für MP3-Wiedergabe sollte 
das locker reichen.

Du musst nur noch hinbekommen, die Daten an den Audio-Chip zu übergeben 
während du mit der SD Karte kommunizierst. Dann ist es nur noch eine 
Frage von ausreichend viel Pufferspeicher. Wenn dein Gerät sonst nicht 
viel RAM belegt könnte es mit dem internen RAM klappen. Ich nehme an, 
dass dein Audio IC auch ein bisschen Puffer hat, der Dir dabei hilft.

von Falk B. (falk)


Lesenswert?

@Mr Des (mrdes)

>Also ich habe mit dem internen SD auf einem DUE Board welches ja mit 84M
>getakted wird, einen Test gemacht.

>Datei öffen,
>lesen von einem Byte
>zähler erhöhen
>MICROSEKUNDEN ausgeben

Quelltext?

>z = micros();
>x = file.read();
>printf(micros() - z);
>while bis alle gelesen.

Solchen Pseudocode kann man sich zu 99% sparen, denn er ist meistens 
weit weg vom Original.

>Ergebnis, alle read haben ca. 5-7 mikros
>alle 512 bytes sind es 2500 - 4500 mikros.

Logisch, denn deine Einzelbytezugriffe kommen aus dem Sektorpuffer im 
RAM und wenn der leer ist muss ein echter Zugriff auf die SD-Karte 
gemacht werden. 4,5ms sind jetzt nicht so der Brüller. Mal rechnen.

Bei 22kHz/8Bit dauern 512 Bytes 23,2ms. Also mehr als genug Zeit, 
währenddessen die nächsten 512 Bytes ranzuschaffen.

>Und das sind TATSACHEN!

WOW!

>Es kann sein, dass wenn man mit read einen Bereich einliest, die 5 dann
>vielleicht 10 mikros sind, nur das Problem ist ich habe kein memory,

Keine Arme, keine Kekse. DU MUSST ein Minimum an Zwischenpuffer zur 
Verfügung stellen. Wenn wir mal die obigen 4,5ms auf 5ms aufrunden, 
musst du mind. 110 Bytes zwischenspeichern. Sagen wir 2x128, das sind 
"runde" Binärzahlen. Darunter geht es nur mit SEHR vielen Tricks, die im 
Moment noch weit außerhalb deiner Reichweite liegen.

>also muss ich das mit read und einem byte lösen, das ganze soll ja auf
>einem nano laufen und nicht auf einem due

Unsinn. Der Nano basiert auf dem Uno, hat nur einen kleineren 
Formfaktor. Dort werkelt ein ATmega 328 mit 32kB Flash und 2kB RAM. Das 
reicht locker! Und selbst der Meister Chan verwendet 1x128 Bytes als 
Zwischenpuffer (FIFO). Und der weiß was er tut!

https://store.arduino.cc/arduino-nano

>Die Samples sind 8khz, das sind 125 uS, also wird ja bei 3000uS mehrere
>Samples unterbrochen, das kann ja gar nie funktionieren!

Auch?

>Ausser man kann das ganze so drehen wenn man den SD treiber selber neu
>schreibt mit nur den nötigen sachen.

Unsinn.

>SPI benutzt immer den gleichen Taktfrequenz, leider kann man diese auch
>nicht ändern... habe jedenfalls nichts dazu gefunden.

Braucht man auch nicht.

>Ich denke wir lassen das mal so stehen, da es leider bereits wieder
>streit gibt hier. ich weiss jedenfalls das es nicht an meinem Programm
>liegt, ansonsten ja ein reines lesen schon bereits viel schneller
>wäre...

HAHAHAHAHAH! Die billigste Ausrede aller Faulen und Unfähigen!
Schäm dich!

Was wollen wir wetten, daß man diese Audioausgabe auf einem Arduino 
UNO/NANO problemlos hinbekommt?

von Falk B. (falk)


Lesenswert?

@Stefan Us (stefanus)

>> Soso? Wie groß denn? Ganz sicher KEINE 500ms

>Richtig, beim lesen hatte ich nur wenige Millisekunden. Ich weiss den
>konkreten Wert nicht mehr, aber es waren auf jeden Fall weit unter 100ms
>jedoch mehr als 1ms.

Das ist schon mal eine GANZ andere Liga. Und den Grund kennst du bis 
heute nicht.

>Das sind etwas mehr als 1 Megabit pro Sekunde. Für MP3-Wiedergabe sollte
>das locker reichen.

Er hat plain old PCM.

von Stefan F. (Gast)


Lesenswert?

> Und den Grund kennst du bis heute nicht.

Doch den kenne ich. Das lesen eines Sektors von der SD Karte benötigt 
eine gewisse nicht konstante Zeit. Wie lange genau, müsste man dem 
Datenblatt der jeweiligen SD Karte entnehmen. Wie wir alle wissen, sind 
die Datenblätter der meisten SD Karten der Allgemeinheit nicht 
zugänglich, vermutlich existieren sie gar nicht für alle Karten.

> Er hat plain old PCM.

Ich meinte mit den 1M bit dass das locker für das Laden normale MP3 
Files genügt. Meine haben in der Regel zwischen 128k und 384k bits pro 
Sekunde.

Dass da als Ausgabe noch mehr Bytes werden, macht die Sache zwar nicht 
einfacher, ist aber momentan jedoch nicht der Knackpunkt.

von Falk B. (falk)


Lesenswert?

@ Stefan Us (stefanus)

>Doch den kenne ich. Das lesen eines Sektors von der SD Karte benötigt
>eine gewisse nicht konstante Zeit.

Naja, da würde ich aber mindestens mal ein paar brauchbare Meßwerte 
sehen wollen. Um wieviel schwankt die Lesezeit eines Sektors? Ein paar 
Dutzend us? Und wenn man eine FAT-Bibliothek benutzt, muss man wissen, 
daß spätestens an einer Clustergrenze die Adresse den neuen Clusters aus 
der FAT ausgelesen werden muss. Das benötigt mindestens einen 
zusätzlichen Sektorzugriff, wenn es keine intelligenten Zwischenpuffer 
gibt, welche die nächste Cluster(Sektor)adresse ohne SD-Zugriff kennen.

Aber alles in allem ist diese Verzögerung noch DEUTLICH unter der beim 
Schreiben.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

>> Um wieviel schwankt die Lesezeit eines Sektors?
> alle 512 bytes sind es 2500 - 4500 mikros.

Klingt plausibel.

> Aber alles in allem ist diese Verzögerung noch DEUTLICH unter
> der beim Schreiben.

Offensichtlich ja.

von batman (Gast)


Lesenswert?

Mr D. schrieb:
> Ergebnis, alle read haben ca. 5-7 mikros
> alle 512 bytes sind es 2500 - 4500 mikros.
>
> Und das sind TATSACHEN!

Bravo, jetzt ist der Groschen gefallen! :-)

> ich weiss jedenfalls das es nicht an meinem Programm
>liegt, ansonsten ja ein reines lesen schon bereits viel schneller

Ohh NEIIIN! :-(

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Sooo, hier mal ein Arduino der in  Echtzeit PCM-Audio von SD-Karte liest 
und per PWM ausgibt. Ohne DMA, ohne dicke CPU, ohne SDIO-Interface  etc. 
Ein Arduino mega + der alte TFT+SD-Karte Shield, verbunden per 
Lochraster-Zwischenstück.

https://www.reichelt.de/?ARTICLE=152634&PROVID=2788&gclid=EAIaIQobChMI1tKrg6qe1wIVERQbCh0VfwsHEAQYBSABEgJR0_D_BwE

Siehe Anhang. Das Programm ist für einen Arduino Mega gemacht, sollte 
aber mit minimalem Aufwand auf fast alle anderen AVR-Arduinos umsetzbar 
sein, man muss nur die #defines der Pins anpassen, der Rest sollte 
passen. Anbei noch zwei Wave-Dateien mit 8 und 22 kHz Samplingrate. Mit 
dem #define BUFFER_SIZE kann man prüfen, ab wann die Ausgabe Aussetzer 
hat. Das wird nämlich live im Programm getestet und mittes LED 
angezeigt. Für 8 kHz reichen 2x50 Bytes, für 22kHz braucht es ca. 2x150 
Bytes. Das Audiosignal wird mittels Elko von 10-100uF an Arduino-Pin 11 
(hier gleich PB5) direkt in einen Kopfhörer eingespeist.

Vini. Vidi. Vici.

;-)

von Stefan F. (Gast)


Lesenswert?

In diesem Programm wird ein Timer benutzt, um die Ausgabe in 
regelmäßigen Intervallen zu erzeugen. Gleichzeitig lädt das 
Hauptprogramm die nächsten Daten von der SD Karte nach, sobald 
erforderlich.

Das ist ein schönes Beispiel, wie man es richtig macht. Und so gut 
lesbar!

von Mr D. (Gast)


Lesenswert?

Falk B. schrieb:
> Sooo, hier mal ein Arduino der in  Echtzeit PCM-Audio von SD-Karte liest
> und per PWM ausgibt. Ohne DMA, ohne dicke CPU, ohne SDIO-Interface  etc.
> Ein Arduino mega + der alte TFT+SD-Karte Shield, verbunden per
> Lochraster-Zwischenstück.
>
>

Vielen Dank für den Tipp. :)

Jo ich habe nun gesehen wo mein Fehler liegt.
2 Buffer und wenn einer leer ist wird der im LOOP Nachgeladen. Sehr gute 
Idee, da bin ich jetzt nicht drauf gekommen, wohl zu verknöchert an 
meinem Problem rumgebissen und vor lauter Code nichts mehr gesehen...

1 Byte lesen zwischen den Samples geht definitiv nicht. Und gut ist das 
eh nicht wenn man im ISR Bytes einliest. werde das nun so umbauen und 
auch mit einem Buffer arbeiten der im Loop geladen wird. Ansonsten ist 
mein Programm auch in etwa so mit Timer1 und PWM mit Timer2 beim Nano 
und mit DAC bei UNE/MEGA.

Interessant ist, dass mit einem UNO ich 20mikros habe bei einem READ von 
einem Byte und beim DUE 2 Mikros, Die Sektoren bleiben dabei in etwa 
gleich mit 2500 bis 4500 Mikros. Einen Buffer mit 256 Bytes liest der 
DUE so mit 250-300 Mikros.

Herzlichen Dank für die Unterstützung.
Gruss

von Stefan F. (Gast)


Lesenswert?

Der DUE hat ja einen viel schnelleren Mikrocontroller.

von Markus F. (mfro)


Lesenswert?

Falk B. schrieb:
> Vini. Vidi. Vici.

SoIssjakeinProblem.

Der Code ist ja schliesslich (s. Programmheader) seiner Zeit um über 
eine Woche voraus... ;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.