Contador Geiger Portátil con Arduino Nano: Construye tu Detector de Radiación
Componentes y materiales
- 1x Arduino Nano R3
- 1x Kit contador Geiger montado (ej. Banggood DIY Geiger Counter Kit con tubo GM)
- 1x Pantalla OLED color 0.96" 96x64 (SSD1331 SPI)
- 1x Placa cargador micro USB para batería 18650 (TP4056 o similar)
- 1x Batería Li-ion 18650 3.7V 4000mAh protegida recargable
- 1x Transistor BC547
- 1x Buzzer 12mm
- 1x Resistencia 1k Ω
Herramientas necesarias
- Impresora 3D (genérica)
Aplicaciones y servicios online
- Autodesk Fusion 360 (diseño carcasa)
- Arduino IDE
- CURA (slicer impresión 3D)
- ClickCharts (diagramas flujo)
- EasyEDA (diseño PCB)
- Fritzing (esquemáticos)
Sobre el proyecto
Este proyecto nació tras comprar un kit de contador Geiger montado en Banggood.
La idea era meter el kit en una carcasa impresa en 3D para tener un contador Geiger portátil y funcional. El resultado final se muestra abajo.
Paso 1: Diseño del sistema
El diseño del contador Geiger portátil se muestra en el diagrama de bloques.
El contador Geiger lleva una pantalla OLED color 0.96" que informa al usuario del CPM (cuentas por minuto, tasa de detección de eventos de ionización por minuto) y de la dosis equivalente calculada en µSv/h usando un factor de conversión simple de 151 (valor bibliográfico para el tipo de tubo Geiger-Müller usado). Ver también Wikipedia: Counts per minute.
El CPM mostrado resulta de calcular cuentas durante un minuto: se miden cuentas por segundo (CPS) y se almacenan en un array que cubre los últimos 10 segundos. El total de cuentas en esa ventana de 10 s se multiplica por 6 para obtener CPM.
El número de cuentas del último segundo se usa para mostrar una barra gráfica en la OLED, útil ante altas tasas o cambios rápidos al mover el detector sobre una fuente radiactiva.
El contador se alimenta con batería Li-ion 18650 recargable vía micro-USB. El puerto USB del Arduino Nano también queda accesible para actualizaciones de firmware. Un buzzer extra conectado a la placa del kit amplifica el sonido de las ionizaciones en el tubo GM.
Toda la electrónica va dentro de la carcasa 3D impresa. La pantalla OLED va en una caja separada encima. Ver imágenes del montaje completo en el proyecto original.
Paso 2: Montaje del conjunto Geiger
Materiales usados (con enlaces de compra):
- Arduino NANO: Tienda oficial
- Kit Geiger Counter: Banggood
- OLED 0.96" color 96x64: Banggood
- Cargador micro USB 18650: Banggood
- Batería 18650 3.7V 4000mAh: Banggood
- Transistor BC547, Buzzer 12mm, Resistencia 1k Ω
Diseño electrónico
El esquema del kit Geiger Counter y el esquema completo del montaje están en la documentación del proyecto. La alimentación 5V sale de la batería 18650 en la placa cargadora micro USB. Los 3.3V para la OLED se toman de esa misma placa.
El montaje en protoboard usado para pruebas y desarrollo de software con Arduino IDE se muestra en las fotos del proyecto.
Montaje mecánico y eléctrico
El ensamblaje de todas las piezas mecánicas y electrónicas se ve en las fotos. El contador portátil no tiene conexiones de cable externas. Para cargar la batería 3.7V hay una abertura en la carcasa para conectar temporalmente micro USB. También hay una conexión mini USB accesible para actualizar el firmware del Arduino Nano.
Paso 3: Diseño del software
El diagrama de flujo del diseño general del software del contador Geiger se muestra en el proyecto.
Las vistas en la pantalla OLED 0.96" son:
- CPM (cuentas por minuto) en rojo, con indicador "10 sec window"
- µSv/h en verde (calculado como CPM / 151)
- Barra gráfica roja inferior que muestra CPS (cuentas por segundo) en tiempo real
- Al encender: nivel de batería en magenta durante 3 segundos
El sketch completo de Arduino (unos 150 líneas, con muchos comentarios) se incluye a continuación:
/********* Proyecto desarrollado por Pierre Pennings (Diciembre 2019) *********
* Contador Geiger portátil usando kit montado, en carcasa 3D impresa.
* Arduino Nano cuenta impulsos del tubo Geiger-Müller en periodos de 10 s
* y muestra CPM medio en OLED 96x64 color. También muestra µSv/h (factor 151).
* La OLED muestra CPS momentáneo como barra roja móvil.
* Carcasa 3D contiene batería 18650 recargable que da 5V al Arduino y kit,
* y 3.3V para la OLED. Incluye interruptor encendido y buzzer externo.
* Al encender, muestra nivel de carga de la batería 18650 en pantalla color.
* Licencia GPL3+.
*********/
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>
// Conexiones OLED
#define sclk 13 // SCL (azul)
#define mosi 11 // SDA (blanco)
#define cs 10 // CS (gris)
#define rst 9 // RES (verde)
#define dc 8 // DC (amarillo)
#define LOGtime 1000 // Tiempo registro en ms (1 segundo)
#define Minute 60000 // Periodo 1 minuto para CPM
#define show endWrite
#define clear() fillScreen(0)
// Colores
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);
int Counts = 0; // eventos tubo GM dentro de LOGtime
unsigned long previousMillis = 0;
int AVGCPM = 0; // media móvil CPM ventana fija
int TenSecCPM = 0;
int units = 0, tens = 0, hundreds = 0, thousands = 0;
float Sievert = 0;
int COUNTS[10]; // array 10 periodos de 1 segundo
int t = 0;
void setup() {
Serial.begin(115200);
display.begin();
display.fillScreen(BLACK);
float Battery = analogRead(A3); // cable naranja
float BattPerc = 100 * (Battery / 770);
// Serial.print("battery value = "); Serial.println(Battery);
// Serial.print("battery percentage = "); Serial.println(BattPerc);
display.setCursor(4,4);
display.setTextSize(2);
display.setTextColor(MAGENTA);
display.println("Battery");
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++) COUNTS[x] = 0; // array a cero
attachInterrupt(0, IMPULSE, FALLING); // interrupción externa pin D2/INT0
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);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > LOGtime) {
previousMillis = currentMillis;
COUNTS[t] = Counts;
for (int y = 0; y < 10; y++) {
TenSecCPM += COUNTS[y]; // suma últimos 10 segundos
}
AVGCPM = 6 * TenSecCPM; // CPM = 6 * suma 10s
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); // limpia campo CPM
display.setCursor(4,20);
display.setTextColor(RED);
display.setTextSize(2);
display.println(AVGCPM);
display.fillRect(45,38,50,10,BLACK); // limpia campo µSv/h
display.setCursor(45,38);
display.setTextColor(GREEN);
display.setTextSize(1);
Sievert = (AVGCPM / 151.0);
units = int(Sievert);
tens = int((10*Sievert) - (10*units));
hundreds = int((100*Sievert) - (100*units) - (10*tens));
thousands = int((1000*Sievert) - (1000*units) - (100*tens) - (10*hundreds));
display.print(units); display.print("."); display.print(tens); display.print(hundreds); display.println(thousands);
display.fillRect(1,49,94,14,BLACK); // limpia barra CPS
display.fillRect(1,49,Counts,14,RED); // barra CPS
Counts = 0;
}
}
// Rutina de interrupción: cuenta impulsos del kit Geiger
void IMPULSE() {
Counts++;
}
La parte clave es la función de interrupción que se llama cuando un impulso en el tubo GM del kit Geiger dispara la salida INT (poniéndola LOW brevemente). La señal INT va al pin D2 (interrupción externa INT0 del Arduino Nano):
attachInterrupt(0, IMPULSE, FALLING);
La señal INT inicia la rutina IMPULSE() que incrementa Counts:
void IMPULSE() { Counts++; }
Cada 1000 ms:
Countsvuelve a 0- El array
COUNTS[]se rellena con cuentas del último segundo - Total de cuentas en 10 segundos = suma array × 6 → CPM en pantalla
- Dosis equivalente µSv/h = CPM / 151
- Barra roja en OLED basada en
Countsdel último segundo = CPS
Código
Archivo: Geiger_Counter.ino (incluido arriba completo)
Piezas 3D (archivos STL/OBJ)
- Carcasa para pantalla OLED 0.96":
display_geiger_rev04_v2_bsLHSDvTUU.3mf - Carcasa principal (tapa y base) diseñada en Fusion 360:
geiger_counter_housing_top__bottom_rev04_v1_cvCIwkO13j.objy STL
Esquemáticos
Diagrama de conexiones electrónicas disponible en la documentación del proyecto.
Proceso de manufactura
- Construye un reloj Numitron retro con Arduino: Simple, fiable y eficiente energéticamente
- Construye un Juego Giroscópico en Tiempo Real con Arduino Nano y Sensor MPU-6050
- Proyecto Dados Digitales Arduino: Construye tu Propio Generador de Números Aleatorios con LCD
- Mando USB para juegos DIY con Arduino – Construye tu propio gamepad de alto rendimiento
- Alcancía Inteligente: Controla un Aceptador de Monedas con Arduino Nano
- Construye un juego Tetris con Arduino Nano en matriz LED 16x8 DIY
- Controla un LED por Bluetooth con Arduino – Guía DIY paso a paso
- Controla Dos Motores Paso a Paso con Arduino Nano y Joystick - Tutorial Sencillo
- Construye un Contador Geiger-Müller Personalizado con Arduino, Elevador de Alta Tensión y Pantalla LCD 20x4
- Pixel Chaser: Juego LED Interactivo de Un Toque con Arduino Nano
- Construir una rueda medidora DIY precisa con Arduino Nano y encoder rotativo