Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 // 07.10.2021 Продолжение (клон )mbed-os5-press22 00002 // По шине i2c Arduino Nano с адресом 2, передает значение веса с дискретностью 1 кг. 00003 // digital pin 11, pin 12 as an input концевики теперь нормально замкнутые 00004 // Вернул timer_4. Теперь он периодически открывает выпускной клапан для контроля утечек воды. 00005 // Вместо pc.printf("Reset ALARM \r\n") теперь plotter.printf("Reset ALARM \r\n") это нужно для парсера программы Setup_EEPROM 00006 // Удалена команда pc.printf, посылающая пустую строку раз в секунду и связанный с ней timer_4, т.к. изменена программа оператора (Loc()). 00007 // Суммирование значений каналов А0 А1 А2 было 9 раз, исправлено на 10. 00008 // Передаваемые через pc.printf сообщения в РС дополнены контрольными суммами для увеличения надёжности связи. 00009 // Введена команда pc.printf, посылающая пустую строку раз в секунду, на случай потери (порчи )данных при пересылке и 00010 // возможного зависания программы оператора при ожидании символа из serial порта (для этого добавлен timer_4). 00011 // Значения уставок EEPROM2 выводяться в pc.print в специальной строке с текущими данными диагностики 00012 // Сделан дополнительный блок в парсере для декодирования приходящих аварийных уставок, они пишутся в EEPROM2 00013 // Сделан timer_2 для отсчёта времени открытого состояния вентиля 1 00014 // Сделан timer_3 для отсчёта времени открытого состояния вентиля 2 00015 // Подключены цифровые входы D11,D12,D13. Реализованы условия остановки по 10 аварийным событиям. 00016 // Реализован сброс события (event_N = 255) через кнопку Стоп в программе оператора 00017 // Принимается флаг от кнопки Стоп - полной остановки регулятора - закрытие всех 4-х клапанов и передача статуса кнопки в программу оператора 00018 // Принимается флаг от кнопок включения - выключения компрессора, - идет команда на дискретный выход digital_6(PB_10) 00019 // Принимается новая уставка num_chan - переключение номера активного измерительного канала для обратной связи регулятора. 00020 // Эта уставка, как и все остальные, пишется в EEPROM. 00021 // Включены все шесть аналоговых входа, читаются пять 00022 // при получении командной строки с нулевой суммой, по новому флагу flag_zerostart, передаётся в сериал текущие уставки и величины 00023 // (важно для старта программы на PC), эти нулевые уставки не вводятся в регулятор и не записываются в EEPROM. 00024 // сторожевой таймер, истекает через 100мс 00025 // 00026 00027 #include "mbed.h" 00028 #include "_24LCXXX.h" 00029 00030 I2C i2c(PB_9,PB_8); // sda, scl 00031 _24LCXXX eeprom(&i2c, 0x50); 00032 const int addr7bit = 0x02; // 7 bit I2C address slave Arduino_Nano 00033 const int addr8bit = 0x02 << 1; // 8bit I2C address, 0x90 00034 00035 AnalogIn analog_value_0(A0); //подключение аналогового входа A0 00036 AnalogIn analog_value_1(A1); //подключение аналогового входа A1 00037 AnalogIn analog_value_2(A2); //подключение аналогового входа A2 00038 AnalogIn analog_value_3(A3); //подключение аналогового входа A3 00039 AnalogIn analog_value_4(A4); //подключение аналогового входа A4 00040 AnalogIn analog_value_5(A5); //подключение аналогового входа A5 00041 //DigitalOut led(LED1); 00042 DigitalOut digital_4(PB_5); //initialize digital pin 4 as an output (high pressure air bulb charge). 00043 DigitalOut digital_7(PA_8); //initialize digital pin 7 as an output. (high pressure air bulb discharge) 00044 DigitalOut digital_5(PB_4); //initialize digital pin 5 as an output (valve3,4) 00045 DigitalOut digital_6(PB_10); //initialize digital pin 6 as an output (compressor on/off) 00046 DigitalIn idigital_11(PA_7); //initialize digital pin 11 as an input концевик при растяжении сильфона 00047 DigitalIn idigital_12(PA_6); //initialize digital pin 12 as an input концевик при сжатии сильфона 00048 DigitalIn idigital_13(PA_5); //initialize digital pin 13 as an input внутрь опрессовщика попала вода 00049 00050 RawSerial plotter(USBTX, USBRX, 115200); // tx, rx for F411RE port for serial_plotter and temporary messages 00051 RawSerial pc(PA_9, PA_10, 115200); // tx, rx for F411RE port for command string distance PC 00052 EventQueue *queue = mbed_event_queue(); //инициализация очереди событий RTOS mbed5 00053 Timer timer; //инициализация таймера для определения частот переключений вентилей 1 и 2 00054 Timer timer_2; //инициализация таймера 2 для отсчёта времени открытого состояния вентиля 1 00055 Timer timer_3; //инициализация таймера 3 для отсчёта времени открытого состояния вентиля 2 00056 Timer timer_4; //инициализация таймера 4 для отсчёта периода времени между контрольными открываниями вентиля 2 00057 //========УСТАВКИ_1 EEPROM======== 00058 uint8_t delta_value = 0; //set delta pressure 1...99 00059 uint8_t flag_compressor = 0; //флаг компрессора. При 0 - выключение компрессора, при 1 - включение компрессора 00060 uint8_t flag_stopRegulator = 0; //Stop- флаг . При 0 - разрешение работы регулятора, при 1 - запрет и запиране всех клапанов 00061 uint8_t num_chan = 1; //set номер аналогового канала 0...5 (1-as default = Pa) 00062 int value = 0; //set begin value "pressure" 1...3300 00063 //========УСТАВКИ_2 EEPROM======== 00064 int Pd_eeprom = 2000; // mV, максимальное дифференциальное давление (беззнаковое) 00065 int frequencyValve1_eeprom = 5; // Гц, максимальная частота переключений клапана 1 00066 int frequencyValve2_eeprom = 5; // Гц, максимальная частота переключений клапана 2 00067 int WL01_eeprom = 10; // mV, минимальный вес опрессовщика 00068 int WL99_eeprom = 2000; // mV, максимальный вес опрессовщика 00069 int T_1 = 4000; // ms, максимальное время открытого состояния для клапана 1 00070 int T_2 = 4000; // ms, максимальное время открытого состояния для клапана 2 00071 uint8_t event_N = 255; // номер события , по умолчанию 255 - событий нет 00072 uint8_t flag_stopRegulatorEEPROM = 0; //если 1 остановка регулятора, когда вручную управляют клапанами через программу SetUp_EEPROM 00073 int openTimeV2_H2O = 2; // ms, Время открытого состояния вентиля V2 для датчика влаги должно быть меньше WDlimit=100ms 00074 int periodV2_H2O = 10000; // ms, Период открывания вентиля V2 для датчика влаги 00075 00076 //======temporary set===== 00077 int numSet, anySet; 00078 //================================= 00079 int value_auto=250 ; //set begin value auto "pressure" 00080 int WL = 0; //напряжение с аналогового входа А0 (WL - вес опресовщика) 00081 int sensor_value =0; //напряжение с аналогового входа А1 (Pa - текущее давление) 00082 int Pb = 0; //напряжение с аналогового входа А2 (Pb - давление в баллоне) 00083 int Pw1 = 0; //напряжение с аналогового входа А3 (Pw1 - давление воды на входе опрессовщика) 00084 int Pw2 = 0; //напряжение с аналогового входа А4 (Pw2 - давление воды в контуре макета) 00085 int Pd = 0; //напряжение с аналогового входа А5 (Pd - дифференциальное давление опресовщика) 00086 int counter_cycle1 = 0; //счётчик цикла while(true) 00087 int counter_cycle2 = 0; //счётчик внутри функции auto_set 00088 int sig = 1; //знак инкримента для автоустаки 00089 00090 // FIFO_buffer must be full (only char and '\0') 00091 //#define maxnsym 26 // maximum nbr of symbols FIFO_buffer (вариант без символов окончания) 00092 #define maxnsym 28 // maximum nbr of symbols FIFO_buffer +CR+LF (символы окончания должны быть включены на передаче) 00093 char Source[maxnsym]="$press,1000,25,0,0,1,2050**"; //25 char- string ,весь массив со строкой для поиска 25+1(null terminal)=26 00094 //уставки и контрольная сумма умноженная на два, должны быть больше нуля 00095 char trueSource[maxnsym]; //верифицированная строка для callback 00096 char trueSourceOld[maxnsym]; //предыдущая верифицированная строка для callback 00097 char trueSource2[maxnsym]; //верифицированная строка для callback 00098 char trueSource2Old[maxnsym]; //предыдущая верифицированная строка для callback 00099 00100 volatile char chr_a; //в прерываниях переменные должны быть защищены при помощи volatile от оптимизации компилятором 00101 volatile bool flag_comand_detected = false; //если строка декодирована правильно то true 00102 volatile bool flag_comand2_detected = false; //если строка в блоке парсинга уставок eeprom декодирована правильно то true 00103 volatile bool flag_zerostart = false; //если строка декодирована c нулевой контрольной суммой то true 00104 //volatile bool flag_stopRegulator = true; //флаг остановки , закрыть все клапана 00105 //_____________________________________________________________________________ 00106 void save_EEPROM () { 00107 int data2; 00108 plotter.printf("EEPROM write------\r\n"); 00109 eeprom.byte_write(0, delta_value); 00110 eeprom.byte_write(1, flag_compressor); 00111 eeprom.byte_write(2, flag_stopRegulator); 00112 eeprom.byte_write(3, num_chan); 00113 data2 = value; 00114 eeprom.nbyte_write( 10, &data2, sizeof(int)); 00115 } 00116 void save_EEPROM2 () { 00117 int data2; 00118 plotter.printf("EEPROM2 write------\r\n"); 00119 eeprom.nbyte_read( 100, &data2, sizeof(int) ); 00120 if (data2 != Pd_eeprom) { //записываем в eeprom только изменившиеся значения (одна из семи уставок) 00121 data2 = Pd_eeprom; 00122 eeprom.nbyte_write( 100, &data2, sizeof(int)); 00123 } 00124 eeprom.nbyte_read( 110, &data2, sizeof(int) ); 00125 if (data2 != frequencyValve1_eeprom){ 00126 data2 = frequencyValve1_eeprom; 00127 eeprom.nbyte_write( 110, &data2, sizeof(int)); 00128 } 00129 eeprom.nbyte_read( 120, &data2, sizeof(int) ); 00130 if (data2 != frequencyValve2_eeprom){ 00131 data2 = frequencyValve2_eeprom; 00132 eeprom.nbyte_write( 120, &data2, sizeof(int)); 00133 } 00134 eeprom.nbyte_read( 130, &data2, sizeof(int) ); 00135 if (data2 != WL01_eeprom){ 00136 data2 = WL01_eeprom; 00137 eeprom.nbyte_write( 130, &data2, sizeof(int)); 00138 } 00139 eeprom.nbyte_read( 140, &data2, sizeof(int) ); 00140 if (data2 != WL99_eeprom){ 00141 data2 = WL99_eeprom; 00142 eeprom.nbyte_write( 140, &data2, sizeof(int)); 00143 } 00144 eeprom.nbyte_read( 180, &data2, sizeof(int) ); 00145 if (data2 != T_1){ 00146 data2 = T_1; 00147 eeprom.nbyte_write( 180, &data2, sizeof(int)); 00148 } 00149 eeprom.nbyte_read( 190, &data2, sizeof(int) ); 00150 if (data2 != T_2){ 00151 data2 = T_2; 00152 eeprom.nbyte_write( 190, &data2, sizeof(int)); 00153 } 00154 eeprom.nbyte_read( 200, &data2, sizeof(int) ); 00155 if (data2 != openTimeV2_H2O){ 00156 data2 = openTimeV2_H2O; 00157 eeprom.nbyte_write( 200, &data2, sizeof(int)); 00158 } 00159 eeprom.nbyte_read( 210, &data2, sizeof(int) ); 00160 if (data2 != periodV2_H2O){ 00161 data2 = periodV2_H2O; 00162 eeprom.nbyte_write( 210, &data2, sizeof(int)); 00163 } 00164 } 00165 //_____________________________________________________________________________ 00166 void load_EEPROM () { 00167 uint8_t data1; 00168 int data2; 00169 plotter.printf("EEPROM read------\r\n"); 00170 eeprom.nbyte_read( 0, &data1, 1 ); 00171 plotter.printf("adress 0 =%d \r\n",data1); 00172 delta_value=data1; 00173 eeprom.nbyte_read( 1, &data1, 1 ); 00174 plotter.printf("adress 1 =%d \r\n",data1); 00175 flag_compressor=data1; 00176 eeprom.nbyte_read( 2, &data1, 1 ); 00177 plotter.printf("adress 2 =%d \r\n",data1); 00178 flag_stopRegulator=data1; 00179 eeprom.nbyte_read( 3, &data1, 1 ); 00180 plotter.printf("adress 3 =%d \r\n",data1); 00181 num_chan=data1; 00182 eeprom.nbyte_read( 10, &data2, sizeof(int) ); 00183 plotter.printf("adress 10 = %d \r\n",data2); 00184 value=data2; 00185 } 00186 void load_EEPROM2 () { 00187 int data2; 00188 plotter.printf("EEPROM2 read------\r\n"); 00189 eeprom.nbyte_read( 100, &data2, sizeof(int) ); 00190 //pc.printf("$adress,100,%d,*\r\n",data2); 00191 Pd_eeprom=data2; 00192 eeprom.nbyte_read( 110, &data2, sizeof(int) ); 00193 //pc.printf("$adress,110,%d,*\r\n",data2); 00194 frequencyValve1_eeprom=data2; 00195 eeprom.nbyte_read( 120, &data2, sizeof(int) ); 00196 //pc.printf("$adress,120,%d,*\r\n",data2); 00197 frequencyValve2_eeprom=data2; 00198 eeprom.nbyte_read( 130, &data2, sizeof(int) ); 00199 //pc.printf("$adress,130,%d,*\r\n",data2); 00200 WL01_eeprom=data2; 00201 eeprom.nbyte_read( 140, &data2, sizeof(int) ); 00202 //pc.printf("$adress,140,%d,*\r\n",data2); 00203 WL99_eeprom=data2; 00204 eeprom.nbyte_read( 180, &data2, sizeof(int) ); 00205 //pc.printf("$adress,180,%d,*\r\n",data2); 00206 T_1=data2; 00207 eeprom.nbyte_read( 190, &data2, sizeof(int) ); 00208 //pc.printf("$adress,190,%d,*\r\n",data2); 00209 T_2=data2; 00210 eeprom.nbyte_read( 200, &data2, sizeof(int) ); 00211 //pc.printf("$adress,200,%d,*\r\n",data2); 00212 openTimeV2_H2O=data2; 00213 eeprom.nbyte_read( 210, &data2, sizeof(int) ); 00214 //pc.printf("$adress,210,%d,*\r\n",data2); 00215 periodV2_H2O=data2; 00216 //pc.printf("$adress,%d,%d,%d,%d,%d,%d,%d,%d,%d,*\r\n",Pd_eeprom,frequencyValve1_eeprom,frequencyValve2_eeprom,WL01_eeprom,WL99_eeprom,T_1,T_2,openTimeV2_H2O,periodV2_H2O); 00217 } 00218 //______________________________________________________________________________ 00219 void substring(char *s,char *d,int pos,int len) { 00220 //usage: substring(Source,Destination,pos,len); 00221 char *t; 00222 s=s+(pos-1); 00223 t=s+len; 00224 while (s!=t) { 00225 *d=*s; 00226 s++; 00227 d++; 00228 } 00229 *d='\0'; 00230 } 00231 //______________________________________________________________________________ 00232 void onDataReceived(); // callback 00233 //______________________________________________________________________________ 00234 void read_serial(void) { 00235 char Destination[50]; 00236 int pos,len; 00237 int controlSum1, controlSum2; 00238 int value_, delta_value_, flag_compressor_, flag_stopRegulator_, num_chan_; 00239 int controlSumSet1, controlSumSet2; 00240 int numSet_, anySet_; 00241 int ch = '$'; // Код искомого символа 00242 int indexCh; // Char on position 00243 char *ach; // Указатель на искомую переменную в строке, по которой осуществляется поиск. 00244 while(pc.readable()) { 00245 chr_a = pc.getc(); 00246 //_____FIFO_buffer_begin_____ 00247 for ( int i = 2; i < maxnsym; i++) { 00248 Source[i-2]=Source[i-1]; 00249 } 00250 Source[maxnsym-2]=chr_a; //предпоследний элемент 00251 Source[maxnsym-1] ='\0'; //последний элемент массива это нуль-терминал для формирования конца строки в Си 00252 //_____FIFO_buffer_end_______ 00253 } 00254 ach=strchr (Source,ch); //поиск первого вхождения символа в строку , ищем указатель символа ‘$’ 00255 if (ach==NULL) { 00256 //pc.printf ("Char not finded \r\n"); //Символ $ в строке не найден 00257 goto endParsing; //пропускаем парсинг 00258 } 00259 else { 00260 indexCh = ach-Source+1; //вычитаем указатель из указателя! 00261 //pc.printf ("Char '$' on position %d\r\n",indexCh); //Искомый символ в строке на позиции 00262 } 00263 if (indexCh!=1) { //позиция символа $ не 1 00264 //pc.printf ("$ position not 1 \r\n"); 00265 goto endParsing; //пропускаем парсинг 00266 } 00267 00268 pos=1; //начало подстроки $press - на 1 позиции 00269 len=6; //длина подстроки $press равна 6 00270 substring(Source,Destination,pos,len); 00271 //pc.printf("for pos=%d and len=%d resultat is d= %s\r\n", pos, len, Destination); 00272 00273 if (strcmp(Destination,"$press" ) != 0) { //функция возвращает ноль если строки совпадают 00274 //pc.printf("wrong Destination=%s\r\n",Destination); //печать "неправильной" нулевой строки 00275 goto eepromSet ; //в начале сообщения нет $press , переход с следующему блоку приёма 00276 } 00277 pos=8; //начало подстроки 1000 - на 8 позиции 00278 len=4; //длина подстроки 1000 равна 4 00279 substring(Source,Destination,pos,len); 00280 value_=atoi(Destination); 00281 //if (value_==0) { 00282 // flag_zerostart = true; //индикатор первого пуска удаленной программы на PC без введенных уставок, надо передать текущее состояние на PC 00283 // goto endParsing; //уставка должна быть больше еденицы, пропускаем парсинг 00284 //} 00285 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, value_); 00286 pos=13; //начало подстроки 25 - на 13 позиции 00287 len=2; //длина подстроки 25 равна 2 00288 substring(Source,Destination,pos,len); 00289 delta_value_=atoi(Destination); 00290 //if (delta_value_==0) { 00291 // flag_zerostart = true; //индикатор первого пуска удаленной программы на PC без введенных уставок, надо передать текущее состояние на PC 00292 // goto endParsing; //уставка отклонения должна быть больше еденицы, пропускаем парсинг 00293 //} 00294 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, delta_value_); 00295 pos=16; //начало подстроки 0 - на 16 позиции 00296 len=1; //длина подстроки 0 равна 1 00297 substring(Source,Destination,pos,len); 00298 flag_compressor_=atoi(Destination); 00299 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, flag_compressor_); 00300 pos=18; //начало подстроки 0 - на 18 позиции 00301 len=1; //длина подстроки 0 равна 1 00302 substring(Source,Destination,pos,len); 00303 flag_stopRegulator_=atoi(Destination); 00304 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, flag_stopRegulator_); 00305 00306 pos=20; //начало подстроки 1 - на 20 позиции 00307 len=1; //длина подстроки 1 равна 1 00308 substring(Source,Destination,pos,len); 00309 num_chan_=atoi(Destination); 00310 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, num_chan_); 00311 00312 pos=22; //начало подстроки 1025 - на 22 позиции 00313 len=4; //длина подстроки 1025 равна 4 00314 substring(Source,Destination,pos,len); 00315 controlSum1=atoi(Destination); 00316 if (controlSum1==2) { 00317 flag_zerostart = true; //индикатор первого пуска удаленной программы на PC без введенных уставок, надо передать текущее состояние на PC 00318 flag_compressor=flag_compressor_; //здесь можно включать-выключать компрессор, но без записи в EEPROM 00319 goto endParsing; //контрольная сумма должна быть больше двух, пропускаем парсинг 00320 } 00321 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, controlSum1); 00322 controlSum2=(value_+delta_value_+flag_compressor_+flag_stopRegulator_+num_chan_)*2; //удвоение чтобы не было одинаковых чисел в сообщении 00323 //pc.printf("controlSum1=%d controlSum2=%d\r\n", controlSum1, controlSum2); 00324 if (controlSum1!=controlSum2) { //не совпала контрольная сумма 00325 //pc.printf ("controlSum1!=controlSum2 \r\n"); 00326 goto endParsing; //пропускаем парсинг 00327 } 00328 //*********присваиваем проверенные значения глобальным переменным*********** 00329 strcpy(trueSource,Source); //копировать из Source в trueSource 00330 if (value_==0 || delta_value_==0) { //при старте с пустой уставкой не изменяем их в регуляторе и не пишем в EEPROM 00331 flag_compressor=flag_compressor_; 00332 flag_stopRegulator=flag_stopRegulator_; //для работы кнопки Stop 00333 } else { 00334 value=value_; 00335 delta_value=delta_value_; 00336 flag_compressor=flag_compressor_; 00337 flag_stopRegulator=flag_stopRegulator_; 00338 num_chan=num_chan_; 00339 } 00340 flag_stopRegulatorEEPROM = 0; //флаг остановки только релейного регулятора (теперь регулятор управляет клапанами!) 00341 flag_comand_detected=true; //если флаг true, то всем переменным присвоены новые значения уставок 00342 goto endParsing ; //завершение блока приема рабочих уставок для работяющего релейного регулятора 00343 00344 //========Начало блока приёма аварийных граничных (максимальных) уставок для записи в EEPROM =================== 00345 eepromSet: 00346 if (strcmp(Destination,"$setup" ) != 0) { //функция возвращает ноль если строки совпадают 00347 //pc.printf("wrong Destination=%s\r\n",Destination); //печать "неправильной" нулевой строки 00348 goto endParsing ; //в начале сообщения нет $setup , пропускаем парсинг 00349 } 00350 pos=8; //начало подстроки 123 - на 8 позиции 00351 len=3; //длина подстроки 123 равна 3 00352 substring(Source,Destination,pos,len); 00353 numSet_=atoi(Destination); 00354 pos=12; //начало подстроки 123456 - на 12 позиции 00355 len=6; //длина подстроки 123456 равна 6 00356 substring(Source,Destination,pos,len); 00357 anySet_ =atoi(Destination); 00358 pos=19; //начало подстроки 1234567 - на 19 позиции 00359 len=7; //длина подстроки 1234567 равна 7 00360 substring(Source,Destination,pos,len); 00361 controlSumSet1 =atoi(Destination); 00362 controlSumSet2=(numSet_+anySet_)*2; 00363 if (controlSumSet1!=controlSumSet2) { //не совпала контрольная сумма 00364 //pc.printf ("controlSumSet1!=controlSumSet2 \r\n"); 00365 goto endParsing; //пропускаем парсинг 00366 } 00367 //*********присваиваем проверенные значения глобальным переменным*********** 00368 strcpy(trueSource2,Source); //копировать из Source в trueSource2 00369 if (numSet_==0) { //при старте с пустым номером не изменяем уставки и не пишем в EEPROM 00370 goto endParsing; //пропускаем парсинг 00371 } else { 00372 numSet=numSet_; 00373 anySet=anySet_; 00374 } 00375 //При первом входе в режим $setup из режима $press - Закрываются все клапана 00376 if (flag_stopRegulatorEEPROM == 0) { 00377 digital_4.write(0); //valve1 off 00378 digital_7.write(0); //valve2 off 00379 digital_5.write(0); //valve3,4 off 00380 digital_6.write(0); //выключение компрессора 00381 } 00382 00383 switch ( numSet ) { 00384 case 1: // это двоеточие 00385 digital_4.write(anySet); //valve1 00386 plotter.printf("1 Valve1=%d\r\n",anySet); 00387 break; 00388 case 2: 00389 digital_7.write(anySet); //valve2 00390 plotter.printf("2 Valve2=%d\r\n",anySet); 00391 break; 00392 case 3: 00393 digital_5.write(anySet); //valve3,4 00394 plotter.printf("3 Valve3,4=%d\r\n",anySet); 00395 break; 00396 case 4: 00397 digital_6.write(anySet); //компрессор 00398 plotter.printf("4 Compressor=%d\r\n",anySet ); 00399 break; 00400 case 9: 00401 if (anySet == 0) { 00402 flag_stopRegulator=0; 00403 plotter.printf("Reset ALARM \r\n"); 00404 } else { 00405 flag_stopRegulator = 1; 00406 } 00407 break; 00408 case 10: 00409 Pd_eeprom = anySet; 00410 plotter.printf( "10 Pd_eeprom=%d\r\n",anySet ); 00411 break; 00412 case 11: 00413 frequencyValve1_eeprom = anySet; 00414 plotter.printf( "11 frequencyValve1_eeprom=%d\r\n",anySet ); 00415 break; 00416 case 12: 00417 frequencyValve2_eeprom = anySet; 00418 plotter.printf( "12 frequencyValve2_eeprom=%d\r\n",anySet ); 00419 break; 00420 case 13: 00421 WL01_eeprom = anySet; 00422 plotter.printf( "13 WL01_eeprom=%d\r\n",anySet ); 00423 break; 00424 case 14: 00425 WL99_eeprom = anySet; 00426 plotter.printf( "14 WL99_eeprom=%d\r\n",anySet ); 00427 break; 00428 case 18: 00429 T_1 = anySet; 00430 plotter.printf( "18 T_1=%d\r\n",anySet ); 00431 break; 00432 case 19: 00433 T_2 = anySet; 00434 plotter.printf( "19 T_2=%d\r\n",anySet ); 00435 break; 00436 case 20: 00437 openTimeV2_H2O = anySet; 00438 plotter.printf( "20 openTimeV2_H2O=%d\r\n",anySet ); 00439 break; 00440 case 21: 00441 periodV2_H2O = anySet; 00442 plotter.printf( "21 periodV2_H2O=%d\r\n",anySet ); 00443 break; 00444 default: 00445 plotter.printf( "Wrong case.\r\n" ); 00446 } 00447 00448 flag_stopRegulatorEEPROM = 1; //флаг остановки только релейного регулятора (теперь оператор вручную управляет клапанами!) 00449 flag_comand2_detected=true; //если флаг true, то всем переменным присвоены новые значения уставок 00450 //========Конец блока приёма аварийных граничных (максимальных) уставок для записи в EEPROM =================== 00451 00452 endParsing: 00453 00454 00455 pc.attach(&onDataReceived, Serial::RxIrq); // reattach interrupt - переподключение прерывания перед выходом из функции 00456 } 00457 //______________________________________________________________________________ 00458 void onDataReceived() { 00459 pc.attach(nullptr, Serial::RxIrq); // detach interrupt 00460 queue->call(read_serial); // process in a non ISR context - переход к функции приема строки - 00461 } // - в статусе отключенного прерывания (учим указатели!) 00462 //______________________________________________________________________________ 00463 void auto_set () { //подпрограмма управления компрессором 00464 00465 if (flag_stopRegulatorEEPROM == 0) { 00466 digital_6.write(flag_compressor); //включение-выкючение компрессора 00467 } 00468 } 00469 //****************************************************************************************************************** 00470 //****************************************************************************************************************** 00471 00472 int main() { 00473 00474 pc.attach(&onDataReceived, Serial::RxIrq); 00475 int time, time_2, time_3, time_4, ks, valve1, valve2, countValve1=0, countValve2=0, temp_valueSensor; 00476 int frequencyValve1, frequencyValve2; 00477 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; 00478 char cmd[1]; //массив с весом, принятым от slave 00479 //i2c.read( addr8bit, cmd, 1); //читаем вес по шине i2c из slave Arduino_Nano 00480 //pc.printf("cmd[0] = %x\n", cmd[0]); 00481 00482 digital_4.write(0); //valve1 off; 00483 digital_7.write(0); //valve2 off; 00484 digital_5.write(0); //valve3,4 off; 00485 digital_6.write(0); //выключение компрессора 00486 //eeprom.nbyte_write( 200, &openTimeV2_H2O, sizeof(int)); //debug set 00487 //eeprom.nbyte_write( 210, &periodV2_H2O, sizeof(int)); //debug set 00488 load_EEPROM (); //загрузка уставок из EEPROM 00489 load_EEPROM2 (); //загрузка граничных уставок (аварийных событий)из EEPROM2 00490 if (value >= 1 && delta_value >= 1 && flag_compressor < 2 && flag_stopRegulator < 2 && num_chan < 6) { 00491 flag_stopRegulator=0; //уставки из EEPROM похожи на правду, разрешаем работу регулятора 00492 } else { 00493 flag_stopRegulator = 1; //флаг остановки установлен 00494 pc.printf("Regulator stopped, error in EEPROM \r\n"); 00495 } 00496 00497 pc.printf("Program started \r\n"); 00498 Watchdog &watchdog = Watchdog::get_instance(); 00499 watchdog.start(100); //WDlimit = 100 ms 00500 timer.start(); 00501 timer_2.start(); 00502 timer_3.start(); 00503 timer_4.start(); 00504 00505 while (true){ //бесконечный цикл 00506 // kick watchdog regularly within provided timeout (сброс собаки в начало счёта) 00507 watchdog.kick(); 00508 00509 if (flag_stopRegulator == 1){ event_N = 255;} //сброс события через кнопку Стоп в программе оператора 00510 00511 if (flag_stopRegulator == 1 || event_N < 255) { //полный останов регулятора и принудительное запирание всех клапанов 00512 digital_4.write(0); //valve1 off 00513 digital_7.write(0); //valve2 off 00514 digital_5.write(0); //valve3,4 off 00515 //digital_6.write(0); //выключение компрессора 00516 } 00517 00518 if (flag_comand_detected) { //пришла правильная командная строка 00519 ks=(value+delta_value+flag_compressor+flag_stopRegulator+ 00520 sensor_value+frequencyValve1+frequencyValve2+ 00521 WL+Pb+Pw1+Pw2+Pd+ 00522 digital_4.read()+digital_7.read()+digital_5.read()+digital_6.read()+event_N+idigital_11.read()+idigital_12.read()+idigital_13.read())*2; 00523 pc.printf("$press,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,*\r\n", 00524 value,delta_value,flag_compressor,flag_stopRegulator, 00525 sensor_value,frequencyValve1,frequencyValve2, 00526 WL,Pb,Pw1,Pw2,Pd, 00527 digital_4.read(),digital_7.read(),digital_5.read(),digital_6.read(),event_N,idigital_11.read(),idigital_12.read(),idigital_13.read(), 00528 ks); //передача текущих значений в РС 00529 00530 //pc.printf("%s\r\n",trueSource); //эхо для отладки канала связи 00531 flag_comand_detected = false; //в последующих обращениях не печатать пока нет новых уставок из СОМ-порта 00532 00533 if (strcmp(trueSourceOld,trueSource) != 0) { //функция возвращает ноль если командные строки совпадают 00534 save_EEPROM (); //пишем в память уставки отличные от старых 00535 load_EEPROM (); 00536 } 00537 00538 strcpy(trueSourceOld,trueSource); //копировать из trueSource в trueSourceOld 00539 } 00540 00541 if (flag_comand2_detected ) { //пришла правильная строка из программы SetUp_EEPROM и передана уставка 00542 ks=(value+delta_value+flag_compressor+flag_stopRegulator+ 00543 sensor_value+frequencyValve1+frequencyValve2+ 00544 WL+Pb+Pw1+Pw2+Pd+ 00545 digital_4.read()+digital_7.read()+digital_5.read()+digital_6.read()+ 00546 event_N+idigital_11.read()+idigital_12.read()+idigital_13.read()+ 00547 Pd_eeprom+frequencyValve1_eeprom+frequencyValve2_eeprom+WL01_eeprom+WL99_eeprom+T_1+T_2+openTimeV2_H2O+periodV2_H2O)*2; 00548 pc.printf("$press,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,*\r\n", 00549 value,delta_value,flag_compressor,flag_stopRegulator, //1,2,3,4 00550 sensor_value,frequencyValve1,frequencyValve2, //5,6,7 00551 WL,Pb,Pw1,Pw2,Pd, //8,9,10,11,12 00552 digital_4.read(),digital_7.read(),digital_5.read(),digital_6.read(), //13,14,15,16 00553 event_N,idigital_11.read(),idigital_12.read(),idigital_13.read(), //17,18,19,20 00554 Pd_eeprom,frequencyValve1_eeprom,frequencyValve2_eeprom,WL01_eeprom,WL99_eeprom,T_1,T_2, 00555 openTimeV2_H2O,periodV2_H2O,ks); //21,22,23,24,25,26,27,28,29,30 00556 flag_comand2_detected = false; //в последующих обращениях не печатать пока нет нового сообщения из СОМ-порта 00557 00558 if (strcmp(trueSource2Old,trueSource2) != 0 && numSet >= 10) { //функция возвращает ноль если командные строки совпадают 00559 00560 save_EEPROM2 (); //пишем в память все уставки от SetUp_EEPROM если хоть одна изменилась 00561 load_EEPROM2 (); 00562 } 00563 strcpy(trueSource2Old,trueSource2); //копировать из trueSource2 в trueSource2Old 00564 //pc.printf("$adress,%d,%d,%d,%d,%d,%d,%d,*\r\n",Pd_eeprom,frequencyValve1_eeprom,frequencyValve2_eeprom,WL01_eeprom,WL99_eeprom,T_1,T_2); 00565 } 00566 00567 if (flag_zerostart) { //пришла командная строка с пустыми уставками (актуально для получения данных на PC при первом запуске) 00568 ks=(value+delta_value+flag_compressor+flag_stopRegulator+ 00569 sensor_value+frequencyValve1+frequencyValve2+ 00570 WL+Pb+Pw1+Pw2+Pd+ 00571 digital_4.read()+digital_7.read()+digital_5.read()+digital_6.read()+event_N+idigital_11.read()+idigital_12.read()+idigital_13.read())*2; 00572 pc.printf("$press,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,*\r\n", 00573 value,delta_value,flag_compressor,flag_stopRegulator, 00574 sensor_value,frequencyValve1,frequencyValve2, 00575 WL,Pb,Pw1,Pw2,Pd, 00576 digital_4.read(),digital_7.read(),digital_5.read(),digital_6.read(),event_N,idigital_11.read(),idigital_12.read(),idigital_13.read(), 00577 ks); //передача текущих значений в РС 00578 flag_zerostart = false; 00579 } 00580 //счет counter_cycle1 идет от еденицы 00581 if (counter_cycle1 < 11 ) { 00582 float raw_value_0 = analog_value_0.read(); // Чтение аналогового входа 0 (0.0 to 1.0 = full ADC диапазон) 00583 raw_value_sum_0 = raw_value_sum_0 + raw_value_0; 00584 float raw_value_1 = analog_value_1.read(); // Чтение аналогового входа 1 (0.0 to 1.0 = full ADC диапазон) 00585 raw_value_sum_1 = raw_value_sum_1 + raw_value_1; 00586 float raw_value_2 = analog_value_2.read(); // Чтение аналогового входа 2 (0.0 to 1.0 = full ADC диапазон) 00587 raw_value_sum_2 = raw_value_sum_2 + raw_value_2; 00588 } 00589 if (counter_cycle1 >= 11 ) { 00590 float raw_value_3 = analog_value_3.read(); // Чтение аналогового входа 3 (0.0 to 1.0 = full ADC диапазон) 00591 raw_value_sum_3 = raw_value_sum_3 + raw_value_3; 00592 float raw_value_4 = analog_value_4.read(); // Чтение аналогового входа 4 (0.0 to 1.0 = full ADC диапазон) 00593 raw_value_sum_4 = raw_value_sum_4 + raw_value_4; 00594 //float raw_value_5 = analog_value_5.read(); // Чтение аналогового входа 5 (0.0 to 1.0 = full ADC диапазон) 00595 //raw_value_sum_5 = raw_value_sum_5 + raw_value_5; 00596 } 00597 00598 if (counter_cycle1 >= 20 ) { 00599 counter_cycle1=0; 00600 00601 //WL = raw_value_sum_0/10 * 3300; // преобразование в напряжение 0-3300 mV с усреднением 00602 raw_value_sum_0 = 0 ; 00603 sensor_value = raw_value_sum_1/10 * 3300; // преобразование в напряжение 0-3300 mV с усреднением 00604 raw_value_sum_1 = 0 ; 00605 Pb = raw_value_sum_2/10 * 3300; // преобразование в напряжение 0-3300 mV с усреднением 00606 raw_value_sum_2 = 0 ; 00607 Pw1 = raw_value_sum_3/10 * 3300; // преобразование в напряжение 0-3300 mV с усреднением 00608 raw_value_sum_3 = 0 ; 00609 Pw2 = raw_value_sum_4/10 * 3300; // преобразование в напряжение 0-3300 mV с усреднением 00610 raw_value_sum_4 = 0 ; 00611 //Pd = raw_value_sum_5/20 * 3300; // преобразование в напряжение 0-3300 mV с усреднением 00612 //raw_value_sum_5 = 0 ; 00613 Pd = abs(sensor_value - Pw1); 00614 00615 if (num_chan == 1) {temp_valueSensor = sensor_value;} //теперь источник сигнала для регулятора - канал 1 00616 if (num_chan == 3) {temp_valueSensor = Pw1;} //теперь источник сигнала для регулятора - канал 3 00617 if (num_chan == 4) {temp_valueSensor = Pw2;} //теперь источник сигнала для регулятора - канал 4 00618 00619 if (flag_stopRegulator == 0 && event_N == 255 && flag_stopRegulatorEEPROM == 0) { // можно запускать регулятор 00620 digital_5.write(1); //valve3,4 открыты - подключаемся к контуру охлаждения макета 00621 //-----------Контроль протечки воды через периодическое отпирание Valve2---------- 00622 time_4 = timer_4.read_ms(); 00623 if (time_4 >= periodV2_H2O) { //Время таймера достигло периода включения вентиля V2 00624 timer_4.reset(); 00625 digital_7.write(1); //valve2 on; 00626 ThisThread::sleep_for(openTimeV2_H2O); //Время открытого состояния (mc) вентиля V2 должно быть меньше WDlimit=100ms 00627 digital_7.write(0); //valve2 off; 00628 } 00629 //--------------regulator begin----------------------- 00630 if (temp_valueSensor > value + delta_value) { 00631 valve2 = digital_7.read(); 00632 digital_7.write(1); //valve2 on; 00633 if (valve2 < digital_7.read()) {countValve2++;} //счётчик передних фронтов напряжения (срабатывания клапана 2) 00634 digital_4.write(0); //valve1 off; 00635 } else if (temp_valueSensor < value - delta_value) { 00636 valve1 = digital_4.read(); 00637 digital_4.write(1); //valve1 on; 00638 if (valve1 < digital_4.read()) {countValve1++;} //счётчик передних фронтов напряжения (срабатывания клапана 1) 00639 digital_7.write(0); //valve2 off; 00640 } else { 00641 digital_4.write(0); //valve1 off; 00642 digital_7.write(0); //valve2 off; 00643 } 00644 //--------------regulator end------------------------- 00645 } 00646 time=timer.read_us(); //условие будет выполнятся ровно один раз в секунду 00647 if (time > 1000000) { 00648 timer.reset(); //начало счёта времени 00649 frequencyValve1 = countValve1; //частота (Гц) срабатывания клапана 1 00650 frequencyValve2 = countValve2; //частота (Гц) срабатывания клапана 2 00651 countValve1=0; 00652 countValve2=0; 00653 i2c.read( addr8bit, cmd, 1); //читаем вес по шине i2c из slave Arduino_Nano 00654 WL=cmd[0]; 00655 //plotter.printf("cmd[0] = %x\n", cmd[0]); 00656 } 00657 //--------------------==_ALARM_scope_Begin==---------------------- 00658 if (Pd >= Pd_eeprom) { 00659 event_N = 0; 00660 } 00661 if (frequencyValve1 >= frequencyValve1_eeprom) { 00662 event_N = 1; 00663 } 00664 if (frequencyValve2 >= frequencyValve2_eeprom) { 00665 event_N = 2; 00666 } 00667 if (WL <= WL01_eeprom) { 00668 event_N = 3; 00669 } 00670 if (WL >= WL99_eeprom) { 00671 event_N = 4; 00672 } 00673 if (idigital_11.read()==1) { 00674 event_N = 5; 00675 } 00676 if (idigital_12.read()==1) { 00677 event_N = 6; 00678 } 00679 if (idigital_13.read()==0) { 00680 event_N = 7; 00681 } 00682 00683 //-----------------Valve1 open time---------------------- 00684 if (digital_4.read() == 0 || flag_stopRegulatorEEPROM == 1 ) { // для режима $setup отключаем счёт времени 00685 timer_2.reset(); 00686 time_2 = 0; 00687 } else { 00688 time_2 = timer_2.read_ms(); 00689 } 00690 if (time_2 >= T_1) { 00691 event_N = 8; 00692 } 00693 //-----------------Valve2 open time---------------------- 00694 if (digital_7.read() == 0 || flag_stopRegulatorEEPROM == 1) { // для режима $setup отключаем счёт времен 00695 timer_3.reset(); 00696 time_3 = 0; 00697 } else { 00698 time_3 = timer_3.read_ms(); 00699 } 00700 if (time_3 >= T_2) { 00701 event_N = 9; 00702 } 00703 //--------------------==_ALARM_scope_End==---------------------- 00704 00705 00706 auto_set(); //включение-выкючение компрессора через flag_compressor 00707 //led = !led; //гасим/зажигаем индикаторный светодиод 00708 } 00709 00710 00711 00712 ThisThread::sleep_for(1); // (mc) правильный оператор задержки для mbed5 00713 counter_cycle1++; 00714 00715 } 00716 }
Generated on Thu Aug 25 2022 06:07:46 by
1.7.2