Sound-Recorder mit dem ATtiny85    


Elektronik-Labor   Projekte   AVR  Tiny85




Video: 
https://youtu.be/CKxWZ-woMuc

Wie kann man mit möglichst wenig Speicherplatz möglichst lange Soundsequenzen speichern? Das möchte ich hier mit dem Lernpaket Mikrocontroller an einem Tiny85 durchspielen. Mit dem Interface-Programm des Lernpakets hat man ja ein kleines Oszilloskop. Hier zeigt es ein Signal mit 800 Hz. Die Daten wurden im RAM zwischengespeichert und könnten über PWM wieder abgespielt werden. Allerdings sind es leider nur 20 volle Schwingungen. Damit wird nur eine Dauer von 25 ms gespeichert. Zu wenig für die meisten Anwendungen.



Lernpaket Mikrocontroller

Der Versuch verwendet einen Koppelkondensator mit 100 nF am Eingang und ein Tiefpassfilter mit 2,2 k und 100 nF am PWM-Ausgang an B0.


'Sound1
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 8
$swstack = 4
$framesize = 4


Config Adc = Single , Prescaler = 4
Start Adc

Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up


Dim D(400) As Byte
Dim U As Word
Dim N As Word
Dim I As Byte


Do
'Aufnahme
For N = 1 To 400
U = Getadc(2)
Shift U , Right , 2
D(n) = U
Waitus 400
Next N
'Abspielen
For N = 1 To 400
Pwm0a = D(n)
Waitus 420
Next N
Loop

End


Im ersten Versuch wurden jeweils 400 Bytes gespeichert und wieder abgespielt. Die Abtastrate musste so tief wie möglich gebracht werden, damit die Speicherzeit so lang wie möglich wurde. Könnte man wenigstens einen Klang erkennen, der in einer Endlosschleife abgespielt wird? Das soll hier mit einem zweiten Basom-Programm getestet werden.

'Sound2
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 8
$swstack = 4
$framesize = 4


Config Adc = Single , Prescaler = 4
Start Adc

Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up


Dim D(400) As Byte
Dim U As Word
Dim N As Word
Dim I As Byte


Do
'Aufnahme
For N = 1 To 400
U = Getadc(2)
Shift U , Right , 2
D(n) = U
Waitus 400
Next N
'10-mal abspielen
For I = 1 To 10
For N = 1 To 400
Pwm0a = D(n)
Waitus 420
Next N
Next I
Loop

End

Zum Test wurde dann auch einmal auf die Speicherung verzichtet. Jedes Byte wird sofort wieder über PWM ausgegeben. Durch Ändern der Wartezeit lassen sich unterschiedliche Abtastraten erzielen und im Klang vergleichen. Dabei zeigt sich natürlich, je höher die Abtastrate, desto besser wird der Klang. Aber leider würde dabei auch der Speicherbedarf steigen.


'Sound3
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 8
$swstack = 4
$framesize = 4


Config Adc = Single , Prescaler = 4
Start Adc

Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up


Dim D(400) As Byte
Dim U As Word
Dim N As Word
Dim I As Byte


Do
U = Getadc(2)
Shift U , Right , 2
Pwm0a = U
Waitus 400
Loop

End

Und es gibt noch ein alternatives Verfahren, das ohne den PWM-Ausgang auskommt. Es entspricht dem PCM-Verfahren und braucht nur einen Port, der passend ein- und ausgeschaltet wird. Das Tiefpassfilter macht daraus einen Spannungsverlauf, der dem Eingangssignal folgt. In der Software wird mitgerechnet. Der Inhalt von P soll U folgen und wird dazu passend vergrößert oder verkleinert.

'Sound4, PCM
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 8
$swstack = 4
$framesize = 4


Config Adc = Single , Prescaler = 4
Start Adc

'Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Up
Ddrb.0 = 1

Dim D(400) As Byte
Dim U As Word
Dim P As Byte


P = 128
Do
U = Getadc(2)
Shift U , Right , 2
If U > P Then
If P < 245 Then P = P + 4
Portb.0 = 1
Else
If P > 10 Then P = P - 4
Portb.0 = 0
End If
Waitus 100
Loop
End

Das Verfahren spart Speicherplatz, weil jetzt immer nur ein Bit gespeichert werden muss. Dafür muss man die Abtastrate erhöhen. Mit einer Wartezeit von 100 µs ist der Klang erträglich. In einem Soundrecorder müsste man jeweils 8 Bits in einem Byte speichern. Insgesamt passt eine deutlich längere Aufnahme in den Speicher.

'Sound5, PCM
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 8
$swstack = 4
$framesize = 4


Config Adc = Single , Prescaler = 4
Start Adc

Ddrb.0 = 1

Dim D(400) As Byte
Dim U As Word
Dim P As Byte
Dim N As Word
Dim I As Byte
Dim B As Byte

P = 128
Do
'Aufnahme
For N = 1 To 400
For I = 1 To 8
Shift B , Right
U = Getadc(2)
Shift U , Right , 2
If U > P Then
If P < 245 Then P = P + 2
B.7 = 1
Else
If P > 10 Then P = P - 2
B.7 = 0
End If
Waitus 100
Next I
D(n) = B

Next N

'Abspielen
For N = 1 To 400
B = D(n)
For I = 1 To 8
Portb.0 = B.0
Shift B , Right
Waitus 120
Next I
Next N
Loop
End

Das ist ungefähr das Beste, was ich aus dem kleinen Speicher herausholen kann. Das Verfahren hat sich jedenfalls bewährt und könnte noch bei anderen Controllern mit etwas mehr Speicher nützlich werden.



Elektronik-Labor   Projekte   AVR  Tiny85