Контроллер системы двухступеньчатого наддува дизезя (BMW M57)

Liske
Offline
Зарегистрирован: 27.06.2016

Всем доброго времяни суток ! Решил выложить свой проэкт сюда, в надежде получить помощь в его дороботке..

Суть проэкта: Управление двумя солиноидами системы двухступенчатого наддува, а так же некоторыми переферийными функциями, как; управление вентилятором системы охлаждения по ШИМ (БМВ е46, е90..), система впрыска спирта в двигатель.

Вот скетч:

 

/* Двух канальный буст контроллер, для системы двухступенчатого наддува, 
       с функцией управления вентилятором охлаждения PWM сигналом BMW Е46*/
 
   // Контакты блютус модуля: TXD - 6  , RXD - 2 
       
int RPMin = 13; // Вход датчика оборотов двигателя (датчик фазы) 
int BARin = 1;   // Вход датчика давления во впускном коллекторе.  Распиновка датчика: 1-сигнал , 2-масса, 3- +5v
int FANout = 3; //Выход вентилятора охлаждения
int FANtempin = 4;//Аналоговый вход датчика температуры двиг.
int FANact;
int sensorValue2;
int FANval;
int FANval1;
int FANconin = 0;   //Аналоговый вход запроса включения вентилятора кондиционера (выход из ЭБУ двигателя)
int FANconval;
int FANconval1;
int FANconact;
int Wout = 4;  // Выход на насос впрыска воды/спирта
int Wval;
int Wval1;
int Wact;
int mact;
int Mval;
int Mval1;
int PWM2out = 10; // Выход солиноида первой(большой)турбины.
int PWM2in = 5;   // Аналоговый вход мап-сенсора первой турбины. (Калибровка датчика: 1.5v = 1013mBar 3.5v = 3000mBar 3.6v = 3200mBar)
int PWM2act;
int PWM2val;
int PWM2val1;
int PWMout = 9;     //PWM для солиноида второй(маленькой) турбины.
int PWMval;       
int mapin = 6;       //Аналоговый вход нагрузки двигателя (датчик педали газа)
int mapact;
int rpmin = 7;       //Analog input actual Exhaust presure sensor
int rpmact;
int PWMval1;            
int PWMval2;            
int PWMval3;   
int mapact2;
int mapact3;
 
                      //  Управление скростью насоса подачи спирта.
const int r20 = 0;
const int r21 = 0;
const int r22 = 0;
const int r23 = 0;
const int r24 = 0;
const int r25 = 80;
const int r26 = 100;
const int r27 = 120;
const int r28 = 140;
const int r29 = 160;
const int r30 = 200;
const int r31 = 240;
const int r32 = 240;
const int r33 = 250;
const int r34 = 250;
const int r35 = 250;
const int r36 = 250;
const int r37 = 250;
const int r38 = 250;
const int r39 = 250;
const int r40 = 250;
const int r41 = 250;
const int r42 = 250;
const int r43 = 250;
const int r44 = 250;
const int r45 = 250;
const int r46 = 250;
const int r47 = 250;
const int r48 = 250;
const int r49 = 250;
const int r50 = 250;
const int r51 = 250;
const int r52 = 250;
const int r53 = 250;
const int r54 = 250;
const int r55 = 250;
 
                         
                         // Положение клапана WG БОЛЬШОЙ турбины, от  датчика давления воздуха певой (большой) турбины.
const int rp20 = 0;
const int rp21 = 0;
const int rp22 = 0;
const int rp23 = 0;
const int rp24 = 0;
const int rp25 = 221;
const int rp26 = 222;
const int rp27 = 223;
const int rp28 = 224;
const int rp29 = 220;
const int rp30 = 220;
const int rp31 = 220;
const int rp32 = 220;
const int rp33 = 240;
const int rp34 = 240;
const int rp35 = 240;
const int rp36 = 240;
const int rp37 = 240;
const int rp38 = 240;
const int rp39 = 240;
const int rp40 = 240;
const int rp41 = 240;
const int rp42 = 220;
const int rp43 = 190;
const int rp44 = 170;
const int rp45 = 150;
const int rp46 = 130;
const int rp47 = 110;
const int rp48 = 90;
const int rp49 = 60;
const int rp50 = 40;
const int rp51 = 20;
const int rp52 = 10;
const int rp53 = 10;
const int rp54 = 10;
const int rp55 = 10;
 
 
const int mpc120 = 200;    // График скорости вращения вентилятора, по запросу кондиционера (ЭБУ двигателя). Значеня от 0-254 
const int mpc107 = 200;    //  Используется как поправка к графику включения вентилятора двиг.
const int mpc102 = 180;
const int mpc99 = 150;
const int mpc96 = 120;
const int mpc93 = 90;
const int mpc90 = 60;
const int mpc85 = 50;
const int mpc80 = 40;
const int mpc70 = 1;   
 
 
 
const int mp120 = 241;   // График темпкратуры влючения вентилятора охлаждения двигателя(PWM) Значеня от 0-254
const int mp107 = 240;      
const int mp102 = 200;
const int mp99 = 120;
const int mp96 = 60;
const int mp93 = 5;
const int mp90 = 4;
const int mp85 = 3;
const int mp80 = 2;
const int mp70 = 1;   // град.цельсия
 
 
const int m20 = 0;   // Коррекция положения геометрии МАЛЕНЬКОЙ турбины, по давлению большой турбины.
const int m21 = 0;
const int m22 = 0;
const int m23 = 0;
const int m24 = 0;
const int m25 = 0;
const int m26 = 0;
const int m27 = 0;
const int m28 = -1;
const int m29 = -3;
const int m30 = -5;
const int m31 = -7;
const int m32 = -9;
const int m33 = -10;
const int m34 = -10;
const int m35 = -10;
const int m36 = -12;
const int m37 = -15;
const int m38 = -20;
const int m39 = -23;
const int m40 = -26;
const int m41 = -29;
const int m42 = -31;
const int m43 = -34;
const int m44 = -37;
const int m45 = -40;
const int m46 = -40;
const int m47 = -40;
const int m48 = -40;
const int m49 = -40;
const int m50 = -40;
const int m51 = -40;
const int m52 = -40;
const int m53 = -40;
const int m54 = -40;
const int m55 = -40;
 
 
const int mpm0 = 0;  //0%   // Коррекция положения геометрии МАЛЕНЬКОЙ турбины, по положению дросселя %(нагрузке) Значения от -100 до 100)
const int mpm2 = 0;      
const int mpm4 = 0;
const int mpm6 = 0;
const int mpm8 = 0;
const int mpm10 = 0;
const int mpm12 = 10;
const int mpm14 = 20;
const int mpm16 = 25;
const int mpm18 = 26;         
const int mpm20 = 24;
const int mpm22 = 22;
const int mpm24 = 20;
const int mpm26 = 18;
const int mpm28 = 17;
const int mpm30 = 16;
const int mpm32 = 15;
const int mpm34 = 14;
const int mpm36 = 13;
const int mpm38 = 12;            
const int mpm40 = 11;
const int mpm42 = 10;
const int mpm44 = 9;
const int mpm46 = 7;
const int mpm48 = 5;
const int mpm50 = 0;  //50%
const int mpm52 = 0;
const int mpm54 = 0;
const int mpm56 = 0;
const int mpm58 = 0;           
const int mpm60 = 0;
const int mpm65 = 0;
const int mpm70 = 0;
const int mpm80 = 0;
const int mpm90 = 0;
const int mpm100 = 0;       //100%
 
 
                          // Положение геометрии МАЛЕНЬКОЙ турбины, по давлению в выхлопе. Значения от 20 до 250.
                          //Болшие значения - увеличивают дьюти клапана и повышают давление наддува.  )
const int rpm20 = 240;
const int rpm21 = 220;
const int rpm22 = 210;
const int rpm23 = 200;
const int rpm24 = 190;
const int rpm25 = 180;
const int rpm26 = 160;
const int rpm27 = 150;
const int rpm28 = 140;
const int rpm29 = 130;
const int rpm30 = 120;
const int rpm31 = 110;
const int rpm32 = 100;
const int rpm33 = 90;
const int rpm34 = 80;
const int rpm35 = 70;
const int rpm36 = 60;
const int rpm37 = 50;
const int rpm38 = 40;
const int rpm39 = 30;
const int rpm40 = 20;
const int rpm41 = 10;
const int rpm42 = 0;
const int rpm43 = 0;
const int rpm44 = 0;
const int rpm45 = 0;
const int rpm46 = 0;
const int rpm47 = 0;
const int rpm48 = 0;
const int rpm49 = 0;
const int rpm50 = 0;
const int rpm51 = 0;
const int rpm52 = 0;
const int rpm53 = 0;
const int rpm54 = 0;
const int rpm55 = 0;
 
 
 
void setup() {
 
  pinMode (PWM2out, OUTPUT);
  pinMode (PWMout, OUTPUT);
  pinMode (rpmin, INPUT);
  pinMode (FANout, OUTPUT);
  pinMode (FANtempin, INPUT);
  pinMode (mapin, INPUT);
  pinMode (PWM2in, INPUT);
  pinMode (FANconin, INPUT);
  pinMode (Wout, OUTPUT);
  pinMode (RPMin, INPUT);
 
  Serial.begin(115200);
  TCCR1B = TCCR1B & 0b11111000 | 0x05;
   TCCR2B = TCCR2B & 0b11111000 | 0x05;
}
 
void loop() {
 
FANconact = analogRead(FANconin);
  FANconact = map(FANconact, 0 , 1023, 0 , 10);
 
 
   { switch (FANconact) {
      default: FANconval = 0;
        break;
 
      case 1: FANconval = mpc120;
        break;
      case 2: FANconval = mpc107;
        break;
      case 3: FANconval = mpc102;
        break;
      case 4: FANconval = mpc99;
        break;
      case 5: FANconval = mpc96;
        break;
      case 6: FANconval = mpc93;
        break;
      case 7: FANconval = mpc90;
        break;
      case 8: FANconval = mpc85;
        break;
      case 9: FANconval = mpc80;
        break;
      case 10: FANconval = mpc70;
        break;
         } FANconval1 = FANconval;}
 
         
 
   {FANact = analogRead(FANtempin);}
   
  FANact = map(FANact, 0 , 323, 0 , 10);
 
 
{ switch (FANact) {
      default: FANval = 0;
        break;
 
      case 1: FANval = mp120;
        break;
      case 2: FANval = mp107;
        break;
      case 3: FANval = mp102;
        break;
      case 4: FANval = mp99;
        break;
      case 5: FANval = mp96;
        break;
      case 6: FANval = mp93;
        break;
      case 7: FANval = mp90;
        break;
      case 8: FANval = mp85;
        break;
      case 9: FANval = mp80;
        break;
      case 10: FANval = mp70;
        break;
         } FANval1 = FANval + FANconval1;}
 
         if (FANval > 200){ FANconval = 0;}
 
 { FANval1 = max(FANval1, 10);
  FANval1 = min(FANval1, 250);
  
  analogWrite (FANout, FANval1);}
 
 
  mapact = analogRead(mapin);
  
  mapact = map(mapact, 57 , 390, 0 , 36);
 
 
{ switch (mapact) {
      default: mapact2 = 0;
        break;
 
      case 1: mapact2 = mpm0;
        break;
      case 2: mapact2 = mpm2;
        break;
      case 3: mapact2 = mpm4;
        break;
      case 4: mapact2 = mpm6;
        break;
      case 5: mapact2 = mpm8;
        break;
      case 6: mapact2 = mpm10;
        break;
      case 7: mapact2 = mpm12;
        break;
      case 8: mapact2 = mpm14;
        break;
      case 9: mapact2 = mpm16;
        break;
      case 10: mapact2 = mpm18;
        break;
      case 11: mapact2 = mpm20;
        break;
      case 12: mapact2 = mpm22;
        break;
      case 13: mapact2 = mpm24;
        break;
      case 14: mapact2 = mpm26;
        break;
      case 15: mapact2 = mpm28;
        break;
      case 16: mapact2 = mpm30;
        break;
      case 17: mapact2 = mpm32;
        break;
      case 18: mapact2 = mpm34;
        break;
      case 19: mapact2 = mpm36;
        break;
      case 20: mapact2 = mpm38;
        break;
      case 21: mapact2 = mpm40;
        break;
      case 22: mapact2 = mpm42;
        break;
      case 23: mapact2 = mpm44;
        break;
      case 24: mapact2 = mpm46;
        break;
      case 25: mapact2 = mpm48;
        break;
      case 26: mapact2 = mpm50;
        break;
      case 27: mapact2 = mpm52;
        break;
      case 28: mapact2 = mpm54;
        break;
      case 29: mapact2 = mpm56;
        break;
      case 30: mapact2 = mpm58;
        break;
      case 31: mapact2 = mpm60;
        break;
      case 32: mapact2 = mpm65;
        break;
      case 33: mapact2 = mpm70;
        break;
      case 34: mapact2 = mpm80;
        break;
      case 35: mapact2 = mpm90;
        break;
      case 36: mapact2 = mpm100;
        break;
    } mapact3 = mapact2;}
 
      
    
 
 
int sensorValue1 = analogRead(A6);                // Датчик положения дросселя
  float voltage1 = sensorValue1 * ( 0 , 313 / 1023.0);
 
  // print out the value you read:
 
int sensorValue2 = analogRead(A4);
   // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage2 = sensorValue2 * ( 0.00 , 5.00 / 1023.0);  
  int sensorValue = analogRead(A7);
   // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * ( 0300 , 4800 / 1023.0);
 
  // print out the value you read:
  {Serial.print("                                                        Loud value TP% ");
  Serial.println(voltage1 - 21.0);
  Serial.print("                                                                             Exhaust pres. mBar: ");
  Serial.println(voltage);
  Serial.print("                                          TP_kor % ");
  Serial.println(mapact2 * 0.392);
  Serial.print("mBar_kor % ");
  Serial.println(PWMval  * 0.392 );
  Serial.print("                      N75 PWM  ");
  Serial.println(PWMval1  );
  Serial.print("                                                                                                                  Coll.Temp: ");
  Serial.println(sensorValue2);
Serial.print("                                                   FANpwm: ");
  Serial.println(FANval1);
  Serial.print("                                                                                                     WG: ");
  Serial.println(PWM2val1);
Serial.print("                                                                                                     FANcon: ");
  Serial.println(FANconval1);}
 
Wact = analogRead(PWM2in);
  Wact = map(Wact, 290 , 823, 20 , 55); //
  //
 
{ switch (Wact) {
      default: Wval = 0;
        break;
 
      case 20: Wval = r20;
        break;
      case 21: Wval = r21;
        break;
      case 22: Wval = r22;
        break;
      case 23: Wval = r23;
        break;
      case 24: Wval = r24;
        break;
      case 25: Wval = r25;
        break;
      case 26: Wval = r26;
        break;
      case 27: Wval = r27;
        break;
      case 28: Wval = r28;
        break;
      case 29: Wval = r29;
        break;
      case 30: Wval = r30;
        break;
      case 31: Wval = r31;
        break;
      case 32: Wval = r32;
        break;
      case 33: Wval = r33;
        break;
      case 34: Wval = r34;
        break;
      case 35: Wval = r35;
        break;
      case 36: Wval = r36;
        break;
      case 37: Wval = r37;
        break;
      case 38: Wval = r38;
        break;
      case 39: Wval = r39;
        break;
      case 40: Wval = r40;
        break;
      case 41: Wval = r41;
        break;
      case 42: Wval = r42;
        break;
      case 43: Wval = r43;
        break;
      case 44: Wval = r44;
        break;
      case 45: Wval = r45;
        break;
      case 46: Wval = r46;
        break;
      case 47: Wval = r47;
        break;
      case 48: Wval = r48;
        break;
      case 49: Wval = r49;
        break;
      case 50: Wval = r50;
        break;
      case 51: Wval = r51;
        break;
      case 52: Wval = r52;
        break;
      case 53: Wval = r53;
        break;
      case 54: Wval = r54;
        break;
      case 55: Wval = r55;
 
        break;
    } Wval1 = Wval;
      analogWrite (Wout, Wval1); 
  }
 
 
PWM2act = analogRead(PWM2in);
  PWM2act = map(PWM2act, 290 , 823, 20 , 55); //
  //
 
{ switch (PWM2act) {
      default: PWM2val = 0;
        break;
 
      case 20: PWM2val = rp20;
        break;
      case 21: PWM2val = rp21;
        break;
      case 22: PWM2val = rp22;
        break;
      case 23: PWM2val = rp23;
        break;
      case 24: PWM2val = rp24;
        break;
      case 25: PWM2val = rp25;
        break;
      case 26: PWM2val = rp26;
        break;
      case 27: PWM2val = rp27;
        break;
      case 28: PWM2val = rp28;
        break;
      case 29: PWM2val = rp29;
        break;
      case 30: PWM2val = rp30;
        break;
      case 31: PWM2val = rp31;
        break;
      case 32: PWM2val = rp32;
        break;
      case 33: PWM2val = rp33;
        break;
      case 34: PWM2val = rp34;
        break;
      case 35: PWM2val = rp35;
        break;
      case 36: PWM2val = rp36;
        break;
      case 37: PWM2val = rp37;
        break;
      case 38: PWM2val = rp38;
        break;
      case 39: PWM2val = rp39;
        break;
      case 40: PWM2val = rp40;
        break;
      case 41: PWM2val = rp41;
        break;
      case 42: PWM2val = rp42;
        break;
      case 43: PWM2val = rp43;
        break;
      case 44: PWM2val = rp44;
        break;
      case 45: PWM2val = rp45;
        break;
      case 46: PWM2val = rp46;
        break;
      case 47: PWM2val = rp47;
        break;
      case 48: PWM2val = rp48;
        break;
      case 49: PWM2val = rp49;
        break;
      case 50: PWM2val = rp50;
        break;
      case 51: PWM2val = rp51;
        break;
      case 52: PWM2val = rp52;
        break;
      case 53: PWM2val = rp53;
        break;
      case 54: PWM2val = rp54;
        break;
      case 55: PWM2val = rp55;
 
        break;
    } PWM2val1 = PWM2val;
     analogWrite (PWM2out, PWM2val1);  
  }
 
  
mact = analogRead(PWM2in);
  mact = map(mact, 290 , 823, 20 , 55); //
  //
 
{ switch (mact) {
      default: Mval = 0;
        break;
 
      case 20: Mval = m20;
        break;
      case 21: Mval = m21;
        break;
      case 22: Mval = m22;
        break;
      case 23: Mval = m23;
        break;
      case 24: Mval = m24;
        break;
      case 25: Mval = m25;
        break;
      case 26: Mval = m26;
        break;
      case 27: Mval = m27;
        break;
      case 28: Mval = m28;
        break;
      case 29: Mval = m29;
        break;
      case 30: Mval = m30;
        break;
      case 31: Mval = m31;
        break;
      case 32: Mval = m32;
        break;
      case 33: Mval = m33;
        break;
      case 34: Mval = m34;
        break;
      case 35: Mval = m35;
        break;
      case 36: Mval = m36;
        break;
      case 37: Mval = m37;
        break;
      case 38: Mval = m38;
        break;
      case 39: Mval = m39;
        break;
      case 40: Mval = m40;
        break;
      case 41: Mval = m41;
        break;
      case 42: Mval = m42;
        break;
      case 43: Mval = m43;
        break;
      case 44: Mval = m44;
        break;
      case 45: Mval = m45;
        break;
      case 46: Mval = m46;
        break;
      case 47: Mval = m47;
        break;
      case 48: Mval = m48;
        break;
      case 49: Mval = m49;
        break;
      case 50: Mval = m50;
        break;
      case 51: Mval = m51;
        break;
      case 52: Mval = m52;
        break;
      case 53: Mval = m53;
        break;
      case 54: Mval = m54;
        break;
      case 55: Mval = m55;
 
        break;
    } Mval1 = Mval;}
     
  
 
 
  
  rpmact = analogRead(rpmin);
  rpmact = map(rpmact, 170 , 923, 20 , 55); //
  //
 
{ switch (rpmact) {
      default: PWMval = 0;
        break;
 
      case 20: PWMval = rpm20;
        break;
      case 21: PWMval = rpm21;
        break;
      case 22: PWMval = rpm22;
        break;
      case 23: PWMval = rpm23;
        break;
      case 24: PWMval = rpm24;
        break;
      case 25: PWMval = rpm25;
        break;
      case 26: PWMval = rpm26;
        break;
      case 27: PWMval = rpm27;
        break;
      case 28: PWMval = rpm28;
        break;
      case 29: PWMval = rpm29;
        break;
      case 30: PWMval = rpm30;
        break;
      case 31: PWMval = rpm31;
        break;
      case 32: PWMval = rpm32;
        break;
      case 33: PWMval = rpm33;
        break;
      case 34: PWMval = rpm34;
        break;
      case 35: PWMval = rpm35;
        break;
      case 36: PWMval = rpm36;
        break;
      case 37: PWMval = rpm37;
        break;
      case 38: PWMval = rpm38;
        break;
      case 39: PWMval = rpm39;
        break;
      case 40: PWMval = rpm40;
        break;
      case 41: PWMval = rpm41;
        break;
      case 42: PWMval = rpm42;
        break;
      case 43: PWMval = rpm43;
        break;
      case 44: PWMval = rpm44;
        break;
      case 45: PWMval = rpm45;
        break;
      case 46: PWMval = rpm46;
        break;
      case 47: PWMval = rpm47;
        break;
      case 48: PWMval = rpm48;
        break;
      case 49: PWMval = rpm49;
        break;
      case 50: PWMval = rpm50;
        break;
      case 51: PWMval = rpm51;
        break;
      case 52: PWMval = rpm52;
        break;
      case 53: PWMval = rpm53;
        break;
      case 54: PWMval = rpm54;
        break;
      case 55: PWMval = rpm55;
 
        break;
    } PWMval1 = PWMval + mapact3 + Mval1;
     
  
    
  }
 
  {PWMval1 = max(PWMval1, 10);
  PWMval1 = min(PWMval1, 250);
 
  analogWrite (PWMout, PWMval1);}
}
Liske
Offline
Зарегистрирован: 27.06.2016

Основной момент, который меня не устраивает в текущей версии, это дискретное изменение уровней управляющих сигналов (отсутствие интерполяциимежду ячейками данных в "графиках"). В виду отсутствия знаний по ардуино, не знаю как это реализовать.

В текущей версии кода, на верняка есть масса грамоздких и не нужных вещей.. Но в целом, все работает.

Пожалуйста прокоментируйте код, если есть серьезные ошибки. И по поводу интерполяции конечно тоже..

 

Liske
Offline
Зарегистрирован: 27.06.2016
kasper007
Offline
Зарегистрирован: 23.05.2016

ну наверное самая первая оптимизация, которую нужно провести  это засунуть все в массивы.

Liske
Offline
Зарегистрирован: 27.06.2016

kasper007 пишет:

ну наверное самая первая оптимизация, которую нужно провести  это засунуть все в массивы.

А вы могли бы на каком нибудь фрагменте кода показать, как это сделать ?

kasper007
Offline
Зарегистрирован: 23.05.2016

Ну если не вдаваться в подробности выглядеть будет примерно так:

ИСХОДНЫЙ ТЕКСТ:

const int mp120 = 241;   // График темпкратуры влючения вентилятора охлаждения двигателя(PWM) Значеня от 0-254

const int mp107 = 240;      

const int mp102 = 200;

const int mp99 = 120;

const int mp96 = 60;

const int mp93 = 5;

const int mp90 = 4;

const int mp85 = 3;

const int mp80 = 2;

const int mp70 = 1;   // град.цельсия

ЧЕРЕЗ МАССИВ:

int mp_tem[] = {0, 241, 240, 200, 120, 60, 5, 4, 3, 2, 1}

 

В ТЕЛЕ ПРОГРАММЫ:

ИСХОДНЫЙ ТЕКСТ:


 {FANact = analogRead(FANtempin);}
  FANact = map(FANact, 0 , 323, 0 , 10);
  { switch (FANact) {
      default: FANval = 0;
        break;
       case 1: FANval = mp120;
        break;
      case 2: FANval = mp107;
        break;
      case 3: FANval = mp102;
        break;
      case 4: FANval = mp99;
        break;
      case 5: FANval = mp96;
        break;
      case 6: FANval = mp93;
        break;
      case 7: FANval = mp90;
        break;
      case 8: FANval = mp85;
        break;
      case 9: FANval = mp80;
        break;
      case 10: FANval = mp70;
        break;
         } FANval1 = FANval + FANconval1;}
 

ЧЕРЕЗ МАССИВ:


 FANact = analogRead(FANtempin);
 FANact = map(FANact, 0 , 323, 0 , 10);
 FANval = mp_tem[FANact];
 FANval1 = FANval + FANconval1;

В таком виде можно расширить массив (допустим не 10 значений сделать, а 30) и сделать более плавную регулировку. Для этого в данном виде не нужно дописывать +100500 строчек кода, а просто добавить 20 лишних значений в первой строчке объявления массива.

Liske
Offline
Зарегистрирован: 27.06.2016

Да, это классно ! Спасибо за помощь ! Попробую переделать код, испытаю.. И напишу что получилось.

kasper007
Offline
Зарегистрирован: 23.05.2016

И вот еще следующий вопрос для размышления:

Во многих местах функцией map идет пересчет данных в область начинающуюся не от нуля, а куда-то выше, а далее по коду идет простой {switc case}.

  rpmact = map(rpmact, 170 , 923, 20 , 55);

Почему не делается вот так:

  rpmact = map(rpmact, 170 , 923, 0 , 35);

И тогда также при инициализации программы также забивается массив данных, только при этом не потребуется вносить первые 20 нулей.

Может в твоем действии и есть сакральный смысл, но вот так вот сходу я смог его понять и считаю, что можно и нужно сделать именно так, как я предлагаю.

kasper007
Offline
Зарегистрирован: 23.05.2016

Для красоты кода и минимизации использования памяти, все переменные, которыми ты описываешь порты ввода/вывода нужно объявлять не через int

ВОТ ТАК НЕ НУЖНО:

int RPMin = 13; // Вход датчика оборотов двигателя (датчик фазы) 
int BARin = 1;   // Вход датчика давления во впускном коллекторе.  Распиновка датчика: 1-сигнал , 2-масса, 3- +5v
int FANout = 3; //Выход вентилятора охлаждения
int FANtempin = 4;//Аналоговый вход датчика температуры двиг.
int FANconin = 0;   //Аналоговый вход запроса включения вентилятора кондиционера (выход из ЭБУ двигателя)
int Wout = 4;  // Выход на насос впрыска воды/спирта
int PWM2out = 10; // Выход солиноида первой(большой)турбины.
int PWM2in = 5;   // Аналоговый вход мап-сенсора первой турбины. (Калибровка датчика: 1.5v = 1013mBar 3.5v = 3000mBar 3.6v = 3200mBar)
int PWMout = 9;     //PWM для солиноида второй(маленькой) турбины.
int mapin = 6;       //Аналоговый вход нагрузки двигателя (датчик педали газа)
int rpmin = 7;       //Analog input actual Exhaust presure sensor

А ВОТ ТАК ХОРОШО:

#define RPMin 13   // Вход датчика оборотов двигателя (датчик фазы) 
#define BARin 1     // Вход датчика давления во впускном коллекторе.  Распиновка датчика: 1-сигнал , 2-масса, 3- +5v
#define FANout 3      //Выход вентилятора охлаждения
#define FANtempin 4 //Аналоговый вход датчика температуры двиг.
#define FANconin 0   //Аналоговый вход запроса включения вентилятора кондиционера (выход из ЭБУ двигателя)
#define Wout 4  //Выход на насос впрыска воды/спирта
#define PWM2out 10  //Выход солиноида первой(большой)турбины.
#define PWM2in 5   //Аналоговый вход мап-сенсора первой турбины. (Калибровка датчика: 1.5v = 1013mBar 3.5v = 3000mBar 3.6v = 3200mBar)
#define PWMout 9     //PWM для солиноида второй(маленькой) турбины.
#define mapin 6      //Аналоговый вход нагрузки двигателя (датчик педали газа)
#define rpmin 7      //Analog input actual Exhaust presure sensor

 

Liske
Offline
Зарегистрирован: 27.06.2016

kasper007 пишет:

Для красоты кода и минимизации использования памяти, все переменные, которыми ты описываешь порты ввода/вывода нужно объявлять не через int

ВОТ ТАК НЕ НУЖНО:


Спасибо ! Я это тоже переделаю. Основу этого проэкта, я нашел на каком то буржуинском сайте.. Переделал под свой алгоритм регулирования, добавил нужные коррекции и функции. Интуитивно понимал, что все громоздко.., но работало..

Теперь настало время сделать все по феншую..)    Пока протестировать возможности нет. Меняю турбины и распылители форсунок, на побольше..

Liske
Offline
Зарегистрирован: 27.06.2016

Нет, ни какого сокрального смысла.. Просто в перво источнике было больше ячеек (от 0 до 55) я убрал первые 20.. Потом просто размножил этот "пример" по другим функциям..

 

Liske
Offline
Зарегистрирован: 27.06.2016

Вот исправленная версия.. Еще, для удобства настроики, добавил графический интерфес от remotexy и перевел некоторые "тугрики", в проценты.

 





 

Liske
Offline
Зарегистрирован: 27.06.2016

Еще есть не решенный вопрос: Сигнал оборотов двигателя. Ни как не могу определиться, как его получить. Есть вариант взять сигнал от датчика хола(датчик распредвала) и счетать импульсы.. Но способа как это сделать, без помех для выполнения остальной части программы, я пока не нашел. Можно просто на аналоговом входе повесить кондер и преобразовывать частоту в напряжение, с последующей калибровкой полученого сигнала. Точность конечно будет не высокая, но думаю для данных нужд достаточня.. И еще есть вариант получать данные из OBD2.., что тоже,  для меня пока не изведанно..

 

Liske
Offline
Зарегистрирован: 27.06.2016
Вот надеюсь практически финальная версия.. Добавил возможность программирования по блютус и подправил кой какие неровности..</pre>
Примечательно то, что мне удалось заставить и программироваться, и работать с интерфейсом, через один и тот же блютус канал, на HC-06. 
Может кому то эта идея пригодится..)
 
Ну и разумеется, жду конструктивной критики и предложений по улучшению кода !
 
 

/* Двух канальный буст контроллер, для системы двухступенчатого наддува,на база arduino NANO
 *     с функцией управления двумя соленоидами перепускных клапанов турбин(частота модуляции 30Гц)
       с функцией управления вентилятором охлаждения PWM сигналом BMW Е46/E90
       с возможностью программирования ардуино по блютус каналу,
       с функцией отображение текущих параметров,по блютус каналу,через графический интерфейс RemoteXY
       с функцией управления исполнительными механизмами по блютус каналу,через графический интерфейс RemoteXY*/
       
/* определение режима соединения и подключение библиотеки RemoteXY */ 
#define REMOTEXY_MODE__HC05_SOFTSERIAL
#include <SoftwareSerial.h> 
#include <CyberLib.h>
#include <RemoteXY.h> 

/* настройки соединения */                 // Используется модуль HC-06 ! Скорость передачи модуля,увеличена до 57600
#define REMOTEXY_SERIAL_RX 7    // <--- Соединен с пином D1 ардуино и пином TXD блютус модуля
#define REMOTEXY_SERIAL_TX 8    // <--- Соединен с пином RXD блютус модуля и через резистор 2ком,с пином D0 ардуино
#define REMOTEXY_SERIAL_SPEED 57600 // Скорость соединения(по умолчанию 9600)
                                            // D2-pin соединён с pin-RESET Arduino NANO
/* конфигурация интерфейса RemoteXY */  
unsigned char RemoteXY_CONF[] = 
  { 6,112,164,2,6,14,4,2,0,40
  ,7,22,11,4,2,208,178,208,186,208
  ,187,0,79,70,70,0,1,0,1,7
  ,12,12,1,2,208,159,209,131,209,129
  ,208,186,0,4,0,84,8,8,48,2
  ,2,5,47,45,28,30,30,2,2,3
  ,3,6,23,8,22,2,2,66,1,8
  ,6,9,33,4,3,67,6,32,6,34
  ,15,1,3,11,67,6,70,6,30,15
  ,1,3,11,67,6,70,27,30,13,4
  ,3,11,67,6,87,48,13,5,4,3
  ,11,67,6,87,57,13,5,2,3,11
  ,67,6,32,27,34,13,2,3,11,67
  ,6,42,48,13,5,2,3,11,67,6
  ,42,57,13,5,2,3,11,67,6,65
  ,57,13,5,2,3,11,67,6,65,48
  ,13,5,2,3,11,65,12,26,7,6
  ,5,2,2,129,0,35,2,18,4,0
  ,3,98,105,103,32,116,117,114,98,111
  ,32,98,111,111,115,116,0,129,0,5
  ,2,11,4,0,3,98,111,111,115,116
  ,0,129,0,3,6,4,3,0,3,52
  ,46,48,0,129,0,3,21,4,3,0
  ,3,50,46,48,0,129,0,3,29,4
  ,3,0,3,49,46,48,0,129,0,3
  ,13,4,3,0,3,51,46,48,0,129
  ,0,9,36,5,3,0,3,98,97,114
  ,0,129,0,5,36,2,3,0,3,48
  ,0,129,0,68,23,11,4,0,3,101
  ,120,104,97,117,115,116,32,112,114,101
  ,115,115,117,114,101,0,129,0,85,45
  ,16,3,0,3,99,111,111,108,46,102
  ,97,110,32,37,0,129,0,70,2,27
  ,4,0,3,98,111,111,115,116,32,40
  ,105,110,116,97,107,101,41,0,129,0
  ,32,18,5,3,8,3,98,97,114,0
  ,129,0,70,18,5,3,8,3,98,97
  ,114,0,129,0,70,37,5,3,8,3
  ,98,97,114,0,130,2,31,1,36,21
  ,9,3,130,2,68,1,34,21,9,3
  ,130,2,68,22,34,19,9,3,129,0
  ,85,54,16,3,0,3,119,97,116,101
  ,114,32,105,110,106,46,37,0,129,0
  ,35,23,24,4,0,3,101,110,103,105
  ,110,101,32,114,112,109,0,129,0,35
  ,45,20,3,0,3,98,105,103,32,116
  ,117,114,98,111,32,87,71,37,0,129
  ,0,32,54,23,3,0,3,115,109,97
  ,108,108,32,116,117,114,98,111,32,87
  ,71,37,0,130,2,31,22,36,19,9
  ,3,129,0,63,45,11,3,0,3,116
  ,104,114,111,116,116,108,101,32,37,0
  ,129,0,60,54,18,3,0,3,101,110
  ,103,46,32,116,101,109,112,46,67,0
  ,130,2,31,43,71,19,9,3,130,2
  ,3,1,15,39,9,3,131,0,0,56
  ,20,7,2,2,99,111,110,116,114,111
  ,108,0,131,1,0,49,20,7,2,3
  ,103,97,117,103,101,0,130,2,82,8
  ,12,49,9,2,129,0,2,0,66,6
  ,0,2,208,148,208,181,208,188,208,190
  ,32,209,130,208,181,209,129,209,130,32
  ,208,178,209,131,208,189,208,186,209,134
  ,208,184,208,184,32,209,131,208,191,209
  ,128,208,176,208,178,208,187,208,181,208
  ,189,208,184,209,143,0,129,0,20,20
  ,57,7,7,2,72,89,67,79,32,116
  ,101,99,104,111,108,111,103,121,32,0
   }; 
   
/* структура определяет все переменные вашего интерфейса управления */ 
struct { 

  /* input variable */
  unsigned char switch_1; /* =1 если переключатель включен и =0 если отключен */
  unsigned char button_1; /* =1 если кнопка нажата, иначе =0 */
  signed char slider_1; /* =0..100 положение слайдера */
  signed char joystick_1_x; /* =-100..100 координата x положения джойстика */
  signed char joystick_1_y; /* =-100..100 координата y положения джойстика */
  unsigned char select_1; /* =0 если переключатель в положении A, =1 если в положении B, =2 если в положении C, ... */
    /* output variable */
  signed char text_1; /* =0..100 положение уровня */
  char text_2[11];  /* =строка оканчивающаяся нулем UNICODE */
  char text_3[11];  /* =строка оканчивающаяся нулем UNICODE */
  char text_4[11];  /* =строка оканчивающаяся нулем UNICODE */
  char text_5[11];  /* =строка оканчивающаяся нулем UNICODE */
  char text_6[11];  /* =строка оканчивающаяся нулем UNICODE */
  char text_7[11];  /* =строка оканчивающаяся нулем UNICODE */
  char text_8[11];  /* =строка оканчивающаяся нулем UNICODE */
  char text_9[11];  /* =строка оканчивающаяся нулем UNICODE */
  char text_10[11];  /* =строка оканчивающаяся нулем UNICODE */
  char text_11[11];  /* =строка оканчивающаяся нулем UNICODE */
  unsigned char led_1_r; /* =0..255 яркость красного цвета индикатора */

  /* other variable */
  unsigned char connect_flag;  /* =1 if wire connected, else =0 */

} RemoteXY; 

///////////////////////////////////////////// 
//           END RemoteXY include          // 
///////////////////////////////////////////// 

#define SENS_1_VAL 100           //Калибровка датчика давления выхлопа
#define SENS_1_TMP 0.10 
/* второе замеренное значение - вторая точка */ 
#define SENS_2_VAL 1000 
#define SENS_2_TMP 5.00 
//______________________________

#define SENS_3_VAL 90               //Калибровка датчика давления большой турбины (в Барах)
#define SENS_3_TMP 0.0 
/* второе замеренное значение - вторая точка */ 
#define SENS_4_VAL 1000 
#define SENS_4_TMP 4.50 
//______________________________

#define SENS_5_VAL 90                 //Калибровка датчика давления во впускном коллекторе(Шкала)
#define SENS_5_TMP 1 
/* второе замеренное значение - вторая точка */ 
#define SENS_6_VAL 1000 
#define SENS_6_TMP 1000.0

//_______________________________

#define SEN_1_VAL 100                   //Калибровка датчика давления во впускном коллекторе
#define SEN_1_TMP 0.2 
/* второе замеренное значение - вторая точка */ 
#define SEN_2_VAL 1000 
#define SEN_2_TMP 4.50 

//_______________________________

#define E_1_VAL 5                       //Калибровка датчика дросселя TPS
#define E_1_TMP 0 
/* второе замеренное значение - вторая точка */ 
#define E_2_VAL 1023 
#define E_2_TMP 100.0

//_______________________________

#define SE_11_VAL 20                      //Калибровка датчика температуры охлаждающей ж.temp
#define SE_11_TMP -30 
/* второе замеренное значение - вторая точка */ 
#define SE_21_VAL 1023 
#define SE_21_TMP 120.0

//_______________________________

#define SE_111_VAL 200                      //Калибровка показаний оборотов двигателя
#define SE_111_TMP 500 
/* второе замеренное значение - вторая точка */ 
#define SE_211_VAL 500 
#define SE_211_TMP 3000

//__________________________________________________________________________________________________________________________________________________

#define RPMin A2      // Аналоговый вход оборотов двигателя (датчик фазы, через конденсатор) 
#define BARin A1      // Аналоговый Вход датчика давления во впускном коллекторе.  Распиновка датчика: 1-сигнал , 2-масса, 3- +5v
#define FANout 3      // PWM Выход вентилятора охлаждения
#define FANtempin A4  // Аналоговый вход датчика температуры двиг.
#define FANconin A0   // Аналоговый вход запроса включения вентилятора кондиционера (выход из ЭБУ двигателя)
#define Wout 4        // Выход на насос впрыска воды/спирта
#define PWM2out 10    // PWM Выход соленоида первой(большой)турбины.
#define PWM2in A5     // Аналоговый вход мап-сенсора первой турбины. (Калибровка датчика: 1.5v = 1013mBar 3.5v = 3000mBar 3.6v = 3200mBar)
#define PWMout 9      // PWM для соленоида второй(маленькой) турбины.
#define mapin A6      // Аналоговый вход нагрузки двигателя (датчик педали газа)
#define rpmin A7      // Аналоговый вход Exhaust pressure sensor
#define PIN_BUTTON_1 13 // Test
int sensorValue;
int sensorValue1;
int sensorValue2;
int sensorValue3;
int sensorValue4;
int sensorValue5;
int sensorValue6;
int FANact;
int FANval;
int FANval1;
int FANval2;
int FANconval;
int FANconact;
int Wval;
int Wval1;
int Wact;
int mact;
int Mval;
int Mval1;
int PWM2act;
int PWM2val;
int PWM2val1;
int mapact;
int mapact1;
int rpmact;
int PWMval;
int PWMval1;
int PWMval2;

double fedr = 2.53;             //  Переменный дядя Фёдр (сын дяди Магнита и брат Конуса..) Для расчета процентов из ШИМ и обратно /

//  Управление скростью насоса подачи спирта,от давления в во впуске.
int r[] = {0, 0, 0, 0, 0, 20, 25, 30, 40, 60, 70, 80, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100};
//mBar -->
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Положение клапана WG БОЛЬШОЙ турбины, от  датчика давления воздуха певой (большой) турбины. Значения от 0 до 100%. Максимальный наддув - 100%, минимальный - 0%.

int rp[] = {0, 0, 0, 0, 0, 0, 88, 88, 88, 88, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 80, 60, 60, 52, 44, 36, 24, 20, 15, 5, 5, 5, 5};
//mBar -->
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// График скорости вращения вентилятора, по запросу кондиционера (ЭБУ двигателя). Значеня от 0-100%
//  Используется как поправка к графику включения вентилятора двиг.

int mp2_tem[] = {0,  80,   80,  72,  60,  48, 36, 24, 20, 16, 1};
//           Темп.  120  107  102   99   96   93  90  85  80  70
////////////////////////////////////////////////////////////////////


// График температуры включения вентилятора охлаждения двигателя(PWM) Значения от 0-100%

int Yp_tem[] = {10, 96, 96,  85,  48, 24,  4,  3,  2,  1,  5};
//град.цельсия    120  107  102  99  96   93  90  85  80  70
////////////////////////////////////////////////////////////////////

// Коррекция положения геометрии МАЛЕНЬКОЙ турбины, по давлению большой турбины.

int m[] = {0, 0, 0, 0, 0, 0, 0, 0, -1, -3, -5, -7, -9, -10, -10, -10, -12, -15, -20, -23, -26, -29, -31, -30, -31, -32, -33, -34, -35, -36, -37, -38, -39, -41, -41, -41,};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Коррекция положения геометрии МАЛЕНЬКОЙ турбины, по положению педали газа %(нагрузке) Значения от -100 до 100%

int mpm[] = {0, 0, 0, 0, 0, 0, 10, 20, 25, 25, 24, 22, 20, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 7, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
//           0%                                                                50%                                                    100%
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Положение геометрии МАЛЕНЬКОЙ турбины, по давлению в выхлопе. Значения от 0 до 100%.
//Большие значения - увеличивают дьюти клапана и повышают давление наддува.  )

int rpm[] = {0, 0, 85, 80, 78, 75, 64, 60, 56, 50, 45, 40, 38, 35, 33, 30, 25, 20, 15, 10, 8, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
//mBar -->
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
 RemoteXY_Init ();
  D10_Out; 
  D9_Out;
  D3_Out;
  D4_Out;
  D5_In;
  D13_Out; 
Serial.begin(57600); // Arduino Speeds == 57600 и Bluetooth модуль HC-06 настроены на скорость (57600). 
TCCR1B = TCCR1B & 0b11111000 | 0x05;
TCCR2B = TCCR2B & 0b11111000 | 0x05;
}
void loop() {
   RemoteXY_Handler ();
/////////////////////////////////////////////////////////////////////////////////////////////////////
                  //Тест
 if (RemoteXY.switch_1 + RemoteXY.button_1!=0) digitalWrite(PIN_BUTTON_1, HIGH); 
  else digitalWrite(PIN_BUTTON_1, LOW);
  if (RemoteXY.switch_1 + RemoteXY.button_1!=0) // если на пин 5 подан высокий уровень 
    RemoteXY.led_1_r = 255;   // тогда включаем красный цвет индикатора 
  else                        // иначе 
    RemoteXY.led_1_r = 0;     // выключаем красный цвет 
   
///////////////////////////////////////////////////////////////////////////////////////////////////////
                   /* получаем значение АЦП */
                    
 sensorValue2 = A5_Read;        //  Давление большой турбины 
 sensorValue1 = A1_Read;        //  Давление во впускном коллекторе
 sensorValue =  A7_Read;        //  Давление выхлопа
 sensorValue3 = A6_Read;        //  Trottle
 sensorValue4 = A4_Read;        //  Temp.
 sensorValue5 = A0_Read;        //  Запрос кондиционера
 sensorValue6 = A2_Read;        //  Аналоговый вход оборотов двигателя
/*  
      
    вычисляем текущую линейную интерполяцию по двум известным точкам  
  */ 
  double temp = SENS_1_TMP + (SENS_2_TMP - SENS_1_TMP) /  
           (SENS_2_VAL - SENS_1_VAL) * (sensorValue- SENS_1_VAL);       // Давление выхлопа

           double temp2 = SENS_3_TMP + (SENS_4_TMP - SENS_3_TMP) /  
           (SENS_4_VAL - SENS_3_VAL) * (sensorValue2 - SENS_3_VAL);     // Давление большой турбины

           double temp1 = SENS_5_TMP + (SENS_6_TMP - SENS_5_TMP) /  
           (SENS_6_VAL - SENS_5_VAL) * (sensorValue1 - SENS_5_VAL);     // Давление во впускном коллекторе(Шкала)

           double temp4 = SEN_1_TMP + (SEN_2_TMP - SEN_1_TMP) /  
           (SEN_2_VAL - SEN_1_VAL) * (sensorValue1- SEN_1_VAL);         // Давление во впускном коллекторе(цифровой индикатор)

           double temp3 = FANval1;                                      // Индикатор Вентилятора %
           
           double temp6 = Wval;                                        // Water
           
           double te = E_1_TMP + (E_2_TMP - E_1_TMP) /                  // Trottle
             (E_2_VAL - E_1_VAL) * (sensorValue3- E_1_VAL);
              te =  constrain(te , 0 , 100); 
              
           double et = SE_11_TMP + (SE_21_TMP - SE_11_TMP) /            // Temp
            (SE_21_VAL - SE_11_VAL) * (sensorValue4- SE_11_VAL);  
                 
           double mm = SE_111_TMP + (SE_211_TMP - SE_111_TMP) /         // Вход оборотов двигателя
            (SE_211_VAL - SE_111_VAL) * (sensorValue6- SE_111_VAL);
             mm =  constrain(mm , 0 , 7000);       

           double ee = PWM2val;                                         // Big turbo WG

           double me = PWMval1;                                         // Small turbo WG


/*  
    преобразуем значение в строку  
    и помещаем ее сразу в поле text структуры RemoteXY  
  */ 
  
  dtostrf(temp2, 0, 1, RemoteXY.text_2);        // Давление большой турбины

  RemoteXY.text_1 = (int)(temp1 / 10.24);       // Давление во впускном коллекторе(Шкала)
  
  dtostrf(temp4, 0, 1, RemoteXY.text_3);        // Давление во впускном коллекторе(цифровой индикатор)

  dtostrf(temp3, 0, 0, RemoteXY.text_5);        // PWM выхода вентилятора
  
  dtostrf(temp, 0, 1, RemoteXY.text_4);         // ext

  dtostrf(temp6, 0, 0, RemoteXY.text_6);        // Water

  dtostrf(te, 0, 1, RemoteXY.text_11);          // Trottle

  dtostrf(et, 0, 0, RemoteXY.text_10);          // Temp.

  dtostrf(ee, 0, 0, RemoteXY.text_8);           // Big turbo WG

  dtostrf(me, 0, 0, RemoteXY.text_9);           // Small turbo WG

  dtostrf(mm, 0, 0, RemoteXY.text_7);           // Engine Rpm
  

  
//____________________________________________________________________________________________
                                                 // Вентилятор
  FANconact = sensorValue5;
  FANconact = map(FANconact, 0 , 1023, 0 , 10);
  FANconval = mp2_tem[FANconact];
  FANconval =  constrain(FANconval , 0 , 99);

  FANact = et;
  FANact = map(FANact, 70 , 120, 0 , 10);
  FANval = Yp_tem[FANact]; 
  FANval =  constrain(FANval , 0 , 99);
  if (FANval > FANconval){FANval1 = FANval;}
  else{FANval1 = FANconval;}
  FANval2 = FANval1 * fedr;
  
  analogWrite (FANout, FANval2);
//________________________________________________________________________________________________
                         //Коррекция положения геометрии МАЛЕНЬКОЙ турбины, по положению педали газа
  mapact = te;                                                    
  mapact = map(mapact, 0 , 100, 0 , 35);           
  mapact1 = mpm  [mapact];
//_____________________________________________________________________________________________________________________________________________________________________
                        // Данные АЦП аналоговых датчиков. Используются только на время калиброви датчиков
  
    //Serial.print("                          value TPS adc ");
    //Serial.println(sensorValue3);
    
    //Serial.print("                                     Exhaust pres.sens adc ");
    //Serial.println(sensorValue);
    
    //Serial.print("                                                                     Coll.Temp: ");
    //Serial.println(sensorValue4);
    
    //Serial.print("                                                                                           FANcon: ");
    //Serial.println(sensorValue5); 
    
    //Serial.print("                                                                                        Big turbo moap sens acp:    ");
    //Serial.println(sensorValue2);
    
    //Serial.print("                                                                                        Датчик давления во впускном коллекторе acp:    ");
    //Serial.println(sensorValue1);
  
/////////////////////////////////////////////////
  Wact = temp4;
  Wact = map(Wact, 0 , 4.5, 0 , 35);
  Wval = r[Wact];
  Wval =  constrain(Wval , 0 , 99);
  Wval1 = Wval * fedr;
  analogWrite (Wout, Wval1);
 
//////////////////////////////////////////////////
  
  PWM2act = temp2;
  PWM2act = map(PWM2act, 0 , 4.5, 0 , 35);
  PWM2val = rp[PWM2act];
  PWM2val =  constrain(PWM2val , 0 , 99);
  PWM2val1 = PWM2val * fedr;
  analogWrite (PWM2out, PWM2val1);
//////////////////////////////////////////////////

  mact = temp2;
  mact = map(mact, 0 , 4.5, 0 , 35);
  Mval = m[mact];
  Mval =  constrain(Mval , 0 , 99);
  Mval1 = Mval;
  
///////////////////////////////////////////////////
  rpmact = temp;
  rpmact = map(rpmact, 0 , 5.0, 0 , 35);
  PWMval = rpm[rpmact];
  PWMval =  constrain(PWMval , 0 , 100);
  PWMval1 = PWMval + mapact1 + Mval1;
  PWMval1 =  constrain(PWMval1 , 0 , 99);
  PWMval2 = PWMval1 * fedr;
  analogWrite (PWMout, PWMval2);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //  Процедура сброса ардуино,при загрузке скетча через блютус
 if (Serial.available() > 0) {  
    // Если обнаружен ASCII Cod - Space / пробел - "32".
    // Если подать LOW на pin-RESET Arduino, произойдёт перезагрузка.
    if (Serial.read() == 32)pinMode(2, OUTPUT); // 2-pin соединён с pin-RESET Arduino NANO
  }   

}

 

kasper007
Offline
Зарегистрирован: 23.05.2016

А почему не получилось и программировать и работать через один и тот же интерфейс BT? Я подозреваю, что вы все таки имели ввиду то, что вы одновременно в одном программном интерфейсе не можете поочередно выполнять управление и при необходимости калибровку. Правильно ли я понял?

Я делал в одном из проектов следующим образом:

1. Разделил все передаваемые пакеты по классам. Т.е. есть пакет управления, есть пакет калибровки. Каждый из пакетов начинается со своего кодового слова. В самом программном интерфейсе ввел переключатель (калибровка/управление). В зависимости от выбранного положения все пакеты маркируеются сначала своим кодовым словам.

2. На приемной части сначала идет разбор заголовка пакета - это управление или это калибровка. И для каждого из них свой алгоритм выполнения.

В таком виде очень просто и управляется и если нужно калибруются какие-нибудь параметры.

 

Liske
Offline
Зарегистрирован: 27.06.2016

Я имел в виду заливку скетча, через аппаратный порт, и интерфес (данные плюс управление), через софтварный. Все передается через один общий модуль блютус (uart). Без каких либо разделений по пакетам и без конфликтов.

Liske
Offline
Зарегистрирован: 27.06.2016

Программы для редактирования скетча и просмотра данных/управления, естественно разные. Поэтому единственным обязательным условием, является необходимость отключиться от одной программы, перед тем как использовать другую..  На практике, получилось очень удобное устройство, для прграмирования которого, не нужен физический контакт. Мечта строителей самоходячих роботов..))

Liske
Offline
Зарегистрирован: 27.06.2016

Всем доброго времени суток! Прошел еще год, но мой проект жив и продолжает развиваться. За год удалось достичь серьезных результатов по мощностным показателям двигателя и его отказоустойчивости. Из нововвидений; добавил функчию дата логера и пришлось добавить управление еще одним перепускным клапаном для турбин. Дата логер получился очень прикольный и удобный. Логи сохраняются в виде csv файлов. Для просмотра можно использовть https://www.efianalytics.com/MegaLogViewer/download/ . Но что бы двигаться дальше, необходимо еще лучше дорабатывать систему управления. В настоящий момент я уже практически полностью исчерпал ресурсы Ардуино Нано. Не осталось свободных выводов и памяти. Уже заказана новая плата Мега про мини и вся периферия для нее. Но есть одна большая проблема - это недостаток моих знаний и опыта в программировании. Я знаю, какими должны получиться функции, но я не знаю как это правильно реализовать. В прошлом году мне очень сильно помогли некоторые участники этого форума. Очень надеюсь и в будущем услышать какие то советы. 

Ну а сейчас перейду к конкретике: Очень хочется реализовать возможность в онлайне, через последовательный порт, изменять настройки. В сети есть примеры подобных решений, но к сожалению мой уровень знаний пока не позволяет мне понять все ньюансы. По этому прошу помощи. Вот собственно мой актуальный код: 

//////////////////////////////////////////////////////////      Small turbo ssettings (VGT turbo)  /////////////////////////////////////////////////////////////////
// Position of the geometry small turbo at exhaust pressure. Values from -100 to 100%.
// Large values - increase the valve signal and increase the boost pressure. 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int rpm [] =   {  90, 88, 86, 85, 75, 73, 68, 63, 60, 57, 54, 51, 48, 45, 42, 39, 36, 33, 31, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13,};
//Exh/intake press.0 bar                       1                               2                           3                           4                       5 bar
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//                                  VGT correction at large turbo pressure. Values from -100 to 100%.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int rpm_2[] =   {  25, 24, 23, 22, 20, 18, 16, 14, 12, 10,  8,  6,  4,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,};
//Large turbo press.0 bar                                   1                                       2                                       3                  3,5 bar                         
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////                           VGT correction at trottle   -100% to 100%
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int vgt_at_tps[]={  0,-11,-12,-13,-14,-15,-14,-12,-10, -8, -6, -4,  -2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  4,  7, 10, 13, 15, 16, 17, 15, 17, 17, 17,};
//Trottle pos.      0%                         20%                          40%                         60%                         80%                        100%
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


                                    // WG in the exhaust manifold
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int WG_1pos[] =   {  90, 97, 96, 95, 94, 93, 92, 91, 90, 89, 74, 71, 68, 65, 62, 59, 56, 53, 50, 47, 45, 43, 41, 39, 37, 35, 33, 31, 29, 27, 25, 23, 21, 18, 15, 11,};
//Exh/intake press.   1 bar                       2                               3                           4                           5                       6 bar
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                                         ///  Big turbo WG at big turbo pressure
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int big_t_trg[] ={  98, 97, 96, 95, 94, 93, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 85, 80, 75, 70, 64, 60, 57, 54, 51, 49, 47, 44, 40, 35, 25,  5,  0,  0,  0,  0,};
//Large turbo press. 0 bar                                   1                                       2                                       3                  3,5 bar 

const byte averageFactor_ext = 20;  // Exthaus pressure sensor average factor  (0 = not smooth)
const byte averageFactor     =  4;  // Intake manifold and big turbo pressure sensor average factor (0 = not smooth)

#define REMOTEXY_MODE__HC05_SOFTSERIAL
       
#include <SoftwareSerial.h> 
#include <CyberLib.h>
#include <RemoteXY.h> 

/* connection settings */          // Use BT module HC-06 Transmission speed of BT module 57600
#define REMOTEXY_SERIAL_RX 7        // <--- Connected to pin D1 with arduino and pin TXD bluetooth module
#define REMOTEXY_SERIAL_TX 8        // <--- Connected to the RXD pin of the bluetooth module and through a 2-kΩ resistor, with pin D0 arduino
#define REMOTEXY_SERIAL_SPEED 57600  // Connection speed (default is 9600)
                                    // D2-pin is connected to pin-RESET Arduino NANO

/* interface configuration  */ 
#pragma pack(push, 1) 
uint8_t RemoteXY_CONF[] = 
  { 255,8,0,85,0,19,3,6,0,4,
  7,13,50,32,25,8,3,2,3,1,
  1,30,32,16,8,1,2,115,97,118,
  101,0,1,1,82,18,12,9,2,2,
  62,0,3,5,0,22,9,40,2,2,
  1,1,30,18,12,9,2,2,60,0,
  67,6,33,6,32,15,3,3,4,67,
  6,69,6,31,15,3,3,4,67,6,
  69,27,31,13,3,3,4,67,6,86,
  57,13,5,3,3,4,67,6,65,57,
  13,5,3,3,4,67,6,69,16,8,
  5,2,3,5,67,5,31,3,62,9,
  3,2,17,67,5,47,18,30,8,3,
  2,8,67,6,87,48,13,5,3,3,
  4,67,5,50,48,25,7,3,2,5,
  67,6,42,48,13,5,3,3,5,67,
  6,33,27,32,13,3,3,5,67,6,
  42,57,13,5,3,3,4,67,6,65,
  48,13,5,3,3,4,67,6,33,16,
  8,5,2,3,4,67,6,69,35,8,
  5,2,3,4,129,0,34,2,29,4,
  8,3,98,105,103,32,116,117,114,98,
  111,32,98,111,111,115,116,0,129,0,
  70,23,11,4,8,3,101,120,104,97,
  117,115,116,32,112,114,101,115,115,117,
  114,101,0,129,0,87,45,16,3,8,
  3,99,111,111,108,46,102,97,110,32,
  37,0,129,0,70,2,27,4,8,3,
  98,111,111,115,116,32,40,105,110,116,
  97,107,101,41,0,129,0,33,12,5,
  3,8,3,98,97,114,0,129,0,69,
  12,5,3,8,3,98,97,114,0,129,
  0,69,31,5,3,8,3,98,97,114,
  0,130,1,31,1,36,21,0,3,130,
  1,68,1,34,21,0,3,130,1,68,
  22,34,19,0,3,129,0,86,54,16,
  3,8,3,119,97,116,101,114,32,105,
  110,106,46,37,0,129,0,43,23,11,
  4,8,3,116,114,111,116,116,108,101,
  0,129,0,37,45,19,3,8,3,98,
  105,103,32,116,117,114,98,111,32,87,
  71,37,0,129,0,37,54,19,3,8,
  3,115,109,46,116,117,114,98,111,32,
  86,71,84,37,0,130,1,31,22,36,
  19,0,3,129,0,63,54,18,3,8,
  3,101,110,103,46,32,116,101,109,112,
  46,67,0,130,1,31,43,71,20,0,
  3,131,0,3,8,23,8,2,2,115,
  101,116,116,105,110,103,115,0,131,1,
  3,0,23,8,2,3,103,97,117,103,
  101,0,129,0,50,13,21,4,0,2,
  115,116,111,114,101,100,32,100,97,116,
  97,0,129,0,50,27,21,4,0,2,
  105,110,112,117,116,32,102,114,97,109,
  101,0,129,0,10,24,17,4,8,2,
  98,105,103,32,116,117,114,98,111,0,
  129,0,10,32,17,4,8,2,115,109,
  46,116,117,114,98,111,0,129,0,10,
  40,15,4,8,2,99,111,111,108,46,
  102,97,110,0,129,0,10,48,17,4,
  8,2,102,117,110,99,116,105,111,110,
  0,130,1,46,17,32,10,9,2,130,
  1,48,31,27,10,11,2,130,1,30,
  2,64,11,9,2,129,0,10,56,17,
  4,8,2,115,101,110,115,46,99,97,
  108,105,98,0,130,1,30,1,66,56,
  0,2,130,1,49,31,27,10,1,2,
  130,1,46,17,32,10,9,2,130,1,
  30,2,64,11,9,2,129,0,50,43,
  24,4,0,2,115,101,110,115,46,97,
  100,99,47,118,97,108,0,130,1,49,
  47,27,9,9,2,129,0,10,59,7,
  4,0,2,97,100,99,0,129,0,34,
  32,3,3,8,3,37,0,129,0,63,
  45,17,3,8,3,69,120,46,109,97,
  110,46,87,71,0,129,0,41,18,7,
  3,8,3,109,97,120,32,0,129,0,
  77,18,7,3,8,3,109,97,120,32,
  0,129,0,77,37,7,3,8,3,109,
  97,120,32,0 }; 
   
// структура определяет все переменные вашего интерфейса управления  
struct { 

    // input variable
  float data_input;
  uint8_t safe_but; // =1 если кнопка нажата, иначе =0 
  uint8_t men_butt_2; // =1 если кнопка нажата, иначе =0 
  uint8_t select_menu; // =0 если переключатель в положении A, =1 если в положении B, =2 если в положении C, ... 
  uint8_t menu_but_1; // =1 если кнопка нажата, иначе =0 

    // output variable
  char text[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_3[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_4[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_6[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_10[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_11[5];  // =строка UTF8 оканчивающаяся нулем 
  char menu_text[17];  // =строка UTF8 оканчивающаяся нулем 
  char data_text[8];  // =строка UTF8 оканчивающаяся нулем 
  char text_1[4];  // =строка UTF8 оканчивающаяся нулем 
  char adc[5];  // =строка UTF8 оканчивающаяся нулем 
  char text_7[5];  // =строка UTF8 оканчивающаяся нулем 
  char text_2[5];  // =строка UTF8 оканчивающаяся нулем 
  char text_5[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_12[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_13[4];  // =строка UTF8 оканчивающаяся нулем 
  char text_14[4];  // =строка UTF8 оканчивающаяся нулем 

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY; 
#pragma pack(pop)  


///////////////////////////////////////////// 
//           END RemoteXY include          // 
///////////////////////////////////////////// 
/*the first measured value is the first point */           //Calibration of the large turbine pressure sensor (in Bar)
#define SENS_3_VAL 100    ///// ADC = Volt * 204.8                    
#define SENS_3_TMP 0.0    ////  BAR ////////////
/*the second measured value is the second point */ 
#define SENS_4_VAL 808    ///// ADC = Volt * 204.8
#define SENS_4_TMP 6.0    ////  BAR ////////////
//______________________________
/*the first measured value is the first point */
#define SEN_1_VAL 37    ///// ADC = Volt * 204.8                   //Calibrating the Intake Manifold Pressure Sensor (Bar)
#define SEN_1_TMP 0.0   ////  BAR /////////////
/* the second measured value is the second point */ 
#define SEN_2_VAL 987   ///// ADC = Volt * 204.8
#define SEN_2_TMP 5.0   ////  BAR /////////////

//__________________________________________________________________________________________________________________________________________________
#define   A0  // Analog Input of the integrated pressure sensor in the intake manifold. Sensor pinout: 1-signal, 2-mass, 3- + 5v
#define   A1  // Analog input of the request for the activation of the air conditioning fan (output from the engine ECU)       
 
                       
#define   A4  // Analog input of the engine temperature sensor.    
#define   A5  // Analog input of the large turbine pressure sensor. 
#define   A6  // Analog input engine load (accelerator pedal sensor)
#define   A7  // Аналоговый вход Exhaust pressure sensor
  //      pin D0      // BT
  //      pin D1      // BT
  //      pin D2      // Output for hardware reset, when loading firmware via bluetooth channel (connected with reset)    
#define FANout 3      // PWM Cooling fan output (outputs 3, 11 245.10Hz)
 //         D4         Engine RPM  
#define   Wout 5      // Exit to water/methanol injection pump                      
                      //
  //       pin D7     // BT
  //       pin D8     // BT
#define  PWMout 9     // PWM output for a small turbo solenoid.
#define PWM2out 10    // PWM Large turbine solenoid output. (outputs 9, 10 = 30.64Hz) 
                      // (PWM 245.10Гц)
                      //
                      // 
byte i,
 flag_but_1,
 flag_but,
 wg_1_pwm,
 incomingByte;                      
int sensorValue,
 sensorValue1,
 sensorValue2,
 sensorValue3,
 sensorValue4,
 sensorValue5,
 sensorValue6,
 wg,
 
 FANval1,
 FANval2,
 PWMval2,
 PWMval3,
 PWMval4,
 PWMval,
 Mval1,
 rpmact,
 rpmact_2,
 Output_1,
 rpmact_3,
 rpmact_4,
 rpmact_5,
 Wval1,
 W_start_d,
 menu_but_flag=1,
 set_time,
      
       
 oldsensorValue,
 oldsensorValue_ext,
 oldsensorValue1,
 oldsensorValue2,
 oldrpmact,
 oldrpmact_2,
 oldrpmact_4,
 oldrpmact_3;
 double// Setpoint_11,Setpoint_1,Input_1,Output_1,
 //Input_flag, 
 fedr = 2.53;             //  Variable uncle Fyodor (son of Uncle Magnet and brother of Conus ..) To calculate interest from PWM and back /       
 float boost_tps_st,
 boost_tps_f,
 con_set_1,
 con_set_2,
 fan_set_1,
 fan_set_2,
 wat_set_1,
 wat_set_2,
 wat_t_adc_2,
 wat_t_adc_1,
 wat_t_temp_1,
 wat_t_temp_2,
 ext_press_1,
 ext_press_2,
 ext_adc_1,
 ext_adc_2,
 TPS_adc_1,
 TPS_adc_2,
 TPSval_1,
 TPSval_2,
 wg_1_bit,
 speed_reg,
 max_boost_big,
 max_exht,
 max_boost;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {RemoteXY_Init ();
  
  D3_Out;          // Fan
  D5_Out;          // Water
  D9_Out;          // WG
  D10_Out;         // WG
  D13_Out;         // Wg_1


// Примечание; ячейка памяти 11 умерла.. :(
speed_reg = (ReadEEPROM_Byte(12) - 100);

fan_set_1= (ReadEEPROM_Byte(22) );
fan_set_2= (ReadEEPROM_Byte(23) );
con_set_1= (ReadEEPROM_Byte(24)*4);
con_set_2= (ReadEEPROM_Byte(25)*4);
max_boost= (ReadEEPROM_Byte(26)* 0.1);
max_boost_big= (ReadEEPROM_Byte(76)* 0.1);
max_exht= (ReadEEPROM_Byte(77)* 0.1);
wat_set_1= (ReadEEPROM_Byte(27)* 0.1);
wat_set_2= (ReadEEPROM_Byte(28)* 0.1);
W_start_d= (ReadEEPROM_Byte(6));
wat_t_adc_1= (ReadEEPROM_Byte(29)*4);
wat_t_adc_2= (ReadEEPROM_Byte(30)*4);
wat_t_temp_1= (ReadEEPROM_Byte(31));
wat_t_temp_2= (ReadEEPROM_Byte(32));
ext_adc_1= (ReadEEPROM_Byte(33) * 4);
ext_press_1= (ReadEEPROM_Byte(34) /20.0);
ext_adc_2= (ReadEEPROM_Byte(35) * 4);
ext_press_2= (ReadEEPROM_Byte(36) /20.0);
TPS_adc_1= (ReadEEPROM_Byte(37) * 4);
TPSval_1= (ReadEEPROM_Byte(38));
TPS_adc_2= (ReadEEPROM_Byte(39) * 4);
TPSval_2= (ReadEEPROM_Byte(40));
boost_tps_st= (ReadEEPROM_Byte(41));
boost_tps_f= (ReadEEPROM_Byte(42));


i = 0;          
UART_Init(57600);   // Arduino Speeds == 57600   
TCCR1B = TCCR1B & 0b11111000 | 0x05;
TCCR2B = TCCR2B & 0b11111000 | 0x06;
}
void loop() {RemoteXY_Handler ();
   
   ///////////////////////////////////////////////////////////////////////////////////////////////////////
                 
 oldsensorValue1 = sensorValue1;        //  Intake manifold pressure 
 sensorValue1 = A0_Read;
 if (averageFactor > 0){        // averaging readings to eliminate "jumps"
 sensorValue1 = (oldsensorValue1 * (averageFactor - 1) + sensorValue1) / averageFactor;  //<new mean> = (<old average> * 19 + <current value>) / 20 
 }
 sensorValue5 = A1_Read;        //  Air conditioning request     
         
 sensorValue4 = A4_Read;        //  Temp.
 
 oldsensorValue2 = sensorValue2;
 sensorValue2 = A5_Read;        //  Pressure of a large turbo 
 if (averageFactor > 0)  {      // averaging readings to eliminate "jumps"
 sensorValue2 = (oldsensorValue2 * (averageFactor - 1) + sensorValue2) / averageFactor; // <new mean> = (<old average> * 19 + <current value>) / 20
  }  
 sensorValue3 = A6_Read;        //  Trottle
 
 oldsensorValue_ext = sensorValue;
 sensorValue =  A7_Read;        //  Exthaus pressure
 if (averageFactor_ext > 0)  {      // averaging readings to eliminate "jumps"
 sensorValue = (oldsensorValue_ext * (averageFactor_ext - 1) + sensorValue) / averageFactor_ext; // <new mean> = (<old average> * 19 + <current value>) / 20
  }  


   
          double exth_bar = ext_press_1 + (ext_press_2 - ext_press_1) /  
           (ext_adc_2 - ext_adc_1) * (sensorValue- ext_adc_1);                    // Exthaus pressure
           exth_bar = constrain(exth_bar , 0 , 10);


           double bigturbo_bar = SENS_3_TMP + (SENS_4_TMP - SENS_3_TMP) /  
           (SENS_4_VAL - SENS_3_VAL) * (sensorValue2 - SENS_3_VAL);               // Pressure of a large turbo 
           bigturbo_bar = constrain(bigturbo_bar , 0 , 5);

         
           double intake_bar = SEN_1_TMP + (SEN_2_TMP - SEN_1_TMP) /  
           (SEN_2_VAL - SEN_1_VAL) * (sensorValue1- SEN_1_VAL);                   // Intake manifold pressure
            
           double te = TPSval_1 + (TPSval_2 - TPSval_1) /                 
             (TPS_adc_2 - TPS_adc_1) * (sensorValue3- TPS_adc_1);                  // Trottle
              te =  constrain(te , 0 , 99); 
              
           double et = wat_t_temp_1 + (wat_t_temp_2 - wat_t_temp_1) /           
            (wat_t_adc_2 - wat_t_adc_1) * (sensorValue4- wat_t_adc_1);              // Temp
                
         double fan_act = 100/(fan_set_2-fan_set_1)*(et - fan_set_1);               // Fan
         fan_act= constrain(fan_act , 0 , 100);

         double fan_con = 100/(con_set_2-con_set_1)*(sensorValue5 - con_set_1);     // Cond
         fan_con= constrain(fan_con , 0 , 100);

         double wat_act = 100/(wat_set_2-wat_set_1)*(intake_bar - wat_set_1);       //  Water/methanol  injection
         wat_act = constrain(wat_act,(0),(100));

     /////////////////////////////////////////////////////////////////////////////////////////////////////
                  //Menu 1 (Large turbo)
                                  
  if(RemoteXY.men_butt_2 == 1 && flag_but == 0){++menu_but_flag; flag_but = 1;}                // Circle menu
  if(RemoteXY.men_butt_2 == 0){flag_but = 0;}
  
  if(RemoteXY.menu_but_1 ==1 &&flag_but_1 ==0){menu_but_flag = menu_but_flag -1; flag_but_1 =1;}
  if(RemoteXY.menu_but_1 ==0){flag_but_1 =0;}
  menu_but_flag = constrain(menu_but_flag, 0 , 20);
  
  if(RemoteXY.select_menu==0)   {dtostrf(0, 0, 0, RemoteXY.adc); menu_but_flag = 1;    // Limits the menu in the menu circle 1 (Large turbo)
  if(menu_but_flag ==0){menu_but_flag =1;}
  
  
  if (menu_but_flag ==1){sprintf  (RemoteXY.menu_text, "WG +/- corr");  dtostrf(speed_reg,0, 0, RemoteXY.data_text );
  if (RemoteXY.safe_but!=0){speed_reg = RemoteXY.data_input; speed_reg = constrain(speed_reg, -100 , 100);  WriteEEPROM_Byte(12, speed_reg +100);}}}
  if (bigturbo_bar >= max_boost_big){max_boost_big = bigturbo_bar;WriteEEPROM_Byte(76,max_boost_big*10);}
///////////////////////////////////////////////////////////////////////////////////////
                                           // Menu 2 (small turbo)
                                           
  //if(RemoteXY.select_menu==1)    {sprintf  (RemoteXY.menu_text, "pres.s.ex-0 in-1");dtostrf(sens_sel, 0, 0, RemoteXY.data_text );  
  //if (RemoteXY.safe_but!=0){sens_sel = RemoteXY.data_input; sens_sel = constrain(sens_sel, 0 , 1);  WriteEEPROM_Byte(21, sens_sel);}}
///////////////////////////////////////////////////////////////////////////////////////
                // Menu 2 (Fan)
                
  if(RemoteXY.select_menu==2)   {if (menu_but_flag >4){menu_but_flag = 1;}    // Limits the menu in a circle
  if(menu_but_flag ==0){menu_but_flag =4;} 
  
  if (menu_but_flag==1){sprintf(RemoteXY.menu_text, "fan.start gr.C");dtostrf(fan_set_1, 0, 0, RemoteXY.data_text);dtostrf(et, 0, 0, RemoteXY.adc); 
  if (RemoteXY.safe_but!=0){fan_set_1 = RemoteXY.data_input; fan_set_1 = constrain(fan_set_1, 0 , 140);  WriteEEPROM_Byte(22, fan_set_1);}} 
  if (menu_but_flag==2){sprintf(RemoteXY.menu_text, "fan.full gr.C");dtostrf(fan_set_2, 0, 0, RemoteXY.data_text);dtostrf(et, 0, 0, RemoteXY.adc);  
  if (RemoteXY.safe_but!=0){fan_set_2 = RemoteXY.data_input; fan_set_2 = constrain(fan_set_2, 0 , 140);  WriteEEPROM_Byte(23, fan_set_2);}}
  if (menu_but_flag==3){sprintf(RemoteXY.menu_text, "con.start adc");dtostrf(con_set_1, 0, 0, RemoteXY.data_text);dtostrf(sensorValue5, 0, 0, RemoteXY.adc);  
  if (RemoteXY.safe_but!=0){con_set_1 = RemoteXY.data_input; con_set_1 = constrain(con_set_1, 0 , 1020);  WriteEEPROM_Byte(24, con_set_1 /4);}}
  if (menu_but_flag==4){sprintf(RemoteXY.menu_text, "con.full adc");dtostrf(con_set_2, 0, 0, RemoteXY.data_text);dtostrf(sensorValue5, 0, 0, RemoteXY.adc);
  if (RemoteXY.safe_but!=0){con_set_2 = RemoteXY.data_input; con_set_2 = constrain(con_set_2, 0 , 1020);   WriteEEPROM_Byte(25, con_set_2 /4);}}}
  
////////////////////////////////////////////////////////////////////////////////////////////
                   //function
 if(RemoteXY.select_menu==3)   {if (menu_but_flag >4){menu_but_flag = 1;}    // Limits the menu in a circle
  if(menu_but_flag ==0){menu_but_flag =4;} 
  
  if (menu_but_flag==1){sprintf(RemoteXY.menu_text, "W.inj.start bar");dtostrf(wat_set_1, 0, 1, RemoteXY.data_text);dtostrf(Wval1, 0, 0, RemoteXY.adc);  
  if (RemoteXY.safe_but!=0){wat_set_1 = RemoteXY.data_input; wat_set_1 = constrain(wat_set_1, 0.0 , 6.0);  WriteEEPROM_Byte(27, wat_set_1*10);}} 
  if (menu_but_flag==2){sprintf(RemoteXY.menu_text, "W.inj.full bar");dtostrf(wat_set_2, 0, 1, RemoteXY.data_text);dtostrf(Wval1, 0, 0, RemoteXY.adc);   
  if (RemoteXY.safe_but!=0){wat_set_2 = RemoteXY.data_input; wat_set_2 = constrain(wat_set_2, 0.0 ,9.0);  WriteEEPROM_Byte(28,wat_set_2*10);}}
  if (menu_but_flag==3){sprintf(RemoteXY.menu_text, "W.inj.start duty");dtostrf(W_start_d, 0, 0, RemoteXY.data_text);dtostrf(Wval1, 0, 0, RemoteXY.adc);   
  if (RemoteXY.safe_but!=0){W_start_d = RemoteXY.data_input; W_start_d = constrain(W_start_d, 0 ,100);  WriteEEPROM_Byte(6,W_start_d);}}
 // if (menu_but_flag==4){sprintf(RemoteXY.menu_text, "boost/TPS start");dtostrf(boost_tps_st, 0, 0, RemoteXY.data_text);dtostrf(te, 0, 0, RemoteXY.adc);  
  //if (RemoteXY.safe_but!=0){boost_tps_st = RemoteXY.data_input;boost_tps_st = constrain(boost_tps_st, 0,99);  WriteEEPROM_Byte(41, boost_tps_st);}} 
 // if (menu_but_flag==5){sprintf(RemoteXY.menu_text, "boost/TPS full");dtostrf(boost_tps_f, 0, 0, RemoteXY.data_text);dtostrf(Setpoint_11, 0, 1, RemoteXY.adc);   
 // if (RemoteXY.safe_but!=0){boost_tps_f = RemoteXY.data_input; boost_tps_f = constrain(boost_tps_f,0,99);  WriteEEPROM_Byte(42,boost_tps_f);}}
  if (menu_but_flag==4){sprintf  (RemoteXY.menu_text, "max boost reset");dtostrf(max_boost, 0, 1, RemoteXY.data_text );dtostrf(intake_bar, 0, 1, RemoteXY.adc);  
  if (RemoteXY.safe_but!=0){max_boost = 0;WriteEEPROM_Byte(26,max_boost);max_boost_big = 0;WriteEEPROM_Byte(76,max_boost_big);
   max_exht = 0;WriteEEPROM_Byte(77,max_exht);}}}
  if (intake_bar >= max_boost){max_boost = intake_bar;WriteEEPROM_Byte(26,max_boost*10);}
  if (exth_bar >= max_exht){max_exht = exth_bar;WriteEEPROM_Byte(77,max_exht*10);}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                                                                     //Sensor Calibrations
 if(RemoteXY.select_menu==4)   {if (menu_but_flag >12){menu_but_flag = 1;}    // Limits the menu in a circle
  if(menu_but_flag ==0){menu_but_flag =12;} 
  if (menu_but_flag==1){sprintf(RemoteXY.menu_text, "wat.tem.volt 1");dtostrf((wat_t_adc_1/204.8), 0, 2, RemoteXY.data_text);dtostrf((sensorValue4/204.8), 0, 2, RemoteXY.adc); 
  if (RemoteXY.safe_but!=0){wat_t_adc_1 = RemoteXY.data_input*204.8; WriteEEPROM_Byte(29, wat_t_adc_1/4);}} 
  if (menu_but_flag==2){sprintf(RemoteXY.menu_text, "wat.temp 1");dtostrf(wat_t_temp_1, 0, 0, RemoteXY.data_text);dtostrf(et, 0, 0, RemoteXY.adc);    
  if (RemoteXY.safe_but!=0){wat_t_temp_1 = RemoteXY.data_input; WriteEEPROM_Byte(31,wat_t_temp_1);}}
  if (menu_but_flag==3){sprintf(RemoteXY.menu_text, "wat.tem.volt 2");dtostrf((wat_t_adc_2/204.8), 0, 2, RemoteXY.data_text);dtostrf((sensorValue4/204.8), 0, 2, RemoteXY.adc);    
  if (RemoteXY.safe_but!=0){wat_t_adc_2 = RemoteXY.data_input*204.8; WriteEEPROM_Byte(30,wat_t_adc_2/4);}} 
  if (menu_but_flag==4){sprintf(RemoteXY.menu_text, "wat.temp 2");dtostrf(wat_t_temp_2, 0, 0, RemoteXY.data_text);dtostrf(et, 0, 0, RemoteXY.adc);    
  if (RemoteXY.safe_but!=0){wat_t_temp_2 = RemoteXY.data_input;  WriteEEPROM_Byte(32,wat_t_temp_2);}}
  if (menu_but_flag==5){sprintf(RemoteXY.menu_text, "ext.pres.volt 1");dtostrf((ext_adc_1/204.8), 0, 2, RemoteXY.data_text);dtostrf((sensorValue/204.8), 0, 2, RemoteXY.adc);   
  if (RemoteXY.safe_but!=0){ext_adc_1 = RemoteXY.data_input*204.8; WriteEEPROM_Byte(33, ext_adc_1/4);}} 
  if (menu_but_flag==6){sprintf(RemoteXY.menu_text, "ext.pres.bar 1");dtostrf(ext_press_1, 0, 1, RemoteXY.data_text);dtostrf(exth_bar, 0, 1, RemoteXY.adc);   
  if (RemoteXY.safe_but!=0){ext_press_1 = RemoteXY.data_input; WriteEEPROM_Byte(34,ext_press_1*20);}}
  if (menu_but_flag==7){sprintf(RemoteXY.menu_text, "ext.pres.volt 2");dtostrf((ext_adc_2/204.8), 0, 2, RemoteXY.data_text);dtostrf((sensorValue/204.8), 0, 2, RemoteXY.adc);    
  if (RemoteXY.safe_but!=0){ext_adc_2 = RemoteXY.data_input*204.8; WriteEEPROM_Byte(35,ext_adc_2/4);}}
  if (menu_but_flag==8){sprintf(RemoteXY.menu_text, "ext.pres.bar 2");dtostrf(ext_press_2, 0, 1, RemoteXY.data_text);dtostrf(exth_bar, 0, 1, RemoteXY.adc);   
  if (RemoteXY.safe_but!=0){ext_press_2 = RemoteXY.data_input; WriteEEPROM_Byte(36,ext_press_2*20);}}
  if (menu_but_flag==9){sprintf(RemoteXY.menu_text, "TPS.adc 1");dtostrf(TPS_adc_1, 0, 0, RemoteXY.data_text);dtostrf(sensorValue3, 0, 0, RemoteXY.adc);  
  if (RemoteXY.safe_but!=0){TPS_adc_1 = RemoteXY.data_input; WriteEEPROM_Byte(37, TPS_adc_1/4);}} 
  if (menu_but_flag==10){sprintf(RemoteXY.menu_text, "TPS.pos.1");dtostrf(TPSval_1, 0, 0, RemoteXY.data_text);dtostrf(te, 0, 0, RemoteXY.adc);   
  if (RemoteXY.safe_but!=0){TPSval_1 = RemoteXY.data_input; WriteEEPROM_Byte(38,TPSval_1);}}
  if (menu_but_flag==11){sprintf(RemoteXY.menu_text, "TPS.adc 2");dtostrf(TPS_adc_2, 0, 0, RemoteXY.data_text);dtostrf(sensorValue3, 0, 0, RemoteXY.adc);   
  if (RemoteXY.safe_but!=0){TPS_adc_2 = RemoteXY.data_input;  WriteEEPROM_Byte(39,TPS_adc_2/4);}}
  if (menu_but_flag==12){sprintf(RemoteXY.menu_text, "TPS.pos.2");dtostrf(TPSval_2, 0, 0, RemoteXY.data_text);dtostrf(te, 0, 0, RemoteXY.adc);   
  if (RemoteXY.safe_but!=0){TPSval_2 = RemoteXY.data_input;  WriteEEPROM_Byte(40,TPSval_2);}}}                    
////////////////////////////////////////////////////////////////////////////////////////////
//                                                Charge level switch.
 // if (select_1_val != RemoteXY.select_1){ WriteEEPROM_Byte(5,RemoteXY.select_1);   
 // select_1_val = RemoteXY.select_1; } 
/////////////////////////////////////////////////////////////////////////////////////////// 

  dtostrf(bigturbo_bar, 0, 1, RemoteXY.text);         // Pressure of a large turbine
 
  dtostrf(intake_bar, 0, 1, RemoteXY.text_3);            // Intake manifold pressure

  dtostrf(FANval1, 0, 0, RemoteXY.text_1);          // Fan output 0-100%
  
  dtostrf(exth_bar, 0, 1, RemoteXY.text_4);              // exthaus pressure

  dtostrf((Wval1/fedr), 0, 0, RemoteXY.text_6);      // Water/methanol injection

  dtostrf(max_boost, 0, 1, RemoteXY.text_11);         // Maximum reached boost value

  dtostrf(max_boost_big, 0, 1, RemoteXY.text_13);     // Maximum reached big turbo boost value

  dtostrf(max_exht, 0, 1, RemoteXY.text_14);         // Maximum reached boost value

  dtostrf(et, 0, 0, RemoteXY.text_10);                // Temp.

  dtostrf((Output_1 / fedr), 0, 0, RemoteXY.text_7);   // Big turbo WG

  dtostrf((PWMval2 / fedr), 0, 0, RemoteXY.text_5);   // Small turbo WG

  dtostrf(te, 0, 1, RemoteXY.text_2);                  // Trottle  

  dtostrf(Output_1/fedr, 0, 0, RemoteXY.text_12);                // Ext.manif.WG
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                              Fan                                        
  if (fan_act > fan_con){FANval1 = fan_act;}
  else{FANval1 = fan_con;}
  FANval2 = FANval1 * 2;
  FANval2 = constrain(FANval2,15,240);
  analogWrite (FANout, FANval2);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                              Water/methanol injection
  if(wat_act < (W_start_d-5)){Wval1=0;}
  if(wat_act > W_start_d){Wval1 = wat_act * fedr;}
  analogWrite (Wout, Wval1);
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //intake_bar = 1.9;  // Test                                                 //Big turbo!
// bigturbo_bar = 0.5;  // Test
 
  rpmact_5 = bigturbo_bar * 100;                           
  rpmact_5 = map(rpmact_5, 0 , 340, 0 , 35);            /////  Position by big turbo pressure
  Output_1 =  big_t_trg[rpmact_5]; 

  Output_1 = (Output_1 + speed_reg)*fedr ;
  Output_1 = constrain(Output_1,0, 250); 
  
 
 analogWrite(PWM2out, Output_1);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//exth_bar = 0.0;  // Test                                                        // Smoll turbina
  //te  = 10;
 
 // if(sens_sel!=0){Input_flag = intake_bar;}
 // else{Input_flag = exth_bar;}
 
  rpmact = exth_bar *100;                             ///// Position by pressure in intake or in the exhaust 
 rpmact = map(rpmact, 0 , 500, 0 , 35);
 PWMval = rpm[rpmact]; 

  rpmact_2 = bigturbo_bar * 100;                           
  rpmact_2 = map(rpmact_2, 0 , 340, 0 , 35);            /////  Position by big turbo pressure
  PWMval3 =  rpm_2[rpmact_2]; 
  
  rpmact_4 = te ;                                       //// Correction of trottle position   
  rpmact_4 = map(rpmact_4, 0 , 100, 0 , 35);  
  PWMval4 =  vgt_at_tps[rpmact_4]; 
 
   
  PWMval2 = (PWMval + PWMval3+ PWMval4 ) * fedr;
  PWMval2 =  constrain(PWMval2 , 0 , 250);
  analogWrite (PWMout, PWMval2);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 wg = exth_bar *100;                             ///// WG_1 position by exhaust pressure  
 wg = map(wg, 100 , 600, 0 , 35);
 wg_1_bit = WG_1pos[wg]; 
 wg_1_bit = constrain(wg_1_bit,0, 100);
 wg_1_bit = wg_1_bit /5;
 wg_1_pwm ++;
 if(wg_1_pwm <= wg_1_bit){D13_High;}
 else {D13_Low;}
 if(wg_1_pwm == 20){wg_1_pwm = 0;}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(RemoteXY.connect_flag ==0){       //  Reset
 
UART_ReadByte(incomingByte);
if(incomingByte == 32) {D2_Out; delay(99);}

if(incomingByte == 108){        //   "l" start signal from loger
  D8_In;  
if(i<1){
  Serial.println();
  Serial.print("Bigturbo bar,TPS,Intake press.Bar,Water injection,Exthaus pressure,VGT,Wat.temp,Cool.fan,Big turbo WG,Fan to cond.,Ext.man_WG");
  Serial.println();
  i++;}}
  
if(i>0){
if(i == 3){
  
  Serial.print(bigturbo_bar);                  // Bigturbo bar
  Serial.print(",");
  Serial.print(te);                    //  TPS%
  Serial.print(",");
  Serial.print(intake_bar);               // Intake press. Bar
  Serial.print(",");
  Serial.print(Wval1/fedr,0);          // Water inj
  Serial.print(",");
  Serial.print(exth_bar);                 // Exthaus pressure
  Serial.print(","); 
  Serial.print(PWMval2 / fedr,0);       // VGT
  Serial.print(",");
  Serial.print(et,0);                    // Water temp.
  Serial.print(",");
  Serial.print(FANval1,0);               // Cool.fan %
  Serial.print(",");
  Serial.print(Output_1 / fedr,0);       // Big turbo WG
  Serial.print(",");
  Serial.print(fan_con,0);             // Cond.fan_con
  Serial.print(",");
  Serial.println(wg_1_bit*5,0);          // Ex.manifold WG         Output_1
          
  
 //Serial.print(",");
 //Serial.print();
  // Serial.println();
   
}
i++; 
if(i == 35){i = 3;}                    //  30 - Speed of transfer data updting 
}
}

}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Liske пишет:

мой проект жив и продолжает развиваться. За год удалось достичь серьезных результатов по мощностным показателям двигателя и его отказоустойчивости.

Из гаража удалось выехать, не заглохнув? 

Liske
Offline
Зарегистрирован: 27.06.2016

DetSimen пишет:

Liske пишет:

мой проект жив и продолжает развиваться. За год удалось достичь серьезных результатов по мощностным показателям двигателя и его отказоустойчивости.

Из гаража удалось выехать, не заглохнув? 

Да, удалось)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Прагрес.

Liske
Offline
Зарегистрирован: 27.06.2016

DetSimen пишет:

Прагрес.

В слове "прогресс" две ошибки..  

Liske
Offline
Зарегистрирован: 27.06.2016

DetSimen пишет:

Из гаража удалось выехать, не заглохнув? 

https://youtu.be/mX8FVFxZQUQ

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

del