Forum: Mikrocontroller und Digitale Elektronik Wie per ADC eine Zeit einstellen ?


von watnu (Gast)


Lesenswert?

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.

von ?!? (Gast)


Lesenswert?

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...

von W.A. (Gast)


Lesenswert?

watnu schrieb:
> Gibt's da irgendwo einen Source oder Tutorial wo das funktionert ?

Das geht mit dem Dreisatz.

von Sascha (Gast)


Lesenswert?

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.

von ?!? (Gast)


Lesenswert?

Ich hab nur etwas weiter ausgeholt. Aber im Prinzip läuft es auf das 
gleiche hinaus. :-)

von watnu (Gast)


Lesenswert?

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 
...

von Sascha (Gast)


Lesenswert?

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.

von Sascha (Gast)


Lesenswert?

*Diagrammen

von Jens G. (jensig)


Lesenswert?

>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.

von W.A. (Gast)


Lesenswert?

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.

von Timmy (Gast)


Lesenswert?

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.

von H.Joachim S. (crazyhorse)


Lesenswert?

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 :-)

von watnu (Gast)


Lesenswert?

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 ?

von DokuLeseVerweigerer (Gast)


Lesenswert?

H.Joachim S. schrieb:
> in 5min bekommst du kein hartes Ei, auch nicht,

Auch nicht mit 20MHz Quarz?

von Peter D. (peda)


Lesenswert?

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
}

von Mitlesa (Gast)


Lesenswert?

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.

von watnu (Gast)


Lesenswert?

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 ...

von Mein grosses V. (vorbild)


Lesenswert?

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
von Mitlesa (Gast)


Lesenswert?

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.

von W.A. (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Fpgakuechle K. (Gast)


Lesenswert?

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,

von Peter D. (peda)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von Wolfgang S. (Firma: Pensionär-Altes-Eisen) (stackpointer)


Lesenswert?

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ß

von Sascha (Gast)


Lesenswert?

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?

von Mein grosses V. (vorbild)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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."

von Sascha (Gast)


Lesenswert?

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.

von Joachim B. (jar)


Lesenswert?

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).

von watnu (Gast)


Lesenswert?

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 ?

von Wolfgang (Gast)


Lesenswert?

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 ...

von Stefan F. (Gast)


Lesenswert?

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.

von Bernd K. (prof7bit)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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!

von hubert (Gast)


Lesenswert?

c-hater schrieb:
> C-only-C'ler

Alle Achtung! Ist dir das auf'm Klo eingefallen? Sorry: Clo :-)

von Stefan F. (Gast)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.