Страница 5 из 6 ПерваяПервая 123456 ПоследняяПоследняя
Показано с 41 по 50 из 56
  1. #41
    Продвинутый
    Регистрация
    20.12.2011
    Сообщений
    336
    Вес репутации
    220

    По умолчанию Re: Питание Arduino в авто

    Код:
    #include <EEPROM.h>
    #include <SPI.h>
    #include <Mystepper.h>
    #include <MsTimer2.h>
    #include <avr/wdt.h>  
    
    // Программа для управления МКПП FM42 автомобиля
    // В качестве привода используются: шаговый двигатель с редуктором (первый привод) и шаговый двигатель с винтовой передачей (второй привод)
    // Первый привод необходим непосредственно для переключения вилок КПП, он является силовым
    // Второй привод - для перемещения между вилками КПП
    // Каждый привод контролируется тремя датчиками холла - для отстеживания положений
    // Кроме того, для блокировки включения задней и пятой передачи (от случайного попадания) имеется актуатор
    
    #define DEBUG 1  // используется при отладке
    
    ////// ********Описание периферии********** ///////////
    // Контакт 0 для  - зарезервировано, не использовать!!!
    // Контакт 1 для  - зарезервировано, не использовать!!!
    #define  TahometrPin 2  // Контакт 2 для тахометра !!!!!!!!! ПРЕРЫВАНИЕ 0 
    #define  SpeedSensorPin 3  // Контакт 3 для датчика скорости !!!!!!!!!ПРЕРЫВАНИЕ 1
    #define  Motor1_RelayPin 4// Контакт 4 для  реле 1 блока-реле1 - реле включения контроллера шаг. двигателя первого привода
    #define  GearBlock5R_RelayPin 5// Контакт 5 для  реле 2 блока-реле1
    // Контакт 6 для  реле 3 блока-реле1
    // Контакт 7 для  реле 4 блока-реле1
    // Контакт 8 для !!!!!!!!! свободно 
    // Контакт 9 для !!!!!!!!! свободно 
    // Контакт 10 для динамика
    // Контакт 11 для !!!!!!!!! свободно 
    // Контакт 12 для !!!!!!!!! свободно 
    #define  LedPin 13  // Контакт 13 для светодиода
    #define  HandBreakPin 14  // Контакт 4 для сигнала от ручного тормоза
    #define  SmallLightPin 15  // Контакт 5 для сигнала от габаритов
    #define  LeftTurnPin 16  // Контакт 6 для сигнала от левого поворотника
    #define  RightTurnPin 17  // Контакт 7 для сигнала от правого поворотника
    // Контакт 18 для !!!!!!!!!ПРЕРЫВАНИЕ 5 !!!!!!!!! свободно 
    // Контакт 19 для !!!!!!!!!ПРЕРЫВАНИЕ 4 !!!!!!!!! свободно 
    #define  ClutchONButtonPin 20 // Контакт 20 для кнопки выжима сцепления NO !!!!!!!!!ПРЕРЫВАНИЕ 3
    #define  ClutchOFFButtonPin 21 // Контакт 21 для кнопки отжима сцепления NC !!!!!!!!!ПРЕРЫВАНИЕ 2
    #define  Motor1HallSensor1Pin 22 // Контакт 22 для датчика холла1 первого привода
    #define  Motor1HallSensor2Pin 23 // Контакт 23 для датчика холла2 первого привода
    #define  Motor1HallSensor3Pin 24 // Контакт 24 для датчика холла3 первого привода
    // Контакт 25 для !!!!!!!!! свободно 
    #define  REG_LATCH 26 // Контакт 26 для "Защелка" для опроса кнопок шифтера 
    #define  Motor2HallSensor4Pin 27 // Контакт 27 для датчика холла4 второго привода
    #define  Motor2HallSensor5Pin 28 // Контакт 28 для датчика холла5 второго привода
    #define  Motor2HallSensor6Pin 29 // Контакт 29 для датчика холла6 второго привода
    #define  Motor2A1Pin 30 // Контакт 30 для второго привода
    #define  Motor2B1Pin 31 // Контакт 31 для второго привода
    #define  Motor2A2Pin 32 // Контакт 32 для второго привода
    #define  Motor2B2Pin 33 // Контакт 33 для второго привода
    // Контакт 34 для реле 5 блока-реле1
    // Контакт 35 для реле 6 блока-реле1
    // Контакт 36 для реле 7 блока-реле1
    // Контакт 37 для реле 8 блока-реле1
    #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  LCDGearP_Indicate_Pin 45 // Контакт 45 для индикации Передачи P на ЖКИ
    #define  Motor1_Rotate_Side_Pin 46 // Контакт 46 для первого привода - направление вращения
    #define  Motor1_Online_Direct_Pin 47 // Контакт 47 для первого привода - прямое управление
    #define  Motor1_Frequency_Pin 48 // Контакт 48 для первого привода - частота импульсов
    // Контакт 49 !!!!!!!!! свободно 
    // Контакт 50 MISO - занято для опроса кнопок шифтера
    // Контакт 51 MOSI - занято для опроса кнопок шифтера  - зарезервировано, не использовать!!!
    // Контакт 52 SCK - занято для опроса кнопок шифтера 
    // Контакт 53 SS - занято для опроса кнопок шифтера - зарезервировано, не использовать!!!
    
    //Stepper Motor1(200, Motor1_Rotate_Side_Pin, Motor1_Frequency_Pin, Motor1_Online_Direct_Pin,   Motor1B2Pin);
    //Stepper Motor1(200, Motor1_Rotate_Side_Pin,  Motor1_Online_Direct_Pin, Motor1_Frequency_Pin,  Motor1B2Pin);
    Stepper Motor2(200, Motor2A1Pin, Motor2B1Pin, Motor2A2Pin,   Motor2B2Pin);
    
    //аналоговые входы
    
    #define  Shifter_AxeY 0 //A0 // Шифтер ось 1 Y
    #define  Shifter_AxeX 1 //A1 // Шифтер ось 2 X
    #define  CurrentSensor1Pin 2 //A2 //датчик тока1
    #define  CurrentSensor2Pin 3 //A3 //датчик тока2
    #define  WheelButtonsPin 6 //A6 // кнопки руля
    
    //кнопки шифтера
    byte Shifter_Button_Array[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 
    byte Shifter_Button_UP=0;
    byte Shifter_Button_DOWN=1;
    byte Shifter_Button_LEFT=2;
    byte Shifter_Button_RIGHT=3;
    byte Shifter_Button_Black3=4;
    byte Shifter_Button_Black1=5;
    byte Shifter_Button_Black4=6;
    byte Shifter_Button_Black2=7;
    byte Shifter_Button_Red1=8;
    byte Shifter_Button_Red4=9;
    byte Shifter_Button_Red2=10;
    byte Shifter_Button_Red3=11;
    byte Shifter_PlusMinusMode=12; //режим +-
    byte Shifter_Button_Uknwn1=13;
    byte Shifter_RearGearMode=14; //режим задней передачи (рычаг утоплен)
    byte Shifter_Button_Uknwn2=15;
    
    int CurrentSensor1Value=0;
    int CurrentSensor2Value=0;
    
    //описание переменных
    //boolean RelayOn = false;
    
    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; // обороты двигателя
    
    char CurGear='0';
    char LastGear='0';
    char RecommendGear='0';
    
    //byte GearLastName=0;
    byte P_1=1;
    byte P_2=2;
    byte P_3=3;
    byte P_4=4;
    byte P_5=5;
    byte P_R=255;
    byte P_N12=12;
    byte P_N34=34;
    byte P_N5R=250;
    byte P_MINUS=127;
    byte P_PLUS=128;
    
    int EEPROMaddrLastMotor1HallSensorNum=0; //адрес в энергонезавсимой памяти куда заносится значение положение привода 1 согласно датчикам холла 1,2 или 3 
    int EEPROMaddrLastMotor2HallSensorNum=1; //адрес в энергонезавсимой памяти куда заносится значение положение привода 2 согласно датчикам холла 4,5 или 6
    int EEPROMaddrLastSuccessGearPosition=2; //адрес в энергонезавсимой памяти куда заносится значение последней удачно включенной передачи
    int EEPROMaddrLastFrontGearPosition=3; //адрес в энергонезавсимой памяти куда заносится значение последней удачно включенной передачи в режиме ( без нейтрали и задней передачи)
    
    // переменные нажатия рулевых кнопок
    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); // сторожевой таймер от зависания
     // Shifter_Button_Array[Shifter_Button_UP]=1;
     
    // MsTimer2::set(500, Timer2_Timer); // таймер будет срабатывать через каждые 500ms 
    // MsTimer2::start();//запустить таймер
    
    //*************************Описание пинов**************************
    // Контакт 0 для  - зарезервировано, не использовать!!!
    // Контакт 1 для  - зарезервировано, не использовать!!!
    //2
    pinMode(TahometrPin, INPUT); // Контакт для тахометра !!!!!!!!!ПРЕРЫВАНИЕ 0
    digitalWrite(TahometrPin, HIGH); //внутренняя подтяжка входа тахометра 
    attachInterrupt(0, TahometrImpulse_on, FALLING); // настройка прерывания и функции на него
    //3
    pinMode(SpeedSensorPin, INPUT); // Контакт для датчика скорости !!!!!!!!!ПРЕРЫВАНИЕ 1
    digitalWrite(SpeedSensorPin, HIGH); //внутренняя подтяжка входа датчика скорости 
    attachInterrupt(1, SpeedImpulse_on, FALLING); // настройка прерывания и функции на него
    
    // Контакт 4 для реле 1 блока-реле1
    pinMode(Motor1_RelayPin, OUTPUT);
    // Контакт 5 для реле 2 блока-реле1
    pinMode(GearBlock5R_RelayPin, OUTPUT);
    // Контакт 6 для реле 3 блока-реле1
    // Контакт 7 для реле 4 блока-реле1
    // Контакт 8 для !!!!!!!!! свободно 
    // Контакт 9 для !!!!!!!!! свободно 
    // Контакт 10 для динамика
    // Контакт 11 для !!!!!!!!! свободно 
    // Контакт 12 для !!!!!!!!! свободно 
    //13
    pinMode(LedPin, OUTPUT); // Контакт для светодиода
    //14
    pinMode(HandBreakPin, INPUT);// Контакт для сигнала от ручного тормоза
    digitalWrite(HandBreakPin, HIGH); //внутренняя подтяжка входа +++++ 
    //15
    pinMode(SmallLightPin, INPUT);// Контакт для сигнала от габаритов
    digitalWrite(SmallLightPin, HIGH); //внутренняя подтяжка входа +++++ 
    //16
    pinMode(LeftTurnPin, INPUT);// Контакт 6 для сигнала от левого поворотника
    digitalWrite(LeftTurnPin, HIGH); //внутренняя подтяжка входа +++++ 
    //17
    pinMode(RightTurnPin, INPUT);// Контакт 7 для сигнала от правого поворотника
    digitalWrite(RightTurnPin, HIGH); //внутренняя подтяжка входа +++++ 
    // Контакт 18 для !!!!!!!!!ПРЕРЫВАНИЕ 5 !!!!!!!!! свободно 
    // Контакт 19 для !!!!!!!!!ПРЕРЫВАНИЕ 4 !!!!!!!!! свободно 
    //20
    pinMode(ClutchONButtonPin, INPUT);// Контакт для кнопки выжима сцепления NO !!!!!!!!!ПРЕРЫВАНИЕ 3
    digitalWrite(ClutchONButtonPin, HIGH); //внутренняя подтяжка входа +++++ 
    //21
    pinMode(ClutchOFFButtonPin, INPUT);// Контакт для кнопки отжима сцепления NC !!!!!!!!!ПРЕРЫВАНИЕ 2
    digitalWrite(ClutchOFFButtonPin, HIGH); //внутренняя подтяжка входа +++++ 
    //22
    pinMode(Motor1HallSensor1Pin, INPUT);// Контакт для датчика холла1 первого привода
    digitalWrite(Motor1HallSensor1Pin, HIGH); //внутренняя подтяжка входа +++++ 
    //23
    pinMode(Motor1HallSensor2Pin, INPUT);// Контакт для датчика холла2 первого привода
    digitalWrite(Motor1HallSensor2Pin, HIGH); //внутренняя подтяжка входа +++++ 
    //24
    pinMode(Motor1HallSensor3Pin, INPUT);// Контакт для датчика холла3 первого привода
    digitalWrite(Motor1HallSensor3Pin, HIGH); //внутренняя подтяжка входа +++++ 
    // Контакт 25 для !!!!!!!!! свободно 
    //26 
    pinMode(REG_LATCH, OUTPUT); // Контакт 26 для "Защелка" для опроса кнопок шифтера 
    digitalWrite(REG_LATCH, HIGH); //внутренняя подтяжка входа +++++ 
    //27
    pinMode(Motor2HallSensor4Pin, INPUT);// Контакт для датчика холла4 второго привода
    digitalWrite(Motor2HallSensor4Pin, HIGH); //внутренняя подтяжка входа +++++ 
    //28
    pinMode(Motor2HallSensor5Pin, INPUT);// Контакт для датчика холла5 второго привода
    digitalWrite(Motor2HallSensor5Pin, HIGH); //внутренняя подтяжка входа +++++ 
    //29
    pinMode(Motor2HallSensor6Pin, INPUT);// Контакт для датчика холла6 второго привода
    digitalWrite(Motor2HallSensor6Pin, HIGH); //внутренняя подтяжка входа +++++ 
    //30
    pinMode(Motor2A1Pin, OUTPUT);// Контакт для второго привода
    //31
    pinMode(Motor2B1Pin, OUTPUT);// Контакт для второго привода
    //32
    pinMode(Motor2A2Pin, OUTPUT);// Контакт для второго привода
    //33
    pinMode(Motor2B2Pin, OUTPUT);// Контакт для второго привода
    // Контакт 34 для реле 5 блока-реле1
    // Контакт 35 для реле 6 блока-реле1
    // Контакт 36 для реле 7 блока-реле1
    // Контакт 37 для реле 8 блока-реле1
    //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(LCDGearP_Indicate_Pin, OUTPUT);// Контакт для индикации Передачи P на ЖКИ
    //46
    pinMode(Motor1_Rotate_Side_Pin, OUTPUT);// Контакт  для первого привода - направление вращения
    //47
    pinMode(Motor1_Online_Direct_Pin, OUTPUT);// Контакт  для первого привода - прямое управление
    //48
    pinMode(Motor1_Frequency_Pin, OUTPUT);// Контакт  для первого привода - частота импульсов
    // Контакт 49 !!!!!!!!! свободно 
    SPI.begin(); //задействуем пины 50-53
    // Контакт 50 MISO - занято для опроса кнопок шифтера
    // Контакт 51 MOSI - занято для опроса кнопок шифтера  - зарезервировано, не использовать!!!
    // Контакт 52 SCK - занято для опроса кнопок шифтера 
    // Контакт 53 SS - занято для опроса кнопок шифтера - зарезервировано, не использовать!!!
    
    
    // параметры моторов, скорости вращения об/мин
    //Motor1.setSpeed(100);  
    Motor2.setSpeed(300);  
    
    //гасим ЖКИ 
    Gear_LCD_Clear();
    //
    
    
    #if DEBUG
    Serial.begin(115200); 
    #endif
      
    }
    
    //###################################################################       
    //функция возвращает положение рычага шифтера КПП       
    byte GetShifterPosition()
    {
    uint16_t ShifterButtonsStatus=Read_ShifterButtonsStatus();
    ShifterButtonsStatus >>= Shifter_PlusMinusMode; 
    byte Shifter_PlusMinusModeStatus=ShifterButtonsStatus & 1;  
    //Serial.println(analogRead(0)); //Y
    // Serial.println(analogRead(1)); //X
    byte ShifterPosition=0;
    int X_Position=analogRead(Shifter_AxeX); 
    int Y_Position=analogRead(Shifter_AxeY);
    
    /*
    Serial.print("X=");
    Serial.println(X_Position);
    Serial.print("Y=");
    Serial.println(Y_Position);
    */
    
    //uint16_t ButtonsStatus=Read_ShifterButtonsStatus();
    //ButtonsStatus[]
    if (Shifter_PlusMinusModeStatus==0) // обычный режим переключения КПП - ручной (не +-)
    {
    if ((X_Position<320) && (Y_Position>600)) {ShifterPosition=P_1;}
    if ((X_Position<320) && (Y_Position<100)) {ShifterPosition=P_2;}
    if (((X_Position>320) && (X_Position<520)) && (Y_Position>600)) {ShifterPosition=P_3;}
    if (((X_Position>320) && (X_Position<520)) && (Y_Position<100)) {ShifterPosition=P_4;}
    if ((X_Position>520) && (Y_Position>600)) {ShifterPosition=P_5;}
    if ((X_Position>520) && (Y_Position<100)) {ShifterPosition=P_R;}
    //if ((Y_Position>100) && (Y_Position<600)) {ShifterPosition=P_N;}
    if ((X_Position<320) && ((Y_Position>100) && (Y_Position<600))) {ShifterPosition=P_N12;}
    if (((X_Position>320) && (X_Position<520)) && (Y_Position>100) && (Y_Position<600)) {ShifterPosition=P_N34;}
    if ((X_Position>520) && ((Y_Position>100) && (Y_Position<600))) {ShifterPosition=P_N5R;}
    }
    
    //+-
    if (Shifter_PlusMinusModeStatus==1) // режим переключения КПП - спортивный (+-)
    {
    if (Y_Position>500) {ShifterPosition=P_MINUS;}
    if (Y_Position<300) {ShifterPosition=P_PLUS;}
    //if ((Y_Position>300) && (Y_Position<500)) {ShifterPosition='N';}
    }
    
    return ShifterPosition;
    } 
    
    //###################################################################
    //функция возвращает состояние изменившихся кнопок шифтера
    uint16_t Read_ShifterButtonsStatus() 
      {
    
    static  uint16_t Last_Shifter_Buttons_States = 0; // статус четырех нижних (красных) кнопок и восьми верхних и средних (черных) кнопок
      uint16_t Shifter_Buttons_Changes =0;
      
      digitalWrite(REG_LATCH, LOW);  //Выставим на защёлке сначала низкий, потом - высокий уровни.
      digitalWrite(REG_LATCH, HIGH); //Сдвиговый регистр запомнит уровни сигналов на входах и сможет их нам потом отдать бит за би
    
      uint16_t Shifter_Buttons_States= (SPI.transfer(0) <<8 ) | SPI.transfer(0); //Читаем запомненные состояния четырех нижних (красных) кнопок и восьми верхних и средних (черных) кнопок
    
      if (Shifter_Buttons_States != Last_Shifter_Buttons_States)
      {
        Shifter_Buttons_Changes = Shifter_Buttons_States ^ Last_Shifter_Buttons_States;
        Last_Shifter_Buttons_States = Shifter_Buttons_States; // запоминаем текущие состояния
        
    //#if DEBUG      
    //Serial.println(Shifter_Buttons_States, BIN);
    //#endif
    
    
      /*
        for (int i = 0; i < 16; ++i)
        {
          if (Shifter_Buttons_Changes & 1) // если состояние кнопки изменилось…
          {
            
         /*  Serial.print("#");
            Serial.print(i); // шлём номер кнопки
            Serial.print(" -> ");
            Serial.println(states & 1); // … и новое состояние
          }
    
          Shifter_Buttons_Changes >>= 1; // Сдвигаем биты вправо
          Shifter_Buttons_States >>= 1; // Сдвигаем биты вправо
        }
        */
      }
      return Shifter_Buttons_States; //Shifter_Buttons_Changes;
     }
    
    //################################################################### 
    //гасим ЖКИ  
    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(byte GearName)
    {
    Gear_LCD_Clear();  
    if (GearName==P_1){digitalWrite(LCDGear1_Indicate_Pin, HIGH);}
    if (GearName==P_2){digitalWrite(LCDGear2_Indicate_Pin, HIGH);}
    if (GearName==P_3){digitalWrite(LCDGear3_Indicate_Pin, HIGH);}
    if (GearName==P_4){digitalWrite(LCDGear4_Indicate_Pin, HIGH);}
    if (GearName==P_5){digitalWrite(LCDGearD_Indicate_Pin, HIGH);}
    if (GearName==P_R){digitalWrite(LCDGearR_Indicate_Pin, HIGH);}
    if (GearName==P_N12){digitalWrite(LCDGearN_Indicate_Pin, HIGH);}
    if (GearName==P_N34){digitalWrite(LCDGearN_Indicate_Pin, HIGH);}
    if (GearName==P_N5R){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 (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;
    }  
    }
    
    
    
    //###################################################################
    // Функция привода переключения передач (1ый привод), можно передавать значения только Motor1HallSensor1Pin, Motor1HallSensor2Pin, Motor1HallSensor3Pin
    // runaway - шаги для перебега (точное позиционирование после срабатывания датчика холла) 
    // holding_time_msec - время (мс) удержания привода после прихода в нужное положение
    byte Change_Gear_Motor_On(int steps, int to_Position, int runaway, int holding_time_msec)
    { 
    int i_runaway=0;
    byte Rezult=0;
    int ttime=millis(); 
    boolean RelayToDo=true;
    int stepped=1; 
    int stepcount=abs(steps);
    if ((steps>0) && (digitalRead(Motor1HallSensor2Pin)==0)) {RelayToDo=false;} // дальше крутить в эту сторону нельзя - конечное положение
    if ((steps<0) && (digitalRead(Motor1HallSensor1Pin)==0)) {RelayToDo=false;} // дальше крутить в эту сторону нельзя - конечное положение
    if (digitalRead(to_Position)==0) {RelayToDo=false;} //уже достигли нужного положения по датчику холла
    
    if (RelayToDo) 
        { //1
    digitalWrite(Motor1_RelayPin, HIGH); //включаем реле 
    if (steps>0) {digitalWrite(Motor1_Rotate_Side_Pin, HIGH);} // задаем сторону вращения
    if (steps<0) {digitalWrite(Motor1_Rotate_Side_Pin, LOW);} // задаем сторону вращения
    digitalWrite(Motor1_Online_Direct_Pin, HIGH); // прямое управление контроллером шагового двигателя с ардуино
    //int TimeBTWNImpulse=3000; //время между импульсами (шагами) - скорость вращения
    int TimeBTWNImpulse=1000; //время между импульсами (шагами) - скорость вращения
      
      
    while (stepped<=stepcount)
      {
    //if (stepped>50) {TimeBTWNImpulse=2000;} //ускорение 1ая ступень
    //if (stepped>100) {TimeBTWNImpulse=1500;} //ускорение 2ая ступень
    //if (stepped>150) {TimeBTWNImpulse=1000;} //ускорение 3ья ступень
    digitalWrite(Motor1_Frequency_Pin, HIGH); //импульс
     delayMicroseconds(TimeBTWNImpulse);
     digitalWrite(Motor1_Frequency_Pin, LOW);
     stepped++; 
    if ((steps>0) && (digitalRead(Motor1HallSensor2Pin)==0)) {stepped=stepcount+1;} // дальше крутить в эту сторону нельзя - конечное положение
    if ((steps<0) && (digitalRead(Motor1HallSensor1Pin)==0)) {stepped=stepcount+1;} // дальше крутить в эту сторону нельзя - конечное положение
    if (digitalRead(to_Position)==0) {i_runaway++; if (i_runaway>=runaway) {stepped=stepcount+1;}} //уже достигли нужного положения по датчику холла
      }
        } //1  
     digitalWrite(Motor1_Frequency_Pin, LOW);
     delay(holding_time_msec); // выдержка (удержание) привода
     digitalWrite(Motor1_RelayPin, LOW); //выключаем реле
    //Serial.println( millis()-ttime);  
    delay(10); //даем время для адаптации датчикам холла
    
    Rezult=GetCurrentGearPosition();
    
    if (Rezult!=0) {SetSuccessGearPosition_to_EEPROM(Rezult);}
    
    if ((Rezult>=P_1) && (Rezult<=P_5)) {SetFrontGearPosition_to_EEPROM(Rezult);}
    
    return Rezult;
           	  }
           
    //###################################################################       
    // Функция привода выбора передач (2ой привод), можно передавать значения только Motor2HallSensor4Pin, Motor2HallSensor5Pin, Motor2HallSensor6Pin 
    // runaway - шаги для перебега (точное позиционирование после срабатывания датчика холла) 
    void Select_Gear_Motor_On(int steps, int to_Position, int runaway)
    { 
    boolean NeedToDo=true;   
    if ((steps>0) && (digitalRead(Motor2HallSensor5Pin)==0)) {NeedToDo=false;} // дальше крутить в эту сторону нельзя - конечное положение
    if ((steps<0) && (digitalRead(Motor2HallSensor6Pin)==0)) {NeedToDo=false;} // дальше крутить в эту сторону нельзя - конечное положение
    if (digitalRead(to_Position)==0) {NeedToDo=false;} //уже достигли нужного положения по датчику холла
      
    if (NeedToDo) {Motor2.step(steps, to_Position, runaway);}
    }  
           
    
          
    
    //###################################################################
    //функция возвращает текущую позицию КПП по датчикам 
    //возвращает значения 1,2,3,4,5,R=255,12,34,250
    // при неудаче возвращает 0
    byte GetCurrentGearPosition()
    {
     
    byte Rezult=0; //неопределенное положение
    int c=0; // количество сработавших датчиков положения (холла)
    if ((digitalRead(Motor1HallSensor1Pin)==0) && (digitalRead(Motor2HallSensor6Pin)==0)) {Rezult=P_1;}
    if ((digitalRead(Motor1HallSensor2Pin)==0) && (digitalRead(Motor2HallSensor6Pin)==0)) {Rezult=P_2;}
    if ((digitalRead(Motor1HallSensor1Pin)==0) && (digitalRead(Motor2HallSensor4Pin)==0)) {Rezult=P_3;}
    if ((digitalRead(Motor1HallSensor2Pin)==0) && (digitalRead(Motor2HallSensor4Pin)==0)) {Rezult=P_4;}
    if ((digitalRead(Motor1HallSensor1Pin)==0) && (digitalRead(Motor2HallSensor5Pin)==0)) {Rezult=P_5;}
    if ((digitalRead(Motor1HallSensor2Pin)==0) && (digitalRead(Motor2HallSensor5Pin)==0)) {Rezult=P_R;} // задняя передача
    
    if ((digitalRead(Motor1HallSensor3Pin)==0) && (digitalRead(Motor2HallSensor6Pin)==0)) {Rezult=P_N12;}
    if ((digitalRead(Motor1HallSensor3Pin)==0) && (digitalRead(Motor2HallSensor4Pin)==0)) {Rezult=P_N34;}
    if ((digitalRead(Motor1HallSensor3Pin)==0) && (digitalRead(Motor2HallSensor5Pin)==0)) {Rezult=P_N5R;}
    
    if (digitalRead(Motor1HallSensor1Pin)==0) {c++;}
    if (digitalRead(Motor1HallSensor2Pin)==0) {c++;}
    if (digitalRead(Motor1HallSensor3Pin)==0) {c++;}
    if (digitalRead(Motor2HallSensor4Pin)==0) {c++;}
    if (digitalRead(Motor2HallSensor5Pin)==0) {c++;}
    if (digitalRead(Motor2HallSensor6Pin)==0) {c++;}
    
    if (c!=2) {Rezult=0;} //неопределенное положение
    //Serial.println(c); /////////////
    return Rezult;  
    }
    
    
    //###################################################################
    //функция извлекающая последнюю успешную передачу КПП, последнее определенное положение КПП
    //возвращает значения 1,2,3,4,5,R=255,12,34,250
    // 0 при отсутствии информации о последнем положении
    byte GetLastSuccessGearPosition()
    {
    byte Rezult=0;
    Rezult=EEPROM.read(EEPROMaddrLastSuccessGearPosition);
    return Rezult;  
    }
    
    byte GetLastFrontGearPosition()
    {
    byte Rezult=0;
    Rezult=EEPROM.read(EEPROMaddrLastFrontGearPosition);
    return Rezult;  
    }
    
    //процедура записывающая в память включенную передачу
    void SetSuccessGearPosition_to_EEPROM(byte Gearvalue)
    {
    EEPROM.write(EEPROMaddrLastSuccessGearPosition, Gearvalue);
    }
    
    void SetFrontGearPosition_to_EEPROM(byte Gearvalue)
    {
    EEPROM.write(EEPROMaddrLastFrontGearPosition, Gearvalue);
    }
    
    
    
    
    //###################################################################  
    //функция перевода в нейтральную поперечную линию между 1-3-5 и 2-4-R
    //возвращает 0 при неудаче
    // 12 при переходе в продольную позицию между 1-2
    // 34 при переходе в продольную позицию между 3-4
    // 250 при переходе в продольную позицию между 5-R
    byte Go_To_Neutral_Line()
    {
    byte Rezult=0;
    
    byte CurrentGearPosition=GetCurrentGearPosition();
    if (CurrentGearPosition==0) {CurrentGearPosition=SearchingGear();}
    
    if ((CurrentGearPosition==P_1) || (CurrentGearPosition==P_3)) {Change_Gear_Motor_On(200, Motor1HallSensor3Pin,18, 10);}
    if ((CurrentGearPosition==P_2) || (CurrentGearPosition==P_4)) {Change_Gear_Motor_On(-200, Motor1HallSensor3Pin,14, 10);}
    if (CurrentGearPosition==P_5) { if (Gear_Unlock_R_Block_5(false)) {Change_Gear_Motor_On(200, Motor1HallSensor3Pin,18, 10);}}
    if (CurrentGearPosition==P_R) { if (Gear_Unlock_R_Block_5(true)) {Change_Gear_Motor_On(-200, Motor1HallSensor3Pin,14, 10); Gear_Unlock_R_Block_5(false);}}
    
    if (CurrentGearPosition==0)
    {
    byte LastGearPosition=GetLastSuccessGearPosition();
    if ((LastGearPosition==P_1) || (LastGearPosition==P_3)) {Change_Gear_Motor_On(200, Motor1HallSensor3Pin,18, 10);}
    if ((LastGearPosition==P_2) || (LastGearPosition==P_4)) {Change_Gear_Motor_On(-200, Motor1HallSensor3Pin,14, 10);}
    if (LastGearPosition==P_5) { if (Gear_Unlock_R_Block_5(false)) {Change_Gear_Motor_On(200, Motor1HallSensor3Pin,18, 10);}}
    if (LastGearPosition==P_R) { if (Gear_Unlock_R_Block_5(true)) {Change_Gear_Motor_On(-200, Motor1HallSensor3Pin,14, 10); Gear_Unlock_R_Block_5(false);}}
    
    }
    
    Rezult=GetCurrentGearPosition();
    
    if (Rezult!=0) {SetSuccessGearPosition_to_EEPROM(Rezult);}
    return Rezult;
    } 
    
    
    // функция поиска передач - при неопределенном положении
    byte SearchingGear()
    {
    byte CurrentGearPosition=GetCurrentGearPosition();  
    if (CurrentGearPosition!=0)  {return CurrentGearPosition;}
    
    
    int c=0;
    if (digitalRead(Motor1HallSensor1Pin)==0) {c++;}
    if (digitalRead(Motor1HallSensor2Pin)==0) {c++;}
    if (digitalRead(Motor1HallSensor3Pin)==0) {c++;}
    if (digitalRead(Motor2HallSensor4Pin)==0) {c++;}
    if (digitalRead(Motor2HallSensor5Pin)==0) {c++;}
    if (digitalRead(Motor2HallSensor6Pin)==0) {c++;}
    if (c>2) {return 0;} //неопределенное положение из-за залипшего датчика холла - тупиковая ситуация
    
    byte GearLastName=GetLastSuccessGearPosition();
    
    if (c<=0) //*************** самый сложный случай ни один датчик не сработал, положение потеряно полностью
    {
    if ((GearLastName==P_1) || (GearLastName==P_3) || (GearLastName==P_5)) {Change_Gear_Motor_On(200, Motor1HallSensor3Pin,18, 10); }
    if ((GearLastName==P_2) || (GearLastName==P_5) || (GearLastName==P_R)) {Change_Gear_Motor_On(-200, Motor1HallSensor3Pin,14, 10); }
    if ((GearLastName==P_N12) || (GearLastName==P_N34) || (GearLastName==P_N5R)) {Change_Gear_Motor_On(200, Motor1HallSensor3Pin,18, 10); }
    }
    
    if (digitalRead(Motor1HallSensor1Pin)==0)  
    {
    Change_Gear_Motor_On(200, Motor1HallSensor3Pin,18, 10); 
    if ((GearLastName==P_1) || (GearLastName==P_2) || (GearLastName==P_N12) ) {Select_Gear_Motor_On(-500, Motor2HallSensor6Pin, 30);}
    if ((GearLastName==P_3) || (GearLastName==P_4) || (GearLastName==P_N34) ) {Select_Gear_Motor_On(-250, Motor2HallSensor4Pin, 40);}
    if ((GearLastName==P_5) || (GearLastName==P_R) || (GearLastName==P_N5R) ) {Select_Gear_Motor_On(500, Motor2HallSensor5Pin, 30);}
    return GetCurrentGearPosition();
    } 
    
    if (digitalRead(Motor1HallSensor2Pin)==0)  
    {
    Change_Gear_Motor_On(-200, Motor1HallSensor3Pin,14, 10); 
    if ((GearLastName==P_1) || (GearLastName==P_2) || (GearLastName==P_N12) ) {Select_Gear_Motor_On(-500, Motor2HallSensor6Pin, 30);}
    if ((GearLastName==P_3) || (GearLastName==P_4) || (GearLastName==P_N34) ) {Select_Gear_Motor_On(-250, Motor2HallSensor4Pin, 40);}
    if ((GearLastName==P_5) || (GearLastName==P_R) || (GearLastName==P_N5R) ) {Select_Gear_Motor_On(500, Motor2HallSensor5Pin, 30);}
    return GetCurrentGearPosition();
    } 
    
    if (digitalRead(Motor1HallSensor3Pin)==0)  
    {
    if ((GearLastName==P_1) || (GearLastName==P_2) || (GearLastName==P_N12) ) {Select_Gear_Motor_On(-500, Motor2HallSensor6Pin, 30);}
    if ((GearLastName==P_3) || (GearLastName==P_4) || (GearLastName==P_N34) ) {Select_Gear_Motor_On(-250, Motor2HallSensor4Pin, 40);}
    if ((GearLastName==P_5) || (GearLastName==P_R) || (GearLastName==P_N5R) ) {Select_Gear_Motor_On(500, Motor2HallSensor5Pin, 30);}
    
    return GetCurrentGearPosition();
    } 
    
    if ((digitalRead(Motor2HallSensor4Pin)==0) || (digitalRead(Motor2HallSensor5Pin)==0) || (digitalRead(Motor2HallSensor6Pin)==0))  //12 34 5R
    {
    if ((GearLastName==P_1) || (GearLastName==P_3) || (GearLastName==P_5)) {Change_Gear_Motor_On(200, Motor1HallSensor3Pin,18, 10); }
    if ((GearLastName==P_2) || (GearLastName==P_5) || (GearLastName==P_R)) {Change_Gear_Motor_On(-200, Motor1HallSensor3Pin,14, 10); }
    if ((GearLastName==P_N12) || (GearLastName==P_N34) || (GearLastName==P_N5R)) {Change_Gear_Motor_On(200, Motor1HallSensor3Pin,18, 10); }
    return GetCurrentGearPosition();
    }  
    
    
    
    }
    
    //###################################################################
    //функция выбора передач по линии нейтрали (влево-вправо)
    // самостоятельно не вызывать - вызывается из функции Go_To_Gear
    byte SelectGear (byte ToNeutralLine)
    {
    byte Rezult=0;
    byte CurrentGearPosition=GetCurrentGearPosition();
    
    if (CurrentGearPosition==0) {CurrentGearPosition=SearchingGear();}
    
    if (CurrentGearPosition==ToNeutralLine) {return CurrentGearPosition;}
    if (ToNeutralLine==P_N12)
     {
    if (CurrentGearPosition==P_N34) {Select_Gear_Motor_On(-250, Motor2HallSensor6Pin, 30);}
    if (CurrentGearPosition==P_N5R) {Select_Gear_Motor_On(-500, Motor2HallSensor6Pin, 30);}
    
    if (CurrentGearPosition==0)
    {
    byte LastGearPosition=GetLastSuccessGearPosition();
    if (LastGearPosition==P_N34) {Select_Gear_Motor_On(-250, Motor2HallSensor6Pin, 30);}
    if (LastGearPosition==P_N5R) {Select_Gear_Motor_On(-500, Motor2HallSensor6Pin, 30);}
    } 
     }
     
     if (ToNeutralLine==P_N34)
     {
    if (CurrentGearPosition==P_N12) {Select_Gear_Motor_On(250, Motor2HallSensor4Pin, 40);}
    if (CurrentGearPosition==P_N5R) {Select_Gear_Motor_On(-250, Motor2HallSensor4Pin, 40);}
    
    if (CurrentGearPosition==0)
    {
    byte LastGearPosition=GetLastSuccessGearPosition();
    if (LastGearPosition==P_N12) {Select_Gear_Motor_On(250, Motor2HallSensor4Pin, 40);}
    if (LastGearPosition==P_N5R) {Select_Gear_Motor_On(-250, Motor2HallSensor4Pin, 40);}
    } 
     }
     
     if (ToNeutralLine==P_N5R)
     {
    if (CurrentGearPosition==P_N12) {Select_Gear_Motor_On(500, Motor2HallSensor5Pin, 30);}
    if (CurrentGearPosition==P_N34) {Select_Gear_Motor_On(250, Motor2HallSensor5Pin, 30);}
    
    if (CurrentGearPosition==0)
    {
    byte LastGearPosition=GetLastSuccessGearPosition();
    if (LastGearPosition==P_N12) {Select_Gear_Motor_On(500, Motor2HallSensor5Pin, 30);}
    if (LastGearPosition==P_N34) {Select_Gear_Motor_On(250, Motor2HallSensor5Pin, 30);}
    } 
     }
    
    Rezult=GetCurrentGearPosition();
    if (Rezult!=0) {SetSuccessGearPosition_to_EEPROM(Rezult);}
    return Rezult;
    }
    
    //###################################################################
    //функция разблокировки задней передачи (блокировки 5ой)
    boolean Gear_Unlock_R_Block_5(boolean Unlock_R_block_5)
    {
    if (Unlock_R_block_5) {digitalWrite(GearBlock5R_RelayPin, HIGH);}
    if (!Unlock_R_block_5) {digitalWrite(GearBlock5R_RelayPin, LOW);}
    return true; // встроить сюда проверку при срабатывании актуатора
    }
    
    //###################################################################
    //функция переключения передачи  
    //сначала производится перевод в нейтральную линию
    //затем выбор передачи по нейтральной линии
    //затем при необходимости разблокировки аередачи (задней или пятой)
    //и уже потом перевод в нужное положение
    boolean Go_To_Gear(byte GearName)
    {
    byte CurrentGearPosition=GetCurrentGearPosition();
    if (CurrentGearPosition==GearName) {return true;}
    if (CurrentGearPosition==0) {CurrentGearPosition=SearchingGear();}
      
    byte SetNeutral=Go_To_Neutral_Line(); //переводим в нейтраль
    if ((SetNeutral==P_N12) || (SetNeutral==P_N34) || (SetNeutral==P_N5R))
    { //1
    if (GearName==P_1) {if (SelectGear(P_N12)==P_N12) {if (Change_Gear_Motor_On(-400, Motor1HallSensor1Pin,0, 100)==GearName){return true;}}}
    if (GearName==P_2) {if (SelectGear(P_N12)==P_N12) {if (Change_Gear_Motor_On(400, Motor1HallSensor2Pin,0, 100)==GearName){return true;}}}
    
    if (GearName==P_3) {if (SelectGear(P_N34)==P_N34) {if (Change_Gear_Motor_On(-400, Motor1HallSensor1Pin,0, 100)==GearName){return true;}}}
    if (GearName==P_4) {if (SelectGear(P_N34)==P_N34) {if (Change_Gear_Motor_On(400, Motor1HallSensor2Pin,0, 100)==GearName){return true;}}}
    
    if (GearName==P_5) {if (SelectGear(P_N5R)==P_N5R) {if (Gear_Unlock_R_Block_5(false)) {if (Change_Gear_Motor_On(-400, Motor1HallSensor1Pin,0, 100)==GearName){return true;}}}}
    if (GearName==P_R) {if (SelectGear(P_N5R)==P_N5R) {if (Gear_Unlock_R_Block_5(true)) {if (Change_Gear_Motor_On(400, Motor1HallSensor2Pin,0, 100)==GearName){Gear_Unlock_R_Block_5(false);return true;}}}}
      
      
    }//1
    return false;
    }  
           
    //###################################################################
    //###################################################################
    // главный цикл
    void loop()
    {
    wdt_reset();
    KPP_working();  
    }
    
    // процедура работы КПП - самодостаточная
    void KPP_working()
    {
    delay(100);  
    uint16_t ShifterButtonsStatus=Read_ShifterButtonsStatus();
    ShifterButtonsStatus >>= Shifter_RearGearMode; 
    byte Shifter_RearGearModeStatus=ShifterButtonsStatus & 1;
    ShifterButtonsStatus=Read_ShifterButtonsStatus();
    ShifterButtonsStatus >>= Shifter_PlusMinusMode; 
    byte Shifter_PlusMinusModeStatus=ShifterButtonsStatus & 1;  
    
    byte ToGear=GetShifterPosition();
    byte GearName=GetCurrentGearPosition();
    byte GearNameToIndicate=GearName;
    
    // обычный режим
    //*******************
    byte GearLastName=GetLastSuccessGearPosition();
    if ((GearLastName!=ToGear) && (Shifter_PlusMinusModeStatus==0))
    {
    if ((ToGear==P_1)&& (Shifter_RearGearModeStatus==0))  {GearNameToIndicate=Go_To_Gear(ToGear);}
    if ((ToGear==P_2)&& (Shifter_RearGearModeStatus==0))  {GearNameToIndicate=Go_To_Gear(ToGear);}
    if ((ToGear==P_3)&& (Shifter_RearGearModeStatus==0))  {GearNameToIndicate=Go_To_Gear(ToGear);}
    if ((ToGear==P_4)&& (Shifter_RearGearModeStatus==0))  {GearNameToIndicate=Go_To_Gear(ToGear);}
    if ((ToGear==P_5)&& (Shifter_RearGearModeStatus==0))  {GearNameToIndicate=Go_To_Gear(ToGear);}
    if ((ToGear==P_R) && (Shifter_RearGearModeStatus==1)) {GearNameToIndicate=Go_To_Gear(ToGear);}
    if ((ToGear==P_N12)||(ToGear==P_N34) ||(ToGear==P_N5R)){GearNameToIndicate=Go_To_Neutral_Line();}
    }
    //*******************
    
    
    
    // спортивный режим +-
    //*******************
    //byte GearLastName_withoutN=0;
    //GearLastName
    byte FrontGearLastName=GetLastFrontGearPosition();
    if ((FrontGearLastName<P_1) || (FrontGearLastName>P_5)) {FrontGearLastName=P_1;}
    if (Shifter_PlusMinusModeStatus==1)
       {
    if (ToGear==P_PLUS)
    {
    if ((GearLastName==P_N5R)&& (FrontGearLastName==P_5)) {GearNameToIndicate=Go_To_Gear(FrontGearLastName);}  
    if ((FrontGearLastName>=P_1) && (FrontGearLastName<P_5)) {GearNameToIndicate=Go_To_Gear(FrontGearLastName+1);}
    }
    
    if (ToGear==P_MINUS)
    {
    //if (GearLastName==P_1) {GearName=Go_To_Neutral_Line();}  
    if ((GearLastName==P_N12)&& (FrontGearLastName==P_1)) {GearNameToIndicate=Go_To_Gear(FrontGearLastName);}
    if ((FrontGearLastName>P_1) && (FrontGearLastName<=P_5))  {GearNameToIndicate=Go_To_Gear(FrontGearLastName-1);}
    }
    
    if (Shifter_RearGearModeStatus==1) {GearNameToIndicate=Go_To_Neutral_Line();} 
       }
    //*******************
    
    #if DEBUG  
    //Serial.println(ToGear);    
    //delay(1000);
    #endif
    
    
    Indicate_Gear_On_LCD(GearNameToIndicate);
    
    
    }
    
    
    
    
    
    //###################################################################
    // обработчик событий тахометра
    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.println(Taho_ImpulseTime);
    //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.println(Speed_ImpulseTime);
    //Serial.println(Speed); 
    #endif
    
    Speed_impulse_count = 0;
      }  
    } 
    
    //###################################################################
    // Функция проверки нажатия рулевой кнопки
    // Возвращает 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;
    }  
    
    
    
    //###################################################################
     int sensorValue = 0;  // variable to store the value coming from the sensor
     int countvalues = 5;      // how many values must be averaged
     int ZeroLevel = 520;    // Zero level
     float kVolt = 0.0506;      // conversion factor
    
    int Current(int sensorPin) {
      int TMPsensorValue = 0;
      int count = 0;
     
      for (count =0; count < countvalues; count++) {
        // read the value from the sensor:
        TMPsensorValue = analogRead(sensorPin);
        delay(30);
        // make average value
        sensorValue = (sensorValue+TMPsensorValue)/2;
        }
      return sensorValue;
      }
    
    //###################################################################
    void Timer2_Timer() //обработка событий в таймере
    {
    
    //CurrentSensor1Value = analogRead(CurrentSensor1Pin);       // read analog input pin CurrentSensor1Pin
    
    //int CurrentSensor1Value = Current(CurrentSensor1Pin);
    //  Serial.println(kVolt * (CurrentSensor1Value - ZeroLevel));
    /*  
    #if DEBUG
        //  Serial.println(CurrentSensor1Value);  // prints the value read
     Serial.println((CurrentSensor1Value-512)*1000/20);  // prints the value read
      delay(100);                        // wait 100ms for next reading
    #endif
    */   
    }
    Последний раз редактировалось kadushkin; 14.08.2012 в 22:02.

  2. #42
    Продвинутый
    Регистрация
    20.12.2011
    Сообщений
    336
    Вес репутации
    220

    По умолчанию Re: Питание Arduino в авто

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

    Выделил все в отдельную тему - уже пора: http://www.compcar.ru/forum/showthread.php?t=9117
    Последний раз редактировалось kadushkin; 12.08.2012 в 11:22.

  3. #43
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,379
    Вес репутации
    10

    По умолчанию Re: Питание Arduino в авто

    Цитата Сообщение от kadushkin Посмотреть сообщение
    Опять странный эффект:
    при питании ардуины от USB скетч работает отлично.
    при питании от VIN (~7,7 V) идут задержки в выполнении скетча, т.е. шаговый двигатель запускается с задержкой около 1 сек после нажатия кнопки, потом при нажатии кнопки опять 1 сек. думает и запускает двигатель. При питании от USB задержек нет вообще...

    Как такое может быть?
    Возможно недостаточно тока, от этого появляются большие пульсации

  4. #44
    Продвинутый
    Регистрация
    20.12.2011
    Сообщений
    336
    Вес репутации
    220

    По умолчанию Re: Питание Arduino в авто

    Спасибо, проверю в авто от АКБ - там точно должно хватить, ведь 75Ач.

  5. #45
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,379
    Вес репутации
    10

    По умолчанию Re: Питание Arduino в авто

    АКБ тут не причем. Для примера можешь подключить питание от АКБ через резистор 1К. И тогда не важно какой ток может выдать АКБ

  6. #46
    Новичок
    Регистрация
    12.10.2014
    Сообщений
    9
    Вес репутации
    120

    Вопрос Re: Питание Arduino в авто

    Всем здравствуйте!
    Зовут меня Женя, мне 29 лет. Недавно тоже начал изучать тему автоматизации на МК, хочу попробовать сделать проект с помощью ArduinoUno.
    По ходу изучения темы возникает масса всяких вопросов, некоторые из которых ставят меня в тупик.
    Т.к. одним из первых вопросов встал вопрос о питании Arduino, то решил написать все в этой теме(если что извиняйте).
    Суть проекта такова: Считывать импульсы с "родного" датчика скорости транспортного средства и пропорционально им выдавать управляющие импульсы на исполнительный орган(насос).
    Ниже приведу схему элементов и соединений, как себе это представляю я.
    Нажмите на изображение для увеличения. 

Название:	IMG.jpg 
Просмотров:	912 
Размер:	75.1 Кб 
ID:	18108

    Вот такой импульсный понижающий стабилизатор
    Название: dwn7s.jpg
Просмотров: 2009

Размер: 6.2 Кб
    Стабилизатор на LM2596 (с пониженными пульсациями)
    Uвх = 4...40 В, Uвых = 1.5...35 В, Iвых = 2(3) А

    А теперь вопросы:
    1. Так ли необходим стабилизированный источник питания на 7-9V для Arduino, или можно просто брать питание от борт. сети?
    2. По схеме, "-" на входе в стабилизатор и "-" на его выходе это одно и то же, т.е. не будет ли между ними падение напряжения?
    Если между ними есть падение напряжения, то тогда как организовать работу силового ключа, для питания исполнительного органа 12V 1,5A?
    3. Пока что точно не знаю величину напряжения на сигнале с датчика скорости (либо 5V либо 12V). Как быть в обоих этих случаях при подключении, так чтоб не спалить вход на Arduino и не внести никаких погрешностей в работу "штатного" спидометра?

  7. #47
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,379
    Вес репутации
    10

    По умолчанию Re: Питание Arduino в авто

    1-Если питается только ардуина без периферии, то можно использовать встроенный в него источник питания
    2-падение возникает если между измеряемыми точками есть сопротивление. Ключ можно запитать от +12в все зависит от схемы подключения
    3-используйте оптрон, например PC817

  8. #48
    Новичок
    Регистрация
    12.10.2014
    Сообщений
    9
    Вес репутации
    120

    Вопрос Re: Питание Arduino в авто

    Спасибо за ответы!
    От Arduino будет питаться дисплей 2х16.
    Сопротивление мне сейчас не измерить, т.к. стабилизатора на руках у нет.
    Ключ я и хотел запитывать от 12V чтобы силовая нагрузка не шла по плате Arduino, вопрос как сделать так чтоб он работал, если "-" 12 V его питания и "-" 9V питания Arduino нельзя замкнуть. Тоже оптопару ставить?
    Посмотрел характеристики оптрона PC817
    I=20mA V=1,2V
    Нашёл вот такую схему делителя
    http://nice.artip.ru/resist/2.jpg
    Посчитал резисторы при питании от 5V получились R1=38 Ом; R2=12 Ом
    Эта схема подойдёт мне? Не чего ненаврал?
    Последний раз редактировалось Biker; 14.10.2014 в 17:51.

  9. #49
    Новичок
    Регистрация
    10.10.2014
    Сообщений
    10
    Вес репутации
    121

    По умолчанию Re: Питание Arduino в авто

    Почитайте эту статью про недорогой и мощный импульсный DC-DC преобразователь
    http://we.easyelectronics.ru/part/pr...3s-mp2307.html

  10. #50
    Администратор Аватар для Chip
    Регистрация
    08.06.2007
    Возраст
    54
    Сообщений
    13,379
    Вес репутации
    10

    По умолчанию Re: Питание Arduino в авто

    Цитата Сообщение от Biker Посмотреть сообщение
    Посчитал резисторы при питании от 5V получились R1=38 Ом; R2=12 Ом
    Эта схема подойдёт мне? Не чего ненаврал?
    Это откуда такая схема? Явно рисовал человек плохо разбирающийся в электронике

    Нажмите на изображение для увеличения. 

Название:	cam_on1.PNG 
Просмотров:	923 
Размер:	8.2 Кб 
ID:	18109
    Последний раз редактировалось Chip; 15.10.2014 в 16:44.

Страница 5 из 6 ПерваяПервая 123456 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •