Forum: Mikrocontroller und Digitale Elektronik 3 versch. Impulse Zählen mit Atmega8


von Nn N. (jaytharevo)


Lesenswert?

Hallo!

Also, mal zur Vorgeschichte. Bei meinem neusten Projekt gibt es einige 
unterschiedliche Impulse, welche alle die nötige Aufmerksamkeit haben 
wollen^^ :D! Zwei der Drei Impulse stehen für Leistungen (el. & th). 
Diese beiden Impulse haben jeweils ein fmax von 4kHz und 200Hz. Für den 
Impuls mit bis zu 4kHz verwende ich den ICP Eingang und für den 
langsameren Impuls den externen Interrupt 1. Diese Impulse dürfen aber 
nur während der Sekunde 5 bis 55 gemessen werden. Die Anzahl der Impulse 
steht dann für die Leistung (el: 1000Hz = 100kW; th: 10Hz = 100kW). Das 
Ergebnis soll dann in ein PWM Signal umgerechnet werden welches einen 
Servo ansteuern soll. Der Servo ist mit einem Laser verbunden welcher 
auf eine Skala leuchtet die auf der Wand aufgebracht ist. Somit kann 
jeder sehen wie viel elektrische Leistung und wie viel thermische 
Leistung gerade benötigt wird. Das ist ein Projekt in meiner alten 
Schule und soll zum denken anregen. Den Schülern soll bewusst werden wie 
hoch der Verbrauch einer solchen Einrichtung ist und eventuell doch das 
Licht ausschalten wenn die Klasse verlassen wird.

Der dritte Impuls tritt jede Minute am Anfang auf. Ist also der 
Indikator für eine "neue" Minute. Die Impulsdauer beträgt 1.5 Sekunden. 
Um Mitternacht ist der Impuls 57 Sekunden lang. Diese können also sehr 
gut für die Synchronisation verwendet werden.

Jetzt frag ich mich wie ich diesen dritten Impuls messen kann und vor 
allem die Länge des Impulses. Ich verwende bereits den 16- Bit Timer1 
des Controller zur Generierung von zwei PWM Signalen und als ICP. Ich 
denke also, dass dieser ausgelastet ist^^.

Mal sehen was ihr so denkt :).

MfG,
JTR

von Falk B. (falk)


Lesenswert?

@  Julian Schild (jaytharevo)

>Diese beiden Impulse haben jeweils ein fmax von 4kHz und 200Hz.

Naja, mittelschnell würde ich mal sagen.

> Für den
>Impuls mit bis zu 4kHz verwende ich den ICP Eingang und für den
>langsameren Impuls den externen Interrupt 1.

Kann man machen.

> Diese Impulse dürfen aber
>nur während der Sekunde 5 bis 55 gemessen werden. Die Anzahl der Impulse

>Der dritte Impuls tritt jede Minute am Anfang auf. Ist also der
>Indikator für eine "neue" Minute. Die Impulsdauer beträgt 1.5 Sekunden.

Eine Ewigkeit.

>Jetzt frag ich mich wie ich diesen dritten Impuls messen kann

Mit einem Timer-[Interrupt]] von sagen wir 100ms, da kann man auch 
die Länge problemlos messen.

>allem die Länge des Impulses. Ich verwende bereits den 16- Bit Timer1
>des Controller zur Generierung von zwei PWM Signalen und als ICP. Ich
>denke also, dass dieser ausgelastet ist^^.

Du hast noch mindestens 1 Timer mehr, meisten zwei.

MFG
Falk

von Nn N. (jaytharevo)


Lesenswert?

Vorweg. Der Controller soll mit 2Mhz laufen. Intern getaktet.


Falk Brunner schrieb:
>>Diese beiden Impulse haben jeweils ein fmax von 4kHz und 200Hz.
>
> Naja, mittelschnell würde ich mal sagen.

Jap, also ich denk, dass das nicht zu schnell sein wird.

>>Der dritte Impuls tritt jede Minute am Anfang auf. Ist also der
>>Indikator für eine "neue" Minute. Die Impulsdauer beträgt 1.5 Sekunden.
> Eine Ewigkeit.

Ist klar.

>>Jetzt frag ich mich wie ich diesen dritten Impuls messen kann
>
> Mit einem Timer-[Interrupt]] von sagen wir 100ms, da kann man auch
> die Länge problemlos messen.


>>allem die Länge des Impulses. Ich verwende bereits den 16- Bit Timer1
>>des Controller zur Generierung von zwei PWM Signalen und als ICP. Ich
>>denke also, dass dieser ausgelastet ist^^.
>
> Du hast noch mindestens 1 Timer mehr, meisten zwei.

Also. Da ich ja die Zeit genau messen muss verwende ich zusätzlich 
Timer0. Um eben sagen zu können wann sich der Controller zwischen der 
Sekunde 5 und 55 befindet.
Der Läuft mit Prescaler 8. Somit erziele ich sehr präzise 1ms. Der muss 
einfach sehr genau sein, sonst kommt am Ende vom Tag nur mehr Käse bei 
raus^^.
Also soll ich jetzt noch einen dritten Timer laufen lassen (Timer2), 
ebenfalls mit 1ms Overflow? 100ms wird sich nicht ausgehen, hätte da 
0,16% Error.

Ich mach mir langsam über das Interrupthandling sorgen. Ich habe noch 
keine Erfahrung mit so "vielen" versch. Interrupts (ca. 5).

Danke für deine Antwort. Schön das ich dich "gewinnen" konnte Falk! :D

MfG

von Falk B. (falk)


Lesenswert?

@Julian Schild (jaytharevo)

>Vorweg. Der Controller soll mit 2Mhz laufen. Intern getaktet.

>Also. Da ich ja die Zeit genau messen muss verwende ich zusätzlich
>Timer0.

Schön, aber so eine Uhr mach der AVR nebenbei beim Einschlafen. Man kann 
die Uhr + Abtastung des 3. Impulse locker dort drin machen.

>Der Läuft mit Prescaler 8. Somit erziele ich sehr präzise 1ms. Der muss
>einfach sehr genau sein, sonst kommt am Ende vom Tag nur mehr Käse bei
>raus^^.

Das kommt es sowiso, wenn du mit dem internen RC-Oszillator arbeitest 
und nicht oft synchronisierst. Das musst du, wenn es funktionieren soll, 
jede Minute machen.

>Also soll ich jetzt noch einen dritten Timer laufen lassen (Timer2),
>ebenfalls mit 1ms Overflow?

Nö, ein Timer reicht dafür locker.

> 100ms wird sich nicht ausgehen, hätte da 0,16% Error.

Ja und? Für diese Messung ist das mehr als genau genug. Du musst ja 
zwischen 1,5 und 57s unterschieden können ;-)

>Ich mach mir langsam über das Interrupthandling sorgen. Ich habe noch
>keine Erfahrung mit so "vielen" versch. Interrupts (ca. 5).

Es sind gerade mal drei. ICP, INT0 un der Timer. ICP und Timer sind 
vollkommen unkritisch, INT0 könnte durch die zwei anderen etwas gestört 
werden. Aber auch hier ist es kein Problem. Nimm einen externen Zähler 
ala 74HC4040 oder so und teile deine 200 Hz durch 64 oder mehr, da 
kommen so um die 3Hz raus. Die kannst du dann deutlich einfacher messen. 
Die Frequenz wird ja linear geteilt.

MFG
Falk

>Danke für deine Antwort. Schön das ich dich "gewinnen" konnte Falk! :D

Hab ich ein Preisausschreiben verpasst? ;-)

von Mark L. (m2k10) Benutzerseite


Lesenswert?

Wenn ich das richtig verstanden habe, kommt dein Zeitimpuls immer in 
Sekunde Null und die Messungen finden in Sekunde 5 bis 55 statt. Du 
könntest den Zeitimpuls auf einen Int-Pin legen, nach 2,5 Sekunden oder 
so nochmal nachsehen, ob ein noch da ist -> Tagessignal und die anderen 
Interrupts nur von Sekunde 5 bis 55 aktivieren, da kann sich dann auch 
nichts mehr in die Quere kommen. Da es wohl nur 1,5 Sekunden oder 
57Sekunden Impuls gibt, musst du nichts messen, nur unterscheiden, bzw. 
den 24h-Impuls erkennen. Wenn du den Prozessor ab Sekunde 55 nur noch 
auf den Zeit-Impuls wartest, sollte der auch immer Taktgenau den 
Interrupt auslösen zum Synchronisieren.
Mark

von Nn N. (jaytharevo)


Lesenswert?

Falk Brunner schrieb:
>>Vorweg. Der Controller soll mit 2Mhz laufen. Intern getaktet.
>
>>Also. Da ich ja die Zeit genau messen muss verwende ich zusätzlich
>>Timer0.
>
> Schön, aber so eine Uhr mach der AVR nebenbei beim Einschlafen. Man kann
> die Uhr + Abtastung des 3. Impulse locker dort drin machen.

Ja, wird wohl am besten sein.

>>Der Läuft mit Prescaler 8. Somit erziele ich sehr präzise 1ms. Der muss
>>einfach sehr genau sein, sonst kommt am Ende vom Tag nur mehr Käse bei
>>raus^^.
>
> Das kommt es sowiso, wenn du mit dem internen RC-Oszillator arbeitest
> und nicht oft synchronisierst. Das musst du, wenn es funktionieren soll,
> jede Minute machen.

Was für eine Genauigkeit kann ich denn erwarten?


>>Ich mach mir langsam über das Interrupthandling sorgen. Ich habe noch
>>keine Erfahrung mit so "vielen" versch. Interrupts (ca. 5).
>
> Es sind gerade mal drei. ICP, INT0 un der Timer. ICP und Timer sind
> vollkommen unkritisch, INT0 könnte durch die zwei anderen etwas gestört
> werden.

Es kommt noch der Overflow Interrupt durch den Timer1 im CTC Modus hinzu 
(PWM Erzeugung).

Aber auch hier ist es kein Problem. Nimm einen externen Zähler
> ala 74HC4040 oder so und teile deine 200 Hz durch 64 oder mehr, da
> kommen so um die 3Hz raus. Die kannst du dann deutlich einfacher messen.
> Die Frequenz wird ja linear geteilt.

Naja, wenn, dann sollte es wohl das 4kHz Signal sein oder? Mhm ich 
hoffe, dass ich da keine Timing Probleme haben werde.


Was ich eigentlich noch fragen wollte war ja an welchem Pin ich, dass 
messen könnte. Aber ich denke ich werds so machen: Einen externen Int. 
hab ich ja noch frei. Bei rising Edge werd ich anfangen zu zählen und 
den ext. Interrupt auf falling Edge umstellen. Sollte dann die falling 
Edge kommen werd ich einfach den Zählerstand auslesen und schaun wie 
weit er gezählt hat. Da mein Timer0 mir sowieso im ms Bereich eine 
Variable hochzählt kann ich die bequem verwenden. Denk so werd ich es 
machen. :)

Danke!

>
>>Danke für deine Antwort. Schön das ich dich "gewinnen" konnte Falk! :D
>
> Hab ich ein Preisausschreiben verpasst? ;-)

Du wirst dich nicht mehr erinner, aber du hast meine "Diplomarbeit" mit 
einer 3- benotet. Ist jetzt ca. ein halbes Jahr her :). [arschkrichen = 
on] Deine dirkete Art hat mir dabei geholfen mein Projekt erfolgreich 
abzuschließen :) [/arschkriechen]

MfG

von Falk B. (falk)


Lesenswert?

@Julian Schild (jaytharevo)

>> Das kommt es sowiso, wenn du mit dem internen RC-Oszillator arbeitest
>> und nicht oft synchronisierst. Das musst du, wenn es funktionieren soll,
>> jede Minute machen.

>Was für eine Genauigkeit kann ich denn erwarten?

1%, wenn die Temperatur nicht mehr als +/-10K schwankt. Siehe 
Datenblatt.

>Es kommt noch der Overflow Interrupt durch den Timer1 im CTC Modus hinzu
>(PWM Erzeugung).

Nein, den brauchst du nicht.

>Naja, wenn, dann sollte es wohl das 4kHz Signal sein oder?

Muss nicht sein. ICP entlastet dich da schon sehr.

>Du wirst dich nicht mehr erinner, aber du hast meine "Diplomarbeit" mit
>einer 3- benotet. Ist jetzt ca. ein halbes Jahr her :). [arschkrichen =
>on] Deine dirkete Art hat mir dabei geholfen mein Projekt erfolgreich
>abzuschließen :) [/arschkriechen]

Hmm, ich erinnere mich dunkel. Und welche Note hat man dir gegeben?

MFg
Falk

von Nn N. (jaytharevo)


Angehängte Dateien:

Lesenswert?

Ich hänge mal das Programm + Include an. Es ist noch lange nicht fertig, 
also bitte keine voreiligen Schlüsse.

Hier hab ich auch gleich eine Frage zur geschickten Realisierung.
Also, ich will ja den Minuten- Impuls mit dem ext. Interrupt erfassen, 
weiters will ich dessen Zeit bestimmen. Also setze ich ein Flag in der 
ISR um im Main zu signalisieren, dass die erste Flanke angekommen ist. 
In der Main, dann speichere ich mir den aktuellen Sekundenstand und 
ändere die Triggerung des ext. Int. auf falling edge. Jetzt, frag ich 
mich was ich in der Zwischenzeit tun soll. Einen neuen State in der 
Statemachine oder zusätzlich eine Variable welche mir die Durchgänge 
signalisiert oder, dass ich nach 3 Sekunden wieder nachschaue ob der H- 
Pegel immer noch anliegt.
1
    case Synchronise:
2
        
3
         if (Flag_m)
4
          {
5
           Second_tmp = Second;
6
           Flag_m = False;
7
           MCUCR ^= (1<<ISC00);  // Toggle Edgetrigger for measuring the pulse duration
8
          }
9
10
    break;

Wenn ich in dem State bleib, dann würd ich beim nächsten Durchlauf den 
temporär gespeicherten Sekundenzähler wieder überschreiben. Fragen über 
fragen.  Ich hänge da irgendwie :(.


@Mark.L:
Danke für deinen Input. Sry, habe deinen Beitrag nicht gleich gesehen 
weil du gleichzeitig geschrieben hast wie ich :). Ist ne super Idee. 
Werd ich einbauen. Danke.


Falk Brunner schrieb:

>>Was für eine Genauigkeit kann ich denn erwarten?
>
> 1%, wenn die Temperatur nicht mehr als +/-10K schwankt. Siehe
> Datenblatt.

Also Temp. wird meiner Meinung nach kaum schwanken. Genaueres kann ich 
leider noch nicht sagen. Hab mich da auch schon ein wenig im Datenblatt 
eingelesen, also gehts hier um ein Calibration Bit. Müsste ich für die 
richtige Einstellung der Frequenz nicht herausfinden wie der Takt 
momentan ausschaut? Damit ich weiß ob ich nach unten oder oben 
korrigieren muss.

>>Es kommt noch der Overflow Interrupt durch den Timer1 im CTC Modus hinzu
>>(PWM Erzeugung).
>
> Nein, den brauchst du nicht.

Hast du recht. Mein Timer1 läuft im "Compare Output Mode, Fast PWM (TOP 
= ICR1)". WGM13:0 =14. Hier auch noch der Code dazu. Vllt findet jemand 
ja einen Fehler bzw. Verbesserungen, würd mich freuen :):
1
void Timer1_init(void)
2
{
3
// Clear OC1A/OC1B on Compare Match, set OC1A/OC1B at BOTTOM
4
TCCR1A |= (1<<COM1A1) | (1<<WGM11);
5
// Compare Output Mode, Fast PWM (TOP = ICR1) | Positive Edge sensetive (ICP) | CPU_Clock
6
TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<ICES1) | (1<<CS10);
7
// ICP enabled | Overflow Interrupt enabled
8
TIMSK |= (1<<TICIE1) | (1<<TOIE1);
9
10
11
// TOP Value --> 20ms Frametime
12
ICR1 = Frame_time;
13
// OCR1A Value --> 1.5ms (Center)
14
OCR1A = Mittelstellung;
15
// OCR1B Value --> 1.5ms (Center)
16
OCR1B = Mittelstellung;
17
}

>>Naja, wenn, dann sollte es wohl das 4kHz Signal sein oder?
> Muss nicht sein. ICP entlastet dich da schon sehr.

Also könnten 200Hz für den ext. Interrupt ein Problem werden?

> Hmm, ich erinnere mich dunkel. Und welche Note hat man dir gegeben?

Beitrag "Stromsparen und Atmega8?"

Ich bekam eine 1. Es ging hier aber nicht alleine um das Programm. 
Zusätzlich kam noch eine 160- seitige Dokumentation und eine Prüfung 
hinzu.
FALLS es dich interessiert kann ich dir ja das PDF (~7MB) schicken. Dann 
kannst meine Note ja immer noch nach unten korrigieren^^ xD.


MfG,
Julian

von Falk B. (falk)


Lesenswert?

@  Julian Schild (jaytharevo)

>Also, ich will ja den Minuten- Impuls mit dem ext. Interrupt erfassen,

Du bist schon wieder lernresistent. :-(
Taste den Puls in einem 100ms Timerinterrupt ab, fertig.

>ändere die Triggerung des ext. Int. auf falling edge. Jetzt, frag ich
>mich was ich in der Zwischenzeit tun soll. Einen neuen State in der
>Statemachine

ja.

>eingelesen, also gehts hier um ein Calibration Bit.

Byte.

> Müsste ich für die
>richtige Einstellung der Frequenz nicht herausfinden wie der Takt
>momentan ausschaut?

Nur, wenn du eine andere Betriebspannung oder Temperatur nutzt. Siehe 
Datenblatt. Die abgelegte Kalibrierung ist meist für 5V/20°C.

>Also könnten 200Hz für den ext. Interrupt ein Problem werden?

Allein nicht, aber wenn noch andere Interrupts laufen. Die können dann 
die Ausführung verzögern und deine Zeitmessung damit negativ 
beeinflussen.
Aber das kann man alles lösen. Nämlich indem man einen Timer als Zähler 
betreibt und die Pulse zählt. Das entspannt die Sache.

>Beitrag "Stromsparen und Atmega8?"

Link?

Beitrag "Stromsparen und Atmega8?"

>Ich bekam eine 1. Es ging hier aber nicht alleine um das Programm.
>Zusätzlich kam noch eine 160- seitige Dokumentation

Aha, also eher Fleiss als Denkleistung. Naja.

>FALLS es dich interessiert kann ich dir ja das PDF (~7MB) schicken. Dann
>kannst meine Note ja immer noch nach unten korrigieren^^ xD.

Ne lass mal, ich bin nicht in der Prüfungskommission. Ausserdem wirst du 
bald merken, dass im wahren Leben (tm) andere Masstäbe gelten.

MFG
Falk

von Nn N. (jaytharevo)


Lesenswert?

Hey!

Bin gerade auf etwas gestoßen, das zum Problem werden könnte.

Und zwar ist im WGM Mode 14 ja ICR1 als TOP value angegeben. Das Problem
ist jetzt, dass wenn ich die ICP funktion verwenden will ich ICR1 nicht
als TOP value verwenden kann. Ich müsste also OCR1A nützen, dadurch geht
mir aber eines der Compare Register verloren und somit ein PWM Channel.
Was kann ich da jetzt machen?



Falk Brunner schrieb:
> Ne lass mal, ich bin nicht in der Prüfungskommission. Ausserdem wirst du
> bald merken, dass im wahren Leben (tm) andere Masstäbe gelten.

Na, das hoff ich doch!

Falk Brunner schrieb:
> Nämlich indem man einen Timer als Zähler
> betreibt und die Pulse zählt. Das entspannt die Sache.

Meinst du als "External Event Counter"? Könntest du, das ein wenig
genauer ausführen? Das Datenblatt schweigt sich darüber aus :(. Meinst
doch nicht ICP oder?

von Nn N. (jaytharevo)


Angehängte Dateien:

Lesenswert?

BTW: Ich upload mal den aktuellen Stand.

MfG

Edit: Lol, noch was^^. Controller ist jetzt ein ATmega88PA

von Nn N. (jaytharevo)


Angehängte Dateien:

Lesenswert?

Hab noch schnell ein paar Bugs ausgebssert. Durch den besseren 
Controller kann ich den Timer1 jetzt auch im CTC Modus laufen lassen.

von Julian (Gast)


Lesenswert?

Scheint so als ob ich ein größeres Problem hab oO?!

Ich hab mir schon überlegt ob ich nicht den ersten Impuls (4kHz) an 
einen der ext. Interrupts lege und wie von Falk vorgeschlagen den 
Minutenimpuls einfach per Polling abfrage.
Einen der PWM Channel kann ich schwer auslagern ohne viel Auflösung zu 
verlieren.

Was meint ihr? Was wäre am geschicktersten?

MfG,
Julian

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.