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

P32L
Offline
Зарегистрирован: 05.04.2016


C:\Users\Nikolay\AppData\Local\Temp\cc8vOB1A.ltrans0.ltrans.o: In function `lcd_init':

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:623: undefined reference to `logo_rag'

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:623: undefined reference to `logo_rag'

C:\Users\Nikolay\AppData\Local\Temp\cc8vOB1A.ltrans0.ltrans.o: In function `lcd_poisk':

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:412: undefined reference to `logo_tr_OLED'

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:412: undefined reference to `logo_tr_OLED'

C:\Users\Nikolay\AppData\Local\Temp\cc8vOB1A.ltrans0.ltrans.o: In function `gif_nabor':

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:309: undefined reference to `gif_chast_1'

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:309: undefined reference to `gif_chast_1'

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:311: undefined reference to `gif_chast_2'

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:311: undefined reference to `gif_chast_2'

C:\Users\Nikolay\AppData\Local\Temp\cc8vOB1A.ltrans2.ltrans.o: In function `battery()':

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:713: undefined reference to `logo_bat'

H:\electronics\Дозиметры\33\ARDOs_noSleep_v105_oled/ARDOs_noSleep_v105_oled.ino:713: undefined reference to `logo_bat'

collect2.exe: error: ld returned 1 exit status

exit status 1
Ошибка компиляции для платы Arduino Nano.

 

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

в папке со скетчем отсутствует файл gif.c;

в пути к файлам не должно быть кириллицы.

P32L
Offline
Зарегистрирован: 05.04.2016

Исправил.

Изменены опции сборки, пересобираем все
H:\electronics\Dosimetr\33\ARDOs_noSleep_v105_oled\ARDOs_noSleep_v105_oled.ino: In function 'void zamer_180s()':

ARDOs_noSleep_v105_oled:344:4: error: expected primary-expression before ')' token

   ();

    ^

exit status 1
expected primary-expression before ')' token

 

P32L
Offline
Зарегистрирован: 05.04.2016


 

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

tekagi пишет:
SergeiEU, здесь проблема проще и не упирается в физические ограничения датчика. У нас есть массив byte, по которому перемещается окно счёта. То есть даже при условии равномерного распределения имульсов (что уже крайне маловероятно) мы за секунду можем подсчитать всего до 255. А делать массив uint16_t такого же размера не даёт ограничение оперативки...

Понятно, значит вы используете примерно одну десятую часть из всего диапазона измерений датчика. Диапазона измерений датчика СБМ-20 от 14,4 мкР/ч до 144000 мкР/ч или в импульсах в секунду: от 0,27 до 2700.

Моя идея была несколько иной. Сохранять в массив не частоты разрядов в единицу времени, а сами промежутки между разрядами, т.е. временные интервалы между разрядами в миллисекундах. Тогда мы решаем сразу две проблемы: (1) легко находим среднюю статистику и (2) решаем проблему медленной реакции регистратора на большие выбросы радиации, так как в нашем случае чем больше разрядов в секунду, тем быстрее заполняется массив и тем быстрее идет окончательный подсчет значений. То есть реакция регистратора на выбросы радиации идет пропорционально количеству радиации. К примеру, если радиоактивный фон подскочит в два раза, то и подсчет будет в двое быстрее и т.д.

P32L
Offline
Зарегистрирован: 05.04.2016

Спасибо! Разобрался.У меня еще проблема с библиотекой OLED была.Схема я так понимаю эта же ?

PS под OLED не нашел ...

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

SergejEU, думал об этом, скорее всего так буду делать для мелких сбм10 или сбм21. С СБМ20 так делать не хочу, при большом фоне будем часто падать в прерывание и в каждом обрабатывать uint32, да ещё и с вызовом миллис. Стабильности явно не прибавится :(
P32L, погуглите "подключение oled дисплея по spi", там 4 провода: питание, gnd, A4, A5. Всё остальное как на приведённой схеме. А вообще схему на олед повторять не рекомендую, там старый скетч, который давно не поддерживается.
Не забывайте подставлять свои коэффициенты делителя перед прошивкой.

P32L
Offline
Зарегистрирован: 05.04.2016

Нет,с OLED разобрался,все завелось.Какую тогда схему посоветуете? LCD от нокии тоже есть.

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

Смотрите пост #26 на первой странице темы. Там неплохие печатки, выложенные форумчанами, схема с сайта автора и моя экспериментальная. В некоторых печатках подписаны элементы (могут чуть отличаться от схемы). Схему с умножителем повторять нежелательно.

P32L
Offline
Зарегистрирован: 05.04.2016

P32L
Offline
Зарегистрирован: 05.04.2016

tekagi пишет:
*****Схему с умножителем повторять нежелательно.

 

Что не так со схемой с умножителем ? речь идет о схеме с умножителем на OLED или на дисплее от Nokia ?

 

 

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

Новые версии скетчей с умножителем не будут работать. Старые работают, про олед точно не помню, вроде должна.

bogdannin1
Offline
Зарегистрирован: 27.10.2018

Здравствуйте! Начну с того, что китайцы спутали и прислали мне нокиевский дисплейчик. Ну значит это судьба!:-) прошил новую прошивучку, вообщем без датчика показывает какую то фигню, можно подумать что внутри ЧАЭС живу. Плату отмыл, но маской не покрывал, печатка своя. Что посоветуете?  

 

https://yadi.sk/i/qncgzNes69eKDA

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

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

bogdannin1
Offline
Зарегистрирован: 27.10.2018

Собрал первую схему Бодрого, кондеры все, на входе 330 мкФ в принципе можно добавить ещё керамики на вход, но это завтра. 

Сис. меню прилагаю: https://yadi.sk/i/kUgopDM91BEIOg

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

Накачка нормально не работает. Для начала попробуйте подстроить длительность импульса накачки. Если не поможет - проверьте фазировку обмоток трансформатора, попробуйте добавить ёмкость керамического конденсатора в цепи накачки (С17, С8 по схеме Бодрого, электролиты туда нельзя, только керамика). Если все эти меры не выровняют напряжение на счётчик и не снизит скорость ниже 100 - меняйте трансформатор.

В системном меню выставьте время бета замера 5 минут, сохраните, потом сбрсьте накопленную дозу. Это необходимо при переходе от скетчей ниже 1.05.

Когда разберётесь с накачкой - продолжим искать источник помех. И выложите детальное фото платы, желательно с обоих сторон.

P32L
Offline
Зарегистрирован: 05.04.2016

 

 

Ткните носом,в каком куске кода изменить под этот датчик. СБМ-21 . Уж очень подкупает размер.Понимаю,что у него время замера значительно больше

Dark-Dante
Offline
Зарегистрирован: 09.01.2018

Почитайте 2 последние страницы хотя бы.

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

P32L, пока никак. Есть желание - ковыряйте код, в нынешнем варианте это можно реализовать только костыльно, задействовав 185-200 ячеек массива и умножив результат на 2, но точность будет вполовину ниже и большая часть функционала АрДоса останется незадействованной. В планах есть добавить данный счётчик по алгоритму, озвученному выше SergejEU, но когда это будет - сказать не могу.

P32L пишет:
Понимаю,что у него время замера значительно больше.

В 10 раз.

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

Режим разностного замера

Время замера -  5 мин

Замер0  - 74

Замер1  - 107

После подсчета результат - 4 мкр/ч

Это правильно?

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

Время замера сколько выставлено?

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

5 минут.

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

Да, всё верно. Результат - превышение второго замера над первым, разница 33 импульса, эквивалентное время счёта для СБМ-20 40 секунд, то есть 33 импульса за 7,5 периодов счёта, или 4,4 условных мкР/ч превышения. Поскольку там int, а не float - дробная часть отброшена. По 74 и 60 - подразумевается, что первый замер контрольный, а второй - предположительно фонящего образца, поэтому если превышение отрицательное - выдаём 0, образец не превышает уровня фона. Собственно режим разностного замера я почти не трогал, только заменил в формуле финального подсчёта "магические числа" на задефайненое время счёта датчика.

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

Второй раз замерил, показания такие

Замер0  - 74

Замер1  - 60

После подсчета результат - 0 мкр/ч

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

Понятно. Спасибо.

Dark-Dante
Offline
Зарегистрирован: 09.01.2018

А что поменять чтобы был 0 при отрицательном втором замере, так как у моей версии скетча результат считается с минусом?

Dark-Dante
Offline
Зарегистрирован: 09.01.2018

Дел

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

Смотреть надо, навскидку не помню. Ежели не забуду - завтра проверю.

P32L
Offline
Зарегистрирован: 05.04.2016

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

bogdannin1
Offline
Зарегистрирован: 27.10.2018

tekagi пишет:

Накачка нормально не работает. Для начала попробуйте подстроить длительность импульса накачки. Если не поможет - проверьте фазировку обмоток трансформатора, попробуйте добавить ёмкость керамического конденсатора в цепи накачки (С17, С8 по схеме Бодрого, электролиты туда нельзя, только керамика). Если все эти меры не выровняют напряжение на счётчик и не снизит скорость ниже 100 - меняйте трансформатор.

В системном меню выставьте время бета замера 5 минут, сохраните, потом сбрсьте накопленную дозу. Это необходимо при переходе от скетчей ниже 1.05.

Когда разберётесь с накачкой - продолжим искать источник помех. И выложите детальное фото платы, желательно с обоих сторон.

спасибо!

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

alexadresat пишет:
Второй раз замерил, показания такие
Замер0 - 74
Замер1 - 60
После подсчета результат - 0 мкр/ч

Похоже, я ошибся, просто результат не превысил 1мкР/ч и поэтому был отброшен. Провёл эксперимент - отрицательные результаты выводятся нормально.

Оставить так или сделать вывод "0" при отрицательном результате? Там максимум пара строк кода будет.

Dark-Dante
Offline
Зарегистрирован: 09.01.2018

Я за 0, какой смысл выводить минус?

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

Dark-Dante, строка 858. Если её закомментировать или убрать - останется вывод отрицательного превышения.

1.08

/* ArDOs   v1.08
***Дозиметр на Ардуино
***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 40 // число секунд для замера, соответствующее характеристикам счётчика. Для СБМ-20 равно 40.
byte beta_time = 5; //время замера бета излучения
//настройки //////////////конец
//служебные переменные
extern uint8_t SmallFontRus[], MediumNumbers[], TinyFontRus[];
volatile uint8_t timer_seconds = 0; // для отсчёта секундных интервалов в прерывании
uint8_t beta_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[], beta_prev_1[], beta_prev_2[];
volatile int shet = 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;
byte sek = 0, minute = 0, bet_z = 0, gotovo = 0;
int  bet_z0 = 0, bet_z1 = 0, bet_r = 0;
float VCC = 0.0, doz_v = 0.0;
bool tr = 0, poisk = 1, fonarik = 0, toch, 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;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
		menu = 4;
		shet = 0;
		bet_z0 = 0;
		bet_z1 = 0;
		bet_r = 0;
		bet_z = 0;
		gotovo = 0;
		sek = 0;
		minute = 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();
			}
	}
//-------------------------------------------------------------------------------------------------------------
/* Костыль. Разностный замер и длительный замер вызываются с частотой отрисовки дисплея, 
поэтому сложно поймать нажатия кнопок внутри функций zamer_200s() и zamer_beta().
Возможно в будущем придётся разделить эти функции на обработку данных (вызывать с частотой loop'а) 
и вывод на дисплей (вызывать с частотой обновления дисплея)
*/
if (menu == 4)
{
    if ((key_data == key_pressed_ok) && (gotovo == 0))  //нажатие OK
		{
			key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
			gotovo = 1;
			switch (bet_z) //проверяем, находимся ли в первом или втором замере
			{
				case 0: //если в первом замере
					bet_z0 = 0; //обнуляем текущие показания замера 1
					shet = 0; //обнуляем счёт
				case 1: //если во втором замере
					bet_z1 = 0; //обнуляем текущие показания замера 2
					shet = 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;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						beta_time++;
					}
			}
	}
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;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
						beta_time--;
					}
			}
	}
//------------------------------------------------------------------------------------------------------------------  
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 ((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 zamer_beta() 
{// замер бета или продуктов
if (gotovo == 0) 
	{
		if (alarm_sound)  //если активен сигнал тревоги первого уровня
			{
				res_first_alarm(); //сбрасываем сигнал тревоги
			}
		myGLCD.clrScr();
		myGLCD.setFont(TinyFontRus);
		if (bet_z == 0)
			{
				myGLCD.drawBitmap(0, 0, beta_prev_1, 84, 48);
				/*
				myGLCD.print(utf8rus("РЕЖИМ РАЗНОСТНОГО"), CENTER, 0);
				myGLCD.print(utf8rus("ЗАМЕРА"), CENTER, 8); 
				myGLCD.drawLine(0, 16, 83, 16); 
				myGLCD.print(utf8rus("УСТАНОВИТЕ ПРИБОР"), CENTER, 20); 
				myGLCD.print(utf8rus("НА ПУСТУЮ КЮВЕТУ И"), CENTER, 28); 		
				*/
		
			}
		else if (bet_z == 1)
			{
				myGLCD.drawBitmap(0, 0, beta_prev_2, 84, 48);	
				/*
				myGLCD.print(utf8rus("ЗАМЕР ОБРАЗЦА"), CENTER, 0); 
				myGLCD.drawLine(0, 8, 83, 8); 		
				myGLCD.print(utf8rus("ЗАПОЛНИТЕ КЮВЕТУ"), CENTER, 12);
				myGLCD.print(utf8rus("ИЗМЕРЯЕМЫМ ВЕЩЕСТВОМ"), CENTER, 20);  
				myGLCD.print(utf8rus("УСТАНОВИТЕ ПРИБОР И"), CENTER, 28);
				*/	
			}

//  myGLCD.setFont(SmallFontRus);
//  myGLCD.print(utf8rus("Замер "), 20, 10); myGLCD.printNumI(bet_z, 55, 10);
myGLCD.setFont(SmallFontRus);
myGLCD.print(utf8rus("НАЖМИТЕ OK"), CENTER, 36);
myGLCD.update();
	}  
if (gotovo == 1) 
	{
		if (timer_seconds != beta_seconds) 
			{
				beta_seconds = timer_seconds;
				sek++;
				toch = !toch;
				if (sek >= 60) 
					{
						sek = 0;
						minute++;
					}
			}	
		byte otsup = 0;
		if (minute > 9) 
			{
				otsup = 5;
			}
		myGLCD.clrScr();
		battery();
    if  (bet_z < 2) //таймер выводим только пока идёт первый или второй замер
		{
			myGLCD.setFont(TinyFontRus);
			myGLCD.printNumI(minute, LEFT, 0);
			if (toch == 0) 
				{
					myGLCD.print(":", 5 + otsup, 0);
				}
			else 
				{
					myGLCD.print(" ", 5 + otsup, 0);
				} 
			myGLCD.printNumI(sek, 10 + otsup, 0); myGLCD.print("\xBC"":""\xB9", 23 + otsup, 0);
		}
    myGLCD.drawLine(0, 8, 83, 8);
    myGLCD.setFont(SmallFontRus);
    myGLCD.drawLine(40, 8, 40, 28);
    myGLCD.print(utf8rus("Замер0"), LEFT, 10); myGLCD.print(utf8rus("Замер1"), RIGHT, 10);
    myGLCD.printNumI(bet_z0, LEFT, 20); myGLCD.printNumI(bet_z1, RIGHT, 20);
    myGLCD.drawLine(0, 28, 83, 28);
    if (bet_z < 2) 
		{
			myGLCD.print(utf8rus("Идёт замер"), CENTER, 30); myGLCD.printNumI(bet_z, RIGHT, 30);
			myGLCD.printNumI(bet_r, CENTER, 38);
		}
    if (bet_z == 2) 
		{
			myGLCD.print(utf8rus("Результат"), CENTER, 30);
			myGLCD.printNumI(bet_r, CENTER, 38); myGLCD.print(utf8rus("мкР/ч"), RIGHT, 38);
		}
    myGLCD.update();
    if (bet_z == 0)  //первый замер
		{
			bet_z0 = bet_z0 + shet;
			shet = 0;
			if (minute >= beta_time) 
				{
					bet_z = 1;
					sek = 0;
					minute = 0;
					gotovo = 0; 
					tone (6,2000,70); //генерим писк 2000Гц 70миллисекунд на 6й ноге
				}
		}
    if (bet_z == 1)  //второй замер
	{
		bet_z1 = bet_z1 + shet;
		shet = 0;
		if (minute >= beta_time) 
			{
				bet_z = 2;
				sek = 0;
				minute = 0;
				tone (6,2000,70); //генерим писк 2000Гц 70миллисекунд на 6й ноге		
			}
    }
    if (bet_z == 2)  //результат
		{
			bet_r = bet_z1 - bet_z0;
//			bet_r = bet_r / (1.5 * beta_time);
			bet_r = bet_r / ((60.0/(float)geiger_counter_seconds) * (float)beta_time);
			if (bet_r < 0) {bet_r = 0;} // если результат отрицательный - выводим 0. Можно оставить вывод отрицательного результата, закомментировав данную строчку.
		}
	}
if (key_data == key_pressed_right)  //нажатие >>>
	{
		key_data = 0;  // обнуляем переменную функции кнопок для предотвращения ложных срабатываний далее по коду
		menu = 0;
		clear_poisk_variables();
	}
}
//-------------------------------------------------------------------------------------------------------------
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;
						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 / 40.0;
				time_doza = time_doza + 1;
				if (doz_v - doza_vr >= save_DOZ)  //а не пора ли сохранить дозу ?
					{
						eeprom_wrD ();
						doza_vr = doz_v;
					}
//Serial.print(" zam_poisk_counter=");
//Serial.println(zam_poisk_counter);						
			}
		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++;
}
//-------------------------------------------------------------------------------------------------
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);
  EEPROM.write(17, beta_time);
  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);
		beta_time = EEPROM.read(17);
	}
_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;}
}

// ________________ конец скетча, дальше можно не копировать _____________________




/*

ChangeLog by tekagi:

1.08		12.01.2019
  -подрихтовано форматирование
  -выброшены неиспользуемые переменные
  -вернул старый график (можно включить вместо нового в пользовательском меню)
  -мелкие багфиксы
  -выброшен отдельный режим длительного замера (показания выводятся на главный экран)
  -если в разностном замере результат отрицательный - теперь выводится 0, а не отрицательное значение

1.07.9		01.01.2019
  -переписан график (ранее график отобржал увеличение кол-ва импульсов над предыдущим временным интервалом, сейчас показывает усреднённое значение за выбранный интервал, масштабируя по максимальному значению за весь отображаемый на экране период)

1.07.8
  -добавлено управление вибросигналом из меню

1.07.7         19.06.2018
  -фикс учёта времени (переведено с миллис на таймер1, код взят из примера, выложенного dimax)
  -сигнал тревоги сделан прерывистым

1.07.6		  15.06.2018
  -начато добавление вибро

1.07.5        10.06.2018
  -мелкие изменения в графике: подкорректированы значки батарейки и аварийного сигнала (в батарейке значение напряжения было сдвинуто на пару пикселов, а колокольчик аварии перекрывался цифрами при повышении фона свыше 100мкР/ч);

1.07.4		  15.05.2018
  -исправлена лишняя секунда в режиме бета замера и немного изменена обработка тревоги первого уровня;

1.07.3		  28.04.2018
  -изменено содержание экранов между бета замерами. В промежуточной 1.07.2 сделал на стандартных функциях вывода библиотеки экрана, на двух экранах съело 12% оперативки. Пришлось переписать в виде картинки, попутно убрав вывод текста с начальной заставки и внеся его в картинку заставки.

1.07.1        25.04.2018
  -добавлен мелкий шрифт, русифицированы меню;

1.07          16.04.2018
  -начато добавление русского языка в интерфейсе. Спасибо kaktuc за русский шрифт к библиотеке и arduinec за функцию перекодирования выводимого на дисплей текста;
  -заменён дефайн "ADC" на "ADC_value", в новых версиях ArduinoIDE из-за этого возникала ошибка компилляции;

1.064         15.04.2018
  -добавлена возможность использования ArduinoUNO или голого камня atmega328p в DIP корпусе. Для переключения раскомментировать #define UNO в начале скетча, это переключит чтение высокого напряжения с делителя с пина A6 на A5;
  -добавлено переключение состояния подсветки при удержании ">>"
  
1.063.7       15.04.2018
  -попытка переписать обработку клавиш (вынесено в отдельную функцию);
  -выключен выход в системное меню из функций длительного и разностного замеров (оставлен только из основного режима "поиск");

1.063.6       25.03.2018
  -пофиксены кракозяблы при выводе "ANALIZ" в начале длительного замера;

1.063.5       14.01.18
  -пофиксена некорректная запись в еепром времени учёта дозы (писалось только 2 байта из четырёх);
  -добавлено преобразование микрорентген/час в миллирентгены/час в режиме поиска и длительного замера при фоне свыше 1000;

  
1.063.4       13.01.18
  -добавлена возможность включать индикацию светодиодом и бузером независимо друг от друга;

  
1.063.3 и ниже    12.11.2017
  -добавлена возможность выбрать активный или пассивный бузер;
  -пофиксен учёт фона во время нахождения в меню (при выходе из меню был скачок фона, поскольку в функции меню не было вызова poisk_f();   arduino.ru/forum/proekty/delaem-dozimetr?page=17#comment-320398   );
  -добавил режим непрерывной аварийной сигнализации при превышении первого порога, длительность сигнала настраивается в дефайне;
  -пофиксен серьёзный баг в режиме разностного замера (счёт импульсов начинался не с нажатия кнопки "ОК" при запуске второго цикла измерения, а сразу после окончания первого измерения, в результате разностный результат сильно завышался);
  -пофиксен паразитный сигнал при значении "shet = 0;"   arduino.ru/forum/proekty/delaem-dozimetr?page=16#comment-318736  ;

  P.S. Спасибо ImaSoft за подсказки и готовые кусочки кода.

*/

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 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};


// заставка БЕТА режима первая
const unsigned char PROGMEM beta_prev_1[] =
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05,
  0x02, 0x00, 0x1F, 0x15, 0x11, 0x00, 0x1B, 0x1F, 0x1B, 0x00, 0x1F, 0x0C,
  0x1F, 0x00, 0x1F, 0x07, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x05,
  0x02, 0x00, 0x1E, 0x05, 0x1E, 0x00, 0x11, 0x15, 0x0A, 0x00, 0x1F, 0x04,
  0x1F, 0x00, 0x0E, 0x11, 0x0E, 0x00, 0x0E, 0x11, 0x0A, 0x00, 0x01, 0x1F,
  0x01, 0x00, 0x1F, 0x04, 0x1F, 0x00, 0x0E, 0x11, 0x0E, 0x00, 0x1F, 0x01,
  0x01, 0x00, 0x0E, 0x11, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x15, 0x0A, 0x00,
  0x1E, 0x05, 0x1E, 0x00, 0x1F, 0x07, 0x1F, 0x00, 0x1F, 0x15, 0x11, 0x00,
  0x1F, 0x05, 0x02, 0x00, 0x1E, 0x05, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00,
  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, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x71, 0x41,
  0xF1, 0x01, 0xE1, 0x11, 0xA1, 0x01, 0x11, 0xF1, 0x11, 0x01, 0xE1, 0x51,
  0xE1, 0x01, 0xF1, 0x41, 0xF1, 0x01, 0xE1, 0x11, 0xE1, 0x01, 0xF1, 0x51,
  0xA1, 0x01, 0xF1, 0xC1, 0xF1, 0x01, 0x11, 0xF1, 0x11, 0x01, 0xF1, 0x51,
  0x11, 0x01, 0x01, 0x01, 0x01, 0x01, 0xF1, 0x11, 0xF1, 0x01, 0xF1, 0x51,
  0x21, 0x01, 0xF1, 0xC1, 0xF1, 0x01, 0xF1, 0x51, 0x91, 0x01, 0xE1, 0x11,
  0xE1, 0x01, 0xF1, 0x51, 0x21, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x40, 0xF1, 0x01,
  0xE0, 0x50, 0xE0, 0x01, 0x00, 0x00, 0xF0, 0x11, 0xF0, 0x00, 0x71, 0x40,
  0xF1, 0x00, 0xE1, 0x10, 0xA1, 0x00, 0x10, 0xF1, 0x10, 0x00, 0x71, 0x41,
  0xF0, 0x00, 0xF1, 0xE0, 0x11, 0xE0, 0x00, 0x01, 0x00, 0xF0, 0x41, 0x91,
  0x01, 0xF0, 0xE0, 0x10, 0xE0, 0x00, 0xF1, 0x50, 0xA1, 0x00, 0xF1, 0x50,
  0x10, 0x00, 0x11, 0xF0, 0x11, 0x00, 0x71, 0x41, 0xF0, 0x00, 0x00, 0x01,
  0xF0, 0xC0, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
  0x01, 0xF0, 0x81, 0x80, 0x80, 0xF0, 0x01, 0xC0, 0x21, 0x10, 0x21, 0xC1,
  0x00, 0x70, 0x80, 0xE1, 0x80, 0x70, 0x00, 0xF1, 0x20, 0xC0, 0x21, 0xF1,
  0x00, 0xF0, 0x01, 0x80, 0x61, 0xF0, 0x00, 0x10, 0x10, 0xF1, 0x10, 0x11,
  0x00, 0xF1, 0x90, 0x91, 0x90, 0x10, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
  0x01, 0xE0, 0x10, 0x11, 0x10, 0xE0, 0x01, 0xF1, 0x80, 0x40, 0x20, 0x10,
  0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x01, 0x01, 0x01, 0x07,
  0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07,
  0x00, 0x07, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
  0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x07, 0x00, 0x01, 0x02, 0x04,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  
// заставка БЕТА режима вторая
const unsigned char PROGMEM beta_prev_2[] =

  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x11, 0x15, 0x0A, 0x00, 0x1E, 0x05, 0x1E, 0x00,
  0x1F, 0x07, 0x1F, 0x00, 0x1F, 0x15, 0x11, 0x00, 0x1F, 0x05, 0x02, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x0E, 0x00, 0x1F, 0x15, 0x1D, 0x00,
  0x1F, 0x05, 0x02, 0x00, 0x1E, 0x05, 0x1E, 0x00, 0x11, 0x15, 0x0A, 0x00,
  0x1F, 0x10, 0x1F, 0x30, 0x1E, 0x05, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, 0x51,
  0xA1, 0x01, 0xE1, 0x51, 0xE1, 0x01, 0xF1, 0x11, 0xF1, 0x01, 0xE1, 0x11,
  0xE1, 0x01, 0xE1, 0x11, 0xF1, 0x01, 0xF1, 0x41, 0xF1, 0x01, 0xF1, 0xC1,
  0xF1, 0x01, 0x11, 0xF1, 0x11, 0x01, 0xF1, 0x51, 0x11, 0x01, 0x01, 0x01,
  0x01, 0x01, 0xF1, 0x41, 0x91, 0x01, 0xF1, 0xE1, 0x11, 0xE1, 0x01, 0xF1,
  0x51, 0xA1, 0x01, 0xF1, 0x51, 0x11, 0x01, 0x11, 0xF1, 0x11, 0x01, 0x71,
  0x41, 0xF1, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
  0x00, 0x00, 0xF0, 0xC0, 0xF0, 0x00, 0x10, 0x50, 0xA0, 0x00, 0xF1, 0x71,
  0xF0, 0x00, 0xF1, 0x50, 0x11, 0x00, 0xF1, 0x50, 0x21, 0x00, 0xA0, 0x51,
  0xF0, 0x00, 0xF1, 0x50, 0x11, 0x00, 0xF1, 0x70, 0xF1, 0x00, 0xF1, 0x40,
  0x81, 0xF0, 0x00, 0xF1, 0x70, 0xF0, 0x01, 0x01, 0x01, 0x00, 0xF0, 0x50,
  0xA0, 0x00, 0xF1, 0x50, 0x11, 0x00, 0xF1, 0xC0, 0xF1, 0x00, 0xF0, 0x51,
  0x11, 0x00, 0xE0, 0x11, 0xA1, 0x01, 0x10, 0xF0, 0x11, 0x00, 0xF0, 0x51,
  0xA1, 0x00, 0xE0, 0x10, 0xE0, 0x00, 0xF0, 0x70, 0xF0, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x71, 0x41, 0xF0, 0x00, 0xE1, 0x10,
  0xA1, 0x00, 0x11, 0xF1, 0x11, 0x00, 0xE1, 0x50, 0xE0, 0x00, 0xF1, 0x40,
  0xF1, 0x00, 0xE1, 0x11, 0xE1, 0x00, 0xF1, 0x50, 0xA1, 0x00, 0xF1, 0xC1,
  0xF0, 0x01, 0x10, 0xF1, 0x10, 0x01, 0xF0, 0x50, 0x10, 0x00, 0x01, 0x01,
  0x00, 0x00, 0xF1, 0x11, 0xF1, 0x00, 0xF1, 0x51, 0x23, 0x00, 0xF1, 0xC1,
  0xF1, 0x00, 0xF0, 0x51, 0xD0, 0x00, 0xE0, 0x11, 0xE0, 0x00, 0xF1, 0x51,
  0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0xF1, 0xC0, 0xF1, 0x00, 0x03, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01,
  0x00, 0xF0, 0x80, 0x81, 0x80, 0xF0, 0x01, 0xC0, 0x21, 0x10, 0x21, 0xC0,
  0x01, 0x70, 0x80, 0xE1, 0x80, 0x70, 0x01, 0xF1, 0x20, 0xC0, 0x21, 0xF0,
  0x01, 0xF0, 0x00, 0x81, 0x60, 0xF0, 0x01, 0x11, 0x11, 0xF0, 0x10, 0x10,
  0x00, 0xF0, 0x91, 0x90, 0x91, 0x10, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
  0x01, 0xE0, 0x11, 0x11, 0x11, 0xE0, 0x00, 0xF1, 0x80, 0x40, 0x21, 0x10,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x01, 0x01, 0x01, 0x07,
  0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07,
  0x00, 0x07, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
  0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x07, 0x00, 0x01, 0x02, 0x04,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


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


// 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, // Я
};

 

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

А я еще вот эти подправил. Мне кажется так лучше смотрится...

строка 690 

myGLCD.print(utf8rus("ТИП. ГРАФИКА"), 5, 18);  myGLCD.printNumI(graph_type, 59, 18); myGLCD.print("0-1", RIGHT, 18); //usr

 

строка 1167 

myGLCD.print(utf8rus("Сохранено"), CENTER, 20);

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

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

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

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

строка 690 

myGLCD.print(utf8rus("ТИП.ГРАФИКА"), 5, 18);  myGLCD.printNumI(graph_type, 55, 18); myGLCD.print("0-1 ", RIGHT, 18); //usr

страка 691

myGLCD.print(utf8rus("ОБН.ГРАФИКА"), 5, 24); myGLCD.printNumI(scrin_GRAF, 55, 24); myGLCD.print(utf8rus("СЕК."), RIGHT, 24);//

А так как все меню получается

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

ИМХО так хуже, изменяемый параметр почти сливается с названием пункта. Оставлю предыдущее.

Dark-Dante
Offline
Зарегистрирован: 09.01.2018

В меню надо убрать второй порог и перенести настройку времени разностного замера из системного в основное и будет нормально, ИМХО. Себе так сделал.

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

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

Скорее всего смену типа графика вынесу в дефайн, а на место этого пункта перенесу бета замер.

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

Проект по чуть-чуть идет в перед. Вчера сделал почти финальную плату, распечатал корпус для датчика СИ20Г. Вид примерно такой

hawk23
Offline
Зарегистрирован: 09.06.2017
Всем привет.
Прочитал все посты с 1 по 2190. 
Спасибо bodriy2014, спасибо tekagi (без Вас тема бы умерла, поражаюсь Вашему терпению и снимаю шляпу), спасибо Shodan, Morroc, Joiner, Logik, kaktuc, sva_khv, ImaSoft, Medvedik, Sajsen, ortus, Dark-Dante, Arhat109-2, alexadresat спасибо за плату.
 
Созрел собрать и себе. В связи с обилием информации хочу уточнить:
1) полевик на дроссель предпочтительнее IRLML0030TRPBF, IRLML6346, IRLML6346 в порядке убывания? Или в данной схеме фиолетово? Цена одинакова, какие брать?
 
Ввиду важности диэлектрических параметров ВВ части схемы еще вопросы:
2) под всеми SMD резисторами делителя напряжения (120 МОм) целесообразно ли сделать прорези? (как на плате alexadresat у нижних двух резисторов).
 
3) целесообразно ли заменить SMD резисторы вышеуказанного делителя например тремя-четырьмя выводными металлопленочнными резисторами по 33 МОм 0,5 Вт 5%, (VR37000003305JA100)спаяв з них последовательную цепочку и подняв над платой, припаяв лишь наружные выводы первого и последнего. Т.е. сборка не будет касаться платы. Или не заморачиваться утечками в стеклотекстолите? Про советы Мой-Суши-Мой-Суши... от Shodan'a или MadOrc'a ознакомлен
 
4) высоковольтный конденсатор пленочный 0,1 мкФ 630 В.
В общей схеме он 0,1 мкФ, в схеме tekagi 0,02 мкФ. Какой емкости оптимальнее? С одной стороны выше емкость - лучше, с другой токи утечки выше.
Или для полного феншуя целесообразно ли применить керамический  с материалом типа NPO? 
Arhat109-2 писал в посте #1482 "...В общем, на вторичку надо ставить керимаческие кондеры с материалом типа NPO (критичен ток утечки даже в пикоамперах) не ниже 1кВ пробивного напряжения (это под штатный датчик до 400в), емкостью не хуже 3.3нф, мои 470пф х 3.3кВ, что устанавливались на высоком для засветки барабана в лазернике сдуваются наполовину (с 950в) уже на 4-й микросекунде на измерительном делителе в 100 мегаом..."
Или поставить обычный CAP/FILM 0.1/630V и не заморачиваться? Кто какие ставил?
 
5) Из какого материала целесообразнее делать плату?
Или наш обычный стеклотекстолит из запасов + ЛУТ/фоторезист или у китайцев чтобы красиво на стандартном FR-4.
Вроде бы поверхностное и объемное сопротивление у них схожи:
объемное электрическое сопротивление после кондиционирования и восстановления (Ом х м): 9,2 х E13;
поверхностное электрическое сопротивление (Ом): 1,4 хE12;
 
6) если я хочу сделать выносной датчик, то проблем с ВВ преобразователем не будет? Например из-за лишних двух отрезков МГТФ длиной 30 см к выносному датчику.
 
Еще вопрос.
7) Может кто-то из присутствующих здесь встречал подобную схему дозиметра, но адаптированную под ESP8266 (например под  NodeMCU) типа как в соседней ветке метеостанция с дозиметром. Идея какая. Включен где-то дома или на работе подобный девайс, подключенный Wi-Fi. На него можно зайти или через вебморду, или приложение, или TelegramBot, или он отсылает данные в народный мониторинг. Доступны текущие и средние за сутки значения. В случае превышения порога, отсылаются по почте или в Telegram предупреждающие сообщения.
Вывод на экран не обязателен. Думаю, что данная схема на 328 Меге без особых проблем может быть портирована на ESP8266, тем более что в Arduino IDE с этим проблем нет. Речь о минимизации тока потребления тоже не ведется. Опрос кнопок тоже не нужен.
 
ps
8) Подскажите еще про датчик СИ8Б.
Алюминиевая крышка отсекает бету нормированно? Или это транспортировочная крышка? Т.е. с этой крышкой и без крышки я могу приблизительно посчитать фон продуктов?
 
tekagi
tekagi аватар
Offline
Зарегистрирован: 07.10.2016

1. IRLML6346 получше, можно и IRLML2502. Работает и с близкими по характеристикам, критичны сопротивление в открытом состоянии, скорость переключения, ёмкость затвора.

2. Слоты желательны, но важнее вымыть из-под резисторов остатки флюса.

3. Не настолько критично. Всё же потребления, сравнимого с Микроном или Нанитом здесь достичь не удастся, в моих экземплярах ВВ преобразователь ест меньше миллиампера, в то время, как остальная часть схемы 8-13 мА. В первом экземпляре стоят выводные по 0.125, во втором СМДшки 1206 со слотами и маской.

4. Больше - лучше. 0,02 в моей первой сборке помогла выявить программный косяк с накачкой, но стабильность с ним ниже, и при прекращении накачки с делителем 126М почти сразу падала в ноль. 0,1 при 100МОм сдувается до нуля где-то за 3-4 секунды, что позволяет безболезненно "проглотить" мелкие паузы в работе генератора. 0.02 K73-17, 0.1 - плёночный серый "кирпич" с маркировкой только ёмкости и напруги 630V. Про китайские синие дисковые керамические на 1-2кV были нелестные отзывы, с фирменными не пробовал.

5. Обычного стеклотекстолита вполне достаточно.

6. С выносным нужно экспериментировать, я бы разделил анодный балластный резистор на датчик на 2 по 5 Мег, один на плате, один в зонде. Плюс обязательный экран  на оба провода, иначе получится отличная антенна. Может и узел детектирования придётся в зонд перенести.

7. Посмотрите в сторону Климатического монитора Смотрителя Убежища. Хотя это так, навскидку, и он вроде без отправки данных.

 

bogdannin1
Offline
Зарегистрирован: 27.10.2018

Хух.... Настроил, осталось дождаться СбМ’ки. 

https://yadi.sk/i/GIg5nYq5gEoaaw

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

12 имп/сек? Мне меньше 28 достичь не удалось)) Что за транс, какая ёмкость выходного конденсатора? Какое потребление на узел ВВ преобразователя? Высокое напряжение по инструкции с 15й страницы проверяли?

Dark-Dante
Offline
Зарегистрирован: 09.01.2018

12 потому что без нагрузки)

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

Датчик при ЕРФ нагрузки мизер даёт, а делитель должен быть. Если бы вывод АЦП болтался в воздухе - на системном вольтметре была бы каша.

hawk23
Offline
Зарегистрирован: 09.06.2017

tekagi спасибо за ответы-советы.

1) Подскажите, кто игрался ВВ делителем.
Как сильно влияет на потребляемый ток ВВ делитель 5, 10, 20, 40, 80, 100, 120, 140 МОм?
Как я понимаю, чем выше его сопротивление, тем  меньше ток расходуем на "служебные цели" (замер 400 В). С другой стороны на очень малых токах со временем становимся заложниками влаги и прочих факторов даже после пропитки.
Рекомендовано - верхнее плечо 80-140 МОм. Ток потребления делителем получаем 400В/R=3-5 мкА.
При 40 МОм ток потребления 10 мкА.
При 20 МОм ток потребления 20 мкА.
При 10 МОм ток потребления 40 мкА.
У кого-то вообще 5 МОм, и соответственно ток потребления делителем 80 мкА.
И это при потреблении ВВ преобразователем в районе 1мА, и всем устройством 5-20 мА.

Суть вопроса: для уменьшения влияния внешних факторов со временем на замер 400 В желательно выбрать делитель, на который не будет влиять дождь на Луне или пот в кармане. Какой это должен быть ток делителя  для данного устройства?  Может у кого-то есть опыт создания и эксплуатации слаботочных устройств с высокоомными цепями?
Как я понимаю, в первой опубликованной авторской прошивке был SLEEP и тогда делитель в 100-140 МОм оправдан. Если нет режима SLEEP, то дополнительные 10-20-40 мкА для данного устройства это просто  ~0,1% от суммарного тока потребления? Может я не прав и что-то упустил - поправьте пожалуйста. И как уменьшение делителя например до 20-40 МОм отразится на запасе ВВ-преобразователя?

Вопрос задаю в связи с тем что в 1990 г сделал дозиметр (СБМ20, ЖКИ, на счетчиках К176ХХХ, без кварца, монтаж ПП+перемычки луженкой в ПВХ изоляции+ МГТФ, пайка спиртоканифолью с промывка, трансик на феррите с тремя обмотками был намотан на производстве по всем правилам). Самым высокоомным элементом есть набор резисторов 10 МОм в цепи СБМ20. Возможно, по неопытности, тогда я упустил какие-то моменты. 
Сейчас наблюдаю интересные вещи. Ладно бы только  уехало время замера из-за потери емкости в времязадающей RC-цепочке. Дозиметр всегда хранился в квартире. Недавно оставил его на балконе при +0-10 градусов, иногда открываю окна, очень редко жена вывешивает белье. И вот вставляю свежую крону и .... считает как из пулемета. Отогреваю в квартире сутки на батарее - считает нормально. Первые 20 лет такого не наблюдалось :). После сборки первые лет 10 часто его таскал в любую погоду с собой (живу в Киеве). Потом включал все реже.
Это я к тому, что собирая сейчас устройство, хочется чтобы оно проработало еще много лет без сюрпризов. 
И в этой чудесной схеме все красиво, только ВВ делитель на 140 МОм смущает. 
Платы еще не травил. Только советуюсь. На данном этапе могу еще подправить плату под себя. 

2) Еще вопрос по adc_value. При подборе плеч делителя, на сколько я понимаю,  adc_value влияет на максимальное измеряемое напряжение и шаг регулировки высокого напряжения?
Например, при adc_value =180 и желаемых 400 В максимальное измеряемое напряжение будет 255х400/180=551 В с шагом 2 вольта (551/255).
При adc_value = 60, макс измеряемое напряжение будет 1700 В с шагом 6,6 В.
Я верно понимаю? Понятно, что при рабочем плато у СБМ20 в 100 В, точность поддержания что 2, что 6 вольт без разницы.

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

При 5МОм в верхнем плече делителя 1мА на преобразователь невозможен в принципе. Когда я грузил на 10МОм было больше 40. Имхо лучше хорошо покрыть плату спецлаком (название Шодан надцать страниц назад советовал), плюс озаботиться влагозащищённым корпусом.

adc_value - это значение на входе ацп, при котором при выбранном делителе на ВВ части 400В. Т.е. Делитель должен обеспечить на входе ацп напряжение около 0.7-0.9 вольта при 400 на выходе. Опорное у нас 1.1 вольта, у ацп 255 отсчётов, равных 1/255 опорного. Соответственно adc_value получится около 170.

hawk23
Offline
Зарегистрирован: 09.06.2017

Спасибо!

Dark-Dante
Offline
Зарегистрирован: 09.01.2018

Как то слишком серьёзно Вы относитесь к сборке и самому прибору из данной темы. Это всего лишь прибор для бытовых целей, если вдруг есть сомнения в каком то предмете или вещи, не более, ИМХО.