Wellenrauschen mit ATtiny85
Elektronik-Labor
Projekte
AVR
Tiny85
In der Zeitschrift Funkamateur 7/2018 habe ich einen Artikel von
Klaus Sander gelesen: Rauschen mit Deltawellen. Ein Rauschen mit
passender Amplitudenänderung soll beim Einschlafen helfen. Es wurde ein
AVR-Controller verwendet um die Wellenmuster zu erzeugen, aber das
Rauschen wurde rein elektronisch generiert und moduliert. Das Konzept
hat mich überzeugt, sowas will ich auch bauen. Aber mein Ziel ist es,
möglichst alles in Software zu gießen, sodass die Aufgabe von einem
Tiny85 im Alleingang bewältigt wird. Dazu reicht ein Tiefpassfilter am
PWM-Ausgang PB0 des Tiny85
Der erste Ansatz war, ich mache das wie bei meinem DDS-Generator im Lernpaket (8.6 Sinusgenerator 0…5 kHz).
Statt einer Sinuswelle wird eine Rauschsequenz gespeichert, die beim
Start mit der RND-Funktion erzeugt wird. Gesagt, getan und Reinfall.
Die Sequenz ist zu kurz, sodass kein weißes Rauschen sondern ein Ton
erzeugt wird.
Der zweite Versuch: Das Rauschen wird direkt in
der Interrupt Routine erzeugt. Das Ergebnis war tatsächlich ein sehr
überzeugendes weißes Rauschen. Ich konnte es im Kopfhörer hören, der
über einen größeren Widerstand von 10 k am PWM-Ausgang lag. Es
funktioniert schon ganz ohne Tiefpassfilterung, weil die PWM-Frequenz
bei ca. 32 kHz liegt.
Tim1_isr:
Portb.2 = 1
E = Rnd(255) 'Rauschen
Pwm0a = E 'Ausgabe
Portb.2 = 0
Return
Das
Ergebnis wurde mit leichter Filterung am Oszilloskop betrachtet. Mit
einem zusätzlichen Printbefehl kann es auch mit dem Serien Plotter aus
der Arduino-IDE angesehen werden.
Als nächstes wurde im
Hauptprogramm der Wellenverlauf erzeugt. Ich stelle mir Wellen am Stand
der Nordsee vor, die immer etwas unregelmäßig verlaufen, mal höher und
mal flacher. Das könnte an der Überlagerung verschiedener Wellenfronten
liegen, die aus unterschiedlichen Richtungen stammen. Deshalb möchte
ich drei Sinusfunktionen mit unterschiedlicher Frequenz überlagern.
Do
I = I + 1 'Wellen
B = I / 300
A = Sin(b) '-1...+1
B = I / 250
A = A + Sin(b) '-2...+2
B = I / 140
A = A + Sin(b) '-3...+3
A = A + 3 '0...6
A = A * 30 '0...180
A = A + 60 '60...240
D = A
Waitms 2
Loop
Tim1_isr:
Portb.2 = 1
Pwm0a = D 'Ausgabe
Portb.2 = 0
Return
Die
Summe der drei Wellen wird auf den Bereich eines Byte gebracht und dann
in D an die Interrupt-Prozedur übergeben. Es entstehen typische
Meereswellen mit wechselnden Amplituden.
Um das Rauschen mit
den Wellen zu modulierten reicht eine Multiplikation. Das wurde zuerst
im Hauptprogramm getestet, wobei die Rauscherzeugung noch zu langsam
war.
Do
I = I + 10 'Wellen
B = I / 300
A = Sin(b) '-1...+1
B = I / 250
A = A + Sin(b) '-2...+2
B = I / 140
A = A + Sin(b) '-3...+3
A = A + 3 '0...6
A = A * 30 '0...180
A = A + 60 '60...240
D = A
E = Rnd(255) 'Rauschen
O = D * E
E = High(o)
Pwm0a = E
Print #1 , E
Waitms 2
Loop
Damit
wirklich ein überzeugendes Rauschen entsteht, muss es mit wesentlich
größerer Frequenz erzeugt werden als die Wellenfunktion. Also Rauschen
im Interrupt, Wellen im Hauptprogramm.
Do
I = I + 1 'Wellen
B = I / 300
A = Sin(b) '-1...+1
B = I / 250
A = A + Sin(b) '-2...+2
B = I / 140
A = A + Sin(b) '-3...+3
A = A + 3 '0...6
A = A * 30 '0...180
A = A + 60 '60...240
D = A
Waitms 2
Loop
Tim1_isr:
Portb.2 = 1
E = Rnd(255) 'Rauschen
O = D * E
E = High(o)
Pwm0a = E 'Ausgabe
Portb.2 = 0
Return
Aber
dabei gab es zuerst große Probleme. Das Programm wurde unzuverlässig
und konnte stecken bleiben. Die Vermutung war, ein Zeitproblem. Die
Interruptprozedur frisst so viel Zeit, dass nicht mehr genügend
Rechenzeit für die Sinusberechnung übrig bleibt. Die Rechenzeit der
Interruptroutine wird mit dem Oszilloskop an B2 sichtbar, weil ich den
Port am Anfang um an Ende umschalte. Da konnte man schon sehen, dass
die RND-Berechnung die meiste Zeit braucht, sodass sogar mehrere
Timer-Überläufe überschlagen wurden.
Das Problem wurde über
den Vorteiler zum Timer 0 gelöst. Der Timer wurde zunehmend langsamer
getaktet, die RND-Funktion also seltener ausgeführt. Am Ende zeigte
sich, dass es mit einem Vorteiler durch 8 funktioniert. Das Rauschen
wird dann noch im Takt von 4 kHz erzeugt, was für andere Sound-Ausgaben
zu wenig wäre, aber beim Rauschen nicht stört. Man bekommt dann auch
spektrale Anteile über 4 kHz, was dem weißen Rauschen keinen Abbruch
tut.
'DDSRausch.bas 'Meeresrauschen
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 80
$swstack = 80
$framesize = 80
Dim A As Single
Dim B As Single
Dim D As Word
Dim I As Long
Dim U As Word
Dim O As Word
Dim N As Integer
Dim M As Word
Dim P As Word
Dim E As Byte
Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up '32 kHz
Config Timer1 = Timer , Prescale = 8 '4 kHz
Pwm0a = 0
On Ovf1 Tim1_isr
Enable Timer1
Enable Interrupts
Ddrb.2 = 1
Portb.3 = 1
Portb.4 = 1
Do
I = I + 1 'Wellen
B = I / 300
A = Sin(b) '-1...+1
B = I / 250
A = A + Sin(b) '-2...+2
B = I / 140
A = A + Sin(b) '-3...+3
A = A + 3 '0...6
A = A * 30 '0...180
A = A + 60 '60...240
If I < 600000 Then '1 h, 10000 für 1 min
D = A
M = 65000 'Leise in 6,5 min
Else
M = M - 1
P = M / 256
P = P * A
U = High(p)
D = U
If M < 2 Then
Powerdown
End If
End If
Waitms 2 'ca. 6 ms insgesamt
Loop
Tim1_isr:
'Timer1 8000 kHz / 256/ 8 = 4 kHz
Portb.2 = 1
E = Rnd(255) 'Rauschen
O = D * E
E = High(o)
Pwm0a = E 'Ausgabe
Portb.2 = 0
Return
End
Längeres Lauschen mit dem Kopfhörer zeigte, dass nun tatsächlich ein
typisches Meeresrauschen zu hören ist. Es wirkt sehr entspannend, fast
wäre ich dabei eingeschlafen. Für den Ernstfall am Abend habe ich dann
noch eine Abschaltfunktion mit eingebaut. Das Rauschen läuft eine
Stunde lang und wird dann in ca. sechs Minuten langsam
ausgeblendet. Dann schaltet sich der Controller ab.
Für
den realen Einsatz wurde die Mikrocontroller-Platine in das Gehäuse der
Franzis-Boombox ("MP3-Verstärker") eingebaut. Der eigentliche
Verstärker wurde nur provisorisch abgeklemmt und stattdessen der
Mikrocontroller eingesetzt. Später wird der Wellengenerator vielleicht
mal mit in ein Radio eingebaut.
Den
Lautsprecher treibt der Tiny85 ganz ohne zusätzlichen Verstärker. Es
gibt nur ein zweistufiges Tiefpassfilter und einen Koppelelko zum
Lautsprecher. Tests haben gezeigt, dass man auch einen der
Filterkondensatoren herausziehen kann. Damit bekommt dann Rauschen mehr
Höhenanteile, was je nach Geschmack die Nordsee noch näher rückt.
Da strahlst du eine Ruhe aus,
die zieht dir die Schuhe aus.
(Robert Gernhardt)
Lautstärke und Filterung, Verwendung des ATtin45 von Ralf Bessner
Ich
habe das Meeresrauschen-Programm ausprobiert. Ob es das Einschlafen
verbessert, kann ich noch nicht beurteilen, aber zumindest stört mich
das Rauschen nicht. Ich habe einen alten 8 Ohm-Kfz-Lautsprecher
verwendet. Da er einen recht breiten Frequenzgang hat, habe ich das
Tiefpassfilter abgewandelt und auch noch einen Trimmer zur
Lautstärke-Einstellung hinzugefügt. Mit den gewählten Werten ist das
Rauschen relativ leise, aber gerade richtig im ruhigen Schlafzimmer.
Die
Schaltung läuft auch mit 2-3V aus zwei Mignonzellen; ggf. muss man den
Brownout des ATtiny mit einem ISP-Programmmer weg-fusen bzw. auf 1,8V
herabsetzen.
Wie
man sieht, ist die Schaltung auf einem kleinen Platinenrest aufgebaut
und mit Senkkopfschrauben und jeweils 2 Muttern als Abstandshalter
huckepack auf einen Zweier-Batteriehalter geschraubt.
Ich hatte
noch einen AtTiny45 herumliegen, für den musste ich die Werte für die
reservierten Stackbereiche etwas herabsetzen, weil das SRAM zu knapp
wurde. Man kann die Werte recht weit herabsetzen; mit
$hwstack = 60
$swstack = 20
$framesize = 10
funktionierte noch alles.
Elektronik-Labor
Projekte
AVR
Tiny85