PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Glockenschlag erzeugen



izaseba
15.11.2006, 20:50
Hallo,
Da ich eine meiner AVR Uhren etwas aufwerten möchte, will ich ihr einen Glockenschlag spendieren.
Wer nah an einer Kirche wohnt kennt es mit Sicherheit, z.B.

11.15 ein Schlag
11.30 zwei Schläge
11.45 drei Schläge
12.00 vier schläge + 12 mal etwas anderer Ton + sehr viel Krach, weil 12 :-)

Jetzt lassen wir den Krach weg sonst meckert die Frau, es würde ein einfacher Glockenschlag reichen :-b

Nur wie macht man sowas :-k

Einfache Töne kann ich produzieren, das ist ja kein Problem, einfach einen Ausgang in der gewünschten Frequenz "wackeln" lassen fertig ist der Ton,
aber so ein Glockenschlag dürfte wohl nicht so einfach zu machen sein, da kommt man mit einfachem Viereck wohl nicht hin :-k

Leider hab ich von sowas keine Ahnung, vielleicht kann mir mal jemand unter die Arme greifen ?

Gruß Sebastian

stochri
15.11.2006, 20:59
Ein erster Versuch wäre das hier:

201 Hz Grundton
7 Hz Modulation
sägezahnförmige, linear abklingende Hüllkurve

und wie das klingt im Anhang:

izaseba
15.11.2006, 21:17
Hallo stochri,

danke für Deine Antwort.

Der Klang hört sich schonmal nicht schlecht an,
Frage,
Grundton,Modulation wir reden hier doch nicht von Viereck, ist das Sinus ?

Zum Thema Sinuserzeugung hab ich das hier (http://www.avr-asm-tutorial.net/avr_de/avr_dac.html)

Also R/2R-Netzwerk, es ist wohl ein Widestandsgrab, ich wüßte aber sonst nicht wie man ohne DAC einen Sinus erzeugen könnte :-k

Gruß Sebastian

stochri
15.11.2006, 21:23
Soweit ich weiss, gibt es R2R Netzwerke auch als Modul. Die sehen so aus Widerstandsarrays.

Ansonsten kann man quasi-analog-Signale via PWM erzeugen. Beim Atmega 8 oder den Attiny's geht das mit 8 Bit bei 31Khz.

Bei 31Khz Ausgabefrequenz hat man ein wenig hochfrequente Rückstände. Die kann man aber ganz gut mit einem einachen RC-Tiefpass ( sagen wir mal 3 kHz Grenzfrequenz ) dämpfen.

Manf
15.11.2006, 21:36
Vielleicht kannst Du Dir hier etwas herausschneiden:
http://www.kprkpr.de/Dresden/Geschichte/Fr/Frauenkirche.htm
http://www.kprkpr.de/Musik/Johannes.wav

izaseba
15.11.2006, 21:55
Hallo Manf,
danke für die links :-)
Ich hab mir schon ein paar wav's besorgt und in einem Bearbeitungsprogramm angeguckt...
Nur leider stehe ich da wie ein Ochse vorm Tor und verstehe nur Bahnhof...
Ich glaube, ich zerlege mir die Aufgabe in kleinere Häppchen, sonst komm ich
da nicht viel weiter...
Ich werde Morgen wenn ich dazu komme versuchen erstmal einen Sinus zu kriegen.
Ich glaube PWM ist da wirklich besser als R2R Netzwerk, schon wegen der vielen Pins, die ich da bräuchte.

Gerd Schmidt hat auf seiner Seite (der Link in meinem letztem Beitrag) eine schöne Sinustabelle gemacht, ich versuche den Timer2 im Phase Correct Mode mit den Werten zu füttern, mal schauen was dabei rauskommt...

Gruß Sebastian

SprinterSB
16.11.2006, 08:30
Warum nimmst du nicht eine richtige Glocke? Hört sich auf jeden Fall besser an als ne elektrische. Wackeln zB per (Stepper)-Motor. Ich mache es so mit nem Klangspiel an meiner Uhr. Solche Sphärenklänge macht mir keine Elektrik!

PicNick
16.11.2006, 09:28
.. nicht eine richtige Glocke..
Ob es Kirchenglocken in SMD-Bauweise gibt, bin ich jetzt nicht sicher. Die gängigen Vorbilder sind nicht für Wohnzimmer etc. gedacht.

dieta
16.11.2006, 11:30
Es gibt doch diese Türglocken. Da hämmert ein starker Zugmagnet zwischen zwei Klangblechen hin und her. Die Dinger sind auh noch nicht sehr groß.

stochri
16.11.2006, 16:54
Gerd Schmidt hat auf seiner Seite (der Link in meinem letztem Beitrag) eine schöne Sinustabelle gemacht.

Habe ich auch schon mal eine gemacht, extra klein für den Attiny:



/************************************************** ********************

int8_t sinus( uint8_t x)

Sinus Berechnung

y=127*sin(2*pi/256*x)

x:0..255
y:-127..+127

23.5.2006 stochri

************************************************** ********************/

int8_t sinwerte[17]={0, 12, 25, 37, 49, 60, 71, 81, 90, 98, 106, 112, 117, 122, 125, 126, 127 };
int8_t sinus( uint8_t x)
{
int8_t wert;
x=x>>2;

if(x>48)
{
x=64-x;
wert=-sinwerte[x];
}
else if(x>32)
{
x=x-32;
wert=-sinwerte[x];
}
else if(x>16)
{
x=32-x;
wert=sinwerte[x];
}
else
{
wert=sinwerte[x];
}
return wert;
}

izaseba
16.11.2006, 19:53
JA, eine richtige Glocke zu verwenden dürfte wohl die einfachste Variante sein, nur wie gesagt, gibt es die wohl kaum in der SMD Version :mrgreen:

Ich habe eben einen Versuch mit Timer 2 in FastPWM Mode gestartet, den ich mit Hilfe von Timer 0 mit Werten aus Stochris Tabelle füttere.

Das sieht schon mal garnicht so übel aus auf dem Oskar, leider noch total verrauscht vom PWM, liegt wohl am falschem Tiefpaß, habe heute leider keine Lust meine Bastelkiste rauszuholen um eben andere Kondensatoren auszuprobieren, das muß wohl bis Samstag warten...

Gruß Sebastian

stochri
16.11.2006, 20:42
Ganz wichtig: Dein PWM muss ohne Vorteiler laufen, Prozessortakt mindestens 8Mhz.

Dann solltest Du die kleinste Zykluszeit des PWM erreichen können, mit der du die 31Khz Ausgabefrequenz schaffst.
Hast Du schon mal mit dem Oszilloskop nachgeschaut, welche Zykluszeit Dein PWM hat ?
Noch ein Tipp: Man sollte möglichst die Ausgabe mit dem PWM-Zyklus synchronisieren, sonst gibt es auch Störungen; d..h. als Grundtakt den Überlauf des PWM-Timers verwenden und dann immer einen neuen Wert schreiben.

Gruss,
stochri

izaseba
16.11.2006, 21:06
Hallo Stochri,
Deine Tips sind wie immer Goldwert :!:

Ja, ich habe PWM ohne Vorteiler in meinem STK steckt ein 7,372 MHz Quarz drin, werde morgen mal einen anderen reinstecken.

Mit Oszilloskop hab ich mir erstmal dürftig den Verlauf nur angeguckt (ich muß erstmal meine Frau von meinem Schreibtisch mit ihrem Laptop verjagen damit man etwas Platz hat ](*,) )
Naja, wie gesagt Sinus ist es schon gewesen nur halt schön mit dem PWM Grundton moduliert, das dürfte wohl weniger das Problem sein, der Tiefpass muß halt noch richtig gemacht werden.


als Grundtakt den Überlauf des PWM-Timers verwenden und dann immer einen neuen Wert schreiben.

Aha, klingt gut, das probiere ich mal aus, damit spar ich ja den Timer 0 wobei dürfte das wohl eine ziemlich große Last erzeugen, oder (alle 256 Takte ein Interrupt)?

Gruß Sebastian

SprinterSB
16.11.2006, 22:42
Ne IRQ-Rate von 256 Ticks sollte ok sein, wenn du nicht in der ISR Krieg und Frieden übertragen willst ;-)

Konkreter Vorschlag: In der ISR zählst du die IRQs, wahrscheinlich ist nur alle x IRQs was zu tun. Falls x keine 2er-Potenz ist, komm nicht auf die Idee, in der ISR ein % (modulo) anzufangen. Vergleich einfach von Hand:

SET x := x+1
IF x >= max
THEN
SET x := 0
ENDIF
Falls Ausgabe (oder was auch immer) gemacht werden soll, setze ein Flag und die Applikation kümmert sich drum. PWM-Werte natürlich in der ISR setzen.
Die IRQ-Latenz deiner ISRs wird sich aufaddieren. Evtl. ist es angezeigt, andere IRQs (z.B UART) für Interrupts zu öffnen. Ansonsten bekommst du tatsächlich Huddel.

izaseba
16.11.2006, 22:56
wenn du nicht in der ISR Krieg und Frieden übertragen willst

Hehe, ne Du, keine Warteschleifen oder sowas...
Eigentlich nur eine Bytevariable inkrementieren, einen Wert aus einem Array holen, in OCR2 schreiben und fertig.
Klappt auch gut bis jetzt...

SprinterSB
17.11.2006, 08:43
Warum muss es eigentlich ein Sinus sein?
Nimm doch nen Cosinus! Ok, Spaß bei Seite...
Tut's ein Rechteck nicht? Da hast du gleich ein paar Obertöne drin. Ich find, Rechteck hört sich etwas sympathischer an als Sinus. Oder wird der Sinus noch durch was anderes ausgetauscht?

izaseba
17.11.2006, 16:28
Warum muss es eigentlich ein Sinus sein?

Also man hat mir gesagt:
Einen Sinus von 200 Hz mit einem Sinus von 4 Hz multiplizieren dann mit der Hüllkurve multiplizieren.

Da habe ich mir gedacht, ich erzeuge zuerst einen einfachen Sinus (das klappt auch eigentlich ziemlich gut, hört sich an wie eine Schiffssirene)
und wenn das klappt versuche ich die zu multiplizieren, und dann kümmere ich mich um die sägezahnförmige, linear abklingende Hüllkurve...

Allerdings habe ich im Moment noch keine Ahnung, wie ich es mache...



Tut's ein Rechteck nicht?

Es ist mir eigentlich egal welche Signalform zum Einsatz kommt von mir aus Dreieck, ich weiß überhaupt nicht wie ich digital solche Klänge erzeugen kann, deswegen kam hier diese Frage und man hat mir einen Vorschlag gemacht und ich versuche ihn jetzt umzusetzen...

Für andere Anregungen bin ich weiterhin sehr dankbar, Dein Vorschlag mit einer realen Glocke find ich auch nicht gerade schlecht, nur was für eine Glocke nehm ich denn da ?
Soll ich Nachbars Katze ihr Glöckchen klauen :-) und es klingelt dann auch wie ein Glöckchen...

Gruß Sebastian

stochri
17.11.2006, 16:46
Meiner Meinung nach gilt es Interrupts zu vermeiden. Hat mir sogar vor kurzem ein Kollege erzählt: Moderne Programmierer verwenden möglichst keine Interrupts.

Für das Programm ist es auch gar nicht notwendig: In einer Schleife wird die Tonberechnung durchgeführt und dann gewartet, bis der PWM Timer abgelaufen ist und der neue Wert geschrieben. Nach diesem Prinzip funktioniert übrigens auch das ASURO-Rätselprogramm.


Für andere Anregungen bin ich weiterhin sehr dankbar, Dein Vorschlag mit einer realen Glocke find ich auch nicht gerade schlecht, nur was für eine Glocke nehm ich denn da ?

Achwas, nimm einen 500 Watt Subwoofer und bastle einen Attiny zur Tonsignalerzeugung dran O:)
Was mir grad einfällt: Eigentlich müsste das PWM-Signal ja ideal für den Input eines Class-D Verstärkers geeignet sein.

vajk
17.11.2006, 19:47
@izaseba frag doch mal Dr.ebay nach Glöckchen :-)
Die Steigerung wären dann Trommeln oder Klangschalen ... letztere machen ganz schön was her :-)

vajk
17.11.2006, 19:54
... Moderne Programmierer verwenden möglichst keine Interrupts....

Könntest Du bitte diese globale Aussage begründen und vor allem den Hintergrund an Hand von Beispielen erklären.

Vorausgesetzt wird werkeln mit max. 16 MHz und haben ein komplexes Progrämmchen, dann gehts ohne Ints m.E. nicht. Allerdings blockiere ich bei der Abarbeitungeines Ints nicht immer andere mögliche Ints ...

izaseba
17.11.2006, 20:12
Die Steigerung wären dann Trommeln oder Klangschalen

@vajk,
Danke für den Tip, glaub mir, wenn ich irgendwann mal vielleicht mit der Glocke fertig bin, denke ich über Buschtrommeln nach :-)

Was die Sache mit den Interrupts angeht, naja, ich glaube, ich habe micht mit den Stochri schon bei dem Robotertreff unterhalten, natürlich hatte jeder seine Meinung :-)

Klar kann man in diesem Fall schön den Timer pollen aber ohne Interrupts würde ich kein Programm hinkriegen,
Vielleicht ist das ein Tip für Bascomer :-&
Bis der µC alle Register gepusht und wieder gepopt hat, wäre der nächste Interrupt schon an der Reihe :-s

Gruß Sebastian

stochri
18.11.2006, 07:29
Tjaja, ich weiß, die Interrupts sind ein harter Streitpunkt. Natürlich kann man nicht bei jedem Programm auf Interrupts verzichten, aber es geht doch in ziemlich vielen Fällen und wenn man sich mal an das Prinzip gewöhnt hat, dann ist es auch gar nicht so schlecht.

Beim Tonereugungsprogramm sieht das folgendermaßen aus

while(1)
{

Ausgabewert ausrechnen ( z.B. sin(freq1)*sin(freq2)*Hüllkurve );
warte auf PWM-timer;
schreibe Wert an timer;

}

Es gilt: die Berechungsroutine darf nur soviel Zeit verbrauchen, dass sie in die Zykluszeit der Ausgabe passt. Das ist übrigens das wesentliche Merkmal eines Echtzeitsystems.

Das Warten auf den Timer benötigt hier sogar weniger Zeit als das Anspringen einer Interruptroutine und es bleiben damit sogar ein paar mehr Zyklen für die Rechenroutine.

Gruss,
stochri

vajk
18.11.2006, 09:32
Nun, Dein Beispiel zeigt eine Verwendung, in der das möglich ist .. aber wie löst Du dasd Problem ohne Timer, wenn Du eine Zeitbasis brauchst? Durch eine externe Taktquelle?

SprinterSB
18.11.2006, 13:55
Naaaja.

Moderne Programmierer fassen oft deshalb keine Interrupts an, weil
-- sie ein Echtzeit-OS verwenden, und sich nicht in Niederungen wie Zeitbasis, USB, MLI, DMA oder CAN begeben müssem
-- sie es nicht gepeilt bekommen und nicht wirklich wissen, was sie tun, mal eben globel IRQs sperren, weil die nerven und damit das System aushebeln, in einer ISR ne komplette FFT-Berechnung machen wollen, etc.
-- So viele Silicon-Bugs in den µC sind, daß die einzige Funktion, die tut was sie soll, ein NOP ist. Und daher möglichst wenig der HW angefasst wird.

@izaseba

Um Schwebungen zu machen lässt du einfach 2 Pointer durch das sin-Array laufen. Einer langsam, der andere schneller (hast du schon). Die Werte werden dann einfach multipliziert. Da die Werte im Array (bzw die daraus erhaltenen sin-Werte) mit 128 skaliert sind, musst du nur 2 Werte multiplizieren (als signed 16 bit) und dann 7 Bits nach rechts shiften (oder 8 nach rechts und 1 nach links). Dann hat das Produkt die gleiche Skalierung.

Mit der Hüllkurve ähnlich. Nur daß die Hüllkurve wohl direkt berechnet wird.

stochri
18.11.2006, 15:02
Nun, Dein Beispiel zeigt eine Verwendung, in der das möglich ist .. aber wie löst Du dasd Problem ohne Timer, wenn Du eine Zeitbasis brauchst? Durch eine externe Taktquelle?

Das gezeigte Beispiel hat eine Zeitbasis. Der Überlauf des PWM-Timers gibt eine sehr exakte Abtastrate vor.
Der Gag an dem Programm ist, dass wenn die Berechnungen durchgeführt sind, die restliche Zeit einfach gewartet wird bis der Timer übergelaufen ist. Das ganze eben ohne Interrupts.

izaseba
18.11.2006, 18:42
Hallo,
@Sprinter,
so in etwa habe ich es Gestern versucht, allerdings am PC die Werte für mein Array berechnet und dann direkt auf dem AVR übernommen, irgendwie kam dabei Käse raus, das werde ich dann wohl oder übel am AVR "on the Fly"berechnen, mal schauen.
Es ist lustig so was zu versuchen.
Ich hab mir scilab besorgt um mir "ein Bild" von so einer Multiplikation zu machen, sieht echt lustig aus...
Ich werde mal weiterberichten.
Anbei ein Bild von 200 Hz und 4 Hz Multiplikation

Gruß Sebastian

stochri
18.11.2006, 19:56
Hallo Sebastian,

frisch aus der Glockenton Entwicklungsabteilung: Mein neuester Glockenton !

Dank dem Post von Sprinter ist mir aufgefallen, dass man ja gewaltig Rechenzeit durch das weglassen der Multiplikation spart. Anstatt Ton(250Hz)*Ton(6Hz) kann man ja auch (Ton(250Hz)+Ton(256Hz))/2 verwenden. So erreicht man die Schwebungsfrequenz von 6 Hz.

Beim obigen Ton habe ich allerdings 3 Frequenzen verwendet: (Ton(250Hz)/4+Ton(252Hz)/4+Ton(256Hz)/4)*Hüllkurve

Klingt ganz interessant, oder?

Übrigens: Diesmal mit einem Attiny13 produziert !

Mit Scilab kannst Du Deine Kurve auch gleich anhören:

Beispiel:

t=1:10000;
y=sin(t/10);
sound(y)

izaseba
18.11.2006, 20:10
Stochri, Du bist der Größte!
Super Sache, prost ! Hört sich an als ob Du zwischendurch ein Bierchen aufmachst :-)

Ich muß mich jetzt auch damit weiter auseinandersetzen :roll: ein Tiny ist natürlich perfekt mit zwei Leitungen könnte man die Anzahl der Schläge reinschieben und gut ist.

Danke erstmal

Gruß Sebastian

izaseba
18.11.2006, 22:23
Hallo,

Ich glaube, ich bin doch zu blöd dafür ](*,)

Habe seit Gestern folgendes Programm stehen ( Heute mal aus Spaß ohne ISR) womit ich mir einen schönen Sinus mit knapp 900Hz erzeuge...


#include<avr/io.h>




int8_t sinwerte[]= {64,76,88,99,109,117,123,126,
128,126,123,117,109,99,88,76,
64,51,39,28,19,11,5,1,
0,1,5,11,19,28,39,51
};


int main(void) {
uint8_t wert,x=0;

TCCR2 = (1<<WGM20)|(1<<COM21)|(1<<CS20);
OCR2 = 0;
/*Timer 0 im Overflowinterrupt*/
// TIMSK = (1<<TOIE2);
DDRB = (1<<PB3);
PORTB = 0;

while (1) {
wert = sinwerte[x];
while(!(TIFR & 1<<TOV2));
OCR2 = wert;
TIFR |=(1<<TOV2);
x++;
if (x == 33)
x = 0;
}
return 0;
}


Nur wie stelle ich das mit der Multiplikation an :-k
Soll man z.B wie der Sprinter schon sagte 2 Zeiger durch die Tabelle durcheiern lassen und bei jedem Überlauf von Timer 2 dann auslesen multiplizieren, schieben und OCR2 damit füttern ?
dazu bräuchte ich wieder einen weiteren Takt, der dann die Zeiger bewegt oder besser gesagt 2 verschiede Takte, weil sie ja unterschiedlich laufen müssen.
Das heißt dann wieder den gemeinsamen Nenner suchen, 2. Timer damit laufen lassen usw. usw.
Ist das so gedacht ?
Ich versuche es jetzt so, vielleicht bin ich wieder auf dem Holzweg...
Gruß Sebastian

EDIT:
Naja, ich glabe ich brauche doch keinen 2. Takt, ich könnte den Timer 2 benutzen ....

SprinterSB
19.11.2006, 00:00
Ey Sebastian, du bekommst gleich nen Watschen von mir! ;-)


while (!(TIFR & (1<<TOV2))); // ()
TIFR = 1<<TOV2; // sonst löschen wir alles (TOV2 ist eh gesetzt)

Wie schon gesagt kann die Multiplikation zweier Sinüsse durch Summe ersetzt werden (andere Frequenzen und Amplituden). Das Zauberwort ist "Additionstheorem".

Zeit bei der Multiplikation spart man eigentlich nur dann, wenn der AVR keine MUL-Befehle hat. Zwei Sinüsse zu addieren, deren Frequenzen dicht beisammen sind, dürfte schwerer sein, als zu Multiplizieren, wenn sich die Frequqnzen teilen:

{
uint8_t x1 = 0;
uint8_t x2 = 0;
uint8_t f = 0;
const uint8_t fak = 7; // Teilungsverhältnis der Frequenzen.

uint8_t wert1, wert2 = 0, wert;

while (1)
{
wert1 = sinwerte[x1++];
if (0 == f)
wert2 = sinwerte[x2++];

if (++f == fak)
f = 0;

wert = (uint16_t) (wert1 * wert2) >> 7;

while (!(TIFR & (1 << TOV2)));
OCR2 = wert;
TIFR |= (1<<TOV2);

if (x1 == sizeof(sinwerte) / sizeof(sinwerte[0]))
x1 = 0;

if (x2 == sizeof(sinwerte) / sizeof(sinwerte[0]))
x2 = 0;
}
}

izaseba
19.11.2006, 00:25
Danke Sprinter, schön, daß Du mir antwortest...


Ey Sebastian, du bekommst gleich nen Watschen von mir!

:cry:
Zugegeben, mir gefällt es auch nicht...
oder verstehe ich das Dattenblatt falsch ?


The TOV2 bit is set (one) when an overflow occurs in Timer/Counter2.TOV2
is cleared by hardware when executing the corresponding interrupt Handling Vector.Alternatively,TOV2 is cleared by writing a logic one to the flag


Naja, dann dachte ich mir, da ich keinen Interrupt habe, nutze ich halt dieses Alternatively...

Ist das jetzt falsch ?

oder meinst Du Dein Zitat


TIFR = 1<<TOV2; // sonst löschen wir alles (TOV2 ist eh gesetzt)


:cry: Hau mich nicht [-o< ich habe es doch verODERt ...

Am sonsten vielen Dank, ich habe mir das Anfangs so gedacht mit 200/4 dann halt Verhältnis 1:50, ich glaub Heut(Gestern) ist(war) nicht mein Tag...

Gruß Sebastian

SprinterSB
19.11.2006, 00:50
Für dieses Beispiel ist es egal, wie du an TIFR ran gehst.
Sobald du in TIFR an eine Stelle eine 1 schreibst, wird dieses Bit gelöscht. Mit einem |= wirst du also *alle* 1-Bits löschen! Wenn nur Timer2-Overflow ne Rolle spielt, ist es egal. Aber wenn du mehrere Timer oder andere Timer-Ereignisse hast, suchst du dir womöglich den Wolf, warum (scheinbar) Timer-Ereignisse verloren gehen...

TIFR kannst du ebenso löschen mit

TIFR = TIFR; ...

Auf TIFR sollte man daher nie mit |= zugreifen, da das alles löscht. (Für INT-Flags gilt ähnliches)

Der Code in dem while schein ok.

Ich war halt nicht sicher, wie die Priorität der Operatoren in TIFR & 1<<TOV2 ist :oops:, also ob das ein
(TIFR & 1)<<TOV2 ist oder ein TIFR & (1<<TOV2). Es ist zum Glück letzteres. Damit können die Klammern tatsächlich entfallen.

Die 7 für fak hab ich einfach so gewählt, hätte auch 42 sein können. Mal rumspielen, was besser tönt. Die ">> 7" muss natürlich bleiben und hat nix damit zu tun.

izaseba
19.11.2006, 01:26
Hallo,

Das ist wirklich interessant, mit den Interruptsflags, ich hab mir bis jetzt keine Gedanken darüber gemacht, weil ich sonst immer ISR benutze und da werden sie ja automatisch gelöscht.

Soll ich das jetzt als Fallstricke eingliedern ?
Bei Assembler hätte ich sbi benutzt, hätte es die gleichen Auswirkungen gehabt ?
TIFR = TIFR leuchtet ein ich schreibe eine eins in TOV2 und belasse den Rest beim altem.
Ich habe es gerade ausprobiert
TIFR = TIFR; klappt, wenn man nichts macht bleibt das Programm hängen.

Man lernt ja nie aus...



Damit können die Klammern tatsächlich entfallen.


Wommt ich sagen muß mit Klammern wäre es eleganter gewesen.
Ich meine in K&R gelesen zu haben daß << >> die höchste Priorität bei den Bitoperationen haben :-k

Am sonsten klappt es jetzt ganz gut jetzt muß ich noch die Hüllkurve dazubasteln, das dürfte wohl das kleinste Problem sein (hoffe ich).

Danke nochmals für Deine Hilfe

Gruß Sebastian

SprinterSB
19.11.2006, 09:21
Some of the Status Flags are cleared by writing a logical one to them. Note that the CBI and SBI instructions will operate on all bits in the I/O Register, writing a one back into any flag read as set, thus clearing the flag. The CBI and SBI instructions work with registers 0x00 to 0x1F only.

CBI und SBI sind read-modify-write Befehle. D.h. sie Lesen das SFR, fummeln das Bit rein und schreiben es wieder. SBI sollte also ebenfalls *alle* Flags löschen. Getestet hab ich es allerding nicht. Ich verwende TIFR/GIFR = Und muss mir keine Gedanken drum machen. Auch nicht darum, ab die auf einem anderen Derivat bitadressierbar sind oder nicht.

AVR ist eine 8-Bit Architektur mit 8-Bit Anbindung der Peripherie (SFRs). Ein SBI/CBI muss sich dieses 8-Bit Bus' bedienen. Es gibt keinen 1-Bit-Bus zum bitadressierbaren SFR-Bereich.

izaseba
19.11.2006, 12:01
So, ich habe jetzt etwas weiter gespielt, im Anhang mein Ergebnis.
Noch weit von einer Glocke entfernt, aber wie heißt es so schön, man sollte immer kleine Brötchen backen :-)

stochri
19.11.2006, 17:10
Hallo Sebastian,
Gratulation zum ersten "Glockenton" ! Der klingt ja doch auch schön sauber, was hast Du denn für einen Tiefpass dahinter ?

Der Lapsus mit TOV und TIFR ist mir doch glatt auch unterlaufen, aber es hat ja trotzdem funktioniert. Hier mein Orginalcodeausschnitt für den Attiny13:

while (!(TIFR0 & (1 << TOV0)));
TIFR0 = (1 << TOV0); // clear PWM overflow flag
OCR0A=k;

Wobei es mir scheint als wenn TIFR=TIFR; auch keine wirklich saubere Lösung ist, wie mir scheine will: Ist es nicht so, dass wenn andere Flags im TIFR gesetzt sind, diese beim Selbskopieren auch gelöscht werden?

Gruss,
stochri

stochri
19.11.2006, 17:18
Und hier noch der neueste Ton aus den Stochri-Glockenton-Forschungslabors.

Diesmal mit Matlab erzeugt, nachdem ich einige Glockentonpapers im Internet überflogen habe. Es ist wirklich unglaublich, was da an Literatur existiert.

Ob ich den Ton in einen Attiny13 reinkriege, weiss ich noch nicht, aber mit einem 16Mhz oder 20 Mhr getakteten Atmega8 müsste es eigentlich gehen.

izaseba
19.11.2006, 17:58
Hallo Stochri,

schön, daß Du Dir auch Gedanken um die Glocke machst :-)

Ter Ton ist schon sehr gut (auf jedem Fall eine Glocke), die errinert aber irgendwie an eine kleine Uhr und nicht eine 2m große Glocke...

Die Aufgabe ist ( zumindest für micht ) ziemlich schwer...
Vielleicht kannst Du mir bitte kurz erklären, wie Du das mit der Addition programmtechnisch machst... keinen Code, nur kurz den Verlauf erklären, bitte :roll:

Ich möchte es schon in einen Tiny reinkriegen, nur leider haben die keinen mul; bin schon am rumprobieren wie ich die Multiplikation ohne mul hinkriege aber egal wie man es nicht dreht und wendet gehen da ziemlich viele Takte drauf.



Wobei es mir scheint als wenn TIFR=TIFR; auch keine wirklich saubere Lösung ist, wie mir scheine will: Ist es nicht so, dass wenn andere Flags im TIFR gesetzt sind, diese beim Selbskopieren auch gelöscht werden?

Das ist auch wieder wahr...
Es kommt zwar nicht oft vor, daß mehr als 1 Flag gesetzt ist, aber ausschliessen kann (darf) man das nicht.

Fazit:
Benutzen wir brav die Interrupts, dann braucht man sich keine Sorgen um sowas zu machen :-)

EDIT:

Hab noch den Tiefpass vergessen :oops:

10 k + 2µ hat mir am besten gefallen

stochri
19.11.2006, 18:29
der Ton ist schon sehr gut (auf jedem Fall eine Glocke), die errinert aber irgendwie an eine kleine Uhr und nicht eine 2m große Glocke...

Du meinst aber keine Armbanduhr oder? Für mich klingt die Glocke am ehesten wie aus einer Standuhr, oder so ähnlich. Obwohl ich meine, dass manche kleinen Kirchenglocken auch so klingen.

Übrigens interessant: Heute ist ja Sonntag und da hört man ja die Kirchenglocken. Seit ich mich ein wenig mit dem Thema beschäftige, achte ich auf deren Klang und überlege mir, wie man den wohl nachbasteln könnte.



Vielleicht kannst Du mir bitte kurz erklären, wie Du das mit der Addition programmtechnisch machst... keinen Code, nur kurz den Verlauf erklären, bitte

Eine Addition?? Ich addire einfach 2 16bit Integer ( 16 Bit wegen dem Überlauf ). Danach um 1 rechts schiften ( /2)

Die Multiplikation für die Hüllkurve kann ich auch nicht vermeinden. Die Rechenzeit reicht aber.

izaseba
19.11.2006, 18:52
Du meinst aber keine Armbanduhr oder?

Versteh mich nicht falsch, es ist ein sehr guter Glockenton, aber eben noch etwas zu hoch meine ich :-)

Wobei in der Kirche gibt es auch unterschiedliche Glocken, Totenglocke klingt tiefer als die Mittagsglocke, bei uns im Dorf gibt es insgesammt 4 Glocken im Turm, weiß was ich wozu.
Ich war schon öfter da oben und meine mich zu errinern daß der viertelstunden Stössel gegen die Mittagsglocke haut, es ist aber egal.



Eine Addition??


Naja ich meine eher die Beschaffung der Werte...

Ich hab meine Glocke etwa so gemacht, wie im Beispiel von Sprinter.

Nur halt verhältns von 1:35 glaube ich.

Nur wenn die Frequenzen so nah aneinander liegen (250Hz:256Hz) geht es halt nicht so einfach, darum ging es mir...

Gruß Sebastian

vajk
19.11.2006, 19:23
Hallo ihr zwei, der Mathlab-Ton klingt echt am Besten .. gefolgt von "Track1" - klingt auch fast realistisch ... :-) Weiter So

Das erinnert mich an meine Wohnzimmeruhr (mit binäre Zeitanzeige, im Kreis angeordnet zur Verwirrung), die hab ich mal mit einem 8051 vor locker 14 Jahren gebaut und wollte damals auch vertonen, aber war es dann doch gelassen ...
... also wenn ich das jetzt höre, gefällt mir das .. vielleicht baue ich sie nächstes Jahr mal neu auf ... schönes, großes Holzgehäuse .. mit 'nem dicken Tieftöner käm das bestimmt gut :-) ...
... wäre auch 'ne Idee via easyradio-Modul das Teil auich für andere Anwendungen zu nutzen ...

Also weiter so, laßt's anschlagen

izaseba
19.11.2006, 20:06
Hallo Vajk,

danke für die Rosen, schön daß wir Dein Interesse erweckt haben :-)
Ja, das letzte Modell von Stochri ist echt der Hammer.

Vielleicht ist es mal so perfekt, daß Du es für Deine Uhr nutzen kannst :-)

Gruß Sebastian

stochri
19.11.2006, 20:22
Nur halt verhältns von 1:35 glaube ich.

Nur wenn die Frequenzen so nah aneinander liegen (250Hz:256Hz) geht es halt nicht so einfach, darum ging es mir...

Ja, an dieser Stelle kommt der entscheidende Trick !

Die Anmerkung von Sprinter, einfach einen Pointer durch das Sin-Array laufen zu lassen ist etwas unpräzisse.
Ein besseres Bild wäre der Begriff "Phase". Man muss sozusagen Phasenzähler einführen.

Also ungefähr so

delta_t1=0.0001;
t1_phase=t1_phase_alt+delta_t1
ton1=sin(t1_phase);

Der Trick ist, unterschiedliche delta_t's für die gewünschten Frequenzen zu verwenden ( Fraktionalzahlen )

Gruss,
stochri

vajk
19.11.2006, 21:03
... ergänzend wollte ich noch, daß die erste variante (längere nachlaufzeit) dem zweiten, etwas zu hohen ton "gong" (nicht mathlab) gut tun würde ...

izaseba
19.11.2006, 21:10
Danke Stochri, das Prinzip verstehe ich, nur mit der Umsetzung klappt es halt noch nicht, da muß ich noch was üben.

@vajk,
welchen Ton meinst Du eigentlich ?

Gruß Sebastian

vajk
19.11.2006, 21:31
grrrr: die dauer/nachklang von "Glocke4.mp3.zip" mit dem Gong von "01 - Track 1.zip" kombiniert, und das ganze etwas tiefer .. oder eben so wie "Glocke_matlab6.mp3.zip" ... alles klar, Herr Ober?

stochri
19.11.2006, 21:59
In "Glocke_matlab6.mp3.zip" besteht aus 6 Grundschwingunen mit 6 Hüllkurven. Das ist der Grund, warum der Ton auch sehr viel realitätsnäher als die anderen Glockentöne klingt.

Die Berechnungen einen Atmega zu stopfen, wird eventuell doch schwierig ......

vajk
19.11.2006, 22:31
.. und wie wäre es, das in eine Tabelle in den Programmcodebereich zu packen :-) (Nein, mit den Tiny hab ich noch nichts gemacht, nur mega's) ...