Alex K / Mbed OS F411_mbed-os5-serial_interrupt_press_8

Files at this revision

API Documentation at this revision

Comitter:
Aleksk
Date:
Fri Apr 24 16:31:28 2020 +0000
Parent:
3:285d45a0d928
Commit message:
The relay controller. $press, 1000,25,0,1 - for example, the following are transmitted: $ - service symbol, 1000 - pressure setpoint, 25 - delta pressure , 0 - auto-set flag OFF, 1- flag serial plotter ON .; Add protection from random input string.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Fri Apr 17 13:27:48 2020 +0000
+++ b/main.cpp	Fri Apr 24 16:31:28 2020 +0000
@@ -1,116 +1,163 @@
 #include "mbed.h"
-//17.04.2020 15:30
+//24.04.2020 11:53
 //Программа для пошагового чтения байтов из последовательного порта и разделения потока байтов на подстроки в реальном времени. Разделитель - запятая.
 //Строка сообщения должна заканчиваться только одним символом /r  или  /n (обнаружение признака окончания сообщения можно сделать любым)
 //Программа нормально разбивает принимаемую строку на подстроки (до 20) в количестве равном количеству запятых, плюс последняя подстрока без запятой.
 //Регулятор релейного типа отлажен на RC-эмуляторе сосуда с двумя клапанами. Давление здесь измеряется в милливольтах. 
-//$,1000,25,0 - для примера здесь передаются:$ - служебный символ, 1000 - уставка давления, 25 - уставка погрешности давления, 0 - флаг запрета работы автоуставки
-
-AnalogIn analog_value(A0);                                          //подключение аналогового входа A0
+//$press,1000,25,0,0 - для примера здесь передаются:
+//$press - идентификатор строки, 1000 - уставка давления, 25 - уставка погрешности давления, 0 - флаг запрета автоуставки, 0 - флаг запрета печати плоттера
+ 
+AnalogIn analog_value(A0);                                                      //подключение аналогового входа A0
 DigitalOut led(LED1);
-DigitalOut digitalWrite4(PB_5);                                    // initialize digital pin 4 as an output (high pressure air bulb charge).
-DigitalOut digitalWrite7(PA_8);                                    // initialize digital pin 7 as an output. (high pressure air bulb discharge
-RawSerial pc(USBTX, USBRX, 115200);
+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
+//Serial pc(PA_9,PA_10);                                                        // tx, rx for F091RC    out port diagnostica
+//Serial plotter(PC_10,PC_11);                                                      // tx, rx for F091RC    in port command string
+
 EventQueue *queue = mbed_event_queue();                                         //инициализация очереди событий RTOS mbed5
+Timer timer;
 
 #define maxnstr 20                                                              // maximum nbr of params(sybstrings) used to hold the data fields
 #define maxnsym 20                                                              // maximum nbr of symbols
-char comand[maxnstr][maxnsym]={""};                                             // 
-int nstr=0;                                                                     //номер строки 
-
-int pressure=0;                                      //давление (аналоговый вход) (резерв)
-int pressure_set=0;                                  //уставка давления (резерв)
-int pressure_set_max=0;                              //уставка максимальног давления (резерв)
-int flag_autoset=1;                                 //отладочный флаг. При 0 - запрет автоуставки давления, при 1 - разрешение
-int value=1000;                   //set "pressure" 
-int delta_value=25;              //set delta pressure
-int counter_cycle1=0;
-int counter_cycle2=0;
-int sig=1;                      //знак инкримента для автоустаки
-int valve1=0;                   // state valve of  charge:  0 - close, 1 - open
-int valve2=0;                   //state valve of  discharge:  0 - close, 1 - open
-
+char comand[maxnstr][maxnsym] = {""};                                           // массив подстрок командной строки
+int nstr = 0;                                                                   // номер подстроки 
+ 
+int pressure = 0;                                                               //давление (аналоговый вход) (резерв)
+int pressure_set = 0;                                                           //уставка давления (резерв)
+int pressure_set_max = 0;                                                       //уставка максимальног давления (резерв)
+int flag_autoset = 0;                                                           //отладочный флаг. При 0 - запрет автоуставки давления, при 1 - разрешение
+int flag_plotter = 0;                                                           //отладочный флаг. При 0 - запрет печати в плоттер, при 1 - разрешение
+int value = 1000;                                                               //set begin value "pressure" 
+int value_auto=250 ;                                                            //set begin value auto "pressure"
+int sensor_value =0;                                                            //напряжение с аналогового входа А0 (текущее давление)
+int delta_value = 25;                                                           //set delta pressure
+int counter_cycle1 = 0;
+int counter_cycle2 = 0;
+int sig = 1;                                                                    //знак инкримента для автоустаки
+int valve1 = 0;                                                                 // state valve of  charge:  0 - close, 1 - open
+int valve2 = 0;                                                                 //state valve of  discharge:  0 - close, 1 - open
+ 
 //______________________________________________________________________________
 void onDataReceived();                                                          // callback
 //______________________________________________________________________________
 void read_serial() {
-    char message[maxnstr][maxnsym]={""};                                        //обнуление строк (локального двумерного массива символов фиксированного размера)
-    int zap=0;                                                                  // счетчик запятых                                                
+    int time;
+    timer.reset();
+    char message[maxnstr][maxnsym]={""};                                        //обнуление строк (локального двумерного массива символов фиксированного размера)                                             
     char chr;                                                                   //байтовый символ полученный из порта (или файла)
     nstr=0;                                                                     //обнуление счетчика строк (на самом деле счетчика запятых в сообщении)
 rs1:
     int string_possition=0;                                                     //обнуляем номер символа (в строке) в массиве входящей строки сообщения
-    do{ chr = pc.getc();                                                        //вынимаем символ из буфера последовательного порта
-        if (chr == ',')                                            //запятая в нашей системе сообщений это признак окончания подстроки
-        {zap++;
-         message[nstr][string_possition] ='\0';                    //дополняем подстроку символом окончания строки
-         nstr++;                                                   //стетчик строк увеличиваем на единицу
-         goto rs1; }                                               //выходим в начало цикла для поиска следующей подстроки
-        if (chr == '\n' || chr == '\r'){message[nstr][string_possition] ='\0';break;} //если сообщение кончилось, то вставка окончания строки и выход из цикла  
-        message[nstr][string_possition] = chr;                                        //складываем символы в подстроку
+    do{
+        
+        chr = pc.getc();                                                        //вынимаем символ из буфера последовательного порта
+        if (chr == ',') {                                                       //запятая в нашей системе сообщений это признак окончания подстроки
+          message[nstr][string_possition] ='\0';                                //дополняем подстроку символом окончания строки
+          nstr++;                                                               //стетчик подстрок увеличиваем на единицу
+          if (nstr >= maxnstr) {
+            goto rs2;                                                           //количество подстрок больше maxnstr, игнорируем сообщение и выходим в конец
+          }
+          goto rs1;                                                             //выходим в начало цикла для поиска следующей подстроки
+        }
+        if (chr == '\n' ){
+          message[nstr][string_possition] ='\0';
+          break;                                                                //если сообщение кончилось, то вставка окончания строки и выход из цикла 
+        } 
+        message[nstr][string_possition] = chr;                                  //складываем символы в подстроку
         string_possition++;                                                     //номер позиции символа увеличиваем на единицу
-       }while (1); 
-   // pc.printf("caught message_nstr is : %s\r\n", message[nstr]);                //последняя подстрока пойманного сообщения
-   // pc.printf("****Detect number of _,_ ****=%d\r\n",zap);                                //количество приянтых запятых
-    for (int i=0; i<=nstr; i++) {strcpy(comand[i],message[i]);}                  //копирование строк в глобальный массив , размеры массивов должны совпадать!
-    for (int i=0; i<=nstr; i++) {pc.printf("Caught comand[%d] is : %s\r\n",i,comand[i]);}     //печать подстрок пойманного сообщения
-    value=atoi(comand[1]);                                // перевод из строчного массива (вторая подстрока сообщения) в целое число (уставка давления) 
+        if (string_possition > maxnsym) {
+          goto rs2;                                                             //количество символов больше maxnsym, игнорируем сообщение и выходим в конец
+          }
+        time=timer.read_us();
+        if (time > 100000) {
+          //if(pc.readable()) {                                                 //работает только для одного (первого) принятого символа
+            pc.putc('>');                                                       // overtime detected - callback to terminal
+          //}
+          goto rs2;                                                             //за 100 мс не обнаружен конец сообщения, игнорируем сообщение и выходим в конец 
+        }                                                                       //обычно время не превышает 1540мкс для сообщения $press,1000,25,0,0
+    }while (true);                                                              
+    if (strcmp(message[0],"$press" ) != 0) {                                    //функция возвращает ноль если строки совпадают, т.е. если нулевая строка равна "$"
+      pc.printf("message[0]=%s\r\n",message[0]);                                //печать "неправильной" нулевой строки 
+      goto rs2 ;                                                                //в начале сообщения нет $ поэтому пропускаем обработку и выходим в конец
+    }
+    for (int i=0; i<=nstr; i++) {strcpy(comand[i],message[i]);}                 //копирование строк в глобальный массив , размеры массивов должны совпадать!
+    for (int i=0; i<nstr; i++) {   pc.printf("%s,",comand[i]);}                 //эхо принятого сообщения (начало)
+    pc.printf("%s\r\n",comand[nstr]);                                           //эхо принятого сообщения (конец)
+    pc.printf("sensor_value=%d\r\n",sensor_value);
+ //   for (int i=0; i<=nstr; i++) {
+ //     pc.printf("Caught comand[%d] is : %s\r\n",i,comand[i]);                 //отладочная печать подстрок пойманного сообщения
+ //   } 
+    pc.printf("time=%d\r\n",time);  
+    value=atoi(comand[1]);                                                      // перевод из строчного массива в целое число (уставка давления) 
     pc.printf("value=%d\r\n",value);
-    delta_value=atoi(comand[2]);                            // перевод из строчного массива (третья подстрока сообщения) в целое число (уставка отклонения давления) 
+    delta_value=atoi(comand[2]);                                                // перевод из строчного массива  в целое число (уставка отклонения давления) 
     pc.printf("delta_value=%d\r\n",delta_value);
-    flag_autoset=atoi(comand[3]);                            // перевод из строчного массива (четвёртая подстрока сообщения) в целое число (флаг автоуставки ) 
+    flag_autoset=atoi(comand[3]);                                               // перевод из строчного массива  в целое число (флаг автоуставки ) 
     pc.printf("flag_autoset=%d\r\n",flag_autoset);
-    
+    flag_plotter=atoi(comand[4]);                                               // перевод из строчного массива  в целое число (флаг плоттера ) 
+    pc.printf("flag_plotter=%d\r\n",flag_plotter);
+rs2:    
     pc.attach(&onDataReceived, Serial::RxIrq);                                  // reattach interrupt - переподключение прерывания перед выходом из функции
 }
 //______________________________________________________________________________
 void onDataReceived() {
-    pc.attach(NULL, Serial::RxIrq);                                             // detach interrupt
-    queue->call(read_serial);                                                   // process in a non ISR context - переход к функции приема строки в статусе отключенного прерывания (учим указатели!)
+    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.attach(&onDataReceived, Serial::RxIrq);                                  //подключение прерывания и имя функции обработчика прерывания по входящему символу в serial порту
-    float raw_value ;
-    int sensor_value ;
-    printf("Start \r\n");
- while (1)                         //бесконечный цикл
- {
+int main() {
+  pc.attach(&onDataReceived, Serial::RxIrq);                                    //подключение прерывания и имя функции обработчика прерывания по входящему символу в serial
+  
+  timer.start();
+  float raw_value_sum = 0 ;
+  printf ("Start \r\n");
+  while (true){                                                                 //бесконечный цикл        
+    float  raw_value = analog_value.read();                                     // Чтение аналогового входа (0.0 to 1.0 = full ADC диапазон)
+    raw_value_sum = raw_value_sum + raw_value;
        
-  /*--------------regulator begin---*/
-  raw_value  = analog_value.read();                                           // Чтение аналогового входа (0.0 to 1.0 = full ADC диапазон)
-  sensor_value  = raw_value  * 3300;                                          // преобразование в напряжение 0-3300 mV 
-  if (sensor_value>value+delta_value)
-  {
-   digitalWrite7=1; valve2=1;
-   digitalWrite4=0; valve1=0;
-  } else  if (sensor_value<value-delta_value)
-  {
-   digitalWrite4=1; valve1=1;
-   digitalWrite7=0; valve2=0; 
-  } else 
-  {
-   digitalWrite4=0; valve1=0;
-   digitalWrite7=0; valve2=0; 
+    if (counter_cycle1 > 20 ) {
+      counter_cycle1=0;
+      sensor_value = raw_value_sum/20 * 3300;                                   // преобразование в напряжение 0-3300 mV  с усреднением
+      //  sensor_value = raw_value * 3300;                                      // преобразование в напряжение 0-3300 mV без усреднения
+      raw_value_sum = 0 ;
+      //--------------regulator begin-----------------------
+      if (sensor_value > value + delta_value) {
+        digital_7.write(1);                                                     //valve2 = 1;
+        digital_4.write(0);                                                     //valve1 = 0;
+      } else  if (sensor_value < value - delta_value) {
+        digital_4.write(1);                                                     //valve1 = 1;
+        digital_7.write(0);                                                     //valve2 = 0; 
+      } else {
+        digital_4.write(0);                                                     //valve1 = 0;
+        digital_7.write(0);                                                     //valve2 = 0; 
+      }
+      //--------------regulator end-------------------------
+
+      if (flag_plotter == 1) {
+        plotter.printf("$%d %d %d %d;\r\n", digital_4.read()*100-110,
+        digital_7.read()*100-220, value, sensor_value );                        //печать в плоттер (только для отладки! т.к. влияет на парсинг)   
+      }
+    
+      auto_set();                                                               //Ступенчатое увеличение и уменьшение уставки value (для отладки если flag_autoset =1)
+      led = !led;                                                               //гасим/зажигаем индикаторный светодиод
+    } 
+    ThisThread::sleep_for(1);                                                   // (mc) правильный оператор задержки для mbed5
+    counter_cycle1++;
+    
   }
-  /*--------------regulator end-----*/
-  
-   pc.printf("$%d %d %d %d;\r\n", valve1*100-110, valve2*100-220, value, sensor_value );       
-   
-  //* Ступенчатое увеличение и уменьшение уставки value (для отладки)
-  if (counter_cycle2>=100 && flag_autoset==1) {
-    counter_cycle2=0;
-     if(value>2800 || value<250){
-      sig=-sig;                           //меняем знак для изменения направления роста/спада автоуставки
-      } 
-       value=value+sig*250;
-     } 
-  //*/    
-    ThisThread::sleep_for(20);                                             // (mc) правильный оператор задержки для mbed5
-    led = !led;                          //гасим/зажигаем индикаторный светодиод
-    counter_cycle1=0;
-    counter_cycle2++;                    //увеличиваем счетчик на 1
- }
 }
\ No newline at end of file