Forum: Mikrocontroller und Digitale Elektronik Arduino "gleichzeitig" RGB Stripe und Musik


von Peterlustig (Gast)


Lesenswert?

Hey

habe folgendes Problem.

Ich möchte mit meinem Arduino Mega ein NEOPIXEL RGB-Stripe ansteuern und 
sozusagen auch gleichzeitig eine Melodie abspielen lassen.

Hat jemand vielleicht eine Idee wie ich das machen kann?

Danke jetzt schonmal für alle Antworten.

von Jens K. (jens_k514)


Lesenswert?

Ja, indem man das gleichzeitg macht ;)

Schonmal keine Funktionen benutzen die blocken und delays benutzen. 
Musik im Interrupt per DDS-Synthese erzeugen.

von holger (Gast)


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.

von c-hater (Gast)


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.

von S. R. (svenska)


Lesenswert?

Dann arbeitet man eben mit einem Zustandsautomaten fester Zykluszeit, 
oder man zweckentfremdet vorhandene Schnittstellen (z.B. SPI- oder 
USART-Schnittstelle für die LEDs).

von c-hater (Gast)


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.

von Dieter F. (Gast)


Lesenswert?

c-hater schrieb:
> 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.

Zeig mal - die Musik kann ich gerne stellen :-)

von Horst (Gast)


Lesenswert?

Dieter F. schrieb:
> Zeig mal

Da wird nichts kommen. C-Hater liefert nur heisse Luft.

von c-hater (Gast)


Angehängte Dateien:

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...

von c-hater (Gast)


Lesenswert?

Horst schrieb:

> Da wird nichts kommen. C-Hater liefert nur heisse Luft.

Du musst es ja wissen. Sogar zu blöd, in der Historie dieses Forums zu 
recherchieren...

Du bist sowas von völlig unfähig, dass es schon weh tut!

von Dieter F. (Gast)


Lesenswert?

c-hater schrieb:
> Kein Thema

Fein - das probiere ich am Wochenende mal aus - sofern ich des 
Compilierens etc. mächtig bin (bin kein Assembler-Freak).

Basis Arduino (ATMega328P) mit 16MHz?

Wie muss die Audio-Datei aufgebaut sein?

von Horst (Gast)


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.

von c-hater (Gast)


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...

von Dieter F. (Gast)


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?

von c-hater (Gast)


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.

von Dieter F. (Gast)


Lesenswert?

c-hater schrieb:
> Gib' mir einfach eine Liste der Frequnzen,
> die du hören willst

O.K.:

264  282  297  317  330  352  372  396  422  440  475  495  528

528     495     475     440     422     396     372     352     330
317     297     282     264

von Jens K. (jens_k514)


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.

von c-hater (Gast)


Lesenswert?

Dieter F. schrieb:

> 264  282  297  317  330  352  372  396  422  440  475  495  528
>
> 528     495     475     440     422     396     372     352     330
> 317     297     282     264

Die Angaben reichen nicht. Dabei hatte ich doch ziemlich genau 
aufgeschrieben, welche benötigt werden...

von Dieter F. (Gast)


Lesenswert?

c-hater schrieb:
> Die Angaben reichen nicht

c-hater schrieb:
> Ich will hören: 440Hz, 553Hz, 381Hz usw...

?

von c-hater (Gast)


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...

von Dieter F. (Gast)


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 ...

von Draco (Gast)


Lesenswert?

Man nennt ihn auch ganz trivial: "Westminster Gong" ;-) Da gibts 
taaaausende Tonbeispiele im Netz... in C, in ASM, in Midi, in Wave... 
wie man das gerne will.

von c-hater (Gast)


Lesenswert?

Dieter F. schrieb:

> Mich hätte nur das Timing interessiert

Das ist doch im Quelltext bereits taktgenau als Kommentar dokumentiert. 
Kannst du nicht lesen?

von Dieter F. (Gast)


Lesenswert?

c-hater schrieb:
> Kannst du nicht lesen?

Du hast es erkannt :-)

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.