Код:
	//#include <SPI.h>
#include <avr/wdt.h>#if DEBUG
#include <SoftwareSerial.h>
#include <TVout.h>
#include <fontALL.h>
#include "pitches.h"
#include <EEPROM.h>
//#include <MsTimer2.h>
#include <TimerFive.h>
#include <IRremote.h>
//**TODO
/*
 */
// Программа для управления контроллером муфты ITM, камерами заднего и бокового видов, кнопками руля и магнитолой автомобиля Chery Tiggo
#define DEBUG 1  // используется при отладке
long MOMENT1=128;
long MOMENT2=224;
long MOM=0;
IRsend irsend;
//long Timer_Time=300000; //mcsec
//boolean at_once=true; // переменная для контроля одноразового выполнения
//Начальная мелодия
/**
int melody[] = {NOTE_C5, NOTE_E5,NOTE_E4, NOTE_C4};
int noteDurations[] = {10,10,10,4};
*/
int melody[] = {NOTE_C5, NOTE_A4,NOTE_F4, NOTE_E5};
int noteDurations[] = {5,15,15,6};
  
volatile unsigned long Speed_ImpulseTime = 0; // время между импульсами датчика скорости
volatile unsigned long Speed_time=0;  // время для отсчета импульсов
volatile int Speed_impulse_count = 0;  // кол-во импульсов датчика скорости
volatile float Speed=0; // скорость с датчика скорости
volatile unsigned long Taho_ImpulseTime = 0; // время между импульсами тахометра
volatile unsigned long Taho_time=0;  // время для отсчета импульсов
volatile int Tahometr_impulse_count = 0;  // кол-во импульсов тахометра
volatile float Taho=0; // обороты двигателя
#define BRAKEVCC 0
#define CW   1
#define CCW  2
#define BRAKEGND 3
#define CS_THRESHOLD 100
char LastGear='0';
char RecommendGear='0';
//*****************ИК порт
#define TOPBIT 0x80000000
#define NEC_HDR_MARK      9000
#define NEC_HDR_SPACE     4500
#define NEC_BIT_MARK       560
#define NEC_ONE_SPACE     1690
#define NEC_ZERO_SPACE     560
#define NEC_BITS 32
#define DUTY_CYCLE         1/3       // Carrier duty cycle
#define PERIOD             26        // 38kHz, 1/38kHz =~ 26us
#define ACTIVE_HIGH       (PERIOD * DUTY_CYCLE)
#define ACTIVE_LOW        (PERIOD - (PERIOD * DUTY_CYCLE))
unsigned long SRC=0x04;   
unsigned long VOLDOWN=0x1F;
unsigned long VOLUP=0x5C;
unsigned long code[96]= {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F}; 
unsigned long codehex[96]= {0xAA00FF, 0xAA807F, 0xAA40BF, 0xAAC03F, 0xAA20DF, 0xAAA05F, 0xAA609F, 0xAAE01F, 0xAA10EF, 0xAA906F, 0xAA50AF, 0xAAD02F, 0xAA30CF, 0xAAB04F, 0xAA708F, 0xAAF00F, 0xAA08F7, 0xAA8877, 0xAA48B7, 0xAAC837, 0xAA28D7, 0xAAA857, 0xAA6897, 0xAAE817, 0xAA18E7, 0xAA9867, 0xAA58A7, 0xAAD827, 0xAA38C7, 0xAAB847, 0xAA7887, 0xAAF807, 0xAA04FB, 0xAA847B, 0xAA44BB, 0xAAC43B, 0xAA24DB, 0xAAA45B, 0xAA649B, 0xAAE41B, 0xAA14EB, 0xAA946B, 0xAA54AB, 0xAAD42B, 0xAA34CB, 0xAAB44B, 0xAA748B, 0xAAF40B, 0xAA0CF3, 0xAA8C73, 0xAA4CB3, 0xAACC33, 0xAA2CD3, 0xAAAC53, 0xAA6C93, 0xAAEC13, 0xAA1CE3, 0xAA9C63, 0xAA5CA3, 0xAADC23, 0xAA3CC3, 0xAABC43, 0xAA7C83, 0xAAFC03, 0xAA02FD, 0xAA827D, 0xAA42BD, 0xAAC23D, 0xAA22DD, 0xAAA25D, 0xAA629D, 0xAAE21D, 0xAA12ED, 0xAA926D, 0xAA52AD, 0xAAD22D, 0xAA32CD, 0xAAB24D, 0xAA728D, 0xAAF20D, 0xAA0AF5, 0xAA8A75, 0xAA4AB5, 0xAACA35, 0xAA2AD5, 0xAAAA55, 0xAA6A95, 0xAAEA15, 0xAA1AE5, 0xAA9A65, 0xAA5AA5, 0xAADA25, 0xAA3AC5, 0xAABA45, 0xAA7A85, 0xAAFA05};  
//*****************ИК порт
volatile unsigned long Time_On=0;
int RearCamNum=1;
#define SignalOn HIGH
#define SignalOff LOW
TVout TV;
boolean mode=false;
char prog_version_major =1;
char prog_version_manor1 =0;
char prog_version_manor2 =0;
int speed_kmh=0;
int taho_obm=0;
//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
////// ********Описание периферии********** ///////////
// Контакт 0 для  - зарезервировано, не использовать!!!
// Контакт 1 для  - зарезервировано, не использовать!!!
#define  TahometrPin 2  // Тахометр - требуется подтяжка, с прерыванием -  ШИМ
#define  SpeedSensorPin 3 // Спидометр - требуется подтяжка, с прерыванием -  ШИМ
#define  HandBrakePin 4 // Ручник - требуется подтяжка
#define  RearGearPin 5 // З.Х. - требуется подтяжка
#define  LeftTurnPin 6 // Лев. пов. - требуется подтяжка
#define  RightTurnPin 7 // Прав. пов. - требуется подтяжка
#define MonsterMoto8 8// Контакт 8 для шилда управления муфты - MONSTER MOTO INB: Counter-clockwise input ШИМ
#define MonsterMoto9 9// Контакт 9 для шилда управления муфты - MONSTER MOTO INB: Counter-clockwise input ШИМ
#define SpeakerPin 10// Контакт 10 для динамика
// Контакт 11 для Tvout Sync ЗАНЯТО!!!!
//Контакт 12-21 СВОБОДНО
#define  FOURxFOURLedPin 22 // Индикатор 4х4
#define  FOURxFOURSwitchPin 23 // Включатель 4х4 (50/50) - требуется подтяжка
#define  AWDSwitchPin 24 // Включатель AWD (70/30) - требуется подтяжка
#define Relay_Camera1_Video_Pin 25// Контакт для реле - Камера З.Х.
#define Relay_Camera2_Video_Pin 26// Контакт для реле - Камера лев.
#define Relay_Camera3_Video_Pin 27// Контакт для реле - Камера прав.
#define Relay_GU_12V_Pin 28// Контакт для реле - 12V питание на ГУ (имитация заднего хода)
// Контакт 29 для Tvout Video ЗАНЯТО!!!!
#define Relay_Camera1_12V_Pin 30// Контакт для реле - питание прав.
#define Relay_Camera2_12V_Pin 31// Контакт для реле - питание лев.
#define Relay_Camera3_12V_Pin 32// Контакт для реле - питание З.Х.
#define Relay_MonsterMoto_12V_Pin 33// Контакт для реле - питание контроллера муфты
#define LCDGearP_Indicate_Pin 34 // Контакт 34 для индикации Передачи P на ЖКИ
#define ModeButtonPin 35// Контакт кнопка-режим
// Контакт 36-37 СВОБОДНО
#define  LCDGear1_Indicate_Pin 38 // Контакт 38 для индикации Передачи 1 на ЖКИ
#define  LCDGear2_Indicate_Pin 39 // Контакт 39 для индикации Передачи 2 на ЖКИ
#define  LCDGear3_Indicate_Pin 40 // Контакт 40 для индикации Передачи 3 на ЖКИ
#define  LCDGear4_Indicate_Pin 41 // Контакт 41 для индикации Передачи 4 на ЖКИ
#define  LCDGearD_Indicate_Pin 42 // Контакт 42 для индикации Передачи D на ЖКИ
#define  LCDGearN_Indicate_Pin 43 // Контакт 43 для индикации Передачи N на ЖКИ
#define  LCDGearR_Indicate_Pin 44 // Контакт 44 для индикации Передачи R на ЖКИ
#define  IRPin 45 // ИК выход
#define MonsterMoto4 46 // Контакт 46 для муфты на шилде MonsterMoto
#define MonsterMoto5 47// Контакт 47 для муфты на шилде MonsterMoto
#define MonsterMoto6 48// Контакт 48 для муфты на шилде MonsterMoto
#define MonsterMoto7 49// Контакт 49 для муфты на шилде MonsterMoto
// Контакт 50 MISO СВОБОДНО
// Контакт 51 MOSI СВОБОДНО
// Контакт 52 SCK СВОБОДНО 
// Контакт 53 SS СВОБОДНО
//аналоговые входы
// Контакт 0-3 СВОБОДНО
#define MonsterMoto0 4//A4 для муфты на шилде MonsterMoto
#define MonsterMoto1 5//A5 для муфты на шилде MonsterMoto
#define MonsterMoto2 6//A6 для муфты на шилде MonsterMoto
#define MonsterMoto3 7//A7 для муфты на шилде MonsterMoto
#define  WheelButtonsPin 8 //A8 // кнопки руля
// Контакт 9-15 СВОБОДНО
// описание контактов шилда Monster Moto
int inApin[2] = {
  MonsterMoto7, MonsterMoto4};  // INA: Clockwise input
int inBpin[2] = {
  MonsterMoto8, MonsterMoto9}; // INB: Counter-clockwise input
int pwmpin[2] = {
  MonsterMoto5, MonsterMoto6}; // PWM input
int cspin[2] = {
  MonsterMoto2, MonsterMoto3}; // CS: Current sense ANALOG input
int enpin[2] = {
  MonsterMoto0, MonsterMoto1}; // EN: Status of switches output (Analog pin)
//описание переменных
//boolean RelayOn = false;
double RPM; 
unsigned long Check_time ; 
// переменные нажатия рулевых кнопок
unsigned long math_time,old_time,real_time, res_dt1, res_d;     
int LIMIT=10;
char ButtonName='X'; // +, -, >, R=>>|, L=|<<, S=SRC, X=None
// переменные нажатия рулевых кнопок - конец
//###################################################################
//общие настройки 
void setup() 
{
  wdt_enable (WDTO_8S); // сторожевой таймер от зависания
  
TV.begin(PAL,120,96);  // 1 ширина, 2 высота
TV.select_font(font6x8); // 1 ширина, 2 высота
TV.clear_screen();
  //*************************Описание пинов**************************
  //Контакт 0 для  - зарезервировано, не использовать!!!
  //Контакт 1 для  - зарезервировано, не использовать!!!
  //Контакт 2  !!!!!!!!!ПРЕРЫВАНИЕ 0
  pinMode(TahometrPin, INPUT); // Контакт для тахометра !!!!!!!!!ПРЕРЫВАНИЕ 0
  digitalWrite(TahometrPin, HIGH); //внутренняя подтяжка входа тахометра 
  attachInterrupt(0, TahometrImpulse_on, FALLING); //RISING);// настройка прерывания и функции на него
  //Контакт 3  !!!!!!!!!ПРЕРЫВАНИЕ 1
  pinMode(SpeedSensorPin, INPUT); // Контакт для датчика скорости !!!!!!!!!ПРЕРЫВАНИЕ 1
  digitalWrite(SpeedSensorPin, HIGH); //внутренняя подтяжка входа датчика скорости 
  attachInterrupt(1, SpeedImpulse_on, FALLING); // настройка прерывания и функции на него
  //Контакт 4
  pinMode(HandBrakePin, INPUT); // Контакт для ручника 
  digitalWrite(HandBrakePin, HIGH); //внутренняя подтяжка входа ручника
  //Контакт 5-7
  pinMode(RearGearPin , INPUT);// Контакт  для сигнала от заднего хода
  digitalWrite(RearGearPin , HIGH); //внутренняя подтяжка входа +++++ 
  pinMode(LeftTurnPin, INPUT);// Контакт  для сигнала от левого поворотника
  digitalWrite(LeftTurnPin, HIGH); //внутренняя подтяжка входа +++++ 
  pinMode(RightTurnPin, INPUT);// Контакт  для сигнала от правого поворотника
  digitalWrite(RightTurnPin, HIGH); //внутренняя подтяжка входа +++++ 
  //Контакт 8-9 MonsterMoto
  for (int i=0; i<2; i++)
  {
    pinMode(inApin[i], OUTPUT);
    pinMode(inBpin[i], OUTPUT);
    pinMode(pwmpin[i], OUTPUT);
  }
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  pinMode(SpeakerPin, OUTPUT); // Контакт 10 для динамика
  //Контакт 11 для TVout
  //Контакт 12-21 СВОБОДНО
  //Контакт 22 Индикатор 4х4
  pinMode(FOURxFOURLedPin, OUTPUT);// Контакт Индикатор 4х4
  //Контакт 23 Включатель 4х4
  pinMode(FOURxFOURSwitchPin, INPUT);// Контакт Включатель 4х4
  digitalWrite(FOURxFOURSwitchPin , HIGH); //внутренняя подтяжка входа +++++ 
  //Контакт 24 Включатель AWD
  pinMode(AWDSwitchPin, INPUT);// Контакт Включатель AWD
  digitalWrite(AWDSwitchPin , HIGH); //внутренняя подтяжка входа +++++ 
  //Контакт 25-28
  pinMode(Relay_Camera1_Video_Pin, OUTPUT);
  pinMode(Relay_Camera2_Video_Pin, OUTPUT);
  pinMode(Relay_Camera3_Video_Pin, OUTPUT);
  pinMode(Relay_GU_12V_Pin, OUTPUT);
  // Контакт 29 для Tvout Video ЗАНЯТО!!!!
  //Контакт 30-33
  pinMode(Relay_Camera1_12V_Pin, OUTPUT);
  pinMode(Relay_Camera2_12V_Pin, OUTPUT);
  pinMode(Relay_Camera3_12V_Pin, OUTPUT);
  pinMode(Relay_MonsterMoto_12V_Pin, OUTPUT);
   //34
  pinMode(LCDGearP_Indicate_Pin, OUTPUT);// Контакт для индикации Передачи P на ЖКИ
  //Контакт 35 кнопка-режим
  pinMode(ModeButtonPin, INPUT);// Контакт кнопка-режим
  digitalWrite(ModeButtonPin , HIGH); //внутренняя подтяжка входа +++++ 
  // Контакт 36-37 СВОБОДНО
  //38
  pinMode(LCDGear1_Indicate_Pin, OUTPUT);// Контакт для индикации Передачи 1 на ЖКИ
  //39
  pinMode(LCDGear2_Indicate_Pin, OUTPUT);// Контакт для индикации Передачи 2 на ЖКИ
  //40
  pinMode(LCDGear3_Indicate_Pin, OUTPUT);// Контакт для индикации Передачи 3 на ЖКИ
  //41
  pinMode(LCDGear4_Indicate_Pin, OUTPUT);// Контакт для индикации Передачи 4 на ЖКИ
  //42
  pinMode(LCDGearD_Indicate_Pin, OUTPUT);// Контакт для индикации Передачи D на ЖКИ
  //43
  pinMode(LCDGearN_Indicate_Pin, OUTPUT);// Контакт для индикации Передачи N на ЖКИ
  //44
  pinMode(LCDGearR_Indicate_Pin, OUTPUT);// Контакт для индикации Передачи R на ЖКИ
   //Контакт 45 ИК выход
  pinMode(IRPin, OUTPUT);
  //46-49 Контакты MonsterMoto
  // Контакт 50 MISO
  // Контакт 51 MOSI 
  // Контакт 52 SCK 
  // Контакт 53 SS 
  //выключаем ЖКИ, камеры и муфту
  Gear_LCD_Clear();
  Cameras_OFF(); 
  motorOff(0);
  motorOff(1);
  //
Startup(); // стартовое приветствие
// MsTimer2::set(1500, Timer2_Timer); // таймер будет срабатывать через каждые 500ms 
// MsTimer2::start();//запустить таймер
 
  Timer5.initialize(5000000);
  Timer5.attachInterrupt(Beep); 
#if DEBUG
Serial.begin(9600);
#endif
}
void Beep(void)
{
  if  ((digitalRead(FOURxFOURSwitchPin)==LOW)|| (digitalRead(AWDSwitchPin)==LOW))// если переключатель в положении 4х4 или Auto
{
TV.tone(NOTE_E5,400);
}
}
// главный цикл
void loop()
{
wdt_reset();
Cameras(); //Работа с камерами
WheelButtons(); //Работа с кнопками руля 
Indicate_Recommended_Gear(Speed); //отображение рекомендуемой передачи на LCD
FOURxFOURButton(); //Работа с переключателем 4x4
ModeButton();//Работа с кнопкой mode
}
boolean notyetdoes=false;
//Работа с кнопкой mode
void ModeButton()
{
  if  (digitalRead(ModeButtonPin)==LOW)
  {
mode=!mode;  
notyetdoes=false;
TV.tone(NOTE_D6,200);
delay(1000);  
  }
  
if (mode) 
{
//TV.begin(PAL,120,96);  // 1 ширина, 2 высота
//TV.select_font(font6x8); // 1 ширина, 2 высота
//TV.clear_screen();
TVoutPrint(); 
}  
if ((!mode) && (!notyetdoes))
{
TV.clear_screen();  
notyetdoes=true;
//TV.end();
}  
}
/*
#define note_len 200000
#define play_c 3830
#define play_d 3400
#define play_e 3038
*/
void Startup() //Стартовое приветствие
{
  for (int thisNote = 0; thisNote < 4; thisNote++) {
    int noteDuration = 1000/noteDurations[thisNote];
    TV.tone(melody[thisNote],noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    TV.delay(pauseBetweenNotes);
    TV.noTone();
  }
}
/*
void Timer2_Timer() //обработка событий в таймере - Работа с статусными событиями в таймере
{
}
*/
  
/*
void playTone(int note) {
  long elapsed_time = 0;
  while (elapsed_time < note_len) {
     digitalWrite(SpeakerPin,HIGH);
     delayMicroseconds(note / 2);
     digitalWrite(SpeakerPin, LOW);
     delayMicroseconds(note / 2);
     elapsed_time += (note);
   }
}
*/
//################################################################### 
//Работа с переключателем 4x4
void FOURxFOURButton()
{
  if  (digitalRead(FOURxFOURSwitchPin)==LOW) // если переключатель в положении 4х4
  {
 digitalWrite(FOURxFOURLedPin, HIGH);
 digitalWrite(Relay_MonsterMoto_12V_Pin, HIGH);
 motorGo(0,CW,MOMENT2);
  }
  
  if  (digitalRead(AWDSwitchPin)==LOW) // если переключатель в положении Auto
  {
 digitalWrite(FOURxFOURLedPin, HIGH);
 digitalWrite(Relay_MonsterMoto_12V_Pin, HIGH);
 
 motorGo(0,CW,MOMENT1);
  }  
if  ((digitalRead(FOURxFOURSwitchPin)==HIGH)&&(digitalRead(AWDSwitchPin)==HIGH)) // если переключатель в положении 4х2
{
  digitalWrite(FOURxFOURLedPin, LOW);
  digitalWrite(Relay_MonsterMoto_12V_Pin, LOW);
  motorOff(0);
}
}
void motorOff(int motor)
{
  // Initialize braked
  for (int i=0; i<2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
  }
  analogWrite(pwmpin[motor], 0);
}
/* motorGo() will set a motor going in a specific direction
 the motor will continue going in that direction, at that speed
 until told to do otherwise.
 
 motor: this should be either 0 or 1, will selet which of the two
 motors to be controlled
 
 direct: Should be between 0 and 3, with the following result
 0: Brake to VCC
 1: Clockwise
 2: CounterClockwise
 3: Brake to GND
 
 pwm: should be a value between ? and 255, higher the number, the faster
 it'll go
 */
void motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
{
  if (motor <= 1)
  {
    if (direct <=4)
    {
      // Set inA[motor]
      if (direct <=1)
        digitalWrite(inApin[motor], HIGH);
      else
        digitalWrite(inApin[motor], LOW);
      // Set inB[motor]
      if ((direct==0)||(direct==2))
        digitalWrite(inBpin[motor], HIGH);
      else
        digitalWrite(inBpin[motor], LOW);
      analogWrite(pwmpin[motor], pwm);
    }
  }
  
#if DEBUG
Serial.print("4x4_PWM=");
Serial.println(pwm); 
#endif
  
}
//################################################################### 
//Работа с кнопками руля
void WheelButtons()
{
char But='X';  
if (WheelButonPush_IsPushed()){ But=ButtonName; }
/*
if (But=='>'){sendNEC(SRC);}
if (But=='-'){sendNEC(VOLDOWN);}
if (But=='+'){sendNEC(VOLUP);}
*/
if (But=='>'){irsend.sendNEC(codehex[SRC], 32);}
if (But=='-'){irsend.sendNEC(codehex[VOLDOWN], 32);}
if (But=='+'){irsend.sendNEC(codehex[VOLUP], 32);}
#if DEBUG
Serial.print("WH_But=");
Serial.println(But); 
#endif
}
//################################################################### 
//Работа с камерами
void Cameras()
{
 int Camera_Num=0;
//boolean Start_Video=false;
if (digitalRead(RearGearPin)==SignalOn) {RearCamNum=1;} // если задняя передача выключена, то установить значение камеры задней =1
if ((digitalRead(RearGearPin)==SignalOff) && (ButtonName=='S')) //если задняя передача включена и нажата кнопка SOURCE, то сменить камеру 
{
RearCamNum++;
if (RearCamNum>3) {RearCamNum=1;}
}
if ((digitalRead(RearGearPin)==SignalOff) && (ButtonName=='L')) //если задняя передача включена и нажата кнопка <<, то сменить камеру левую 
{
RearCamNum=2;
}
if ((digitalRead(RearGearPin)==SignalOff) && (ButtonName=='R')) //если задняя передача включена и нажата кнопка <<, то сменить камеру правую
{
RearCamNum=3;
}
if ((digitalRead(LeftTurnPin)==SignalOn) && (digitalRead(RightTurnPin)==SignalOff)) {Camera_Num=2; Time_On=millis();}
if ((digitalRead(LeftTurnPin)==SignalOff) && (digitalRead(RightTurnPin)==SignalOn)) { Camera_Num=3; Time_On=millis();}
if (digitalRead(RearGearPin)==SignalOff) {Camera_Num=RearCamNum; Time_On=millis();}
if ((digitalRead(LeftTurnPin)==SignalOn) && (digitalRead(RightTurnPin)==SignalOn) && (digitalRead(RearGearPin)==SignalOn)) {Cameras_OFF();}
//if ((digitalRead(LeftTurnPin)==SignalOff) && (digitalRead(RightTurnPin)==SignalOff) && (digitalRead(RearGearPin)==SignalOff)){Cameras_OFF();}
#if DEBUG
//Serial.println(digitalRead(RearGearPin));
#endif
//if ((Start_Video) && (Camera_Num>0)) 
//{
if ((Time_On+1000)>millis()) {Camera_ON(Camera_Num);} //если время после события (поворота или заднего хода) не болле 1 сек, то камеру включить
else {Cameras_OFF();}
//}
//if ((Time_On+1000)<millis())   {Cameras_OFF();}
#if DEBUG
Serial.print("Cam_Num=");
Serial.println(Camera_Num); 
#endif
delay(300);
} 
//гасим ЖКИ  
void Gear_LCD_Clear()
{
  digitalWrite(LCDGear1_Indicate_Pin, LOW);
  digitalWrite(LCDGear2_Indicate_Pin, LOW);
  digitalWrite(LCDGear3_Indicate_Pin, LOW);
  digitalWrite(LCDGear4_Indicate_Pin, LOW);
  digitalWrite(LCDGearD_Indicate_Pin, LOW);
  digitalWrite(LCDGearN_Indicate_Pin, LOW);
  digitalWrite(LCDGearR_Indicate_Pin, LOW);
  digitalWrite(LCDGearP_Indicate_Pin, LOW);
}
/*
//################################################################### 
 void Indicate_Gear_On_LCD(char GearName)
{
Gear_LCD_Clear();  
if (GearName=='1'){digitalWrite(LCDGear1_Indicate_Pin, HIGH);}
if (GearName=='2'){digitalWrite(LCDGear2_Indicate_Pin, HIGH);}
if (GearName=='3'){digitalWrite(LCDGear3_Indicate_Pin, HIGH);}
if (GearName=='4'){digitalWrite(LCDGear4_Indicate_Pin, HIGH);}
if (GearName=='5'){digitalWrite(LCDGearD_Indicate_Pin, HIGH);}
if (GearName=='R'){digitalWrite(LCDGearR_Indicate_Pin, HIGH);}
if (GearName=='N'){digitalWrite(LCDGearN_Indicate_Pin, HIGH);}
}
*/
//###################################################################
void Indicate_Recommended_Gear(float Speed_kmh)
{
  
if (Speed_kmh<=0) {RecommendGear='N';} //  N
if ((Speed_kmh>0) && (Speed_kmh<=7)) {RecommendGear='1';} //    1 
if ((Speed_kmh>10) && (Speed_kmh<=22)) {RecommendGear='2';} //    2
if ((Speed_kmh>25) && (Speed_kmh<=40)) {RecommendGear='3';} //    3
if ((Speed_kmh>43) && (Speed_kmh<=85)) {RecommendGear='4';} //   4
if (Speed_kmh>90) {RecommendGear='D';} //    5
if (digitalRead(RearGearPin)==SignalOff){RecommendGear='R';} // R
if (LastGear!=RecommendGear)
{
if (LastGear=='1'){digitalWrite(LCDGear1_Indicate_Pin, HIGH);}
if (LastGear=='2'){digitalWrite(LCDGear2_Indicate_Pin, HIGH);}
if (LastGear=='3'){digitalWrite(LCDGear3_Indicate_Pin, HIGH);}
if (LastGear=='4'){digitalWrite(LCDGear4_Indicate_Pin, HIGH);}
if (LastGear=='D'){digitalWrite(LCDGearD_Indicate_Pin, HIGH);}
if (LastGear=='N'){digitalWrite(LCDGearN_Indicate_Pin, HIGH);}
if (LastGear=='R'){digitalWrite(LCDGearR_Indicate_Pin, HIGH);}
if (LastGear=='P'){digitalWrite(LCDGearP_Indicate_Pin, HIGH);}
if (RecommendGear=='1'){digitalWrite(LCDGear1_Indicate_Pin, LOW);}
if (RecommendGear=='2'){digitalWrite(LCDGear2_Indicate_Pin, LOW);}
if (RecommendGear=='3'){digitalWrite(LCDGear3_Indicate_Pin, LOW);}
if (RecommendGear=='4'){digitalWrite(LCDGear4_Indicate_Pin, LOW);}
if (RecommendGear=='D'){digitalWrite(LCDGearD_Indicate_Pin, LOW);}
if (RecommendGear=='N'){digitalWrite(LCDGearN_Indicate_Pin, LOW);}
if (RecommendGear=='R'){digitalWrite(LCDGearR_Indicate_Pin, LOW);}
if (RecommendGear=='P'){digitalWrite(LCDGearP_Indicate_Pin, LOW);}
LastGear=RecommendGear;
#if DEBUG
Serial.print("R_GEAR=");
Serial.println(RecommendGear); 
#endif
}  
}
//###################################################################
// обработчик событий тахометра
void  TahometrImpulse_on() //сидит на прерывании 0, срабатывает при возникновении событий на 2 цифровом входе
{ 
//TimeImpulse1=
Tahometr_impulse_count++; //увеличить счетчик импульсов
//Speed=0;
if (Tahometr_impulse_count >=2) //2имп=1 оборот коленвала
  {
Taho_ImpulseTime = micros()-Taho_time;  //время прихода между импульсами
Taho_time = micros(); //обнулить
Taho=((Tahometr_impulse_count*60*1000000)/(2*Taho_ImpulseTime));   // перевод в об/мин, формула универсальна для Тигго, 1 об на 2 ммпульса,1000000 - перевод мкс в сек., 60 - перевод сек в мин.
#if DEBUG
Serial.print("TIT=");
Serial.println(Taho_ImpulseTime);
Serial.print("Taho=");
Serial.println(Taho); 
#endif
Tahometr_impulse_count = 0;
  }  
} 
//###################################################################
// обработчик событий датчика скорости
void  SpeedImpulse_on() //сидит на прерывании 1, срабатывает при возникновении событий на 3 цифровом входе
{ 
//TimeImpulse1=
Speed_impulse_count++; //увеличить счетчик импульсов
//Speed=0;
if (Speed_impulse_count >=2) //2имп=0,8м    5имп=2м
  {
Speed_ImpulseTime = micros()-Speed_time;  //время прихода между импульсами
Speed_time = micros(); //обнулить
Speed=((Speed_impulse_count*2*3.6*1000000)/(5*Speed_ImpulseTime));   // перевод в км/ч, формула универсальна для Тигго, 2=2м за 5 ммпульсов, 3.6 - перевод м/с в км/ч, 1000000 - перевод мкс в сек., 5 - 5 импульсов
#if DEBUG
Serial.print("SIT=");
Serial.println(Speed_ImpulseTime);
Serial.print("Speed=");
Serial.println(Speed); 
#endif
Speed_impulse_count = 0;
  }  
} 
void TVoutPrint()
{
  //TV.clear_screen(); 
  TV.set_cursor(0,0);
  TV.print(" MONSTER IV v1.0.0");
 /*TV.print(prog_version_major);
  TV.print(".");
  TV.print(prog_version_manor1);
  TV.print(prog_version_manor2);*/
  TV.set_cursor(0,6);
  TV.print("-------------------");
  TV.set_cursor(0,11);
  TV.print("SPD=");
  speed_kmh=Speed;
  TV.print(speed_kmh);
  TV.print("   ");
  TV.set_cursor(60,11);
  TV.print("TAH=");
  taho_obm=RPM;
  TV.print(taho_obm);
  TV.print("    ");
  TV.set_cursor(0,17);
  TV.print("-------------------");
  TV.set_cursor(0,22);
  TV.print("MODE=");
  TV.print(int(mode));
  TV.set_cursor(60,22);
 TV.print("REAR=");
 TV.print(digitalRead(RearGearPin));
  TV.set_cursor(0,30);
  TV.print("LEFT=");
  TV.print(digitalRead(LeftTurnPin));
  TV.set_cursor(60,30);
 TV.print("RIGH=");
 TV.print(digitalRead(RightTurnPin));
 
  TV.set_cursor(0,38);
  TV.print("GEAR=");
  TV.print(RecommendGear);
  TV.set_cursor(60,38);
 TV.print("WHEL=");
 TV.print(ButtonName);
  TV.set_cursor(0,46);
  TV.print("4x4=");
  TV.print(digitalRead(FOURxFOURSwitchPin));
  TV.set_cursor(60,46);
 TV.print("AWD=");
 TV.print(digitalRead(AWDSwitchPin));
   TV.set_cursor(0,54);
  TV.print("-------------------");
   TV.set_cursor(0,59);
  TV.print("C1_12V=");
  TV.print(digitalRead(Relay_Camera1_12V_Pin));
  TV.set_cursor(60,59);
 TV.print("C1_VID=");
 TV.print(digitalRead(Relay_Camera1_Video_Pin));
 
    TV.set_cursor(0,67);
  TV.print("C2_12V=");
  TV.print(digitalRead(Relay_Camera2_12V_Pin));
  TV.set_cursor(60,67);
 TV.print("C2_VID=");
 TV.print(digitalRead(Relay_Camera2_Video_Pin));
    TV.set_cursor(0,75);
  TV.print("C3_12V=");
  TV.print(digitalRead(Relay_Camera3_12V_Pin));
  TV.set_cursor(60,75);
 TV.print("C3_VID=");
 TV.print(digitalRead(Relay_Camera3_Video_Pin));
   TV.set_cursor(0,83);
  TV.print("-------------------");
     TV.set_cursor(0,88);
  TV.print("MN_12V=");
 TV.print(digitalRead(Relay_MonsterMoto_12V_Pin));
  TV.set_cursor(60,88);
 TV.print("MOM=");
 if  ((digitalRead(AWDSwitchPin)==HIGH)&& (digitalRead(FOURxFOURSwitchPin)==HIGH)){TV.print(0);}
 if  (digitalRead(AWDSwitchPin)==LOW) {MOM=((MOMENT1*100)/512); TV.print(MOM);}
 if  (digitalRead(FOURxFOURSwitchPin)==LOW) {MOM=((MOMENT2*100)/512); TV.print(MOM);}
TV.print("% ");
//  TV.print(rear_status);
} 
/*
void play_OK()
{
    tone(SpeakerPin, NOTE_E4,800);
}
void play_reset()
{
    tone(SpeakerPin, NOTE_A5,1000); // reset
}
void play_caution()
{
    tone(SpeakerPin, NOTE_D7,800);
}
void mute()
{
    noTone(SpeakerPin);
}
*/
void Cameras_OFF()
{
  Camera_OFF(1);
  Camera_OFF(2);
  Camera_OFF(3);  
}
void Camera_ON(int Camera_Num)
{
 if (Camera_Num==1)
{
  Camera_OFF(2);
  Camera_OFF(3);
digitalWrite(Relay_Camera1_12V_Pin, HIGH);
digitalWrite(Relay_Camera1_Video_Pin, HIGH);
digitalWrite(Relay_GU_12V_Pin, HIGH);
}
if (Camera_Num==2)
{
  Camera_OFF(1);
  Camera_OFF(3);
digitalWrite(Relay_Camera2_12V_Pin, HIGH);
digitalWrite(Relay_Camera2_Video_Pin, HIGH);
digitalWrite(Relay_GU_12V_Pin, HIGH);
}
if (Camera_Num==3)
{
  Camera_OFF(1);
  Camera_OFF(2);
digitalWrite(Relay_Camera3_12V_Pin, HIGH);
digitalWrite(Relay_Camera3_Video_Pin, HIGH);
digitalWrite(Relay_GU_12V_Pin, HIGH);
} 
if ((Camera_Num<1)||(Camera_Num>3)){Cameras_OFF();}
}
void Camera_OFF(int Camera_Num)
{
 if (Camera_Num==1)
{
digitalWrite(Relay_Camera1_12V_Pin, LOW);
digitalWrite(Relay_Camera1_Video_Pin, LOW);
digitalWrite(Relay_GU_12V_Pin, LOW);
}
if (Camera_Num==2)
{
digitalWrite(Relay_Camera2_12V_Pin, LOW);
digitalWrite(Relay_Camera2_Video_Pin, LOW);
digitalWrite(Relay_GU_12V_Pin, LOW);
}
if (Camera_Num==3)
{
digitalWrite(Relay_Camera3_12V_Pin, LOW);
digitalWrite(Relay_Camera3_Video_Pin, LOW);
digitalWrite(Relay_GU_12V_Pin, LOW);
} 
}
//###################################################################
// Функция проверки нажатия рулевой кнопки
// Возвращает false если кнопка не была нажата 
// и true если нажата
// ButtonName принимает значения в зависимости от нажатой кнопки +, -, >, R=>>|, L=|<<, S=SRC, X=None
boolean WheelButonPush_IsPushed()    
{    
bool result; 
result=false;
unsigned long buttonVal;
buttonVal=0; 
ButtonName='X';
 res_d = analogRead(WheelButtonsPin);  
  if( res_d < LIMIT) res_d = LIMIT; 
  delay(10);   
  res_dt1 = analogRead(WheelButtonsPin);   
        old_time = millis();    
        math_time = 0;     
        while(math_time < 200)    
          {    
             real_time = millis();                 
             math_time = real_time - old_time;   
            res_dt1 = analogRead(WheelButtonsPin);  
            if(res_dt1 < res_d-LIMIT || res_dt1 > res_d+LIMIT)break; 
          }    
       
    if( math_time > 70)  
      {   
  buttonVal=res_d;
  ButtonName='X';
   //   Serial.println (res_d);
              
        if ((buttonVal>25) && (buttonVal<45))
       {
ButtonName='-'; //35-36
result=true;
        }
    
        if ((buttonVal>60) && (buttonVal<85))
       {
ButtonName='+'; //72-73
result=true;
        }
        if ((buttonVal>110) && (buttonVal<135))
       {
ButtonName='S'; //122
result=true;
        }
        if ((buttonVal>175) && (buttonVal<200))
       {
ButtonName='R'; //187
result=true;
        }
        if ((buttonVal>275) && (buttonVal<295))
       {
ButtonName='L'; //285
result=true;
        }
        if ((buttonVal>415) && (buttonVal<440))
       {
ButtonName='>'; //429
result=true;
        }
        
        if ((buttonVal>645) && (buttonVal<670))
       {
ButtonName='X'; //658-659
result=false;
        }          
 buttonVal=0;    
    }  
       return result;
}  
//Функции работы с ИК портом
void mark(long time)
{
  for(int i = 0; i < (time / PERIOD); i++)
  {
    digitalWrite(IRPin, HIGH);
    delayMicroseconds(ACTIVE_HIGH - 4); // digitalWrite() takes 4us
    digitalWrite(IRPin, LOW);
    delayMicroseconds(ACTIVE_LOW - 4); // digitalWrite() takes 4us
  }  
}
void sendNEC(unsigned long data)
{
    // Leader code
    mark(NEC_HDR_MARK);
    delayMicroseconds(NEC_HDR_SPACE);
  
    for (int i = 0; i < NEC_BITS; i++)
    {
      mark(NEC_BIT_MARK);
      if (data & TOPBIT)
        delayMicroseconds(NEC_ONE_SPACE);
      else
        delayMicroseconds(NEC_ZERO_SPACE);
  
      data <<=1;
    }
    
    // stop bit
    mark(NEC_BIT_MARK); 
}
 Спасибо огромное отзывчивому и крайне терпеливому Администратору данного сайта.