An additional block has been made in the parser for decoding incoming alarm settings for writing to the EEPROM. Additional digital inputs are activated.

Dependencies:   _24LCXXX

main.cpp

Committer:
Aleksk
Date:
2020-06-11
Revision:
6:fe0a7180ebb7
Parent:
5:bb595cde0c82

File content as of revision 6:fe0a7180ebb7:

// 11.06.2020 Продолжение (клон )mbed-os5-press9
// Сделан дополнительный блок в парсере для декодирования приходящих аварийных уставок для EEPROM
// Сделан timer_2 для отсчёта времени открытого состояния вентиля 1
// Сделан timer_3 для отсчёта времени открытого состояния вентиля 2
// Подключены цифровые входы D11,D12,D13. Реализованы условия остановки по 10 аварийным событиям.
// Реализован  сброс события (event_N = 255) через кнопку Стоп в программе оператора 
// Принимается флаг от кнопки Стоп - полной остановки регулятора - закрытие всех 4-х клапанов и передача статуса кнопки в программу оператора
// Принимается флаг от кнопок включения - выключения компрессора, - идет команда на дискретный выход digital_6(PB_10)
// Принимается новая уставка num_chan - переключение номера  активного измерительного канала для обратной связи регулятора. 
// Эта уставка, как и все остальные,  пишется в EEPROM.
// Включены все шесть аналоговых входа, читаются пять
// при получении командной строки с нулевой суммой, по новому флагу flag_zerostart, передаётся в сериал текущие уставки и величины
// (важно для старта программы на PC), эти нулевые уставки не вводятся в регулятор и не записываются в EEPROM.
// сторожевой таймер,  истекает через 100мс
// 

#include "mbed.h"
#include "_24LCXXX.h"

I2C i2c(PB_9,PB_8);        // sda, scl
_24LCXXX eeprom(&i2c, 0x50);

AnalogIn analog_value_0(A0);                                                      //подключение аналогового входа A0
AnalogIn analog_value_1(A1);                                                      //подключение аналогового входа A1
AnalogIn analog_value_2(A2);                                                      //подключение аналогового входа A2
AnalogIn analog_value_3(A3);                                                      //подключение аналогового входа A3
AnalogIn analog_value_4(A4);                                                      //подключение аналогового входа A4
AnalogIn analog_value_5(A5);                                                      //подключение аналогового входа A5
//DigitalOut led(LED1);
DigitalOut digital_4(PB_5);                                                     //initialize digital pin 4 as an output (high pressure air bulb charge).
DigitalOut digital_7(PA_8);                                                     //initialize digital pin 7 as an output. (high pressure air bulb discharge)
DigitalOut digital_5(PB_4);                                                     //initialize digital pin 5 as an output (valve3,4)
DigitalOut digital_6(PB_10);                                                    //initialize digital pin 6 as an output (compressor on/off)
DigitalIn idigital_11(PA_7);                                                     //initialize digital pin 11 as an input концевик при растяжении сильфона
DigitalIn idigital_12(PA_6);                                                     //initialize digital pin 12 as an input концевик при сжатии сильфона
DigitalIn idigital_13(PA_5);                                                     //initialize digital pin 12 as an input внутрь опрессовщика попала вода 

RawSerial plotter(USBTX, USBRX, 115200);                                        // tx, rx for F411RE    port for serial_plotter and temporary messages
RawSerial pc(PA_9, PA_10, 115200);                                              // tx, rx for F411RE     port  for  command string distance PC
EventQueue *queue = mbed_event_queue();                                         //инициализация очереди событий RTOS mbed5
Timer timer;                                                                    //инициализация таймера для определения частот переключений вентилей 1 и 2
Timer timer_2;                                                                  //инициализация таймера 2 для отсчёта времени открытого состояния вентиля 1
Timer timer_3;                                                                  //инициализация таймера 3 для отсчёта времени открытого состояния вентиля 2
//========УСТАВКИ_1 EEPROM========
uint8_t delta_value = 0;                                                        //set delta pressure 1...99
uint8_t flag_compressor = 0;                                                    //флаг компрессора. При 0 - выключение компрессора, при 1 - включение компрессора
uint8_t flag_stopRegulator = 0;                                                 //Stop- флаг . При 0 - разрешение работы регулятора, при 1 - запрет и запиране всех клапанов
uint8_t num_chan = 1;                                                           //set номер аналогового канала 0...5 (1-as default = Pa)
int value = 0;                                                                  //set begin value "pressure"   1...3300
//========УСТАВКИ_2 EEPROM========
int Pd_eeprom = 2000;                                                           // mV,  максимальное дифференциальное давление (беззнаковое)
int frequencyValve1_eeprom = 5;                                                 // Гц, максимальная частота переключений клапана 1 
int frequencyValve2_eeprom = 5;                                                 // Гц, максимальная частота переключений клапана 2 
int WL01_eeprom = 10;                                                           // mV, минимальный вес опрессовщика
int WL99_eeprom = 2000;                                                         // mV, максимальный вес опрессовщика
int T_1 = 4000;                                                                 // ms, максимальное время открытого состояния для клапана 1 
int T_2 = 4000;                                                                 // ms, максимальное время открытого состояния для клапана 2 
uint8_t event_N = 255;                                                          // номер события , по умолчанию 255 - событий нет
//======temporary set=====
int numSet, anySet;
//=================================
int value_auto=250 ;                                                            //set begin value auto "pressure"
int WL = 0;                                                                     //напряжение с аналогового входа А0 (WL - вес опресовщика)
int sensor_value =0;                                                            //напряжение с аналогового входа А1 (Pa - текущее давление)
int Pb = 0;                                                                     //напряжение с аналогового входа А2 (Pb - давление в баллоне)
int Pw1 = 0;                                                                    //напряжение с аналогового входа А3 (Pw1 - давление воды на входе опрессовщика)
int Pw2 = 0;                                                                    //напряжение с аналогового входа А4 (Pw2 - давление воды в контуре макета)
int Pd = 0;                                                                     //напряжение с аналогового входа А5 (Pd - дифференциальное давление опресовщика)
int counter_cycle1 = 0;                                                         //счётчик цикла while(true)
int counter_cycle2 = 0;                                                         //счётчик внутри функции auto_set
int sig = 1;                                                                    //знак инкримента для автоустаки

//                       FIFO_buffer must be full (only char  and '\0') 
//#define maxnsym 26                                                             // maximum nbr of symbols FIFO_buffer (вариант без символов окончания)
#define maxnsym 28                                     // maximum nbr of symbols FIFO_buffer +CR+LF (символы окончания должны быть включены на передаче)
char Source[maxnsym]="$press,1000,25,0,0,1,2050**";      //25 char- string ,весь массив со строкой для поиска 25+1(null terminal)=26 
                                                      //уставки и контрольная сумма умноженная на два, должны быть больше нуля  
char trueSource[maxnsym];                             //верифицированная строка для callback
char trueSourceOld[maxnsym];                          //предыдущая верифицированная строка для callback
char trueSource2[maxnsym];                             //верифицированная строка для callback
char trueSource2Old[maxnsym];                          //предыдущая верифицированная строка для callback

volatile char chr_a;                                        //в прерываниях переменные должны быть защищены  при помощи volatile от оптимизации компилятором
volatile bool flag_comand_detected = false;                 //если строка декодирована правильно то true
volatile bool flag_comand2_detected = false;                //если строка в блоке парсинга уставок eeprom декодирована правильно то true
volatile bool flag_zerostart = false;                       //если строка декодирована c нулевой контрольной суммой то true
//volatile bool flag_stopRegulator = true;                    //флаг остановки , закрыть все клапана 
//_____________________________________________________________________________
void save_EEPROM () {
    int data2;
    plotter.printf("EEPROM write------\r\n");    
    eeprom.byte_write(0, delta_value);
    eeprom.byte_write(1, flag_compressor);
    eeprom.byte_write(2, flag_stopRegulator);
    eeprom.byte_write(3, num_chan);
    data2 = value;
    eeprom.nbyte_write( 10, &data2, sizeof(int));
}
//_____________________________________________________________________________
void load_EEPROM () {
    uint8_t data1;
    int data2;
    plotter.printf("EEPROM read------\r\n");
    eeprom.nbyte_read( 0, &data1, 1 );
    plotter.printf("adress 0  =%d \r\n",data1);
    delta_value=data1;
    eeprom.nbyte_read( 1, &data1, 1 );
    plotter.printf("adress 1  =%d \r\n",data1);
    flag_compressor=data1;
    eeprom.nbyte_read( 2, &data1, 1 );
    plotter.printf("adress 2  =%d \r\n",data1);
    flag_stopRegulator=data1;
    eeprom.nbyte_read( 3, &data1, 1 );
    plotter.printf("adress 3  =%d \r\n",data1);
    num_chan=data1;
    eeprom.nbyte_read( 10, &data2, sizeof(int) );
    plotter.printf("adress 10  = %d \r\n",data2);
    value=data2;
    }
//______________________________________________________________________________
void substring(char *s,char *d,int pos,int len) {
//usage: substring(Source,Destination,pos,len);
    char *t;
    s=s+(pos-1);
    t=s+len;
    while (s!=t) {
        *d=*s;
        s++;
        d++;
    }
    *d='\0';
}
//______________________________________________________________________________
void onDataReceived();                                                          // callback
//______________________________________________________________________________ 
void read_serial(void) {
  char Destination[50];
  int pos,len;
  int controlSum1, controlSum2;
  int value_, delta_value_, flag_compressor_, flag_stopRegulator_, num_chan_;
  int controlSumSet1, controlSumSet2;
  int numSet_, anySet_;
  int ch = '$';    // Код искомого символа
  int indexCh;       // Char on position
  char *ach;       // Указатель на искомую переменную в строке, по которой осуществляется поиск.
    while(pc.readable()) {
       chr_a = pc.getc();
       //_____FIFO_buffer_begin_____
       for ( int i = 2; i < maxnsym; i++) {
       Source[i-2]=Source[i-1];
       }
       Source[maxnsym-2]=chr_a;                     //предпоследний элемент
       Source[maxnsym-1] ='\0';                     //последний элемент массива это нуль-терминал для формирования конца строки в Си
       //_____FIFO_buffer_end_______
    }
   ach=strchr (Source,ch);   //поиск первого вхождения символа в строку , ищем указатель символа ‘$’
   if (ach==NULL) {
     //pc.printf ("Char  not finded \r\n");                   //Символ $ в строке не найден
     goto endParsing;        //пропускаем парсинг
   }
   else {
     indexCh = ach-Source+1;                                //вычитаем указатель из указателя!
     //pc.printf ("Char '$' on position  %d\r\n",indexCh);   //Искомый символ в строке на позиции 
   } 
   if (indexCh!=1) {                           //позиция символа $ не 1
     //pc.printf ("$ position not 1 \r\n");
     goto endParsing;       //пропускаем парсинг
   }
   
    pos=1;  //начало подстроки $press - на 1 позиции
    len=6;   //длина подстроки $press равна 6
    substring(Source,Destination,pos,len);
    //pc.printf("for pos=%d and  len=%d  resultat is  d= %s\r\n", pos, len, Destination);
    
    if (strcmp(Destination,"$press" ) != 0) {                                   //функция возвращает ноль если строки совпадают
      //pc.printf("wrong Destination=%s\r\n",Destination);                         //печать "неправильной" нулевой строки 
      goto eepromSet ;                                                         //в начале сообщения нет $press , переход с следующему блоку приёма
    }
    pos=8;  //начало подстроки 1000 - на 8 позиции
    len=4;   //длина подстроки 1000 равна 4
    substring(Source,Destination,pos,len);
    value_=atoi(Destination);
    //if (value_==0) {
    //  flag_zerostart = true;    //индикатор первого пуска удаленной программы на PC без введенных уставок, надо передать текущее состояние на PC
    //  goto endParsing;          //уставка должна быть больше еденицы, пропускаем парсинг
    //}
    //pc.printf("for pos=%d and  len=%d  resultat is  d= %s atoi=%d\r\n", pos, len, Destination, value_);
    pos=13;  //начало подстроки 25 - на 13 позиции
    len=2;   //длина подстроки 25 равна 2
    substring(Source,Destination,pos,len);
    delta_value_=atoi(Destination);
    //if (delta_value_==0) {
    //  flag_zerostart = true;    //индикатор первого пуска удаленной программы на PC без введенных уставок, надо передать текущее состояние на PC
    //  goto endParsing;       //уставка отклонения должна быть больше еденицы, пропускаем парсинг
    //}
    //pc.printf("for pos=%d and  len=%d  resultat is  d= %s atoi=%d\r\n", pos, len, Destination, delta_value_);
    pos=16;  //начало подстроки 0 - на 16 позиции
    len=1;   //длина подстроки 0 равна 1
    substring(Source,Destination,pos,len);
    flag_compressor_=atoi(Destination);
    //pc.printf("for pos=%d and  len=%d  resultat is  d= %s atoi=%d\r\n", pos, len, Destination, flag_compressor_);
    pos=18;  //начало подстроки 0 - на 18 позиции
    len=1;   //длина подстроки 0 равна 1
    substring(Source,Destination,pos,len);
    flag_stopRegulator_=atoi(Destination);
    //pc.printf("for pos=%d and  len=%d  resultat is  d= %s atoi=%d\r\n", pos, len, Destination, flag_stopRegulator_);
    
    pos=20;  //начало подстроки 1 - на 20 позиции
    len=1;   //длина подстроки 1 равна 1
    substring(Source,Destination,pos,len);
    num_chan_=atoi(Destination);
    //pc.printf("for pos=%d and  len=%d  resultat is  d= %s atoi=%d\r\n", pos, len, Destination, num_chan_);
    
    pos=22;  //начало подстроки 1025 - на 22 позиции
    len=4;   //длина подстроки 1025 равна 4
    substring(Source,Destination,pos,len);
    controlSum1=atoi(Destination);
    if (controlSum1==2) {
      flag_zerostart = true;       //индикатор первого пуска удаленной программы на PC без введенных уставок, надо передать текущее состояние на PC
      flag_compressor=flag_compressor_;  //здесь можно включать-выключать компрессор, но без записи в EEPROM
      goto endParsing;             //контрольная сумма должна быть больше двух, пропускаем парсинг
    }
    //pc.printf("for pos=%d and  len=%d  resultat is  d= %s atoi=%d\r\n", pos, len, Destination, controlSum1);
    controlSum2=(value_+delta_value_+flag_compressor_+flag_stopRegulator_+num_chan_)*2;            //удвоение чтобы не было одинаковых чисел в сообщении
    //pc.printf("controlSum1=%d   controlSum2=%d\r\n", controlSum1, controlSum2);
    if (controlSum1!=controlSum2) {                                             //не совпала контрольная сумма
      //pc.printf ("controlSum1!=controlSum2 \r\n");
      goto endParsing;                                                          //пропускаем парсинг
    }
    //*********присваиваем проверенные значения глобальным переменным***********
    strcpy(trueSource,Source);                                                  //копировать из Source в trueSource
    if (value_==0 || delta_value_==0) {                                         //при старте с пустой уставкой не изменяем их в регуляторе и не пишем в EEPROM
      flag_compressor=flag_compressor_;
      flag_stopRegulator=flag_stopRegulator_;                                               //для работы кнопки Stop
      } else {
      value=value_;
      delta_value=delta_value_;
      flag_compressor=flag_compressor_;
      flag_stopRegulator=flag_stopRegulator_;
      num_chan=num_chan_;  
    }      
    
    flag_comand_detected=true;        //если флаг true, то всем переменным  присвоены новые значения уставок
 goto endParsing ;                    //завершение блока приема рабочих уставок для работяющего релейного регулятора  

  //========Начало блока приёма аварийных граничных (максимальных) уставок для записи в EEPROM ===================
 eepromSet:
    if (strcmp(Destination,"$setup" ) != 0) {                                      //функция возвращает ноль если строки совпадают
      //pc.printf("wrong Destination=%s\r\n",Destination);                         //печать "неправильной" нулевой строки 
      goto endParsing ;                                                         //в начале сообщения нет $setup , пропускаем парсинг
    }
    pos=8;  //начало подстроки 123 - на 8 позиции
    len=3;   //длина подстроки 123 равна 3
    substring(Source,Destination,pos,len);
    numSet_=atoi(Destination);
    pos=12;  //начало подстроки 123456 - на 12 позиции
    len=6;   //длина подстроки 123456 равна 6
    substring(Source,Destination,pos,len);
    anySet_ =atoi(Destination);
    pos=19;  //начало подстроки 1234567 - на 19 позиции
    len=7;   //длина подстроки 1234567 равна 7
    substring(Source,Destination,pos,len);
    controlSumSet1 =atoi(Destination);
    controlSumSet2=(numSet_+anySet_)*2;
    if (controlSumSet1!=controlSumSet2) {                                       //не совпала контрольная сумма
      //pc.printf ("controlSumSet1!=controlSumSet2 \r\n");
      goto endParsing;                                                          //пропускаем парсинг
    }
    //*********присваиваем проверенные значения глобальным переменным***********
    strcpy(trueSource2,Source);                                                 //копировать из Source в trueSource2
    if (numSet_==0) {                                                           //при старте с пустым номером не изменяем уставки  и не пишем в EEPROM
      goto endParsing;                                                          //пропускаем парсинг
      } else {
      numSet=numSet_;
      anySet=anySet_;  
    }      
    
    switch ( numSet ) {
        case 1:            // это двоеточие
            
            plotter.printf("1 Valve1=%d\r\n",anySet);
            break;
        case 2:
            plotter.printf("2 Valve2=%d\r\n",anySet);
            break;
        case 3:
            plotter.printf("3 Valve3,4=%d\r\n",anySet);
            break;
        case 4:
            plotter.printf("4 Compressor=%d\r\n",anySet );
            break;
        case 10:
            Pd_eeprom = anySet;
            plotter.printf( "10 Pd_eeprom=%d\r\n",anySet );
            break;
        case 11:
            frequencyValve1_eeprom = anySet;
            plotter.printf( "11 frequencyValve1_eeprom=%d\r\n",anySet );
            break;
        case 12:
            frequencyValve2_eeprom = anySet;
            plotter.printf( "12 frequencyValve2_eeprom=%d\r\n",anySet );
            break;
        case 13:
            WL01_eeprom = anySet;
            plotter.printf( "13 WL01_eeprom=%d\r\n",anySet );
            break;
        case 14:
            WL99_eeprom = anySet;
            plotter.printf( "14 WL99_eeprom=%d\r\n",anySet );
            break;
        case 18:
            T_1 = anySet;
            plotter.printf( "18 T_1=%d\r\n",anySet );
            break;
        case 19:
            T_2 = anySet;
            plotter.printf( "19 T_2=%d\r\n",anySet );
            break;                            
        default:
            plotter.printf( "Wrong case.\r\n" );
    } 
 






    
    flag_comand2_detected=true;        //если флаг true, то всем переменным  присвоены новые значения уставок
  //========Конец блока приёма аварийных граничных (максимальных) уставок для записи в EEPROM ===================
 
 endParsing:   
    
        
pc.attach(&onDataReceived, Serial::RxIrq);                             // reattach interrupt - переподключение прерывания перед выходом из функции
}
//______________________________________________________________________________
void onDataReceived() {
    pc.attach(nullptr, Serial::RxIrq);                                          // detach interrupt
    queue->call(read_serial);                                                   // process in a non ISR context - переход к функции приема строки -
}                                                                               // - в статусе отключенного прерывания (учим указатели!)
//______________________________________________________________________________
void auto_set () {                                                              //подпрограмма управления компрессором
    
    digital_6.write(flag_compressor);                                              //включение-выкючение компрессора   
 
}
//*****************************************************************************
//***************************************************************************** 

int main() {
    
    pc.attach(&onDataReceived, Serial::RxIrq);
    int time, time_2, time_3, valve1, valve2, countValve1=0, countValve2=0, temp_valueSensor;
    int frequencyValve1, frequencyValve2;
    float raw_value_sum_0=0, raw_value_sum_1=0, raw_value_sum_2=0, raw_value_sum_3=0, raw_value_sum_4=0, raw_value_sum_5=0;
    digital_4.write(0);                                                         //valve1  off;
    digital_7.write(0);                                                         //valve2  off;    
    digital_5.write(0);                                                         //valve3,4  off; 
    digital_6.write(0);                                                         //выключение компрессора
    load_EEPROM ();                                                             //загрузка уставок из EEPROM
    if (value >= 1 && delta_value >= 1 && flag_compressor < 2 && flag_stopRegulator < 2 && num_chan < 6) {
      flag_stopRegulator=false;                                                 //уставки из EEPROM похожи на правду, разрешаем работу регулятора 
    } else {
      flag_stopRegulator = true;                                                //флаг остановки установлен 
      pc.printf("Regulator stopped, error in EEPROM \r\n");       
    }
      
    pc.printf("Program started \r\n");
    Watchdog &watchdog = Watchdog::get_instance();
    watchdog.start(100);                         //WDlimit = 100  ms
    timer.start();
    timer_2.start();
    timer_3.start();
    
  while (true){                                                                 //бесконечный цикл
    // kick watchdog regularly within provided timeout (сброс собаки в начало счёта)
    watchdog.kick();
    
    if (flag_stopRegulator == 1){ event_N = 255;}                               //сброс события через кнопку Стоп в программе оператора 
    
    if (flag_stopRegulator == 1 || event_N < 255) {                             //полный останов регулятора и принудительное запирание всех клапанов
      digital_4.write(0);                                                       //valve1  off
      digital_7.write(0);                                                       //valve2  off
      digital_5.write(0);                                                       //valve3,4 off
      //digital_6.write(0);                                                       //выключение компрессора
    }
    
    if (flag_comand_detected) {                                                 //пришла правильная командная строка
                                                 
      pc.printf("$press,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,*\r\n",
        value,delta_value,flag_compressor,flag_stopRegulator,
        sensor_value,frequencyValve1,frequencyValve2,
        WL,Pb,Pw1,Pw2,Pd,
        digital_4.read(),digital_7.read(),digital_5.read(),digital_6.read(),event_N,idigital_11.read(),idigital_12.read(),idigital_13.read());        //передача текущих значений в РС
        
    //    pc.printf("$press,%d,%d,%d,%d,%d,%d,%d,*\r\n",
    //    value,delta_value,flag_compressor,flag_stopRegulator,
    //    sensor_value,frequencyValve1,frequencyValve2);                                     //передача текущих значений в РС
        
      //pc.printf("%s\r\n",trueSource);                                         //эхо для отладки канала связи
      flag_comand_detected = false;                                               //в последующих обращениях не печатать пока нет новых уставок из СОМ-порта
      //flag_stopRegulator = false;                                                 //сброс флага,  регулятор ждет пока  не будет сброшен этот флаг
      //plotter.printf("$%d %d %d %d %d;\r\n", digital_4.read()*100-110,
      //  digital_7.read()*100-220, value, sensor_value, time );                //печать в плоттер в другой СОМ-порт
      if (strcmp(trueSourceOld,trueSource) != 0) {                              //функция возвращает ноль если командные строки совпадают
        save_EEPROM ();                                                         //пишем в память уставки отличные от старых
        load_EEPROM ();
      }
      
      strcpy(trueSourceOld,trueSource);        //копировать из trueSource в trueSourceOld 
    }
    
    if (flag_zerostart) {                                            //пришла командная строка с пустыми уставками (актуально для получения данных на PC при первом запуске)
      pc.printf("$press,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,*\r\n",
        value,delta_value,flag_compressor,flag_stopRegulator,
        sensor_value,frequencyValve1,frequencyValve2,
        WL,Pb,Pw1,Pw2,Pd,
        digital_4.read(),digital_7.read(),digital_5.read(),digital_6.read(),event_N,idigital_11.read(),idigital_12.read(),idigital_13.read());        //передача текущих значений в РС  
        flag_zerostart = false;
    }   
    
    if (counter_cycle1 < 10 ) {
      float raw_value_0 = analog_value_0.read();                                     // Чтение аналогового входа 0 (0.0 to 1.0 = full ADC диапазон)
      raw_value_sum_0 = raw_value_sum_0 + raw_value_0;
      float raw_value_1 = analog_value_1.read();                                     // Чтение аналогового входа 1 (0.0 to 1.0 = full ADC диапазон)
      raw_value_sum_1 = raw_value_sum_1 + raw_value_1;
      float raw_value_2 = analog_value_2.read();                                     // Чтение аналогового входа 2 (0.0 to 1.0 = full ADC диапазон)
      raw_value_sum_2 = raw_value_sum_2 + raw_value_2;
    }
    if (counter_cycle1 >= 10 ) {
      float raw_value_3 = analog_value_3.read();                                     // Чтение аналогового входа 3 (0.0 to 1.0 = full ADC диапазон)
      raw_value_sum_3 = raw_value_sum_3 + raw_value_3;
      float raw_value_4 = analog_value_4.read();                                     // Чтение аналогового входа 4 (0.0 to 1.0 = full ADC диапазон)
      raw_value_sum_4 = raw_value_sum_4 + raw_value_4;
      //float raw_value_5 = analog_value_5.read();                                     // Чтение аналогового входа 5 (0.0 to 1.0 = full ADC диапазон)
      //raw_value_sum_5 = raw_value_sum_5 + raw_value_5;
    }
       
    if (counter_cycle1 >= 19 ) {
      counter_cycle1=0;
      
      WL = raw_value_sum_0/10 * 3300;                                           // преобразование в напряжение 0-3300 mV  с усреднением
      raw_value_sum_0 = 0 ;
      sensor_value = raw_value_sum_1/10 * 3300;                                 // преобразование в напряжение 0-3300 mV  с усреднением
      raw_value_sum_1 = 0 ;
      Pb = raw_value_sum_2/10 * 3300;                                           // преобразование в напряжение 0-3300 mV  с усреднением
      raw_value_sum_2 = 0 ;
      Pw1 = raw_value_sum_3/10 * 3300;                                          // преобразование в напряжение 0-3300 mV  с усреднением
      raw_value_sum_3 = 0 ;
      Pw2 = raw_value_sum_4/10 * 3300;                                          // преобразование в напряжение 0-3300 mV  с усреднением
      raw_value_sum_4 = 0 ;
      //Pd = raw_value_sum_5/20 * 3300;                                           // преобразование в напряжение 0-3300 mV  с усреднением
      //raw_value_sum_5 = 0 ;
      Pd = abs(sensor_value - Pw1);
      
      if (num_chan == 1) {temp_valueSensor = sensor_value;}                     //теперь источник сигнала для регулятора - канал 1
      if (num_chan == 3) {temp_valueSensor = Pw1;}                              //теперь источник сигнала для регулятора - канал 3
      if (num_chan == 4) {temp_valueSensor = Pw2;}                              //теперь источник сигнала для регулятора - канал 4
      
      if (flag_stopRegulator == 0 && event_N == 255) {                          // можно запускать регулятор
        digital_5.write(1);                                                     //valve3,4 открыты - подключаемся к контуру охлаждения макета
        //--------------regulator begin-----------------------
        if (temp_valueSensor > value + delta_value) {
          valve2 = digital_7.read();
          digital_7.write(1);                                                     //valve2  on;
          if (valve2 < digital_7.read()) {countValve2++;}                         //счётчик передних фронтов напряжения (срабатывания клапана 2)
          digital_4.write(0);                                                     //valve1  off;
        } else  if (temp_valueSensor < value - delta_value) {
          valve1 = digital_4.read();
          digital_4.write(1);                                                     //valve1  on;
          if (valve1 < digital_4.read()) {countValve1++;}                         //счётчик передних фронтов напряжения (срабатывания клапана 1)
          digital_7.write(0);                                                     //valve2  off; 
        } else {
          digital_4.write(0);                                                     //valve1  off;
          digital_7.write(0);                                                     //valve2  off; 
        }
        //--------------regulator end-------------------------
      }
      time=timer.read_us();
      if (time > 1000000) {
        timer.reset();                                                          //начало счёта времени
        frequencyValve1 =  countValve1;                                         //частота (Гц) срабатывания клапана 1 
        frequencyValve2 =  countValve2;                                         //частота (Гц) срабатывания клапана 2 
        countValve1=0;
        countValve2=0;
      }
      //--------------------==_ALARM_scope_Begin==----------------------
       if (Pd >= Pd_eeprom) {
             event_N = 0;
       }
       if (frequencyValve1 >= frequencyValve1_eeprom) {
             event_N = 1;
       }
       if (frequencyValve2 >= frequencyValve2_eeprom) {
             event_N = 2;
       }
       if (WL <= WL01_eeprom) {
             event_N = 3;
       }
       if (WL >= WL99_eeprom) {
             event_N = 4;
       }
       if (idigital_11.read()==1) {
             event_N = 5;
       }
       if (idigital_12.read()==1) {
             event_N = 6;
       }
       if (idigital_13.read()==1) {
             event_N = 7;
       }
      
      //-----------------Valve1 open time----------------------
        if (digital_4.read() == 0) {
            timer_2.reset(); 
            time_2 = 0;
        } else {
          time_2 = timer_2.read_ms();   
        }
        if (time_2 >= T_1) {
             event_N = 8;
        }
     //-----------------Valve2 open time----------------------
        if (digital_7.read() == 0) {
            timer_3.reset();
            time_3 = 0;
        } else {
          time_3 = timer_3.read_ms();   
        }
        if (time_3 >= T_2) {
             event_N = 9;
        }
      //--------------------==_ALARM_scope_End==----------------------          
     
      
      auto_set();                                                               //включение-выкючение компрессора  через flag_compressor
      //led = !led;                                                               //гасим/зажигаем индикаторный светодиод
    } 
    ThisThread::sleep_for(1);                                                   // (mc) правильный оператор задержки для mbed5
    counter_cycle1++;
    
  }
}