Показано с 1 по 10 из 69

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #23
    Продвинутый
    Регистрация
    20.12.2011
    Сообщений
    336
    Вес репутации
    238

    По умолчанию Re: Управление полным приводом

    После долгой паузы работа над проектом продолжена.
    Уточнены условия работы полного привода (ПП).

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

    Проект оброс мясом и сейчас выглядит следующим образом.
    Задачи:
    1. Включение муфты ПП по 3х позиционному переключателю "AUTO"-"4x2"-"4x4"
    - AUTO - режим работы муфты для распределения крутящего момента 75/25 (пер./задний мост)
    - 4х2 - муфта выкл.
    - 4х4 - режим работы муфты для распределения крутящего момента 60/40 (пер./задний мост)
    - звуковое оповещение о вкл. муфте (реализовано)
    - индикация о вкл. муфте на панели приборов (реализовано)
    2. Управление видеокамерами (задняя, две боковые мертвых зон) - от сигнала заднего хода и при включении поворотников, доп. управление (переключение) камерами с рулевых кнопок (было реализовано, в наст. момент в доработке)
    3. Управление Головным устройством (ГУ) с рулевых кнопок через ИК передатчик - "+/-" звук, след. трек.
    4. Индикация на ЖКИ панели приборов рекомендуемой передачи КПП в зависимости от скорости движения (было реализовано, в наст. момент в доработке)

    Реализация:
    В проекта использованы модули:
    - Seeeduino Mega 1280 (http://www.seeedstudio.com/wiki/Seeeduino_Mega)
    - Monster moto shield (http://arduino.ru/forum/programmirov...er-moto-shield)
    - 8 Relay Shield (http://big-e.ru/images/4х4_arduino/8...e-Arduino1.jpg)
    - Шилд питания
    - ИК передачик от пульта TV
    - Отдельные решения ввода-вывода сигналов

    Эл. схема проекта: http://big-e.ru/images/4х4_arduino/1.pdf
    Фото готового модуля:
    http://big-e.ru/images/4х4_arduino/P1040464.JPG
    http://big-e.ru/images/4х4_arduino/P1040465.JPG
    http://big-e.ru/images/4х4_arduino/P1040466.JPG
    Скетч (пока в отладке, основные моменты работают):
    Код:
    //#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); 
    }
    Спасибо огромное отзывчивому и крайне терпеливому Администратору данного сайта.
    Которого и прошу с пристрастием посмотреть схему и скетч.

    Сильно тормозит работу TVout от которого видимо придется отказаться.
    Последний раз редактировалось kadushkin; 07.01.2016 в 23:54.

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

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

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

Ваши права

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