PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frequenz beim Beeper



RobotMichi
08.01.2010, 17:08
Hi,

auh ich hab jetzt das M32 Erweiterungsboard. Nun habe ich eine Frage zum Beeper:
Man kann da Tonhöhen von 0-255 eingeben. Wie kann man nun rausfinden, welche Frequenz diese Töne in Wirklichkeit haben? Ich würde den RP6 nämlich gern ein Lied singen lassen, zu dem ich die Noten auf Papier hab. (z.B. a' = 440hz). Allerdings weiß ich nicht, was ich für eine Zahl eingeben muss, damit ich 440hz bekomme.

lg
Michi

021aet04
08.01.2010, 18:59
Frequenzen kannst du mit einem Frequenzmesser, mit einem Oszilloskop und teilweiße mit DMM messen. Wenn du einen µC übrig hast könntest du ein Porgramm schreiben, der die Frequenz misst und dann anzeigt.

MfG Hannes

radbruch
08.01.2010, 19:20
Hallo

Gleich vorweg: Ich bin ziemlich unmusikalisch, ein mäsiger Mathematiker und ich besitze kein M32. Aber ich kann versuchen, dir (mehr oder weniger gut) die Funktion von beep() erklären:

Basis ist der Timer2 der im CTC-Mode mit Perscaler /256 betrieben wird. Die Funktion des OC2-Pins steht dabei auf togglen:


void beep(uint8_t pitch, uint16_t time)
{
controlStatus.beep = true;
sound_timer = time;
OCR2 = 255-pitch;
// CTC-Mode, toggle OC2, prescaler /256
TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS22) | (1 << CS21);
}(Die Funktion beep() aus der Datei RP6ControlLib.c)

Der Prescaler teilt den Kontrollertakt und erzeugt den Countertakt. Bei jedem Countertakt zählt der Counter das Zählregister TCNT2 um einen Schritt weiter. Wenn das Zählregister gleich dem Wert im OCR2-Register ist, wird der Ausgang OC2 (an dem der Lautsprecher angeschlossen ist) umgeschaltet und das Zählregister startet wieder bei 0. Wenn wir uns nun auf die Formeln stürzen, müssen wir noch beachten, dass eine Schwingung aus zwei Counterdurchläufen besteht, der OC2-Pin also zweimal umgeschaltet werden muss und dass der maximale Wert für OCR2 255 ist (Timer2 hat 8 Bit):

Höchste Frequenz bei OCR2=1:
16000000MHz/256 Prescaler/2 Halbwellen=31250 Hz

Tiefste Frequenz bei OCR2=255:
16000000MHz/256 Prescaler/2 Halbwellen/255 Countertakte= ca. 120 Hz

Berechnung des OCR2-Wertes aus der gewünschten Frequenz des Tones:

16000000MHz/256 Prescaler/2 Halbwellen/ Tonfrequenz ergibt für den Kammerton "A" 31250Hz/440Hz ca. 71

Da die beep()-Funktion den Parameter nicht direkt ins OCR2-Register schreibt, müssen wir den Parameter noch anpassen:

beep(255-(31250/440), dauer)

(Keine Gewähr für diese Berechnung;)

Gruß

mic

PICture
08.01.2010, 20:19
Hallo!

@ RobotMichi

Musik ist nur mein Hobby, weiss ich aber sicher, dass die benachbarte Töne in einer Oktave in im Code skizziertem Verhältniss zueinander sind.

Daraus ergibt sich z.B. für a´= 440 Hz ais´= 446,... also rund 466 Hz usw.

Wahrscheinlich weiss du es... :)

MfG

12
__ _____
Ton1 \ /
----- = \ / 2 = 1,059463094...
Ton2 \/

Dirk
08.01.2010, 21:06
Hallo RobotMichi,

ich habe dies für die M32 herausgefunden:
H - 2

c - 16
cis - 30
d - 42
dis - 54
e - 65
f - 76
fis - 86
g - 96
gis - 105
a - 113
ais - 121
h - 128

C1 - 136
Cis1 - 142
D1 - 149
Dis1 - 155
E1 - 160
F1 - 166
Fis1 - 171
G1 - 175
Gis1 - 180
A1 - 184
Ais1 - 188
H1 - 192

C2 - 195
Cis2 - 199
D2 - 202
Dis2 - 205
E2 - 208
F2 - 210
Fis2 - 213
G2 - 215
Gis2 - 217
A2 - 219
Ais2 - 221
H2 - 223

C3 - 225
Cis3 - 227
D3 - 228
Dis3 - 230
E3 - 231
F3 - 233
Fis3 - 234
G3 - 235
Gis3 - 236
A3 - 237
Ais3 - 238
H3 - 239

Höhere Töne sind nicht mehr genau reproduzierbar.

Gruß Dirk

radbruch
08.01.2010, 21:59
Hallo

Zur Einstimmung erstmal ein kleines Video:

http://i2.ytimg.com/vi/a60aLP9_1_A/3.jpg (http://www.youtube.com/watch?v=a60aLP9_1_A)
http://www.youtube.com/watch?v=a60aLP9_1_A

Mein Jukebox-Speaker (https://www.roboternetz.de/phpBB2/viewtopic.php?p=339303#339303) hängt an SCL, die Frequenzen werden wie beim M32 mit dem Timer2 erzeugt und am OC2 ausgegeben (die IR-COMM-LEDs blinken im Takt). Bei der Ausgabe wird der Pegel an OC2 eingelesen und auf den SCL-Pin kopiert (der selbe Trick funktioniert ja auch am TXD):

// Tonerzeugung am RP6-Base mit beep() aus der M32-Library 9.1.2010 mic
// Der Speaker hängt an PC0(SCL)

// https://www.roboternetz.de/phpBB2/viewtopic.php?t=52013

#define ton_c 255-(15625/264)
#define ton_d 255-(15625/297)
#define ton_e 255-(15625/330)
#define ton_f 255-(15625/352)
#define ton_g 255-(15625/396)
#define ton_a 255-(15625/440)
#define ton_h 255-(15625/495)
#define ton_c1 255-(15625/528)

#define ganzton 400

#include "RP6RobotBaseLib.h"

void beep(uint8_t pitch, uint16_t time) // aus der Lib des M32
{
//controlStatus.beep = true;
//sound_timer = time;
OCR2 = 255-pitch;
// CTC-Mode, toggle OC2, prescaler /256
TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS22) | (1 << CS21);

setStopwatch1(0);
DDRD |= (1<<PD7); // OC2-Pin auf Ausgang für Timer2 ;)
while(getStopwatch1()<time)
{
if(PIND & (1<<PD7)) PORTC |= 1; else PORTC &= ~1; // SCL mit OC2 togglen ;)
}
TCCR2 = 0; // Ton aus
DDRD &= ~(1<<PD7); // OC2-Pin auf Eingang ;)
PORTD &= ~(1<<PD7); // damit die IR-Comm-LED nicht durchbrennt
PORTC &= ~1; // Lautsprecher aus
mSleep(ganzton/10); // Trennung zwischen den Tönen
}

int main(void)
{
initRobotBase();
DDRC |= 1; // SCL auf Ausgang und Low Der Speaker
PORTC &= ~1;
DDRD &= ~(1<<PD7); // OC2-Pin auf Eingang
PORTD &= ~(1<<PD7); // ohne PullUp
startStopwatch1();

beep(ton_c, ganzton); // Tonleiter rauf
beep(ton_d, ganzton);
beep(ton_e, ganzton);
beep(ton_f, ganzton);
beep(ton_g, ganzton);
beep(ton_a, ganzton);
beep(ton_h, ganzton);
beep(ton_c1, ganzton);
mSleep(1000);
beep(ton_c1, ganzton/2); // und wieder runter
beep(ton_h, ganzton/2);
beep(ton_a, ganzton/2);
beep(ton_g, ganzton/2);
beep(ton_f, ganzton/2);
beep(ton_e, ganzton/2);
beep(ton_d, ganzton/2);
beep(ton_c, ganzton/2);
mSleep(2000);

while(1)
{
//Ode an die Freude (http://www.doktus.de/dok/25443/ode-an-die-freude.html)
beep(ton_e, ganzton);
beep(ton_e, ganzton);
beep(ton_f, ganzton);
beep(ton_g, ganzton);

beep(ton_g, ganzton);
beep(ton_f, ganzton);
beep(ton_e, ganzton);
beep(ton_d, ganzton);

beep(ton_c, ganzton);
beep(ton_c, ganzton);
beep(ton_d, ganzton);
beep(ton_e, ganzton);

beep(ton_e, ganzton+ganzton/2);
beep(ton_d, ganzton/2);
beep(ton_d, ganzton*2);

beep(ton_e, ganzton);
beep(ton_e, ganzton);
beep(ton_f, ganzton);
beep(ton_g, ganzton);

beep(ton_g, ganzton);
beep(ton_f, ganzton);
beep(ton_e, ganzton);
beep(ton_d, ganzton);

beep(ton_c, ganzton);
beep(ton_c, ganzton);
beep(ton_d, ganzton);
beep(ton_e, ganzton);

beep(ton_d, ganzton+ganzton/2);
beep(ton_c, ganzton/2);
beep(ton_c, ganzton*2);

beep(ton_d, ganzton);
beep(ton_d, ganzton);
beep(ton_e, ganzton);
beep(ton_c, ganzton);

beep(ton_d, ganzton);
beep(ton_e, ganzton/2);
beep(ton_f, ganzton/2);
beep(ton_e, ganzton);
beep(ton_c, ganzton);

beep(ton_d, ganzton);
beep(ton_e, ganzton/2);
beep(ton_f, ganzton/2);
beep(ton_e, ganzton);
beep(ton_d, ganzton);

beep(ton_c, ganzton);
beep(ton_d, ganzton);
mSleep(ganzton*2);

beep(ton_e, ganzton);
beep(ton_e, ganzton);
beep(ton_f, ganzton);
beep(ton_g, ganzton);

beep(ton_g, ganzton);
beep(ton_f, ganzton);
beep(ton_e, ganzton);
beep(ton_d, ganzton);

beep(ton_c, ganzton);
beep(ton_c, ganzton);
beep(ton_d, ganzton);
beep(ton_e, ganzton);

beep(ton_d, ganzton+ganzton/2);
beep(ton_c, ganzton/2);
beep(ton_c, ganzton*2);

mSleep(2000);
}
return(0);
}
Die Formel habe ich an die 8MHz des Base angepasst. Warum die Stopwatch() gelegentlich "stolpert" habe ich noch nicht rausbekommen, aber als Demo scheint mir das schon recht nett :)

@Dirk: Wie hast du deine Werte für die beep()-Funktion ermittelt?

Gruß

mic

[Edit]
Lautsprecher aus nach beep()

Dirk
08.01.2010, 22:14
@radbruch:
Pitch = 255 - (16000000 / 256 / Tonfrequenz / 2)

Für "Tonfrequenz" habe ich die temperierte Stimmung genommen.

Gruß Dirk

radbruch
08.01.2010, 22:21
Hallo Dirk

Na wunderbar. Dann hätte ich mir das ja auch alles ersparen können, wenn du die Formel schon hast ;)

Gruß

mic

Dirk
08.01.2010, 22:39
Übrigens, Leute:

Wer auch die RP6CCPRO M128 "singen" lassen will:
Pitch = 14745600 / 64 / Tonfrequenz / 2

Gruß Dirk

P.S.: Die klingt auch wesentlich besser und schafft 7,5 Oktaven.

kyodai
08.01.2010, 22:40
Habe gerade überlegt ob man mit dem M32 auch Wave Klänge wiedergeben könnte. Über beep könnte man das Wave in kurze 1 ms Happen verteilen, den durchschnittswert der Frequenz während der milisekunde ermitteln und einen passenden beep für 1 ms abspielen. Aber bestimmt gibs eh schon eine wave funktion, oder?

Xandi11
08.01.2010, 22:53
Das mit den Durchschnittswerten ist so eine Sache, genau genommen klingen die meisten bescheiden.

Den Durchschnittswert zu nehmen ist eigentlich keine so gute Lösung, viel besser ist es meiner Meinung nach sich die Melodie (oder was auch) selbst vorzujodeln und dann zu beurteilen was passen könnte.

Mit etwas Verstand und viel Glück kein Problem =)

Dirk
09.01.2010, 12:15
Hallo Xandi11,

was meinst du mit "Durchschnittswerten" und "klingen die meisten bescheiden"?

Das mit dem "selbst vorjodeln" klappt bei mir weder mit Verstand noch mit Glück.

Leider habe ich aber auch nicht das absolute Gehör ... =P~

Gruß Dirk

RobotMichi
09.01.2010, 15:31
Hi,

danke für die vielen Antworten, ihr habt mir wirklich sehr geholfen.

lg
Michi

kyodai
09.01.2010, 20:57
Das mit den Durchschnittswerten ist so eine Sache, genau genommen klingen die meisten bescheiden.

Den Durchschnittswert zu nehmen ist eigentlich keine so gute Lösung, viel besser ist es meiner Meinung nach sich die Melodie (oder was auch) selbst vorzujodeln und dann zu beurteilen was passen könnte.

Mit etwas Verstand und viel Glück kein Problem =)

Hmm ist die Frage wie fein die "Auflösung" des menschlichen Ohres ist. Vermutlich so hoch wie die höchste Frequenz die man wahrnehmen kann? Wäre die Frage wie es ein richtiger SOundchip beim wave playback macht, wie oft kann er die Frequenz ändern? ich denke mal da 48 KHz so das höchste ist daß man bei wave angeboten bekommt also 48 mal je milisekunde? Denke mal aber so ab 10 mal pro milisekunde "10 KHz" müsste sich das doch brauchbar anhören?

Xandi11
09.01.2010, 21:40
@ kyodai:
theoretisch ja ... das mit dem brauchbar anhören das ist so ne sache

@ Dirk:
Mit den Durchschnittwerten meine ich dass man ein D im Code verwendet obwohl eigentlich gleichzeitig C und E verwendet werden müssen und mit "Klingen die meisten bescheiden" meine ich eben dass genau diese nicht gerade toll klingen.


Tatsache ist dass die M32 nur 1 Piezokristall hat ... und das eben oft zu wenig ist ...
hätte man 2 Stück, wäre die Sache viel einfacher und es würde eigentlich relativ schön klingen.

Dirk
09.01.2010, 22:02
@Xandi11:

Mit den Durchschnittwerten meine ich dass man ein D im Code verwendet obwohl eigentlich gleichzeitig C und E verwendet werden müssen ...
Der kümmerliche Sound, den solche Piepser mit Timer-Ansteuerung an einem uC-Pin produzieren können, ist zwangsläufig homophon (das ist das Gegenteil von polyphon). Also ist ein D ein D und zwei Töne gleichzeitig sind nicht möglich.

Gruß Dirk

Xandi11
10.01.2010, 10:30
Eben darum klingt es ja dann nicht wirklich gut ...

Kann man eigentlich einen 2ten Beeper auf die M32 aufbauen?

M1C
10.01.2010, 13:51
Das ding hatt 16 Freie IO Ports^^
Sicherlich kannst du das machen =)

Xandi11
10.01.2010, 13:59
... die Frage war etwas blöd gestellt, glaube ich.

Eigentlich hätte mich interessiert, wie man den dann anspricht.

Kann ich dann die Library so verändern, dass ich die Funktion vom Originalbeeper kopiere, sie auf z.B. sound2 oder so umbenenne und den Port logischerweise auch umbenenne.

Müsste doch so funktionieren, oder ?

radbruch
10.01.2010, 14:42
Ganz so einfach ist es leider nicht, weil der Mega32 nur einen Timer2 besitzt.

Da beim M32 die Ausgänge OC1A und OC1B des 16_Bit-Timer1 nicht belegt sind, könnte man hier ansetzen. Aber wollen wir das wirklich? Blechern wird es trotzdem klingen ;)

Gruß

mic

Xandi11
10.01.2010, 14:50
Die Base des RP6 wäre ja auch noch da.

Kann man über sie einen Timer für einen 2. Beeper verwenden, oder ist das nicht möglich?

Das wäre ja vom Prinzip her das Selbe, wie wenn man 2 Servos gleichzeitig unterschiedliche Bewegungen durchführen lässt (was ich bis jetzt noch nie gemacht habe 8) ).

Edit:
Aber wenn ich mir das so überlegt ... nicht rentabel ... zumindest nicht für einen 2. Beeper.