
The values of the EEPROM2 settings are displayed in pc.print in a special line with the current diagnostic data. An additional block has been made in the parser for decoding incoming alarm settings; they are written in EEPROM2.
Diff: main.cpp
- Revision:
- 0:f2aaa8c6decf
- Child:
- 1:1d4ec28f17c4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri May 01 11:41:23 2020 +0000 @@ -0,0 +1,222 @@ +#include "mbed.h" + +AnalogIn analog_value(A0); //подключение аналогового входа A0 +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 +RawSerial pc(USBTX, USBRX, 115200); // tx, rx for F411RE in port command string +RawSerial plotter(PA_9, PA_10, 115200); // tx, rx for F411RE out port for serial_plotter +EventQueue *queue = mbed_event_queue(); //инициализация очереди событий RTOS mbed5 +Timer timer; //инициализация таймера + +int flag_autoset = 0; //отладочный флаг. При 0 - запрет автоуставки давления, при 1 - разрешение +int flag_plotter = 0; //отладочный флаг. При 0 - запрет печати в плоттер, при 1 - разрешение +int value = 0; //set begin value "pressure" +int delta_value = 0; //set delta pressure +int value_auto=250 ; //set begin value auto "pressure" +int sensor_value =0; //напряжение с аналогового входа А0 (текущее давление) +int counter_cycle1 = 0; +int counter_cycle2 = 0; +int sig = 1; //знак инкримента для автоустаки +// FIFO_buffer must be full (only char and '\0') +//#define maxnsym 24 // maximum nbr of symbols FIFO_buffer (вариант без символов окончания) +#define maxnsym 26 // maximum nbr of symbols FIFO_buffer +CR+LF (символы окончания должны быть включены на передаче) +char Source[maxnsym]="$press,1000,25,0,0,2050**"; //23 char- string ,весь массив со строкой для поиска 23+1(null terminal)=24 + //уставки и контрольная сумма умноженная на два, должны быть больше нуля +char trueSource[maxnsym]; //верифицированная строка для callback + +volatile char chr_a; //в прерываниях переменные должны быть защищены при помощи volatile от оптимизации компилятором +volatile bool flag_comand_detected = false; //если строка декодирована правильно то true + +//______________________________________________________________________________ +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_autoset_, flag_plotter_; + 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 endParsing ; //в начале сообщения нет $press пропускаем парсинг + } + pos=8; //начало подстроки 1000 - на 8 позиции + len=4; //длина подстроки 1000 равна 4 + substring(Source,Destination,pos,len); + value_=atoi(Destination); + if (value_==0) { + 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) { + 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_autoset_=atoi(Destination); + //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, flag_autoset_); + pos=18; //начало подстроки 0 - на 18 позиции + len=1; //длина подстроки 0 равна 1 + substring(Source,Destination,pos,len); + flag_plotter_=atoi(Destination); + //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, flag_plotter_); + pos=20; //начало подстроки 1025 - на 18 позиции + len=4; //длина подстроки 1025 равна 4 + substring(Source,Destination,pos,len); + controlSum1=atoi(Destination); + if (controlSum1==0) { + 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_autoset_+flag_plotter_)*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 + value=value_; + delta_value=delta_value_; + flag_autoset=flag_autoset_; + flag_plotter=flag_plotter_; + flag_comand_detected=true; //если флаг true, то всем переменным присвоены новые значения уставок + + 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 (counter_cycle2 >= 100 && flag_autoset == 1) { + counter_cycle2=0; + if (value_auto > 2800 || value_auto < 250) { + sig = -sig; //меняем знак для изменения направления роста/спада автоуставки + } + value_auto = value_auto + sig * 250; + value=value_auto; + } + counter_cycle2++; //увеличиваем счетчик функции auto_set() на 1 +} +//***************************************************************************** +//***************************************************************************** + +int main() { + pc.printf("program started \r\n"); + pc.attach(&onDataReceived, Serial::RxIrq); + int time, valve1, valve2, countValve1=0, countValve2=0; + int frequencyValve1, frequencyValve2; + float raw_value_sum = 0 ; + timer.start(); + while (true){ //бесконечный цикл + + if (flag_comand_detected) { + pc.printf("$press,%d,%d,%d,%d,%d\r\n", + value,delta_value,flag_autoset,flag_plotter,sensor_value); //текущие данные + //pc.printf("%s\r\n",trueSource); //эхо для отладки канала связи + flag_comand_detected=false; //в последующих обращениях не печатать пока нет новых уставок из СОМ-порта + //plotter.printf("$%d %d %d %d %d;\r\n", digital_4.read()*100-110, + // digital_7.read()*100-220, value, sensor_value, time ); //печать в плоттер в другой СОМ-порт + } + float raw_value = analog_value.read(); // Чтение аналогового входа (0.0 to 1.0 = full ADC диапазон) + raw_value_sum = raw_value_sum + raw_value; + + if (counter_cycle1 > 20 ) { + counter_cycle1=0; + sensor_value = raw_value_sum/20 * 3300; // преобразование в напряжение 0-3300 mV с усреднением + raw_value_sum = 0 ; + //--------------regulator begin----------------------- + if (sensor_value > value + delta_value) { + valve2 = digital_7.read(); + digital_7.write(1); //valve2 = 1; + if (valve2 < digital_7.read()) {countValve2++;} //счётчик передних фронтов напряжения (срабатывания клапана 2) + digital_4.write(0); //valve1 = 0; + } else if (sensor_value < value - delta_value) { + valve1 = digital_4.read(); + digital_4.write(1); //valve1 = 1; + if (valve1 < digital_4.read()) {countValve1++;} //счётчик передних фронтов напряжения (срабатывания клапана 1) + digital_7.write(0); //valve2 = 0; + } else { + digital_4.write(0); //valve1 = 0; + digital_7.write(0); //valve2 = 0; + } + //--------------regulator end------------------------- + time=timer.read_us(); + if (time > 1000000) { + timer.reset(); //начало счёта времени + frequencyValve1 = countValve1; //частота (Гц) срабатывания клапана 1 + frequencyValve2 = countValve2; //частота (Гц) срабатывания клапана 2 + countValve1=0; + countValve2=0; + } + + if (flag_plotter == 1) { + plotter.printf("$%d %d %d %d %d %d;\r\n", digital_4.read()*100-110, + digital_7.read()*100-220, value, sensor_value, 100*frequencyValve1, 100*frequencyValve2 ); //печать в плоттер в другой СОМ-порт (только для отладки) + } + + auto_set(); //Ступенчатое увеличение и уменьшение уставки value (для отладки если flag_autoset =1) + led = !led; //гасим/зажигаем индикаторный светодиод + } + ThisThread::sleep_for(1); // (mc) правильный оператор задержки для mbed5 + counter_cycle1++; + + } +} \ No newline at end of file