Програмне опрацювання переривань від імпульсів, які генерує лічильник Гейгера-Мюллера для розрахунку еквівалентної потужності іонізуючого випромінювання.

Вступ

  1. Активний стан – логічна одиниця
  2. Реєстратор імпульсів і Трубка Гейгера-Мюллера
  3. Форма імпульсів з реєстратора GGreg20_V1 з трубкою СБМ-20
  4. Висновок
  5. Перерахунок імпульсів у потужність випромінювання
  6. Післямова

Публікація розглядає аспекти розробки спеціалізованого ISR (interrupt service routine, interrupt handler) – опрацьовувач переривань являє собою функцію зворотного виклику (callback function) в середовищі NodeMCU/Lua, як реакцію на зміну зовнішнього по відношенню до порту вводу/виводу контролера ESP8266 стану. У тіло функції зворотного виклику розміщується код, котрий необхідно виконати у процесі опрацювання зміни стану GPIO, щойно така зміна виникла.

Оскільки будь-який контролер очікує на вході якісний сигнал квадратної форми, а трубка Гейгера-Мюллера видає на вихід сигнал сформований розрядом, виникає задача правильного програмного підрахунку імпульсів, що є основою для розрахунку потужності іонізуючого випромінювання.

Далі у статті докладно розглянемо шляхи подолання цієї та інших супутніх проблем.

Розглядати часткові випадки і наводити приклади будемо у середовищі Lua, спираючись на наш комерційний програмний модуль radCounter.

Активний стан – логічна одиниця

У сучасній міжнародній літературі активний стан прийнято позначати як active-high або active-low

active-high означає, що логічна одиниця за задумом розробника/виробника виникає на дискретному вході чи виході тоді, коли значення рівня фізичної величини, котра використовується для кодування дискретних станів, стає вищим встановленого порога. 

active-low – аналогічно, але навпаки: стан дискретного рівня вважається активним (тотожним логічній одиниці), якщо значення рівня кодуючої фізичної величини стає меншим встановленого абсолютного порога.

Наприклад, 

Припустимо, що у нас є пристрій з виходом INT і контролер з входом GPIO. Ці два порти з’єднано сигнальним провідником.

Найчастіше, кодуючою фізичною величиною виступає напруга. 

У документації виробник вказує характеристики спеціального фізичного виходу переривання (INT): 

  • Напруга живлення Vdd = 3.3V;
  • за еквівалентний рівень логічної одиниці приймаємо аналоговий рівень > 0.7 * Vdd, V;
  • за еквівалентний рівень логічного нуля приймаємо аналоговий рівень < 0.3 * Vdd, V;
  • дискретна логіка є наступною: active-low.

Це означає, що:

  • пристрій, котрий “генерує” переривання, подасть на певний час на свій вихід INT рівень напруги 0.7 вольт, що є відповідно до документації нижче порога 0.3 * 3.3 = 0.99 вольт;
  • цей рівень (0.7V) у себе на вхідному GPIO зареєструє контролер і оцінить його як “низький”, бо відповідно до його специфікації, цей рівень напруги теж сприймається як “низький”;
  • в залежності від налаштованої дискретної логіки (а ми налаштували active-low) на порту GPIO, контролер запустить обробник переривання, так як “низький” – є активним – тобто рівнем TRUE, тобто потрібно обробляти переривання. 🙂

Зазвичай, у мікроелектроніці загальноприйнятим активним рівнем є “низький”. Але бувають виключення з цього правила, як з точки зору апаратного дизайну, так і з точки зору задачі, що необхідно вирішити. А тому, виробники мікроконтролерної техніки передбачають щонайменше декілька різних активних станів на вхідних портах, що необхідно налаштувати. 

Ще раз: підпорядковані пристрої можуть генерувати активний рівень по-різному. Тому контролери повинні вміти обробляти активний рівень на вході різними методами.

Контролер ESP8266 на рівні Lua, підтримує чотири типи обробки переривань:

  • зростаючий фронт;
  • спадаючий фронт;
  • низький рівень;
  • високий рівень.

Рис.1 Типи режимів роботи опрацьовувача переривань NodeMCU/ESP8266

Примітка: за обробку переривань в NodeMCU відповідає метод gpio.trig(). Документацію можливо знайти тут: gpio.trig()

В залежності від апаратної та програмної архітектури контролера, а також від реалізації виробником механізмів обробки на низькому рівні, апаратний watchdog переривань може по-різному обробляти одну і ту ж прикладну зміну стану на вході.

Наведемо приклад. Для прикладу використаємо кнопку D3 Flash, що є на платі NodeMCU.

Для того, щоб підключити опрацьовувач переривань, напишемо простий код.

Натиснемо Flash, декілька разів (ми натиснули 4 рази), щоб перевірити, як працює наш скрипт:

Як можна бачити, кнопка D3 в натиснутому стані дає level == 0; eventcount == 1. Тобто логіка кнопки працює в режимі active-low, брязкіт відсутній, адже апаратний API дає нам eventcount 1 для кожного натискання.

Що буде, якщо ми натиснемо кнопку і не будемо її відпускати?

0 654602962 1 — з’явилася лише ще одна подія обробника. При відпусканні події немає.

Тепер дещо змінимо наш тестовий код:

і натиснемо на кнопку знову декілька разів:

такий код нам дав 121 подію при всього чотирьох натисканнях на кнопку.

Що ж буде, коли ми натиснемо кнопку і будемо її тримати?

Аналогічна історія – події генеруються зі швидкістю, котру тільки вміє розвивати апаратний обробник на порту. У нас вийшло близько 5000 мікросекунд == 5 мілісекунд між подіями, а це аналогічно частоті 200 гц.

Зауважимо, що якщо розігнати центральний процесор ESP8266 з 80МГЦ до 160МГЦ командою node.setcpufreq(node.CPU160MHZ):

то обробка переривань на порту в такому режимі відбувається в середньому кожні 2.6 мілісекунди, що дорівнює частоті 384.6 ГЦ.

Таким чином, у цьому прикладі ми побачили, що одне й те ж натискання кнопки, або інший аналогічний інформаційний сигнал, може оброблятися на порту GPIO по різному, відповідно до встановлених параметрів. Тому у даній статті ми будемо розглядати лише ті режими роботи, котрі нам підходять для реєстрації імпульсів з трубки Гейгера-Мюллера, а саме “up” та “down” що принято в прошивці NodeMCU для переднього та заднього фронтів відповідно. Цим типам обробки відповідають діаграми Рис.1 Type A і Рис.1 Type B.

З теоретичною частиною розібралися і навіть провели необхідні експерименти. Переходимо до імпульсів з реєстратора імпульсів з встановленою трубкою Гейгера-Мюллера.

Реєстратор імпульсів і Трубка Гейгера-Мюллера

Для вимірювання еквівалентної потужності іонізуючого випромінювання ми застосовуємо апаратний модуль українського виробника GGreg20_V1. Серед інших, ми знайшли на сайті комплект №1, котрий вже включає до складу трубку СБМ-20. Що дуже зручно, адже ця трубка є однією з найпопулярніших. 

Таку популярність СБМ-20 отримала не кількістю, а своїми зручними для побутового застосування технічними характеристиками. Наведемо лише деякі з них, котрі нам важливо розглянути і цій статті:

  • швидкість рахунку при потужності 4 мкР ∙ с-1 від джерела 137Cs від 240 імп ∙ с-1 до 280 імп ∙ с-1;
  • чутливість – від 60 імп / мкР до 75 імп / мкР;
  • діапазон відхилення чутливості – не більше ± 20%;
  • рівень натурального фону (Nф) – 60 імп / хв.;
  • мінімальний мертвий час при 400 В – 190 мкс

Реєстратор імпульсів GGreg20_V1 забезпечує необхідний режим живлення для трубки СБМ-20 і формує на вихід узгоджені за напругою та тривалістю імпульси, котрі ми подаємо на порт GPIO контролера ESP8266 (підійде як модуль ESP8266-12 з платою-програматором, так і плата NodeMCU з модулем ESP8266-12E/F) і обробляємо переривання, що виникають за умови надходження імпульсів.

Форма імпульсів з реєстратора GGreg20_V1 з трубкою СБМ-20

Схематично, імпульси, що приходять на порт GPIO можемо зобразити так, як це показано на Рис.2.

З урахуванням викладеного раніше, у розробника є щонайменше два варіанти, коли саме опрацьовувати вхідний імпульспо передньому фронту, або ж по задньому фронту. Якщо виходити з дискретної логіки пристрою GGreg20_V1, котрим ми послуговуємося, нам необхідно було використовувати саме передній фронт імпульса, адже логіка виходу реєстратора active-low та в стані спокою на вході контролера формується високий рівень, тобто для програмного коду – активний рівень має бути низький.

Рис.2 Схематична форма імпульсів від реєстратора на базі трубки Гейгера-Мюллера

Так і вчинимо – налаштуємо метод gpio.trig() на обробку переривання з параметром “down”. Далі наводимо журнал роботи обробника переривань нашого програмного продукту radCounter з розширеними даними налагодження. 

Примітка: з описом продукту radCounter можливо ознайомитися у магазині за посиланням: Модуль лічильника імпульсів

Для виводу журналу обробки окремих імпульсів у консоль, запустимо модуль radCounter наступним чином:

спершу зареєструємо у системному оточенні NodeMCU новий модуль radCounter:

а далі, відповідно до синтаксису:

де 

pin номер піну контролера для отримання імпульсів
dir фронт спрацювання ( 1 – передній, 0 – задній )
time_out час одиничного циклу вимірювання, мілісекунд (для трубки СБМ-20 рекомендуємо 60)
lo_fltнизькорівневий фільтр ( ‘ON’ – вмикання, ‘OFF’ – вимикання )
hi_fltвисокорівневий фільтр ( ‘ON’ – вмикання, ‘OFF’ – вимикання )
dbgвивод у консоль розширених даних діагностики ( 1 – вмикання, 0 – вимикання )

запустимо публічний метод ініціалізації/налаштування модуля radCounter:

з такими параметрами radCounter буде опрацьовувати переривання на вході D4, дискретна логіка буде active-low (задній фронт), цикл вимірювання мікрозівертів на годину буде відбуватися протягом однієї хвилини, всі наявні фільтри вимкнено, режим діагностики активовано.

В консолі спостерігаємо наступне:

де

lvl рівень GPIO, з котрим відбулося спрацювання і запуск функції опрацювання переривання
ts відмітка системного часу
evcntкількість спрацювань на апаратному рівні, якщо це число не дорівнює 1, то ймовірно присутній брязкіт
true countнакопичувальний лічильник врахованих у даному циклі вимірювання імпульсів

через 60 секунд, по завершенню циклу вимірювання відбувається розрахунок результатів першої хвилини роботи, де:

avgLvlковзне середнє з п’яти хвилинних циклів вимірювання, мікрозівертів на годину
minмінімальне зареєстроване значення, мікрозівертів на годину
maxмаксимальне зареєстроване значення, мікрозівертів на годину
doseнакопичена доза від початку роботи, мікрозівертів
impsнакопичена кількість імпульсів від початку роботи
minsнакопичена кількість хвилин (тобто циклів вимірювання), що пройшло від початку роботи

Уважний читач неодмінно звернув увагу, що в наведеному журналі вимірювання, параметр lvl іноді приймає дивні значення, а саме “1”. І це при тому, що ми налаштували дискретну логіку як active-low, і в такому разі спрацювання мало б відбуватися лише з lvl “0”.

Ми маємо припущення, що проблема криється у наступному:

Оскільки вихідний тракт реєстратора імпульсів GGreg20_V1 ніяк не втручається і не спотворює форму сигналів з трубки СБМ-20, а це потрібно для того, щоб розробник був впевненим у своїх розрахунках, ми бачимо в журналі спрацювань radCounter нерівності у формі розрядів, що відбуваються в трубці. І таким чином контролер ESP8266, маючи порти з високою швидкодією на рівні заліза, встигає зареєструвати перехідні процеси і рахує їх як окремі імпульси – хибні-позитивні (false-positive) спрацювання.

А тепер запустимо radCounter у іншому режимі:

Як видно, маємо зовсім іншу картину. Немає хибних спрацювань. Рівень потужності іонізуючого випромінювання в межах притаманного для Києва, де ми і проводимо вимірювання.

Примітка: всі вимірювання в статті порівнювалися із вимірами другого, сертифікованого, професійного дозиметра.

Висновок

Хоча апаратний реєстратор імпульсів розроблено для active-low логіки, ми успішно і якісно застосували програмний модуль radCounter в логіці active-high

Перерахунок імпульсів у потужність випромінювання

Перерахунок виконується відповідно до документації виробника на трубку Гейгера-Мюллера. Трубка СБМ-20, яки зазначили раніше, має наступні характеристики швидкості підрахунку імпульсів:

при потужності 4 мкР/с від джерела 137Cs від 240 імп/с до 280 імп/с. (а)

також, виробник наводить коефіцієнт:

рівень натурального фону (Nф) – 60 імп / хв (б)

Спробуємо виконати розрахунки з першим виразом, що позначено (а). Для того щоб перейти до практичних розрахунків у програмному забезпеченні, спочатку виконуємо математичні перетворення:

  1. візьмемо середнє з (а) => Імп = (240 + 280) / 2 = 260
  2. 4 мкР/с = 260 імп/c => 1 мкР/с = 65 імп/с
  3. від мкР/с перейдемо до мР/с => 1 мР/с = 65000 імп/с
  4. від мР/с перейдемо до мР/год, для цього поділимо 65000 поділимо на 3600:
  5.   1 мР/год = ~ 18 імп/с
  6. від імп/с перейдемо до імп/хв => 1 мР/год = 1080 імп/хв
  7. від мР/год перейдемо до мкЗв/год => 1 мкЗв/год = 108 імп/хв
  8. розрахуємо значення одного імпульсу на хвилину у мкЗв/год:
  9. коефіцієнт перетворення 1 імп/хв = 0.0092 мкЗв/год (в)

Алгоритм застосування формули (в) наступний:

Щоб отримати значення еквівалентної потужності іонізуючого випромінювання, потрібно кількість імпульсів, що отримано протягом шестидесяти секундного циклу вимірювання, необхідно помножити на коефіцієнт перетворення:

мкЗв/год = імп/хв * 0.0092 (г)

Перевіримо отриманий результат за допомогою виразу (б)

60 * 0.0092 = 0.552 мкЗв/год

Як можна бачити, 0.552 мкЗв/год значно перевищує прийняту зараз норму потужності фонового випромінювання у 0.3 мкЗв/год, що свідчить або про неточності у документації з минулого століття, або про різночитання у означенні що таке натуральний фон (Nф), або ж про відхилення цивільного застосування від цілового призначення трубки, для якого і було розроблено документацію.

Зауважте, що для трубки Гейгера-Мюллера відмінної від СБМ-20, необхідно виконувати індивідуальний розрахунок відповідно до технічних характеристик заявлених виробником. Отриманий коефіцієнт перерахунку (г) підходить лише для СБМ-20 і відповідає наявній документації. 

Фільтри – low-pass та high-pass

Ми не змогли під час підготовки матеріалів для статті відтворити на практиці випадки, коли потрібно застосовувати фільтри передбачені у radCounter – і це добре, бо це означає, що залізо працює як треба і в нашому тестовому стенді брязкоту немає. А тому, ми наведемо теоретичні відомості про ці фільтри, без скріншотів чи журналів.

Фільтри виникли під час процесу налагодження кількох стендових комплексів вимірювання радіації з іншими трубками в тому числі.

lo_flt – це фільтр, котрий працює на низькому рівні API, і дозволяє відкинути хиби за яких evcnt (дивись вище) має значення більше одиниці. Тобто є брязкіт на GPIO.

hi_flt – це фільтр, котрий на високому рівні (тобто на рівні скриптових алгоритмів) відкидає імпульси, що прийшли через час, що є меншим за час нечутливості (deadtime) трубки. Трубка СБМ-20 просто не взмозі, відповідно до настанов виробника, надсилати імпульси протягом 190 мікросекунд від попереднього імпульса.

Післямова

Ми розглянули процес розробки опрацьовувача переривань, навели приклади і звернули увагу на виклики що постали свого часу перед нами, провели практичні досліди, розглянули наш підхід у комерційних продуктах, надали підказки із розв’язування проблем,  зробили прив’язку матеріалів до характеристик і особливостей трубки Гейгера-Мюллера.

Сподіваємося, що цей матеріал допоможе вам у програмуванні власного програмного коду вимірювача потужності іонізуючого випромінювання.

Якщо ж вас зацікавив наш комерційний програмний модуль radCounter, будь-ласка, замовляйте!

Купуте українське, друзі!