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.
Ja, indem man das gleichzeitg macht ;)
Schonmal keine Funktionen benutzen die blocken und delays benutzen.
Musik im Interrupt per DDS-Synthese erzeugen.
>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.
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.
Dann arbeitet man eben mit einem Zustandsautomaten fester Zykluszeit,
oder man zweckentfremdet vorhandene Schnittstellen (z.B. SPI- oder
USART-Schnittstelle für die LEDs).
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.
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 :-)
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...
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!
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?
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.
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...
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?
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.
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.
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...
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 ...
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.
Dieter F. schrieb:> Mich hätte nur das Timing interessiert
Das ist doch im Quelltext bereits taktgenau als Kommentar dokumentiert.
Kannst du nicht lesen?