Исходник прошивки контроллера привода ворот

Nov 28, 2017 20:35


#define pPulse 2 //Пульс таходатчика
#define pOpenESP 12 //Команда открытия ворот от ESPхи
#define pCloseESP 11 //Команда закрытия ворот от ESPхи
#define pOpenMan 9 //Кнопка открытия ворот, инвертированная!
#define pCloseMan 10 //Кнопка закрытия ворот, инвертированная!
#define pPowerRelay 13 //Силовое общее реле, размыкает оба полюса
#define pReverceRelay 4 //Реле реверса, переключает обмотки двгателя
#define pPower 3 //Выход для тиристорного ключа
#define aBorder 1 //Аналоговый вход для уовня напряжения с герконов
#define pSensZero 5 //Датчик 0

#define FullPower 60 //Максимальная мощность мотора

#include

unsigned int CntPulse = 0;

bool bPulseHigh = false;
unsigned int TimePulse = 0;
long PercentPower = 0;

void setup()
{
pinMode(pPowerRelay, OUTPUT);
pinMode(pReverceRelay, OUTPUT);
pinMode(pPower, OUTPUT);
pinMode(pPulse, INPUT);
pinMode(pOpenESP, INPUT);
pinMode(pCloseESP, INPUT);
pinMode(pOpenMan, INPUT);
pinMode(pCloseMan, INPUT);
pinMode(pSensZero, INPUT);

Serial.begin(9600);
Serial.println("Init ok");
Serial.println(analogRead(aBorder));
if (GateState() == 0)
Serial.println("State - ERROR!!!");
if (GateState() == 1)
Serial.println("State - Open");
if (GateState() == 2)
Serial.println("State - Close");
if (GateState() == 3)
Serial.println("State - Neytral");
}

void loop()
{
//Обработка открытия
if (ComfirmCommand(pOpenESP, true) || (digitalRead(pCloseMan) && ComfirmCommand(pOpenMan, false))) //Нажали кнопку открытия
{
Serial.println("Command Open");
if (CntPulse == 0) //Режим ожидания
{
if (GateState() == 2 || GateState() == 3) //Закрыто или середина
{
Serial.println("Start Open");
digitalWrite(pReverceRelay, HIGH);
pStart();
}
else //И так открыто. Ничего делать и не надо
{
Serial.println("Command ignore");
delay(500);
}
}
else
{
if (IsClosing()) //Сейчас закрываем - останавливаем процесс
{
Serial.println("Manual stop");
pStop(false);
}
}
}

//Обработка закрытия
if (ComfirmCommand(pCloseESP, true) || (digitalRead(pOpenMan) && ComfirmCommand(pCloseMan, false))) //Нажали кнопку открытия
{
Serial.println("Command Close");
if (CntPulse == 0) //Режим ожидания
{
if (GateState() == 1 || GateState() == 3) //Открыто или середина
{
Serial.println("Start Close");
pStart();
}
else //И так закрыто. Ничего делать и не надо
{
Serial.println("Command ignore");
delay(500);
}
}
else
{
if (!IsClosing()) //Сейчас открываем - останавливаем процесс
{
Serial.println("Manual stop");
pStop(false);
}
}
}

if (CntPulse > 0) //Если счётчик стронулся - считаем что пошёл процесс открывания/закрывания
{
pRun();
}
else
{
//ну... шобы наверняка. Тушим свет, сливаем воду.
digitalWrite(pPower, LOW);
digitalWrite(pPowerRelay, LOW);
digitalWrite(pReverceRelay, LOW);
}

}

//Вернёт состояние ворот.
byte GateState()
{
if (analogRead(aBorder) > 400 && analogRead(aBorder) < 500)
return 1; //Открыто
if (analogRead(aBorder) > 550 && analogRead(aBorder) < 650)
return 2; //Закрыто
if (analogRead(aBorder) > 750 && analogRead(aBorder) < 850)
return 3; //Серединнное положение

return 0; //Ошибка!
}

//Вернёт, закрываем ли мы сейчас ворота?
bool IsClosing()
{
return !digitalRead(pReverceRelay);
}

//Разгон мотора
void pStart()
{
digitalWrite(pPowerRelay, HIGH);
delay(100);
Serial.println("Servo Start");
for (long i = 0; i < 15000; i++)
{
PercentPower = FullPower * (i / 150) / 100;
SetPower();
}
Serial.println("...Started");
CntPulse = 1;
}

//Рабочий ход мотора
void pRun()
{

PercentPower = FullPower;
SetPower();

TimePulse ++;
if (bPulseHigh != digitalRead(pPulse))
{
bPulseHigh = !bPulseHigh;
TimePulse = 0;
CntPulse ++;
}

if (TimePulse > 300)
{
pStop(true);
Serial.println("No pulse!");
return;
}

//Аварийная остановка по времени работы
if (CntPulse == 4000)
{
Serial.println("Max CntPulse!");
pStop(true);
}

if (CntPulse == 150)
{
//Аварийные остановки по неразмыканию герконов после запуска
if (IsClosing() && GateState() == 1)
{
Serial.println("Closing failed!");
pStop(true);
}

if (!IsClosing() && GateState() == 2)
{
Serial.println("Opening failed!");
pStop(true);
}
}
if (IsClosing() && GateState() == 2)
pStop(false);

if (!IsClosing() && GateState() == 1)
pStop(false);
}

//Остановка мотора. Флаг - резкая остановка, или плавная
void pStop(bool bForced)
{
if (bForced)
Serial.println("Servo Stop Forced");
else
Serial.println("Servo Stop");

if (!bForced)
{
for (long i = 0; i < 30000; i = i + 15)
{
PercentPower = FullPower - FullPower * (i / 300) / 100;
SetPower();
}
}

PercentPower = 0;
MsTimer2::stop();
digitalWrite(pPower, LOW);
delay(50);
digitalWrite(pPowerRelay, LOW);
digitalWrite(pReverceRelay, LOW);
Serial.print("CntPulse = ");
Serial.println(CntPulse);
CntPulse = 0;

}

// Установка мощности мотора.
void SetPower()
{
if (digitalRead(pSensZero) == HIGH) //Всё взводится только если сейчас 0!
{
MsTimer2::stop();
digitalWrite(pPower, LOW);

//Serial.println(PercentPower);

if (PercentPower <= 0 || PercentPower > 100)
return;

unsigned long ms = 6 - (PercentPower * 6 / 100); //А 6мс потому, что датчик 0 не идеален и уже проходит некоторое время до того, как напряжение будет достаточно большое для загорания светодиода в оптоаре.

MsTimer2::set(ms, PowerControl);
MsTimer2::start();
}

}

//Функция избавления от дребезга контактов и импульсных помех
bool ComfirmCommand(int button, bool ActiveHigh)
{
for (byte i = 0; i < 150; i++)
{
if (digitalRead(button) == (ActiveHigh? LOW : HIGH))
{
delayMicroseconds(500);
return false;
}
}
return true;
}

//Метод вызывается из перывания по таймеру и тупо активирует тиристорный ключ.
void PowerControl()
{
digitalWrite(pPower, HIGH);
}

#include, #define

Previous post Next post
Up