Einfache Tonerzeugung

OP #2788123
Lesenswert?

Hallo
habe da ein kleines Problem mit einer einfachen Tonerzeugung. Ich 
verwende den Befehl

sound_tone(spannung2,32000);

Mit einer Spannung (spannung2) die ich einstellen kann von 0 bis 5V 
verändere ich die Tonhöhe (durchstimmbar). Die 32000 geben die Tonlänge 
an. Dabei sind die 32000 fast schon die längste einstellbare Zeit. Dann 
beendet der Ton und beim nächsten Durchlauf beginnt alles wieder von 
vorn.
Ich möchte denn Ton aber auf Dauer haben, so wie bei einem Tongenerator.
achim
Gast #2788145
Lesenswert?

Keine Ahnung, welche Programmiersprache oder Bibliothek du verwendest. 
Genausowenig wie klar ist, welchen Prozessor du benutzt bzw. welche 
Hardware deinen Ton erzeugen soll.
Aber ich würde mal annehmen, dass der Parameter 0 für die Tonlänge 
"unendlich" bedeutet, d.h. ein Dauerton, wie du ihn willst.
#2788351
Lesenswert?

Ralf schrieb:

> "spannung2" ist wirklich eine Spannungsangabe und keine Frequenz?

Ich denke mal er meint:

Mit einem ADC greift er eine Spannung von einem Poti ab und den ADC Wert 
nimmt er direkt als Frequenzangabe für die Funktion sound_tone.

Keine Ahnung, welche Lib das ist. Auch bei Arduino gibts keine Funktion 
dieses Namens (zumindest ist mit Google nichts zu finden)
OP #2788426
Lesenswert?

Hallo
Karl-Heinz hat genau recht. Ich bekomme die Spannug von einem Poti 
zwischen 0 und 5 Volt. Diese kommen über einen ADC und werden auf dem 
LCD angezeigt. Danach drehe ich die Spannung 5V zu 0V, da die tiefste 
Frequenz bei 5V und die höchste Frequenz bei 0V liegt. Beide Werte lasse 
ich mir auf dem Display anzeigen. Dadurch habe ich die Möglichkeit mit 
den 5V das gesamte NF Band zu durchlaufen. Der Klang aus dem Piezo ist 
Mist (anderes Problem. Da die max Zeit aber feststeht kommt es zu kurzen 
Unterbrüchen. Alle delay sind raus, auch alles was nicht unbedingt 
gebraucht wird.
Die Angabe mit dem Nibo ist korrekt. Gibt es eine andere Art den Ton zu 
erzeugen?
achim
Gast #2788462
Lesenswert?

Hi

>Die Angabe mit dem Nibo ist korrekt. Gibt es eine andere Art den Ton zu
>erzeugen?

Da ich nicht glaube das der NIBO Sinustöne erzeugt, reduziert sich die 
Tonerzeugung auf einfaches Umschalten eines Pin im geeigneten Takt. 
Dafür bietet sich ein Timer im CTC-Mode. Dein Aussagen lassen vermuten, 
das der NIBO das auch so macht. Mit einem 16-Bit-Timer (CTC, Vorteiler 
256) lassen sich mit den ADC-Werten (0...1023) Töne im Bereich von etwa 
30Hz bis 30kHz erzeugen. Kannst ja mal überprüfen, ob der Piezo an PB5 
oder PE2 angeschlossen ist.

Also einfach statt 'sound_tone' zu verwenden die passenden Timerregister 
beschreiben und fertig.

MfG Spess
Gast #2788664
Lesenswert?

Hi

Ich muß mich revidieren. Die Jungs sind dümmer als erwartet:
1
void sound_tone(int interval, int time) {
2
  while (time) {
3
    int i=interval;
4
    clear_output_bit(IO_AUDIO);
5
    while (time && i) {
6
      time--;
7
      i--;
8
      delay_us(10);
9
    }
10
    i=interval;
11
    set_output_bit(IO_AUDIO);
12
    while (time && i) {
13
      time--;
14
      i--;
15
      delay_us(10);
16
    }
17
  }
18
}

MfG Spess
#2788672
Lesenswert?

spess53 schrieb:
> Hi
>
> Ich muß mich revidieren. Die Jungs sind dümmer als erwartet:

Geh nicht so hart mit ihnen ins Gericht.
Die Jungs müssen darauf Rücksicht nehmen, dass die Timer an einem Robot 
für wichtige Dinge gebraucht werden, wie zb die PWM für die 
Motorsteuerung.

Wer seinen Robot beim Rumfahren noch düdeln lassen will, muss eben 
zurückstecken.
#2788722
Lesenswert?

spess53 schrieb:
> Hi
>
>>Wer seinen Robot beim Rumfahren noch düdeln lassen will, muss eben
>>zurückstecken.
>
> Aber zum LED-Dimmen wird ein 16-Bit-Timer (mit)benutzt.

Echt?
Na ja. zum LED dimmen ist die PWM Frequenz auch ziemlich wurscht, das 
geht mit der Motor-PWM mit.

(Ich hab die Lib nicht im Detail studiert. Ich kenn nur den Teil der 
beim NiboBee benutzt wird. Und auch den nicht besonders gut.)
Gast #2788743
Lesenswert?

Hi

>Echt?

Ja, leds.c benutzt die pwm.c und die wiederum Timer1. Mich hatte 
eigentlich nur die obige Routine interessiert. Aber den Code gab es nur 
im Paket. Und da habe ich mich mal kurz umgesehen.

MfG Spess
Gast #2789347
Lesenswert?

Hi

>Habe gerade nachgesehen. Es liegt auf dem PB(4). Der Lautsprecher ist
>aber mit 2 x LM358 angeschlossen, mit Randbeschaltung.

PB4 ist der Wert von IO_AUDIO. Hatte ich schon gefunden.

>bei den 2 OPV handelt es sich um LM358. Diese sind als Sallen-Key
>Tiefpass geschaltet.

Macht das Rechtecksignal erträglicher.

Das Prinzip von sound_tone ist nur für kurze Töne geeignet, da der 
Controller damit blockiert wird. Wie willst du jetzt weiter machen?

MfG Spess
#2789400
Lesenswert?

Zum Beispiel, in dem man in festgelegten Zeitabständen, die sich durch 
Frequenz und Samplerate ergeben, den PWM Wert verändert. Den zu ladenden 
PWM Wert kann man in einer Lookuptable ablegen, so dass keine 
Sinusberechnungen durchgeführt werden müssen.
Das sieht zum Beispiel so aus:
1
/* Sinustabelle mit 16 Samples (=22,5°) für 4 Bit DAC. Nulldurchgang = 7 */
2
const uint8_t sinus[16] = {7,10,12,13,14,13,12,10,7,4,2,1,0,1,2,4};
Ist allerdings für einen 4-Bit R2R DAC. Bei der PWM Lösung werden die 
einzelenen Werte entsprechend größer, da ja nicht 4 sondern 8 oder sogar 
16 Bit zur Verfügung stehen. Ich hab die Tabelle in Excel vorbereitet, 
da gibts ja eine Sinusfunktion.

Um nun die Frequenz zu ändern, muß die Zeit zwischen dem Neuladen des 
PWM Wertes geändert werden. Für obige Tabelle mit 16 Samples ist die 
Zeit also
t= T/16.
Nun muß man also eine Zeitbasis finden, um zum richtigen Zeitpunkt den 
PWM Wert zu ändern. Ich hab das mal mit einem zweiten Timer gemacht, 
aber es geht bestimmt auch eleganter mit dem PWM Timer selbst - wenn die 
PWM Frequenz höher als die Tonfrequenz*Samplerate ist.
Außerdem sollte die PWM Frequenz sowie deutlich höher als die 
Tonfrequenz sein, um vernünftig mit einem Tiefpaß filtern zu können.

Gruß, Jan

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren