On the i2c bus, Arduino Nano with address 2, transmits the weight value with a resolution of 1 kg.

Dependencies:   _24LCXXX

Committer:
Aleksk
Date:
Fri May 08 12:05:29 2020 +0000
Revision:
1:1d4ec28f17c4
Parent:
0:f2aaa8c6decf
Child:
2:8230a5a4cc13
The microcontroller program has been changed so that when restarting or turning on the power, all valves are closed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Aleksk 0:f2aaa8c6decf 1 #include "mbed.h"
Aleksk 0:f2aaa8c6decf 2
Aleksk 0:f2aaa8c6decf 3 AnalogIn analog_value(A0); //подключение аналогового входа A0
Aleksk 0:f2aaa8c6decf 4 DigitalOut led(LED1);
Aleksk 0:f2aaa8c6decf 5 DigitalOut digital_4(PB_5); //initialize digital pin 4 as an output (high pressure air bulb charge).
Aleksk 0:f2aaa8c6decf 6 DigitalOut digital_7(PA_8); //initialize digital pin 7 as an output. (high pressure air bulb discharge
Aleksk 0:f2aaa8c6decf 7 RawSerial pc(USBTX, USBRX, 115200); // tx, rx for F411RE in port command string
Aleksk 0:f2aaa8c6decf 8 RawSerial plotter(PA_9, PA_10, 115200); // tx, rx for F411RE out port for serial_plotter
Aleksk 0:f2aaa8c6decf 9 EventQueue *queue = mbed_event_queue(); //инициализация очереди событий RTOS mbed5
Aleksk 0:f2aaa8c6decf 10 Timer timer; //инициализация таймера
Aleksk 0:f2aaa8c6decf 11
Aleksk 0:f2aaa8c6decf 12 int flag_autoset = 0; //отладочный флаг. При 0 - запрет автоуставки давления, при 1 - разрешение
Aleksk 0:f2aaa8c6decf 13 int flag_plotter = 0; //отладочный флаг. При 0 - запрет печати в плоттер, при 1 - разрешение
Aleksk 0:f2aaa8c6decf 14 int value = 0; //set begin value "pressure"
Aleksk 0:f2aaa8c6decf 15 int delta_value = 0; //set delta pressure
Aleksk 0:f2aaa8c6decf 16 int value_auto=250 ; //set begin value auto "pressure"
Aleksk 0:f2aaa8c6decf 17 int sensor_value =0; //напряжение с аналогового входа А0 (текущее давление)
Aleksk 0:f2aaa8c6decf 18 int counter_cycle1 = 0;
Aleksk 0:f2aaa8c6decf 19 int counter_cycle2 = 0;
Aleksk 0:f2aaa8c6decf 20 int sig = 1; //знак инкримента для автоустаки
Aleksk 0:f2aaa8c6decf 21 // FIFO_buffer must be full (only char and '\0')
Aleksk 0:f2aaa8c6decf 22 //#define maxnsym 24 // maximum nbr of symbols FIFO_buffer (вариант без символов окончания)
Aleksk 0:f2aaa8c6decf 23 #define maxnsym 26 // maximum nbr of symbols FIFO_buffer +CR+LF (символы окончания должны быть включены на передаче)
Aleksk 0:f2aaa8c6decf 24 char Source[maxnsym]="$press,1000,25,0,0,2050**"; //23 char- string ,весь массив со строкой для поиска 23+1(null terminal)=24
Aleksk 0:f2aaa8c6decf 25 //уставки и контрольная сумма умноженная на два, должны быть больше нуля
Aleksk 0:f2aaa8c6decf 26 char trueSource[maxnsym]; //верифицированная строка для callback
Aleksk 0:f2aaa8c6decf 27
Aleksk 0:f2aaa8c6decf 28 volatile char chr_a; //в прерываниях переменные должны быть защищены при помощи volatile от оптимизации компилятором
Aleksk 0:f2aaa8c6decf 29 volatile bool flag_comand_detected = false; //если строка декодирована правильно то true
Aleksk 1:1d4ec28f17c4 30 volatile bool flag_reset = true; //флаг индикатора перезагрузки
Aleksk 0:f2aaa8c6decf 31 //______________________________________________________________________________
Aleksk 0:f2aaa8c6decf 32 void substring(char *s,char *d,int pos,int len) {
Aleksk 0:f2aaa8c6decf 33 //usage: substring(Source,Destination,pos,len);
Aleksk 0:f2aaa8c6decf 34 char *t;
Aleksk 0:f2aaa8c6decf 35 s=s+(pos-1);
Aleksk 0:f2aaa8c6decf 36 t=s+len;
Aleksk 0:f2aaa8c6decf 37 while (s!=t) {
Aleksk 0:f2aaa8c6decf 38 *d=*s;
Aleksk 0:f2aaa8c6decf 39 s++;
Aleksk 0:f2aaa8c6decf 40 d++;
Aleksk 0:f2aaa8c6decf 41 }
Aleksk 0:f2aaa8c6decf 42 *d='\0';
Aleksk 0:f2aaa8c6decf 43 }
Aleksk 0:f2aaa8c6decf 44 //______________________________________________________________________________
Aleksk 0:f2aaa8c6decf 45 void onDataReceived(); // callback
Aleksk 0:f2aaa8c6decf 46 //______________________________________________________________________________
Aleksk 0:f2aaa8c6decf 47 void read_serial(void) {
Aleksk 0:f2aaa8c6decf 48 char Destination[50];
Aleksk 0:f2aaa8c6decf 49 int pos,len;
Aleksk 0:f2aaa8c6decf 50 int controlSum1, controlSum2;
Aleksk 0:f2aaa8c6decf 51 int value_, delta_value_, flag_autoset_, flag_plotter_;
Aleksk 0:f2aaa8c6decf 52 int ch = '$'; // Код искомого символа
Aleksk 0:f2aaa8c6decf 53 int indexCh; // Char on position
Aleksk 0:f2aaa8c6decf 54 char *ach; // Указатель на искомую переменную в строке, по которой осуществляется поиск.
Aleksk 0:f2aaa8c6decf 55 while(pc.readable()) {
Aleksk 0:f2aaa8c6decf 56 chr_a = pc.getc();
Aleksk 0:f2aaa8c6decf 57 //_____FIFO_buffer_begin_____
Aleksk 0:f2aaa8c6decf 58 for ( int i = 2; i < maxnsym; i++) {
Aleksk 0:f2aaa8c6decf 59 Source[i-2]=Source[i-1];
Aleksk 0:f2aaa8c6decf 60 }
Aleksk 0:f2aaa8c6decf 61 Source[maxnsym-2]=chr_a; //предпоследний элемент
Aleksk 0:f2aaa8c6decf 62 Source[maxnsym-1] ='\0'; //последний элемент массива это нуль-терминал для формирования конца строки в Си
Aleksk 0:f2aaa8c6decf 63 //_____FIFO_buffer_end_______
Aleksk 0:f2aaa8c6decf 64 }
Aleksk 0:f2aaa8c6decf 65 ach=strchr (Source,ch); //поиск первого вхождения символа в строку , ищем указатель символа ‘$’
Aleksk 0:f2aaa8c6decf 66 if (ach==NULL) {
Aleksk 0:f2aaa8c6decf 67 //pc.printf ("Char not finded \r\n"); //Символ $ в строке не найден
Aleksk 0:f2aaa8c6decf 68 goto endParsing; //пропускаем парсинг
Aleksk 0:f2aaa8c6decf 69 }
Aleksk 0:f2aaa8c6decf 70 else {
Aleksk 0:f2aaa8c6decf 71 indexCh = ach-Source+1; //вычитаем указатель из указателя!
Aleksk 0:f2aaa8c6decf 72 //pc.printf ("Char '$' on position %d\r\n",indexCh); //Искомый символ в строке на позиции
Aleksk 0:f2aaa8c6decf 73 }
Aleksk 0:f2aaa8c6decf 74 if (indexCh!=1) { //позиция символа $ не 1
Aleksk 0:f2aaa8c6decf 75 //pc.printf ("$ position not 1 \r\n");
Aleksk 0:f2aaa8c6decf 76 goto endParsing; //пропускаем парсинг
Aleksk 0:f2aaa8c6decf 77 }
Aleksk 0:f2aaa8c6decf 78
Aleksk 0:f2aaa8c6decf 79 pos=1; //начало подстроки $press - на 1 позиции
Aleksk 0:f2aaa8c6decf 80 len=6; //длина подстроки $press равна 6
Aleksk 0:f2aaa8c6decf 81 substring(Source,Destination,pos,len);
Aleksk 0:f2aaa8c6decf 82 //pc.printf("for pos=%d and len=%d resultat is d= %s\r\n", pos, len, Destination);
Aleksk 0:f2aaa8c6decf 83
Aleksk 0:f2aaa8c6decf 84 if (strcmp(Destination,"$press" ) != 0) { //функция возвращает ноль если строки совпадают
Aleksk 0:f2aaa8c6decf 85 //pc.printf("wrong Destination=%s\r\n",Destination); //печать "неправильной" нулевой строки
Aleksk 0:f2aaa8c6decf 86 goto endParsing ; //в начале сообщения нет $press пропускаем парсинг
Aleksk 0:f2aaa8c6decf 87 }
Aleksk 0:f2aaa8c6decf 88 pos=8; //начало подстроки 1000 - на 8 позиции
Aleksk 0:f2aaa8c6decf 89 len=4; //длина подстроки 1000 равна 4
Aleksk 0:f2aaa8c6decf 90 substring(Source,Destination,pos,len);
Aleksk 0:f2aaa8c6decf 91 value_=atoi(Destination);
Aleksk 0:f2aaa8c6decf 92 if (value_==0) {
Aleksk 0:f2aaa8c6decf 93 goto endParsing; //уставка должна быть больше еденицы, пропускаем парсинг
Aleksk 0:f2aaa8c6decf 94 }
Aleksk 0:f2aaa8c6decf 95 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, value_);
Aleksk 0:f2aaa8c6decf 96 pos=13; //начало подстроки 25 - на 13 позиции
Aleksk 0:f2aaa8c6decf 97 len=2; //длина подстроки 25 равна 2
Aleksk 0:f2aaa8c6decf 98 substring(Source,Destination,pos,len);
Aleksk 0:f2aaa8c6decf 99 delta_value_=atoi(Destination);
Aleksk 0:f2aaa8c6decf 100 if (delta_value_==0) {
Aleksk 0:f2aaa8c6decf 101 goto endParsing; //уставка отклонения должна быть больше еденицы, пропускаем парсинг
Aleksk 0:f2aaa8c6decf 102 }
Aleksk 0:f2aaa8c6decf 103 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, delta_value_);
Aleksk 0:f2aaa8c6decf 104 pos=16; //начало подстроки 0 - на 16 позиции
Aleksk 0:f2aaa8c6decf 105 len=1; //длина подстроки 0 равна 1
Aleksk 0:f2aaa8c6decf 106 substring(Source,Destination,pos,len);
Aleksk 0:f2aaa8c6decf 107 flag_autoset_=atoi(Destination);
Aleksk 0:f2aaa8c6decf 108 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, flag_autoset_);
Aleksk 0:f2aaa8c6decf 109 pos=18; //начало подстроки 0 - на 18 позиции
Aleksk 0:f2aaa8c6decf 110 len=1; //длина подстроки 0 равна 1
Aleksk 0:f2aaa8c6decf 111 substring(Source,Destination,pos,len);
Aleksk 0:f2aaa8c6decf 112 flag_plotter_=atoi(Destination);
Aleksk 0:f2aaa8c6decf 113 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, flag_plotter_);
Aleksk 0:f2aaa8c6decf 114 pos=20; //начало подстроки 1025 - на 18 позиции
Aleksk 0:f2aaa8c6decf 115 len=4; //длина подстроки 1025 равна 4
Aleksk 0:f2aaa8c6decf 116 substring(Source,Destination,pos,len);
Aleksk 0:f2aaa8c6decf 117 controlSum1=atoi(Destination);
Aleksk 0:f2aaa8c6decf 118 if (controlSum1==0) {
Aleksk 0:f2aaa8c6decf 119 goto endParsing; //контрольная сумма должна быть больше еденицы, пропускаем парсинг
Aleksk 0:f2aaa8c6decf 120 }
Aleksk 0:f2aaa8c6decf 121 //pc.printf("for pos=%d and len=%d resultat is d= %s atoi=%d\r\n", pos, len, Destination, controlSum1);
Aleksk 0:f2aaa8c6decf 122 controlSum2=(value_+delta_value_+flag_autoset_+flag_plotter_)*2; //удвоение чтобы не было одинаковых чисел в сообщении
Aleksk 0:f2aaa8c6decf 123 //pc.printf("controlSum1=%d controlSum2=%d\r\n", controlSum1, controlSum2);
Aleksk 0:f2aaa8c6decf 124 if (controlSum1!=controlSum2) { //не совпала контрольная сумма
Aleksk 0:f2aaa8c6decf 125 //pc.printf ("controlSum1!=controlSum2 \r\n");
Aleksk 0:f2aaa8c6decf 126 goto endParsing; //пропускаем парсинг
Aleksk 0:f2aaa8c6decf 127 }
Aleksk 0:f2aaa8c6decf 128 //присваиваем проверенные значения глобальным переменным
Aleksk 0:f2aaa8c6decf 129 strcpy(trueSource,Source); //копировать из Source в trueSource
Aleksk 0:f2aaa8c6decf 130 value=value_;
Aleksk 0:f2aaa8c6decf 131 delta_value=delta_value_;
Aleksk 0:f2aaa8c6decf 132 flag_autoset=flag_autoset_;
Aleksk 0:f2aaa8c6decf 133 flag_plotter=flag_plotter_;
Aleksk 0:f2aaa8c6decf 134 flag_comand_detected=true; //если флаг true, то всем переменным присвоены новые значения уставок
Aleksk 0:f2aaa8c6decf 135
Aleksk 0:f2aaa8c6decf 136 endParsing:
Aleksk 0:f2aaa8c6decf 137
Aleksk 0:f2aaa8c6decf 138
Aleksk 0:f2aaa8c6decf 139 pc.attach(&onDataReceived, Serial::RxIrq); // reattach interrupt - переподключение прерывания перед выходом из функции
Aleksk 0:f2aaa8c6decf 140 }
Aleksk 0:f2aaa8c6decf 141 //______________________________________________________________________________
Aleksk 0:f2aaa8c6decf 142 void onDataReceived() {
Aleksk 0:f2aaa8c6decf 143 pc.attach(nullptr, Serial::RxIrq); // detach interrupt
Aleksk 0:f2aaa8c6decf 144 queue->call(read_serial); // process in a non ISR context - переход к функции приема строки -
Aleksk 0:f2aaa8c6decf 145 } // - в статусе отключенного прерывания (учим указатели!)
Aleksk 0:f2aaa8c6decf 146 //______________________________________________________________________________
Aleksk 0:f2aaa8c6decf 147 void auto_set () {
Aleksk 0:f2aaa8c6decf 148 if (counter_cycle2 >= 100 && flag_autoset == 1) {
Aleksk 0:f2aaa8c6decf 149 counter_cycle2=0;
Aleksk 0:f2aaa8c6decf 150 if (value_auto > 2800 || value_auto < 250) {
Aleksk 0:f2aaa8c6decf 151 sig = -sig; //меняем знак для изменения направления роста/спада автоуставки
Aleksk 0:f2aaa8c6decf 152 }
Aleksk 0:f2aaa8c6decf 153 value_auto = value_auto + sig * 250;
Aleksk 0:f2aaa8c6decf 154 value=value_auto;
Aleksk 0:f2aaa8c6decf 155 }
Aleksk 0:f2aaa8c6decf 156 counter_cycle2++; //увеличиваем счетчик функции auto_set() на 1
Aleksk 0:f2aaa8c6decf 157 }
Aleksk 0:f2aaa8c6decf 158 //*****************************************************************************
Aleksk 0:f2aaa8c6decf 159 //*****************************************************************************
Aleksk 0:f2aaa8c6decf 160
Aleksk 0:f2aaa8c6decf 161 int main() {
Aleksk 1:1d4ec28f17c4 162
Aleksk 0:f2aaa8c6decf 163 pc.attach(&onDataReceived, Serial::RxIrq);
Aleksk 0:f2aaa8c6decf 164 int time, valve1, valve2, countValve1=0, countValve2=0;
Aleksk 0:f2aaa8c6decf 165 int frequencyValve1, frequencyValve2;
Aleksk 0:f2aaa8c6decf 166 float raw_value_sum = 0 ;
Aleksk 1:1d4ec28f17c4 167 //после перезагрузки немедленно закрыть оба клапана
Aleksk 1:1d4ec28f17c4 168 digital_4.write(0); //valve1 off;
Aleksk 1:1d4ec28f17c4 169 digital_7.write(0); //valve2 off;
Aleksk 1:1d4ec28f17c4 170
Aleksk 1:1d4ec28f17c4 171 pc.printf("Program started \r\n");
Aleksk 0:f2aaa8c6decf 172 timer.start();
Aleksk 1:1d4ec28f17c4 173
Aleksk 0:f2aaa8c6decf 174 while (true){ //бесконечный цикл
Aleksk 0:f2aaa8c6decf 175
Aleksk 1:1d4ec28f17c4 176 if (flag_comand_detected) { //пришла правильная командная строка
Aleksk 1:1d4ec28f17c4 177 pc.printf("$press,%d,%d,%d,%d,%d,%d,%d,*\r\n",
Aleksk 1:1d4ec28f17c4 178 value,delta_value,flag_autoset,flag_plotter,sensor_value,frequencyValve1,frequencyValve2); //текущие данные
Aleksk 0:f2aaa8c6decf 179 //pc.printf("%s\r\n",trueSource); //эхо для отладки канала связи
Aleksk 0:f2aaa8c6decf 180 flag_comand_detected=false; //в последующих обращениях не печатать пока нет новых уставок из СОМ-порта
Aleksk 1:1d4ec28f17c4 181 flag_reset=false; //сброс флага перезагрузки (после перезагрузки клапана закрыты, регулятор ждет пока не будет сброшен этот флаг)
Aleksk 0:f2aaa8c6decf 182 //plotter.printf("$%d %d %d %d %d;\r\n", digital_4.read()*100-110,
Aleksk 0:f2aaa8c6decf 183 // digital_7.read()*100-220, value, sensor_value, time ); //печать в плоттер в другой СОМ-порт
Aleksk 0:f2aaa8c6decf 184 }
Aleksk 0:f2aaa8c6decf 185 float raw_value = analog_value.read(); // Чтение аналогового входа (0.0 to 1.0 = full ADC диапазон)
Aleksk 0:f2aaa8c6decf 186 raw_value_sum = raw_value_sum + raw_value;
Aleksk 0:f2aaa8c6decf 187
Aleksk 0:f2aaa8c6decf 188 if (counter_cycle1 > 20 ) {
Aleksk 0:f2aaa8c6decf 189 counter_cycle1=0;
Aleksk 0:f2aaa8c6decf 190 sensor_value = raw_value_sum/20 * 3300; // преобразование в напряжение 0-3300 mV с усреднением
Aleksk 0:f2aaa8c6decf 191 raw_value_sum = 0 ;
Aleksk 1:1d4ec28f17c4 192 if (flag_reset == false) { //после перезагрузки уставки получены, можно запускать регулятор
Aleksk 1:1d4ec28f17c4 193 //--------------regulator begin-----------------------
Aleksk 1:1d4ec28f17c4 194 if (sensor_value > value + delta_value) {
Aleksk 1:1d4ec28f17c4 195 valve2 = digital_7.read();
Aleksk 1:1d4ec28f17c4 196 digital_7.write(1); //valve2 on;
Aleksk 1:1d4ec28f17c4 197 if (valve2 < digital_7.read()) {countValve2++;} //счётчик передних фронтов напряжения (срабатывания клапана 2)
Aleksk 1:1d4ec28f17c4 198 digital_4.write(0); //valve1 off;
Aleksk 1:1d4ec28f17c4 199 } else if (sensor_value < value - delta_value) {
Aleksk 1:1d4ec28f17c4 200 valve1 = digital_4.read();
Aleksk 1:1d4ec28f17c4 201 digital_4.write(1); //valve1 on;
Aleksk 1:1d4ec28f17c4 202 if (valve1 < digital_4.read()) {countValve1++;} //счётчик передних фронтов напряжения (срабатывания клапана 1)
Aleksk 1:1d4ec28f17c4 203 digital_7.write(0); //valve2 off;
Aleksk 1:1d4ec28f17c4 204 } else {
Aleksk 1:1d4ec28f17c4 205 digital_4.write(0); //valve1 off;
Aleksk 1:1d4ec28f17c4 206 digital_7.write(0); //valve2 off;
Aleksk 1:1d4ec28f17c4 207 }
Aleksk 1:1d4ec28f17c4 208 //--------------regulator end-------------------------
Aleksk 0:f2aaa8c6decf 209 }
Aleksk 0:f2aaa8c6decf 210 time=timer.read_us();
Aleksk 0:f2aaa8c6decf 211 if (time > 1000000) {
Aleksk 0:f2aaa8c6decf 212 timer.reset(); //начало счёта времени
Aleksk 0:f2aaa8c6decf 213 frequencyValve1 = countValve1; //частота (Гц) срабатывания клапана 1
Aleksk 0:f2aaa8c6decf 214 frequencyValve2 = countValve2; //частота (Гц) срабатывания клапана 2
Aleksk 0:f2aaa8c6decf 215 countValve1=0;
Aleksk 0:f2aaa8c6decf 216 countValve2=0;
Aleksk 0:f2aaa8c6decf 217 }
Aleksk 0:f2aaa8c6decf 218
Aleksk 0:f2aaa8c6decf 219 if (flag_plotter == 1) {
Aleksk 0:f2aaa8c6decf 220 plotter.printf("$%d %d %d %d %d %d;\r\n", digital_4.read()*100-110,
Aleksk 0:f2aaa8c6decf 221 digital_7.read()*100-220, value, sensor_value, 100*frequencyValve1, 100*frequencyValve2 ); //печать в плоттер в другой СОМ-порт (только для отладки)
Aleksk 0:f2aaa8c6decf 222 }
Aleksk 0:f2aaa8c6decf 223
Aleksk 0:f2aaa8c6decf 224 auto_set(); //Ступенчатое увеличение и уменьшение уставки value (для отладки если flag_autoset =1)
Aleksk 0:f2aaa8c6decf 225 led = !led; //гасим/зажигаем индикаторный светодиод
Aleksk 0:f2aaa8c6decf 226 }
Aleksk 0:f2aaa8c6decf 227 ThisThread::sleep_for(1); // (mc) правильный оператор задержки для mbed5
Aleksk 0:f2aaa8c6decf 228 counter_cycle1++;
Aleksk 0:f2aaa8c6decf 229
Aleksk 0:f2aaa8c6decf 230 }
Aleksk 0:f2aaa8c6decf 231 }