Цитата:
	
	
		| 
					Сообщение от Langdan  Скинь код, пожалуйста, чего то я с калибровкой разобраться не могу, походу что то не так делаю( | 
	
 В помощь 
https://lesson.iarduino.ru/page/urok...6050-k-arduio/
http://forumdvrobot.ru/forum/3-41-
//
#include <IRremote.h> 
#include <OneWire.h>
#include <SPI.h>
#include <EEPROM.h>
//>>>- GY521
#include <Wire.h> 
#include "Kalman.h"
#include "MPU6050.h"
#include "I2Cdev.h"
Kalman kalmanX;
Kalman kalmanY;
double accXangle; // Angle calculate using the accelerometer
double accYangle;
MPU6050 accelgyro; 
int16_t ax, ay, az; 
int16_t gx, gy, gz;
uint32_t timer; 
//<<<- GY521
 
#define RES_KEY_FLAG_ 0x76  // Флаг первого запуска скетча
byte bytes[4];
//-----------------------------------------
//- входы(пины) ардуино                   -
//-----------------------------------------
int WIRE_PIN = 4;       // цифровой вход(пин) 1WIRE-шины ( температурные датчики )
int RECV_PIN = 7;       // цифровой вход(пин) ИК приемника 
int REG_SELECT = 8 ;    // цифровой вход(пин), управляющий защёлкой (SS в терминах SPI)
int xpin=0;             // аналоговый вход(пин) для оси X акселерометра
int ypin=1;             // аналоговый вход(пин) для оси Y акселерометра
int zpin=2;             // аналоговый вход(пин) для оси Z акселерометра
int ENCODER1_PIN = 6 ;  // аналоговый вход(пин) для первого энкодера
int ENCODER2_PIN = 7 ;  // аналоговый вход(пин) для второго энкодера 
int RES_PIN = 1 ;       // аналоговый вход(пин) для резестивных(рулевых) кнопок 
//-----------------------------------------
//- переменные включения функций скетча   -
//-----------------------------------------
boolean is_ir_key = false;
boolean is_temperature_sensors = false;
boolean is_accelerometer = false;
boolean is_encoder_1 = false;
boolean is_encoder_2 = false;
boolean is_res_keys = false;
boolean is_relay_state = false;
//-----------------------------------------
//- Переменные для температурных датчиков -
//-----------------------------------------
OneWire  ds(WIRE_PIN);
byte addr[8];            
byte data[12];
unsigned long temperature_sensors_milles;
unsigned long temperature_sensors_wait_milles = 500; // Интервал передачи данных от температурных датчиков
//-----------------------------------------
//- Переменные для ИК датчика             -
//-----------------------------------------
IRrecv irrecv(RECV_PIN); 
decode_results results; 
unsigned long ir_dt;
unsigned long ir_dt_old = 0;
unsigned long ir_dt_millis;
unsigned long ir_wait_millis;
unsigned long ir_wait_first = 250;  // время ожидания после первого нажатия кнопки
unsigned long ir_wait_next = 200;    // время ожидания при удержании
//-----------------------------------------
//- Переменные для акселерометра          -
//-----------------------------------------
int x, y, z;
int xyz[4];
int n=0; 
int x_cal=0;
int y_cal=0; //калибровка датчика
int z_cal=0;
unsigned long accelerometer_milles;
unsigned long accelerometer_wait_milles = 80; // Интервал передачи данных от акселерометра
//-----------------------------------------
//- Переменные для первого энкодера       -
//-----------------------------------------
unsigned long encoder1_dt;
unsigned long encoder1_key=0;
unsigned long encoder1_key_old=0;
int encoder1_key1 = 0;
int encoder1_key2 = 0;
int encoder1_key3 = 0;
unsigned long encoder1_millis;
unsigned long encoder1_wait_millis=1;
unsigned long encoder1_key_wait = 500;  // время ожидания до следующего нажатия кнопки энкодера
unsigned long encoder1_key_wait_millis;
unsigned long encoder1_key_millis;
unsigned long encoder1_dt_sum = 0;  
int encoder1_dt_n = 0;
//-----------------------------------------
//- Переменные для второго энкодера       -
//-----------------------------------------
unsigned long encoder2_dt;
unsigned long encoder2_key=0;
unsigned long encoder2_key_old=0;
int encoder2_key1 = 0;
int encoder2_key2 = 0;
int encoder2_key3 = 0;
unsigned long encoder2_millis;
unsigned long encoder2_wait_millis=1;
unsigned long encoder2_key_wait = 500;  // время ожидания до следующего нажатия кнопки энкодера
unsigned long encoder2_key_wait_millis;
unsigned long encoder2_key_millis;
//-----------------------------------------
//- Переменные для резестивных кнопок     -
//-----------------------------------------
unsigned long  res_dt = 0; 
unsigned long  res_dt_sum=0; 
#define RES_DT_COUNT 500 // Количество считываемых данных
#define RES_DT_SKIP_COUNT 100 // Количество данных, которые надо пропустить при нажатии
#define RES_DT_POINT 6 // Точность
int res_dt_n = 0;
unsigned long res_key=0;
unsigned long res_key_old=0;
unsigned long res_key_wait_first = 500;  // время ожидания после первого нажатия кнопки
unsigned long res_key_wait_next = 250;  // время ожидания до следующего нажатия кнопки
unsigned long res_key_wait_millis = 0;
unsigned long res_key_millis;
unsigned long res_key_array[51][2];
unsigned int res_key_count = 0;
unsigned int res_key_delta = 3;
//-----------------------------------------
//- Переменные для управления блоком реле -
//-----------------------------------------
unsigned long relays_milles ;
unsigned long  relays_wait_milles = 1000;
static uint8_t relays_state1 = 0x0000;
static uint8_t relays_state2 = 0x0000;
static uint8_t relays_state3 = 0x0000;
static uint8_t relays_state4 = 0x0000;
  
void setup() 
{ 
  //>>>- GY521
   Wire.begin();
   accelgyro.initialize();
   kalmanX.setAngle(180); // Set starting angle 
   kalmanY.setAngle(180);
   timer = micros();
   //<<<- GY521
  Serial.begin(115200); 
  irrecv.enableIRIn(); // включить приемник 
    xyz[0]=0;
    xyz[1]=0; // прочитать значение осей
    xyz[2]=0;
    ir_wait_millis = ir_wait_first;
    accelerometer_milles = millis();
    temperature_sensors_milles = millis();
    encoder1_key_millis = millis();
    encoder2_key_millis = millis();
    encoder1_millis = millis();
    encoder2_millis = millis();
    res_key_millis = millis();
    relays_milles = millis();
    
    encoder1_key_wait_millis=encoder1_key_wait;
    encoder2_key_wait_millis=encoder2_key_wait;
    
    unsigned int first_run_key = EEPROM.read(0);
    if ( first_run_key == RES_KEY_FLAG_ )
    {
      res_key_count = EEPROM.read(1);
      //EEPROM.write(addr, val);
      for(int i=0; i<res_key_count;i++) 
      { 
        res_key_array[i][0] = (EEPROM.read(i+2) * 256) + EEPROM.read(i+2+50) - res_key_delta; res_key_array[i][1] = res_key_array[i][0] + res_key_delta + res_key_delta; 
      }
    }
    for(int i=res_key_count; i<51;i++) 
    { 
      res_key_array[i][0] = 0xFFFFFFFF; res_key_array[i][1] = 0xFFFFFFFF; 
    }
    
    // Инициализируем шину SPI. Если используется программная реализация,
    // то вы должны сами настроить пины, по которым будет работать SPI.
    SPI.begin();
    pinMode(REG_SELECT, OUTPUT);
    digitalWrite(REG_SELECT, LOW); // выбор ведомого - нашего регистра
    SPI.transfer(relays_state4); // очищаем содержимое регистра
    SPI.transfer(relays_state3);
    SPI.transfer(relays_state2);
    SPI.transfer(relays_state1);
    // Завершаем передачу данных. После этого регистр установит
    // на выводах Q0-Q7 уровни, соответствующие записанным битам.
    digitalWrite(REG_SELECT, HIGH);
}
 
void loop() 
{
  if (Serial.available() >= 1) // Проверяем наличие команд от компьютера
  {
     switch (Serial.read())
    {
     case 0x01: // включить передачу данных от ик-пульта
       is_ir_key = true;
     break;
     case 0x02: // включить передачу данных от датчиков температуры
       is_temperature_sensors = true;
     break;
     case 0x03: // включить передачу данных от акселерометра
       is_accelerometer = true;
     break;
     case 0x04: // включить передачу данных от первого энкодера
       is_encoder_1 = true;
     break;
     case 0x05: // включить передачу данных от второго экнодера
       is_encoder_2 = true;
     break;
     case 0x06: // включить передачу данных от резестивных кнопок
       is_res_keys = true;
     break;
     case 0x07: // включить передачу данных о состоянии реле
       is_relay_state = true;
     break;
     case 0x17: // восстановить состояние реле
     {
       relays_state1 = EEPROM.read(211);
       relays_state2 = EEPROM.read(212);
       relays_state3 = EEPROM.read(213);
       relays_state4 = EEPROM.read(214);
       digitalWrite(REG_SELECT, LOW);
       SPI.transfer(relays_state4);
       SPI.transfer(relays_state3);
       SPI.transfer(relays_state2);
       SPI.transfer(relays_state1);
       digitalWrite(REG_SELECT, HIGH);
       bytes[0] = 0xBF;          // преобразовать в 4-байта  
       bytes[1] = 0xFF;  
       bytes[2] = 0xFF; 
       bytes[3] = 0xFF; 
       Serial.write( bytes,4); // отправить прочитаное значение компьютеру
       bytes[0] = relays_state4;          // преобразовать в 4-байта  
       bytes[1] = relays_state3;  
       bytes[2] = relays_state2; 
       bytes[3] = relays_state1; 
       Serial.write( bytes,4); // отправить прочитаное значение компьютеру
     }
     break;
     case 0x81: // выключить передачу данных от ик-пульта
       is_ir_key = false;
     break;
     case 0x82: // выключить передачу данных от датчиков температуры
       is_temperature_sensors = false;
     break;
     case 0x83: // выключить передачу данных от акселерометра
       is_accelerometer = false;
     break;
     case 0x84: // выключить передачу данных от первого энкодера
       is_encoder_1 = false;
     break;
     case 0x85: // выключить передачу данных от второго энкодера
       is_encoder_2 = false;
     break;
     case 0x86: // выключить передачу данных от резестивных кнопок
       is_res_keys = false;
     break;
     case 0x87: // выключить передачу данных от резестивных кнопок
       is_relay_state = false;
     break;
     case 0x27: // сохранить текущее состояние реле и отключить их
     {
       EEPROM.write(211,relays_state1);
       EEPROM.write(212,relays_state2);
       EEPROM.write(213,relays_state3);
       EEPROM.write(214,relays_state4);
       relays_state1 = 0;
       relays_state2 = 0;
       relays_state3 = 0;
       relays_state4 = 0;
       digitalWrite(REG_SELECT, LOW);
       SPI.transfer(relays_state4);
       SPI.transfer(relays_state3);
       SPI.transfer(relays_state2);
       SPI.transfer(relays_state1);
       digitalWrite(REG_SELECT, HIGH);
       bytes[0] = 0xBF;          // преобразовать в 4-байта  
       bytes[1] = 0xFF;  
       bytes[2] = 0xFF; 
       bytes[3] = 0xFF; 
       Serial.write( bytes,4); // отправить прочитаное значение компьютеру
       bytes[0] = relays_state4;          // преобразовать в 4-байта  
       bytes[1] = relays_state3;  
       bytes[2] = relays_state2; 
       bytes[3] = relays_state1; 
       Serial.write( bytes,4); // отправить прочитаное значение компьютеру
     }
     break;
     case 0xAA: // выключить передачу данных от резестивных кнопок
     {
       while (Serial.available() < 5) {}
       int i = Serial.read();
       bytes[0] = Serial.read();          // преобразовать в 4-байта  
       bytes[1] = Serial.read();  
       bytes[2] = Serial.read(); 
       bytes[3] = Serial.read(); 
       unsigned long key_res_min = 0; key_res_min = bytes[0]; key_res_min = key_res_min * 256 + bytes[1];  
       unsigned long key_res_max = 0; key_res_max = bytes[2]; key_res_max = key_res_max * 256 + bytes[3];  
       res_key_array[i-1][0] = key_res_min; 
       res_key_array[i-1][1] = key_res_max;
     }
     break;
     case 0xAB: // сбросить настройки резестивных кнопок в EEPROM
     {
       EEPROM.write(0,0); // сбросить флаг первого запуска
       res_key_count = 0; // сбросить количество резистивных кнопок 
       EEPROM.write(1,0); //
       for(int i=0; i<51;i++) 
       { 
        res_key_array[i][0] = 0xFFFFFFFF; res_key_array[i][1] = 0xFFFFFFFF; 
       }
     } 
     break;
     case 0xBB: // Команда управление реле
     {
       while (Serial.available() < 2) {}
       byte relay_number = Serial.read();
       byte relay_command = Serial.read();
       if( relay_number == 0 && relay_command == 0xFF )
       {
          bytes[0] = 0xBF;          // преобразовать в 4-байта  
          bytes[1] = 0xFF;  
          bytes[2] = 0xFF; 
          bytes[3] = 0xFF; 
          Serial.write( bytes,4); // отправить прочитаное значение компьютеру
          bytes[0] = relays_state4;          // преобразовать в 4-байта  
          bytes[1] = relays_state3;  
          bytes[2] = relays_state2; 
          bytes[3] = relays_state1; 
          Serial.write( bytes,4); // отправить прочитаное значение компьютеру
       }
       else
       {
         uint8_t one = 1 ;
         switch (relay_command)
         {
           case 0x00: // выключить реле № relay_number
           if(relay_number <=8)
           {
             relays_state1 = relays_state1 & ~( one << (relay_number - 1) );
           }
           else
           {
             if(relay_number <=16)
             {
               relays_state2 = relays_state2 & ~( one << (relay_number - 9) );
             }
             else
             {
               if(relay_number <=24)
               {
                 relays_state3 = relays_state3 & ~( one << (relay_number - 17) );
               }
               else
               {
                 if(relay_number <=32)
                 {
                   relays_state4 = relays_state4 & ~( one << (relay_number - 25) );
                 }
               }
             }
           }
           digitalWrite(REG_SELECT, LOW);
           SPI.transfer(relays_state4);
           SPI.transfer(relays_state3);
           SPI.transfer(relays_state2);
           SPI.transfer(relays_state1);
           digitalWrite(REG_SELECT, HIGH);
            bytes[0] = 0xBF;          // преобразовать в 4-байта  
            bytes[1] = 0xFF;  
            bytes[2] = 0xFF; 
            bytes[3] = 0xFF; 
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру
            bytes[0] = relays_state4;          // преобразовать в 4-байта  
            bytes[1] = relays_state3;  
            bytes[2] = relays_state2; 
            bytes[3] = relays_state1; 
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру
           break;
           case 0x01: // включить реле № relay_number
           if(relay_number <=8)
           {
             relays_state1 = relays_state1 | ( one << (relay_number - 1) );
           }
           else
           {
             if(relay_number <=16)
             {
               relays_state2 = relays_state2 | ( one << (relay_number - 9) );
             }
             else
             {
               if(relay_number <=24)
               {
                 relays_state3 = relays_state3 | ( one << (relay_number - 17) );
               }
               else
               {
                 if(relay_number <=32)
                 {
                   relays_state4 = relays_state4 | ( one << (relay_number - 25) );
                 }
               }
             }
           }
           digitalWrite(REG_SELECT, LOW);
           SPI.transfer(relays_state4);
           SPI.transfer(relays_state3);
           SPI.transfer(relays_state2);
           SPI.transfer(relays_state1);
           digitalWrite(REG_SELECT, HIGH);
            bytes[0] = 0xBF;          // преобразовать в 4-байта  
            bytes[1] = 0xFF;  
            bytes[2] = 0xFF; 
            bytes[3] = 0xFF; 
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру
            bytes[0] = relays_state4;          // преобразовать в 4-байта  
            bytes[1] = relays_state3;  
            bytes[2] = relays_state2; 
            bytes[3] = relays_state1; 
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру
           break;
         }
       }
     }
     break;
    }
  } 
  if( is_ir_key ) ir_key();                            //  ИК приёмник
  if( is_temperature_sensors ) temperature_sensors();  //  температурные датчики
  if( is_accelerometer ) accelerometer();              //  акселерометр
  if( is_encoder_1 ) encoder_1();                      //  первый энкодер
  if( is_encoder_2 ) encoder_2();                      //  второй энкодер
  if( is_res_keys ) res_keys();                        //  резестивные кнопки
  if( is_relay_state ) relay_state();
}
//----------------------------------------------------------------------------------
// Функция работы с реле
//----------------------------------------------------------------------------------
void relay_state()
{
  if( relays_milles + relays_wait_milles < millis() )
  {
    bytes[0] = 0xBF;          // преобразовать в 4-байта  
    bytes[1] = 0xFF;  
    bytes[2] = 0xFF; 
    bytes[3] = 0xFF; 
    Serial.write( bytes,4); // отправить прочитаное значение компьютеру
    bytes[0] = relays_state4;       // преобразовать в 4-байта  
    bytes[1] = relays_state3;  
    bytes[2] = relays_state2; 
    bytes[3] = relays_state1; 
    Serial.write( bytes,4); // отправить прочитаное значение компьютеру
    relays_milles = millis();
  }
}
//----------------------------------------------------------------------------------
// Функция работы с резестивными кнопками
//----------------------------------------------------------------------------------
void res_keys()
{  
  {
    res_dt = analogRead(RES_PIN); // прочитать данные АЦП 
    if( res_dt >= 0x05 && res_dt <= 0x3F0 )
    { 
      res_dt_n++;
      if( res_dt_n > RES_DT_SKIP_COUNT )
      {
        res_dt_sum += (res_dt << RES_DT_POINT);
        if( res_dt_n == RES_DT_COUNT)
        { 
          res_key = (res_dt_sum / (RES_DT_COUNT - RES_DT_SKIP_COUNT));
          res_key = (((((( res_dt_sum / (( RES_DT_COUNT - RES_DT_SKIP_COUNT ) + (2^(RES_DT_POINT-1)-1) ) >> (RES_DT_POINT-1)) + 1) >> 1) + 1)>> 1)); // + 1) >> 1;
          res_dt_sum = 0; res_dt_n = 0;
        }
       }
    }
    else
    {
      res_dt_sum = 0; res_dt_n = 0; res_key = 0;
      res_key_wait_millis = 0;
    }
  }
  if( res_key_millis + res_key_wait_millis*2 <= millis() ) { res_key_old = 0; }
  if( res_key_millis + res_key_wait_millis <= millis() )
  {
    if( res_key != 0 )
    {
      if( ((res_key_old - res_key_delta) <=  res_key) && (res_key <= (res_key_old + res_key_delta)) )
      {
        res_key_millis = millis(); res_key_wait_millis = res_key_wait_next;
      }
      else
      {
        res_key_millis = millis(); res_key_wait_millis = res_key_wait_first;
      }
        int i = 0; int exit = 0;
        while( res_key_array[i][0] != 0xFFFFFFFF && exit == 0 )
        {
          if( (res_key_array[i][0] <= res_key) && (res_key <= res_key_array[i][1]) ) exit = 1; else i++;
        }
        if( exit == 1 ) 
        { 
          bytes[0] = 0xAA;          // преобразовать в 4-байта  
          bytes[1] = 0;  
          bytes[2] = RES_PIN; 
          bytes[3] = i+1; 
          Serial.write( bytes,4); // отправить прочитаное значение компьютеру
        }
        else
        {
          if( res_key_count < 50 )
          {
            res_key_array[res_key_count][0] = res_key - res_key_delta; res_key_array[res_key_count][1] = res_key + res_key_delta;
            res_key_count++;
            
            EEPROM.write(1, res_key_count); // Запоминаем количество кнопок
            byte one_byte = res_key / 256;
            EEPROM.write(res_key_count+1, one_byte ); // Запоминаем старший байт значения кнопки
            one_byte = res_key - one_byte * 256;
            EEPROM.write(res_key_count+1+50, one_byte ); // Запоминаем младший байт значения кнопки
            EEPROM.write(0, RES_KEY_FLAG_);
          
            bytes[0] = 0xAA;          // преобразовать в 4-байта  
            bytes[1] = 0;  
            bytes[2] = RES_PIN; 
            bytes[3] = res_key_count; 
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру
          }
          else
          {
            bytes[0] = 0xAA;          // преобразовать в 4-байта  
            bytes[1] = 0xAA;  
            bytes[2] = (res_key & 0xFF00) >> 8; 
            bytes[3] = res_key & 0xFF; 
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру
          }
        }
    }
    res_key_old = res_key;
  }
}
//----------------------------------------------------------------------------------
// Функция работы с первым энкодером
//----------------------------------------------------------------------------------
void encoder_1()
{
  if( encoder1_key_millis + encoder1_key_wait_millis*2 < millis() ) { encoder1_key_old = 0; }
  if( encoder1_millis + encoder1_wait_millis < millis() )
  {
    encoder1_millis = millis();
    encoder1_dt = analogRead(ENCODER1_PIN); // прочитать данные АЦП
    
    if( encoder1_dt >= 0x246 && encoder1_dt <= 0x286 )
    { // Здесь обрабатываем удержание кнопки
      encoder1_key = ENCODER1_PIN;
      encoder1_key = (encoder1_key << 16) | 0x030000EE;
      if ( encoder1_key == encoder1_key_old )
      { // Здесь обрабатываем удержание кнопки
        if( encoder1_key_millis + encoder1_key_wait_millis < millis() )
        { 
          bytes[0] = encoder1_key & 0xFF;          // преобразовать в 4-байта  
          bytes[1] = (encoder1_key & 0xFF00) >> 8;  
          bytes[2] = (encoder1_key & 0xFF0000) >> 16; 
          bytes[3] = (encoder1_key & 0xFF000000) >> 24;
          Serial.write( bytes,4); // отправить прочитаное значение компьютеру
          encoder1_key_millis = millis(); encoder1_key_wait_millis = encoder1_key_wait; //ir_wait_next;
        }
      }
      else 
      { // Здесь обрабатываем первое нажатие кнопки
        encoder1_key_millis = millis(); encoder1_key_wait_millis = 50; //ir_wait_first;
      } 
      encoder1_key_old = encoder1_key;
    } 
    else
    {
      if( encoder1_dt >= 0x3E0 && encoder1_dt <= 0x410 && encoder1_key3 != 1 )
      {
        if( (encoder1_key2 == 2) && (encoder1_key3 == 3))
        { 
          bytes[0] = 0xEE;          // преобразовать в 2-байта 
          bytes[1] = 0; 
          bytes[2] = ENCODER1_PIN;
          bytes[3] = 1;
          Serial.write( bytes,4); // отправить прочитаное значение компьютеру     
        }
        else
        {
          if( (encoder1_key2 == 3) && (encoder1_key3 == 2) )
          {
            bytes[0] = 0xEE;          // преобразовать в 2-байта 
            bytes[1] = 0; 
            bytes[2] = ENCODER1_PIN;
            bytes[3] = 2;
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру     
          }
        }
        encoder1_key1=encoder1_key2; encoder1_key2=encoder1_key3; encoder1_key3=1;
      }
      else
      {
        if( encoder1_dt >= 0xA0 && encoder1_dt <= 0xF0 && encoder1_key3 != 2 )
        {
          encoder1_key1=encoder1_key2; encoder1_key2=encoder1_key3; encoder1_key3=2;
        }
        else
        {
          if( encoder1_dt >= 0x1A0 && encoder1_dt <= 0x200 && encoder1_key3 != 3 )
          {
            encoder1_key1=encoder1_key2; encoder1_key2=encoder1_key3; encoder1_key3=3;
          }
        }
      }
    }
  }
}
//----------------------------------------------------------------------------------
// Функция работы со вторым энкодером
//----------------------------------------------------------------------------------
void encoder_2()
{  
  if( encoder2_key_millis + encoder2_key_wait_millis*2 < millis() ) { encoder2_key_old = 0; }
  if( encoder2_millis + encoder2_wait_millis < millis() )
  {
    encoder2_millis = millis();
    encoder2_dt = analogRead(ENCODER2_PIN); // прочитать данные АЦП
    if( encoder2_dt >= 0x246 && encoder2_dt <= 0x286 )
    { // Здесь обрабатываем удержание кнопки
      encoder2_key = ENCODER2_PIN;
      encoder2_key = (encoder2_key << 16) | 0x030000EE;
      if ( encoder2_key == encoder2_key_old )
      { // Здесь обрабатываем удержание кнопки
        if( encoder2_key_millis + encoder2_key_wait_millis < millis() )
        { 
          bytes[0] = encoder2_key & 0xFF;          // преобразовать в 4-байта  
          bytes[1] = (encoder2_key & 0xFF00) >> 8;  
          bytes[2] = (encoder2_key & 0xFF0000) >> 16; 
          bytes[3] = (encoder2_key & 0xFF000000) >> 24; 
          Serial.write( bytes,4); // отправить прочитаное значение компьютеру
          encoder2_key_millis = millis(); encoder2_key_wait_millis = encoder2_key_wait; //ir_wait_next;
        }
      }
      else 
      { // Здесь обрабатываем первое нажатие кнопки
        encoder2_key_millis = millis(); encoder2_key_wait_millis = 50; //ir_wait_first;
      } 
      encoder2_key_old = encoder2_key;
    } 
    else
    {
      if( encoder2_dt >= 0x3E0 && encoder2_dt <= 0x410 && encoder2_key3 != 1 )
      {
        if( (encoder2_key2 == 2) && (encoder2_key3 == 3))
        { 
          bytes[0] = 0xEE;          // преобразовать в 2-байта 
          bytes[1] = 0; 
          bytes[2] = ENCODER2_PIN;
          bytes[3] = 1;
          Serial.write( bytes,4); // отправить прочитаное значение компьютеру     
        }
        else
        {
          if( (encoder2_key2 == 3) && (encoder2_key3 == 2) )
          {
            bytes[0] = 0xEE;          // преобразовать в 2-байта 
            bytes[1] = 0; 
            bytes[2] = ENCODER2_PIN;
            bytes[3] = 2;
            Serial.write( bytes,4); // отправить прочитаное значение компьютеру     
          }
        }
        encoder2_key1=encoder2_key2; encoder2_key2=encoder2_key3; encoder2_key3=1;
      }
      else
      {
        if( encoder2_dt >= 0xA0 && encoder2_dt <= 0xF0 && encoder2_key3 != 2 )
        {
          encoder2_key1=encoder2_key2; encoder2_key2=encoder2_key3; encoder2_key3=2;
        }
        else
        {
          if( encoder2_dt >= 0x1A0 && encoder2_dt <= 0x200 && encoder2_key3 != 3 )
          {
            encoder2_key1=encoder2_key2; encoder2_key2=encoder2_key3; encoder2_key3=3;
          }
        }
      }
    }
  }
}
//----------------------------------------------------------------------------------
// Функция работы с ИК приёмником
//----------------------------------------------------------------------------------
void ir_key()
{
  if( ir_dt_millis + ir_wait_millis*2 < millis() ) { ir_dt_old = 0; }
  if (irrecv.decode(&results))  
  {
   if (results.value > 0 && results.value < 0xFFFFFFFF) 
   {
    ir_dt = results.value;
    if ( ir_dt == ir_dt_old )
    { // Здесь обрабатываем удержание кнопки
      if( ir_dt_millis + ir_wait_millis < millis() )
      { 
        bytes[0] = ir_dt & 0xFF;          // преобразовать в 4-байта  
        bytes[1] = (ir_dt & 0xFF00) >> 8;  
        bytes[2] = (ir_dt & 0xFF0000) >> 16; 
        bytes[3] = (ir_dt & 0xFF000000) >> 24; 
        Serial.write( bytes,4); // отправить прочитаное значение компьютеру
        ir_dt_millis = millis(); ir_wait_millis = ir_wait_next;
      }
    }
    else 
    { // Здесь обрабатываем первое нажатие кнопки
      bytes[0] = ir_dt & 0xFF;          // преобразовать в 4-байта  
      bytes[1] = (ir_dt & 0xFF00) >> 8;  
      bytes[2] = (ir_dt & 0xFF0000) >> 16; 
      bytes[3] = (ir_dt & 0xFF000000) >> 24; 
      Serial.write( bytes,4); // отправить прочитаное значение компьютеру
      ir_dt_millis = millis(); ir_wait_millis = ir_wait_first;
    } 
    ir_dt_old = ir_dt;
   }
   else
   {
      ir_dt_millis = millis(); ir_wait_millis = ir_wait_first;
   }
   irrecv.resume();
  }
}
//----------------------------------------------------------------------------------
// Функция работы с акселерометром
//----------------------------------------------------------------------------------
void accelerometer()
{
  if( accelerometer_milles + accelerometer_wait_milles < millis() )
  {
    
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); 
    accelgyro.getAcceleration(&ax, &ay, &az); 
    accelgyro.getRotation(&gx, &gy, &gz); 
    accYangle = (atan2(ax,az)+PI)*RAD_TO_DEG;
    accXangle = (atan2(ay,az)+PI)*RAD_TO_DEG;
    double gyroXrate = (double)gx/131.0;
    double gyroYrate = -((double)gy/131.0);
    
    xyz[0]=kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000);
    xyz[1]=kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000); // прочитать значение осей
    timer = micros();
    xyz[2]=az;
    xyz[3]=0;
    bytes[0] = 0xEF; bytes[1] = 0xFF; bytes[2] = 0xFF; bytes[3] = 0xFF; 
    Serial.write( bytes,4); // отправить 0xEFFFFFFF - код данных от акселерометра
    Serial.write( (byte*)&xyz,8); // отправить значения осей 
    accelerometer_milles = millis();
  }
}
//----------------------------------------------------------------------------------
// Функция определение температуры датчиков DS18B20
//----------------------------------------------------------------------------------
void temperature_sensors()
{
  if( temperature_sensors_milles + temperature_sensors_wait_milles < millis() )
  {
    temperature_sensors_milles = millis();
  
    byte i;
    if (!ds.search(addr)) 
    {                       // поиск нового датчика
      ds.reset_search();    // если не нашли, сбрасываем поиск в начало
      return;               // и выходим 
    }
  
    // Часть кода, которая ниже, выполняется только если
    // найден новый датчик, с которым ещё не работали в
    // главном цикле до сброса поиска
    if (OneWire::crc8( addr, 7) != addr[7]) // Проверка CRC 
    { 
      return; // Если не пройдена, то в начало главного цикла и продолжаем поиск других датчиков
    }
  
    if (addr[0] != 0x28) // Проверка того, что найденное устройство - температурный датчик DS18B20 
    {        
      return; // Если не он, то опять в начало главного цикла на продолжение поиска
    }
  
    ds.reset();
    ds.select(addr);
    ds.write(0x44,1);
    ds.reset();
    ds.select(addr);
    ds.write(0xBE);
    bytes[0] = 0xFF; bytes[1] = 0xFF; bytes[2] = 0xFF; bytes[3] = 0xFF; 
    Serial.write( bytes,4); // отправить 0xFFFFFFFF - код температурного датчика
    Serial.write( addr,8); // отправить 8 байтовый номер температурного датчика 
  
    for ( i = 0; i < 9; i++) // получаем данные с датчика
    {         
      data[i] = ds.read();
    }
    bytes[0] = 0;          // отправляем байты содержащие температуру  
    bytes[1] = 0;  
    bytes[2] = data[0]; 
    bytes[3] = data[1]; 
    Serial.write( bytes,4); // значение температурного датчика 
  }
}