Код:
#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
*/
}
С благодарностью приму любые замечания по коду.