Alex K
/
mbed-os5-press_23
On the i2c bus, Arduino Nano with address 2, transmits the weight value with a resolution of 1 kg.
main.cpp
- Committer:
- Aleksk
- Date:
- 2021-10-08
- Revision:
- 11:86a18c130515
- Parent:
- 10:b6de15a30716
File content as of revision 11:86a18c130515:
// 07.10.2021 Продолжение (клон )mbed-os5-press22 // По шине i2c Arduino Nano с адресом 2, передает значение веса с дискретностью 1 кг. // digital pin 11, pin 12 as an input концевики теперь нормально замкнутые // Вернул timer_4. Теперь он периодически открывает выпускной клапан для контроля утечек воды. // Вместо pc.printf("Reset ALARM \r\n") теперь plotter.printf("Reset ALARM \r\n") это нужно для парсера программы Setup_EEPROM // Удалена команда pc.printf, посылающая пустую строку раз в секунду и связанный с ней timer_4, т.к. изменена программа оператора (Loc()). // Суммирование значений каналов А0 А1 А2 было 9 раз, исправлено на 10. // Передаваемые через pc.printf сообщения в РС дополнены контрольными суммами для увеличения надёжности связи. // Введена команда pc.printf, посылающая пустую строку раз в секунду, на случай потери (порчи )данных при пересылке и // возможного зависания программы оператора при ожидании символа из serial порта (для этого добавлен timer_4). // Значения уставок EEPROM2 выводяться в pc.print в специальной строке с текущими данными диагностики // Сделан дополнительный блок в парсере для декодирования приходящих аварийных уставок, они пишутся в EEPROM2 // Сделан 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); const int addr7bit = 0x02; // 7 bit I2C address slave Arduino_Nano const int addr8bit = 0x02 << 1; // 8bit I2C address, 0x90 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 13 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 Timer timer_4; //инициализация таймера 4 для отсчёта периода времени между контрольными открываниями вентиля 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 - событий нет uint8_t flag_stopRegulatorEEPROM = 0; //если 1 остановка регулятора, когда вручную управляют клапанами через программу SetUp_EEPROM int openTimeV2_H2O = 2; // ms, Время открытого состояния вентиля V2 для датчика влаги должно быть меньше WDlimit=100ms int periodV2_H2O = 10000; // ms, Период открывания вентиля V2 для датчика влаги //======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 save_EEPROM2 () { int data2; plotter.printf("EEPROM2 write------\r\n"); eeprom.nbyte_read( 100, &data2, sizeof(int) ); if (data2 != Pd_eeprom) { //записываем в eeprom только изменившиеся значения (одна из семи уставок) data2 = Pd_eeprom; eeprom.nbyte_write( 100, &data2, sizeof(int)); } eeprom.nbyte_read( 110, &data2, sizeof(int) ); if (data2 != frequencyValve1_eeprom){ data2 = frequencyValve1_eeprom; eeprom.nbyte_write( 110, &data2, sizeof(int)); } eeprom.nbyte_read( 120, &data2, sizeof(int) ); if (data2 != frequencyValve2_eeprom){ data2 = frequencyValve2_eeprom; eeprom.nbyte_write( 120, &data2, sizeof(int)); } eeprom.nbyte_read( 130, &data2, sizeof(int) ); if (data2 != WL01_eeprom){ data2 = WL01_eeprom; eeprom.nbyte_write( 130, &data2, sizeof(int)); } eeprom.nbyte_read( 140, &data2, sizeof(int) ); if (data2 != WL99_eeprom){ data2 = WL99_eeprom; eeprom.nbyte_write( 140, &data2, sizeof(int)); } eeprom.nbyte_read( 180, &data2, sizeof(int) ); if (data2 != T_1){ data2 = T_1; eeprom.nbyte_write( 180, &data2, sizeof(int)); } eeprom.nbyte_read( 190, &data2, sizeof(int) ); if (data2 != T_2){ data2 = T_2; eeprom.nbyte_write( 190, &data2, sizeof(int)); } eeprom.nbyte_read( 200, &data2, sizeof(int) ); if (data2 != openTimeV2_H2O){ data2 = openTimeV2_H2O; eeprom.nbyte_write( 200, &data2, sizeof(int)); } eeprom.nbyte_read( 210, &data2, sizeof(int) ); if (data2 != periodV2_H2O){ data2 = periodV2_H2O; eeprom.nbyte_write( 210, &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 load_EEPROM2 () { int data2; plotter.printf("EEPROM2 read------\r\n"); eeprom.nbyte_read( 100, &data2, sizeof(int) ); //pc.printf("$adress,100,%d,*\r\n",data2); Pd_eeprom=data2; eeprom.nbyte_read( 110, &data2, sizeof(int) ); //pc.printf("$adress,110,%d,*\r\n",data2); frequencyValve1_eeprom=data2; eeprom.nbyte_read( 120, &data2, sizeof(int) ); //pc.printf("$adress,120,%d,*\r\n",data2); frequencyValve2_eeprom=data2; eeprom.nbyte_read( 130, &data2, sizeof(int) ); //pc.printf("$adress,130,%d,*\r\n",data2); WL01_eeprom=data2; eeprom.nbyte_read( 140, &data2, sizeof(int) ); //pc.printf("$adress,140,%d,*\r\n",data2); WL99_eeprom=data2; eeprom.nbyte_read( 180, &data2, sizeof(int) ); //pc.printf("$adress,180,%d,*\r\n",data2); T_1=data2; eeprom.nbyte_read( 190, &data2, sizeof(int) ); //pc.printf("$adress,190,%d,*\r\n",data2); T_2=data2; eeprom.nbyte_read( 200, &data2, sizeof(int) ); //pc.printf("$adress,200,%d,*\r\n",data2); openTimeV2_H2O=data2; eeprom.nbyte_read( 210, &data2, sizeof(int) ); //pc.printf("$adress,210,%d,*\r\n",data2); periodV2_H2O=data2; //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); } //______________________________________________________________________________ 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_stopRegulatorEEPROM = 0; //флаг остановки только релейного регулятора (теперь регулятор управляет клапанами!) 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_; } //При первом входе в режим $setup из режима $press - Закрываются все клапана if (flag_stopRegulatorEEPROM == 0) { digital_4.write(0); //valve1 off digital_7.write(0); //valve2 off digital_5.write(0); //valve3,4 off digital_6.write(0); //выключение компрессора } switch ( numSet ) { case 1: // это двоеточие digital_4.write(anySet); //valve1 plotter.printf("1 Valve1=%d\r\n",anySet); break; case 2: digital_7.write(anySet); //valve2 plotter.printf("2 Valve2=%d\r\n",anySet); break; case 3: digital_5.write(anySet); //valve3,4 plotter.printf("3 Valve3,4=%d\r\n",anySet); break; case 4: digital_6.write(anySet); //компрессор plotter.printf("4 Compressor=%d\r\n",anySet ); break; case 9: if (anySet == 0) { flag_stopRegulator=0; plotter.printf("Reset ALARM \r\n"); } else { flag_stopRegulator = 1; } 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; case 20: openTimeV2_H2O = anySet; plotter.printf( "20 openTimeV2_H2O=%d\r\n",anySet ); break; case 21: periodV2_H2O = anySet; plotter.printf( "21 periodV2_H2O=%d\r\n",anySet ); break; default: plotter.printf( "Wrong case.\r\n" ); } flag_stopRegulatorEEPROM = 1; //флаг остановки только релейного регулятора (теперь оператор вручную управляет клапанами!) 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 () { //подпрограмма управления компрессором if (flag_stopRegulatorEEPROM == 0) { digital_6.write(flag_compressor); //включение-выкючение компрессора } } //****************************************************************************************************************** //****************************************************************************************************************** int main() { pc.attach(&onDataReceived, Serial::RxIrq); int time, time_2, time_3, time_4, ks, 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; char cmd[1]; //массив с весом, принятым от slave //i2c.read( addr8bit, cmd, 1); //читаем вес по шине i2c из slave Arduino_Nano //pc.printf("cmd[0] = %x\n", cmd[0]); digital_4.write(0); //valve1 off; digital_7.write(0); //valve2 off; digital_5.write(0); //valve3,4 off; digital_6.write(0); //выключение компрессора //eeprom.nbyte_write( 200, &openTimeV2_H2O, sizeof(int)); //debug set //eeprom.nbyte_write( 210, &periodV2_H2O, sizeof(int)); //debug set load_EEPROM (); //загрузка уставок из EEPROM load_EEPROM2 (); //загрузка граничных уставок (аварийных событий)из EEPROM2 if (value >= 1 && delta_value >= 1 && flag_compressor < 2 && flag_stopRegulator < 2 && num_chan < 6) { flag_stopRegulator=0; //уставки из EEPROM похожи на правду, разрешаем работу регулятора } else { flag_stopRegulator = 1; //флаг остановки установлен 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(); timer_4.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) { //пришла правильная командная строка ks=(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())*2; 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", 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(), ks); //передача текущих значений в РС //pc.printf("%s\r\n",trueSource); //эхо для отладки канала связи flag_comand_detected = false; //в последующих обращениях не печатать пока нет новых уставок из СОМ-порта if (strcmp(trueSourceOld,trueSource) != 0) { //функция возвращает ноль если командные строки совпадают save_EEPROM (); //пишем в память уставки отличные от старых load_EEPROM (); } strcpy(trueSourceOld,trueSource); //копировать из trueSource в trueSourceOld } if (flag_comand2_detected ) { //пришла правильная строка из программы SetUp_EEPROM и передана уставка ks=(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()+ Pd_eeprom+frequencyValve1_eeprom+frequencyValve2_eeprom+WL01_eeprom+WL99_eeprom+T_1+T_2+openTimeV2_H2O+periodV2_H2O)*2; 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", value,delta_value,flag_compressor,flag_stopRegulator, //1,2,3,4 sensor_value,frequencyValve1,frequencyValve2, //5,6,7 WL,Pb,Pw1,Pw2,Pd, //8,9,10,11,12 digital_4.read(),digital_7.read(),digital_5.read(),digital_6.read(), //13,14,15,16 event_N,idigital_11.read(),idigital_12.read(),idigital_13.read(), //17,18,19,20 Pd_eeprom,frequencyValve1_eeprom,frequencyValve2_eeprom,WL01_eeprom,WL99_eeprom,T_1,T_2, openTimeV2_H2O,periodV2_H2O,ks); //21,22,23,24,25,26,27,28,29,30 flag_comand2_detected = false; //в последующих обращениях не печатать пока нет нового сообщения из СОМ-порта if (strcmp(trueSource2Old,trueSource2) != 0 && numSet >= 10) { //функция возвращает ноль если командные строки совпадают save_EEPROM2 (); //пишем в память все уставки от SetUp_EEPROM если хоть одна изменилась load_EEPROM2 (); } strcpy(trueSource2Old,trueSource2); //копировать из trueSource2 в trueSource2Old //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); } if (flag_zerostart) { //пришла командная строка с пустыми уставками (актуально для получения данных на PC при первом запуске) ks=(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())*2; 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", 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(), ks); //передача текущих значений в РС flag_zerostart = false; } //счет counter_cycle1 идет от еденицы if (counter_cycle1 < 11 ) { 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 >= 11 ) { 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 >= 20 ) { 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 && flag_stopRegulatorEEPROM == 0) { // можно запускать регулятор digital_5.write(1); //valve3,4 открыты - подключаемся к контуру охлаждения макета //-----------Контроль протечки воды через периодическое отпирание Valve2---------- time_4 = timer_4.read_ms(); if (time_4 >= periodV2_H2O) { //Время таймера достигло периода включения вентиля V2 timer_4.reset(); digital_7.write(1); //valve2 on; ThisThread::sleep_for(openTimeV2_H2O); //Время открытого состояния (mc) вентиля V2 должно быть меньше WDlimit=100ms digital_7.write(0); //valve2 off; } //--------------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; i2c.read( addr8bit, cmd, 1); //читаем вес по шине i2c из slave Arduino_Nano WL=cmd[0]; //plotter.printf("cmd[0] = %x\n", cmd[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()==0) { event_N = 7; } //-----------------Valve1 open time---------------------- if (digital_4.read() == 0 || flag_stopRegulatorEEPROM == 1 ) { // для режима $setup отключаем счёт времени 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 || flag_stopRegulatorEEPROM == 1) { // для режима $setup отключаем счёт времен 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++; } }