Seit
ich mein Tiny01-Buch abgeschlossen habe, ist wieder mehr Zeit für andere
Dinge. Da wollte ich meine alte Geige mal wieder entstauben und etwas
darauf spielen. Aber sie war nach der langen Zeit so verstimmt, dass es
schwierig war. Schon vorher hatte ich mal daran gedacht, ein Stimmgerät
zu bauen. Am besten mit einem kleinen ATtiny202. Das Gerät sollte die
Töne G, D, A und E spielen, sodass ich die Geige auf gleiche Tonhöhen
stimmen kann.
Ein nummerisch gesteuerter Oszillator (NCO) kann ähnlich aufgebaut
werden wie ein DDS-Generator. Allerdings hat der Tiny202 keinen
DA-Wandler. Deshalb wird im einfachsten Fall ein Rechtecksignal
erzeugt. Die Kurvenform ist relativ egal, denn die Geige erzeugt auch
keinen Sinuston, sondern hat zahlreiche Obertöne.
Wenn ich von null anfange, muss ich nun wieder neu nachdenken und im
Datenblatt suchen, wie man einen Timer-Interrupt bildet, und wie
schnell er laufen sollte. Aber mit den Beispielen aus dem Buch geht das
einfacher. Ich nehme einfach den
1-kHz-DDS-Gernator aus dem Buch, der
mit einem Tiny3216 lief. Dann muss nur alles rausgelöscht werden, was
den DA-Wandler und die Sinustabelle betrifft. Stattdessen wird das
oberste Bit im Phasen-Akku direkt an den Port PA3 ausgegeben.
Damit läuft alles auf dem Tiny202. Der Umbau hat sofort funktioniert,
und ich konnte ein Rechtecksignal mit 1 kHz messen. Als nächstes musste
ich nur noch in der Hauptschleife die vier Frequenzen festlegen. Sie
werden nacheinander für einige Sekunden abgespielt. Das ist
gerade richtig, um die Saiten nacheinander zu stimmen. Man muss ja
mehrmals durch alle Saiten gehen, weil es eine gegenseitige
Beeinflussung der mechanischen Saitenspannung gibt.
//NCO202, Geigen-Stimmgerät
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define F_CPU 20000000
uint16_t phase=0;
uint16_t freq = 1000; //1kHz
ISR(TCA0_OVF_vect) {
PORTA.OUT = 8*(phase>>15);
phase += freq;
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
}
int main(void) {
sei();
_PROTECTED_WRITE (CLKCTRL_MCLKCTRLB, 0); // 20 MHz
PORTA.DIR |= PIN3_bm;
TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc;
TCA0.SINGLE.PER = 305; //65,536 kHz
TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm;
TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm;
while (1) {
freq=196; //G
_delay_ms(5000);
freq=294; //D
_delay_ms(5000);
freq=440; //A
_delay_ms(5000);
freq=659; //E
_delay_ms(5000);
}
}
Für den ersten Test habe ich einfach einen großen
Lautsprecher in Reihe mit 1 k direkt am Port A3 verwendet. Aber dann
sollte es etwas ordentlicher gebaut werden. Eine eigene kleine Platine
konnte direkt auf dem Steckboard über die UPDI-Leitung programmiert
werden.
Zu viele unterschiedliche
Geräte bauen ist nicht zielführend. Wenn ich dann ein bestimmtes Gerät
nach längerer Zeit mal wieder brauche, ist es nicht mehr auffindbar.
Deshalb wurde das Stimmgerät mit in mein neues UKW-Radio
einbaut.
Gleicher Akku, gleicher Lautsprecher, und sogar der Endverstärker kann
mit verwendet werden. Gebraucht wird nur der Tiny202 und ein
Koppelelko. Wenn der Tiny eingeschaltet wird, verstummt
das Radio automatisch, weil der Port dann niederohmig wird und das
Radiosignal kurzschließt. Ein Schalter ist auch nicht nötig, im
ausgeschalteten Zustand wird einfach die Plusleitung der
Tiny202-Platine abgezogen.