Hallo, also ich will sowas wie eine "Eieruhr" bauen mit einem Tiny13 und einem Transistor der dann durchschalten soll wenn der Wert des Potis erreicht ist. Soweit ich das jetzt verstanden habe geht der Poti von 0 bis 1024 nur wie rechne ich das nun auf z.B. fünf Minuten für ein hartes Ei ? Das ich einen Timer nehmen will frage ich mich wie ich die zwei Dinge verbinden kann ? Ich habe mir das Tutorial durchgelesen kann da aber keine Verbindung herstellen. Der Timer läuft durch und ich habe eine Zeit aber wie vergleiche ich das mit dem ADC ? Gibt's da irgendwo einen Source oder Tutorial wo das funktionert ? Danke.
watnu schrieb: > Soweit ich das jetzt verstanden habe geht der Poti von 0 bis 1024 nur > wie rechne ich das nun auf z.B. fünf Minuten für ein hartes Ei ? Wenn du einen Timer hast, der beispielsweise bis 1024 in 10min läuft, dann ist bei einem Timerwert von ca. 500 eine Zeit von ca. 5min vergangen. Das Beispiel kannst du mit unterschiedlichen Skalierungen umrechnen, je nachdem, welchen Zeitbereich du haben möchtest...
watnu schrieb: > Gibt's da irgendwo einen Source oder Tutorial wo das funktionert ? Das geht mit dem Dreisatz.
W.A. schrieb: > watnu schrieb: >> Gibt's da irgendwo einen Source oder Tutorial wo das funktionert ? > > Das geht mit dem Dreisatz. Das war auch meine erste Reaktion.
Ich hab nur etwas weiter ausgeholt. Aber im Prinzip läuft es auf das gleiche hinaus. :-)
Ja ist schon klar aber wie weiß ich wann der Timer den Wert vom Poti hat ? Muß ich da direkt die Register vergleichen oder wie macht man das ? Ist mein erster Versuch und der Assambler ist auch nicht gerade einfach ...
Du darfst das auch gern in C machen. Guck dir mal an wie ein Timer funktioniert. Und welche Betriebsmodi der hat. Steht alles im Datenblatt von deinem Mikrocontroller. Mit schönen Programmen. Und dann guckst du was so ein ADC macht und welchen Wert der dir rausschmeisst wenn die Konvertierung beendet ist. Und dann überlegst du dir einen Weg, wie man das beides verwenden kann um ein Problem zu lösen. Und ja, du wirst dafür Register lesen und schreiben müssen.
>Das ich einen Timer nehmen will frage ich mich wie ich die zwei Dinge >verbinden kann ? Man nimmt einfach den ADC-Wert, rechnet den dann in einen passenden Timerwert um, füttert damit den Timer, der entsprechend takten muß. Und wenn der Timer den Wert dann bis auf 0 runtergezählt hat, löst dieser einen Interrupt aus, dessen Interrupthandler dann die Aktion ausführt. Oder du nimmst einfach die konventionelle Art mit dem NE555 ohne µC.
watnu schrieb: > Muß ich da direkt die Register vergleichen oder wie macht man das ? Du kannst einfach zählen, wie oft der Timer überläuft. Wenn du beim Start den Zähler auf die gewünschte Anzahl setzt und bei jedem Überlauf runter zählst, musst du nur gucken, wann er 0 wird.
Eine Eieruhr gibts in allen erdenklichen Formen und Farben für 5 Euro im Laden. Aber abseits dessen müsste mal das Rad erfunden werden, wenn du grad Zeit hast.
Versuch nicht, dass direkt mit dem Timer zu erledigen. Du programmierst dir einen Timer, der sagen wir all 10ms auslöst. Das macht der ständig, unabhängig von deinem eigentlichen Programm. -warten, bis Start-Taster gedrückt wird -wenn erkannt, A/D-Wandlung starten (sagen wir der liefert 500, was bei dir 5min entsprechen soll (also 300s = 30000 10ms-tics) -Wandlerergebnis mit 60 multiplizieren (=30000) -diese Variable bei jedem Timertic rückwärts zählen -Vergleich, ob schon Null -wenn ja, Piep Ansonsten: in 5min bekommst du kein hartes Ei, auch nicht, wenn die Zeit MC-gesteuert läuft :-)
Also mß ich jetzt zwei Register vom ADC mit zwei Registern vom Timer vergleichen ? Geht das in C einfacher als in Assembler ? Wenn der ADC 1024 hat und damit die fünf Minuten einstellt wie kann dann der Timer nur 1024 haben wenn er doch immer durchläuft ?
1 | #define F_CPU 1.2e6
|
2 | |
3 | #include <avr/io.h> |
4 | #include <util/delay.h> |
5 | |
6 | void wait_until_adc( void ) |
7 | {
|
8 | for( uint16_t time = 0; time < ADC; time++) // ADC free running mode |
9 | _delay_ms( 600 ); // max ~10min |
10 | }
|
W.A. schrieb: > Du kannst einfach zählen, wie oft der Timer überläuft. Klasse! Das ist die didaktisch einwandfreie Methode einem Anfänger beizubringen was er zu tun hat! Wirklich vorbildlich.
Peter D. schrieb: >
1 | > #define F_CPU 1.2e6 |
2 | >
|
3 | > #include <avr/io.h> |
4 | > #include <util/delay.h> |
5 | >
|
6 | > void wait_until_adc( void ) |
7 | > { |
8 | > for( uint16_t time = 0; time < ADC; time++) // ADC free running mode |
9 | > _delay_ms( 600 ); // max ~10min |
10 | > } |
11 | >
|
Das ist jetzt c ? Woher bekomme ich denn "time" muß ich das selber machen und woher habe ich denn da nun meinen Timer ? Und den ADC gibt's da direkt ? Total verwirrt ...
watnu schrieb: > Geht das in C einfacher als in Assembler ? "In C ist alles einfacher und schneller", sagte der C-Programmierer. "Du hast doch keine Ahnung. Assembler ist viel einfacher und schneller ist es sowieso", antwortete der Assembler-Programmierer. Such dir was aus. watnu schrieb: > Wenn der ADC 1024 hat und damit die fünf Minuten einstellt wie kann dann > der Timer nur 1024 haben wenn er doch immer durchläuft ? Stell dir vor, du hast einen Pieper, der einmal por Sekunde piept. Wieviele Piepser musst du zählen, bis 5 Minuten vergangen sind? Richtig, 300. Andersrum fängst du bei 300 an und zählst bis 0 runter. Jetzt kommt dein ADC. Du stellst einen Wert ein, z.B. 300, lässt diesen Wert, den du einmal eingelesen hast(Taster), mit Hilfe des Timers runterzählen. Jede Sekunde -1. Du kannst auch den ADC-Wert mit z.B. 100 multiplzieren und zählst dann im 10ms-Takt runter. Wurde ja schon oben so gesagt. Dem Controller ist das egal. Die 10ms-Version könnte aber einfacher zu realisieren sein. Dazu guckst du dir den CTC-Mode an und stellst den auf einen Takt von 100Hz. Das geht auf jeden Fall. In jedem Interrupt zählst du um 1 runter, bei 0 lässt du es bimmeln. Ist dein Ei nicht hart genug, stellst du am nächsten Morgen das Poti auf 360. Du malst dir also eine Skala über 270° und machst in gleichen Abständen Striche von 1 - 17 Minuten. 1020 / 60 = 17 (min.). Das reicht dann auch noch für Kochbeutelreis. Die Linearität von Poti und Timer sollte in Verbindung mit dem internen Timer ausreichen. Aus Eierkochen muss man keine exakte Wissenschaft machen.
:
Bearbeitet durch User
watnu schrieb: > Also mß ich jetzt zwei Register vom ADC mit zwei Registern vom Timer > vergleichen ? Man merkt dass du sicherlich (fast) keine Ahnung hast. So wie du schreibst glaube ich dass du erst mal wissen (lernen) musst wie man ein Poti an einen ADC anschliesst. Dann müsstest du den ADC auslesen lernen (vor allem können). Deesen ADC Wert würdest du dann - um die Sache möglichst leicht zu verstehen - in einen Wertebereich umrechnen der die Anzahl der Sekunden deiner gewunschten Wartezeit wiederspiegelt. Auf der Timer Seite würdest du ein Zeitintervall programmieren das dir eine Schrittweite in Sekunden (oder auch zehntel, hunderstel) vorgibt die du einfach von Null aus (auch umgekehrt) solange zählst bis du (durch Vergleich) den Zeitwert aus der ADC-Zeitkonvertierung erreicht hast. Das ales ist auch für den Anfänger sicher leichter in C zu bewerkstelligen als in Assembler.
Mitlesa schrieb: > Wirklich vorbildlich. Das war die Pieper Version mit einem Systembasistick der neben anderen Aufgaben Taktgeber für die Eieruhr spielt. Wenn man für jede Task individuell am Timer rumprökelt, werden die Timer schnell knapp und das (Anfänger)-Geschrei von "ich hab keinen Timer mehr frei" ertönt schnell.
Mitlesa schrieb: > So wie du schreibst glaube ich dass du erst mal wissen (lernen) > musst wie man ein Poti an einen ADC anschliesst. Ja. Am besten nach dem Prinzip "teile und herrsche" das Problem in mehrere Teilprobleme untergliedern und jedes davon einzeln lösen (inklusive Test, ob's auch funktioniert). Ich glaube auch, dass der TE hier schon einen zu großen Schritt macht. Erstmal ein existierendes Programm hernehmen und dann mit einzelnen Modifikationen rumspielen und testen, ob die erwartete Reaktion eintritt. Erst wenn man da schon etwas sattelfester wird, daran gehen, ein eigenes Programm zu schreiben. Mitlesa schrieb: > Das ales ist auch für den Anfänger sicher leichter in C zu > bewerkstelligen als in Assembler. Ich glaube, bei diesem Programm macht es keinen so großen Unterschied. Es kommt daher meines Erachtens mehr darauf an, welche der Sprachen er bisher besser kennt. Timmy schrieb: > Eine Eieruhr gibts in allen erdenklichen Formen und Farben für 5 Euro im > Laden. > > Aber abseits dessen müsste mal das Rad erfunden werden, wenn du grad > Zeit hast. Darf man fragen, was du mit der Einstellung verdammt nochmal in einem Bastlerforum zu suchen hast? Mitlesa schrieb: > W.A. schrieb: >> Du kannst einfach zählen, wie oft der Timer überläuft. > > Klasse! Das ist die didaktisch einwandfreie Methode einem > Anfänger beizubringen was er zu tun hat! > > Wirklich vorbildlich. Ja, fand ich auch. Es wirft ihm nicht gleich die fertige Lösung vor die Füße, sondern gibt einen Ansatz. Dazu muss er dann etwas nachdenken, denn auch wenn selber denken heute irgendwie out ist, ist es didaktisch gesehen ein sehr gutes Mittel zum Lernen.
Ich schätze der Timer zählt nicht bis 1024 sondern von 0 bis 1023 (2**10-1). In der zeitschrift Funkamateur gab es im Heft 11/01 einen Kurzzeitwecker mit dem AVR, Quellcode dort: http://www.funkamateur.de/tl_files/downloads/hefte/2001/kzt.zip. Da kannst du dir zumindest den Timer-interrupt in Assembler anschauen. MfG,
watnu schrieb: > Das ist jetzt c ? Ja. watnu schrieb: > Woher bekomme ich denn "time" time ist hier als Variable vom Typ uint16_t definiert. In C kann man sich einfach Variablen definieren und damit z.B. zählen. watnu schrieb: > und woher habe > ich denn da nun meinen Timer ? Einfach mit dem Macro _delay_ms(). Der MC hat ja sonst nichts weiter zu tun. watnu schrieb: > Und den ADC gibt's da direkt ? ADC ist in io.h definiert als 16 Bit. Der Compiler kümmert sich dann automatisch um die richtige Reihenfolge beim Zugriff auf die beiden Bytes. Die Beispielroutine ist aber nur die Wartefunktion. Du mußt natürlich noch den ADC initialisieren, die Starttaste entprellen und nach Ablauf nen Pin setzen oder nen Pieper takten. Am besten erstellst Du aber erstmal einen Programmablaufplan. Gerade Anfänger denken oft, daß sie ohne einen Plan einfach drauflos programmieren könnten und verlieren dadurch den Überblick.
Vergiss die Hardware-Timern (Register) mal, die brauchst du für diese simple Anwendung gar nicht. Was der Peter Danneger da gepostet hat, war ein unvollständiger Lösungsansatz. Du musst schon ein bisschen selbst mit arbeiten. Die Idee ist, dass du in einer Wiederholschleife Zeit abwartest. Und zwar 600ms pro Schleifendurchlauf. Das Poti liefert über den ADC Werte von 0-1023. So oft lässt du die Schleife wiederholen. Also 0 bis 1023 mal 600 Millisekunden. Ergibt ungefähr 60.0000 Millisekunden (=10 Minuten) beim Endanschlag. Vor der for-Schleife musst du noch Code einfügen, der den ADC startet und auf das Ende der Messung wartet. Hinter der for-Schleife musst du Code einfügen, der den Summer ertönen lässt. nachtrag: Upps, jetzt war der Peter schneller als ich.
Ein kleiner Tip zur Vermediung eines typischen Anfängerfehlers, der schnell zu Frust führen kann: Nachdem du den ADC-Eingangskanal eingestellt hast, mache zwei Messungen. Das erste Messergebnis ist nämlich meist unbrauchbar. Warum, steht im Datenblatt.
Hallo, auch mit dem CD4060 lässt sich das gut machen, beschaltet als RC-Osziallator und von einem höherwertigen Ausgang mit einer Diode 1n4148 den Oszi stillegen, ein einfaches Poti ermöglicht Frequenzeinstellung sicher von 1:3 bis 1:6, da aber Binärstufen verfügbar sind würde 1:2 ausreichen Gruß
Wolfgang S. schrieb: > Mag sein, aber denkst du der TE hat auch nur ein Wort von dem verstanden was du gesagt hast, wenn der nicht mal von der Programmiersprache C schonmal was gehört hat?
Mein grosses V. schrieb: > Die Linearität von Poti und Timer sollte in Verbindung mit dem internen > Timer ausreichen. Das soll natürlich 'interner Oszillator' heissen.
Stefan U. schrieb: > Nachdem du den ADC-Eingangskanal eingestellt hast, mache zwei Messungen. > Das erste Messergebnis ist nämlich meist unbrauchbar. Das betrifft nur die bandgap reference: "When the bandgap reference voltage is used as input to the ADC, it will take a certain time for the voltage to stabilize. If not stabilized, the first value read after the first conversion may be wrong."
Peter D. schrieb: > Stefan U. schrieb: >> Nachdem du den ADC-Eingangskanal eingestellt hast, mache zwei Messungen. >> Das erste Messergebnis ist nämlich meist unbrauchbar. > > Das betrifft nur die bandgap reference: > "When the bandgap reference voltage is used as input to the ADC, it will > take a certain time for the voltage to stabilize. If not stabilized, the > first value read after the first conversion may be wrong." Das betrifft zu einem gewissen Teil auch die Sample & Hold Stufe. Aber das spielt nur bei hohen Abtastraten eine Rolle.
Sascha schrieb: > Das betrifft zu einem gewissen Teil auch die Sample & Hold Stufe. Aber > das spielt nur bei hohen Abtastraten eine Rolle. er hat doch für diese Aufgabe alle Zeit der Welt um 8 16 32 ADC Messungen zu mitteln (und kann die Erste sogar verwerfen).
Also ich habe nun mal das C-Tutorial gelesen aber nicht sehr viel verstanden. Wenn ich nun wie im Beispiel int16 nehme werden zwei Register benutzt und ich muß nicht die Reihenfolge beachten ? Um nun mein ADC abzugleichen muß ich doch die Register dekrementieren wie das ja gesagt wurde. Wenn das in C einfacher geht wie mache ich das ? timer - 1 ? Und einen Poti anschließen ist kein Problem, mitte auf den ADC und dann VCC und GND auf die anderen Pins. Das mit dem Programmieren und dem Controller ist mein Problem. Die Vorschläge mit den anderen ICs sind nicht was ich lernen will. Gibt es ein einfaches Tutorial wo ich C lenen kann ? Scheint mit wirklich einfacher als Assembler vor allem weil es für alles gleich ist oder ?
watnu schrieb: > Scheint mit wirklich einfacher als Assembler vor allem weil es für alles > gleich ist oder ? Ohne das Hintergrundwissen von Assembler, kann es dir leicht passieren, dass du unbemerkt eine größere Maschinerie anschmeißt, ohne dass es dir bewußt ist. Dann sind schnell mal ein paar kB Flash weg, und du wunderst dich, warum? Oder eine Zeile Programmcode verbraucht unerwartet viel Rechenzeit ...
In C Quelltexten greift man nur selten direkt auf Register zu. Ob diene 16bit Variable in Registern oder RAM Zellen liegt und in welche Reihenfolge, braucht dich nicht zu kümmern. Du dekrementierst einfach die Variable und der Compiler setzt das für die Hardware passend um.
1 | uint16_t gemessen; |
2 | gemessen = ADC; |
3 | |
4 | gemessen = gemessen-1; |
5 | gemessen -= 1; |
6 | gemessen--; |
Die drei letzten Befehle erzeugen alle den selben Maschinencode. Interessanter ist die Zeile "gemessen=ADC". Da werden die beiden Register des ADC, also ADCL und ADCH nacheinander gelesen, und zwar in der richtigen Reihenfolge, so wie es das Datenblatt verlangt. > Um nun mein ADC abzugleichen muß ich doch die Register > dekrementieren wie das ja gesagt wurde. Hier komme ich nicht mit. Ich finde weiter oben weder das Wort "abgleichen", noch "abzugleichen", noch "dekrementieren". Worauf bezieht sich der Satz? Hast du inzwischen das Beispiel von Peter verstanden? Wenn nicht, dann übe doch erstmal die Programmierung in C auf einem PC, statt am Mikrocontroller. Für den Einstieg ist dieser Weg sicher einfacher.
DokuLeseVerweigerer schrieb: > H.Joachim S. schrieb: >> in 5min bekommst du kein hartes Ei, auch nicht, > > Auch nicht mit 20MHz Quarz? Nein. Aber grundsätzlich gilt: Je kleiner der Quarz desto härter die Eier.
Stefan U. schrieb: > Vergiss die Hardware-Timern (Register) mal, die brauchst du für diese > simple Anwendung gar nicht. Bullshit par excellance. Natürlich ist auch für diese primitive Anwendung die Verwendung eines Timers sehr nützlich. Man kann damit nämlich den µC zumindest in den Idle-Schlafmodus schicken, während er sowieso nichts anderes tut, als einfach nur das Verstreichen einer Zeit abzuwarten. Gerade bei solchen typischerweise batteriebetriebenen Anwendungen kann das einen geldwerten Vorteil generieren. Man muss nämlich einfach deutlich seltener eine neue Batterie für das Gerät kaufen... Ja, man muss dafür auf die eine oder andere liebgewordene C-Lib verzichten. D'rauf geschissen, nur stupide C-only-C'ler haben überhaupt ein Problem damit. Außerdem: Wer braucht überhaupt Libs für die primitive, wohldokumentierte und leicht überschaubare AVR8-Hardware? Die hindern einen nur daran, das Optimimum da heraus zu kitzeln. Und zwar das Optimum in jeder Beziehung. Sei es maximale Performance, minimaler Energieverbrauch, minimaler Speicherverbrauch, praktisch immer ist man mit Asm ein gutes Stück besser aufgestellt, weil dort nämlich alles gleichzeitig geht (für unterschiedliche Teile des Codes), wenn man programmieren und Datenblätter lesen kann. So einfach ist das!
> Bullshit par excellance.
Na klar, deine erste Anwendung hat selbstverständlich alle Features des
Mikrocontrollers optimal genutzt. Und dein erstes Backwerk ist sicher
eine dreistöckige Hochzeitstorte.
Meinst du nicht, dass Anfänger einfach anfangen sollten? Der der arme
Mann verstanden hat, wie die Timer funktionieren, wird es noch einige
Wochen dauern. Er kann ja nicht einmal richtig C!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.