PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Musik abspielen Attiny (Happy birthday)



runner02
19.01.2011, 18:08
Hallo an alle,

Ich hab mir aus dem Musikgeschäft ein Tonmessgerät besorgt.

Dann habe ich lange am AVR rumgespielt, und mir tat sich folgendes Problem auf:

Die meisten Noten, die er spielt, sind immer Cs ...

Dabei habe ich mir alle Frequenzen ausgerechnet (A -> 440 Hz -> 1/440 2,2727ms; C= 523,25 Hz -> 1,911 Ms .... usw.)

Egal, was ich eingebe, es kommt immer C, außer bei 5Ms (da ists ein A)

Bei meiner Eieruhr ist mir das übrigends auch aufgefallen... Ob ich 0.8 oder 1 bzw. 1,2 Ms schrieb, es klang immer gleich!!


//----------------------------------------------------------------------
// Titel : C Grundgerüst für das myAVR-Board
//----------------------------------------------------------------------
// Funktion : ...
// Schaltung : ...
//----------------------------------------------------------------------
// Prozessor : ...
// Takt : 1 MHz
// Sprache : C
// Datum : ...
// Version : ...
// Autor : ...
//----------------------------------------------------------------------
#define F_CPU 1000000 // Taktfrequenz des myAVR-Boards
#include <avr\io.h> // AVR Register und Konstantendefinitionen
//----------------------------------------------------------------------

uint8_t playa()
{
int a=0;
DDRB=0b00001111;

for (a; a<1150; a++)
{
PORTB=PORTB|(1<<PB2); // 440 Hz
waitMs(0.66);
PORTB=PORTB&(~(1<<PB2));
waitMs(0.66);
}
}

uint8_t playg()
{
int b=0;

for (b; b<1500; b++)
{
PORTB=PORTB|(1<<PB2); //587,33 Hz
waitMs(1.28);
PORTB=PORTB&(~(1<<PB2));
waitMs(1.28);
}
}

uint8_t playd()
{
int c=0;

for (c; c<1000; c++)
{
PORTB=PORTB|(1<<PB2);
waitMs(1.59);
PORTB=PORTB&(~(1<<PB2));
waitMs(1.59);
}
}

uint8_t playe()
{
int d=0;

for (d; d<1000; d++)
{
PORTB=PORTB|(1<<PB2);
waitMs(2.52);
PORTB=PORTB&(~(1<<PB2));
waitMs(2.52);
}
}

uint8_t playh()
{
int e=0;

for (e; e<1000; e++)
{
PORTB=PORTB|(1<<PB2);
waitMs(3.14);
PORTB=PORTB&(~(1<<PB2));
waitMs(3.14);
}
}

uint8_t playj()
{
int f=0;

for (f; f<800; f++)
{
PORTB=PORTB|(1<<PB2);
waitMs(3.76);
PORTB=PORTB&(~(1<<PB2));
waitMs(3.76);
}
}

uint8_t playt()
{
int g=0;

for (g; g<800; g++)
{
PORTB=PORTB|(1<<PB2);
waitMs(4.38);
PORTB=PORTB&(~(1<<PB2));
waitMs(4.38);
}
}

uint8_t playr()
{
int h=0;

for (h; h<1000; h++)
{
PORTB=PORTB|(1<<PB2);
waitMs(5);
PORTB=PORTB&(~(1<<PB2));
waitMs(5);
}
}

main ()
{

DDRB=0b00001111;

PORTB=PORTB|(1<<PB1); // LED blinkt 1* wenn Stromversorgung // und Chip klappt
waitMs(250);

PORTB=PORTB&(~(1<<PB1));
waitMs(20);

PORTB=PORTB&(~(1<<PB2));

while (true)
{
playa();
waitMs(500);

playg();
waitMs(500);

playd();
waitMs(500);

playe();
waitMs(500);

playh();
waitMs(500);

playj();
waitMs(500);

playt();
waitMs(500);

playr();
waitMs(500);

}

}
//----------------------------------------------------------------------



(Übrigens: r und t sind natürlich keine Noten, aber ich habe dann im verzweifelten Versuch, irgend einen anderen Ton als C zu finden, einfach irgendwelche Variablen genommen... )





Und jetzt kommts:


//----------------------------------------------------------------------
// Titel : C Grundgerüst für das myAVR-Board
//----------------------------------------------------------------------
// Funktion : ...
// Schaltung : ...
//----------------------------------------------------------------------
// Prozessor : ...
// Takt : 1 MHz
// Sprache : C
// Datum : ...
// Version : ...
// Autor : ...
//----------------------------------------------------------------------
#define F_CPU 1000000 // Taktfrequenz des myAVR-Boards
#include <avr\io.h> // AVR Register und Konstantendefinitionen
//----------------------------------------------------------------------

main ()
{

DDRB=0b00001111;

PORTB=PORTB|(1<<PB1);
waitMs(250);
PORTB=PORTB&(~(1<<PB1));
waitMs(20);
PORTB=PORTB&(~(1<<PB2));
int x=1900;
int n=0;

while (true)
{
for (int i=0; i<330; i++)
{
PORTB=PORTB|(1<<PB2); // 440 Hz
waitMs(x/1000);
PORTB=PORTB&(~(1<<PB2));
waitMs(x/1000);
}
x=x+310;
int j=0;
waitMs(150);
while (j<n)
{
PORTB=PORTB|(1<<PB1);
waitMs(150);
PORTB=PORTB&(~(1<<PB1));
waitMs(150);
j++;
}
}

}
//----------------------------------------------------------------------


Dieser Code sollte irgendwelche Frequenzen erzeugen, dass ich damit zufällig auf Töne stoßen kann...

Nun kamen bei +310 folgende Töne: G,B,E,C,G,F !!!!
Dann habe ich mir die Frequenzen ausgerechnet, die der Chip errechnet hat und sie dann in mein Programm geschrieben. Und, der Chip spielt wieder nur Cs!!! :(

Obwohl es doch genau die selben Frequenzen sind, nur dass er es sich einmal selbst errechnet und einmal gebe ich ihm diesselben vor!!!

Kann jemand darin den Fehler finden??


Mfg

PicNick
19.01.2011, 18:20
Du hast z.B
waitMs(4.38 ) ;

ich glaub, dezimalzahlen wird der Bursche nicht haben wollen.
Und auch nicht als ergebnis einer Division
waitMs(x/1000

TobiKa
19.01.2011, 18:24
Richtig waitMs akzeptiert nur natürliche Zahlen. Müsstest eigentlich auch ne Warnung bekommen.
Desweiteren könntest du bei hohen Werten (bei dir 150 und 500) auch Probleme kriegen, da war mal irgendwas bei dem myAVR Wordpad das Werte über 50 (oder so) nicht hinhaun.

runner02
19.01.2011, 19:06
Richtig waitMs akzeptiert nur natürliche Zahlen. Müsstest eigentlich auch ne Warnung bekommen.

Das hatte ich ja befürchtet, aber es schien ja zu gehen.

Heißt das, dass er aus 1,3 und 0,8 Ms immer 1 Ms rundet???
Darum immer der selbe Ton!

Ich hoffte halt, dass er es in uS umrechnen würde...
Ich habe es auch mit waitus probiert, da schrieb er einen Error...


Das hieße, wenn ich auf delayUs umsteige wird es funktionieren? Das wäre ja super!!!!!!

TobiKa
19.01.2011, 19:09
Heißt das, dass er aus 1,3 und 0,8 Ms immer 1 Ms rundet???
Darum immer der selbe Ton!
Nein, höchst wahrscheinlich rundet er nicht, sondern lässt das hinterm Komma einfach wegfallen.

Statt mit diesen Unterbrechungen könntest du es auch richtig machen, also mit einem Timer!

runner02
19.01.2011, 21:52
Hey, da ist ein Fehler in der Logik:

Es hat ja schon geklappt, als er Kommazahlen selbst dazu addierte.

Also denke ich doch, dass es auch so klappen müsste???




Das mit dem Timer versuche ich später mal, aber das ist mir noch zu hoch... Ich mache das step-by-step...

runner02
20.01.2011, 15:55
//----------------------------------------------------------------------
// Titel : C Grundgerüst für das myAVR-Board
//----------------------------------------------------------------------
// Funktion : ...
// Schaltung : ...
//----------------------------------------------------------------------
// Prozessor : ...
// Takt : 1. MHz
// Sprache : C
// Datum : ...
// Version : ...
// Autor : ...
//----------------------------------------------------------------------
#define F_CPU 1000000 // Taktfrequenz des myAVR-Boards
#include <avr\io.h> // AVR Register und Konstantendefinitionen
#include <util\delay.h>
//----------------------------------------------------------------------
main () // Hauptprogramm, startet bei Power ON und Reset
{
DDRB=0b00001111;

while (true)
{
PORTB=PORTB|(1<<PB1);

for (int i=0; i<1000; i++)
{
_delay_us(5000);

}

PORTB=PORTB&(~(1<<PB1));

for (int i=0; i<1000; i++)
{
_delay_us(5000);

}
}
}
//----------------------------------------------------------------------




Habe es jetzt mit delay us versucht.

Aber bie dem Programm gab es einen Error, er schrieb "writing 4076 Bytes in flash"

Der Attiny verfügt aber nur über 1 kB!!!!

Ist delay so Speicherplatz - aufwendig???

TobiKa
20.01.2011, 16:00
Aber bie dem Programm gab es einen Error, er schrieb "writing 4076 Bytes in flash"

Der Attiny verfügt aber nur über 1 kB!!!!
4076 sind vier mal soviel wie 1kB!
Du könntest die Optimierung einschalten, aber dann optimiert er dir wahrscheinlich auch dein delay weg.

Trau dich ruhig an Timer ran, ist nicht schwierig.

runner02
21.01.2011, 10:27
4076 sind vier mal soviel wie 1kB!




Ich weiß, darum kann ich mir ja nicht vorstellen, dass das so ein riesen Programmcode wäre!!


Trau dich ruhig an Timer ran, ist nicht schwierig.

danke, werd ich versuchen
Her gehts weiter :)
https://www.roboternetz.de/phpBB2/viewtopic.php?p=535079#535079