test

Dependencies:   ad5422_arduino mbed LT1446 ADS1248-1 LM35-1 Flash FT813 PGA280_ADS1259

Revision:
3:d4b106bf3a32
Parent:
2:04090a362742
Child:
4:d53895f65eb7
--- a/main.cpp	Mon Jun 22 10:33:10 2020 +0000
+++ b/main.cpp	Sat Aug 08 18:32:53 2020 +0000
@@ -6,39 +6,61 @@
 #include "ad5422_arduino.h"
 #include "lm35.h"
 #include "LT1446.h"
+#include "ads1248.h"
+#include "flashwrapper.h"
+#include <cmath>
+#include "FT_Platform.h"
+#include "display.h"
 
-#define PID_SAMPLE_TIME 0.25    //Период ПИД
-#define Kp (E_PCOEFF)   //Получение коэффициентов ПИД
-#define Ki (E_PCOEFF / E_ICOEFF * PID_SAMPLE_TIME)
-#define Kd (E_PCOEFF * E_DCOEFF / PID_SAMPLE_TIME)
+//коэффициенты по умолчанию температура колонки
+#define E_PCOEFF    0.5F    //Пропорциональный коэффициент ПИД регулятора (Из EEPROM)
+#define E_ICOEFF    1500.0F //Постоянная времени интегрирования ПИД регулятора в секундах (Из EEPROM) (был 3000)
+#define E_DCOEFF    0.1F
+#define PID_SAMPLE_TIME 0.25F    //Период ПИД
+// --//-- расхода
+#define R_PCOEFF    0.11F    //Пропорциональный коэффициент ПИД регулятора (Из EEPROM)
+#define R_ICOEFF    3000.0F //Постоянная времени интегрирования ПИД регулятора в секундах (Из EEPROM) (был 3000)
+#define R_DCOEFF    0.1F
+#define R_PID_SAMPLE_TIME 0.25F
 
-#define E_PCOEFF    0.11F    //Пропорциональный коэффициент ПИД регулятора (Из EEPROM)
-#define E_ICOEFF    3000.0F //Постоянная времени интегрирования ПИД регулятора в секундах (Из EEPROM) (был 3000)
-#define E_DCOEFF    0.1F
+#define CHKD (0x43484B44) //константа для проверки записанных данных (необходима контрольная сумма)
 #define TEMP 35
 
 
 /*Таймер для вызова функции каждые 40 мс*/
 Ticker lm_temp;
 Ticker adctask;
-Ticker PID1;
+Ticker PID1; //ПИД для нагрева колонки
+Ticker PID2; //ПИД для расхода
 /*Конец*/
-InterruptIn button(USER_BUTTON);
+//InterruptIn button(USER_BUTTON);
+InterruptIn ADSRdy(PG_3);
 
-volatile float Error = 0, dError = 0, last_Error = 0;    //Ошибка и предыдущее значение для ПИД
-volatile float Integral = 0.0;    //Интегральная составляющая ПИД-регулятора
-volatile uint8_t temp=0;
+//настройка SPI для дисплея (надо поменять чтобы избежать конфликта с внешними платами)
+FT813 TFT (D11, D12, D13, D10, D9, D8); // mosi, miso, sck, ss, int, pd
+Display disp(&TFT);
+//конец
+
+ADS1248_t ads1;//экземпляр ЦАП 1446 в памяти
+LM35_t RAS;
+PID_prom_t TempCol;
+PID_prom_t Rashod;
+PID_defs_t PID_defs={E_PCOEFF,E_ICOEFF,E_DCOEFF,PID_SAMPLE_TIME};
+PID_defs_t PID_R_defs={R_PCOEFF,R_ICOEFF,R_DCOEFF,R_PID_SAMPLE_TIME};
+volatile uint8_t temp=0;// уставка температуры колонки
+volatile float rashod_u=0; //уставка расхода
 char mbflag;
 unsigned char pga280gain;
 char UComandFlag;
 volatile unsigned char UComand;
 volatile long tempdata=0;
-char ch=0;                          //адрес на плате ТЭД-2 = 6
+char ch=0;              //адрес на плате ТЭД-2 = 6
 float x=0;
 float k;
 unsigned char str[];
 
-
+//указатель для подстановки нужной функции
+void (*printer_p)(void);
 
 //функция чтения АДС для выполнения в задаче
 void readADC()
@@ -52,32 +74,89 @@
 {    
     float t;
     /*Обработка ошибки*/
-    LM35_start(0.25);
+    //LM35_start(0.25);
+     if(ads1.MUX0.MUX_SP!=0)
+    {
+                 DS1248_START=1;
+                 ADS1248WakeupCommand();
+                 ads1.MUX0.MUX_SN=1; //AIN1
+                 ads1.MUX0.MUX_SP=0; //AIN0
+                 ads1.VBIAS.all=0;
+                 ADS1248SettingReg(&ads1);
+        }
+    
     if (LM35_0.ready) //если данные готовы то считать и сбросить флаг (способ многозадачности)
     {
         LM35_0.ready=0;
-        t=LM35_0.temp;    
-        Error=temp-t;  
-        Integral += Error;
-        dError = Error - last_Error;
-        last_Error = Error;    
+        t=LM35_0.temp;
+        TempCol.Error=temp-t;
+        TempCol.Integral += TempCol.Error;
+        TempCol.dError = TempCol.Error - TempCol.last_Error;
+        TempCol.last_Error = TempCol.Error;
         //временно записать в калиброванное значение (нельзя так делать)
-        LT1446_0.dacA.Code=(uint16_t)(PID() * 4095);
-        LT1446_Write(&LT1446_0);
-        UART.printf("Power %04d temp %0.1f\r\n",LT1446_0.dacA.Code,t);
+        LT1446_0.dacB.Code=(uint16_t)(PID(&Mem.PID,&TempCol) * 4095);
+        LTCwrite(&LT1446_0);        
     }
     
 }
-void printtemp()
+
+void readRashod()
 {
-    if (LM35_0.ready) //если данные готовы то считать и сбросить флаг (способ многозадачности)
+    float r;
+    //Если не настроен, то настраиваем нужный канал чтения
+    if(ads1.MUX0.MUX_SP!=2)
     {
-    UART.printf("TempCol %0.1f\r\n",LM35_0.temp);
-    LM35_0.ready=0;
+                 DS1248_START=1;
+                 ADS1248WakeupCommand();
+                 ads1.MUX0.MUX_SN=3; //AIN3
+                 ads1.MUX0.MUX_SP=2; //AIN2
+                 ads1.VBIAS.VBIAS3=1;
+                 ADS1248SettingReg(&ads1);
+        }
+    //используем тот же тип из-за схожести
+    if(RAS.ready)//Если данные готовы для считывания..
+    {RAS.ready=0;
+        r=RAS.temp; 
+        Rashod.Error=rashod_u-r;
+        Rashod.Integral += Rashod.Error;//
+        Rashod.dError = Rashod.Error - Rashod.last_Error;
+        Rashod.last_Error = Rashod.Error;
+        LT1446_0.dacA.Code=(uint16_t)(PID(&Mem.PID_R,&Rashod) * 4095);
+        LTCwrite(&LT1446_0);        
+    //Pressure.write(PID(&Mem.PID_R,&Rashod));
+    }
+}
+
+void printtemp()
+//отобразить температуру 1 раз
+{
+    if (LM35_0.ready||RAS.ready) //если данные готовы то считать
+    {
+    UART.printf("TempCol %0.2f\t|\tRashod %0.4f ml (%0.4fV)\r\n",LM35_0.temp,RAS.temp,RAS.volts);
     }
     
     }
 
+void printPID()
+{
+    /*функция отобображает в терминале значения не в момент расчёта ПИДа,
+    но этого по идее достаточно для оценки результата работы, 
+    так как отображаются последние записанные в переменную данные*/
+    if ((Mem.PID.enabled==1)&&(Mem.PID_R.enabled==0)) //Если включен только первый ПИД
+    {
+        UART.printf("PID_t: Power %04d temp %0.2f\r\n",LT1446_0.dacB.Code,LM35_0.temp);
+        }
+    else if ((Mem.PID_R.enabled==1)&&(Mem.PID.enabled==0)) //Если включен только второй ПИД
+    {
+    UART.printf("PID_R: Power %04d rashod %0.4f ml (%0.4fV)\r\n",LT1446_0.dacA.Code,RAS.temp,RAS.volts);    
+        }
+    else if ((Mem.PID_R.enabled==1)&&(Mem.PID.enabled==1)) //Если включены оба ПИД    
+        {
+    UART.printf("PID_t: Power %04d temp %0.2f | ",LT1446_0.dacB.Code,LM35_0.temp);
+    UART.printf("PID_R: Power %04d rashod %0.4f ml (%0.4fV)\r\n",LT1446_0.dacA.Code,RAS.temp,RAS.volts);    
+            }    
+}
+
 float inline NormADC(long data)
 {
     x=data*2.5/0x800000;
@@ -85,6 +164,295 @@
     return x;
 }
 
+
+ /*Собственно сам расчёт ПИД. В аргумент подставляется
+ конкретный ПИД (температура или расход) и его промежуточные значения (вклады)*/
+ float PID (PID_t *pidx, PID_prom_t *prom)
+    {         
+    float P = pidx->kP * prom->Error;
+    float I = pidx->kP / pidx->kI * pidx->sampleTime * prom->Integral;
+    float D = pidx->kP * pidx->kD / pidx->sampleTime * prom->dError;
+    float control = P + I + D;
+    if (control > 1.0) return 1.0;
+    if (control < 0.0) return 0.0;
+    return control;
+    }
+
+//включить пид1
+void pressed()
+{
+    /*Включить АЦП*/
+    DS1248_START=1;
+    ADS1248WakeupCommand();
+    /*Выключить постоянное оторажение температуры*/
+    
+    //запустить ПИД
+    PID1.attach(&readtemp,0.25);
+    Mem.PID.enabled=1;
+    UART.printf("PID is ON\r\n");
+}
+
+//включить пид2
+void pid2_start()
+{
+    DS1248_START=1;
+    ADS1248WakeupCommand();    
+    PID2.attach(&readRashod,0.25);
+    Mem.PID_R.enabled=1;
+    UART.printf("PID_R is ON\r\n");
+}
+
+void readads()
+/*чтение АЦП в режиме
+-только первый канал
+-только второй канал
+-оба канала
+или как вариант: позиция бита означает какие каналы считываются если их больше чем 2*/
+{    
+    double v=0;
+    v=2.048*ADS1248ReadData(&ads1)/0x800000;    
+    if(ads1.MUX0.MUX_SP==0)
+    {    
+    LM35_0.temp=v*100;    
+    LM35_0.ready=1;
+    }
+    if (ads1.MUX0.MUX_SP==2)
+    {
+        RAS.volts=v;
+        RAS.temp=v*26.316-0.263;// мл/мин (сделать уставку)
+        RAS.ready=1;
+        }
+    
+    }
+    
+void Mem_write()
+{
+    flashWrite(0,Mem.w,(sizeof(Mem.w)/sizeof(uint32_t)));
+}
+
+float BufToFloat(unsigned char *buf)
+/*Преобразование строки из 16 символов в float*/
+{
+    uint8_t i=0;
+    uint8_t j=1; //счётчик символов до точки
+    uint8_t p=0; //позиция точки
+    float result=1;  //временно используем чтобы определить знак числа
+    i=3; //команда выглядит как "v0=-123.456" поэтому считаем с символа - позиция которого 3
+            
+    
+    if(buf[i]=='-'){
+        result=-result;
+        i++;
+    }    
+    //до тех пор, пока поступают нужные символы и нет превышения длины строки
+    while((i<16)&&(buf[i]>=0x30)&&(buf[i]<=0x39)||((buf[i]=='.')||(buf[i]==',')))
+        {                
+        i++;        
+        //проверять на наличие точки или запятой
+            if((buf[i]=='.')||(buf[i]==',')) 
+            {
+                p=i; //запоминаем позицию плавающей запятой
+                if (result>=0)
+                j=i-3; //цифр до точки
+                else j=i-4;                
+            }             
+        }
+    
+    //ниже преобразуем информацию в число
+    if (result>=0){        
+        result=0;
+        i=i-j-4; //знаки после запятой         
+        while(i--){
+            result+=(buf[p+i+1]-0x30)*powf(10,-i-1);
+        }
+        while(j--){            
+        result+=(buf[p-j-1]-0x30)*powf(10,j);        
+        }
+    }            
+    else {
+        result=0;
+        i=i-j-5; //знаки после запятой         
+        while(i--){
+            result+=(buf[p+i+1]-0x30)*powf(10,-i-1);
+        }
+        while(j--){            
+        result+=(buf[p-j-1]-0x30)*powf(10,j);        
+        }
+        result=-result;
+    }
+    if (result>=0&&result<=10000)
+    return result;
+    else return 0;
+       
+}    
+void setPIDdefault(PID_t *pidx,PID_defs_t *defs)
+/*Установка для нужного пида его настроек по умолчанию*/
+{
+        pidx->kP=defs->kp;
+        pidx->kI=defs->ki;
+        pidx->kD=defs->kd;
+        pidx->sampleTime=defs->st;
+        pidx->chkd=CHKD;
+    }
+  
+int main()
+{     
+    printf("started\r\n");
+    //считывание данных настроек из памяти
+    for (int i=0;i<sizeof(Mem.w)/sizeof(uint32_t);i++)
+    {    
+    Mem.w[i]=flashRead(i*4);//sizeof(uint32_t)=4;
+    }
+    if ((Mem.PID.chkd!=CHKD)||(Mem.PID_R.chkd!=CHKD))
+    {
+    //если метки данных нет то записать настройки ПИД по умолчанию
+    UART.printf("PID is default\r\n");
+        setPIDdefault(&Mem.PID,&PID_defs);
+        setPIDdefault(&Mem.PID_R,&PID_R_defs);
+        Mem_write();
+        }
+    UART.printf("PID:\r\nKp=%0.3f\r\nkI=%0.3f\r\nkD=%0.3f\r\n",Mem.PID.kP,Mem.PID.kI,Mem.PID.kD);
+    UART.printf("PID_R:\r\nKp=%0.3f\r\nkI=%0.3f\r\nkD=%0.3f\r\n",Mem.PID_R.kP,Mem.PID_R.kI,Mem.PID_R.kD);
+    UART.printf("%08X\r\n",Mem.PID.chkd);
+    
+    //Инициализация периферийных устройств
+    SPI1_MasterInitMode(1);//работают режимы 1 и 2 для платы ТЭД2
+     //SPI3_MasterInitMode(1);
+   //запустить задачу проверки команды по прерыванию УАРТ
+    UART.attach(&ComandCheck,Serial::RxIrq);
+    /*EN1=1;
+    
+     ch=5;
+    pga280_setAdress(ch);    
+    pga280_ads1259_init(ch); //инициализировать АЦП по адресу на плате ТЭД-2 = 5 (4)
+    printf("\r\n");
+    tempdata=pga280_readOneRegisterDevice(PGA280_BUF_TIMEOUT_ADR,ch);
+    printf("Timeout %X\n",tempdata);
+    wait_ms(20);
+    pga280_setGAIN(GAIN_1_PGA280,ch);
+    pga280_setMUX(2,ch);
+    pga280gain=3; //   gain=1 (0x03)
+    tempdata=pga280_readOneRegisterDevice(PGA280_ERROR_ADR,ch);//чтение ошибок
+    printf("Errors %X\n",tempdata);
+    /*Конец*/
+    
+
+    
+    
+    /*Инициализация внешнего АПЦ для LM35*/
+    //создадим экземпляр АЦП если их несколько
+    UART.printf("Configuring ADC\r\n");
+    DS1248_START=0;
+    wait_ms(20);
+    DS1248_START=1;
+    wait_ms(20);
+    /*Настройка регистров в ОЗУ (описание в заголовочном файле)*/
+    ads1.MUX0.MUX_SN=1; //AIN1
+    ads1.MUX0.MUX_SP=0; //AIN0
+    ads1.MUX0.BCS=0;
+    
+    ads1.VBIAS.all=0;
+    ads1.VBIAS.VBIAS0=0;
+    
+    ads1.SYS0.DR=DR20;
+    ads1.SYS0.PGA=PGA_1; //=log2(PGA) пример: PGA=16 значит значение будет log2(16)=4;
+    
+    ads1.MUX1.MUXCAL=0;
+    ads1.MUX1.REFSELT=2;
+    ads1.MUX1.VREFCON=1;
+    
+    ads1.IDAC0.all=0;
+        
+    ads1.IDAC1.all=0xFF;
+    
+    ads1.FSC.all=1*(0x400000); //масштаб АЦП (наверное не коэффициент усиления)
+    /*Конец*/
+     //Записать в чип
+    ADS1248SettingReg(&ads1);
+    if(ads1.SYS0.all==ADS1248ReadRegister(DS1248_REGISTER_SYS0,1))  //30.07.2020/8:40
+    UART.printf("ADS is configured \r\nMUX1 =%d\r\n",ADS1248ReadRegister(DS1248_REGISTER_SYS0,1));
+    ADSRdy.fall(&readads);//виснет без платы (решение - закомментить)
+    wait_ms(20);
+    //ADS1248SleepCommand();//временно отключаем чтобы при старте не началось считывание
+    DS1248_START=0;
+    
+    /*Инициализация внещнего ЦАП*/
+    LT1446_0.dacA.Code=0;
+    LT1446_0.dacA.Code=0;
+    LTCwrite(&LT1446_0);
+    UART.printf("DAC is configured\r\n");
+    
+    //обнуление режима работы ПИД
+    Mem.PID.enabled=0;
+    Mem.PID_R.enabled=0;
+    /*Тестовая кнопка для включения PID*/
+    //button.fall(&pressed);
+    //Калибрануть если есть дисплей
+    if(TFT.IsOn()){
+    UART.printf("Process of calibration\r\n");
+    disp.Calibration(Mem.calibration,0);    
+    Mem_write();
+    UART.printf("Calibrated\r\n");}    
+    disp.activeScreen = TEST_CHROM_SCREEN;
+    disp.pressedButton = NONE_PRESS;
+    
+    // change active screen depending on pressed area
+    while(1) {
+        
+        if(TFT.IsOn())
+        //проверка включения дисплея
+        {
+        disp.pressedButton = disp.GetTouch();
+        //-------------------------------ChromTestScreen------------------------
+        if (disp.activeScreen == TEST_CHROM_SCREEN) {
+            disp.ChromTest(LM35_0.temp,RAS.temp,temp,rashod_u);
+            if(disp.pressedButton){
+                wait_ms(100);
+                if(disp.pressedButton==CHROM_TEMP_PRESS){
+                     disp.pressedButton = NONE_PRESS;
+                    disp.activeScreen=MENU_SCREEN;
+                    }
+                }
+            }
+        // ---------------------------------------------------------------------
+        // Main menu screen
+        if (disp.activeScreen == MENU_SCREEN) {
+            disp.MainMenu(LM35_0.temp, LM35_0.temp);//сюда писать значения (наверное) (расход/температура)
+            if (disp.pressedButton) {
+                wait_ms(150);
+                if (disp.pressedButton == CURR_TEMP_PRESS) {
+                    disp.activeScreen = CURR_TEMP_SCREEN;
+                } else if (disp.pressedButton == CURR_HUM_PRESS) {
+                    disp.activeScreen = CURR_HUM_SCREEN;
+                } 
+                disp.pressedButton = NONE_PRESS;
+            }
+ 
+        // ---------------------------------------------------------------------
+        // Any other screen
+        } else {
+            // ----------------------------------------------------------------------------------------------
+            // You can back to main menu from any screen
+            if (disp.pressedButton == MENU_PRESS) {
+                disp.pressedButton = NONE_PRESS;
+                disp.activeScreen = MENU_SCREEN;
+            } else {
+                // ----------------------------------------------------------------------------------------------
+                // Screen with current temperature / humidity
+                if (disp.activeScreen == CURR_TEMP_SCREEN) {
+                    disp.CurrentTemperature(LM35_0.temp);//и сюда тоже
+                } else if (disp.activeScreen == CURR_HUM_SCREEN) {
+                    disp.CurrentHumidity(LM35_0.temp);//и сюда
+                } 
+            }
+        }
+   }//Проверка включения дисплея
+    }
+}
+
+
+
+/*команды*/
 void ComandCheck()
 {    
     if(UART.getc()=='/')              
@@ -92,43 +460,229 @@
         UART_gets(16); //моя функция на время
         UART.printf("%c\r\n",str[0]);
         switch (str[0]){
-             case 'k':{
-                 PID1.detach();
-                 temp=(str[1]-'0')*10+(str[2]-'0');                 
-                 UART.printf("temp= %d\r\n",temp);
+             /*Проверка платы SB-1 SWEN*/
+             case 'i':{
+                 if (str[1]=='1')
+                 {SB1_SWEN=1;
+                 UART.printf("SW is ON\r\n");}
+                 else if (str[1]=='0')
+                 {SB1_SWEN=0;
+                 UART.printf("SW is OFF\r\n");}
+                 else if (str[1]=='a')
+                 {
+                     PosAw=1;
+                     PosBw=0;
+                     wait_ms(50);
+                     PosAw=0;
+                     PosBw=0;
+                     }
+                 else if (str[1]=='b')
+                 {
+                     PosAw=0;
+                     PosBw=1;
+                     wait_ms(50);
+                     PosAw=0;
+                     PosBw=0;
+                     }
+                 else if (str[1]=='r')
+                 {
+                     char a='0';
+                     if (PosAr)
+                     a='a';
+                     else if (PosBr)
+                     a='b';                    
+                     UART.printf("POS is %c",a);
+                     }
                  break;}
+             case 'k':{//настройки ПИДа температуры колонки
+                 PID1.detach();
+                 LT1446_0.dacB.Code=0;
+                 LT1446_0.dacA.Code=0;                 
+                 LTCwrite(&LT1446_0);
+                 switch (str[1]){
+                 case 'P':{
+                 Mem.PID.kP=BufToFloat(str);
+                 Mem_write();
+                 UART.printf("P=%f\r\n",Mem.PID.kP);
+                 break;
+                 }
+                 case 'I':{
+                 Mem.PID.kI=BufToFloat(str);
+                 Mem_write();
+                 UART.printf("I=%f\r\n",Mem.PID.kI);
+                 break;
+                 }
+                 case 'D':{
+                 Mem.PID.kD=BufToFloat(str);
+                 Mem_write();
+                 UART.printf("D=%f\r\n",Mem.PID.kD);
+                 break;
+                 }
+                 case 'f':{
+                     setPIDdefault(&Mem.PID,&PID_defs);
+                     Mem_write();
+                     UART.printf("PID is default\r\n");
+                     break;}
+                 default:break;
+                 }
+                 //задание уставки температуры
+                 if ((str[1]>='0')&&(str[1]<='9')){
+                 temp=(str[1]-'0')*10+(str[2]-'0');                 
+                 UART.printf("temp= %d\r\n",temp); }                    
+                 break;}
+                 
              case 't':{
+                 //начать чтение температуры
+                 //отключаем отображение для перенастройки, настраиваем, записываем, включаем обратно отображение с новым параметром
+                 lm_temp.detach();      
+                 DS1248_START=1;
+                 ADS1248WakeupCommand();
+                 ads1.MUX0.MUX_SN=1; //AIN1
+                 ads1.MUX0.MUX_SP=0; //AIN0
+                 ads1.VBIAS.all=0;
+                 ADS1248SettingReg(&ads1);
+                 UART.printf("Temperature reading started.\r\n");
                  //снять показания термодатчика
-                 LM35_start(0.25);
-                 lm_temp.attach(&printtemp,0.25);
+                 //LM35_start(0.25);
+                 printer_p=&printtemp;
+                 lm_temp.attach(printer_p,0.1);
                  break;}
+                 
              case 'p':{                
                 pga280gain=str[1]; //присваиваем числовое значение команды взятое из символа цифры
                 pga280gain-=0x30;
                 ch=5;
                 pga280_setGAIN(pga280gain,ch);
                 ch=0;               
-                break;}            
-            case 'g': {               
-                //запустить задачу чтения АЦП каждые 40 мс (25 герц)
-                adctask.attach(&readADC,0.04);               
                 break;}
-            case's':    {//остановить постоянное отображение
-                adctask.detach();
+                
+            case 'g': {      //включить нужный ПИД         
+                if(str[1]=='p')
+                {
+                    switch(str[2])
+                    {//gp1
+                    case '1'://первый - температура
+                    {
+                        lm_temp.detach();
+                        pressed();
+                        printer_p=&printPID;
+                        lm_temp.attach(printer_p,0.25);
+                        break;}
+                    case '2'://второй - расход
+                    {//gp2
+                        lm_temp.detach();
+                        pid2_start();
+                        printer_p=&printPID;
+                        lm_temp.attach(printer_p,0.25);
+                        break;}
+                    
+                    //остановить работу ПИД регуляторов.
+                    case 's'://  /gps
+                    {
+                        lm_temp.detach();                        
+                        PID1.detach();
+                        PID2.detach();
+                        Mem.PID.enabled=0;
+                        Mem.PID_R.enabled=0;
+                        LT1446_0.dacB.Code=0;
+                        LT1446_0.dacA.Code=0;
+                        LTCwrite(&LT1446_0);
+                        UART.printf("PIDs is stopped\r\n");
+                        break;}
+                    }
+                }
+                //запустить задачу чтения АЦП каждые 40 мс (25 герц)
+                //adctask.attach(&readADC,0.04);
+                break;}
+                
+            case's':  {//остановить постоянное отображение
+                //adctask.detach();
                 lm_temp.detach();
-                LM35_stop();              
+                Mem.PID.enabled=0;
+                Mem.PID_R.enabled=0;
+                //LM35_stop();
+                ADS1248SleepCommand();
+                DS1248_START=0;
                 break;}
-            case 'd':
+                
+            case 'd':{//LTC1446 задание значений на ЦАП оба канала
                 //MBFlagRegister.DAC=1;
-                break;
+                if (str[1]=='a')//команда = "da=xxxx" где хххх - код ЦАП
+                {
+                    LT1446_0.dacA.Code=(str[2]-0x30)*1000+(str[3]-0x30)*100+(str[4]-0x30)*10+(str[5]-0x30);
+                    UART.printf("%d\r\n",LT1446_0.dacA.Code);
+                    }
+                if (str[1]=='b')
+                {
+                    LT1446_0.dacB.Code=(str[2]-0x30)*1000+(str[3]-0x30)*100+(str[4]-0x30)*10+(str[5]-0x30);
+                    UART.printf("%d\r\n",LT1446_0.dacB.Code);
+                    }
+                 LTCwrite(&LT1446_0);
+                break;}
             case 'e':{
                 tempdata=pga280_readOneRegisterDevice(PGA280_ERROR_ADR,5);//чтение ошибок                
                 printf("ERRORS %X\n",tempdata);                               
                 break;}            
-            case 'r':{
+            case 'r':{//выключить ПИД 2 перед манипуляциями с ним
+                 PID2.detach();
+                 //задающее воздействие =0;
+                 LT1446_0.dacA.Code=0;
+                 LT1446_0.dacB.Code=0;
+                 LTCwrite(&LT1446_0);
+                 //обработка команд
+                 switch (str[1]){
+                 case 'P':{
+                 Mem.PID_R.kP=BufToFloat(str);
+                 Mem_write();
+                 UART.printf("P=%f\r\n",Mem.PID_R.kP);
+                 break;
+                 }
+                 case 'I':{
+                 Mem.PID_R.kI=BufToFloat(str);
+                 Mem_write();
+                 UART.printf("I=%f\r\n",Mem.PID_R.kI);
+                 break;
+                 }
+                 case 'D':{
+                 Mem.PID_R.kD=BufToFloat(str);
+                 Mem_write();
+                 UART.printf("D=%f\r\n",Mem.PID_R.kD);
+                 break;
+                 }
+                 case 'f':{//  /rf
+                     setPIDdefault(&Mem.PID_R,&PID_defs);
+                     Mem_write();
+                     UART.printf("PID is default\r\n");
+                     break;}
+                 case 'g':{//запуск чтения расхода /rg
+                 lm_temp.detach();
+                     DS1248_START=1;
+                 ADS1248WakeupCommand();
+                 ads1.MUX0.MUX_SN=3; //AIN3
+                 ads1.MUX0.MUX_SP=2; //AIN2
+                 ads1.VBIAS.VBIAS3=1;
+                 ADS1248SettingReg(&ads1);
+                 UART.printf("Rashod reading started.\r\n");
+                 printer_p=&printtemp;
+                 lm_temp.attach(printer_p,0.1);
+                     break;}
+                     
+                     case 'u':{ // ru=xx.xx; точка обязательна
+                         //задание уставки расхода
+                 rashod_u=BufToFloat(str);
+                 UART.printf("Rashod = %0.3f\r\n",rashod_u);
+                         break;}
+                 default:break;
+                 }
+                 
+                if((str[1]=='e')&&(str[2]=='s')&&(str[3]=='e')&&(str[4]=='t')){
                 //перезагрука                           
                 printf("System Reset\r\n");
-                NVIC_SystemReset();
+                NVIC_SystemReset();}
+                if ((str[1]=='e')&&(str[2]=='c')&&(str[3]=='a')&&(str[4]=='l')){
+                    disp.Calibration(Mem.calibration,1);
+                    UART.printf("Recalibrated\r\n");
+                    };
                 break;}
             default:                
                 //MBFlagRegister.TMLS=0; //починка зависания (не работает)
@@ -136,64 +690,4 @@
         }
     }
 }
- float PID ()
-    {
-    float P = Kp * Error;
-    float I = Ki * Integral;
-    float D = Kd * dError;
-    float control = P + I + D;
-    if (control > 1.0) return 1.0;
-    if (control < 0.0) return 0.0;
-    return control;
-    }
-
-void pressed()
-{
-    PID1.attach(&readtemp,0.25);
-    UART.printf("PID is ON\r\n");
-}
-
-int main()
-{    
-    UART.printf("ksdgjlsdkjgskdjg");
-    //Инициализация периферийных устройств
-    SPI1_MasterInitMode(2);//работают режимы 1 и 2 
-   //запустить задачу проверки команды по прерыванию УАРТ
-    UART.attach(&ComandCheck,Serial::RxIrq);
-    EN1=1;
-          
-    
-    ch=5;
-    pga280_setAdress(ch);    
-    pga280_ads1259_init(ch); //инициализировать АЦП по адресу на плате ТЭД-2 = 5 (4)
-    printf("\r\n");      
-    tempdata=pga280_readOneRegisterDevice(PGA280_BUF_TIMEOUT_ADR,ch);
-    printf("Timeout %X\n",tempdata);
-    wait_ms(20);
-    pga280_setGAIN(GAIN_1_PGA280,ch);
-    pga280_setMUX(2,ch);
-    pga280gain=3; //   gain=1 (0x03)
-    tempdata=pga280_readOneRegisterDevice(PGA280_ERROR_ADR,ch);//чтение ошибок
-    printf("Errors %X\n",tempdata);   
-    /*Конец*/
-    
-    button.fall(&pressed);
-    
-        
-    uint16_t q1=0;
-    while(1)
-    {     
-      q1=4;
-      while(q1--){
-          SPI1_MasterInitMode(q1);
-    Cs=0;   
-    TED2.write(0x00);    
-    TED2.write(0x00);
-    TED2.write(0x00);    
-    Cs=1;
-    UART.printf("%d\r\n",q1);
-    wait_ms(3000);          
-          }
-    }
-}
  
\ No newline at end of file