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

Dependencies:   _24LCXXX

main.cpp

Committer:
Aleksk
Date:
2020-05-01
Revision:
0:f2aaa8c6decf
Child:
1:1d4ec28f17c4

File content as of revision 0:f2aaa8c6decf:

#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++;
    
  }
}