Делаем дозиметр!

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

И опыт, сын ошибок трудных, и Гена, Чебурашкин друг) Если по печатке собран стабильно работающий девайс (а то и не один) - то больше шансов собрать подобный по этой же печатке. Есть немало моментов, которые нужно учитывать при создании платы "с нуля", и некоторые пользователи из темы на подобные грабли уже наступали. А чуть скорректировать посадочные места под свои детали не проблема.

Muxi
Offline
Зарегистрирован: 22.01.2019

С чужой печаткой вы обречены искать / печатать корпус, чтобы все классно смотрелось, со своей же можно сделать под любой, который понравился, можно и на 2+ датчика нормально развести. Я убил дня 3 и не жалею, все отлично работает, за помощь отдельное спасибо

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

f_max, следующий код будет выдавать в монитор порта (скорость 115200) каждые 30 секунд данные о текущем фоне (фактически для СБМ-20 сумму импульсов за последние 36 секунд). При превышении счётных возможностей кода будет выдано сообщение "zashkal!" Строки, отвечающие за вывод, подсвечены. Разностный режим удалён. Тестируйте, разбирайтесь.

Не забывайте менять на свои коэффициенты ADC_value и k_delitel.

/* ArDOs   v1.08.2
***Дозиметр на Ардуино
***IDE Arduino 1.8.8
  ветка форума arduino.ru/forum/proekty/delaem-dozimetr
  сайт srukami.inf.ua/ardos.html
*/
#include <util/delay.h> //уже есть
#include <EEPROM.h>//уже есть
#include <LCD5110_Graph.h>//нужно установить

//настройки /////////////начало
LCD5110 myGLCD(A1, A0, 12, 10, 11); //подключение дисплея
#define contrast 60 //контрастность дисплея
//#define buzzer_active //если используется активный бузер (со встроенным генератором), управляемый транзистором с выхода 6, то раскомментировать эту строчку, если пассивный (с усилителем или без) - оставить закомментированой.
//#define UNO_DIP // если используется ArduinoUNO или плата на голой атмеге328 в корпусе DIP - раскомментируйте данную строчку. Это переключит чтение напряжения с делителя с ноги A6 на ногу A5.
#define first_alarm_duration 7000 //длительность сигнала тревоги при превышении первого аварийного порога в миллисекундах
byte treviga_1 = 30; //первая ступень тревоги
byte treviga_2 = 60; //вторая ступень тревоги
byte del_BUZZ = 7;//длительность одиночного сигнала
#define  ADC_value 163  //значение АЦП при котором 400В с учетом вашего делителя напряжения (0..255). Для значений делителя с сайта srukami 163. alexadresat 185. (Тестовая версия tekagi  67)
#define k_delitel 576 //коефициент делителя напряжения, зависит от вашего делителя. Для значений делителя с сайта srukami k_delitel 576. alexadresat 500 (Тестовая версия tekagi  1395)
byte puls = 2; //тонкая настройка длинны импульса высоковольтного транса
byte scrin_GRAF = 1; //скорость построения графика в секундах
bool podsvetka = 0; //подсветка
uint8_t graph_type = 1; //тип графика
bool alarm_sound = 0; //флаг индикации превышения порога звуком
float opornoe = 1.10; //делить на opornoe/10
#define save_DOZ 20 //как часто сохранять накопленную дозу например каждые 20мкР
#define geiger_counter_seconds 36 // число секунд для замера, соответствующее характеристикам счётчика. Для СБМ-20 равно 36-40.
int8_t set_com_send_period = 30; //период вывода данных в порт, в секундах (не более 127)
//настройки //////////////конец
//служебные переменные
int8_t com_send_period = 0;
extern uint8_t SmallFontRus[], MediumNumbers[], TinyFontRus[];
volatile uint8_t timer_seconds = 0; // для отсчёта секундных интервалов в прерывании
uint8_t count_and_dose_seconds = 0;
#define maxString 21 // для работы функции преобразования кодировки utf8us
char target[maxString + 1] = ""; // для работы функции преобразования кодировки utf8us
extern uint8_t logo_bat[], logo_rag[], logo_tr[], em_logo[];
volatile int shet = 0;
volatile bool overflow_alarm = 0;
int8_t ind_ON = 1;  //0 - индикация выключена, 1 - включён бузер, 2 - светодиод, 3 - и бузер, и светодиод
uint8_t first_alarm_type = 1;  //1-3, 1 - только бузер, 2 - только вибро, 3 - и бузер, и вибро
byte periodical_alarm_variable = 0; // переменная для периодически повторяющейся тревожной сигнализации
unsigned long gr_milis = 0, lcd_milis = 0;
unsigned long alarm_milis = 0; //для отсчёта длительности сигнала тревоги по превышению порога
unsigned long spNAK_milis = 0, time_doza = 0, bat_mill = 0;
uint16_t hv_adc, hv_400, shet_n = 0, shet_s = 0;
uint16_t fon = 0, fon_254 = 0;
int speed_nakT = 0, speed_nak = 0, result;
byte MIN, DAY, HOUR, MONTH; //для учёта времени дозы
uint16_t doza_vr = 0, fon_vr254 = 0, fon_vr_poisk = 0;
byte mass_p[84]; // массив для графика
byte m = 0, n_menu = 0, sys_menu = 0;
byte  mass_poisk[255]; // основной рабочий массив
byte val_kl = 0, val_ok = 0, menu = 0, zam_poisk_counter = 0;
float VCC = 0.0, doz_v = 0.0;
bool tr = 0, poisk = 1, fonarik = 0, blink_data=1;
uint8_t GRAPH_max = 5; // максимальное значение за период отображения графика
uint8_t GRAPH_count = 0; // счётчик для поиска максимального значения для графика
#define key_pressed_left 1
#define key_pressed_right 2
#define key_pressed_ok 3
#define key_holded_left 4
#define key_holded_right 5
#define key_holded_ok 6
#define keys_not_pressed 0
uint8_t key_data = 0;
//-------------------------------------------------------------
void setup() {
  //-----------------------------------------------------------
  // настраиваем таймер на секундный интервал
  TCCR1A=(1<<WGM11); //режим14 FAST PWM 
  TCCR1B=(1<<CS12)|(1<<WGM13)|(1<<WGM12); //делить частоту CPU на 256
if (F_CPU == 16000000UL) 
 {
  ICR1=62499;  // (16000000MHz /div256) -1 = 1 раз в секунду
 }
else if (F_CPU == 8000000UL) 
 {
  ICR1=31249;  // (8000000MHz /div256) -1 = 1 раз в секунду
 } 
  TIMSK1=(1<<TOIE1); //разрешить прерывание
  //-----------------------------------------------------------
  Serial.begin(115200);
  ACSR |= 1 << ACD; //отключаем компаратор
  //ADCSRA &= ~(1 << ADEN);  // отключаем АЦП,
  pinMode(3, INPUT_PULLUP); //кнопка
  pinMode(4, INPUT_PULLUP); //кнопка
  pinMode(7, INPUT_PULLUP); //кнопка
  DDRB |= (1 << 0); PORTB &= ~(1 << 0); //пин вибры 8
  DDRC |= (0 << 4); PORTC &= ~(1 << 4); //пин пустой А4
  DDRC |= (0 << 5); PORTC &= ~(1 << 5); //пин пустой А5
  DDRB |= (1 << 1);//пин фонаря
  DDRC |= (1 << 3);//A3 дисплей GND
  DDRC |= (1 << 2);//A2 дисплей Light
  PORTC &= ~(1 << 3); //A3 дисплей GND
  PORTC  |= (1 << 2); //A2 дисплей Light
  eeprom_readS ();
  eeprom_readD ();
  lcd_init();
  attachInterrupt(0, Schet, FALLING);//прерываниям пин 2
  DDRB |= (1 << 5); //пины на выход
  DDRD |= (1 << 5);
  DDRD |= (1 << 6);
  DDRD |= (1 << 6);//пин бузера
  nakachka();
  clear_poisk_variables();
}
//-------------------------------------------------------------
void loop() 
{
key_data = get_key();  // вызываем функцию определения нажатия кнопок, присваивая возвращаемое ней значение переменной, которую далее будем использовать в коде
if (menu == 0) 
  {
    if (key_data == key_pressed_left) 	//нажатие <<<
		{
			key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду 
			clear_poisk_variables();
		}
    if (key_data == key_holded_left) //удержание <<< фонарик  
	{
		fonarik = !fonarik; 
		key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
	}  	
    if (key_data == key_holded_right) // удержание <<< подсветка
	{
		key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду		  
        podsvetka = !podsvetka;
    }		
    if (key_data == key_pressed_right)  //нажатие >>>
	{
		key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
    }
 } 
if (menu == 3)
  {
    if (key_data == key_pressed_left)  //нажатие <<<
	{
		key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
		menu = 0;
		shet = 0; fon = 0; zam_poisk_counter = 0;
		for (int i = 0; i < 18; i++) { mass_poisk[i] = 0; }//чистим
	}
  } 
if (menu == 4) 
  {
    if (key_data == key_pressed_right)  //нажатие >>>
	{
		key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
		menu = 0;
		clear_poisk_variables();
    }
  }
if (fonarik == 0)  //фонарик
	{
		PORTB &= ~(1 << 1);//пин фонаря
	} 
else if (fonarik == 1) 
	{
		PORTB |= (1 << 1);//пин фонаря
	}
if (podsvetka == 1) 
	{
		PORTC &= ~(1 << 2); //A2 дисплей Light
	}
else if (podsvetka == 0) 
	{
		PORTC |= (1 << 2); //A2 дисплей Light
	}
  if (millis() - lcd_milis >= 300)  //скорость отрисовки дисплея
	{
		lcd_milis = millis();
		blink_data = !blink_data;
		if (menu == 0) 
			{
				lcd_poisk();  //вывод на дисплей режима поиск
				poisk_f();    //вызов функции счёта и набора массива
			}
		if (menu == 1) 
			{
				lcd_menu();   //вывод на дисплей меню
				poisk_f();	//вызов функции счёта и набора массива 
			}
		if (menu == 2) 
			{
				lcd_sys();    //вывод на дисплей системного меню
				poisk_f();	//вызов функции счёта и набора массива
			}
		if (menu == 3) 
			{
//      		zamer_200s(); //вывод на дисплей замер 180сек
				menu = 0;
			}
		if (menu == 4) 
			{
//				zamer_beta();
				menu = 0;				
			}
	}
//-------------------------------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------------------------------  
generator();//накачка по обратной связи с АЦП
if (shet_s != shet) 
	{
		signa ();//подача сигнала о частичке
	}
if (key_data == key_pressed_ok) { //нажатие ок
if (menu == 2) 
	{
		key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
		sys_menu++;
		if (sys_menu > 5) 
			{
				sys_menu = 0;
			}
	}
if (menu == 1) 
	{
		key_data = 0;    // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
		n_menu++;
		if (n_menu > 7) 
			{
				n_menu = 0;
			}
	}
if (menu == 0) 
	{
		key_data = 0;   // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
		menu = 1;
	}
  } 
if (menu == 0)  // в меню по удержанию кнопки "ок" входим только из режима "поиск"
	{
		if (key_data == key_holded_ok)  //удержание OK
			{
				menu = 2; 
				key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
			}
	}
if (menu == 1) 
	{
		if (key_data == key_pressed_right)  //нажатие >>>
			{
				if (n_menu == 0) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду	  
						treviga_1++;
					}
				if (n_menu == 1) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду		  
						treviga_2++;
					}
				if (n_menu == 2) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду		  
						podsvetka = !podsvetka;
					}
				if (n_menu == 3) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						graph_type++;
						if (graph_type>1) {graph_type = 1;}
					}
				if (n_menu == 4) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду		  
						scrin_GRAF++;
						if (scrin_GRAF > 10) 
							{
								scrin_GRAF = 1;
							}
					}
				if (n_menu == 5) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду		  
						ind_ON++; 
						ind_ON = constrain (ind_ON, 0, 4); //держим значение в диапазоне 0...4
					}
				if (n_menu == 6) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду		  
						menu = 0;
					}
				if (n_menu == 7) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду		  
						eeprom_wrS ();
						menu = 0;
					}
			}
	}
if (menu == 2) 
	{
		if (key_data == key_pressed_right)  //нажатие >>>
			{
				if (sys_menu == 0) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду	
						opornoe = opornoe + 0.01;
						if (opornoe < 0.98) 
							{
								opornoe = 1.20;
							}
						if (opornoe > 1.20) 
							{
								opornoe = 0.98;
							}
					}
				if (sys_menu == 1) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						puls++;
						if (puls < 1) 
							{
								puls = 200;
							}
						else if (puls > 200) 
							{
								puls = 1;
							}
					}
				if (sys_menu == 2) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						time_doza = 0;//сброс накопленной дозы
						doz_v = 0;//сброс накопленной дозы
						eeprom_wrD ();
						myGLCD.clrScr();
						myGLCD.setFont(SmallFontRus);
						myGLCD.print(utf8rus("ДОЗА И ВРЕМЯ"), CENTER, 16);
						myGLCD.print(utf8rus("ОБНУЛЕНЫ"), CENTER, 24);
						myGLCD.update();
						_delay_ms(1000);
					}
				if (sys_menu == 3) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						menu = 0;
					}
				if (sys_menu == 4) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						eeprom_wrS ();
						menu = 0;
					}
				if (sys_menu == 5) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду

					}
			}
	}
if (menu == 1) 
	{
		if (key_data == key_pressed_left)  //нажатие <<<
			{
				if (n_menu == 0) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						treviga_1--;
					}
				if (n_menu == 1) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						treviga_2--;
					}
				if (n_menu == 2) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						podsvetka = !podsvetka;
					}
				if (n_menu == 3) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						graph_type--;
						if (graph_type > 1) {graph_type = 0;}
					}
				if (n_menu == 4) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						scrin_GRAF--;
						if (scrin_GRAF < 1) 
							{
								scrin_GRAF = 10;
							}
					}
				if (n_menu == 5) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						ind_ON--; 
						ind_ON = constrain (ind_ON, 0, 4); //держим значение в диапазоне 0...4
					}
				if (n_menu == 6) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						menu = 0;
					}
				if (n_menu == 7) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						eeprom_wrS ();
						menu = 0;
					}
			}
	}
if (menu == 2) 
	{
		if (key_data == key_pressed_left)  //нажатие <<<
			{
				if (sys_menu == 0) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						opornoe = opornoe - 0.01;
						if (opornoe < 0.98) 
							{
								opornoe = 1.20;
							}
						else if (opornoe > 1.20) 
							{
								opornoe = 0.98;
							}
					}
				if (sys_menu == 1) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						puls--;
						if (puls < 1) 
							{
								puls = 200;
							}
						else if (puls > 200) 
							{
								puls = 1;
							}
					}
				if (sys_menu == 2) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						time_doza = 0;//сброс накопленной дозы
						doz_v = 0;//сброс накопленной дозы
						eeprom_wrD ();
						myGLCD.clrScr();
						myGLCD.setFont(SmallFontRus);
						myGLCD.print(utf8rus("ДОЗА И ВРЕМЯ"), CENTER, 16);
						myGLCD.print(utf8rus("ОБНУЛЕНЫ"), CENTER, 24);
						myGLCD.update();
						_delay_ms(1000);
					}
				if (sys_menu == 3) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						menu = 0;
					}
				if (sys_menu == 4) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						eeprom_wrS ();
						menu = 0;
					}
				if (sys_menu == 5) 
					{
						key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду

					}
			}
	}
//------------------------------------------------------------------------------------------------------------------  
if (alarm_sound && (millis() - lcd_milis >= 300)) //если поднят флаг аварийного сигнала (плюс попользуемся интервалом обновления экрана)
	{
		periodical_alarm_variable++; 
		if (periodical_alarm_variable >= 4) {periodical_alarm_variable = 1;} // держим переменную в пределах
		PORTB |= (1 << 0); //включаем вибру
		if (periodical_alarm_variable  > 1 )
			{
				PORTB &= ~(1 << 0); // выключаем вибру	
			}
		if  (periodical_alarm_variable  < 3) // периодичный звук тревоги
			{
				#ifdef buzzer_active //если задефайнен активный бузер
				PORTD |= (1 << 6); // включаем непрерывный сигнал тревоги
				#else //пассивный
				tone (6, 1300); //генерим писк с частотой 1300Гц (значение можно изменить на своё) на пине 6
				#endif
			}
		else 
			{
				#ifdef buzzer_active   //если задефайнен активный бузер
				PORTD &= ~(1 << 6); // выключаем непрерывный сигнал тревоги
				#else //пассивный бузер
				noTone (6); //выключаем писк на 6й ноге
				#endif 
			}
	if ((millis() - alarm_milis) > first_alarm_duration) // проверяем, не истекло ли время подачи сигнала тревоги
		{
			PORTB &= ~(1 << 0); // выключаем вибру
			periodical_alarm_variable = 0; // обнуляем переменную
			#ifdef buzzer_active   //если задефайнен активный бузер
			PORTD &= ~(1 << 6); // выключаем непрерывный сигнал тревоги
			#else //пассивный бузер
			noTone (6); //выключаем писк на 6й ноге
			#endif 
			alarm_sound = 0; // сбрасываем флаг сигнала тревоги
		}
	}
//------------------------------------------------------------------------------------------------------------------
if (!tr && alarm_sound) // если фон ниже порога тревоги, но сигнал тревоги ещё не выключен
	{
		res_first_alarm(); //сбрасываем сигнал тревоги
	}
}
//-------------------------------------------------------------------------------------------------------
void lcd_poisk() 
{//вывод на дисплей режима поиск
if (shet < treviga_1 && fon < treviga_1) //проверяем тревогу
	{
		tr = 0;
	}
if (shet > treviga_1 || fon > treviga_1) //проверяем тревогу
	{
		check_alarm_signal(); // устанавливаем сигнал непрерывной тревоги, если "tr" переключился в "1"
		tr = 1;
	}
myGLCD.clrScr();
myGLCD.setFont(SmallFontRus);
if (tr == 1)  //опасно
	{
		myGLCD.drawBitmap(0, 0, logo_tr, 24, 8);
	}
myGLCD.setFont(TinyFontRus);
if (fon_254 > 0) 
	{
		if (fon_254 >= 1000) 
			{
				myGLCD.print("\xBC\xBE\xBF", 43, 0);
			}
		if (fon_254 < 1000) 
			{
				myGLCD.print("\xBC\xBD\xBE\xBF", 43, 0);
			}
	}
if ((zam_poisk_counter >= 254) || blink_data)
	{
	myGLCD.setFont(TinyFontRus);
	if (fon_254 > 0) 
		{
			if (fon_254 >= 1000) 
				{
					myGLCD.printNumF((float(fon_254)/1000.0), 1, 26, 0);
				}
			if (fon_254 < 1000) 
				{
					if (fon_254 < 100)
						{
							myGLCD.printNumI(fon_254, 32, 0);
						}
					else
						{
							myGLCD.printNumI(fon_254, 26, 0);
						}
				}
		}
	}
if (overflow_alarm && !blink_data)
	{
	myGLCD.drawBitmap(16, 8, em_logo, 16, 16);
	overflow_alarm = 0;
	}
else if ((zam_poisk_counter >= geiger_counter_seconds) || blink_data)
	{
		myGLCD.setFont(MediumNumbers);
		if (fon > 0) 
			{
				if (fon >= 1000) 
					{
						myGLCD.printNumF((float(fon)/1000), 2, LEFT, 7);
						myGLCD.setFont(SmallFontRus); myGLCD.print(utf8rus("мР/ч"), RIGHT, 12);
					}
				if (fon < 1000) 
					{
						if (fon < 100)
							{
								myGLCD.printNumI(fon, CENTER, 7);
							}
						else
							{
								myGLCD.printNumI(fon, LEFT, 7);	
							}
						myGLCD.setFont(SmallFontRus); myGLCD.print(utf8rus("мкР/ч"), RIGHT, 12);
					}
			}
	}
if (fon > 0) 
	{
		myGLCD.setFont(SmallFontRus);
		if (fon >= 1000) 
			{
				myGLCD.print(utf8rus("мР/ч"), RIGHT, 12);
			}
		if (fon < 1000) 
			{
				myGLCD.print(utf8rus("мкР/ч"), RIGHT, 12);
			}
	}
time_d ();
myGLCD.setFont(TinyFontRus);
ind_doze_time();	//вывод времени накопления дозы на дисплей	  
myGLCD.setFont(SmallFontRus);
if (doz_v < 1000) 
	{
		if (doz_v < 100)
			{
				myGLCD.printNumF(doz_v, 1, 41, 24); myGLCD.print(utf8rus("мкР"), RIGHT, 24);
			}
		else
			{
				myGLCD.printNumF(doz_v, 1, 34, 24); myGLCD.print(utf8rus("мкР"), RIGHT, 24);
			}    
	}
if (doz_v >= 1000) 
	{
		myGLCD.printNumF(doz_v / 1000.0, 2, 41, 24); myGLCD.print(utf8rus("мР"), RIGHT, 24);
	}
myGLCD.drawLine(0, 32, 83, 32);//верхняя
battery();
if (graph_type == 0)
	{
	for (uint8_t i = 0; i < 82; i ++)  //печатаем график
		{
			uint8_t max_pixel = map(mass_p[i], 0, GRAPH_max, 0, 15);
			myGLCD.drawLine(i + 1, 47, i + 1, 47 - max_pixel);
		}
	}
else if (graph_type == 1)
	{
	for (int i = 0; i < 82; i ++)  //печатаем график
	  {
		if (mass_p[i] > 0) 
			{
				if (mass_p[i] <= 15) 
					{
						myGLCD.drawLine(i + 1, 47, i + 1, 47 - mass_p[i]);
					}
				if (mass_p[i] > 15) 
					{
						myGLCD.drawLine(i + 1, 47, i + 1, 47 - 15);
					}
			}
		}
	}
myGLCD.update();
}
//-------------------------------------------------------------------------------------------------------
void lcd_menu()  //вывод на дисплей меню
{
myGLCD.clrScr();
myGLCD.setFont(TinyFontRus);
myGLCD.print(utf8rus("ПОРОГ 1"), 5, 0); myGLCD.printNumI(treviga_1, 55, 0); myGLCD.print("\xBC\xBD\xBE\xBF", RIGHT, 0);
myGLCD.print(utf8rus("ПОРОГ 2"), 5, 6); myGLCD.printNumI(treviga_2, 55, 6); myGLCD.print("\xBC\xBD\xBE\xBF", RIGHT, 6);
myGLCD.print(utf8rus("ПОДСВЕТКА"), 5, 12); 
if (podsvetka)  { myGLCD.print(utf8rus("ВКЛ."), RIGHT, 12); }
else  { myGLCD.print(utf8rus("ВЫКЛ."), RIGHT, 12);  }
myGLCD.print(utf8rus("ТИП. ГРАФИКА"), 5, 18);  myGLCD.printNumI(graph_type, 59, 18); myGLCD.print("0-1", RIGHT, 18); //
myGLCD.print(utf8rus("ОБН. ГРАФИКА"), 5, 24); myGLCD.printNumI(scrin_GRAF, 59, 24); myGLCD.print(utf8rus("СЕК."), RIGHT, 24);//
myGLCD.print(utf8rus("ИНДИКАЦИЯ"), 5, 30); //пункт меню выбора индикации частиц
switch (ind_ON)
	{
	case 0:
		myGLCD.print(utf8rus("ВЫКЛ."), RIGHT, 30); //индикация выключена
		break;	
	case 1:
		myGLCD.print(utf8rus("ЗВУК"), RIGHT, 30); //индикация звуком
		break; 	
	case 2:
		myGLCD.print(utf8rus("СВЕТ"), RIGHT, 30); //индикация светом
		break;	
	case 3:
		myGLCD.print(utf8rus("ЗВУК+СВЕТ"), RIGHT, 30); //индикация звуком и светом
		break; 
	case 4:
		myGLCD.print(utf8rus("ВИБРО"), RIGHT, 30); //индикация вибрацией
		break; 
		default:
		myGLCD.print("err", RIGHT, 30); //	если значение не равно 1,2,3 или 0 - выводим ошибку	
	}
myGLCD.print(utf8rus("ВЫХОД"), 5, 36);
myGLCD.print(utf8rus("СОХРАНИТЬ"), 5, 42);
myGLCD.print(">", 0, n_menu * 6);
myGLCD.update();
}
//----------------------------------------------------------------------------------------------------------------------
void lcd_sys()  //вывод на дисплей меню
{
VCC_read();
speed_nakachka ();//скорость накачки имлульсы/сек
myGLCD.clrScr();
myGLCD.setFont(TinyFontRus);
myGLCD.print(utf8rus("ОПОРН."), 5, 0); myGLCD.printNumF(opornoe, 2, CENTER, 0); myGLCD.print("VCC", 55, 0); myGLCD.printNumF(VCC, 2, RIGHT, 0);
hv_400 = hv_adc * opornoe * k_delitel / 255; //считем высокео перед выводом
myGLCD.print(utf8rus("НАКАЧКА"), 5, 6); myGLCD.printNumI(puls, 55, 6); myGLCD.printNumI(hv_400, RIGHT, 6);
myGLCD.print(utf8rus("СБРОС ДОЗЫ"), 5, 12); 
myGLCD.print(utf8rus("ВЫХОД"), 5, 18);
myGLCD.print(utf8rus("СОХРАНИТЬ"), 5, 24);
//myGLCD.print(utf8rus("БЕТА"), 5, 30); myGLCD.printNumI(beta_time, 55, 30); myGLCD.print(utf8rus("МИН."), RIGHT, 30);
myGLCD.print(">", 0, sys_menu * 6);
myGLCD.print(utf8rus("СКОРОСТЬ"), 5, 40); myGLCD.printNumI(speed_nak, 40, 40); myGLCD.print(utf8rus("ИМП/СЕК"), RIGHT, 40);
myGLCD.update();
}
//---------------------------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------------------
void poisk_f() //режим поиска
{
int16_t shet_gr = 0;
if (poisk == 1) 
	{
		if (timer_seconds != count_and_dose_seconds) 
			{
				count_and_dose_seconds = timer_seconds;
					for (int i = 0; i < 254; i++)  //сдвигаем
					{
						mass_poisk[i] = mass_poisk[i + 1];
					}
				mass_poisk[254] = shet;
				if ((zam_poisk_counter < 254) && (zam_poisk_counter < geiger_counter_seconds))  //первый набор массива
					{
						fon_vr_poisk = fon_vr_poisk + shet;  						
						zam_poisk_counter++;
						fon = fon_vr_poisk*((float(geiger_counter_seconds))/(float(zam_poisk_counter))); 
//						fon_254 = fon;
						fon_254 = 0;
					}
				else if ((zam_poisk_counter < 254) && (zam_poisk_counter == geiger_counter_seconds))  //
					{		
						zam_poisk_counter++;
						fon_vr_poisk = fon_vr_poisk + shet; 
						fon = fon_vr_poisk*((float(geiger_counter_seconds))/(float(zam_poisk_counter)));
						fon_254 = fon;		
						fon_vr254 = fon_vr_poisk;
					}
				else if ((zam_poisk_counter < 254) && (zam_poisk_counter > geiger_counter_seconds))  //
					{
						fon_vr_poisk = 0;
						fon_vr254 = 0;
						for (int i = zam_poisk_counter; i > 0; i--) 
							{
								fon_vr254 = fon_vr254 + mass_poisk[254-i];
							}
						for (int j = 254 - geiger_counter_seconds; j < 255; j++) 
							{	
								fon_vr_poisk = fon_vr_poisk + mass_poisk[j];
							}
						fon = fon_vr_poisk;
//						fon_254 = (float(fon_vr254))*((float(geiger_counter_seconds))/(float(zam_poisk_counter)));
						fon_254 = (float)fon_vr254*((float)geiger_counter_seconds/(float)zam_poisk_counter); 
						fon_vr254 = 0;
						zam_poisk_counter++;
					}	
				else if (zam_poisk_counter >= 254)  //набор массива
					{
						fon_vr_poisk = 0;
						fon_vr254 = 0;
						byte geiger_counter_seconds_reverse = 254 - geiger_counter_seconds;
						for (int i = 254; i > 0; i--) 
							{
								fon_vr254 = fon_vr254 + mass_poisk[i];
								if (i > geiger_counter_seconds_reverse)
									{
										fon_vr_poisk = fon_vr_poisk + mass_poisk[i];
									}
							}
						fon = fon_vr_poisk;
						fon_254 = (float(fon_vr254))*((float(geiger_counter_seconds))/254.0);
					}
				shet = 0;
				doz_v = doz_v + fon / 100.0 / 36.0;
				time_doza = time_doza + 1;
				if (doz_v - doza_vr >= save_DOZ)  //а не пора ли сохранить дозу ?
					{
						eeprom_wrD ();
						doza_vr = doz_v;
					}
com_send_period--;
if ((com_send_period<=0) && (zam_poisk_counter>geiger_counter_seconds))
	{
		Serial.print("fon=");
		if (overflow_alarm) 
			{
				Serial.println(" zashkal! ");
			}
		else
			{
				Serial.println(fon);	
			}
		com_send_period = set_com_send_period;
	}				
			}
		if (millis() - gr_milis >= scrin_GRAF * 1000) //счет для графика
			{
			gr_milis = millis();
			if (graph_type == 0)
				{
				val_ok = 0;//сброс удержания системного меню  
				for (uint8_t s = 254; s >= (255 - scrin_GRAF); s--) 
					{
						shet_gr = shet_gr + mass_poisk[s];
					}
				shet_gr = shet_gr / scrin_GRAF;
				for (int i = 0; i < 83; i++) // сдвигаем массив графика
					{
						mass_p[i] = mass_p[i + 1];
					}
				mass_p[82] = byte(shet_gr);
				if (GRAPH_count > 82) 
					{
						GRAPH_max = 5; 
						GRAPH_count = 0;
					}		
				for (int i = 0; i < 82; i++) 
					{
						if (mass_p[i] > GRAPH_max)
							{
								GRAPH_max = mass_p[i];
								GRAPH_count = 0;
							}
					}
				GRAPH_count++;	   
				}
			if (graph_type == 1)
				{
					val_ok = 0;//сброс удержания системного меню
					shet_gr = shet - shet_n;
					if (shet_gr < 0) 
						{
							shet_gr = 1;
						}
					shet_n = shet;
					for (int i = 0; i < 83; i++) 
						{
							mass_p[i] = mass_p[i + 1];
						}
					mass_p[82] = byte(shet_gr);
						
				
				}				
			}
	}
}
//----------------------------------------------------------------------------------------------------------------

void clear_poisk_variables ()
{
shet = 0;
fon = 0;
fon_254 = 0;
zam_poisk_counter = 0;
GRAPH_max = 5;
GRAPH_count = 0;
fon_vr254 = 0;
fon_vr_poisk = 0;
for (uint8_t i = 0; i < 83; i++) { mass_p[i] = 0; } // чистим массив графика
for (uint8_t i = 0; i < 254; i++) { mass_poisk[i] = 0; } // чистим массив поиска	
}

void signa ()  //индикация каждой частички звуком светом
{
shet_s = shet;  
if (!alarm_sound) //если флаг сигнала тревоги не поднят, генерим одиночные сигналы, озвучивающие пойманные частицы
    {
		if (!shet_s) {return;} //если залетели в функцию signa() при обнулении переменной shet_s - просто возвращаемся в точку вызова. Детальнее здесь: arduino.ru/forum/proekty/delaem-dozimetr?page=16#comment-318736
		switch (ind_ON) //проверяем, какой тип индикации выбран
			{
				case 0: //индикация выключена
					break;	
				case 1: //индикация звуком
					#ifdef buzzer_active //если задефайнен активный бузер
						{
							PORTD |= (1 << 6); //включаем бузер 
							delay(del_BUZZ); //длительность одиночного сигнала
							PORTD &= ~(1 << 6); //выключаем бузер 
						}
					#else //пассивный бузер
						{
							tone (6,1000,30); //генерим писк 1000Гц 30миллисекунд на 6й ноге
						}
					#endif 
					break; 	
				case 2: //индикация светом
					PORTB |= (1 << 5); //включаем светодиод
					delay(del_BUZZ); //длительность одиночного сигнала
					PORTB &= ~(1 << 5); //выключаем светодиод
					break;
	
				case 3: //индикация звуком и светом
					#ifdef buzzer_active //если задефайнен активный бузер
						{
							PORTB |= (1 << 5); //включаем светодиод
							PORTD |= (1 << 6); //включаем бузер 
							delay(del_BUZZ); //длительность одиночного сигнала
							PORTD &= ~(1 << 6); //выключаем бузер 
							PORTB &= ~(1 << 5); //выключаем светодиод
						}
					#else //пассивный бузер
						{
							PORTB |= (1 << 5); //включаем светодиод
							tone (6,1000,30); //генерим писк 1000Гц 30миллисекунд на 6й ноге
							delay(del_BUZZ);//длительность одиночного сигнала
							PORTB &= ~(1 << 5);//выключаем светодиод
						}
					#endif 
					break; 
				case 4: // индикация вибрацией
					PORTB |= (1 << 0); //включаем вибру
					delay(del_BUZZ); //длительность одиночного сигнала
					PORTB &= ~(1 << 0); // выключаем вибру			
			} 
    }
else // если активен сигнал тревоги, то только мигаем светодиодом (независимо от того, включён или нет светодиод в меню)
	{
	    PORTB |= (1 << 5); //включаем светодиод
		delay(del_BUZZ);
		PORTB &= ~(1 << 5);//выключаем светодиод
	}
}
//-------------------------------------------------------------------------------------------------
void Schet()  //прерывание от счетчика на пин 2
{
shet++;
if (shet>250) {overflow_alarm = 1;} // детект приближения к переполнению переменной
}
//-------------------------------------------------------------------------------------------------
void generator() //накачка по обратной связи с АЦП
{
hv_adc  = Read_HV();
if (hv_adc < ADC_value)  //Значение АЦП при котором на выходе 400В
	{
		int c = puls;
		PORTD |= (1 << 5); //пин накачки
		while (c > 0) 
			{
				asm("nop");
				c--;
			}
		PORTD &= ~(1 << 5);//пин накачки
		speed_nakT++;
	}
}
//--------------------------------------------------------------------------------------------------
byte Read_HV () 
{
ADCSRA = 0b11100111;
#ifdef UNO_DIP //если при компилляции выбрана плата ArduinoUNO
ADMUX = 0b11100101;//выбор внутреннего опорного 1,1В и А5 
#else // если используется промини, нано или голый камень в tqfp
ADMUX = 0b11100110;//выбор внутреннего опорного 1,1В и А6
#endif  
for (int i = 0; i < 10; i++) 
	{
		while ((ADCSRA & 0x10) == 0);
		ADCSRA |= 0x10;
	}
result = 0;
for (int i = 0; i < 10; i++) 
	{
		while ((ADCSRA & 0x10) == 0);
		ADCSRA |= 0x10;
		result += ADCH;
	}
result /= 10;
return result;
}
//----------------------------------------------------------------------------------------------------
void battery()  //батарейка
{
if (bat_mill - millis() > 2000) 
	{
		bat_mill = millis();
		VCC_read();
	}
myGLCD.drawBitmap(59, 0, logo_bat, 24, 8);
myGLCD.setFont(TinyFontRus);
myGLCD.printNumF(VCC, 2, 65, 1);
}
//----------------------------------------------------------------------------------------------------
void VCC_read()  // Чтение напряжения батареи
{
ADCSRA = 0b11100111;
ADMUX = 0b01101110;//Выбор внешнего опорного+BG
_delay_ms(5);
while ((ADCSRA & 0x10) == 0);
ADCSRA |= 0x10;
byte resu = ADCH;
//ADCSRA &= ~(1 << ADEN);  // отключаем АЦП,
VCC = (opornoe * 255.0) / resu;
}
//----------------------------------------------------------------------------------------------------
void lcd_init() 
{
myGLCD.InitLCD();
myGLCD.setContrast(contrast);
myGLCD.clrScr();
myGLCD.drawBitmap(0, 0, logo_rag, 84, 48);
//myGLCD.setFont(SmallFontRus);
//  myGLCD.print(utf8rus("Ардуино+"), CENTER, 32);
//  myGLCD.print(utf8rus("Дозиметр v1.07"), CENTER, 40);
myGLCD.update();
_delay_ms(1000);
}
//----------------------------------------------------------------------------------------------------
void eeprom_wrS ()  //запись настроек в память
{
  EEPROM.write(0, 222);
  EEPROM.write(1, treviga_1);
  EEPROM.write(2, podsvetka);
  EEPROM.write(3, graph_type);
  EEPROM.write(4, scrin_GRAF);
  EEPROM.write(5, ind_ON);
  EEPROM.write(6, puls);
  EEPROM.write(7, opornoe * 100);
  EEPROM.write(8, treviga_2);
  myGLCD.clrScr();
  myGLCD.setFont(SmallFontRus);
  myGLCD.print(utf8rus("Сохранено"), CENTER, 20);
  myGLCD.update();
  _delay_ms(1000);
}
//-----------------------------------------------------------------------------------------------------
void eeprom_wrD ()  //запись настроек в память время накопления дозы
{
  EEPROM.put(9, time_doza);
  EEPROM.put(13, doz_v);   
}
//-----------------------------------------------------------------------------------------------------
void eeprom_readD ()  //чтение настроек из памяти время накопления дозы
{
  EEPROM.get(9, time_doza);
  EEPROM.get(13, doz_v);   
}
//-----------------------------------------------------------------------------------------------------
void eeprom_readS ()  //чтение настроек из памяти
{
  if (EEPROM.read(0) == 222) 
	{
		treviga_1 = EEPROM.read(1);
		podsvetka = EEPROM.read(2);
		graph_type = EEPROM.read(3);
		scrin_GRAF = EEPROM.read(4);
		ind_ON = EEPROM.read(5);
		puls = EEPROM.read(6);
		opornoe = EEPROM.read(7) / 100.0;
		treviga_2 = EEPROM.read(8);
	}
_delay_ms(10);
}
//------------------------------------------------------------------------------------------------------
void nakachka() //первая накачка
{
byte n = 0;
while (n < 30) 
	{
		PORTD |= (1 << 5);//дергаем пин
		int c = puls;
		while (c > 0) 
			{
				asm("nop");
				c--;
			}
		PORTD &= ~(1 << 5);//дергаем пин
		n++;
		_delay_us(100);
	}
}
//------------------------------------------------------------------------------------------------------
void speed_nakachka ()  //скорость накачки имлульсы/сек
{
if (millis() - spNAK_milis >= 1000) 
	{
		spNAK_milis = millis();
		speed_nak = speed_nakT;
		speed_nakT = 0;
	}
}
//------------------------------------------------------------------------------------------------------
void time_d() 
{
	MONTH = time_doza / 2592000;
	DAY = (time_doza / 86400) % 30 ;
	HOUR = (time_doza / 3600) % 24 ;
	MIN = (time_doza / 60) % 60;
}
//------------------------------------------------------------------------------------------------------
void check_alarm_signal()  // устанавливаем сигнал непрерывной тревоги, если "tr" переключился в "1"
{
	if (!tr) // если счёт превысил аварийный порог, но флаг "tr" ещё не установлен
		{
			alarm_sound = 1; // поднимаем флаг аварийного сигнала
			alarm_milis = millis(); // запоминаем время начала тревоги
		}
}
//------------------------------------------------------------------------------------------------------
void res_first_alarm() //подпрограмма выключения тревоги (ручного или по истечении таймаута)
{
   alarm_sound = 0; // сбрасываем флаг звукового сигнала тревоги
   PORTB &= ~(1 << 0); // выключаем вибру
   periodical_alarm_variable = 0; // обнуляем переменную
   #ifdef buzzer_active //если задефайнен активный бузер
   PORTD &= ~(1 << 6); // выключаем бузер
   #else //пассивный бузер
   noTone(6);   //выключаем генерацию сигнала на 6й ноге
   #endif
}
//------------------------------------------------------------------------------------------------------
void ind_doze_time() //вывод времени накопления дозы на дисплей
{
	myGLCD.setFont(TinyFontRus);
	if (MONTH) // если есть месяцы
		{
			myGLCD.printNumI(MONTH, 0, 26);
			if(MONTH>99)
				{
					myGLCD.print("M", 13, 26);
				}
			else if (MONTH>9)
				{
					myGLCD.print("M", 9, 26);
				}
			else
				{
					myGLCD.print("M", 5, 26);
				}
		myGLCD.printNumI(DAY, 18, 26);
		if (DAY > 9) 
			{
				myGLCD.print("\xBB", 26, 26);
			}
		else
			{
				myGLCD.print("\xBB", 23, 26);
			}	
		}
	else if (DAY) // если нет месяцев, но есть дни
		{
			myGLCD.printNumI(DAY, 0, 26);
			if (DAY > 9) 
				{
					myGLCD.print("\xBB", 9, 26);
				}
			else
				{
					myGLCD.print("\xBB", 5, 26);
				}
			myGLCD.printNumI(HOUR, 18, 26);
			if (HOUR > 9) 
				{
					myGLCD.print("\xBA", 26, 26);
				}
			else 
				{
					myGLCD.print("\xBA", 23, 26);
				}
		}
	else // если нет дней
		{
			myGLCD.printNumI(HOUR, 0, 26);
			if (HOUR > 9) 
				{
					myGLCD.print("\xBA", 9, 26);
				}
			else
				{
					myGLCD.print("\xBA", 5, 26);
				}
			myGLCD.printNumI(MIN, 18, 26);
			if (MIN > 9) 
				{
					myGLCD.print("\xBC", 26, 26);
				}
			else
				{
					myGLCD.print("\xBC", 23, 26);
				}
		}		

}
//--------------------------------------------------------------------------------------------------------
byte get_key() // Функция определения нажатия и удержания кнопок
{
// версия 1 - для кратковременного нажатия значение возвращается при отпускании кнопки, для длительного - пока кнопка остаётся нажатой, с заданным интервалом
uint8_t trigger_push_hold_counter = 10; // задержка триггера кратковременного/длительного нажатия (проходов функции, умноженных на задержку "milliseconds_between_increment")  
uint8_t milliseconds_between_increment = 50; // интервал в миллисекундах между инкрементом счётчика нажатой кнопки 
static uint8_t val_kp, val_kl, val_ok;
static uint32_t key_delay_millis;
static uint32_t key_delay_after_hold_millis;
if ((millis() - key_delay_millis) > milliseconds_between_increment) //обрабатываем нажатия инкрементом переменной только если после предыдущей обработки прошло не менее "milliseconds_between_increment" миллисекунд
	{
	  if (!(PIND & (1 << PIND4)))  //нажатие >>>
		{
		val_kp++;  // инкрементируем счётчик
		if (val_kp > trigger_push_hold_counter) // если значение счётчика больше порога детектирования удержания клавиши 
			{
			 val_kp = 0; // сбрасываем счётчик 
			 key_delay_after_hold_millis = millis(); // запоминаем время
			 return key_holded_right; // возвращаем значение
			}
		}
	  if (!(PIND & (1 << PIND7)))  //нажатие <<<
		{
		val_kl++;  // инкрементируем счётчик
		if (val_kl > trigger_push_hold_counter) // если значение счётчика больше порога детектирования удержания клавиши
			{
				val_kl = 0; // сбрасываем счётчик
				key_delay_after_hold_millis = millis(); // запоминаем время 
				return key_holded_left; // возвращаем значение
			}   
		}
	  if (!(PIND & (1 << PIND3)))  //нажатие OK
		{
		val_ok++; // инкрементируем счётчик
		if (val_ok > trigger_push_hold_counter) // если значение счётчика больше порога детектирования удержания клавиши
			{
				val_ok = 0; // сбрасываем счётчик
				key_delay_after_hold_millis = millis(); // запоминаем время 
				return key_holded_ok; // возвращаем значение
			}       
		}
	  key_delay_millis = millis(); // запоминаем время 
	}
if (val_ok > 0) //если клавиша OK перед этим была нажата 
	{
		 if ((PIND & (1 << PIND3)) && ((millis() - key_delay_after_hold_millis) > (trigger_push_hold_counter * milliseconds_between_increment))) // если клавиша на данный момент отпущена и с момента последнего удержания любой клавиши прошёл интервал больше, чем один интервал удержания клавиши
			{
				val_ok = 0;  // сбрасываем счётчик
				return key_pressed_ok; // возвращаем значение
			}
	}
if (val_kp > 0) //если клавиша >>> перед этим была нажата 
	{
		if ((PIND & (1 << PIND4)) && ((millis() - key_delay_after_hold_millis) > (trigger_push_hold_counter * milliseconds_between_increment))) // если клавиша на данный момент отпущена и с момента последнего удержания любой клавиши прошёл интервал больше, чем один интервал удержания клавиши
			{
				val_kp = 0;  // сбрасываем счётчик 
				return key_pressed_right; // возвращаем значение
			}
	}
if (val_kl > 0) //если клавиша <<< перед этим была нажата 
	{
		if ((PIND & (1 << PIND7)) && ((millis() - key_delay_after_hold_millis) > (trigger_push_hold_counter * milliseconds_between_increment))) // если клавиша на данный момент отпущена и с момента последнего удержания любой клавиши прошёл интервал больше, чем один интервал удержания клавиши
			{
				val_kl = 0;  // сбрасываем счётчик  
				return key_pressed_left; // возвращаем значение
			}
	}
if (PIND & (1 << PIND4)) {val_kp = 0;} // если добрались до этой точки и кнопка не нажата - обнуляем счётчик (защита от появления "pressed" после "holded")
if (PIND & (1 << PIND7)) {val_kl = 0;} // если добрались до этой точки и кнопка не нажата - обнуляем счётчик (защита от появления "pressed" после "holded")
if (PIND & (1 << PIND3)) {val_ok = 0;} // если добрались до этой точки и кнопка не нажата - обнуляем счётчик (защита от появления "pressed" после "holded")
return 0; // если ни одна из кнопок не была нажата - возвращаем 0
}
//------------------------------------------------------------------------------------------------------------------------------
char *utf8rus(char *source) // функция преобразования utf8 для вывода кириллицы (by arduinec)
{
  int i,j,k;
  unsigned char n;
  char m[2] = { '0', '\0' };

  strcpy(target, ""); k = strlen(source); i = j = 0;

  while (i < k) {
    n = source[i]; i++;

    if (n >= 0xC0) {
      switch (n) {
        case 0xD0: {
          n = source[i]; i++;
          if (n == 0x81) { n = 0xA8; break; }
          if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
          break;
        }
        case 0xD1: {
          n = source[i]; i++;
          if (n == 0x91) { n = 0xB8; break; }
          if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
          break;
        }
      }
    }

    m[0] = n; strcat(target, m);
    j++; if (j >= maxString) break;
  }
  return target;
}

ISR (TIMER1_OVF_vect) // прерывание по таймеру, генерируемое каждую секунду
{ 
timer_seconds++ ; //инкремент переменной каждую секунду
if (timer_seconds > 59){timer_seconds = 0;}
}

Файл gif.c

// файл gif.c
// должен находиться в папке со скетчем

#include <avr/pgmspace.h>
#ifndef fontdatatype
#define fontdatatype const uint8_t
#endif

const unsigned char PROGMEM logo_bat[] =
{ 0x00, 0x00, 0x1C, 0x7F, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x7F};
  
const unsigned char PROGMEM  logo_tr[] =
{ 0x0C, 0x12, 0x21, 0x0C, 0x00, 0x10, 0x28, 0x26, 0x61, 0x61, 0x26, 0x28,
  0x10, 0x00, 0x0C, 0x21, 0x12, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  
const unsigned char PROGMEM  em_logo[] =
{ 0x00, 0x00, 0x10, 0x18, 0x9C, 0xCC, 0xEC, 0xFC,
  0xF8, 0x78, 0x77, 0xE7, 0xC7, 0x80, 0x80, 0x80,
  0x0C, 0x0C, 0x0C, 0x0E, 0x07, 0x43, 0x63, 0x77,
  0x3E, 0x1C, 0x08, 0x00, 0x01, 0x01, 0x01, 0x01};

const unsigned char PROGMEM logo_rag[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF0, 0xF8, 0xF8,
  0xF8, 0xF8, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8,
  0xF8, 0xF8, 0x78, 0x78, 0x78, 0x78, 0xF8, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0,
  0xC0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF0, 0xF8, 0x98, 0x18,
  0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFE, 0xFF, 0xFF, 0x9F, 0x81,
  0x81, 0x81, 0x9F, 0xFF, 0xFF, 0xFC, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFC, 0x1E, 0x0F, 0x0F, 0x0F, 0x06, 0x00, 0xFF, 0xFF,
  0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCF, 0xFF, 0xFF,
  0xFF, 0xFF, 0x00, 0xFC, 0xFF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x36,
  0x78, 0x78, 0x78, 0x36, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF, 0xFC,
  0x00, 0xFC, 0xFE, 0xFF, 0xEF, 0xC7, 0xC7, 0x8F, 0x0F, 0x0E, 0x00, 0x00,
  0x00, 0x00, 0x00, 0xC0, 0xFC, 0xFF, 0xFF, 0xFF, 0x1F, 0x07, 0x07, 0x07,
  0x07, 0x07, 0x07, 0x07, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0xC0, 0x00, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
  0xFF, 0xFF, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x7E, 0x7F, 0x3F, 0x3F,
  0x0F, 0x07, 0x00, 0x01, 0x0F, 0x1E, 0x38, 0x70, 0x60, 0xF0, 0xFE, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0x60, 0x70, 0x38, 0x1F, 0x07, 0x01,
  0x00, 0x79, 0xF9, 0xF1, 0xF3, 0xF7, 0xFF, 0xFF, 0x7F, 0x3E, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,
  0x00, 0x7C, 0x24, 0x24, 0x24, 0x18, 0x00, 0x60, 0x3C, 0x24, 0x3C, 0x60,
  0x00, 0x0C, 0x50, 0x50, 0x50, 0x3C, 0x00, 0x7C, 0x20, 0x10, 0x08, 0x7C,
  0x00, 0x7C, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38,
  0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x60, 0x3E, 0x23, 0x3F, 0x60, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38,
  0x00, 0x28, 0x44, 0x54, 0x54, 0x28, 0x00, 0x7C, 0x20, 0x10, 0x08, 0x7C,
  0x00, 0x7C, 0x08, 0x10, 0x08, 0x7C, 0x00, 0x38, 0x54, 0x54, 0x54, 0x18,
  0x00, 0x04, 0x04, 0x7C, 0x04, 0x04, 0x00, 0x7C, 0x24, 0x24, 0x24, 0x18,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,
  0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
  0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x36, 0x49, 0x49, 0x49, 0x36};


//----------------------------------------------------------------------
// Секция шрифтов


// Font size    : 6x8 pixels
fontdatatype SmallFontRus[] PROGMEM={
0x06,0x08,0x20,0x5F,
0x00,0x00,0x00,0x00,0x00,0x00,  // <space>
0x00,0x00,0x00,0x2F,0x00,0x00,  // !
0x00,0x00,0x07,0x00,0x07,0x00,  // "
0x00,0x14,0x7F,0x14,0x7F,0x14,  // #
0x00,0x24,0x2A,0x7F,0x2A,0x12,  // $
0x00,0x23,0x13,0x08,0x64,0x62,  // %
0x00,0x36,0x49,0x55,0x22,0x50,  // &
0x00,0x00,0x05,0x03,0x00,0x00,  // '
0x00,0x00,0x1C,0x22,0x41,0x00,  // (
0x00,0x00,0x41,0x22,0x1C,0x00,  // )
0x00,0x14,0x08,0x3E,0x08,0x14,  // *
0x00,0x08,0x08,0x3E,0x08,0x08,  // +
0x00,0x00,0x00,0xA0,0x60,0x00,  // ,
0x00,0x08,0x08,0x08,0x08,0x08,  // -
0x00,0x00,0x60,0x60,0x00,0x00,  // .
0x00,0x20,0x10,0x08,0x04,0x02,  // /

0x00,0x3E,0x51,0x49,0x45,0x3E,  // 0
0x00,0x00,0x42,0x7F,0x40,0x00,  // 1
0x00,0x42,0x61,0x51,0x49,0x46,  // 2
0x00,0x21,0x41,0x45,0x4B,0x31,  // 3
0x00,0x18,0x14,0x12,0x7F,0x10,  // 4
0x00,0x27,0x45,0x45,0x45,0x39,  // 5
0x00,0x3C,0x4A,0x49,0x49,0x30,  // 6
0x00,0x01,0x71,0x09,0x05,0x03,  // 7
0x00,0x36,0x49,0x49,0x49,0x36,  // 8
0x00,0x06,0x49,0x49,0x29,0x1E,  // 9
0x00,0x00,0x36,0x36,0x00,0x00,  // :
0x00,0x00,0x56,0x36,0x00,0x00,  // ;
0x00,0x08,0x14,0x22,0x41,0x00,  // <
0x00,0x14,0x14,0x14,0x14,0x14,  // =
0x00,0x00,0x41,0x22,0x14,0x08,  // >
0x00,0x02,0x01,0x51,0x09,0x06,  // ?

0x00,0x32,0x49,0x59,0x51,0x3E,  // @
0x00,0x7C,0x12,0x11,0x12,0x7C,  // A
0x00,0x7F,0x49,0x49,0x49,0x36,  // B
0x00,0x3E,0x41,0x41,0x41,0x22,  // C
0x00,0x7F,0x41,0x41,0x22,0x1C,  // D
0x00,0x7F,0x49,0x49,0x49,0x41,  // E
0x00,0x7F,0x09,0x09,0x09,0x01,  // F
0x00,0x3E,0x41,0x49,0x49,0x7A,  // G
0x00,0x7F,0x08,0x08,0x08,0x7F,  // H
0x00,0x00,0x41,0x7F,0x41,0x00,  // I
0x00,0x20,0x40,0x41,0x3F,0x01,  // J
0x00,0x7F,0x08,0x14,0x22,0x41,  // K
0x00,0x7F,0x40,0x40,0x40,0x40,  // L
0x00,0x7F,0x02,0x0C,0x02,0x7F,  // M
0x00,0x7F,0x04,0x08,0x10,0x7F,  // N
0x00,0x3E,0x41,0x41,0x41,0x3E,  // O

0x00,0x7F,0x09,0x09,0x09,0x06,  // P
0x00,0x3E,0x41,0x51,0x21,0x5E,  // Q
0x00,0x7F,0x09,0x19,0x29,0x46,  // R
0x00,0x46,0x49,0x49,0x49,0x31,  // S
0x00,0x01,0x01,0x7F,0x01,0x01,  // T
0x00,0x3F,0x40,0x40,0x40,0x3F,  // U
0x00,0x1F,0x20,0x40,0x20,0x1F,  // V
0x00,0x3F,0x40,0x38,0x40,0x3F,  // W
0x00,0x63,0x14,0x08,0x14,0x63,  // X
0x00,0x07,0x08,0x70,0x08,0x07,  // Y
0x00,0x61,0x51,0x49,0x45,0x43,  // Z
0x00,0x00,0x7F,0x41,0x41,0x00,  // [
0xAA,0x55,0xAA,0x55,0xAA,0x55,  // <backslash>
0x00,0x00,0x41,0x41,0x7F,0x00,  // ]
0x00,0x04,0x02,0x01,0x02,0x04,  // ^
0x00,0x40,0x40,0x40,0x40,0x40,  // _

0x00,0x00,0x03,0x05,0x00,0x00,  // `
0x00,0x7C,0x12,0x11,0x12,0x7C,  // a
0x00,0x7F,0x49,0x49,0x49,0x36,  // b
0x00,0x7F,0x49,0x49,0x49,0x36,  // c
0x00,0x7F,0x01,0x01,0x01,0x01,  // d
0x00,0x60,0x3E,0x23,0x3F,0x60,  // e
0x00,0x7F,0x49,0x49,0x49,0x41,  // f
0x00,0x77,0x08,0x3E,0x08,0x77,  // g
0x00,0x22,0x49,0x49,0x5D,0x36,  // h
0x00,0x00,0x44,0x7D,0x40,0x00,  // i
0x00,0x40,0x80,0x84,0x7D,0x00,  // j
0x00,0x7F,0x10,0x28,0x44,0x00,  // k
0x00,0x00,0x41,0x7F,0x40,0x00,  // l
0x00,0x7C,0x04,0x18,0x04,0x78,  // m
0x00,0x7C,0x08,0x04,0x04,0x78,  // n
0x00,0x38,0x44,0x44,0x44,0x38,  // o

0x00,0xFC,0x24,0x24,0x24,0x18,  // p
0x00,0x18,0x24,0x24,0x18,0xFC,  // q
0x00,0x7C,0x08,0x04,0x04,0x08,  // r
0x00,0x48,0x54,0x54,0x54,0x20,  // s
0x00,0x04,0x3F,0x44,0x40,0x20,  // t
0x00,0x3C,0x40,0x40,0x20,0x7C,  // u
0x00,0x1C,0x20,0x40,0x20,0x1C,  // v
0x00,0x3C,0x40,0x30,0x40,0x3C,  // w
0x00,0x44,0x28,0x10,0x28,0x44,  // x
0x00,0x1C,0xA0,0xA0,0xA0,0x7C,  // y
0x00,0x44,0x64,0x54,0x4C,0x44,  // z
0x00,0x00,0x10,0x7C,0x82,0x00,  // {
0x00,0x00,0x00,0xFF,0x00,0x00,  // |
0x00,0x00,0x82,0x7C,0x10,0x00,  // }
0x00,0x00,0x06,0x09,0x09,0x06,  // ~
//-----------------------------------
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  //
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 

0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 

0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x7E,0x4B,0x4A,0x4B,0x42,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 

0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  //
0x00,0x00,0x00,0x00,0x00,0x20,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x38,0x55,0x54,0x55,0x58,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  //
0x00,0x00,0x00,0x00,0x00,0x00,  //
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 
0x00,0x00,0x00,0x00,0x00,0x00,  // 

0x00,0x00,0x03,0x05,0x00,0x00,  // 
0x00,0x7C,0x12,0x11,0x12,0x7C,  // 
0x00,0x7F,0x49,0x49,0x49,0x30,  // 
0x00,0x7F,0x49,0x49,0x49,0x36,  // 
0x00,0x7F,0x01,0x01,0x01,0x01,  // 
0x00,0x60,0x3E,0x23,0x3F,0x60,  // 
0x00,0x7F,0x49,0x49,0x49,0x41,  //
0x00,0x77,0x08,0x3E,0x08,0x77,  // 
0x00,0x22,0x49,0x49,0x5D,0x36,  // 
0x00,0x7F,0x30,0x08,0x06,0x7F,  // 
0x00,0x7F,0x30,0x19,0x0C,0x7F,  // 
0x00,0x7F,0x08,0x08,0x14,0x63,  // 
0x00,0x40,0x7E,0x01,0x01,0x7F,  // 
0x00,0x7F,0x02,0x0C,0x02,0x7F,  // 
0x00,0x7F,0x08,0x08,0x08,0x7F,  // 
0x00,0x3E,0x41,0x41,0x41,0x3E,  // 

0x00,0x7F,0x01,0x01,0x01,0x7F,  // 
0x00,0x7F,0x09,0x09,0x09,0x06,  // 
0x00,0x3E,0x41,0x41,0x41,0x22,  // 
0x00,0x01,0x01,0x7F,0x01,0x01,  // 
0x00,0x07,0x48,0x48,0x48,0x3F,  // 
0x00,0x0E,0x11,0x7F,0x11,0x0E,  // 
0x00,0x63,0x14,0x08,0x14,0x63,  // 
0x00,0x3F,0x20,0x20,0x3F,0x60,  // 
0x00,0x07,0x08,0x08,0x08,0x7F,  // 
0x00,0x7F,0x40,0x7E,0x40,0x7F,  // 
0x00,0x3F,0x20,0x3F,0x20,0x7F,  // 
0x40,0x01,0x7F,0x48,0x48,0x30,  // 
0x00,0x7F,0x48,0x30,0x00,0x7F,  // 
0x00,0x7F,0x48,0x48,0x30,0x00,  // 
0x41,0x49,0x49,0x49,0x3E,0x00,  // 
0x00,0x7F,0x08,0x3E,0x41,0x3E,
0x00,0x46,0x29,0x19,0x09,0x7F,
//-----------------------------------
//0x00,0x00,0x00,0x00,0x00,0x00,
//0x00,0x7C,0x10,0x7C,0x44,0x7C,
0x00,0x20,0x54,0x54,0x54,0x78,  // 
0x00,0x3C,0x4A,0x4A,0x4A,0x30,  // 
0x00,0x7C,0x54,0x54,0x54,0x28,  // 
0x00,0x7C,0x04,0x04,0x04,0x00,  // 
0x00,0x60,0x3C,0x24,0x3C,0x60,  // 
0x00,0x38,0x54,0x54,0x54,0x18,  // 
0x00,0x6C,0x10,0x7C,0x10,0x6C,  // 
0x00,0x28,0x44,0x54,0x54,0x28,  // 
0x00,0x7C,0x20,0x10,0x08,0x7C,  // 
0x00,0x7C,0x20,0x12,0x08,0x7C,  // 
0x00,0x7C,0x10,0x10,0x28,0x44,  // 
0x00,0x40,0x7C,0x04,0x04,0x7C,  // 
0x00,0x7C,0x08,0x10,0x08,0x7C,  // 
0x00,0x7C,0x10,0x10,0x10,0x7C,  // 
0x00,0x38,0x44,0x44,0x44,0x38,  // 

0x00,0x7C,0x04,0x04,0x04,0x7C,  // 
0x00,0x7C,0x24,0x24,0x24,0x18,  // 
0x00,0x38,0x44,0x44,0x44,0x28,  // 
0x00,0x04,0x04,0x7C,0x04,0x04,  // 
0x00,0x0C,0x50,0x50,0x50,0x3C,  // 
0x00,0x18,0x24,0x7C,0x24,0x18,  // 
0x00,0x44,0x28,0x10,0x28,0x44,  // 
0x00,0x3C,0x20,0x20,0x3C,0x60,  // 
0x00,0x1C,0x20,0x20,0x7C,0x00,  // 
0x00,0x7C,0x40,0x78,0x40,0x7C,  // 
0x00,0x3C,0x20,0x3C,0x20,0x7C,  // 
0x40,0x04,0x7C,0x50,0x50,0x20,  //
0x00,0x7C,0x50,0x70,0x00,0x7C,  // 
0x00,0x7C,0x50,0x50,0x20,0x00,  // 
0x44,0x54,0x54,0x54,0x38,0x00,  // 
0x00,0x7C,0x10,0x7C,0x44,0x7C,
0x00,0x48,0x54,0x34,0x14,0x7C,
};

/*
fontdatatype rus_4x6[] PROGMEM =
{
0x04, 0x08, 0xC0, 0x20,
0x00, 0x3c, 0x12, 0x3c,                        // Code for char А
0x00, 0x3E, 0x2A, 0x12,                        // Code for char Б
0x00, 0x3E, 0x2A, 0x14,                        // Code for char В
0x00, 0x3E, 0x02, 0x02,                        // Code for char Г
0x00, 0x30, 0x1E, 0x30,                        // Code for char Д
0x00, 0x3E, 0x2A, 0x22,                        // Code for char Е
0x00, 0x36, 0x3E, 0x36,                        // Code for char Ж
0x00, 0x22, 0x2A, 0x14,                        // Code for char З
0x00, 0x3E, 0x18, 0x3E,                        // Code for char И
0x00, 0x3E, 0x19, 0x3E,                        // Code for char Й
0x00, 0x3E, 0x08, 0x22,                        // Code for char К
0x00, 0x3C, 0x02, 0x3E,                        // Code for char Л
0x00, 0x3E, 0x0E, 0x3E,                        // Code for char М
0x00, 0x3E, 0x08, 0x3E,                        // Code for char Н
0x00, 0x1C, 0x22, 0x1C,                        // Code for char О
0x00, 0x3E, 0x02, 0x3E,                        // Code for char П
0x00, 0x3E, 0x0A, 0x04,                        // Code for char Р
0x00, 0x1C, 0x22, 0x14,                        // Code for char С
0x00, 0x02, 0x3E, 0x02,                        // Code for char Т
0x00, 0x06, 0x28, 0x1E,                        // Code for char У
0x00, 0x1C, 0x3E, 0x1C,                        // Code for char Ф
0x00, 0x36, 0x08, 0x36,                        // Code for char Х
0x00, 0x1E, 0x10, 0x2E,                        // Code for char Ц
0x00, 0x0E, 0x08, 0x3E,                        // Code for char Ч
0x00, 0x3E, 0x38, 0x3E,                        // Code for char Ш
0x00, 0x1E, 0x1C, 0x3E,                        // Code for char Щ
0x00, 0x3E, 0x28, 0x10,                        // Code for char Ъ
0x3E, 0x30, 0x00, 0x3E,                        // Code for char Ы
0x00, 0x3E, 0x28, 0x10,                        // Code for char Ь
0x00, 0x14, 0x2A, 0x1C,                        // Code for char Э
0x3E, 0x08, 0x3E, 0x3E,                        // Code for char Ю
0x00, 0x34, 0x0A, 0x3E,                        // Code for char Я
};
*/

fontdatatype TinyFontRus[] PROGMEM =
{
0x04, 0x06, 0x20, 0x5f,
0x00, 0x00, 0x00, 0x03, 0xa0, 0x00, 0xc0, 0x0c, 0x00, 0xf9, 0x4f, 0x80, 0x6b, 0xeb, 0x00, 0x98, 0x8c, 0x80, 0x52, 0xa5, 0x80, 0x03, 0x00, 0x00,  // Space, !"#$%&'
0x01, 0xc8, 0x80, 0x89, 0xc0, 0x00, 0x50, 0x85, 0x00, 0x21, 0xc2, 0x00, 0x08, 0x40, 0x00, 0x20, 0x82, 0x00, 0x00, 0x20, 0x00, 0x18, 0x8c, 0x00,  // ()*+,-./
0xfa, 0x2f, 0x80, 0x4b, 0xe0, 0x80, 0x5a, 0x66, 0x80, 0x8a, 0xa5, 0x00, 0xe0, 0x8f, 0x80, 0xea, 0xab, 0x00, 0x72, 0xa9, 0x00, 0x9a, 0x8c, 0x00,  // 01234567
0xfa, 0xaf, 0x80, 0x4a, 0xa7, 0x00, 0x01, 0x40, 0x00, 0x09, 0x40, 0x00, 0x21, 0x48, 0x80, 0x51, 0x45, 0x00, 0x89, 0x42, 0x00, 0x42, 0x66, 0x00,  // 89:;<=>?
0x72, 0xa6, 0x80, 0x7a, 0x87, 0x80, 0xfa, 0xa5, 0x00, 0x72, 0x25, 0x00, 0xfa, 0x27, 0x00, 0xfa, 0xa8, 0x80, 0xfa, 0x88, 0x00, 0x72, 0x2b, 0x00,  // @ABCDEFG
0xf8, 0x8f, 0x80, 0x8b, 0xe8, 0x80, 0x8b, 0xe8, 0x00, 0xf8, 0x8d, 0x80, 0xf8, 0x20, 0x80, 0xf9, 0x0f, 0x80, 0xf9, 0xcf, 0x80, 0x72, 0x27, 0x00,  // HIJKLMNO
0xfa, 0x84, 0x00, 0x72, 0x27, 0x40, 0xfa, 0x85, 0x80, 0x4a, 0xa9, 0x00, 0x83, 0xe8, 0x00, 0xf0, 0x2f, 0x00, 0xe0, 0x6e, 0x00, 0xf0, 0xef, 0x00,  // PQRSTUVW
0xd8, 0x8d, 0x80, 0xc0, 0xec, 0x00, 0x9a, 0xac, 0x80, 0x03, 0xe8, 0x80, 0xc0, 0x81, 0x80, 0x8b, 0xe0, 0x00, 0x42, 0x04, 0x00, 0x08, 0x20, 0x80,  // XYZ[\]^_
0x02, 0x04, 0x00, 0x31, 0x23, 0x80, 0xf9, 0x23, 0x00, 0x31, 0x24, 0x80, 0x31, 0x2f, 0x80, 0x31, 0x62, 0x80, 0x23, 0xea, 0x00, 0x25, 0x53, 0x80,  // `abcdefg
0xf9, 0x03, 0x80, 0x02, 0xe0, 0x00, 0x06, 0xe0, 0x00, 0xf8, 0x42, 0x80, 0x03, 0xe0, 0x00, 0x79, 0x87, 0x80, 0x39, 0x03, 0x80, 0x31, 0x23, 0x00,  // hijklmno
0x7d, 0x23, 0x00, 0x31, 0x27, 0xc0, 0x78, 0x84, 0x00, 0x29, 0x40, 0x00, 0x43, 0xe4, 0x00, 0x70, 0x27, 0x00, 0x60, 0x66, 0x00, 0x70, 0x67, 0x00,  // pqrstuvw
0x48, 0xc4, 0x80, 0x74, 0x57, 0x80, 0x59, 0xe6, 0x80, 0x23, 0xe8, 0x80, 0x03, 0x60, 0x00, 0x8b, 0xe2, 0x00, 0x61, 0x0c, 0x00,                     // zyx{|}~
0x00, 0x00, 0x1E, // Index: 95 (0x005F)  Character: 0x007F ('')
0x01, 0x07, 0x96, // Index: 96 (0x0060)  Character: 0x0080 ('?')
0x00, 0x07, 0x90, // Index: 97 (0x0061)  Character: 0x0081 ('?')
0x00, 0x30, 0x00, // Index: 98 (0x0062)  Character: 0x0082 ('?')
0x00, 0x00, 0x00, // Index: 99 (0x0063)  Character: 0x0083 ('?')
0x0C, 0x00, 0x00, // Index: 100 (0x0064)  Character: 0x0084 ('?')
0x00, 0x00, 0x00, // Index: 101 (0x0065)  Character: 0x0085 ('?')
0x00, 0x00, 0x00, // Index: 102 (0x0066)  Character: 0x0086 ('?')
0x00, 0x00, 0x00, // Index: 103 (0x0067)  Character: 0x0087 ('?')
0x00, 0x00, 0x00, // Index: 104 (0x0068)  Character: 0x0088 ('?')
0x00, 0x00, 0x00, // Index: 105 (0x0069)  Character: 0x0089 ('?')
0x00, 0x00, 0x00, // Index: 106 (0x006A)  Character: 0x008A ('?')
0x00, 0x01, 0x0A, // Index: 107 (0x006B)  Character: 0x008B ('?')
0x00, 0x00, 0x00, // Index: 108 (0x006C)  Character: 0x008C ('?')
0x01, 0xE3, 0x12, // Index: 109 (0x006D)  Character: 0x008D ('?')
0x01, 0x07, 0x96, // Index: 110 (0x006E)  Character: 0x008E ('?')
0x01, 0xE0, 0xDE, // Index: 111 (0x006F)  Character: 0x008F ('?')
0x01, 0xE1, 0x80, // Index: 112 (0x0070)  Character: 0x0090 ('?')
0x01, 0x00, 0x00, // Index: 113 (0x0071)  Character: 0x0091 ('?')
0x01, 0x00, 0x00, // Index: 114 (0x0072)  Character: 0x0092 ('?')
0x40, 0x00, 0x00, // Index: 115 (0x0073)  Character: 0x0093 ('?')
0x00, 0x00, 0x00, // Index: 116 (0x0074)  Character: 0x0094 ('?')
0x00, 0x00, 0x00, // Index: 117 (0x0075)  Character: 0x0095 ('?')
0x00, 0x00, 0x00, // Index: 118 (0x0076)  Character: 0x0096 ('?')
0x00, 0x00, 0x00, // Index: 119 (0x0077)  Character: 0x0097 ('?')
0x00, 0x00, 0x00, // Index: 120 (0x0078)  Character: 0x0098 ('')
0x00, 0x00, 0x00, // Index: 121 (0x0079)  Character: 0x0099 ('?')
0x00, 0x00, 0x00, // Index: 122 (0x007A)  Character: 0x009A ('?')
0x00, 0x02, 0x84, // Index: 123 (0x007B)  Character: 0x009B ('?')
0x00, 0x00, 0x00, // Index: 124 (0x007C)  Character: 0x009C ('?')
0x00, 0x00, 0x00, // Index: 125 (0x007D)  Character: 0x009D ('?')
0x00, 0x00, 0x00, // Index: 126 (0x007E)  Character: 0x009E ('?')
0x00, 0x00, 0x00, // Index: 127 (0x007F)  Character: 0x009F ('?')
0x00, 0x00, 0x00, // Index: 128 (0x0080)  Character: 0x00A0 (' ')
0x00, 0x00, 0x00, // Index: 129 (0x0081)  Character: 0x00A1 ('?')
0x00, 0x00, 0x00, // Index: 130 (0x0082)  Character: 0x00A2 ('?')
0x00, 0x00, 0x9C, // Index: 131 (0x0083)  Character: 0x00A3 ('?')
0x00, 0x00, 0x00, // Index: 132 (0x0084)  Character: 0x00A4 ('¤')
0x00, 0x00, 0x00, // Index: 133 (0x0085)  Character: 0x00A5 ('?')
0x00, 0x00, 0x00, // Index: 134 (0x0086)  Character: 0x00A6 ('¦')
0x00, 0x00, 0x00, // 0xA7  
0x03, 0xFF, 0xFF, // 0xA8   |||
0x00, 0x0F, 0xFF, // 0xA9    ||
0x00, 0x00, 0x3F, // 0xAA     |
0x82, 0x08, 0x20, // 0xAB 1-
0xC3, 0x0C, 0x30, // 0xAC 2-
0xE3, 0x8E, 0x38, // 0xAD 3-
0xF3, 0xCF, 0x3C, // 0xAE 4-
0xFB, 0xEF, 0xBE, // 0xAF 5-
0x3C, 0xF3, 0xCF, // 0xB0 5_
0x3C, 0xF3, 0xCF, // 0xB1 4_
0x1C, 0x71, 0xC7, // 0xB2 3_
0x0C, 0x30, 0xC3, // 0xB3 2_
0x04, 0x10, 0x41, // 0xB4 1_
0xFF, 0xFF, 0xFF, // 0xB5 ||||
0xFF, 0xFF, 0xC0, // 0xB6 |||
0xFF, 0xF0, 0x00, // 0xB7 ||
0xFC, 0x00, 0x00, // 0xB8 |
0x38, 0xA2, 0x80, // 0xB9 с
0x30, 0x43, 0x80, // 0xBA ч
0x18, 0xC1, 0x80, // 0xBB д 
0x38, 0xC3, 0x80, // 0xBC м
0x38, 0x42, 0x80, // 0xBD к
0xFA, 0x84, 0x8C, // 0xBE Р/
0x40, 0xC1, 0x0E, // 0xBF /ч
0x7A, 0x87, 0x80, // А
0xFA, 0xAB, 0x80, // Б
0xFA, 0xA5, 0x00, // В
0xFA, 0x08, 0x00, // Г
0x1B, 0xC1, 0x80, // Д
0xFA, 0xA8, 0x80, // Е
0xDB, 0xED, 0x80, // Ж
0x8A, 0xA5, 0x00, // З
0xF8, 0xCF, 0x80, // И
0x7A, 0xC7, 0x80, // Й
0xF8, 0x89, 0x80, // К
0x7A, 0x0F, 0x80, // Л
0xFB, 0x8F, 0x80, // М
0xF8, 0x8F, 0x80, // Н
0x72, 0x27, 0x00, // О
0xFA, 0x0F, 0x80, // П
0xFA, 0x84, 0x00, // Р
0x72, 0x28, 0x80, // С
0x83, 0xE8, 0x00, // Т
0xE8, 0xAF, 0x00, // У
0x73, 0xE7, 0x00, // Ф
0x89, 0xC8, 0x80, // Х
0xF8, 0x2F, 0x83, // Ц
0xE0, 0x8F, 0x80, // Ч
0xF8, 0xEF, 0x80, // Ш
0xF8, 0xEF, 0xC0, // Щ
0x83, 0xE2, 0x84, // Ъ
0xF8, 0xA1, 0x3E, // Ы
0xF8, 0xA1, 0x00, // Ь
0x8A, 0xA7, 0x00, // Э
0xF9, 0xC8, 0x9C, // Ю
0x5A, 0x8F, 0x80, // Я
};

 

kkk51
Offline
Зарегистрирован: 05.03.2019

Здравствуйте.на какое напряжение должен быть конденсатор в цепи катода счётчика?100V нормально?

 

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

На 50V более чем достаточно. Смотрел осликом, импульс 2-3 вольта. Хотя ослик не самый быстрый, верх иглы может и не видеть.

f_max
Offline
Зарегистрирован: 29.03.2019

Здравствуйте, Tagaki! Большое спасибо за вашу деятельность. При сборке дозиметра по схеме (Собираем с микроконтроллером Arduino Uno) (из сайта http://srukami.inf.ua/ardos.html), с прошивкой 1.05 возникла проблема. Номиналы резисторов, конденсаторов, транзисторов совпадают со схемой. Трансформатор 4 витка на гантельке 10 млГ + удвоитель напряжения. При вынутой колбе счетчика, в момент запуска загружается заставка, на секунду идет отсчет больших чисел радиации и потом вся информация пропадает с дисплея, при чем он светиться. При отключении 5 пина экран включается, картинка есть, но счета нет. Транзистор накачки целый, вроде бы, на держателях СБМ20 возникает напряжение 420 вольт. Почему на дисплее возникает информация о подсчете дозы, когда база транзистора на 2 пине отключен?

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

Если замер на держателях счётчика обычным мультиметром выдаёт 420В - то в действительности там напряжение явно больше киловольта, идёт дикая перекачка.
1. Выкладывайте детальное фото того, что уже собрали. (На беспаечной макетке и с длинными втыкаемыми хвостами схема нормально работать не будет.) Также нужен скриншот второго уровня меню (системного).
2. Куда подсаживали вход обратной связи с делителя? На большинстве плат UNO отсутствует вход А6. Или использовался китайский клон с выведенными А6 и А7?
3. Умножитель уберите. При гантельке в 10мГ он излишен, и работа с ним в текущих прошивках не поддерживается. Один диод, один конденсатор на 630V.
4. Используйте скетч и файл gif.c из поста выше. По старым версиям здесь никто не подскажет.
5. На 15й странице есть детальное описание первого запуска и настройки. Пройдите поэтапно. С постом #26 на первой странице тоже рекомендуется ознакомиться. (Особенно обратите внимание на изменения в схеме, указанные красным цветом).

blokerun2
Offline
Зарегистрирован: 27.01.2019

Приветствую всех дозиметристов!

Свой дозиметр вчера уже облагородил полностью. Вставил в корпус от "Беллы".

kkk51
Offline
Зарегистрирован: 05.03.2019

здравствуйте. подскажите почем унету напряжения на выходе трансформатора,точнее оно было но потом пропало.вот ссылка на проект в изи идея(https://easyeda.com/nyonya2003/55343)

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

kkk51, детальное фото собранной платы с двух сторон, скриншот системного меню, потребляемый ток.

kkk51
Offline
Зарегистрирован: 05.03.2019

ток померить немогу(сгорел предохранитель в мультиметре).и еще у меня есть мысль о браке конденсаторов на 10 мкф.трансформатор пробовал паять от старого дозиметра

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

Какое напряжение на конденсаторах преобразователя? На высокой и низкой стороне. Если есть дроссель на гантельке 2-10мГ - припаяйте к его выводам светодиод (лучше в прозрачном корпусе) и поднесите гантелькой сверху к трансформатору, будет светиться или нет.

kkk51
Offline
Зарегистрирован: 05.03.2019

на высокой части 33в , а на низкой 3.99в

kkk51
Offline
Зарегистрирован: 05.03.2019

в моем городе проблемы с индуктивностями

 

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

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

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

kkk51
Offline
Зарегистрирован: 05.03.2019

под микроскопом нашел замыкание дорожек.теперь на конденсаторе в высокой части 280в , а на дисплее показывается 9-12в конденсатор на 630в

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

Монтаж и дорожки проверять надо в первую очередь, до обращения на форум (отмывать флюс тоже).

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

Проверяйте правильность коэффициентов k_delitel и ADC_value, номиналы элементов делителя, цепи обратной связи по напряжению. Если покрытие на ВВ часть наносили недавно - вполне может быть ещё невысохшим и вносить искажения. Если маска УФ - то на подоконник на солнышко на недельку (без аккума). Либо недомыта/недосушена плата.

kkk51
Offline
Зарегистрирован: 05.03.2019

здравствуйте.ОГРОМНОЕ СПАСИБО tekadi.проблема была найдена и она заключалась в резисторе на 10мом китайцы подсунули брак

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

Напряжение откалибровали? Какая скорость накачки?

kkk51
Offline
Зарегистрирован: 05.03.2019

401.188

 

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

Великовата. Одновременные показания мультиметра на высоковольтном конденсаторе и вольтметра в системном меню?
Фазировку транса проверяли?

kkk51
Offline
Зарегистрирован: 05.03.2019

мультимерт 250в в меню 251в

поменял фазировку

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

Более-менее нормально. Если при изменении уровня накачки в пределах 2-15 скорость не уменьшается - то можно так и оставить.

kkk51
Offline
Зарегистрирован: 05.03.2019

 

Здравствуйте. Вчера собрал дозиметр в корпус , корпус напечатал на 3д принтере , то измерение радиоктивных электродов.Все работает НОРМАЛЬНО!!!!!!!

1707
Offline
Зарегистрирован: 08.02.2017

Привет мужики. Опять вернулся к проекту, прицепил индуктивность на 10.000, накачка 387, импульсов 504.

Со старта за пару минут показания доходят до 40мкР, и постепенно опускается до 35мкР и дрейфуют в этом районе. У меня 3 датчика из разных мест, плата 3-я по счёту, а данные одни те же всегда, по средним данным показания должны кружиться в районе 20мкР. Прошивка 1.07. Так и не разобрался почему так, как ни переделывал. Вижу новые прошивки вышли, какую заливать 1,8,1 или 1,8,2?

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

1707 пишет:
...какую заливать 1,8,1 или 1,8,2?...

Последнюю вестимо. Там для каждой чейнджлог под спойлером. Но всё равно это далеко не финальная версия, ещё много чего допиливать надо.

1707 пишет:
...накачка 387, импульсов 504....

Скорость слишком высокая, генератор плохо работает. Традиционные вопросы: кондёры керамика, фазировка транса проверена? Раньше нормально ж работал.

1707 пишет:
...Со старта за пару минут показания доходят до 40мкР, и постепенно опускается до 35мкР и дрейфуют в этом районе....

У меня тоже немного завышает, хотя по импульсам вроде всё верно. Последние прошивки будут давать чуть меньший результат, время счёта уменьшено на 4 секунды. Можно сделать вычет собственного фона, вот только достоверно замерить его не выйдет... Ну и не забываем про отсутствие (в большинстве) компенсирующего экрана, и соответственно неравномерность и суммирование показаний от гаммы и беты.

Silent Hunter
Offline
Зарегистрирован: 14.04.2019

Приветствую всех.

Просмотрев видео от bodriy2014 появилось желание повторить данный конструктив. Понравилась реализация и вразумительные объяснения основных моментов. Так как интересовала скорость измерения решил применить четыре  СБМ-20. Высоковольтный преобразователь собрал на MC 34063 http://radiostorage.net/3870-preobrazovatel-napryazheniya-dc-dc-400v-dlya-schetchika-gejgera-mc34063.html.

Использовал Arduino nano.

Трубки подключил по этой схеме:

Вот что из этого получилось.

  

Прошивку использую 1.08.2 , время счёта установил 9 сек(с учётом четырёх счётчиков). Работой прибора доволен.

Хотелось-бы выразить благодарность bodriy2014 tekagi и всем кто помогал проекту.

п.с. присутствует такой баг, периодически слетает прошивка, независимо от версии. Пробовал другую ардуинку, дефект повторился. Есть ощущение, что проблема аппаратная - например: когда садится батарея, после полного отключения может слететь прошива, но не всегда. Иногда слетает просто при включении. Случается это периодически, может кто сталкивался???    

 

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

Silent Hunter, почему решили использовать внешний преобразователь? Оно ж есть аккум будет столовой ложкой. С подобной схемой, емнип, Joiner экспериментировал.

В коде можно функцию накачки отключить, оставив только замер.

Провода на электролит слишком длинные, укоротить бы. И керамики между Vcc и Gnd ардуинки добавить. Непосредственно возле узла повышайки тоже нужны электролит low esr + керамика. Блокировка работы по снижению питания планируется в ближайших версиях.

Плюс на ардуину подан на Vcc или Vin?

Для четырёх счётчиков получится очень низкий порог переполнения, порядка пары миллирентген. Это тоже в планах по доработке кода.

Можно было поставить один СИ22Г, чувствительность была бы выше четырёх СБМ20. Минуса два - он тупой по бете и размер поболе.

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

tekagi пишет:

Silent Hunter, почему решили использовать внешний преобразователь? Оно ж есть аккум будет столовой ложкой. С подобной схемой, емнип, Joiner экспериментировал.......................................................

Эксперименты продолжаются, я уперся рогом и уверен до сих пор, что не царское дело для ардуинки преобразованием заниматься :) Я уже на пороге решения. Научился генерировать импульсы длительностью 40 наносекунд на частоте 3-10 килогерц.

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

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

В посте #26 на первой странице есть ссылка на видео с осцилла, там видно. Около 3 микросекунд, 18-80 импульсов в секунду (при дополнительной нагрузке в 10М по выходу выпрямителя до 380 имп/с).  Это для транса на гантельке 6х8, для большего размера управляющий импульс будет длиннее.

1707
Offline
Зарегистрирован: 08.02.2017

tekagi

Традиционные вопросы: кондёры керамика, фазировка транса проверена?

Транс стоит по схеме точно, стороны не перепутал.

Раньше нормально ж работал.

Да, но я случайно протерял то что сделал по трансам( Остался транс где накачка под 400, напруга на кондёре 220В, импульсов около 240. Кондёры с ноутбука выдрал

 

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

Не стороны, фазировка. Поменять местами выводы одной (любой) обмотки.

Если сердечник большой - стоит добавить ещё керамики, до 30-40мкФ.

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

tekagi пишет:

В посте #26 на первой странице есть ссылка на видео с осцилла, там видно. Около 3 микросекунд, 18-80 импульсов в секунду (при дополнительной нагрузке в 10М по выходу выпрямителя до 380 имп/с).  Это для транса на гантельке 6х8, для большего размера управляющий импульс будет длиннее.

Огромное спасибо. Буду изучать дальше. Импульсная электроника очень не проста, как на первый взгляд. Да и MC34063 оказалась не совсем такой, какой я ее представлял.

Silent Hunter
Offline
Зарегистрирован: 14.04.2019

tekagi, внешний преобразователь применён по банально-простой причине, MC 34063 была в наличии, а нужный мосфет и ультрафаст диодов не оказалось. Плюс данная схема универсальна к напряжению питания, присутствует стабилизация выходного напряжения, существует возможность оперативного изменения выходного напряжения в широком диапазоне. Что при экспериментах с другими датчиками может понадобится, к тому-же нагрузочная способность данного преобразователя достаточно большая, плюс он может работать автономно. Несмотря на древность самой микрухи, работает она вобщемто неплохо.  Минус пожалуй один, сравнительно большое потребление (в моём случае 50 mA).    

Керамика между Vcc и Gnd ардуины установлена.

Плюс питания батареи подан на Vcc  ардуины.

Возле узла повышайки  электролит low esr полимерный установлен, а вот керамику не ставил(может и зря) посчитав что данный преобразователь сравнительно низкочастотный.

Низкий порог переполнения для четырёх счётчиков это безусловно нехорошо...

 

 

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

Полевички подобные можно и со старых ноутовских материнок наковырять, да и стоят недорого. Ультрафаст со скрипом меняется на что-то из HERxxx (точно не помню).
Лучше уж было сделать блокинг с обратной связью через супрессор, экономнее минимум в два раза.
Со слётом прошивки - не подскажу, может и импульсные наводки, может и при просадке питания и обращению к еепром (отсечка будет позже). Кстати, на какое значение выставлен дефайн #define save_DOZ?
В текущей конфигурации верхний порог будет около 2000мкР/ч. Больше сейчас можно сделать только на прошивке для СИ22Г, но там недоработок много.

Silent Hunter
Offline
Зарегистрирован: 14.04.2019

define save_DOZ 20

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

Попробуйте три ноля добавить, и погонять девайс в разных режимах, слетит или нет. Доза сохраняться не будет, но и ЕЕПРОМ дёргать не должен.

Преобразователь АрДоса тоже может менять выходное, изменением дефайна (при желании можно и в меню вывести). Хотя большинство счётчиков работают в пределах 400 вольт, стеклянные с другим газовым составом требуют больше тысячи.

Silent Hunter
Offline
Зарегистрирован: 14.04.2019

Всё принято, пошел пробовать.

1707
Offline
Зарегистрирован: 08.02.2017

Дожил, не могу скомпилировать прошивку, какая то ошибка warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] как я понял по библиотеке экрана

 
     
DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

это не ошибка, а предупреждение.  скорее всего обьявил строку как 

char *myString = "blablabla";

надо переделать на 

char myString[] = "blablabla";

и то и другое амбивалентно, а канпилятор не ругаеца

 
1707
Offline
Зарегистрирован: 08.02.2017

Полтергейтс, usbasp и usb ttl так и не прошили платку. Изначально шил usb ttl и всё было без проблем, плата Александра. Видимо хана обоим программаторам( Хоть они и определяют, питание идёт на дозиметр и он работает.

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

я на плоншете, канпа нет под рукой

1707
Offline
Зарегистрирован: 08.02.2017

Всем привет. Всё же вынужден просить помощь, не могу залить новую прошивку, и видимо ушатал ардуинку, так как при подключении горит постоянно красный без реакции на ресет. Ком порт определяется, при отправке 123 на программаторе моргает светодиод, но залить ничего не получается и прибор не включается. Взял новую ардуинку с пакета, подключил, зелёный горит, красный моргает, ком порт есть, ресет нажимал в любых вариациях - ничего не залтвает, даже загрузчик. Куда копать не знаю, шью USB TTL CP2102, USBasp есть, им тоже не шьёт.

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

Dtr подключён? Usbasp используется как программатор или как конвертер юсб<>юарт? Соединено верно, rx-tx, tx-rx, gnd-gnd, dtr-dtr?

1707
Offline
Зарегистрирован: 08.02.2017

Так точно, всё верно подключаю TTL, им же заливал первую прошивку. Постоянно горящий светодиод красный и отсуствие реакции на нажатие кнопки видимо говорит о смерти, т.к. реакция была, но в ходе попыток прошивки пропала. Юсбасп припаивал к ногам сбоку на 6 пинов.

----------------------------

Выпаял всё к фигам, ардуино сгорела, может кто знает что там надо заменить для оживления, уже 2 лежит.

Зашил новую, вставил, всё работает, по питанию нахреначил кондёров, теперь крутится в районе 20 туда сюда (накачка 400 импульсов 200, транс дроссель 10000), т.е. хороший результат. Плата ушатана, сделаю новую, она будет наверное 4 или 5 :)

Новая плата будет от Александра от 17,02,2019 года, Arezus если можно поделитесь корпусом lee11@ya.ru

alexadresat
alexadresat аватар
Offline
Зарегистрирован: 22.02.2017

1707 - советую ардуинку не запаивать, а ставить через низкопрофильный цанговый разъём. Ответную часть не обязательно, просто используй выводы (ножки) от транзисторов (желательно позолоченные).

Radioactive
Offline
Зарегистрирован: 20.04.2019

Подскажите как прошить голую мегу 328 через ide? Может им у кого-нибудь есть hex прошивки?

Radioactive
Offline
Зарегистрирован: 20.04.2019

Подскажите как прошить голую мегу 328 через ide? Может им у кого-нибудь есть hex прошивки?

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

Хекс отлично собирается ИДЕ, плюс под свою версию надо же коэффициенты проставить. Проще всего с помощью программатора залить ардуиновский загрузчик, а потом заливать/обновлять прошивку из ИДЕ по юарт.

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

Radioactive
Offline
Зарегистрирован: 20.04.2019

Пробовал, проблемы ещё на этапе компиляции, выдает ошибку компиляции для платы. В моем случае голая мега, выбираю arduino genios uno. Пробовал разные платы, одна дичь.