Forum: Mikrocontroller und Digitale Elektronik tonleitergenerator m328


von grundschüler (Gast)


Lesenswert?

ich möchte ein Ereignis - Beendigung eines Backvorgangs -  akustisch 
anzeigen. Dem Ereignisangemessen wäre eine kleine Fanfare, z.B. 
verkürzter Walkürenritt. Dafür suche ich einen einfachen Tongenerator. 
Ich habe bislang:
1
main(){
2
...
3
#if 01
4
#define wait _delay_ms(20);
5
    soundtimer=10000;
6
while(1){
7
    wait;pwm_sound_on(10);//2778
8
    wait;pwm_sound_off();
9
    wait;pwm_sound_on(20);//1562
10
    wait;pwm_sound_off();
11
    wait;pwm_sound_on(30);//1000
12
    wait;pwm_sound_off();
13
    wait;pwm_sound_on(40);//780
14
    wait;pwm_sound_off();
15
    wait;pwm_sound_on(50);//610
16
    wait;pwm_sound_off();
17
    wait;pwm_sound_on(60);//510
18
    wait;pwm_sound_off();
19
    wait;pwm_sound_on(70);//446
20
    wait;pwm_sound_off();
21
    wait;pwm_sound_on(80);//390
22
    wait;pwm_sound_off();
23
    wait;pwm_sound_on(90);//347
24
    wait;pwm_sound_off();
25
    wait;pwm_sound_on(100);//312
26
    wait;pwm_sound_off();
27
    wait;pwm_sound_on(120);//260
28
    wait;pwm_sound_off();
29
    wait;pwm_sound_on(130);//242
30
    wait;pwm_sound_off();
31
    wait;pwm_sound_on(140);//225
32
    wait;pwm_sound_off();
33
    wait;pwm_sound_on(150);//208
34
    wait;pwm_sound_off();
35
    wait;pwm_sound_on(200);//156
36
    wait;pwm_sound_off();
37
    wait;pwm_sound_on(250);//125
38
    wait;pwm_sound_off();
39
    wait;pwm_sound_on(254);//124
40
    wait;pwm_sound_off();
41
    wait;pwm_sound_on(255);//123
42
    wait;pwm_sound_off();
43
    _delay_ms(1000);
44
    
45
  }
46
47
48
#else
49
pwm_sound_on(110);
50
soundtimer=2;
51
#endif
52
53
...
54
}
55
56
57
58
59
void pwm_sound_on(u8 ton){
60
 /*
61
cs02+01+00:
62
0 no clock
63
1 no presc
64
2 /8
65
3 /64
66
4 /256
67
5 /1024
68
*/
69
70
TCCR2A |= (1<<WGM21);
71
    // 1; Timer0 Vorteiler: 64 -> bei 16 MHz: 
72
    // 16.000.000 / 64 = 250000 Mal pro Sek gibts einen Takt an den Timer
73
    // 8.000.000 / 1024 = 7812 Mal pro Sek gibts einen Takt an den Timer
74
    
75
TCCR2B |= ((1<<CS22)|(1<<CS20));//1024
76
    
77
    // Timer0 soll bei 250 einen Output Compare Interrupt ausl?sen ->
78
    // 250.000 / 250 = 1000 mal pro Sek gibts einen Interrupt
79
    // 7812 /78 = 100 mal pro Sek gibts einen Interrupt
80
OCR2A = ton;//189;//30ms
81
82
    //Compare Interrupt aktivieren
83
TIMSK2 |= (1<<OCIE2A);
84
85
    //Globale Interrupts aktivieren
86
sei();
87
88
 
89
 }
90
91
void pwm_sound_off(void){
92
TCCR2A =0;
93
TCCR2B=0;
94
TIMSK2 &= ~(1<<OCIE2A);
95
}


Die Frequenzen sind mit dem la ausgemessen. Müsste jetzt Tonleiternoten 
zugeordnet werden. Bevor das ganze in Arbeit ausartet, hat jemand 
irgendetwas brauchbares Fertiges für avr?

Danke für Unterstützung

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Tonleiter ist doch einfach. Ein Halbtonschritt ist die zwölfte Wurzel 
aus zwei. Nach zwölf Halbtonschritten hat man die Frequenz halbiert oder 
verdoppelt, das ist eine Oktave. Einfach die Zahl mit dem 
wissenschaftlichen Taschenrechner mal oder durch 2^(1/12) pro Halbton 
multiplizieren/dividieren.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Christoph db1uq K. schrieb:
> Tonleiter ist doch einfach. Ein Halbtonschritt ist die zwölfte Wurzel
> aus zwei. Nach zwölf Halbtonschritten hat man die Frequenz halbiert oder
> verdoppelt, das ist eine Oktave.
Und ganz offenbar verdoppelt sich die Frequenz bei halbem "ton"-Wert. 
Damit kann man doch schon was anfangen und den nächsten Ton sogar in 
Echtzeit ausrechnen...

> Tonleiter ist doch einfach.
Naja, kann auch kompliziert werden. Siehe dazu den 
Beitrag "Tonleiter mit acht Tönen herstellen"
;-)

: Bearbeitet durch Moderator
von Daten Experte (Gast)


Lesenswert?

Christoph db1uq K. schrieb:
> Tonleiter ist doch einfach. Ein Halbtonschritt ist die zwölfte Wurzel
> aus zwei.

Das ergibt aber keine Tonleiter nach dem Empfinden des
menschlichen Gehörs.

Eine Dur-Tonleiter besteht aus 8 Tönen

1) dem Grundton
2) +  2xHT (dem nächsten Ganzton, zwei Halbtöne)
3) +  4xHT
4) +  5xHT
5) +  7xHT (Quint)  (un-temperiert: 1.5x Grundton)
6) +  9xHT (Sext)
7) + 11xHT (Sept)
8) + 12xHT (Oktave)

von grundschüler (Gast)


Lesenswert?

1
#define ton_H pwm_sound_off();pwm_sound_on(255)
2
#define ton_e pwm_sound_off();pwm_sound_on(188)
3
#define ton_g pwm_sound_off();pwm_sound_on(160)
4
#define ton_h pwm_sound_off();pwm_sound_on(128)
5
#define wait _delay_ms(20);
6
#define w _delay_ms(800);
7
8
9
10
11
soundtimer=10000;
12
13
while(1){
14
15
ton_e;w;w;
16
ton_g;w;
17
ton_e;w;w;
18
ton_H;w;
19
ton_e;w;
20
ton_g;w;
21
ton_h;w;
22
ton_e;w;w;
23
pwm_sound_off();
24
25
    
26
}

noch nicht der Walkürenritt - aber immerhin eine Melodie aus Noten 
zusammengestellt.

von Max II (Gast)


Lesenswert?

Schau dir doch mal den Beitrag "Klingel mit 100 Melodien - last minute Weihnachtsgeschenk"
an. Da sollte alles dabei sein, was du brauchst.

von grundschüler (Gast)


Lesenswert?

Max II schrieb:
> "Klingel mit 100 Melodien - last minute Weihnachtsgeschenk"


genau das wärs gewesen, was ich gesucht hatte.

Leider ist das Programm schon fertig:

1
#define achtelton _delay_ms(400)
2
3
#define ton_H(achtel) pwm_sound_on(255);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
4
#define ton_c(achtel) pwm_sound_on(235);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
5
#define ton_d(achtel) pwm_sound_on(215);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
6
#define ton_e(achtel) pwm_sound_on(188);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
7
#define ton_f(achtel) pwm_sound_on(177);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
8
#define ton_g(achtel) pwm_sound_on(160);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
9
#define ton_a(achtel) pwm_sound_on(142);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
10
#define ton_h(achtel) pwm_sound_on(128);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
11
#define ton_hc(achtel) pwm_sound_on(118);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
12
#define ton_hd(achtel) pwm_sound_on(105);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
13
#define ton_he(achtel) pwm_sound_on(94);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
14
#define ton_hf(achtel) pwm_sound_on(88);for(i=0;i<achtel;i++)achtelton;pwm_sound_off();
15
16
17
18
while(1){
19
20
ton_e(4);
21
ton_g(2);
22
ton_e(4);
23
ton_H(2);
24
ton_e(2);
25
ton_g(2);
26
ton_h(2);
27
ton_e(4);
28
29
30
_delay_ms(1000);
31
}

Dameit kann man einfach Notenschriften in code umsetzen.

Ich werde mir aber den pwm-timer-Teil anschauen und wahrscheinlich 
übernehmen

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.