...

вторник, 16 июня 2020 г.

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

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

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

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

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

Вторым главным компонентом устройства, кроме фотоприемника, является сцинтилляционный кристалл. И здесь большое поле для модификаций. Найти используемый автором CsI(Tl) маленьких размеров дешевле 90 долларов мне не удалось. Поэтому остановился на NaI(Tl) 10x40мм 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 почти идеально припаивается к куску макетной платы 3x3 отверстия: лудим угловые отверстия и припаиваем датчик феном. С обратной стороны макетки припаиваем провода. Вот так это выглядит.

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

Внимательный читатель может заметить, что процессор я взял 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

Let's block ads! (Why?)

Комментариев нет:

Отправить комментарий