Питание Arduino в авто
- Войдите на сайт для отправки комментариев
Пнд, 16/04/2012 - 16:46
Каковы варианты решения правильного питание ардуины в авто?
Заказываю Arduino Mega ADK, хочу, пока будет ехать, решить вопрос с питанием. По ссылке пишут:
Input Voltage (recommended) 9V
Input Voltage (limits) 7-18V
The board can operate on an external supply of 5.5 to 16 volts. If supplied with less than 7V, however, the 5V pin may supply less than five volts and the board may be unstable. If using more than 12V, the voltage regulator may overheat and damage the board. The recommended range is 7 to 12 volts.
Надо именно 9В, жрать будет 0.7-1.5А.
Если вы просто подключите дуину к бортой сети автомобиля, то стабилизатор на дуине будет очень сильно греться. Можно поставить промежуточный стабилизатор на 9 вольт, например LM7809.
http://www.ebay.com/itm/251019100818?ssPageName=STRK:MEWNX:IT&_trksid=p3...
http://www.ebay.com/itm/330694777838?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1439.l2649#ht_1375wt_1270
Купил http://item.taobao.com/item.htm?id=13688667509 , выставил 9V, но при включении Arduino виснет, приходится жать RESET.
Такое чувство, что источник питания плавно и медленно набирает напряжение и ардуина виснет, а может что-то еще...
Подскажите реальный вариант для питания ардуины в авто.
Во втором посту - аналог моему.
В третьем посту - выдает 5-6В, а для ардуины нужно минимум 7.
Ну почему же, дуину можно питать и от 5 вольт. А преобразователь вещь хорошая, но дорогая по сравнению со стабилизатором. Что бы дуина стартовала с задержкой попробуйте поставить конденсатор между землей и ресетом, чем выше емкость тем позже дуина будет стартовать.
а как быть если необходимо управлять именно 12 вольтовым оборудованием?
Смотря чем управлять
фарой к примеру, без реллея тут видимо не обойтись. Пытаемся связать мотоцикл и андоройд, если со входими все боль менее понятно , то с силовым оборудованием и как лучше подавать питание на саму ардуину, а то начитался про глюки с запуском что мол только через выпрямитель.
по ссылке из первого поста
Input Voltage (recommended) 7-12V
Input Voltage (limits) 6-20V
или у вас какая то особенная мега?
и не ставьте вы китайские dc-dc преобразователи, если нет возможности проверить, что на выходе.
а управлять нагрузкой, получилось, что РЭС80 -03 можно сажать прям на цифровой выход дуины без ограничительных резисторов (ток 35мА), но ток коммутации не более 1 А
Думаю что Вам Relay Module нужно использовать
ничего особенног мега адк, думаю просто поставить советский стабилизатор крен-9. по поводу рэс80 маловато в описании подцветки in 0.12A (Ipulse 1,2)
как раз вчера нашел, жалко что нет в продаже таких реллейев сразу выхода на 4, во всяком случаи на российских сайтах.
для автомобильной коммутации нужно 5-10А и более, а это в любом случае одноступенчатым решением не осилить, маленькое реле должно управлять большим, маленький транзистор раскачивать большойм и т.п.. разве что на каких нибудь твердотельных удастся вырулить(но я пока приемлемых не нашел, или дорогие или параметры г.)
По-моему, реллеймодуль очень даже, и не надо ни каких многоступенчатых решений.
так посмотрите конструкцию модуля, она как раз многоступенчатая и есть. если для вас оно легко доступно и не нужно 2 месяца с ебэя ждать, то почему бы и нет.. но для моего города это не так (или по тройной цене).
Кстати, если хотите преобретать релейный модуль с питанием реле от 12 вольт советую почитать вот эту тему.
фарой к примеру, без реллея тут видимо не обойтись. Пытаемся связать мотоцикл и андоройд, если со входими все боль менее понятно , то с силовым оборудованием и как лучше подавать питание на саму ардуину, а то начитался про глюки с запуском что мол только через выпрямитель.
про релейный модуль написали уже, кроме этого еще как вариант MOSFET транзистор, они позволяют управлять многоамперными нагрузками
При питании ардуины от USB мой скетч работает отлично.
при питании от VIN (~7,7 V) идут задержки в выполнении скетча, т.е. шаговый двигатель запускается с задержкой около 1 сек после нажатия кнопки, потом при нажатии кнопки опять 1 сек. думает и запускает двигатель. При питании от USB задержек нет вообще...
Как такое может быть?
А скейтч можно посмотреть? и опишите подробнее что и как подключено к дуине.
Скетч управления КПП. Состав: два шаговых двигателя и два контроллера для них, 6 датчиков холла, блок питания ардуины, актуатор, блок из 8ми реле, также подключен шифтер для переключения КПП от игрового руля Logitech. Питание шаговых двигателей и блока питания ардуины пока от старого блока питания ПК.
Все работает отлично при питании ардуины от USB, при питании от блока питания ардуины - идут задержки.
Фотки, для лучшего понимания:
http://big-e.ru/images/Gallery/preview_ex.php?dir=Robot
Подробное описание в самом коде ниже.
#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 */ }раз уж разговор прошел про авто, может кто подскажет чем управляются воздуховодные заслонки климата в авто? не..ну понятно что какой-то двигатель, может кто смотрел?
Тоже надо переделать управление климатом, сейчас у меня все тросами регулируется. Есть шаговые но пока толком запустить их не удалось.