Hallo,
also, ich erklär mal kurz das Drum-Herum:
Wir wollen als Projekt für unser Studium ein intelligentes MEtronom
bauen.
Also, nicht wirklich "intelligent" aber immerhin mit einstellbarem
bpm-Wert.
Die Schaltung ist gebaut, das Metronom klickt auch schon, jedoch viel zu
ungenau. Wenn man 1 bpm einstellt, klickt es 2 mal pro Minute.
Bei 60 bpm sieht es schon fast ganz gut aus, es läuft aber trotzdem weg.
Als Programm-Code haben wir einen fertigen Metronom-Code benutzt, der
mit Ansage aber noch nicht perfekt ist, da er zu ungenau ist.
Leider haben wir nicht wirklich viel Ahnung von C und somit suchen wir
schon sehr lange nach dem Fehler. Auch ist es das erste Mal, dass wir
uns mit Mikrocontrollern beschäftigen.
Mit den Begriffen "preload", prescale und timer können wir aber grob
etwas anfangen. Wir haben an diesen Werten schon rumgeschraubt, kommen
nur nicht auf die Lösung....
Vielleicht kann da jemand ja mal rüberschauen und gucken, wo es da
hapert :)
Grüße und schonmal danke
Maik Schröder
Ich rate mal ins blaue.
Ihr habt zwar einen Quarz an der Schaltung, wisst aber nicht, dass man
im µC ein paar Fuses ändern muss, damit der auch benutzt wird.
Ulfgar Hammerschlag schrieb:> Hallo,>> also, ich erklär mal kurz das Drum-Herum:> Wir wollen als Projekt für unser Studium ein intelligentes MEtronom> bauen.
Wie, Ihr seid Studenten, baut einen Mikrocontroller auf und programmiert
ihn und hat keine Ahnung? Was studiert Ihr denn? Musik? Dann kauft euch
ein fertiges Metronom. E-Technik oder IInformatik? Dann Schämt Euch! Mir
wäre das an Eurer Stelle ja viel zu peinlich, auch noch im Internet
nachzufragen. Habt Ihr keine Komillitonen? Setzt sich heute keiner mehr
auf seine 4 Buchstaben und lernt? Oder muß heutzutage alles mundfertig
in Häppchen aufbereitet werden, damit das der Herr Student auch
versteht? Also echt...
@ Nico Sch.:
Wir benutzten einen 16 MHz Quarz und er ist mit jeweils 22 pF an GND und
am Mikrocontroller.
Ich hänge mal einen Schaltplan an.
@ Karl heinz Buchegger:
Die Fusebits sind schon auf externer Takt umgestellt. Auch im
Programmcode haben wir 16MHz angegeben :)
Irgendwie sind glaube ich die Timer dafür verantwortlich, ich habe nur
keine Idee, wie ich sie anders einstellen muss bzw. auf welche Werte.
Aber schon mal danke :)
@ Johann:
Entspann dich mal, ist das Forum nicht da um sich gegenseitig zu helfen?
Es ist noch kein Meister vom Himmel gefallen. Wir studieren
Medientechnik. Das ist ein Studium, was E-Technik, Tontechnik,
Elektronik, Programmieren, Informatik, Nachrichtentechnik usw. lehrt.
Aber eben alles, deswegen auch nur die Grundlagen.
Meine Kommilitonen studieren logischerweise auch Medientechnik.
Ihre Mikrocontrollerkenntnisse sind auch eher wenig ausgeprägt.
(Und: Mir wäre es zwar egal, aber wäre es nicht viel peinlicher, im Kurs
anzukündigen, man wähle das Metronom-Projekt, und dann seine
Kommilitonen zu fragen, wie es denn geht?)
Mikrocontroller programmieren sehe ich als etwas an, dass ich auch
lernen kann, ohne es extra studieren zu müssen, und das tue ich ja
gerade. Nur geht es nicht von heute auf morgen.
Musik mache ich auch, ja und ich bin mir auch bewusst, dass ich mir ein
Metronom kaufen kann. Aber ich will eins bauen ^^
Du must mir ja nicht dabei helfen, wenn du nicht willst ^^
Warum siehst du es nicht so: Wow, der Junge studiert eigentlich
Medientechnik und haut sich jetzt Mikrocontroller um die Ohren, das ist
ja toll :) ^^
Naja, vielen Dank auf jeden Fall ^^
#define PRELOAD_T0 255 //??Wofür sind die Preloads wichtig?
#define PRELOAD_T2 6
Der Timer zählt von 0 bis 255 hoch. Dann fängt er wieder bei 0 an und
löst einen Overflow-Interrupt aus. Will man jetzt aber nicht von 0 bis
255 sondern von z.B 6 bis 255 zählen, lädt man eben diesen Wert nach dem
Overflow "per Hand" in das Counterregister.
Damit kann man das Timing kontrollieren.
Allerdings ladet ihr den Timer0 mit 255 vor, was bedeutet, daß bei einer
Prescaler-Einstellung von 64, nach eben 64 Takten wieder in die
Interrupt-Routine gesprungen wird.
Wenn ich mir diese Funktion so ansehe, ist die doch arg lang. Sodaß der
Controller kaum noch was anderes macht, als sich in dieser Funktion
aufzuhalten. Und damit ist das ganze restliche Timing im Ar...
In die Timer-Routine gehört nur das Setzen eines Flag. Das wird dann im
Hauptprogramm abgefragt und dann wird die Anzeige angesteuert. Ohne
Interrupt. Dann sind die Interrupts frei für die wichtigeren Dinge.
mfg.
Hab' gerade gesehen, daß der Timer0-Prescaler auf 1024 und T2 auf 64
stehen. Ändert aber nichts am Problem, daß die Interrupt-Routinen zu
lang sind und dadurch die anderen Interupts zu lange blockieren.
Das Multiplexing könnt ihr aus dem Timer komplett rausschmeissen und im
Hauptprogramm laufen lassen. Den LEDs ist es völlig egal wie hoch die
Frequenz ist.
Und dann bringt erstmal das richtige Ticken zum laufen und nichts
anderes.
mfg.
OK, super danke :)
UNd woran erkenne ich, welche ISRs welchen Overflows zugeordnet sind?
Wenn der Preload-Wert für Timer0, welcher ein 8-Bit timer ist, auf 255
gesetzt, macht er ja jeden Schritt ein Overflow.
Zum Prescale-Wert:
Der Wert skaliert doch eigentlich die CPU-Frequenz runter, oder?
Das heisst, nehmen wir an, ich habe 16MHz und einen Pre-Scaler für den
TImer 1 von 256 habe, müsste der Timer 1 ja eine Frequenz von 62500
haben, oder?
Also mit der Frequenz 62500 Hz vom Wert 0 bis zum Wert 65535 zählen,
richtig?
Nur irgendwie finde ich den Timer 1 bei uns in der Funktion garnicht.
Grüße
Maik
Hallo Maik,
nur kurz am Rande: mit eurem Schaltplan ist etwas faul. Reset ist fest
auf Masse verdrahtet.
Ist wohl nur ein Zeichenfehler, nicht, dass ihr das so routet ;-)
Liebe Grüße
Ralph
Ulfgar Hammerschlag schrieb:> @ Johann:>> Entspann dich mal, ist das Forum nicht da um sich gegenseitig zu helfen?> Es ist noch kein Meister vom Himmel gefallen. Wir studieren> Medientechnik. Das ist ein Studium, was E-Technik, Tontechnik,> Elektronik, Programmieren, Informatik, Nachrichtentechnik usw. lehrt.
Entspannt habe ich mich mittlerweile. Aber im Ernst, das Argument von
wegen es wäre peinlich, die Komillitonen zu fragen, das kann ich nicht
nachvollziehen. Und meinen Programcode zu posten, um andere Leute den
Fehler suchen zu lassen, auf diese Idee käme ich auch nicht. Eher würde
ich mal die technischen Daten des verwendeten Controllers lesen und
versuchen zu verstehen. Dabei lernt man methodisches Vorgehen - für
einen Studenten nicht ganz unwichtig, oder?
Sicher ist das Forum da, sich gegenseitig zu helfen. Aber es sollte auch
nicht dazu mißbraucht werden, nur noch andere für sich denken zu lassen.
Johann schrieb:> Und meinen Programcode zu posten, um andere Leute den Fehler suchen zu lassen,
Oft sieht man den Fehler vor lauter Bugs nicht mehr. Da ist es schon mal
hilfreich:
1. eine Nacht drüber zu schlafen
2. jemand anderes draufschauen zu lassen
Ulfgar Hammerschlag schrieb:> UNd woran erkenne ich, welche ISRs welchen Overflows zugeordnet sind?
An dem Parameter, mit dem die Funktion aufgerufen wird.
ISR(TIMER2_OVF_vect) Das ist ISR für Timer2 overflow
Ulfgar Hammerschlag schrieb:> Also mit der Frequenz 62500 Hz vom Wert 0 bis zum Wert 65535 zählen,>> richtig?
Richtig.
Ulfgar Hammerschlag schrieb:> Nur irgendwie finde ich den Timer 1 bei uns in der Funktion garnicht.
Der Timer1 ist als Compare Timer initialisiert. Wenn der entsprechende
Wert erreicht ist, toggled ein Port(OC1A). Das ist das Metronom.
Räumt euer Programm vernünftig auf.
Alle Initialisierungen gehören zusammenhängend und vernünftig
kommentiert in eine Init-Funktion.
Jede Funktion sollte zumindest soweit kommentiert werden, daß man weiss,
was diese macht. Auch wenn tick_on oder tick_off eigentlich
selbsterklärend ist. Aber ihr steigt da ja schon jetzt nicht mehr durch.
Und dann bringt ihr das Teil Schritt für Schritt zum Laufen.
Als erstes die Timer1-Funktion mit festen Parametern.
Die Eingabe und Anzeige kann bis zum Schluß warten.
Jede Funktion muß einzeln getestet werden!
Alles auf einmal zu programmieren, hat noch nie funktioniert.
mfg.
@ Thomsas Eckmann:
OK, super, danke :) damit können wir was anfangen.
Ich denke, bis nächste Woche Freitag kriegen wir zwar kein brauchbares
Resultat mehr, aber die Informationen sind trotzdem sehr hilfreich :)
Dann können wir das doch noch hinkriegen.
@ Johann:
Im Gegensatz dazu, hier nachzufragen, ist es mir eher peinlicher, meine
Kommilitonen zu fragen, denn da habe ich ja gerade angekündigt, ein
Metronom zu bauen. Aber das würde auch gar nichts bringen, weil sich
noch niemand mit Mikrocontrollern beschäftigt hat.
UNd die Professoren haben wir auch schon gefragt ^^
Bei diesem Projekt war es vom Anfang an geplant, keinen eigenen
Programmtext zu suchen, weil es viel zu lange dauern würde, jetzt C zu
lernen. Wir können ja schlecht mit "Hello World" anfangen, weil gar
nicht so viel Zeit bleibt. Genauso aufwändig ist es, sich von Anfang an
ins das Thema Mikrocontroller reinzufuchsen.
Unsere Professorin weiß auch darüber Bescheid, dass wir uns Hilfe holen.
UNd das ist doch auch ok, oder nicht?
Und was ist daran falsch, andere Leute bei der Fehlersuche mit
einzubinden, wenn diese den Fehler vielleicht mit Leichtigkeit erkennen
und uns somit einen großen Schritt weiterbringen. Die Lösung von
Problemen lehrt doch auch am meisten.
Außerdem sehe ich das Projekt eher als Exkurs in weiterführende Themen
an, und siehe da, ich finde Mikrocontroller ziemlich interessant und ich
denke, es wird schon bald das ein oder andere Lehrbuch über das Thema in
meinen Besitz übergehen.
Daher machen wir solche Projekte.
Ich denke, wir werden uns nächstes Semester auch eingehender mit C
beschäftigen.
Hi,
ich hab gerade erst gestern mein Metronom fertig gebaut. Ich hab nen
ATmega8 mit 8 MHz Quarz verbaut. Als kleines Gimmick hat mein Metronom
einen Geschwindigkeitstrainer, mit dem die Geschwindigkeit innerhalb
einer bestimmten Anzahl von Takten hochgefahren, bzw. verzögert wird.
Die Tonausgabe mache ich mit Pulsweitenmodulation, die Klicks werden
ebenfalls in der Timer Overflow Routine erzeugt.
Wenn noch Interesse besteht schicke ich euch gerne Quelltext und
Schaltplan zu.
Das ganze Projekt (incl. Video) gibts auf meiner Seite:
http://philaudio.wordpress.com/phi-x/
Gruß Philipp.
Edit...: Oh sorry. Ich sehe grad, dass ich mich um ca. 1 Jahr im Datum
vertan hab.
Thomas Eckmann schrieb:> Das Multiplexing könnt ihr aus dem Timer komplett rausschmeissen und im> Hauptprogramm laufen lassen. Den LEDs ist es völlig egal wie hoch die> Frequenz ist.
Auf keinen Fall, das ist ganz großer Quatsch!
Multiplex im Hauptprogramm sieht jeder sofort und wirkt dilettantisch
(flackern bzw. ungleichmäßig helle Digits).
Es macht Dir außerdem nur unnötig Arbiet, da Du immer sämtliche
Laufzeiten im Main beachten mußt.
Multiplexing gehört immer in den Timerinterrupt!
Nur so erhält man ein konstantes Leuchtintervall und damit kein Flackern
und keine ungleiche Helligkeit.
Im Timerinterrupt ein Byte an einen Port ausgeben und den Digit-Pin
weiterschalten geht auch ratzfatz, kostet keine merkbare CPU-Zeit.
Und das Main muß keine Rücksicht nehmen, kann soviel Zeit brauchen, wie
es lustig ist.
Peter
Der Lautsprecher ist hoffentlich etwas hochohmiges, ansonsten dürfte der
etwas zu viel Strom von den Pin ziehen, was u.U. den Controller
resettet. Wenn dann der RAM Inhalt erhalten bleibt kann es so wirken
als ob alles läuft (da die alten Werte bleiben), in Wirklichkeit aber
ständig alles von neuem Anfängt.
Um sich die Rechnerei bzgl. Timer-Intervallen/Clocks zu erleichtern kann
man ein passendes Quarz nehmen dessen Frequenz 2^N ist. Wenn man z.B.
einen 10,24 MHz Quarz hat, und einen Vorteiler von 1024, dann hat die
Timer-Clock glatte 10kHz.
Grüße,
Chris