Ich habe es bislang auf keiner der überlichen Wege hinbekommen,
eine Melody über den Piezo Speaker auszugeben ohne die delay Funktion zu
nutzen.
Die delay Funktion ist während der Widergabe kontraproduktiv für mein
Programm. Im Internet habe ich so noch keine Lösung gefunden.
Bislang versucht mit der millis() und Metro. Hat aber nicht hingehauen.
Hoffentlich kann mir einer helfen.
Des weiteren würde ich gerne, das es nur einmal durch läuft für jedesmal
wo ich das Programm aufruf.
> Bislang versucht mit der millis() und Metro. Hat aber nicht hingehauen.
warum nicht? guck dir den Besipielcode von Blink without delay an und
model dir das um.
Geht ganz einfach, musste aber selbst was machen.
Mit DDS... dazu braucht man einen schnellen Timer mit Interrupt. Der
Interrupt muss mit der doppelten Frequenz getriggert werden wie die
maximale Frequenz die man widergeben möchte.
In der Interrupt-Routine hat man dann folgendes...
Zaehler = Zaehler + Set
If Delay > 0
Portpin = MSB von Zaehler
Delay = Delay - 1
Else
Portpin = 0
Wenn man "Set" auf die hälfte von der Bitbreite von Zaehler setzt
bekommt man am Portping 1/2 Frequenz vom Interrupt. Reduziert man den
Wert von "Set" Sinkt auch die Frequenz mit der der Portpin toggelt...
Das Delay setzt man auf einen Wert X und der Portpin gibt bis ablauf die
Frequenz aus.
Das schöne daran ist das kann man auf Polyphonien erweitern und braucht
trotzdem nur einen Timer... Das einzige was beschränkt ist die
Rechenleistung vom AVR....
Das versteh ich kein bisschen von :(
Ich hätte gehofft, iwas Richtung millis() wäre machbar.
Weiß aber nicht, wie ich die Verschachtelung passend umschreiben kann.
> tone(buzzerPin, rhythmNotes[i], rhythmDuration);>> Entspricht hier nicht bereits die ryhtmDuration einem delay?
das müsste natürlich noch geklärt werden, währe aber sehr unschick und
dann kannst du tone() ja eh vergessen.
hier:
http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation#Ugly_Details
ist beschrieben wie die Timer verwendet werden, und es scheint so, als
ob Timer0 für millis() frei bleiben würde.
> Ich hätte gehofft, iwas Richtung millis() wäre machbar.> Weiß aber nicht, wie ich die Verschachtelung passend umschreiben kann.
was hast du denn versucht? Vestehst du den Code von blink without delay?
AVR-Tutorial: TimerInterrupt
Die millis Variante kennt ich,
hab sie im Hauptsketch in verwendung an einigen Stellen
if(aktuelleZeit - vorherigeZeit > wartezeit)
{
digitalWrite(pumpePin, LOW);
pumpeStatus = digitalRead(pumpePin);
vorherigeZeit = aktuelleZeit;
Serial.print("Ende 0");
i++;
}
Weiß aber nicht, wie ich das in der verschachtelte Variante von dem
Melody Sketch machen soll.
> Weiß aber nicht, wie ich das in der verschachtelte Variante von dem> Melody Sketch machen soll.
na dann überleg's dir, scheinst ja alle Hilfsmittel zu kennen,
verschachteln, ja, da muss man sich was überlegen
Bin noch nicht weitergekommen. Gibts kein fertigen Sketch? Habe bei
github nur welche basierend auf delays gefunden. Muss man immer das Rad
neu erfinden? Es ist eine kleine Spielerei funktion später in meiner
Steuerung die rein soll, habe mir aber schon derzeit so den Kopf drum
zerbrochen, dass ich fast denke, es ist so einfach nicht realisierbar.
Denn ansonsten wären die Tuts damit voll.
Manche Sachen sind eben komplizierter, und es gibt keine fertige Lösung
im Internet, und auch keinen im Forum, der das mal schnell schreibt.
Da muss man dann doch selber ein paar Stunden prokeln.
Falls das zu teuer ist: die Arduinos sind doch so günstig, dass man
einfach einen zweiten nimmt. Kommunikation über einen IO-Pin, und schon
wird parallel die Musik gespielt.
20 Euro für einen Arduino sind billiger als eine Stunde Arbeitszeit.
Nax schrieb:> Bin noch nicht weitergekommen. Gibts kein fertigen Sketch? Habe bei> github nur welche basierend auf delays gefunden. Muss man immer das Rad> neu erfinden?
In deinem Fall ja.
Wer radfahren will, muss eben radfahren lernen.
Zumal das nun wirklich keine Raketentechik ist.
> zerbrochen, dass ich fast denke, es ist so einfach nicht realisierbar.
Es ist sogar recht trivial.
Aber: Vor das Wollen haben die Götter das Können gesetzt. Und das muss
man eben lernen. Mussten wir alle. Und nein. Stundelang nach fertigem
Code googeln hat auf diesem Schwierigkeitslevel nichts mit lernen zu
tun. In der Zeit hättest du schon längst mit einer blinkenden Led als
Ausgangspunkt dir die notwendige Technik selber beigebracht und Schritt
für Schritt um die Dinge ergänzt, die anders sein sollen.
1
intnotenNr=0;
2
intnoten[]={440,880,600};
3
intdauer[]={1000,500,500};
4
5
unsignedlongaktuell=0;
6
unsignedlongtonBeginn=0;
7
unsignedlongtonDauer=0;
8
9
voidloop()
10
{
11
aktuell=millis();
12
13
if(aktuell-tonBeginn>tonDauer)
14
{
15
tone(buzzerPin,noten[notenNr]);
16
tonDauer=dauer[notenNr];
17
18
notenNr++;
19
if(notenNr==3)
20
notenNr=0;
21
22
tonBeginn=aktuell;
23
}
24
}
und das ist jetzt vom Prinzip her so wahnsinnig schwer?
Noch dazu, wo ich es dir schon vorgekaut habe, bzw. du dir an einem
LED-Blink Beispiel die Grundtechnik hättest anschauen können?
Den Rest musst du jetzt alleine einbauen. Wenigstens das wirst du ja
wohl hoffentlich können.
PittyJ schrieb:> Manche Sachen sind eben komplizierter, und es gibt keine fertige Lösung> im Internet, und auch keinen im Forum, der das mal schnell schreibt.> Da muss man dann doch selber ein paar Stunden prokeln.>> Falls das zu teuer ist: die Arduinos sind doch so günstig, dass man> einfach einen zweiten nimmt. Kommunikation über einen IO-Pin, und schon> wird parallel die Musik gespielt.
Ich hoffe, das war als Satire gemeint.
Wenn Du eine Melodie spielen willst, ohne das Main zu stoppen, mußt Du:
1. einen PWM-fähigen Ausgangspin nehmen.
2. im Timerinterrupt die Tondauer zählen und den nächsten Tonwert in die
PWM laden.
Die Tonerzeugung über Delays ist dazu völlig ungeeignet.
Gibt es eine Möglichkeit einen Ton auf leise zu stellen. Habe im Sketch
3 Pausen drin von 250ms.
Der "Ton" pause defeniert mit 0 gibt aber so ein kleines rattern auf den
Piezo.
1
const int buzzerPin = 3;
2
3
#define c 261
4
#define d 294
5
#define e 329
6
#define f 349
7
#define g 391
8
#define gS 415
9
#define a 440
10
#define aS 455
11
#define b 466
12
#define cH 523
13
#define cSH 554
14
#define dH 587
15
#define dSH 622
16
#define eH 659
17
#define fH 698
18
#define fSH 740
19
#define gH 784
20
#define gSH 830
21
#define aH 880
22
#define pause 0
23
24
int notenNr = 0;
25
int noten[] = {
26
a, a, a, f, cH, a, f, cH, a, eH, eH, eH, fH, cH, gS, f, cH, a, aH, a, a, aH, gSH, gH, fSH, fH, fSH,
27
pause, f, gS, f, a, cH, a, cH, eH, aH, a, a, aH, gSH, gH, fSH, fH, fSH,
Siehe Doku bei Arduino.
Um tone() abzudrehen, noTone() aufrufen.
1
....
2
if(noten[notenNr]==pause)
3
noTone(buzzerPin);
4
else
5
tone(buzzerPin,noten[notenNr]);
6
7
...
Besser du gewöhnst dich gleich daran: Die Arduino-Doku wird deine zweite
Bibel.
Also lies gefälligst nach. Ich hab in meinem ganzen Leben noch nie einen
Arduino programmiert, geschweige denn einen in der Hand gehabt. Ich
finde die Dinge raus und du nicht? Das kanns ja wohl nicht sein.