www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Impuls-Zähler mit Mega8


Autor: Zotteljedi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich habe hier einen lustigen Geiger-Müller-Zähler, der an einem Ausgang
Rechtecke mit 0 und Versorgungsspannung (max. 9 Volt) ausgibt. Jetzt
möchte ich eine Schaltung basteln, die diese Impulse zählt und
verwurstet, Durchschnitt berechnet etc. pp.

Die Totzeit des Rohrs beträgt 10^-4 bis 10^-5 Sekunden, also kann im
ungünstigsten Fall der Abstand zwischen zwei Impulsen 10 us betragen.
Zählen möchte ich in einem uint32_t, als uC-Takt wollte ich den
internen Taktgeber bei 1 MHz nutzen. Von der Idee über einen
Interrupt-Pin zu zählen bin ich schon abgekommen, weil mir 10 Takte
etwas knapp erscheinen (32-Bit-Inkrement auf einer 8-Bit-CPU ist sicher
nicht das Fixeste), aber vor allem in anderen Interrupt-Handlern dann ja
Impulse verloren gehen würden.

Wenn ich das Datenblatt soweit richtig verstanden habe, kann man den
16-Bit-Timer/Counter über einen externen Pin immer eins weiterzählen
lassen, und das ist unabhängig vom Rest des Controllers, insbesondere
ob man sich in einer ISR befindet oder nicht. Soweit korrekt?

Mein Plan ist nun mit Timer0 alle 100 ms einen Interrupt auszulösen,
der dann den Wert aus dem 16-Bit-Zähler nimmt und auf meinen uint32_t
draufaddiert. Ich habe dann noch zwei Buttons die bedient werden
sollen, das könnte ich dann auch in diesem Handler erledigen, wenn ein
Portpin 2x oder 3x hintereinander an bzw. aus ist, ist es ein bewusstes
Drücken gewesen.

Ausgabe, Berechnung etc. dann in der Main-Loop, das Übliche halt. Taugt
der Plan soweit?

Den Eingang wollte ich dann noch mit einem Optokoppler abhängen, der
hat allerdings Rise- und Falltimes von je 10 us. Tut's bei Signalen
0/9 Volt auch eine 5,1 V Z-Diode? Ich dachte dann auch noch an 5k6 in
Reihe vor der Z-Diode, dann kommt so ca. 1 mA durch. Beide Geräte sind
Batteriegetrieben und von daher weiß niemand was von einem echten
Ground.

Autor: Läubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja der Plan Taugt was ;)
Und für die Konvertierung der Spannungen kannst du einen
Spannungsteiler benutzen, zudem soltlest du die Massen beider Geräte
zusammenschalten sonst gibts nur Ärger.

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"...der dann den Wert aus dem 16-Bit-Zähler nimmt und auf meinen
uint32_t draufaddiert. "


Das kann so nichts werden.
Was soll denn diese Summe sein ?
Auf keinen Fall hat sie irgendwas mit der Impulszahl zu tun.


Du nimmst einfach den Overflowinterupt und zählst dort eine
16-Bit-Variable hoch, das ergibt dann zusammen die 32 Bit.

Und vor dem Auslesen nicht vergessen, den Zähler anzuhalten !
O.k. wenn man ein bischen nachdenkt, kann man auch einen laufenden
Zähler auslesen, ohne daß es Übertragsfehler gibt.


Peter

Autor: papa_of_t (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Du könntest doch relativ einfach einen externen Quarz z.B. mit 10MHz
anschließen, dann bist Du 10x so schnell - das reicht bestimmt für
einen Zähl-Interrupt (100 Takte in 10uS).

Außerdem könntest Du einen Vorteiler benutzen. Such mal hier im Forum
nach "Frequenzzähler".

C.

Autor: Zotteljedi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das kann so nichts werden.
> Was soll denn diese Summe sein ?
> Auf keinen Fall hat sie irgendwas mit der Impulszahl zu tun.

Das bedarf genauerer Erklärung, ich sehe das Problem nicht.

Ich nenne den uint32_t mal sum, und das Zählerregister vom
16-Bit-Counter cnt, weil ich den genauen Namen nicht parrat habe.

1) Start der Messung, sum = cnt = 0.
2) ISR: sum += cnt; cnt = 0;

Damit habe ich IMHO nach jeder Synchronisation im ISR die Impulse seit
Start der Messung in sum stehen. Ich hatte das Datasheet jedenfalls so
verstanden, daß ich auf das Counter-Register schreiben kann, es also
insbesondere zu beliebigen Zeiten auf 0 setzen darf.

Aber vielleicht habe ich ja was übersehen, erleuchte mich :-)

> Du nimmst einfach den Overflowinterupt und zählst dort eine
> 16-Bit-Variable hoch, das ergibt dann zusammen die 32 Bit.

Dann muß ich aber immer, wenn ich die Gesamtzahl wissen will, beide
Variablen lesen. Ich hätte das zum Rumrechnen schon gerne als eine. Ich
sehe auch das Problem bei meinem Vorgehen noch nicht, wink doch mal
kräftiger.


> Und vor dem Auslesen nicht vergessen, den Zähler anzuhalten !
> O.k. wenn man ein bischen nachdenkt, kann man auch einen laufenden
> Zähler auslesen, ohne daß es Übertragsfehler gibt.

Jo, das untere wird ja zuerst gelesen. Daß der Zähler überläuft ist
auszuschließen, wenn's irgendwo 65536 Impulse pro 100 ms strahlt, dann
will ich da nicht sein. Ob's bei so einer Strahlung die Schaltung
nicht eh schon fraggt ist die andere Frage ;-))

Autor: Zotteljedi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Du könntest doch relativ einfach einen externen Quarz z.B. mit 10MHz
> anschließen, dann bist Du 10x so schnell - das reicht bestimmt für
> einen Zähl-Interrupt (100 Takte in 10uS).

Das wäre die Ausweichlösung, ja. Aber soweit ich das verstanden habe,
löst der interne Counter mein Problem in Wohlgefallen auf.

> Außerdem könntest Du einen Vorteiler benutzen. Such mal hier im
Forum
> nach "Frequenzzähler".

Naja, wenn ich nix messe, habe ich eine Nullrate von 120 pro Minute,
wenn ich da einen Teiler vor den Controller packe, habe ich ja erst
nach einigen Sekunden eine Anzeige, das fände ich etwas doof. Von der
Verschenkten Genauigkeit mal ganz abgesehen.

Autor: Zotteljedi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter:

Ich sehe gerade, daß ich mich im OP nicht "algorithmisch genau"
ausgedrückt habe, Du dachtest vermutlich, daß ich den weiterlaufenden
Zähler immer draufaddiere, dann kommt natürlich irgendein integrierter
Murks raus. Das sind ja nur softwaremäßige Details, die krieg ich schon
auf die Reihe. Mir ging es um den Gesamtplan, ob das so geht.

Konkrete würde es mir also einen Strich durch die Rechnung machen,
wenn

a) der Counter nicht völlig unabhängig von der CPU ist
b) ich auf den Counter nicht schreiben darf (zum Resetten)

oder halt noch c), d) und e), an die ich nicht denke, weil ich sie
nicht kenne. Dazu die Frage hier.

Autor: Läubi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach doch so das du 2 Modi erlaubst, einmal Tiks/sek und einmal einfach
fortlaufend.
Ich weiß aus den Experimenten in der Schule, das man da eh nicht
sooooviel mißt.
Und dann kanste ja mal in der Shcule freudnlich fragen ob du mal
vergleichen darfst, deien Messung mit dem Messgerät dan wießte gleich
obs Hinkommt. ;)

Autor: Zotteljedi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ist es gedacht, drei Modi will ich realisieren:

- fortlaufen zählen, also Anzeige "Sekunden" und "Impulse"

- gemittelt ausgeben "Pro Minute" und "Pro Sekunde" wobei der
  erste Wert natürlich erst nach 60 Sekunden ausgegeben wird,
  davor wäre es ja statistisch gelogen.

- ablaufender Zeitraum über den gesammelt wird, also "hh:mm:ss"
  als Countdown, und "Impulse" als zweite Anzeige, das Zählen wird
  dann dann gestoppt, wenn der 00:00:00 erreicht ist.

Wird auf einem 2 x 16 LCD ausgegeben. Ich habe noch einen Moment über
eine RS-232 Schnittstelle nachgedacht, das wäre ein exzellenter
Zufallszahlengenerator. Über eine Minute zählen und das unterste Bit
davon verwenden, zufälliger geht es nicht. (Außer das hier schonmal
vorgestellte Halbleiter-Rauschen hochverstärken und durch den ADC
jagen, die Idee hat mir auch gefallen.)

Ich habe hier eine alte Armbanduhr zur Verfügung, mit den ungesunden
Leuchtziffern. Die kommt auf 6000 Impulse pro Minute, mithin also noch
100 pro Sekunde. Ein befreundeter Physiklehrer hat noch eine
Radium-Probe die noch deutlich heftiger war, "die stand in der Schule
in der hintersten Ecke der Sammlung, die wollte niemand mehr
verwenden". Die wollte er mir auch nicht mitgeben, was ich durchaus
verstehe ;-)

Autor: Zotteljedi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Vollständigkeit halber will ich noch erwähnen, daß bei der besagten
Armbanduhr ein großer Teil Beta-Strahlung ist, und durch ein paar mm
Alublech schon etliches weg war, aber die Gamma-Strahlung hat's auch
noch auf einige hundert Impulse pro Minute gebracht. Muß man sich mal
überlegen, das Teil hat der Mann 15 Jahre lang am Handgelenk getragen
schüttel

Autor: Rahul Der trollige (rahul)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die Radium-Probe?

Autor: Zotteljedi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Humm, nein. Die Armbanduhr gehört auch dem Physik-Lehrer, und die hat er
am Handgelenk getragen, gar nicht so unüblich. Nur hat er mir die für
Versuche geliehen, daher schrub ich "habe zur Verfügung".


Je länger ich über Peters Idee mit dem Overflow-Interrupt nachdenke,
desto besser gefällt sie mir. Das spart nämlich die Race Condition des
Lesens und Nullsetzens. Ist zwar hinreichend unwahrscheinlich und
überbietet die Genauigkeit des Zählrohrs, aber ist natürlich vorhanden,
und könnte jeweils einen Impuls verlieren, bei niedrigen Raten
ärgerlich.

Zur Verwurstung kann ich dann immernoch
sum = (overflows << 16) + cnt;
verwenden, ist ja kein Akt, und wenn ich jederzeit auf den Zählerstand
zugreifen kann, ist ja auch nichts an Genauigkeit o.ä. verloren.

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Das spart nämlich die Race Condition des Lesens und Nullsetzens."

Genau das isses. Es kann Dir jedesmal 1 Impuls verloren gehen. Den
Overflow zu verwenden ist daher genauer.


Beim 8051 kann man auch atomar Lesen und Nullsetzen:

clr a        ;A = 0
xch a, tl0   ;A = TL0, TL0 = A

Das Zählen erfolgt ja immer in dem Zyklus nach der
Read-Modify-Write-Instruktion.


Peter

Autor: Zotteljedi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Teil ist übrigens inzwischen fertig und funktioniert einwandfrei.

Naja, meistens zumindest, manchmal zählt er für jedes Rechteck vom
Zählrohr 2 oder 3 Ticks weiter. Hängt scheinbar davon ab, wie fit die
Batterie (im Geigerzähler) noch ist, und hält sich dann über die
gesamte Laufzeit (also immer genau 2 Ticks oder genau 3 Ticks pro
Zerfall, zumindest über einige Minuten hin beobachtet). Ohne Oszi lässt
sich da aber wohl nur mutmaßen.

Vielleicht einen winzigen Kondensator rein, oder einen Schmitt zum
Aufbereiten des Signals vor dem AVR-Eingang? Da es sich um den
T1-Eingang handelt ist softwaremäßig nix drin, bevor jemand meint
"niemals hardwaremäßig entprellen" :-))

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.