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.
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.
"...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
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.
> 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 ;-))
> 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.
@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.
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. ;)
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 ;-)
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
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.
"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
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" :-))
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.