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
- Committer:
- Aleksk
- Date:
- 2020-05-08
- Revision:
- 1:1d4ec28f17c4
- Parent:
- 0:f2aaa8c6decf
- Child:
- 2:8230a5a4cc13
File content as of revision 1:1d4ec28f17c4:
#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
volatile bool flag_reset = 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.attach(&onDataReceived, Serial::RxIrq);
int time, valve1, valve2, countValve1=0, countValve2=0;
int frequencyValve1, frequencyValve2;
float raw_value_sum = 0 ;
//после перезагрузки немедленно закрыть оба клапана
digital_4.write(0); //valve1 off;
digital_7.write(0); //valve2 off;
pc.printf("Program started \r\n");
timer.start();
while (true){ //бесконечный цикл
if (flag_comand_detected) { //пришла правильная командная строка
pc.printf("$press,%d,%d,%d,%d,%d,%d,%d,*\r\n",
value,delta_value,flag_autoset,flag_plotter,sensor_value,frequencyValve1,frequencyValve2); //текущие данные
//pc.printf("%s\r\n",trueSource); //эхо для отладки канала связи
flag_comand_detected=false; //в последующих обращениях не печатать пока нет новых уставок из СОМ-порта
flag_reset=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 ;
if (flag_reset == false) { //после перезагрузки уставки получены, можно запускать регулятор
//--------------regulator begin-----------------------
if (sensor_value > 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 (sensor_value < 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;
}
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++;
}
}