Ввиду планируемого запуска АЭС в Беларуси, озаботился я радиационным фоном. Решил собрать дозиметр и вышел в интернет с этим вопросом. Вторая ссылка в google по запросу «дозиметр на arduino» привела меня на данный сайт, где автор утверждает, что все прекрасно работает и считает. Даже красивый лейбл на дисплей прикрепил. Ну что ж, заказал детали на али, запасся терпением и начал ждать.
Детали пришли. Я все собрал и запустил. Да, все работает, только не считает датчик ионы. Мне стало грустно и начал искать в интернете правильную схему включения датчика. Попробовав каждую что нашел, почитав комментарии что все они полная ерунда, решил собрать схему, что нашел на хабре .
Осциллограф показывает, что импульсы идут, а это хороший знак – я в процессе опытов не спалил датчик СТС-5. Дальше подключаю buzzer, который начинает пищать от 5В, и о чудо, он пикает. Начинаем усложнять схему подключения и подключаю все это дело через Arduino. Опять все работает.
Воодушевленный я начал писать свой код работы, т.к. код автора, по чьей схеме я первоначально хотел собирать мне жутко не понравился (имхо, отдельную библиотеку для обработки кнопки — это дикость…). Ну да ладно, о вкусах не спорят.
Углубился в теорию. Самое сложное это было понять, как связать пик-пик buzzer-а, с уровнем радиации. Полазив в интернете я нашел статью на англоязычном форуме, где автор показатель CPM (количество импульсов в минуту) умножает на загадочный коэффициент и переводит все это дело в микро зиверты в час. Изучив данную тему (в коде есть ссылка на неё), я нашел коэффициент для своего датчика, ну и решил: почему бы не использовать их всех. Пускай схема идет в массы, пользователь сам решил какой датчик использовать.
Через некоторое время я дописал код, прошелся напильником и готов представить предрелизную версию (в релизной кроме использования китайского модуля DC-DC up на 400В, можно будет включить генерацию ШИМ с Arduino и намотать/найти где то повышающий трансформатор.
Логика работы программы следующая: после включения выводится таймер на 60 секунд (именно столько времени должен идти отсчет для подсчета импульсов), после выводится текущий фон в мкЗв/ч, CPM и сколько импульсов получается в течении минуты. Обработка полученного сигнала делал через прерывания. Все просто.
Представляю Вашему внимание мой код и схему.
p.s. берегите глаза.
Спойлер
Код: Выделить всё
#define schet 2 //желательно не менять. Если очень надо, то https://alexgyver.ru/lessons/interrupts/
#define buzz 9
#define batIn A1
#define detectorName 4 // 1-SBM20, 2-SI29BG, 3-SBM19, 4-STS5, 5-SI22G, 6-SI3BG, 7-SBM21, 8-LND712, 9-SBT9, 10-SI1G.
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 7, 6, 5, 4, 3); // (RS, E, DB4, DB5, DB6, DB7)
int flag = 0, temp = 0, tikTak = 0, batLvl = 0;
int temp1 = -1, tikTak1 = -1, batLvl1 = -1, SPM1 = -1; //чтобы экран часто не обновлять
volatile int SPM = 0;
float type = 0, mkSv = 0, mkSv1 = -1;
unsigned long previousMillis = 0;
const long interval = 60000; //SPM 60 sec
unsigned long previousMillis1 = 0;
const long interval1 = 100; //power on buzzer 0.2 sec
unsigned long previousMillis2 = 0;
const long interval2 = 1000; //отсчет до вывода инфы
boolean calculation = false, timer = true;
void setup() {
pinMode(schet, INPUT);
digitalWrite(schet, INPUT_PULLUP);
pinMode(buzz, OUTPUT);
digitalWrite(buzz, LOW);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(schet), trigger, FALLING);
switch (detectorName) {//https://www.uradmonitor.com/topic/hardware-conversion-factor/
case 1:
type = 0.006315;
break;
case 2:
type = 0.010000;
break;
case 3:
type = 0.001500;
break;
case 4:
type = 0.006666;
break;
case 5:
type = 0.001714;
break;
case 6:
type = 0.631578;
break;
case 7:
type = 0.048000;
break;
case 8:
type = 0.005940;
break;
case 9:
type = 0.010900;
break;
case 10:
type = 0.006000;
break;
}
lcd.begin(16, 2);
tikTak = interval / 1000;
// pesent=
checkBat();
}
void trigger() { // считаем количество срабатываний датчика
flag = 1;
SPM++; //считаем количество импульсов в минуту
digitalWrite(buzz, HIGH);
previousMillis1 = millis();
}
void loop() {
unsigned long currentMillis = millis();
if ((currentMillis - previousMillis1 >= interval1) && (flag == 1)) { //раз в интервал выключаем пищалку
digitalWrite(buzz, LOW);
flag = 0;
}
if (currentMillis - previousMillis >= interval) { //раз в интервал обнуляем SPM
previousMillis = currentMillis;
temp = SPM;
SPM = 0;
calculation = true;
checkBat();
}
if ((tikTak > 0) && ((currentMillis - previousMillis2) >= interval2)) {
previousMillis2 = currentMillis;
tikTak--;
}
if (tikTak == 0) {
timer = false;
}
if (calculation == true) {
mkSv = temp * type;
calculation = false;
}
if ((SPM1 != SPM) || ( tikTak1 != tikTak) || (temp1 != temp) || (batLvl1 != batLvl) || (mkSv1 != mkSv)) {
lsdOut();
}
}
int checkBat() {
batLvl = (analogRead(batIn) * 5.0 / 1024.0 - 2.8) * 100 / 1.4;
if (batLvl > 99) batLvl = 99;
if (batLvl < 0) batLvl = 0;
}
void lsdOut() {
lcd.clear();
lcd.setCursor(0, 0);
if (timer) {
lcd.print("Wait");
lcd.setCursor(5, 0);
if (tikTak >= 10) {
lcd.print(tikTak);
} else {
lcd.print("0");
lcd.print(tikTak);
}
lcd.print("s");
} else {
lcd.print("SPM");
lcd.setCursor(4, 0);
lcd.print(temp);
}
lcd.setCursor(9, 0);
lcd.print("bat");
lcd.setCursor(13, 0);
lcd.print(batLvl);
lcd.setCursor(15, 0);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print(mkSv);
lcd.setCursor(5, 1);
lcd.print("mkSv/h");
lcd.setCursor(13, 1);
lcd.print(SPM);
{
tikTak1 = tikTak;
temp1 = temp;
batLvl1 = batLvl;
mkSv1 = mkSv;
SPM1 = SPM;
}
}
Спойлер
Всем спасибо за внимание
- Вложения
-
- схема.JPG
- Схема
- (247.35 КБ) 630 скачиваний



