Contador Geiger v2
Basado en el realizado en el año 2016. Se mantiene la parte de alto voltaje y se sustituye la placa del microprocesador por un Nodemcu D1 Mini, la pantalla a una de 2,2 pulgadas 240x320 pixel y programación Arduino en vez de LUA.
La idea no es hacer medidas puntuales de radiación, sino un seguimiento a lo largo del día. Se presentan medidas cada 5' con la media por minuto (CPM). Es decir, 6 por hora x 24h =288 presentaciones en pantalla.
Lo normal es recibir con este tubo SBM-20 entre 15 y 25 "click" por minuto que corresponden a la radiación natural de fondo.
En los esquemas no está representado la parte de alto voltaje del año 2016. El WEMOS esta sobre elevado en un zócalo tipo Arduino que permite poner debajo el condensador, las 3 resistencia y el transistor. Y para dejar mas espacio, Rx, Tx, RST y A0 no tienen zócalo.
La pantalla está en una placa aparte, en ella el pin de iluminación está unido al de 3,3v y el CS a masa. Asi nos ahorramos dos hilos al WEMOS.
El código es muy simple y admite la mejora de guardar los datos de la media del día en una base de datos en el NAS.
//Geigerv2 Joaquín Paredes 2022 www.jopapa.me
#include <Adafruit_GFX.h> // include Adafruit graphics library
#include <Adafruit_ILI9341.h> // include Adafruit ILI9341 TFT library 240x320
#define TFT_CS D2 // TFT CS pin is connected to NodeMCU pin D2
#define TFT_RST D3 // TFT RST pin is connected to NodeMCU pin D3
#define TFT_DC D4 // TFT DC pin is connected to NodeMCU pin D4
// initialize ILI9341 TFT library with hardware SPI module
// SCK (CLK) ---> NodeMCU pin D5 (GPIO14)
// MOSI(DIN) ---> NodeMCU pin D7 (GPIO13)
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
const int inputgeiger = D1;
//unsigned long getDataTimer = 0;
int i=0;
//int valor=0;
volatile int CPM=0; int mapCPM;
unsigned long intervalo = 300000; //5'
unsigned long millisAnterior = 0;
int FactorConversion = 175;
//unsigned int intervalLED =150;
//unsigned long interpLED;
const byte LED = D6;
const byte Buzzer = D8;
// Funcion cuando se produce la interrupcion.
void IRAM_ATTR pulso_al_1() {
CPM++;
digitalWrite(D6, HIGH); //Pulso LED, usar de alto brillo.
digitalWrite(D8, LOW);
delay(1); //¡¡No aumentar el delay()!! bloquea las interrupciones.
digitalWrite(D8, HIGH);
digitalWrite(D6, LOW);
// Serial.println("Pulso");
}
void setup() {
// Serial.begin(9600);
tft.begin();
pinMode(LED, OUTPUT);
pinMode(Buzzer, OUTPUT);
pinMode(inputgeiger, INPUT);
attachInterrupt(digitalPinToInterrupt(inputgeiger), pulso_al_1, FALLING);
millisAnterior =millis();
textInicio();
textFijo();
textHoras();
}
void loop(void){
if(millis() - millisAnterior >= intervalo) { //Cada 5' reinicia conteo
testlines();
millisAnterior=millis();
CPM=0;
}
}
void testlines() {
CPM=CPM/5; //Ajusta datos a Click Por Minuto CPM
mapCPM = map(CPM, 0, 50, 0,232); //Ajusta a display 240x320
// Serial.print("CPM: ");
// Serial.println(CPM);
i++;
if (i <= 288){ //Máximo número de lecturas para 24 horas
tft.setRotation(0);
tft.drawLine(0, i, mapCPM, i, ILI9341_BLACK);
}
textHoras(); //Repone horas en linea inferior
//Borra espacio para valor de CPM y uSv/hr
tft.setRotation(0);
for(int b=0; b<=210; b++){
tft.drawLine(225, b, 240, b, ILI9341_WHITE); //(y,x, y', x')
}
tft.setRotation(1);
tft.setTextSize(2);
tft.setTextColor(ILI9341_BLACK);
tft.setCursor(0, 0); tft.println("CPM:"); tft.setCursor(45, 0); tft.println(CPM);
tft.setCursor(90, 0); tft.println("uSv/hr:");
tft.setCursor(170, 0); tft.println(CPM/float(FactorConversion),2);
}
void textInicio() {
tft.setRotation(1);
tft.fillScreen(ILI9341_WHITE);
tft.setCursor(12, 60);
tft.setTextColor(ILI9341_RED);
tft.setTextSize(4);
tft.println(" Geiger");
tft.setCursor(11, 120);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.println(" Grafica de 24h cada 5'");
tft.println(" de medias por minuto");
tft.setCursor(0, 170);
tft.println(" Escala:cuentas por minuto");
delay(5000);
}
void textFijo(){ //Eje y
tft.setRotation(1);
tft.fillScreen(ILI9341_WHITE);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(294, 192);
tft.println("10");
tft.drawLine(0, 195, 290, 195, ILI9341_BLUE); //(x,y,x',y')
tft.setCursor(294, 144);
tft.println("20");
tft.drawLine(0, 147, 290, 147, ILI9341_BLUE); //(x,y,x',y')
tft.setCursor(294, 96);
tft.println("30");
tft.drawLine(0, 99, 290, 99, ILI9341_BLUE); //(x,y,x',y')
tft.setCursor(294, 48);
tft.println("40");
tft.drawLine(0, 51, 290, 51, ILI9341_BLUE); //(x,y,x',y')
tft.setCursor(294, 0);
tft.println("50");
tft.drawLine(220, 3, 290, 3, ILI9341_BLUE); //(x,y,x',y')
}
void textHoras(){
//Lineas verticales
tft.setRotation(0);
for(int i=24; i<=288; i=i+24){
tft.drawLine(0, i, 240, i, ILI9341_BLUE); //(y,x, y', x')
}
// horas en x
tft.setRotation(1);
for(int z=232; z<=240; z++){
tft.drawLine(0, z, 320, z, ILI9341_BLACK);
}
//horas eje x
tft.setTextSize(1);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(70, 233); tft.println("6");
tft.setCursor(140, 233); tft.println("12");
tft.setCursor(212, 233); tft.println("18");
tft.setCursor(282, 233); tft.println("24h");
}