Geigerzähler mit 2 zählrohre

Hallo
Ich bin Neuling, habe mich aber mit Arduino ein bischen beschäftigt ,
jetzt komm ich an meine grenzen. Ich möchte gerne einen Geigerzähler mit 2 Zähler Impulsen Bauen,
das mit einem Impuls funktioniert schon. Und mit logview wird das am Pc mit geschrieben.
jetzt möchte ich noch einen 2. Impuls zählen und mit logview plotten .
und auf einem Display anzeigen habe ein TC1604
vielleicht ist es nur eine kleinesache oder es geht vielleicht gar nicht so wie ich mir das vorstelle

Vielen dank
LG
Marc

Mein Arduino Mega 2530

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8,9,10,3,4,5,6);

// Threshold values for the led bar
//#define TH1 50
//#define TH2 150
//#define TH3 300
//#define TH4 600
//#define TH5 900

// Variables
//int ledArray [] = {13,};

int geiger_input = 1;
//int geiger_input = 2;

int count = 0;
int count2 = 0;
int countPerMinute = 0;
int countPerMinute2 = 0;
long timePrevious = 0;
long timePreviousMeassure = 0;
long time = 0;
int countPrevious = 0;
float radiationValue = 0.0;

void setup(){

pinMode(geiger_input, INPUT );
for (int i=0;i<5;i++){
//pinMode(ledArray*,OUTPUT);*

  • }*
    // pinMode(geiger_input2, INPUT);
    // for (int i=0;i<5;i++){
    // pinMode(ledArray*,OUTPUT);*
    * //}*
    * Serial.begin(19200);*

* //set up the LCD's number of columns and rows:*
* lcd.begin(16, 4);*
* lcd.clear();*

* lcd.clear(); *
* lcd.setCursor(0, 0);*
* lcd.print("CPM=");*
* lcd.setCursor(4,0);*
_ lcd.print(6count);_
_
lcd.setCursor(0,1);_
_
lcd.print(radiationValue);*_

* attachInterrupt(0,countPulse,FALLING);*

}
void loop(){
* if (millis()-timePreviousMeassure > 10000){*
_ countPerMinute = 6count;_
_
radiationValue = countPerMinute/360.0;_
_
timePreviousMeassure = millis();_
_
Serial.print("$1;1;0;");_
_
Serial.print((byte) countPerMinute,DEC);_
_
Serial.print(";");_
_
//Serial.print("uSv/h = ");_
_
Serial.print(radiationValue,4); _
_
Serial.print(";0");_
_
Serial.println(13,DEC);*_

* lcd.clear(); *
* lcd.setCursor(0,0);*
* lcd.print("CPM=");*
* lcd.setCursor(4,0);*
* lcd.print(countPerMinute);*
* lcd.setCursor(0,1);*
* lcd.print(radiationValue,4);*
* lcd.setCursor(6,1);*
* lcd.print(" uSv/h");*
* // Geigerzähler 2*
* //lcd.clear();*

* lcd.setCursor(-4,2);*
* lcd.print("CPM=");*
* lcd.setCursor(0,2);*
* lcd.print(countPerMinute2);*
* lcd.setCursor(-4,3);*
* lcd.print(radiationValue,4);*
* lcd.setCursor(2,3);*
* lcd.print(" uSv/h");*

* count = 0;*

* }*
}
void countPulse(){
* if(timePrevious != millis()){*
* count++;*
* time = millis()-timePrevious;*
* timePrevious = millis();*
* }*
}
//void ledVar(int value){
* //if (value > 0){*
* //for(int i=0;i<=value;i++){*
_ //digitalWrite(ledArray*,HIGH);
//}
//for(int i=5;i>value;i--){
//digitalWrite(ledArray,LOW);
//}
//}
//else {
//for(int i=5;i>=0;i--){
//digitalWrite(ledArray,LOW);
//}
//}
//}*_

Hallo Marcmdt

Zuerst mal
long timePrevious = 0; müssen "unsigned long" sein weil Millis() auch unsigned long ist.

Die Interrupt-Routine muß so kurz wie möglich sein.

void countPulse(){
  if(timePrevious != millis()){
    count++;
    time = millis()-timePrevious;
    timePrevious = millis();
   }
}

Diese Routine ist viel zu lang.

Ich verstehe die Zeitkontrollen in der Interruptroutine nicht. Du kontrollierst ob in der gleichen Microsekunde schon ein Impuls da war. Wieso denn das?
Diese Code zählt mächtig falsch, wenn Du mehr als 1000 CPS (60000 CPM) Aktivität, da Impulse nicht gezählt werden.

EIN GM-Zählrohr braucht nach einem Zählimpuls eine gewisse Regenerationszeit in der es "blind" ist. Das sind in der Regel einige µsec (je nach Modell), aber bei weiten nicht 1msek.

Die Eingenheit von radioaktiven Zerfällen ist auch, daß sie zeitlich zufällig sind. Wenn Du zB 600CPM hast, heißt das nicht, daß alle 100msek ein Zerfall stattfindet sondern im Mittel auf einige Minuten!!! Darum kann schon bei niedrigen Zählraten auch mal 2 Impulse kürzer als 1msek nacheinander kommen.

Wieso brauchst Du 2 GM_Zählrohre?

Viele Grüeß Uwe

Hallo Uwe

Vielen dank für die Antwort

Habe die Software aus dem Netz und habe sie ein wenig leien haft
ab geändert .
ich habe 2 Platine mit je einem Geigermüller Zählrohr und möchte sie auf unser Haus Bauen und die umgebungs Stralung zu messen und zu loggen
ich habe wie gesagt die Software geändert vielleicht kannst du mir ein bischen helfen
Vielen Dank
Liebe Grüsse
Marc

Also zuerst mal :

  1. welches GM-Zählrohr hast Du?
  2. welche Elektronik verwendest Du?
    Grüße Uwe

Hallo Uwe

das ist eine Platine von Ebay da sind 2 Zählrohre

http://cgi.ebay.de/Geigerzahler-Dosimeter-Modul-DLM-1420-ODL-Hormann-/150611837016?pt=Wissenschaftliche_Geräte&hash=item23112a4058#ht_834wt_1139

und davon habe ich 2

LG Marc

Nee - Ich sage doch nix, weil ich alles & jeden beleidigen würde. ( 28 Zeilen gelöscht - Vor allem die Geiger !) ]:smiley:

Hallo Uwe
hier noch mal eine abgespeckte Version
Liebe Grüße

Marc

geiger_2_1_abgespekt.pde (1.95 KB)

Also
Du hast eine Platine mit Hochspannungs-Erzeugung und Vorverstärker. Es sind 2 verschiedene GM-Rohre drauf die wahrscheinlich 2 verschiedene Meßbereiche haben.
der ZP1221-1 hat eine max Totzeit von 210µS das heißt er mißt maximal ca 5000 CPS oder 285000 CPM.

Deine Quelle konnte das Model des 2. Zählrohr nicht entziffern, kannst Du das?

Woher hast Du den Code?

Morgen mehr.
Grüße Uwe

Hallo Uwe

ich habe eine PDF Datei bekommen über das Modul. Ich muss mal schauen, ob ich sie zuhause oder in der Firma habe.
Ich kann sie Dir ja mal mailen .
Übrigens vielen Dank, daß Du mir bei meinem Projekt hilfst.
Die Software habe ich von der Seite
http://www.cooking-hacks.com/index.php/documentation/tutorials/geiger-counter-arduino-radiation-sensor-board
kopiert und ein bißchen abgeändert. z.B. das mit dem Display das hat bei der Software nicht funktioniert
das habe ich hinbekommen .

Liebe Grüsse

Marc

Ich hab mir mal die Quelle des Codes angeschaut.

void countPulse(){
  if(timePrevious != millis()){
    count++;
    time = millis()-timePrevious;
    timePrevious = millis();
   }
}

Die Variable "time" wird nur in dieser Interrupt-Funktion verwendet.
Darum verlängert die Zeile

time = millis()-timePrevious;

nur die Ausführungszeit der Interrupt-Funktion. Für die Funktion ist sie kontraproduktiv.

Dies verleitet mich zur Annahme daß der Code fehlerhaft ist, oder von jemanden geschrieben wurde der keine klare Ahnung von der Programmierung und Funktion des GM-Zähler hat.

In den Kopfdaten steht:

We count the time (ms) between two pulses of the Geiger tube.

Dieser Wert hat aber keine Aussagekraft weil sie Zerfälle im Bezug auf die Zeit zufällig sind und nicht gleichmäßig erfolgen. Außerdem wenn man eine radioaktive Quelle messen will, mißt man nur die Radioaktivität die in Richtung des Zählrohrs ausgesendet wird. Da die Richtung auch als solche zufällig ist ergeben sich noch willkührlichere Periodendauern zwischen 2 gemessenen Zerfällen.

Für dei Funktion des programms genügt:

void countPulse(){
     count++;
}

Die Platine die Du erstanden hast, ist gebraucht. Sie wird routinemäßig ausgetauscht worden sein, bevor ein Zählrohr verbraucht war. Darum nehme ich mal an daß sie funktioniert.
GM-Zählrohre verbrauchen sich, durch die gemessenen Zerfälle.

Sie hat 2 GM-Zählrohre um versciedene Radioaktivitäten zu messen. Das ZP1221-1 mißt nur Gamma-Strahlen. Das 2 GM-Zählrohre könnte auch Alpha und Beta messen. Alpha - Telchen können sehr einfach abgeschirmt werden und darum bereits durch die Ummantelung des Sensors abgeschirmt werden.

Schau mal, ob Du das Modell des kleineren GM-Zählrohr ablesen kannst.

Programmcode Beispiele:

https://sites.google.com/site/diygeigercounter/software
Wobei ich mit diesem Code auch nicht glücklich bin, da in der Interruptfunktion nur ein Bit TRUE gesetzt wird und darum die Auswertung auf die loop-Funktion delegiert wird und vertraut wird daß die loop-Funktion kurz ist. Kann gut für niedrige Zählraten funktionieren, aber nicht für höhere. Würde schätzen 100CPS oder 6000CPM könnte das Limit sein; Für die Messung der Hintergrundstrahlung und knappe Erhöhung auf das 100 fache könnte das funktionieren.

Viele Grüße Uwe

Hallo Uwe

Vielen Dank für den link,

Also das große Zählrohr ist ein Zp1221/01 und das kleine Zp 1301.
geht da s überhaut das ich mit einer Arduino Mega2560 zwei Eingänge gleichzeitig zählen kann oder nach einander
habe mich mal mit einem sketch gespielt aber bis jetzt funktioniert es leider nicht
aber ich gebe noch nicht auf

Liebe Grüße
Marc

Geiger_Counter_DefaultMarc.pde (9.77 KB)

Das ZP1301 hat einen weiteren Meßbereich. Es ist unempfindlicher, kann aber höhere Dosen messen wo das ZP1221/01 schon nichts mehr mißt, weil es in Sättigung geht.

Du kannst ohne Probleme 2 Interrupt-Funktionen benutzen.

 attachInterrupt(0,countPulseL,FALLING);  // Pin 2
 attachInterrupt(1,countPulseH,FALLING);  // Pin 3
...
void countPulseL(){
     countL++;
}
void countPulseH(){
     countH++;
}

Nach einer Meßzeit die Du definierst wertest Du countL bzw countH aus.
Grüße Uwe

Hi

ich baue eine ähnliche Langzeitmessstation mit dem gleichen Modul und dem gleichen code.

void usvcounter() {
if (millis()-timePreviousMeassure > 1000) { 
     CPS = count;    CPM = 6*count;    uSv = CPM/360.0;
     timePreviousMeassure = millis();
     count = 0;
void Pulse() { 
    count++; 
}

Wenn ich das Gerät nun länger wie 50 Tage am Stück laufen lasse, habe ich dann auch diesen berühmten millis-overflow, von dem ich hier schon so viel gelesen habe ?

Dann versuche ich gerade noch Pachube miteinzubinden, den code habe ich von hier : https://github.com/openenergymonitor/sketchbook/tree/master/EtherShield_simpleClient
"EtherShield_simpleClient_Pachube/"

Funzt soweit ganz gut, bloß sobald ich irgendetwas anderes mit millis() verwenden möchte friert mir das board ein. Ich habe das dumpfe Gefühl, das man mit millis sehr vorsichtig umgehen muss, sobald zuviele Funktionen darauf zugreifen, stürzt es ab.

Gruß
MTE

Ja, millis() läuft nach 49, irgendwas Tagen über, aber durch geschicktes berechnen der Diferenzzeit kann man den Überlauf automatisch berücksichtigen und erhält immer die richtige Differenzzeit.
Millis() ist eine Funktion die einen Numerischen Wert zurückgibt und Du kannst es sooft aufrufen wie Du willst. Der Grund der Abstürze ist in Deinem Progrann und nicht in der Verwendung von Millis(). Poste mal Deinen Code.
Grüße Uwe

Nur so als Anregung: wer "schnell" zählen will sollte das nicht in Software sondern in Hardware erledigen. Die AVRs und damit auch der Arduino haben bequemerweise auch eingebaute Hardwarezähler. Das allwissende Datenblatt sagt dazu in "16.3 External Clock Source", daß man damit bis auf Clock/2 samplen kann, d.h. beim Arduino also bis 8 MHz. Das sollte auch für hohe Zählraten mehr als ausreichend sein.

Die Pinbelegung ist: T0 ist mit D4 und T1 mit D5 verbunden.

Interessant ist auch: "15.11.2 TCCR1B – Timer/Counter1 Control Register B".

Hier mal die Fehlermeldung wenn ich versuche das "blink" auf den Nano zu schieben...

avrdude: stk500_getsync(): not in sync: resp=0x00
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

Hast Du den richtigen COM-Port eingestellet?
Jeder Arduino hat einen anderen COM-Port, weil jeder eine andere Seriennummer im USB-Serial-Interface hat.
Grüße Uwe

Ja, alles quer durchs Gemüsebeet 5x probiert.

Beim einstecken des USB-Kabels flackern die RX/TX-LEDs kurz 2x auf und das wars, die Spannungen hab ich auch alle gecheckt, stimmt auch soweit alles.

Wenn ich versuche via Arduino as ISP den bootloader mit nem Funktionierenden Nano zu brutzeln kommt folgende Fehlermeldung

avrdude: stk500_getsync(): not in sync: resp=0x15

Hast Du das Richtige Board eingestellt?
Der Nano braucht als Einstellung den Arduino 2009 .
Grüße Uwe

Ja, alles richtig eingestellt, ich programmiere ja schon seit wochen damit rum...