Compteur Geiger portable avec Arduino Nano
Composants et fournitures
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Outils et machines nécessaires
|
Applications et services en ligne
| ||||
| ||||
| ||||
| ||||
| ||||
|
À propos de ce projet
Ce projet a commencé après que j'ai acheté un kit de compteur Geiger prêt à l'emploi chez Banggood.
L'idée était de placer ce kit dans un boîtier imprimé en 3D afin que l'ensemble complet de compteurs Geiger puisse être portable. Le résultat final est affiché ci-dessous :
Étape 1 :Conception du système
La conception du compteur Geiger portable est illustrée dans le schéma ci-dessous :
Le compteur Geiger est équipé d'un écran OLED couleur de 0,96 pouce, qui informe l'utilisateur du CPM mesuré (mesure du taux de détection d'événements d'ionisation par minute) ainsi que de l'équivalent de dose (calculé) en µSv/h à l'aide d'un simple facteur de 151 qui peuvent être trouvés dans la littérature pour le type de tube Geiger-Müller (GM) utilisé.
Voir aussi Wikipédia :https://en.wikipedia.org/wiki/Counts_per_minute
En fait, le CPM affiché est le résultat d'un calcul de coups pendant une minute, en mesurant les coups par seconde (CPS) et en stockant ces mesures dans un tableau qui couvre les dix dernières secondes. Le nombre total de comptes au cours des 10 dernières secondes est multiplié par 6 pour obtenir la valeur CPM.
Le nombre de comptes au cours de la dernière seconde est utilisé pour afficher le nombre momentané de mesures via un graphique à barres sur l'écran OLED. Ceci est utile en cas de taux de comptage élevés ou lorsque des changements rapides du taux de comptage se produisent lorsque le compteur portable est déplacé au-dessus d'une source de rayonnement.
Le compteur Geiger est alimenté par une batterie Li-ion de type 18650, qui peut être chargée via une prise micro-USB. Le port USB Arduino Nano est également accessible pour les modifications logicielles. Un buzzer supplémentaire est connecté à la carte compteur Geiger pour améliorer le son des ionisations dans le tube GM.
Toute l'électronique du compteur Geiger est intégrée dans le boîtier imprimé en 3D :
L'écran OLED est placé dans un boîtier séparé au-dessus du compteur Geiger :
La version entièrement assemblée :
Étape 2 :fabrication de l'assemblage du compteur Geiger
Les matériaux suivants sont utilisés :
- Arduino NANO 1 https://store.arduino.cc/arduino-nano
- Kit de compteur Geiger 1 https://uk.banggood.com/Assembled-DIY-Geiger-Counter-Kit-Module-Miller-Tube-GM-Tube-Nuclear-Radiation-Detector-p-1136883.html?rmmds =search&cur_warehouse=CN
- Écran couleur OLED 0.96" 96 * 64 1 https://www.banggood.com/0_95-Inch-7pin-Full-Color-65K-Color-SSD1331-SPI-OLED-Display-For-Arduino-p- 1068167.html?rmmds=search&cur_warehouse=CN
- Carte chargeur micro USB 18650 Batterie 1 https://www.banggood.com/5pcs-ESP32S-ESP32-0_5A-Micro-USB-Charger-Board-18650-Battery-Charging-Shield-p-1398716.html? rmmds=myorder&cur_warehouse=UK
- Batterie Li-ion 18650 rechargeable protégée 3.7v 4000mAh 1 https://www.banggood.com/4PCS-MECO-3_7v-4000mAh-Protected-Rechargeable-18650-Li-ion-Battery-p-992723.html? rmmds=myorder&cur_warehouse=CN
- Transistor BC547 1
- BUZZER -12MM 1
- Résistance 1k Ohm 1
La conception électronique
La conception électronique du kit compteur Geiger est illustrée dans le schéma de circuit suivant :
Le schéma de circuit de la configuration complète du compteur Geiger est le suivant :
L'alimentation 5V est fournie par une batterie Li-Ion rechargeable placée dans une carte de chargeur Micro USB. Le 3, 3 V pour l'écran OLED est tiré de cette carte.
La configuration de la maquette utilisée pour tester et créer le logiciel avec l'IDE ARDUINO est illustrée dans l'image suivante :
Assemblage mécanique et électrique
L'assemblage de toutes les pièces mécaniques et électroniques est illustré dans les images ci-dessous :
Notez que le compteur Geiger portable n'a pas de connexion par câble.
Pour charger la batterie Li-ion 3, 7V, il y a une ouverture séparée dans le boîtier pour connecter (temporairement) une prise micro USB.
Une connexion mini USB supplémentaire est disponible pour les mises à jour logicielles de l'Arduino Nano.
Étape 3 :La conception du logiciel
L'organigramme suivant montre la conception générale du logiciel du compteur Geiger :
Les vues sur l'écran OLED 0, 96" sont :
L'esquisse Arduino complète est répertoriée ci-dessous :
#include
#include
#include
//Connexions pour l'écran OLED
#define sclk 13 //SCL (fil bleu)
#define mosi 11 //SDA (fil blanc)
#define cs 10 //CS (fil gris)
#define rst 9 / /RES (fil vert)
#define dc 8 //DC (fil jaune)
#define LOGtime 1000 //Temps d'enregistrement en millisecondes (1 seconde)
#define Minute 60000 //le délai de 1 minute pour le calcul des valeurs CPM
#define show endWrite
#define clear() fillScreen(0)
// Définitions des couleurs
#define BLACK 0x0000
#define BLEU 0x001F
#define ROUGE 0xF800
#define VERT 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define JAUNE 0xFFE0
#define BLANC 0xFFFF
Adafruit_SSD1331 display =Adafruit_SSD1331(cs, dc, rst);
int Counts =0; //variable contenant le nombre d'événements GM Tube dans le LOGtime
unsigned long previousMillis=0 ; //variable pour stocker l'heure précédente
int AVGCPM =0; //variable contenant le nombre moyen flottant de comptes sur une période windo mobile fixe
int TenSecCPM =0;
int units =0;
int tens =0;
int centaines =0;
int milliers =0;
float Sievert =0;
int COUNTS[10]; // tableau de stockage des quantités d'impulsions mesurées en 10 périodes consécutives de 1 seconde
int t =0;
///////////////////le paramétrage code qui suit, s'exécutera une fois après "Power On" ou après un RESET //////////////////
void setup() {
Serial. begin(115200);
display.begin();
display.fillScreen(BLACK);
floatBattery =analogRead(A3) ; //(fil orange)
floatBattPerc =100 * (Batterie/770);
//Serial.print("valeur de la batterie ="); Serial.println (Batterie); Serial.print("pourcentage de batterie ="); Serial.println (BattPerc);
display.setCursor(4,4);
display.setTextSize(2);
display.setTextColor(MAGENTA);
display.println( "Batterie");
display.setCursor(4,24);
display.print (int (BattPerc)); display.print("."); display.print (int((10*BattPerc)-(10*int(BattPerc))));display.print(" %");
delay(3000);
display.fillScreen(BLACK );
for(int x =0; x <10; x++) { //mettre toutes les données dans le tableau COUNTS à 0 (les positions du tableau sont exécutées de 0 à 10 ;
COUNTS[x] =0 ; //10 positions couvrant une période de 10 secondes
}
attachInterrupt(0, IMPULSE, FALLING); //définir la broche d'interruption externe D2/INT0 pour démarrer la routine d'interruption IMPULSE (fil vert )
display.drawRect(0,0,96,64,WHITE);
display.setCursor(4,4);
display.setTextColor(RED);
display.setTextSize(2);
display.print("CPM");
display.setCursor(50,4);
display.setTextSize(1);
display.print("10 sec");
display.setCursor(50,12);
display.print("window");
display.setCursor(4, 38);
display.setTextSize(1);
display.setTextColor(GREEN);
display.print("uSv/hr");
display. drawRect(0,48, 96, 16, JAUNE);
}
////////////////// //////le code de boucle qui suit, s'exécutera à plusieurs reprises jusqu'à ce que "Power Off" ou un RESET ////////
boucle vide()
{
unsignedlong currentMillis=millis();
if(currentMillis - previousMillis>LOGtime)
{
previousMillis =currentMillis;
COUNTS[t] =Counts;
pour (int y =0 ; y <10; y++) { //ajouter toutes les données du tableau COUNTS ensemble
TenSecCPM =TenSecCPM + COUNTS[y]; //et calculez le CPM moyen glissant sur une période de 10 secondes
}
AVGCPM =6* TenSecCPM ;
TenSecCPM =0;
t++;
if (t> 9) { t =0;}
//Serial.print ("COUNTS "); Serial.print(t);Serial.print (" =");Serial.println (COUNTS[t]);
display.fillRect(4,20,90,17,BLACK); // efface le champ de valeur CPM sur l'affichage
display.setCursor(4,20);
display.setTextColor(RED);
display.setTextSize(2);
display .println(AVGCPM);
//Serial.print ("AVGCPM ="); Serial.print(AVGCPM); //Série.print (" CPM ="); Serial.println(CPM);
display.fillRect(45,38,50,10,BLACK); //effacer le champ de valeur uSv/Hr sur l'affichage
display.setCursor(45,38);
display.setTextColor(GREEN);
display.setTextSize(1);
Sievert =(AVGCPM /151,0); //Serial.print (" Sievert =");Serial.println (Sievert);
units =int (Sievert); //Serial.print ("unités ="); Serial.println(unités);
dizaines =int ((10*Sievert) - (10*unités)); //Serial.print (" dizaines ="); Serial.println(dizaines);
centaines =int ((100*Sievert) - (100*unités) - (10* dizaines)); //Serial.print ("cents ="); Serial.println(centaines);
milliers =int ((1000*Sievert) - (1000*unités) - (100*dizaines) - (10*centaines)); //Serial.print ("milliers ="); Serial.println (milliers);
display.print (unités); display.print("."); display.print (dizaines); display.print (centaines); display.println (milliers);
display.fillRect(1,49,94,14,BLACK); // efface le champ indicateur CPM sur l'affichage
display.fillRect(1,49,Counts,14,RED); //remplir le champ indicateur CPM sur l'affichage
Counts =0;
}
}
////////////// ////FIN DE BOUCLE//////////////////////////////////
//// //////////////////////////// Ci-après suit la fonction de comptage du nombre d'impulsions du kit compteur Geiger
void IMPULSE( )
{
Comptes++ ;
}
La partie la plus importante de l'esquisse est la fonction d'interruption qui est appelée lorsqu'une impulsion sur le tube GM du compteur Geiger est mesurée et déclenche la sortie INT du compteur Geiger (en la rendant LOW pendant une courte période). Le signal INT est connecté à la broche D2 (la broche d'interruption externe INT0 de l'Arduino Nano) :
attachInterrupt(0, IMPULSE, FALLING);
Le signal INT lancera la routine d'interruption IMPULSE () pour augmenter les comptes de 1 :
void IMPULSE() {Compte++ ; }
Au bout de 1000 millisecondes :
- l'entier Counts est remis à 0
- le tableau COUNTS [ ] est rempli avec le nombre de comptes mesurés au cours des 1000 dernières millisecondes
- le nombre total de comptes au cours des 10 dernières secondes est calculé en additionnant tous les nombres du tableau COUNTS [ ] et multiplié par 6 pour présenter la valeur CPM à l'écran.
- L'équivalent de dose exprimé en µSv/h est calculé en divisant la valeur CPM par 151 (valeur trouvée dans la littérature).
- Sur l'écran couleur OLED, une barre rouge s'affiche en fonction de la valeur des comptes au cours de la dernière seconde, présentant donc en fait la valeur CPS (comptes par seconde)
L'esquisse ARDUINO complète pour le compteur Geiger comprend environ 150 lignes de code. La liste complète est incluse dans le cadre de ce tutoriel, le code ARDUINO (voir chapitre 9) est fourni avec de nombreux commentaires.
Code
- Geiger_Counter.ino
Geiger_Counter.inoArduino
ARDUINO Sketch pour le compteur Geiger fonctionnant sur un Arduino Nano :/********** Ce projet a été développé et produit par Pierre Pennings (décembre 2019), ce projet consiste à fabriquer un compteur Geiger portable en utilisant un kit de compteur Geiger prêt à l'emploi, dans un détecteur de rayonnement portable imprimé en 3D, le kit est connecté à un Arduino Nano qui compte le nombre d'impulsions du tube Geiger/Muller sur une période de 10 secondes, puis affiche le CPM moyen (compte par Minute) sur un écran couleur OLED 96*64. Le CPM mesuré est également affiché en micro Sievert par heure (avec un simple facteur de conversion de 151). L'écran OLED affiche également la quantité d'impulsions mesurée momentanément (par seconde) et affiche les mesures sous forme de barre rouge mobile sur l'écran. Le boîtier imprimé en 3D contient également la batterie 18650-Ion Lithium (rechargeable) qui fournit l'alimentation 5V à l'Arduino Nano ainsi que le kit Geiger Counter et 3,3V pour l'écran OLED. Un interrupteur de mise sous tension et un bip externe complètent le détecteur. À la mise sous tension, le niveau de charge de la batterie 18650 s'affiche sur l'écran couleur. Ce code est sous licence GPL3+. *********/#include#include #include //Connexions pour l'écran OLED#define sclk 13 //SCL (fil bleu)# define mosi 11 //SDA (fil blanc)#define cs 10 //CS (fil gris)#define rst 9 //RES (fil vert)#define dc 8 //DC (fil jaune)#define LOGtime 1000 //Logging temps en millisecondes (1 seconde)#define Minute 60000 //la période de 1 minute pour calculer les valeurs CPM#define show endWrite#define clear() fillScreen(0)// Color definitions#define BLACK 0x0000#define BLUE 0x001F#define ROUGE 0xF800#define VERT 0x07E0#define CYAN 0x07FF#define MAGENTA 0xF81F#define YELLOW 0xFFE0 #define WHITE 0xFFFFadafruit_SSD1331 display =Adafruit_SSD1331(cs, dc, rst);int Counts =0; //variable contenant le nombre d'événements GM Tube dans le LOGtimeunsigned long previousMillis =0; //variable pour stocker le timeint précédent AVGCPM =0; //variable contenant le nombre moyen flottant de comptes sur une fenêtre mobile fixe periodint TenSecCPM =0;int units =0;int dizaines =0;int centaines =0;int milliers =0;float Sievert =0;int COUNTS[10]; // tableau pour stocker les quantités mesurées d'impulsions dans 10 périodes consécutives de 1 secondeint t =0;///////////////////le code de configuration qui suit, s'exécutera une fois après "Power On" ou après un RESET///////////////////void setup() { Serial.begin(115200); display.begin(); display.fillScreen(NOIR); Batterie flottante =lecture analogique (A3) ; //(fil orange) float BattPerc =100 * (Batterie/770); //Serial.print ("valeur de la batterie ="); Serial.println (Batterie); Serial.print ("pourcentage de batterie ="); Serial.println (BattPerc); display.setCursor(4,4); display.setTextSize(2); display.setTextColor(MAGENTA); display.println("Batterie"); display.setCursor(4,24); display.print (int (BattPerc)); display.print("."); display.print (int((10*BattPerc)-(10*int(BattPerc)))); display.print(" %"); retard (3000); display.fillScreen(NOIR); for (int x =0; x <10; x++) { //mettre toutes les données dans le tableau COUNTS à 0 (les positions du tableau vont de 0 à 10; COUNTS[x] =0; //10 positions couvrant une période de 10 secondes } attachInterrupt(0, IMPULSE, FALLING); //définir une interruption externe sur la broche D2/INT0 pour démarrer la routine d'interruption IMPULSE (fil vert) display.drawRect(0,0,96,64,WHITE); display.setCursor( 4,4 ); display.setTextColor(RED); display.setTextSize(2) ; display.print("CPM"); display.setCursor(50,4) ; display.setTextSize(1) ; display.print("10 sec"); display.setCursor(50,12); display.print("window"); display.setCursor(4,38); display.setTextSize(1); display.setTextColor(GREEN); display.print(" uSv/hr"); display.drawRect(0,48, 96, 16, YELLOW);}////////////////////////le code de boucle qui suit, s'exécutera à plusieurs reprises jusqu'à ce que "Power Off" ou une boucle RESET /////////void loop() { long currentMillis =millis(); if(currentMillis - previousMillis> LOGtime) { previousMillis =currentMillis; COUNTS[ t] =Comptes ; pour (int y =0 ; y <10 ; y++) { //ajouter toutes les données du tableau COUNTS ensemble TenSecCPM =TenSecCPM + COUNTS[y]; //et calculez le CPM moyen glissant sur une période de 10 secondes } AVGCPM =6* TenSecCPM; TenSecCPM =0 ; t++; if (t> 9) { t =0;} //Serial.print ("COUNTS "); Serial.print(t); Serial.print (" ="); Serial.println (COUNTS[t]); display.fillRect(4,20,90,17,NOIR); // effacer le champ de valeur CPM sur l'affichage display.setCursor(4,20); display.setTextColor(RED); display.setTextSize(2); display.println(AVGCPM); //Série.print ("AVGCPM ="); Serial.print (AVGCPM); //Série.print (" CPM ="); Serial.println (CPM); display.fillRect(45,38,50,10,NOIR); // effacer le champ de valeur uSv/Hr sur l'affichage display.setCursor(45,38); display.setTextColor(GREEN); display.setTextSize(1); Sievert =(AVGCPM /151,0); //Serial.print (" Sievert ="); Serial.println (Sievert); unités =entier (Sievert); //Serial.print ("unités ="); Serial.println (unités); dizaines =int ((10*Sievert) - (10*unités)); //Serial.print (" dizaines ="); Serial.println (dizaines); centaines =int ((100*Sievert) - (100*unités) - (10* dizaines)); //Serial.print ("cents ="); Serial.println (centaines) ; milliers =int ((1000*Sievert) - (1000*unités) - (100*dizaines) - (10*cents)); //Serial.print ("milliers ="); Serial.println (milliers); display.print (unités); display.print("."); display.print (dizaines); display.print (centaines); display.println (milliers); display.fillRect(1,49,94,14,NOIR); // efface le champ indicateur CPM sur l'affichage display.fillRect(1,49,Counts,14,RED); // remplir le champ indicateur CPM sur l'affichage Counts =0; }}/////////////////FIN DE BOUCLE///////////////////////// //////////////////////////////////////// Ci-après suit la fonction pour compter le nombre d'impulsions de Geiger Counter kitvoid IMPULSE() { Counts++; }
Pièces et boîtiers personnalisés
Boîtier imprimé en 3D pour l'écran OLED 0,96" display_geiger_rev04_v2_bsLHSDvTUU.3mfhousing réalisé avec Fusion 360, composé d'une partie supérieure et inférieure : geiger_counter_housing_top__bottom_rev04_v1_cvCIwkO13j.obj3D fichier stlSchémas
Ce schéma montre la configuration de l'électronique :Processus de fabrication
- horloge IV9 Numitron DIY la plus simple avec Arduino
- Jeu de gyroscope Arduino avec MPU-6050
- Dés numériques Arduino
- Contrôleur de jeu Arduino
- Contrôler l'accepteur de pièces avec Arduino
- Jeu Arduino Nano Tetris sur matrice 16x8 maison
- Arduino avec Bluetooth pour contrôler une LED !
- Arduino Nano :contrôler 2 moteurs pas à pas avec joystick
- Compteur Geiger Muller personnalisable