Я предложу свой вариант. Еще сырой. но идея развивается. Мой код работает на прерываниях и без задержек в теле программы. При одновременной обработке нескольких задач это критично.
Сейчас программка работает с енкодером для регулировки громкости и переключает монитор. Дальше можно добавлять все что надо. У меня будет включать/выключать bluetooth gps, энкодер будет рулить основными параметрами звука (громкость, баланс, фадер), мониторить температуру за бортом и в салоне, может еще что придумаю. Часть функций будут отрабатывать напрямую исполнительными устройствами, а часть будет заведена на комп (например температура).
Еще раз подчеркну - код не оптимальный совсем. Сегодня только начал писать.
	PHP код:
	
#include <MsTimer2.h>
#define BACKINPUTPIN 2    // Вход включения задней передачи
#define BACKOUTPUTPIN 13  // Выход на кнопку монитора
#define TIMEOUTBACKON 20 // Задержка ожидания на включение камеры для устранения дребезга контактов и ложных срабатывания при включении передачи (у меня автоматическая коробка)
#define ENCODERPIN1 4    // Вход энкодера 1
#define ENCODERPIN2 5    // Вход энкодера 2
                                    // центральный вход энкодера на массу
int state, prevstate = 0, count = 0, backstate = LOW, current_backstate = LOW;
int set_flag_control_state_back = 0;
int command_run = 0, set_command = 0;
int time_massive13[5] = {0,0,0,0,0};
int stat_massive13[5] = {0,0,0,0,0};
int pos_massive13 = 0;
int nextEncoderState[4] = { 2, 0, 3, 1 };
int prevEncoderState[4] = { 1, 3, 0, 2 };
void setup()
{
  pinMode(BACKINPUTPIN, INPUT);
  pinMode(ENCODERPIN1, INPUT);
  pinMode(ENCODERPIN2, INPUT);
  digitalWrite(BACKINPUTPIN, HIGH);
  digitalWrite(ENCODERPIN1, HIGH);
  digitalWrite(ENCODERPIN2, HIGH);
  Serial.begin(9600); 
  pinMode(BACKOUTPUTPIN, OUTPUT);
  digitalWrite(BACKOUTPUTPIN, LOW);
  current_backstate = digitalRead(BACKINPUTPIN);
  backstate = digitalRead(BACKINPUTPIN);
  MsTimer2::set(100, flash); // 100ms period
  MsTimer2::start();
}
void loop()
{
  if(change_state_back())
  {
    set_flag_control_state_back = TIMEOUTBACKON;  // взвели флаг контроля для устранения дребезга
    set_command = 1;
  }
  state = (digitalRead(ENCODERPIN2) << 1) | digitalRead(ENCODERPIN1);
  if (state != prevstate) {
    if (state == nextEncoderState[prevstate]) {
       count++;
    } else if (state == prevEncoderState[prevstate]) {
       count--;
    }
    Serial.println(count, DEC);
    prevstate = state;
  }
}
void flash() {
  if(pos_massive13)
  {
    
    if(time_massive13[pos_massive13-1]--)
    {
      return;
    }
    digitalWrite(BACKOUTPUTPIN, stat_massive13[pos_massive13-1]);
    pos_massive13++;
    if(!time_massive13[pos_massive13-1])
    {
      pos_massive13 = 0;
      return;
    }
  }
  else if(set_flag_control_state_back)
  {
    if(!--set_flag_control_state_back)
    {
      if(current_backstate != backstate)
      {
        current_backstate = backstate;
        if(backstate)
        {
          stat_massive13[0] = 1;  // команда "один раз зажечь на 0.2с и потушить.
          time_massive13[0] = 2;
          stat_massive13[1] = 0;
          time_massive13[1] = 2;
          time_massive13[2] = 0;
          pos_massive13 = 1;
        }
        else
        {
          stat_massive13[0] = 1;  // команда "два раза зажечь на 0.2с и потушить.
          time_massive13[0] = 2;
          stat_massive13[1] = 0;
          time_massive13[1] = 2;
          stat_massive13[2] = 1;
          time_massive13[2] = 2;
          stat_massive13[3] = 0;
          time_massive13[3] = 2;
          time_massive13[4] = 0;
          pos_massive13 = 1;
        }
      }
    }
  }
  return;
}
  
int change_state_back()
{
  if(backstate != digitalRead(BACKINPUTPIN))
  {
    backstate = digitalRead(BACKINPUTPIN);
    return 1;
  }
  return 0;
}