Делаем сами сцинтилляционный спектрометр из… радиометра

от автора

Весной меня отправили на карантин и появилось немного времени, что бы спаять что-нибудь интересное. Выбор пал на вот это устройство.

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

В статье расскажу, как собирал прибор и что поменял в схемотехнике и прошивке.

Первым делом нужно заказать платы. В материалах к исходной статье есть гербер файлы, поэтому все просто. Заказ сделал на PCBWay и JLCPCB, чтобы сравнить качество. Первый рекомендовать не могу: доставка заняла 3 месяца, крепежные отверстия на платах оказались меньше, чем нужно. Из 5 системных плат 2 оказались бракованными (о чем они мне сообщили в письме). C JLCPCB все вышло хорошо и придраться не к чему.

Компоненты заказывал на Mouser и наборы конденсаторов и резисторов на Али (лень стало подбирать все по емкости и решил просто заказать набор). В качестве SiPM использовал MicroFC 60035 — это самая дорогая часть устройства. На момент заказа стоила 70 долларов на Mouser. С более мелким и дешевым 30035 решил не связываться, испугавшись, что припаять и собрать его будет сложнее.

Вторым главным компонентом устройства, кроме фотоприемника, является сцинтилляционный кристалл. И здесь большое поле для модификаций. Найти используемый автором CsI(Tl) маленьких размеров дешевле 90 долларов мне не удалось. Поэтому остановился на NaI(Tl) 10×40мм c ебея за 32 доллара с доставкой. Поиск такого кристалла — это само по себе увлекательное занятие, здесь главное не спешить. Все поисковые запросы в гугле вели меня к Евгению с Украины, но прозрачных кристаллов для спектрометрии у него просто нет. Все, что он присылал имело неприятный желтый оттенок урины.

И вот, все детальки и платы пришли, можно начинать паять. Первым делом решил спаять аналоговую плату. Здесь все без приключений, главное не забыть припаять резистор, место под которое не разведено (внимательно читаем советы по сборке к оригинальной статье).

В системную плату пришлось внести следующие изменения: По даташиту LM2733Y, выходное напряжение не зависит от входного, соответственно подстраивать нечего. Берем из того же даташита формулу R1 = R2 X (VOUT/1.23 − 1) и из того, что нашлось, ставим R13 = 1.8K, R12 = 12K, R11 = 300K. На выходе стабильно 28.18В (пробовал подавать 2.5В, 5В — на выходе все стабильно). После подключения дисплея устройство стало выдавать намного большее число импульсов, чем есть на самом деле. Исправить удалось изменением цепи питания дисплея: вход переключателя DA6 подключаем ко входу DA3. На выходе DA6 ставим преобразователь на 5В (у меня под рукой оказался pololu cj7032) и уже от него питаем дисплей. При таком подключении все помехи сразу ушли.

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

После пайки отмывал схемы изопропиловым спиртом в УЗ ванне. После спирта стоит отмыть дистиллированной водой в той же ванне и просушить в духовке при температуре около 70-80 градусов.

Теперь пришла пора сделать самое интересное: подключить датчик и посмотреть, что же получится. MicroFC 60035 почти идеально припаивается к куску макетной платы 3×3 отверстия: лудим угловые отверстия и припаиваем датчик феном. С обратной стороны макетки припаиваем провода. Вот так это выглядит.

Вот так выглядит кучка плат и деталек без корпуса.

Внимательный читатель может заметить, что процессор я взял STM32L152CBT6A — чуть больше памяти и доступен локально.

Корпус сделал в Fusion 360 и напечатал на 3D принтере. Вот ссылка на проект.

Вот так все выглядит уже в сборе:

Настало время для самого интересного — изменений в прошивке. Мы же хотим сделать именно сцинтилляционный детектор, а не просто радиометр. Для этого нам понадобится использовать DMA с ADC (ADC в этом процессоре один, но есть переключатель входов). А входов у нас два: SP и вольтаж батареи. DMA нужно для ускорения всего процесса. Так же хочу обратить внимание на количество циклов измерений ADC_SampleTime, при 48 и более у меня ничего не получилось. 4 цикла показали наиболее стабильный результат.

Меняем код инициализации ADC следующим образом:

void initADC(void) { 	/* PWR_CTRL and CHG_STAT clock enable */ 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);  	/* UBAT input pin configuration */ 	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_15; 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; 	GPIO_Init(GPIOB, &GPIO_InitStructure);  	/*------------------------ DMA1 configuration ------------------------------*/ 	/* Enable DMA1 clock */ 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 	/* DMA1 channel1 configuration */ 	DMA_DeInit(DMA1_Channel1); 	DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_ADDRESS; 	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue[0]; 	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 	DMA_InitStructure.DMA_BufferSize = 2; 	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; 	DMA_InitStructure.DMA_Priority = DMA_Priority_High; 	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 	DMA_Init(DMA1_Channel1, &DMA_InitStructure); 	/* Enable DMA1 channel1 */ 	DMA_Cmd(DMA1_Channel1, ENABLE); 	/*----------------- ADC1 configuration with DMA enabled --------------------*/ 	/* Enable The HSI (16Mhz) */ 	RCC_HSICmd(ENABLE); 	/* Check that HSI oscillator is ready */ 	while 	(!RCC_GetFlagStatus(RCC_FLAG_HSIRDY)); 	/* Enable ADC1 clock */ 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 	/* ADC1 Configuration -----------------------------------------------------*/ 	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; 	ADC_InitStructure.ADC_ScanConvMode = ENABLE; 	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; 	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; 	ADC_InitStructure.ADC_ExternalTrigConv = 0; 	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 	ADC_InitStructure.ADC_NbrOfConversion = 2; 	ADC_Init(ADC1, &ADC_InitStructure); 	/* Enable temperature sensor and Vref */ 	ADC_TempSensorVrefintCmd(ENABLE); 	//ADC_TempSensorVrefintCmd(DISABLE); 	/* ADC1 regular channel configuration */ 	ADC_RegularChannelConfig(ADC1, SP_ADC_CHANNEL, 1, ADC_SampleTime_4Cycles); 	ADC_RegularChannelConfig(ADC1, UBAT_ADC_CHANNEL, 2, ADC_SampleTime_4Cycles);  	/* Enable the request after last transfer for DMA Circular mode */ 	ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); /* Causes problem.. */ 	/* Define delay between ADC1 conversions */ 	ADC_DelaySelectionConfig(ADC1, ADC_DelayLength_None); 	/* Enable ADC1 Power Down during Delay */ 	ADC_PowerDownCmd(ADC1, ADC_PowerDown_Idle_Delay, ENABLE); 	/* Enable ADC1 DMA */ 	ADC_DMACmd(ADC1, ENABLE); 	/* Enable ADC1 */ 	ADC_Cmd(ADC1, ENABLE);  	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS));  	ADC_SoftwareStartConv(ADC1); } 

Теперь нам нужно попросить контроллер сделать измерения сигнала каждый раз, когда мы видим импульс на входе TRIG:

void EXTI0_IRQHandler(void) // Обработчик импульсов сцинтиллятора { 	uint16_t i;     /* Проверяем, откуда у нас прерывание */     if (EXTI_GetITStatus(EXTI_Line0) != RESET) {         if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) != 1) {             // Убеждаемся, что прерывание прилетело по нужной линии, а не с клавиатуры, например.         	if(Mute == false) {         		GPIOB->ODR &= ~GPIO_ODR_ODR_3;         	}         	if(DMA_GetFlagStatus(DMA1_FLAG_TC1)) {         		ADC_SoftwareStartConv(ADC1);         	}          	counter++;             Delay(20); // ждем, пока не кончится дребезжащий хвост импульса             if(Mute == false) {             	GPIOB->ODR |= GPIO_ODR_ODR_3;             }              if(	(DMA_GetFlagStatus(DMA1_FLAG_TC1))) { 				i = ADC_ConvertedValue[0]; 				adcBatValue += ADC_ConvertedValue[1]; 				if (i >= SPECTRE_START_BIT && i < (SPECTRE_RES + SPECTRE_START_BIT)) { 				i = i-SPECTRE_START_BIT; 				spectre[i] ++;  				if(spectre[i] > spectreMax) { 					spectreMax = spectre[i]; 				}  				if(spectreMax > SPECTRE_MAX_VAL) { 					spectreMax = 0; 					resetSpectre(); 				}  			} 		}         }         /* Не забываем сбросить флаг прерывания */         EXTI_ClearITPendingBit(EXTI_Line0);     } } 

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

Кроме этого, в прошивке поменял назначение кнопок: вверх/вниз изменяет яркость дисплея, кнопка меню показывает спектр, последняя кнопка включает и выключает звук. Экрана у нас только два: основной поисковый экран с графиком интенсивности счетных импульсов и пустой экран для вывода спектрограммы. Спектрограмму выводим сразу в линейном и логарифмическом масштабе, так удобнее смотреть.

Вот такие так выглядят спектрограммы фона и америций-241 из датчика дыма.

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

Модифицированные прошивка дисплея и микроконтроллера доступны на Google Drive.

При создании устройства мне пригодились следующие материалы:

habr.com/ru/post/456878
habr.com/ru/post/487510 и habr.com/ru/post/487518
misrv.com/ultra-micron-module-as
www.youtube.com/watch?v=I8-h8mLnexw

ссылка на оригинал статьи https://habr.com/ru/post/506826/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *