Вопрос по использованию внутреннего таймера в ардуино Нано

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

Доброго всем времяни суток. 

Уже достаточно долго пытаюсь найти ответ через поиск, но конкретно моего случая не нашел :(

А именно: Имеется усртойство на плате Нано, в котором уже используются изменения в работе двух внутренних счетчиков. С помощью этих счетчиков, была достигнута нужная для конкретных условий, частота шим на выходах..  В данный момент, код и все устройство работают хорошо, без каких либо зависаний и задержек.. Но мне реализовать еще одну функцию: считывание и подсчет импульсов (сигнал оборотов двигателя. Частота 250-3500 герц).

Использование milis и delay исключается (что бы не затормозить работу остального кода). Выделение персонального таймера под эти нужды, так же исключено (т.к. два таймера из трех, уже заняты).

И из всего выше сказанного, у меня появилась мысль об использовании частоты таймера 3, как опорной, для сравнения ее с частотой оборотов, посупающей на цифровой вход.

Но как это можо реализовать, я не знаю..(   Может ли кто то подсказать ?

 

Прилагаю свой код. В данной версии кода, сигнал оборотов двигателя не используется...

 

/* Двух канальный буст контроллер, для системы двухступенчатого наддува,на база 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
  }   

}

 

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

Уточню свой вопрос:            Допустим, высокий уровень на входе сигнала оборотов, использовать для обнуления счета. А в качестве опорной частоты, использовать частоту внутреннего счетчика TCCR2B (в моем случае это 245.10 Гц). Каждый цикл программы, в случае появления положительного импульса на TCCR2B,  добавлял бы к некой переменной +1. И так до появления сигнала сброса со входа оборотов (переменная обнуляется и начинается новый отсчет).     

Возможен ли такой алгоритм ? Если да, то как его реализовать на практике ? Как в программе получать частоту от счетчика TCCR2B ?

 

З.Ы.    В первом своем посте, не правильно указал частоту вращения в герцах. Правильная частота соответственно: от 4 до 60 Гц.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Liske, не нужны никакие извращения с таймером2. Вешаете входной сигнал на любое свободное прерывание,  в обработчике прерывания при первом входе создаёте статик-переменную uint32_t,  и вторую uint16_t для подсчёта кол-ва импульсов. В первую кладёте значение миллис (или микрос, в зависимости от частоты), при последующих входах в прерывание сравнивать разницу с миллис, если больше 1 секунды, то поделить дельту времени на кол-во импульсов, и рассчитать частоту. Потом всё обнулить, и так по кругу.

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

dimax пишет:

Liske, не нужны никакие извращения с таймером2. Вешаете входной сигнал на любое свободное прерывание,  в обработчике прерывания при первом входе создаёте статик-переменную uint32_t,  и вторую uint16_t для подсчёта кол-ва импульсов. В первую кладёте значение миллис (или микрос, в зависимости от частоты), при последующих входах в прерывание сравнивать разницу с миллис, если больше 1 секунды, то поделить дельту времени на кол-во импульсов, и рассчитать частоту. Потом всё обнулить, и так по кругу.

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

dimax, а вы могли бы накидать пример, как это должно выглядеть в коде ?  

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Если честно, не понял, как millis() сможет повлиять на скорость выполнения основного кода. И не совсем понял, что мешает повесить источник импульсов, которые нужно считать, на прерывание?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Liske, да пожалста..


volatile float freq;
void setup() {
Serial.begin(9600);
pinMode(3,INPUT); // Input frequency
attachInterrupt(1,fcount, RISING);
}

void loop() {
Serial.println(freq);
 }

void fcount(){
static uint32_t m1=micros();
static int n=0; 
uint32_t m2= micros()-m1;
if( m2 > 1E6) {freq= (float)1E6/(m2/n); n=0; m1=micros(); }
n++;
}//end ISR

 

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

dimax пишет:

Liske, да пожалста..


volatile float freq;
void setup() {
Serial.begin(9600);
pinMode(3,INPUT); // Input frequency
attachInterrupt(1,fcount, RISING);
}

void loop() {
Serial.println(freq);
 }

void fcount(){
static uint32_t m1=micros();
static int n=0; 
uint32_t m2= micros()-m1;
if( m2 > 1E6) {freq= (float)1E6/(m2/n); n=0; m1=micros(); }
n++;
}//end ISR

 


Dimax, вы могли бы прокоментировать как это работает ? Не совсем (мне) понятно, где тут что..

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Liske, ну я же расписал всё в #2, чего же боле, как говорится? :) Может ЕвгенийП подтянется, у него хватает терпения всё разжёвывать, у меня нет ))

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

Сорри dimax.. Тогда попытаюсь как нибудь сам вьехать, зачем к примеру, мне нужно повторно писать функцию Serial.begin(9600), хотя у меня в коде уже есть эта функция, но с другой скоростью..

 

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

dimax пишет:

Liske, да пожалста..


volatile float freq;
void setup() {
Serial.begin(9600);
pinMode(3,INPUT); // Input frequency
attachInterrupt(1,fcount, RISING);
}

void loop() {
Serial.println(freq);
 }

void fcount(){
static uint32_t m1=micros();
static int n=0; 
uint32_t m2= micros()-m1;
if( m2 > 1E6) {freq= (float)1E6/(m2/n); n=0; m1=micros(); }
n++;
}//end ISR

 

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

П.С. Ура ! Заработала ! :) Теперь осталось откалибровать частоту..      Dimax, огромное спасибо !

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

Нет, не работает нормально. Постоянно зависает вся программа на три - четыре секунды. В этот момент на плате перестают мигать индикаторы RX-TX.  Пробовал менять разные значения, но толку особого нет..)

 

#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

//__________________________________________________________________________________________________________________________________________________
//         pin 5      // Выход для апаратного ресета,при загрузке по блютус каналу(соеденен с reset)
#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;
volatile float freq;
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). 
pinMode(3,INPUT); // Input frequency
attachInterrupt(0,fcount, RISING);
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 = freq * 121.12;                                            // Вход оборотов двигателя
           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(6, OUTPUT); // 5-pin соединён с pin-RESET Arduino NANO
  }   
Serial.println(freq);
}
void fcount(){
static uint32_t m1=micros();
static int n=0;
uint32_t m2= micros()-m1;
if( m2 > 1E6) {freq= (float)1E6/(m2/n); n=0; m1=micros(); }
n++;
}//end ISR