Programmes pour exploiter les différents montages

On présente ici trois solutions pour exploiter le module Geiger avec la carte Arduino :

  1. Comptages des désintégrations pendant une fenêtre de temps définie et affichage dans le moniteur série.

  2. Comptage des désintégrations pendant une fenêtre de temps définie et lecture des données par un programme Python pour construction de l’histogramme des comptages.

  3. Utilisation d’une bibliothèque d’instructions et mesure de dose radioactive.

Comptage et lecture des données sur le moniteur série

Principe

Dans ce programme, on paramètre la durée de la fenêtre de comptage et on lit directement sur le moniteur série le nombre de coups comptés par le module Geiger.

Le programme proposé permet aussi d’afficher les mesures sur un écran LCD si la durée de la fenêtre de comptage est suffisamment longue.

1
#include <Wire.h>
2
#include <LiquidCrystal_I2C.h>
3
LiquidCrystal_I2C lcd(0x27, 20, 4);  // Adapter l'adresse et nb colonnes lignes à l'écran
4
int Coups, Coups_avant;
5
int dt;  // Durée de la fenêtre de mesure en s
6
int pinEntree = 3;
7
long Tinit;
8
9
void Detection() {  // Routine executée lors de l'interruption (ajoute 1 coup)
10
  Coups++;
11
}
12
13
void setup() {
14
  Serial.begin(9600);  // Initialisation du moniteur série
15
  lcd.init();          //Initialisation de l'écran LCD
16
  lcd.backlight();     //Allumage du rétroéclairage
17
  lcd.setCursor(0, 0);
18
  lcd.print("Comptage commence");
19
  dt = 10;  // Modifier pour ajouster la durée de la fenêtre de comptage (en s)
20
  Coups = 0;
21
  Coups_avant = 0;
22
  pinMode(pinEntree, INPUT);
23
  attachInterrupt(digitalPinToInterrupt(pinEntree), Detection, FALLING);  // Déclenchement de l'interruption, Port 3 , front descendant
24
  Tinit = millis();
25
}
26
27
void loop() {
28
  delay(dt * 1000);
29
  int Res = Coups - Coups_avant;
30
  Coups_avant = Coups;
31
  // Affichage d'infos sur l'écran LCD si écran connecté (pas obligatoire)
32
  lcd.clear();
33
  lcd.setCursor(0, 0);
34
  lcd.print("Fenetre (s) : ");
35
  lcd.print(dt);
36
  lcd.setCursor(0, 2);
37
  lcd.print("Coups : ");
38
  lcd.print(Res);
39
  //--------------------------
40
  // Affichage d'infos sur le moniteur série (ne pas afficher le moniteur série pour récupération)
41
  Serial.print("nombre impulsion : ");
42
  Serial.print(Res);  // Affichage du dernier comptage
43
  Serial.print("    ");
44
  Serial.println((millis() - Tinit) / 1000);
45
}

MéthodeUtilisation

Le seul paramétrage à effectuer ici est le réglage de la durée de la fenêtre de mesure en seconde à la ligne 19, en renseignant la valeur de la variable dt.

RemarqueUtilisation des interruptions

Ce programme utilise les interruptions pour compter les désintégrations.

Explication de la ligne 23 : attachInterrupt(digitalPinToInterrupt(pinEntree), Detection, FALLING);

  • Le module Geiger génère une brève impulsion descendante 5V -> 0V lors de la détection d’une particule ou d’un rayonnement.

  • La détection de cette impulsion descendante (FALLING), appelle la fonction Detection qui incrémente le nombre de coups.

Récupération des données avec un programme Python pour tracer les histogrammes

Le programme proposé ici a pour objectif le tracé de l’histogramme des comptages effectués. Il récupères les données envoyées par la carte Arduino sur le port série et trace au fur et à mesure l’histogramme des comptages en superposant la gaussienne de même moyenne et de même écart-type que la distribution des mesures.

Comptage de désintégrationsInformations[1]

MéthodeUtilisation

Il faut téléverser le programme de la partie précédente dans la carte Arduino après avoir renseigné la ligne 19. Une fois le téléversement effectué, Arduino IDE peut être fermé. Il faut en tout état de cause que le moniteur série soit fermé.

On exécute ensuite le programme ci-dessous qui se charge de la récupération des données après quelques questions :

  • Titre du graphique.

  • Durée de la fenêtre de mesure.

  • Durée totale de l’acquisition.

Programme

1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Wed Feb 21 10:29:08 2024
5
6
@author: Jonas Forlot Modifications Compteur Geiger 2024 Cédric Vanden Driessche puis C. Bellessort
7
Dernière mofif : détection du port Arduino sur nom du périphérique plutôt que sur le nom du port
8
Tracé du diagramme en "temps réel"
9
Ajout des données statistiques sur le graph
10
Tracé de la gaussienne de même moyenne et de même écart-type
11
"""
12
13
# Importation des modules
14
import serial
15
import serial.tools.list_ports   # pour la communication avec le port série
16
import time  # gestion du temps
17
import matplotlib.pyplot as plt  # pour le tracé de graphe
18
from matplotlib import animation  # pour la figure animée
19
from math import e, pi
20
from statistics import mean, stdev, pstdev
21
22
# initialisation des listes
23
liste_temps_mesure = []  # liste pour stocker le temps"brut"
24
liste_temps = []  # liste pour stocker les valeurs de temps en partant de t=0
25
liste_impulsion = []  # liste pour stocker les impulsions
26
liste_duree = []
27
28
Duree_acquisition = int(input(
29
    "Entrer la durée totale de l'acquisition en secondes : "))
30
t_fenetre = int(
31
    input("Entrer la durée de la fenêtre de mesure en secondes : "))
32
cps_total = 0  # Nombre total de détections
33
Ntotal = int(Duree_acquisition / t_fenetre)  # Nombre d'échantillons
34
N = 0
35
36
37
def recup_port_Arduino():
38
    ports = list(serial.tools.list_ports.comports())
39
    for p in ports:
40
        print(p.description)
41
        if "Arduino Uno" in p.description:  # On cherche dans la description le nom de la carte "Arduino Uno"
42
            mData = serial.Serial(p.device, 9600)
43
    print(mData.is_open)
44
    print(mData.name)
45
    return mData
46
47
48
def gauss(m, s, c):
49
    return 1 / (s * (2 * pi)**0.5)*e**(-0.5 * ((c-m) / s)**2)
50
51
52
Titre = input("Nom de l'échantillon testé (titre du graphique) : ")
53
Titre = Titre + " - Coups par fenêtre de " + str(t_fenetre) + " s"
54
t0 = time.time()
55
Data = recup_port_Arduino()
56
57
while N < Ntotal:
58
    plt.clf()
59
    ligne1 = Data.readline()
60
    liste_données = ligne1.strip().split()
61
62
    if len(liste_données) != 0:
63
        liste_impulsion.append(int(liste_données[3].decode()))
64
        liste_temps.append(int(time.time()-t0))
65
        cps_total = cps_total + liste_impulsion[-1]
66
        N = N + 1
67
    m = min(liste_impulsion)
68
    M = max(liste_impulsion)
69
    print("t=" + str(liste_temps[-1]), "  ", cps_total, liste_impulsion[-1])
70
71
    if len(liste_impulsion) > 1:
72
        cps_moy = mean(liste_impulsion)
73
        cps_ecartype = stdev(liste_impulsion)
74
        cps_pecartype = pstdev(liste_impulsion)
75
        if cps_ecartype != 0:
76
            x = [m + i * (M - m) / 500 for i in range(501)]
77
            y = [N * gauss(cps_moy, cps_pecartype, val) for val in x]
78
            plt.plot(x, y, color="red")
79
            plt.text(0.7, 0.83, r"$cps_{total}=$"+f"{cps_total:.0f}",
80
                     transform=plt.gcf().transFigure, fontsize="large")
81
            plt.text(0.7, 0.80, r"$N=$"+f"{N:.0f}",
82
                     transform=plt.gcf().transFigure, fontsize="large")
83
            plt.text(0.7, 0.77, r"$\overline {cps}=$"+f"{cps_moy:.1f}",
84
                     transform=plt.gcf().transFigure, fontsize="large")
85
            plt.text(0.7, 0.74, r"$\sigma_{n-1}=$"+f"{cps_ecartype:.3e}",
86
                     transform=plt.gcf().transFigure, fontsize="large")
87
            plt.text(0.7, 0.71, r"$\sigma_{n}=$"+f"{cps_pecartype:.3e}",
88
                     transform=plt.gcf().transFigure, fontsize="large")
89
90
    plt.title(Titre)
91
    plt.xlabel('Coups')
92
    plt.ylabel('Effectif')
93
    plt.hist(liste_impulsion, bins=[
94
             i + 0.5 for i in range(m-1, M+1)], density=False, rwidth=0.8, color="blue")
95
    plt.pause(0.0001)
96
    plt.show()
97
98
Data.close()  # pour arrêter la lecture des données série
99
100
101
"""#Ecriture dans un fichier txt
102
lines=['N \t duree \n'] #première ligne du fichier txt
103
for i in range (len (liste_impulsion)):
104
    line = (str(liste_impulsion[i])+'\t'+ str(liste_duree[i])+'\n')
105
    lines.append(line)
106
107
fichier = open('data_arduino2.txt', 'w').writelines(lines) # création d'un nouveau fichier texte
108
"""
109

Bibliothèque et programme permettant de mesurer une dose

La documentation en ligne du module Geiger permet de télécharger une bibliothèque d'instructions permettant d'afficher :

  • le nombre de coups par minute (CPM), en moyenne glissante ;

  • le débit de dose en µS/h, en moyenne glissante.

Le programme par défaut affiche ces données dans le moniteur série. On peut ajouter un écran LCD pour une lecture plus simple et un compteur autonome.

Vous pouvez télécharger ci-dessous :