Ручной дозиметр (Гейгер-счетчик) на Arduino Nano: сборка в 3D-корпусе
Компоненты и материалы
| Arduino Nano R3 | 1 |
| Готовый набор Гейгер-счетчика (с М-счетчиком, высоковольтный блок) | 1 |
| Цветной OLED-дисплей 0.96" 96×64 (SSD1331, SPI) | 1 |
| Плата зарядки micro USB для 18650 (TP4056 с защитой) | 1 |
| Аккумулятор 18650 3.7В 4000 мАч (защищенный) | 1 |
| Транзистор BC547 | 1 |
| Пьезоизлучатель (buzzer) 12 мм | 1 |
| Резистор 1 кОм | 1 |
Инструменты
- 3D-принтер
- Autodesk Fusion 360 (моделирование корпуса)
- Cura (слайсер)
Программное обеспечение для разработки
- Arduino IDE
- EasyEDA / Fritzing / ClickCharts — схемы и платы
О проекте
Начал после покупки готового набора Гейгер-счетчика на Banggood. Идея — разместить всё в 3D-печатном корпусе для ручного использования. Итог на фото.
Шаг 1: Системный дизайн
Блок-схема: Arduino Nano опрашивает выход INT Гейгер-кита (прерывание по спаду), считает импульсы за скользящее окно 10 сек, выводит CPM (имп/мин) и эквивалент дозы µSv/ч (коэф. 151 для данной М-трубки). OLED 96×64 цветной (SPI) показывает: CPM крупно, 10-секундное окно, µSv/ч, батарею, и барграф CPS (имп/сек) — полезен при быстрых изменениях/поиске источника.
Питание: 18650 в плате зарядки micro USB (выдает 5В для Nano и кента, 3.3В для OLED). Зарядка — через отверстие в корпусе. USB Nano доступен для перепрошивки. Доп. бузер на BC547 усиливает звук от кента.
Шаг 2: Сборка электроники
Схема готового кента (high-voltage генератор + М-трубка) и полная схема устройства в разделе Schematics. Макетная сборка для отладки ПО на фото.
Шаг 3: Механическая и электрическая сборка
Все модули помещаются в 3D-корпус без внешних проводов. Корпус в два куска (верх/низ) + отдельный бокс для OLED сверху. Отверстия: micro USB (зарядка), mini USB (прошивка Nano).
Шаг 4: Программное обеспечение
Алгоритм: прерывание INT0 (D2) инкрементирует счетчик. Каждую секунду (LOGtime=1000 мс) значение сбрасывается в кольцевой буфер COUNTS[10]. CPM = 6 × сумма буфера. µSv/ч = CPM / 151. На дисплее: CPM (красный), µSv/ч (зеленый), барграф CPS (красный), батарея при старте (маджента).
Полный скетч (Geiger_Counter.ino)
/********* Pierre Pennings, Dec 2019. GPL3+ *********/
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>
// OLED SSD1331 (SPI)
#define sclk 13 // SCL (синий)
#define mosi 11 // SDA (белый)
#define cs 10 // CS (серый)
#define rst 9 // RES (зеленый)
#define dc 8 // DC (желтый)
#define LOGtime 1000
#define Minute 60000
#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;
unsigned long previousMillis = 0;
int AVGCPM = 0, TenSecCPM = 0;
int units=0, tens=0, hundreds=0, thousands=0;
float Sievert = 0;
int COUNTS[10];
int t = 0;
void setup() {
Serial.begin(115200);
display.begin(); display.fillScreen(BLACK);
// Батарея на A3 (оранжевый провод)
float Battery = analogRead(A3);
float BattPerc = 100.0 * (Battery / 770.0);
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;
attachInterrupt(0, IMPULSE, FALLING); // 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;
TenSecCPM = 0;
for (int y=0; y<10; y++) TenSecCPM += COUNTS[y];
AVGCPM = 6 * TenSecCPM;
TenSecCPM = 0;
t++; if (t > 9) t = 0;
display.fillRect(4,20,90,17,BLACK);
display.setCursor(4,20); display.setTextColor(RED); display.setTextSize(2); display.println(AVGCPM);
display.fillRect(45,38,50,10,BLACK);
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);
display.fillRect(1,49,Counts,14,RED); // барграф CPS
Counts = 0;
}
}
void IMPULSE() { Counts++; } // ISR на INT0 (D2)
3D-модели корпуса
- Корпус дисплея (отдельный бокс):
display_geiger_rev04_v2_bsLHSDvTUU.3mf - Основной корпус (верх + низ, Fusion 360):
geiger_counter_housing_top__bottom_rev04_v1_cvCIwkO13j.obj/ STL
Схемы
Полная схема подключения в разделе Schematics.
Производственный процесс
- Ретро-часы на индикаторах Numitron с Arduino: просто, надёжно, экономно
- Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
- Цифровые кости на Arduino: генератор случайных чисел с LCD-дисплеем и кнопкой
- DIY USB-геймпад на Arduino: собственный высокопроизводительный контроллер
- Умная копилка: управление монетоприёмником на Arduino Nano
- Tetris на Arduino Nano: самостоятельная сборка 16×8 LED-матрицы на 74HC595
- Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
- Управление двумя шаговыми двигателями через джойстик на Arduino Nano — простой урок (Visuino)
- Сборка собственного счётчика Гейгера‑Мюллера на Arduino, HV Boost и LCD 20x4
- Pixel Chaser: игра на один тап с NeoPixel Ring и Arduino Nano