ArDos / дозиметр, часть №1

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

Собрал себе тоже дозиметр на Arduino. Простенький - пока без плюшек в виде графика, меню настроек и прочего..

https://www.youtube.com/watch?v=0TRqcrwA2MI - внешний вид без корпуса

https://www.youtube.com/watch?v=zN0SDuAx4Wc - в работе.

Если интересно выложу скетч.

tekagi
tekagi аватар
Offline
Зарегистрирован: 07.10.2016

Выкладывайте, лишним точно не будет. Преобразователь на блокинге без обратной связи?
Олед много оперативки съедает, с функционалом особо не разгуляешься.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019
// V0.4
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define PIN_BUZ		9	// пин пищалки
#define NTUBE		3	// число трубок гейгера в дозиметре
#define TIMEREG		34200	// длительность регистрации имрульсов в замере mS для трубки СБМ20 (К~0.57 CPM)
#define MAX_BUF_IMP	20	// max размер буфера замеров импульсов
#define MAX_R_SRD	50	// max число итераций для усреднения ( хоть тыща)
#define DELITEL		20	// Делитель регистрации - ускорение замера - потеря точности ( 10, 20, 40)
				// timeReg = TIMEREG / NTUBE / DELITEL;

Adafruit_SSD1306 display(128, 64, &Wire, 4);
volatile unsigned long nImp = 0;    // счетчик в обработчике INT0
bool fReset = false,                // флаг сброса данных замеров
	 fDisplay = false,	    // флаг показа данных
	 fSetup = false;	    // флаг настройки

byte nKey = 0,			// номер нажатой кнопки
     prevKey = 0,		// номер предыдущей нажатой кнопки
     modeDisp = 0,		// режим отображения BASE, COUNTER, GRAPH10, GRAPH100, TEST, VBAT, SETUP
     modeShet = 0;		// режимы работы - NORM, COUNT, SETUP

unsigned int  vBat;			// напряжение аккумулятора
unsigned int  bufImp[MAX_BUF_IMP];	// буфер импульсов
unsigned long impRad = 0,		// доза по импульсам
	prevRad = 0,		        // предыдущая доза
	sumRad = 0,		        // сумма доз
	usrRad = 0,		        // усредненная доза
	maxRad = 0,		        // максимальный замер в серии - для графика
        nZamerSer = 1,	                // номер замера в серии
        numUsr = 1,		        // номер замера для усреднения
	time1,
	time2,
	temp,
	iBuf;				// текущий индекс буфера импульсов

unsigned long tStart,    // время начала замера серии
              tCurCyc,         // текущее время в замере  
              tKey = 0,         // время нажатия кнопки
	      timeReg;	     // длительность регистрации импульсов в замере

void setup() {
	//Serial.begin(115200);
	pinMode(A6, INPUT);
	pinMode(2, INPUT);
	pinMode(4, INPUT);
	pinMode(5, INPUT);
	pinMode(6, INPUT);
	pinMode(7, INPUT);
	pinMode(9, OUTPUT);
	display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
	display.setTextColor(WHITE);  
	DisplayLogo();   
	attachInterrupt(0, Int0Count, FALLING); // импульс с трубки на пин2 INT0 прерывания 
	timeReg = TIMEREG / NTUBE / DELITEL;
	//tone( PIN_BUZ, 440,100);
	//Serial.println(" setup ok");
}
void loop() {
	uint8_t iMax;
	unsigned long impSum;
	fReset = false;
	vBat = map( analogRead(A6), 0, 1023, 0, 500);	// напряжение аккумулятора
	if ( numUsr == 1) {
		tStart = millis();						// время начала замера для начального замера
		nImp = 0;								// обнуление счетчика импульсов трубки
	}
	for ( iBuf=0; iBuf<MAX_BUF_IMP; iBuf++) {		// замер и вывод данных на экран в цикле
		/////////////////////////////////////
		// ожидание окончания замера
		do {
			tCurCyc = millis() - tStart;
			GetKey();							// опрос кнопок
			ProcKey();						// обработка по нажатию
		} while( tCurCyc < timeReg);				// пока время замера не вышло
		/////////////////////////////////////
		//TestTimeZamer();
		temp = nImp;							// количество импульсов замера в temp
		bufImp[iBuf]=temp;					        // количество импульсов замера в буфер накопления
		tStart = millis();					        // время начала следующего замера 
		nImp = 0;								// обнуление счетчика импульсов в замере
//		Serial.print( temp);Serial.write(' ');
		if ( temp > 8) tone( PIN_BUZ, 3600, 100);	// сигнал - что то не так..
		if ( nZamerSer < MAX_BUF_IMP)						
			iMax = nZamerSer;					// номер замера в серии
		else iMax = MAX_BUF_IMP;
		impSum = 0;							// обнуление суммы импульсов серии
		for ( byte i=0; i<iMax; i++) {
			impSum = impSum + bufImp[i];		// суммирование импульсов
		}
		impRad = impSum * DELITEL / iMax;		// вычисление дозы за серию замеров импульсов
		if ( numUsr < MAX_R_SRD ){				// if номер усреднения меньше предела
			sumRad += impRad;				// суммирование
			usrRad = sumRad / numUsr;			// усреднение 
		} else {
			sumRad = usrRad * (MAX_R_SRD/5);	// usrRad в 20% sumRad
			numUsr = MAX_R_SRD / 5;			// коррекция номера усреднения
		}
		display.invertDisplay( false);
		switch ( modeDisp) {					// режим экрана
			case 0:
				DisplayBase(); break;
			case 1:
				DisplayVBAT(); break;
			case 2:
				DisplayTest(); break;
			case 3:
				DisplaySetup(); break;
			default: ;
		}
		if ( impRad > 24)							
			if ( (impRad*10/usrRad) >=15 || (usrRad*10/impRad) >= 15) { // детектор изменения уровня радиации
				display.invertDisplay( true);
				tone( PIN_BUZ, 440, 50);			// сигнал - пересчет
				fReset = true;
			}
		if ( fReset) {								// очистка и выход по сбросу
			nZamerSer = 1;
			numUsr = 1;
			sumRad = 0;
//			Serial.println(" reset ");
			break;
		}
		nZamerSer++;
		numUsr++;
	}
}
// счетчик импульсов по прерыванию на INT0
void Int0Count() { 
  nImp++;
}
// опрос кнопок
byte GetKey (void) {
  byte keyPres = ~ (((PIND & 0xf0) >> 4) + 0xf0);   // получить код кнопки старшие разряды сдвинуть в младшие, дополнить и инвертировать
  nKey = 0;
  if ( keyPres) {                                   // если нажата
    if  ( ((millis() - tKey) > 200) ||              // если не дребезг    
                          (prevKey != keyPres)) {   // или отличается от предыдущей
      nKey = keyPres;
      prevKey = keyPres;        // запоминаем как предыдущую
    } else nKey = 0;
    tKey = millis();  
  }   
}
// определение действий по кнопке
void ProcKey() {
  switch(nKey) {
      case 1:
        modeDisp++;
		fDisplay = true;
        if (modeDisp > 3) modeDisp = 0;
        break;
      case 2:
        ;
        break;
      case 3:
        fReset = true;    // сброс данных регистрации
        modeDisp = 0;
        break;
      case 4:
        ;
        break;
      case 8:
        ;
        break;                
      default:
        ;
    }
}
// отрисовка заставки
void DisplayLogo(void) {
  vBat= map( analogRead(A6), 0, 1023, 0, 500);
  display.clearDisplay();
  display.setCursor(0,38);
  display.setTextSize(3);
  display.print(F("Vb"));	  display.print( vBat/100.0); display.println("v");
  for(int16_t i=0; i<14; i+=2) {
    display.drawRoundRect(i, i, 128-2*i, 32-2*i,
      display.height()/4, WHITE);
    display.display();
    delay(200);
  }
  for(int16_t i=0; i<14; i+=2) {
    display.drawRoundRect(i,i, 128-2*i, 32-2*i,
      display.height()/4, BLACK);
    display.display();
    delay(200);
  }
}
// вывод импульсной и усредненной дозы
void DisplayBase( void) {
  display.clearDisplay(); display.setCursor(0,0);
  display.setTextSize(4);
  display.setTextSize(4); 
   if ( impRad < 1000) {
	  display.print( impRad);
	  display.setCursor(80,2);
	  display.print(F("uR"));
  }
	else if ( impRad >= 1000000) {
		display.print( impRad/1000000.0, 1); 
		display.setCursor(80,2);
		display.print(F(" R"));
	}
		else {
			if ( impRad >= 10000) display.print( impRad/1000);
			else display.print( impRad/1000.0, 1); 
			display.setCursor(80,2);
			display.setCursor(80,2);
			display.print(F("mR"));
		}
  if ( usrRad < 1000) {
	  display.print( usrRad);
	  display.setCursor(80,35);
	  display.print(F("uR"));
  }
	else if ( usrRad >= 1000000) {
		display.print( usrRad/1000000.0, 1); 
		display.setCursor(80,35);
		display.print(F(" R"));
	}
		else {
			if ( usrRad >= 10000) display.print( impRad/1000);
			else display.print( usrRad/1000.0, 1); 
			display.setCursor(80,35);
			display.print(F("mR"));
		}
  display.display();
}
// вывод Test информации 
void DisplayTest(void) {
  display.setTextSize(2);
  display.clearDisplay(); 
  display.setCursor(0,0);
  display.print(F("Z"));	display.print( iBuf+1); display.print(F(" N"));	display.println( numUsr);
  display.print(F("	X "));	display.println( temp); 
  display.print(F("Rc "));	display.println( impRad);
  display.print(F("Rs "));	display.println( usrRad); 
  display.display();  
}
// вывод напряжения батареи
void DisplayVBAT( void) {
  display.clearDisplay(); display.setCursor(0,0);
  display.setTextSize(3);
  display.print( F("Vb "));	  display.println( vBat/100.0);
  display.setTextSize(2);	
  display.print( F("Rad=")); display.print( impRad);
  display.display();
}
// вывод Настроек
bool DisplaySetup(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0,0);
  display.println( F("TimeReg-    34200ms"));
//  display.println( F("Tube-3  Delitel-20"));
//  display.println( F("BufImp-3  Usred-50"));
  display.display();
  return false;
} 
// вывод времени замера для тестирования
inline void TestTimeZamer()
{
	time2 =  millis() - time1;
	time1 = millis();
	Serial.println( time2);
}

 

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

Движок форума судя по всему архаичный, скетч вставился пост пропал :(

tekagi пишет:
Преобразователь на блокинге без обратной связи? Олед много оперативки съедает, с функционалом особо не разгуляешься.

Чувствуется опытный взгляд дозиметростроителя :). Да, и блокинг есть и отдельная схема светозвуковой индикации. Для повышения живучести дозиметра.
Олед не только память отъедает, еще и хорошо кушает по току. Но поскольку графики и прочее прикручивать все равно надо - буду выкручиваться. Как говорится - не впервой. В пред. версиях графики были, пока убрал. В последней версии прошивки сделал упор на увеличение скорости реакции обсчета и индикации. Критика и предложения естественно приветствуются.
Вечерком сниму видео по работе с одной и двумя трубками СБМ20.

 

OfficialGalkin
OfficialGalkin аватар
Offline
Зарегистрирован: 29.06.2019

Я тоже тут пытаюсь свой сделать. 

Но есть НО. Ограничил индикация частиц (проигрывать каждую 10-ю частицу) и прерывания без delay идут. Отсюда короткий импульс на выход, светодиод еле моргает и бузер активный щелкает неохотна. Как увеличить длинну импульса программно либо схематически. Без delay. Пробовал по всякому задержки, условия прописывать. На высокой интенсивности излучения это работает коряво. 

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

OfficialGalkin пишет:
Я тоже тут пытаюсь свой сделать.  Пробовал по всякому задержки, условия прописывать. На высокой интенсивности излучения это работает коряво.

На мой взгляд все должно работать гладко, без тормозов в виде delay(). По своей отладочной инфе считаю что millis( t) и tone(p,f,t) позволяют это сделать. Они, если не ошибаюсь, работают с таймерами, с минимальными программными временными лагами. Посему, если не городить отдельный аппаратный канал индикации импульсов, целесообразно работать с tone(). Разумно привязывая длительность tone() к числу импульсов за время единичного замера. 

tekagi
tekagi аватар
Offline
Зарегистрирован: 07.10.2016

Домосед, блокингом тоже рулить можно, в режиме старт-стоп, к примеру по пробою высоковольтного супрессора. Дисплейчик имхо включать по нажатию кнопки на короткое время, плюс при срабатывании аварийных порогов. Ну и в режиме поиска артефактов непрерывно.
Форумный движок то ещё удовольствие, не спорю. А с телефона и вовсе ужасть.
Код вечером гляну, сейчас нет возможности.

MacMillan
Offline
Зарегистрирован: 25.10.2016

Интереса ради - СБМ-19. Первые 2 замера обычные, 20 секунд и 2 минуты. Третий - замеры каждые 3 секунды, далее медианный фильтр, который берёт 10 итераций по 3 секунды. Результат соотвественно тоже каждые 3 секунды. Это наверное чем то похоже на фильтр АрДоса, только с мгновенным результатом На фото источником является 10 ламп 6Ф3П вплотную к счётчику. Кстати, почему от них фон...? Торий в накале?

PS: Joiner, если ты ещё тут и читаешь сообщения - я не смог справиться с MC34063, не судьба этой микрухе работать в дозиметре. Сделал как в АрДосе, гантель на 30uH, первичка 40 витков, полевик и прошивка с PID регулятором. Работает очень стабильно. Сейчас работает при 750 Гц и 16 битном ШИМе. 400В ± 0,5В (нехватка разрядности АЦП). С другой стороны уменьшать потребление генератора при работающем OLED - почти что странность, потому как сам по себе OLED жрёт 20-30мА. 

Joiner
Offline
Зарегистрирован: 04.09.2014

MacMillan пишет:

..........................................

PS: Joiner, если ты ещё тут и читаешь сообщения - я не смог справиться с MC34063, не судьба этой микрухе работать в дозиметре............................

..............................................................

Поспорить пока не могу, но и подтвердить тоже не могу. В моем макете преобразователь такой работает, и даже на ферритовом кольце. Жрет, правда миллиампер 25..... Но работает. Неторопливо занимаюсь между делом модернизацией преобразователя. Если что-то получится, расскажу про результаты. А если не получится, буду искать другой путь....Но микроконтроллер на регулировку напряжения отвлекать не буду.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

Выложил видео по работе дозиметра с разным количеством трубок СБМ20.
https://www.youtube.com/watch?v=fIKw6NKIALk
Увеличение числа трубок с одной стороны подрывает семейный бюджет, с другой стороны повышает чувствительность до уровня датчика БЕТА 2-1. Причем увеличение чувствительности при 3 трубках явно более 3 в пересчете на одну трубку, поскольку увеличивается и площадь (объем) регистратора, что есть имхо хорошо :0
https://idealratio.ru/shop/product/schetchik-geygera-myullera-sbm-20-1
https://idealratio.ru/shop/product/schetchik-geygera-myullera-beta-1-1
https://idealratio.ru/shop/product/schetchik-geygera-myullera-beta-2-1
Что позволяет повысить быстродействие и упростить алгоритмы обсчета. И что немаловажно с меньшими потерями точности и времени реакции использовать режим <<Поиск>>

OfficialGalkin
OfficialGalkin аватар
Offline
Зарегистрирован: 29.06.2019

А я просто купил БЕТА-1 счетчик, за 1500р

сБМ20, по 300р штука брал.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

<strong>MacMillan</strong> пишет:
Интереса ради - СБМ-19. Первые 2 замера обычные, 20 секунд и 2 минуты. Третий - замеры каждые 3 секунды, далее медианный фильтр, который берёт 10 итераций по 3 секунды. Результат соотвественно тоже каждые 3 секунды. Это наверное чем то похоже на фильтр АрДоса, только с мгновенным результатом На фото источником является 10 ламп 6Ф3П вплотную к счётчику. Кстати, почему от них фон...? Торий в накале?

Как по вашему есть ли смысл использовать медианный фильтр? И  почему его нельзя использовать со старта замеров? И любопытно взглянуть на реализацию. Скетч то бишь..
<strong>MacMillan</strong> пишет:
На фото источником является 10 ламп 6Ф3П вплотную к счётчику. Кстати, почему от них фон...? Торий в накале?

Да покрывают катоды оксидами редкоземов - тория, стронция, бария, кальция и проч. Было бы интересно сравнить фон от новых ламп и от поработавщих. Чую, там пахнет изотопами и трансмутацией.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

OfficialGalkin пишет:

А я просто купил БЕТА-1 счетчик, за 1500р

сБМ20, по 300р штука брал.

Это где ж такие цены??? В магазинах цены конские, хотя всё это мелочевка дешевая по сути. Но ...

И как в работе датчики Бета. Какое фон. CPM ( импульсов в минуту при нормальном фоне)?

OfficialGalkin
OfficialGalkin аватар
Offline
Зарегистрирован: 29.06.2019

Цены такие на авито искать надо. Фон 11-13 микрорентген показывает. Счет за 36 секунд. В районе 20 импульсов выходит в минуту. Я пока только один вечер поигрался с ним. 

От изотопа америция  из HIS07 14 милирентген ловит вплотную к окну

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

tekagi пишет:
Домосед, блокингом тоже рулить можно, в режиме старт-стоп, к примеру по пробою высоковольтного супрессора. Дисплейчик имхо включать по нажатию кнопки на короткое время, плюс при срабатывании аварийных порогов. Ну и в режиме поиска артефактов непрерывно.

Самый оптимальный (аппаратно простой) вариант конечно же реализация HV блока Ардуина+mosfet. Но склоняюсь всё же к автономному блоку - паранойя ёпт.
Дисплей, LCD - лучший вариант в походе. На солнце не слепнет, в темноте можно и подсветить.
Вариантов много, но счас мне бы алгоритм обсчета победить, по чуйке и быстроте. :(
Нужно что то оригинальное..

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

OfficialGalkin пишет:
Фон 11-13 микрорентген показывает. Счет за 36 секунд. В районе 20 импульсов выходит в минуту. Я пока только один вечер поигрался с ним.

У меня СБМ20. Характеристическая чуйка для голого счетчика ~ 0.57 CPM. То есть - считаем импульсы за минуту умножаем на 0.57, получаем uR/h. Пример - 20 имп/мин * 0.57 = 11.4uR/h
Или проще: 60s*0.57=34.2s время замера для одного СБМ20. Далее доза равна числу импульсов за замер.
А у Беты 1 чуйка оценочно > раза в 3, только по гамме.
Считаю 20 имп/мин * 0.19 = 3.8uR/h Фон такой что ли? Или счетчик с Авито дохлый, или высокое не высокое?
Чего то я не допонимаю.. Хотя по америцию вроде норм.. Высоковольтный блок держит нагрузку..

Хочу импульсы с трубки осциллографом посмотреть. Надо определиться с пределом измерений по трубке.
Потом проверить блок HV по нагрузке - ключик повесить вместо СБМ с генератором. Счетная часть атмеги по прерыванию отрабатывает на ура до рентгенов. Проверял подачей импульсов от генератора на INT0 pin. 

 

 

MacMillan
Offline
Зарегистрирован: 25.10.2016

Домосед пишет:
Как по вашему есть ли смысл использовать медианный фильтр? И  почему его нельзя использовать со старта замеров? И любопытно взглянуть на реализацию. Скетч то бишь..

На мой взгляд для сырых и быстрых показаний он подходит. Для более точных нужен фильтр с другим алгоритмом. У меня показания по 3-м секундам скачут, где то 75% он попадает на нормальный результат (по 20 секундному значению), оставшиеся 25% выходят за рамки нормы - при фоне ~40 мкР/ч бывает показывает 19 или 85 мкР/ч. 

 

#include "GyverFilters.h" 
/*
в файле GyverFilters.h настраиваем фильтр по Медиане:
//#define MEDIAN_FILTER_SIZE	(10) // размер медианного фильтра! 
Я ставил 10 итераций. А так, можно любое количество.
*/

GMedian RADfast3sec; //подключаем фильтр по Медиане

setup () {
attachInterrupt(0, myEventListener, FALLING); //включаем прерывания на D2
}

void myEventListener() {
  CountRADfast3sec++ ; //считаем частицы на счётчике по прерыванию
}

void loop() {
//самым просты методом считаем уровень радиации в мкРентгенах через миллис
  unsigned long currentMillis3sec = millis();
  if (currentMillis3sec - previousMillis3sec >= interval3sec) {
    previousMillis3sec = currentMillis3sec;
    uRfast3sec = (CountRADfast3sec / 250) * 1200; //(1200 кусков по 3 секунды в часе); расчёт микроРентген
    CountRADfast3sec = 0;  //обнуляем значение
  }
//теперь прищла пора засунуть результат в фильтр по Медиане
  CountRADfastFilter = RADfast3sec.filtered(uRfast3sec);

//выводим на дисплей (библиотеки и всё остальное я не включал в пример):
  display.print(CountRADfastFilter, 1);
  display.println(utf8rus(" мкР/ч - FAST"));
}

 

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

MacMillan пишет:
На мой взгляд для сырых и быстрых показаний он подходит. Для более точных нужен фильтр с другим алгоритмом. У меня показания по 3-м секундам скачут, где то 75% он попадает на нормальный результат (по 20 секундному значению), оставшиеся 25% выходят за рамки нормы - при фоне ~40 мкР/ч бывает показывает 19 или 85 мкР/ч.

Если правильно понял - медианный фильтр это скользящее окно fix размера, в буфере замеров,  с упорядочиванием значений в окне по возрастанию и выдачей из него серединного значения как результата фильтрации? Если честно не понимаю преимущества этого метода перед обычным усреднением в нашем случае. Ведь Рад.распад стохастический процесс и не тождественен сигналу с импульсными помехами..?

 

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

дубль Ж(
Почему нет (Х) для удаления?

 

tekagi
tekagi аватар
Offline
Зарегистрирован: 07.10.2016

Здесь много чего нет) В медианном фильтре смысла не вижу, его задача - отсеять заведомо ложные значения, помехи, а в нашем случае, имхо, лучше обычное среднее. При резком скачке фона он скорее мешать будет, пока не наберётся некое количество замеров с повышенным значением.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

tekagi пишет:
Здесь много чего нет)
Позовите мне Вия.. :D
tekagi пишет:
В медианном фильтре смысла не вижу, его задача - отсеять заведомо ложные значения, помехи, а в нашем случае, имхо, лучше обычное среднее. При резком скачке фона он скорее мешать будет, пока не наберётся некое количество замеров с повышенным значением.
Проще говоря - помехи у нас не помехи, а данные требующие калькуляции. Так что фильтрацию данных можно пока отставить и все усреднять :D
Хотя бывают эпизодические прострелы в регистрации.

MacMillan
Offline
Зарегистрирован: 25.10.2016

Мне нравятся библиотеки Гайвера, множество вариантов. Будет завтра-послезавтра время, попробую фильтр Калмана в сравнении с простыми способами и медианой.

AlexGyver пишет:
Выбор фильтра зависит от типа сигнала и ограничений по времени фильтрации. Среднее арифметическое – самый простой и быстрый, но и результат соответствующий, из настроек только ширина “окна” и период вызова. Для большинства ситуаций подходит бегущее среднее, он довольно быстрый и даёт хороший результат на правильной настройке. Медианный фильтр 3-го порядка тоже очень быстрый, но он может только отсеить выбросы, сам сигнал он не сгладит. Медиана большего порядка является довольно таки громоздким алгоритмом, но работает уже лучше. Очень хорошо работает медиана 3 порядка + бегущее среднее, получается сглаженный сигнал с отфильтрованными выбросами (сначала фильтровать медианой, потом бегущим). AB фильтр и фильтр Калмана – отличные фильтры, справляются с шумным сигналом не хуже связки медиана + бегущее среднее, но нуждаются в тонкой настройке, также они довольно громоздкие с точки зрения кода. Линейная аппроксимация – инструмент специального назначения, позволяющий буквально предсказывать поведение значения за период – ведь мы получаем уравнение прямой.

tekagi
tekagi аватар
Offline
Зарегистрирован: 07.10.2016

За упоминание кода Гайвера на этом форуме могут и тапком)

MacMillan
Offline
Зарегистрирован: 25.10.2016

tekagi пишет:
За упоминание кода Гайвера на этом форуме могут и тапком)

Мне всё равно. Это форум. Я использую любые возможности для реализации своих проектов. Тем более это во много раз ускоряет процесс работы. А те умники с тапками могут писать весь код без библиотек напрямую на ассемблере, они же умные такие :)

 

Да и интересно за что не любят то? За популярность? Или он библиотеки плохие пишет? По крайней мере с его библиотеками некоторые мои проекты успешно работают незная проблем. Сдаётся мне это зависть тапкодержателей.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019


Осциллографирование разрядного тока трубки СБМ20 в точке А при отключенном VT1 (база оторвана) при регистрации гамма кванта 


Характерная длина разрядного шлейфа порядка 250 uS. Если принять этот интервал за время восстановления трубки, то можно ожидать частоту счета порядка 4 кГц. Что в пересчете для СБМ20 должно дать интенсивность ионизирующего излучения .. эм..мэ.

4000*60*0.57 = 136.800 mR/H
136.800*3(трубки) около 400 mR/H
И это если не будет единовременных совпадений по ионизации в трубках, и сдюжит блок питания HV.

MacMillan пишет:
Это форум. Я использую любые возможности для реализации своих проектов. Тем более это во много раз ускоряет процесс работы.

Золотые слова. Надеюсь вы поделитесь, по возможности, результатами.

SergejEU
SergejEU аватар
Offline
Зарегистрирован: 05.11.2018

tekagi пишет:
... В медианном фильтре смысла не вижу, его задача - отсеять заведомо ложные значения, помехи, а в нашем случае, имхо, лучше обычное среднее. При резком скачке фона он скорее мешать будет, пока не наберётся некое количество замеров с повышенным значением.

целиком поддерживаю. никакие фильтры там не нужны. Что нам нужно так это оценить математическое ожидание плотности ионизации. Для этого применяют методы статистики. И среднее арифметическое подходит лучше всего, так как среднее арифметическое является несмещенной оценкой математического ожидания и Эта оценка является также состоятельной. Если причесывать значения выборки фильтрами, то мы получим ложные показания. То есть сделаем только хуже - сместим показания в одну из сторон. Лучше не выдумимать велосипед. Вся теория уже есть. Подробно можно посмотреть лабораторные работы для физиков по регистрации частиц. Ссылку на документ я когда-то здесь давал.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

По вышеприведенным осцилограммам замечу, что амплитуда импульсов не постоянна. Вероятно зависит от энергии кванта. Может гамма спектрометр замутить на СБМ20 :D

SergejEU пишет:
целиком поддерживаю. никакие фильтры там не нужны. Что нам нужно так это оценить математическое ожидание плотности ионизации. Для этого применяют методы статистики. И среднее арифметическое подходит лучше всего, так как среднее арифметическое является несмещенной оценкой математического ожидания и Эта оценка является также состоятельной. Если причесывать значения выборки фильтрами, то мы получим ложные показания. То есть сделаем только хуже - сместим показания в одну из сторон.
Сместим мы конечно показания в худшую для организма сторону, в меньшую.
Но вероятно фильтрация импульсных выбросов(кратковременных повышений - иголок) благотворно скажется при детектировании изменения уровня излучения, то есть на входе детектора будет сглаженная дельта.. И он не будет сбрасывать накопленную за сеанс статистику при прострелах. А аккумулировать естно будем все без фильтрации. И сигнализировать о выбросах тоже.

MacMillan
Offline
Зарегистрирован: 25.10.2016

Фильтр не нужен только в пределах нормальных по времени измерений. Но мы же хотим быстро и по возможности точно. Например получить первый же результат в первые 3 секунды (или хотябы 10 секунд), а не 36. Даже с СБМ-19 в окне 5 секунд при нормальном фоне зарегистрируется 6-7 частиц. 12-14 частиц это уже фон вдвое выше. Частицы прилетают не регулярно, иногда за 2 секунды ничего не прилетает, а иногда бахает по 8 штук. Таким образом при быстрых измерениях мы будем видеть просто непредсказуемый набор чисел, но точно не фон. Наверняка что бы это было более сглаженно необходим фильтр на окно коротких измерений. У меня с алгеброй плохо и я не знаю какие типы фильтров бывают и какие правильные и подходят для нас. И думаю что без них не обойтись (если по быстрому хочется). По поводу средне-арифметического - я тоже думал. Но в окне из 4-6 итераций по 3 секунды любое повышение фона в поиске (например пик) - просто затеряется. Если я в чём то не прав, объясните мне пожалуйста, как правильнее.

MacMillan
Offline
Зарегистрирован: 25.10.2016

Попробовал фильтры с графиками. 

Красная - чистые измерения в мкР каждые 3 секунды.

Жёлтая - по Медиане, 10 итераций по 3 секунды.

Зелёная - Упрощённый фильтр Калмана, данные берутся опять с 3-х секундного окна.

Левая половина скрина - с фонящими лампами (около 45 мкР/ч), как только график добрался до центра, я быстро собрал лампы. Видно, что Медианный фильтр - неточный тормоз, порой он просто дрыхнет, пока фон меняется. Калман - быстрая и плавная реакция на изменения. Фактически в первые 3 секунды я уже получаю результат. Очень понравился, но нужно экспеременировать с настройками реакции. Интересно попробовать 1-секундный результат.

PS: попробовал Калмана по одной секунде, результат поражает, результат очень хороший. Думаю для СБМ-19 идеальное соотношение скорость/точность это окно 2-3 секунды, для одной СБМ-20 - 5-8 секунд.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

MacMillan пишет:
Попробовал фильтры с графиками.
Красная - чистые измерения в мкР каждые 3 секунды.
Жёлтая - по Медиане, 10 итераций по 3 секунды.
Зелёная - Упрощённый фильтр Калмана, данные берутся опять с 3-х секундного окна.
Видно, что Медианный фильтр - неточный тормоз, порой он просто дрыхнет, пока фон меняется. Калман - быстрая и плавная реакция на изменения. Фактически в первые 3 секунды я уже получаю результат. Очень понравился, но нужно экспеременировать с настройками реакции. Интересно попробовать 1-секундный результат.
PS: попробовал Калмана по одной секунде, результат поражает, результат очень хороший. Думаю для СБМ-19 идеальное соотношение скорость/точность это окно 2-3 секунды, для одной СБМ-20 - 5-8 секунд.
Респект за работу
Весьма обнадеживающе. Буду пробовать. Есть соображение куда этот фильтр прикрутить. Я правда стараюсь избегать расчетов с float величинами.
В моём варианте пока, кольцевой буфер импульсов на 40 замеров. Каждый замер 570mS. С последующим усреднением и переводом в дозу, после каждого замера. Далее аккумулирование(суммирование) с последующим делением на число суммирований. И вывод доз по усредненному буферу и аккумулятору. Детектор изменения уровня срабатывает по отличию этих значений в 1.5 раза и сбрасывает буфер и аккумулятор. Заведу еще один аккумулятор от импульсного буфера через фильтр и пущу на детектор изменения. Как то так..
Новое видео - проверка счетной части от генератора - https://www.youtube.com/watch?v=zw4Y-4tkynQ
Везде должны присутствовать цифры 114. Но местами происходит огрубление.

Jeep64
Jeep64 аватар
Offline
Зарегистрирован: 04.05.2019

Добрый день. Не могу понять откуда в схеме 5В  берется, для питания ардуины нано? Ведь аккумулятор  3.7В на схеме.

 

tekagi
tekagi аватар
Offline
Зарегистрирован: 07.10.2016

Схема питается напрямую от лития, 3.6-4.2 вольта. Немного за пределами, рекомендуемыми даташитом для 16МГц, но пока явных глюков ни у кого не наблюдалось.
В проекте используется ProMini, а не нано. На нанке тоже работать будет, но лишняя периферия - лишнее потребление.

TIGR
Offline
Зарегистрирован: 01.09.2019

Корпус сделал очень примитивный (quadratisch, praktisch, gut) 63х117х23 Аккум поставил от 4 айфона (1300мА). Осталось ток покрасить. Думаю для 1 раза сойдет. +1 пользователь ArDos а) https://sun9-43.userapi.com/c858328/v858328165/79386/K_FnAdlnk68.jpg

tekagi
tekagi аватар
Offline
Зарегистрирован: 07.10.2016

Очень даже ничего. Края бы только скруглить, чтобы в руке удобней лежал. И светодиод синий поставить, красные при ярком свете еле видно.

Картинки лучше так вставлять:

TIGR
Offline
Зарегистрирован: 01.09.2019

Картинку вставил так, чтоб качество не уменьшалось и можно было увеличить. Да, края немного даже островаты. Про светодиод спасибо, поменяю

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

TIGR пишет:
 Корпус сделал очень примитивный (quadratisch, praktisch, gut) 63х117х23 Аккум поставил от 4 айфона (1300мА). Осталось ток покрасить.

Минимализм :D Пластик только красить по науке, грунт по пластику, краска, лак. А то облезет. 

Допилил алгоритм детектирования изменения уровня радиации. На мой взгляд результат реакции удовлетворительный.
https://www.youtube.com/watch?v=-69XE_nhHmU
https://www.youtube.com/watch?v=Z29T5CodsuM
Некоторая медлительность на спад, но это на здоровье не влияет.

Samodelkin_YouTube
Offline
Зарегистрирован: 16.12.2018

Как обещал добавляю файлы для изготовления корпуса.

Пластик шлифовал, после чего красил чистым ацетоном

Символы на кнопках залил краской. Знак радиации перед сборкой, предварительно смочил ацетоном

Подставку под экран приклеил с помощью суперклея

Сделал место под установку вибромотора

Отверстие в корпусе нужно залить жидким клеем, для визуализации процесса зарядки

 

Файлы загружаем здесь.https://drive.google.com/open?id=1tmX0dKfSoQhewfP3WXMMoLQUxfwkwhJi

Также могу изготовить данный корпус на заказ, цена 150 грн.

Vitalink
Offline
Зарегистрирован: 17.09.2019

Собираю дозиметр на ардуино нано с олед дисплеем на 4 вывода (GND, VCC, SCK, SDA) по схеме товарища bodriy2014. Прошивка ARDOs_noSleep_v105_oled с сайта автора схемы. Подскажите нужно ли что то менять в скетче? Т.к. в нем прописанно что пин А4 и А5 пустой, но ведь в ардуино нано именно эти пины и являются SDA и SCL. Сейчас рисую cхему в лайаоте и уперся в тупик. С дисплеем Ноккиа 5110 проблем небыло собрал то же на ардуино нано под корпус ИИИ-1, все работает! Сейчас хочу собрать в корпусе G430 размером 90х50х16 мм. должен выйти очень маленький дозиметр.

tekagi
tekagi аватар
Offline
Зарегистрирован: 07.10.2016

Скетч рабочий, менять особо ничего не нужно (разве что коэффициенты делителя проверить). Но код там старый и с букетом багов.

Vitalink
Offline
Зарегистрирован: 17.09.2019

tekagi пишет:
Скетч рабочий, менять особо ничего не нужно (разве что коэффициенты делителя проверить). Но код там старый и с букетом багов.

Спасибо! Буду ваять дальше.

Jeep64
Jeep64 аватар
Offline
Зарегистрирован: 04.05.2019

Новую прошивку под oled перевести технически не возможно? Памяти не хватит? В папке прошивки 1.05 вроде схема с умножителем лежит. Если без умножителя, это на значения коффициена делителя повлияет?

tekagi
tekagi аватар
Offline
Зарегистрирован: 07.10.2016

Не хватит. Не повлияет.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

Очередная выпечка подоспела. Первая бета версия. 
https://www.youtube.com/watch?v=utUnhOI0D1w
 Вот что говорит компилятор:
Binary sketch size: 19 638 bytes (used 61% of a 32 256 byte maximum) (0,00 secs)
Minimum Memory Usage: 738 bytes (36% of a 2048 byte maximum)
Флеша ещё много. С памятью непонятно..

MacMillan
Offline
Зарегистрирован: 25.10.2016

Jeep64 пишет:
Новую прошивку под oled перевести технически не возможно? Памяти не хватит? В папке прошивки 1.05 вроде схема с умножителем лежит. Если без умножителя, это на значения коффициена делителя повлияет?

На самом деле свою не сложно написать. Да и библиотеки разные есть под SSD1306 и SH1106. Есть даже без буферизации, занимают очень мало места в оперативе, но работают медленно (в дозиметре быстро и не нужно). Я сейчас пишу прошивку дозиметра, под OLED на SH1106. Библиотека Adafruit в данный момент сжирает сразу 80%, ещё 9% оставшийся функционал - ШИМ для трансформатора, кнопки, измерение напряжений (счётчик/аккум), вычисления уровня фона по двум алгоритмам. Итого 89%, а ещё нужно запихнуть дохрена. Поэтому приходится пресаживать проект на U8glib, вроде там жор памяти дисплеем меньше, а некоторые тесты показывают что значительно меньше.

Jeep64
Jeep64 аватар
Offline
Зарегистрирован: 04.05.2019

Добрый день. Схемой что к каким пинам ардуины подключать не поделитесь? И прошивкой тоже.

Jeep64
Jeep64 аватар
Offline
Зарегистрирован: 04.05.2019

Пожалуйста.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

MacMillan пишет:
Библиотека Adafruit в данный момент сжирает сразу 80%

Adafruit под буфер берет:
boolean Adafruit_SSD1306::begin(uint8_t vcs, uint8_t addr, boolean reset, boolean periphBegin) {
  if((!buffer) && !(buffer = (uint8_t *)malloc(WIDTH * ((HEIGHT + 7) / 8))))
         return false;

Считаю - 128*(64+7)/8=1136 байт - теоретически..
Остаток   2048-1136=912 байт.
Так вот, максимум может использоваться по опыту 884 байт RAM, если больше Adafruit не работает, т.к. память под буфер не выделяется. Еще 912-884=28 байт зависает.. где то..
Я лично проблем с количеством памяти не испытываю пока, еще в запасе целая прорва - 120 байт :) 

OfficialGalkin
OfficialGalkin аватар
Offline
Зарегистрирован: 29.06.2019

Когда хочется немного покрасивее меню.

Как вам начало?

Правда с таким визуалом уже 60% оперативки занято. а еще режима разностоного замера нет, дозы и накачки.

Индикация блокировки клавиш. Блокирование клавиш, нажатием комбинации.

Домосед
Домосед аватар
Offline
Зарегистрирован: 18.09.2019

OfficialGalkin пишет:
Как вам начало?

Красота!!
Грызу ногти от зависти, где то у меня цветной дисплей завалялся.. :D

OfficialGalkin пишет:
Индикация блокировки клавиш. Блокирование клавиш, нажатием комбинации.

Нажатием комбинации клавиш клавиши заблокировались. Заблокировались. Заблокировались..
Как же разблокировать то их? Ж|

OfficialGalkin
OfficialGalkin аватар
Offline
Зарегистрирован: 29.06.2019

Комбинацией клавиш блокируются не полностью. Основной код перестает реагировать на них, остаются реагировать переменные которые дают разблокировать кнопки той-же комбинацией.