Arduino "gleichzeitig" RGB Stripe und Musik

Gast #4728728
Lesenswert?

>Schonmal keine Funktionen benutzen die blocken und delays benutzen.

Muss man bei den Neopixeln aber weil das Timing sehr eng ist.

>Musik im Interrupt per DDS-Synthese erzeugen.

Dieser Interrupt versaut das Timing der Neopixel.
Das gibt fehlerhafte Ausgaben an den LEDs.

Perfekt ist für die Aufgabe ein Stripe mit SPI
Ansteuerung. Da kann man z.B. die Stripes mit Dotstars
oder LPD8806 nehmen. Die benötigen keinerlei Timing.
Gast #4728753
Lesenswert?

holger schrieb:

>>Schonmal keine Funktionen benutzen die blocken und delays benutzen.
>
> Muss man bei den Neopixeln aber weil das Timing sehr eng ist.

Nein, muss man nicht. Jedenfalls nicht, wenn man zur Ausgabe die UART 
benutzt. Dann ist es nicht nur möglich, kontinuierlich 1024 WS281x mit 
maximal möglicher Framerate anzusteuern, sondern man kann gleichzeitig 
mit 78kHz PWM-Rate DDS-Sound ausgeben. Bei 20MHz Systemtakt.

Und es bleibt dabei sogar noch etliches an Rechenzeit über. Code in 
"main()" kann dann immer noch mit einem effektiv wirksamen Takt von 
knapp 10Mhz betrieben werden. Es wird also nur knapp über die Hälfte der 
verfügbaren Rechenzeit benötigt, um die WS281x-Ausgabe und die 
Audioausgabe zu realisieren.

Das alles klappt so natürlich nur in Assembler. Nicht in plain C und 
schon garnicht in der Arduino-Softwareumgebung.
Gast #4728823
Lesenswert?

c-hater schrieb:

> Und es bleibt dabei sogar noch etliches an Rechenzeit über. Code in
> "main()" kann dann immer noch mit einem effektiv wirksamen Takt von
> knapp 10Mhz betrieben werden. Es wird also nur knapp über die Hälfte der
> verfügbaren Rechenzeit benötigt, um die WS281x-Ausgabe und die
> Audioausgabe zu realisieren.

Vergessen zu erwähnen: für weitere ISRs ist allerdings selbst in dem 
schon ganz gut durchoptimiertem Assemblercode schon fast keine Luft 
mehr.

Alles andere muss sich also auch tatsächlich ausschließlich in main() 
abspielen. Da stört's die zeitkritischen Aufgaben nicht.
Gast #4728871
Lesenswert?

Dieter F. schrieb:

> Zeig mal

Kein Thema, den WS281x-Krams habe ich ja bereits hier im Forum 
veröffentlicht. Das Audiozeug ist im Vergleich dazu doch ziemlich 
trivial und straight-forward. Es zeigt nur erneut die unendliche 
Überlegenheit freier Assemblerprogrammierung bezüglich der erzielbaren 
Performance.

Denn die beiden extrem zeitkritischen ISRs teilen sich exclusiv 
reservierte Register. Genau das geht in C im Allgemeinen kaum, in gcc 
praktisch garnicht. Genau diese Möglichkeit ist aber gerade das 
"Geheimnis", warum eben doch geht, was geht...

Ich benutze den Kram übrigens, damit eine Uhr aus zwei Ringen mit WS281x 
(1x60, 1x24) den originalgetreuen Sound des Westminster-Schlags 
abspielen kann. Diesen Teil werde ich aber nicht veröffentlichen, denn 
weder für das Sample (...des BigBen, welches ich allerdings auch dazu 
benutze, die Melodien zu spielen) noch für die Melodie besitze ich die 
nötigen Rechte. Alles was ich veröffentlichen kann, ist also die reine 
Audio-Ausgabe-Routine. Sozusagen den Gerätetreiber...
Angehängte Dateien:
Gast #4728899
Lesenswert?

c-hater schrieb:
> Sogar zu blöd, in der Historie dieses Forums zu
> recherchieren...

Wen interessiert die Historie?
Du bist hier in letzter Zeit nur mit sinnlosem c-, Arduino- und 
Anfänger-Bashing und strunzdummen Kommentaren aufgefallen, da mußt Du 
Dich über eine schlechte Meinung nicht wundern.
Gast #4728915
Lesenswert?

Dieter F. schrieb:

> Basis Arduino (ATMega328P) mit 16MHz?

Geht auch, natürlich hast du dann aber keine 78,125kHz PWM-Frequenz, 
sondern nur 16.000.000/256=62,5kHz.

> Wie muss die Audio-Datei aufgebaut sein?

Was für eine Datei? Einfach nur die Samples hintereinander weg im Flash. 
Die müssen als unsigned 8Bit Samples vorliegen. Die Samplerate spielt 
keine Rolle, sie muss nur kleiner sein als die Hälfte der PWM-Frequenz. 
Alles andere regelst du über den Pitch, den du audout_play übergibst. 
Das ist eine 0.16-Bit Festkommazahl, die angibt, wie viele Samples pro 
PWM-Periode abgespielt werden sollen.

Wenn du die Sache als stupiden Musikplayer verwenden willst, musst du es 
ändern und erweitern. Du musst dann die Samples statt aus dem Flash aus 
dem RAM holen und ein DoubleBuffer-System im RAM bauen, bei dem du den 
jeweils gerade nicht abgespielten Buffer mit den nächsten Daten aus der 
"Datei" befüllst. Auch nicht gerade Raketentechnik...
Gast #4728931
Lesenswert?

c-hater schrieb:
> Geht auch, natürlich hast du dann aber keine 78,125kHz PWM-Frequenz,
> sondern nur 16.000.000/256=62,5kHz.

Ja, O.K. - die Frage bezog sich schon auf den Arduino ... aber egal. Dem 
kann ich auch einen 20 MHz Quarz zur Seite stellen.

c-hater schrieb:
> Was für eine Datei? Einfach nur die Samples hintereinander weg im Flash

Öhm .. ja .. ich bin bekennender Assmebler-Noob. Ich kann comiliertes 
zwar einigermassen Lesen aber sonst ...

Ich nehme an, die Daten sollen unter "RAMPZ" liegen - k. A. wie genau.

Kannst Du nicht bitte ein Beispiel (meinetwegen Die Tonleiter hoch und 
runter) beifügen?
Gast #4728960
Lesenswert?

Dieter F. schrieb:

> Ich nehme an, die Daten sollen unter "RAMPZ" liegen - k. A. wie genau.

Nein, ein RAMPZ-Register hast du beim Mega328P überhaupt nicht. Das 
gibt's nur bei AVRs mit mehr als 64k Flash. Ich z.B. benutze für meine 
Uhr einen Mega1284P mit 128k Flash. Das reicht dann für ein 4s-Sample 
des BigBen mit 22,05kHz Samplefrequenz (und den ganzen Code und die 
ganzen konstanten Daten, die sonst noch in der Software stecken). Du 
übergibst audout_play einfach die Adresse des Samples. Für AVRs mit mehr 
als 64k Flash musst du halt den oberen Teil der Adresse im 
RAMPZ-Register übergeben.

Mit diesem einen Sample spiele ich den kompletten Westminster-Sound. Das 
geht, weil es eine DDS-Ausgabe ist, ich spiele also immer das gleiche 
Sample in unterschiedlichen Tonhöhen ab.

Kurz: Beim 328P brauchst du dir um RAMPZ einfach keine Sorgen zu 
machen...

> Kannst Du nicht bitte ein Beispiel (meinetwegen Die Tonleiter hoch und
> runter) beifügen?

Hmm. Ich bin kein Musiker. Gib' mir einfach eine Liste der Frequnzen, 
die du hören willst, die Samplefrequenz des Samples, welches du 
abspielen willst und seine "Eigenfrequenz".

Also beispielsweise:
Sample ist mit 22,05kHz gesampelt.
Sample ist Kammerton a (also 440Hz).
Ich will hören: 440Hz, 553Hz, 381Hz usw...

Dann kann ich dir einen Beispielcode dafür schreiben.
#4729232
Lesenswert?

Es stellt sich erstmal die Frage ob der Ersteller überhaupt richtigige 
Musik abspielen will oder nur ne Melodie aus gepiepse. ^^

Wenn es nur um piepsen geht, reicht ein Interrupt mit dem doppelten der 
maximalen Frequenz die man abspielen will ;) dann tut es wahrscheinlich 
auch ein 10khz Intgerrupt. In der ISR muss dann nur noch pro Stimme eine 
16bit oder 32bit (je nach gewünschter Frequenzauflösung) Addition und 
ein vergleich auf ein MSB gemacht werden. Sowie das Setzen/Löschen des 
Portpins. Ausgabe auf dem Neopixel kann man per SPI plus kleiner 
außenbeschaltung machen. Gibt genügend Beispiele dafür. Dann ist nämlich 
fast nix mehr Zeitkritisch.

Auf C rumzuhacken ist absolut nicht zielführend, warum soll man so viel 
mehr Arbeit in hoch optimierten Code stecken, wenn man für 
wahrscheinlich noch drei Euro weniger einen Cortex mit 120Mhz bekommt. 
Die Wartbarkeit des Codes ist auch noch 100mal besser.

Ich habe sowieso gelesen das es bei den LEDs garnicht auf exaktes Timing 
ankommt. Es müssen nur die Timing-Verhältnisse stimmen. Selbst 
nachgeprüft habe ich das noch nicht.
Gast #4730094
Lesenswert?

Dieter F. schrieb:

> ?

Du hättest mein Posting einfach vollständig lesen und beantworten 
sollen.

Ich kann sinnvoll nur irgendwas abspielen, von dem ich die 
ursprünglichen Eigenschaften kenne. Und das sind: Samplerate und die 
durch das Sample repräsentierte (Grund-)Frequenz.

In meinem Fall z.B. (BigBen-Sample) waren das 22,05kHz Samplerate und 
der BigBen läutete in dem Sample den Ton e0 (was er eigentlich immer tut 
;o) und ca. 165Hz Grundfrequenz entspricht). Damit (und mit der 
PWM-Rate, die wiederum vom Systemtakt abhängt) kann ich erst den Pitch 
errechnen, um erstmal den BigBen originalgetreu erklingen zu lassen.

Erst dann kann ich mich darum kümmern, ihn auch in anderen Tonhöhen 
abzuspielen (um damit z.B. eine Melodie zu erzeugen). Erst dafür genügt 
dann die einfache Angabe der gewünschten Wiedergabefrequenz der Noten. 
Alles andere für die Berechnung der jeweils nötigen Werte für den Pitch 
weiß ich dann schon.

Ein DDS-Sampleplayer ist was anderes als bloß einfach Rumzupiepsen. Du 
hast die Funktionsweise offensichtlich nichtmal ansatzweise verstanden, 
sonst hättest du gewußt, welche Angaben ich benötige. Das ist schlecht. 
Zumindest für dich...
Gast #4730119
Lesenswert?

c-hater schrieb:
> Du
> hast die Funktionsweise offensichtlich nichtmal ansatzweise verstanden,
> sonst hättest du gewußt, welche Angaben ich benötige.

Ja - und es ist mir vollkommen egal, da ich mit einem AVR keine Musik 
abspielen will.

c-hater schrieb:
> Das ist schlecht.
> Zumindest für dich...

s.o.

Mich hätte nur das Timing interessiert - und ob das wirklich so gut 
funktioniert, wie Du schreibst. Ist aber egal (übrigens denke ich nicht, 
dass der Big Ben-Sound geschützt ist) - ich kann auch ohne ganz gut 
Leben :-). Danke für die Mühe ...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren