запустить действие на нужное время и заблокировать переменную

maxvalin
Offline
Зарегистрирован: 22.02.2016

Есть такая вот задача

при смене состояние "кнопки"

зафиксировать флаг аварии на 0  на пол секунды.

Вот сижу и ломаю голову... как так поступить..

 

if (PrevKonvFlag != KonvFlag )
     {
      FlagAlarm = 0;
      if (millis() - PauseAlarmkonveyor >500)
           {
            PauseAlarmkonveyor = millis();
            пока идет 500 то FlagAlarm = 0  ;      
            }
      PrevKonvFlag != KonvFlag;
     }

В принципе во время переключения конвеера псторонних функций которые включали бы аварию- нет. Включает аварию чисто из-за помех, скетч пишу без делаев, возможно из-за этого

maxvalin
Offline
Зарегистрирован: 22.02.2016

здесь ошибка

09 PrevKonvFlag != KonvFlag;
 
     }
PrevKonvFlag = KonvFlag
 
подумываю ресетить(FlagAlarm = 0) внешней релюшкой, на которую при смене состояний подается напряжение на определенное время. Это стабильней конечно будет но подход далеко не симпатичный((
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вот у Вас все посты одинаковые. Вы когда-нибудь научитесь формулировать задачу, чтобы её понимал кто-нибудь кроме Вас? Выньте жвачку изо рта и скажите внятно что-нибудь вроде такого:

1. Имеется флаг, который в нормальнос момстоянии - false;
2. Нужна процедура, которая взводит его в состояние true;
3. Будучи взведён он остаётся true в течение времени Т, независимо от того проверяет его кто-то или нет;
4. Через время Т он снова становится false
5. Если после взведения, но до истечения времени T, его взведут ещё раз, то время T заново начинает отсчитываться с момента последнего взвода.

Вот примерно так опишите задачу.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

maxvalin пишет:

Есть такая вот задача

при смене состояние "кнопки"

зафиксировать флаг аварии на 0  на пол секунды.

Примерно так, навскидку:

bool isAlarmFlag = false;
unsigned long alarmStartTime;
uint8_t currentButtonFlag = 0;
uint8_t  lastButtonFlag = 0;

void loop()
{
	currentButtonFlag = digitalRead(buttonPin);

	if(lastButtonFlag != currentButtonFlag && !isAlarmFlag)
	{
		lastButtonFlag = currentButtonFlag;
		isAlarmFlag = true;
		alarmStartTime = millis();
	}
	
	if(isAlarmFlag && millis() - alarmStartTime > 500)
	{
		isAlarmFlag = false;
	}
}

 

maxvalin
Offline
Зарегистрирован: 22.02.2016

"Вот у Вас все посты одинаковые. Вы когда-нибудь научитесь формулировать задачу, чтобы её понимал кто-нибудь кроме Вас?"

 

-в точку.... сам вижу когда перечитываю(такое ощущение что писал мастер еда из звездных войн.

но мышление не стандартное, как то врач сказал- с таким жить можно)))

 

p.s

Сейчас проверю пример из 3 поста

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

maxvalin пишет:

Сейчас проверю пример из 3 поста

Лучше задачу чётко сформулируйте :))))

Пока толком не знаете куда плыть, ни один ветер не попутный :)

maxvalin
Offline
Зарегистрирован: 22.02.2016

Есть:

uint8_t FlagAlarm = 0; // флаг аварии 0 если все ok , от кнопки RESET тоже
#define ButtonResset 49 //ВХОД Кнопка Сброса Аварии на пульту оператора Желтая


и вот есть задача

if    кнопка (49)меняет свое состояние (важно!)

        {

          FlagAlarm становится НОЛЕМ на 1 секунду (не через секунду и не циклом а разово)

         {

вот в принципе и все. ну и без делаев естественно)) 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, я же Вам привёл пример. ВОт скажите, а что если в течение этой секунды кнопка ещё раз нажмётся? И ещё - кто делает Ваш флаг единицей?

maxvalin
Offline
Зарегистрирован: 22.02.2016

Пусть нажимется хоть это и исключено , это образно кнопка ресет. а вообще я подставлю эту операцию при срабатывании поворотных механизмов - они вертятся больше 3-ох секунд а дребезга на входе нет, так как входа через оптроны с подтяжкой. Во время переворота или обратно флаг аварии будет 0.

 этот флаг аварии меняется от состояния концевиков этих же поворотных механизмов. Но в момент переворота на самом деле аварии нет. там все сделанно чтоб это учитывалось (и я это уже отловил). Но ошибка появляется, возможно из-за модуля реле так как он лежит прям рядом возле арды, потому как вываливается после отключения 4ох катушек реле.Но суть в том что все равно хочу убрать этот не красивый момент. 

по вашему примеру я не смогу описать((

не умею 

maxvalin
Offline
Зарегистрирован: 22.02.2016

ЕвгенийП пишет:

 

1. Имеется флаг, который в нормальном состоянии = 0;
2. При изменении состояния кнопки флаг = 0;
3. Будучи взведён он остаётся =0 в течение времени Т, независимо от того проверяет его кто-то или нет;
4. Через время Т он просто свободен
5. Если после взведения, но до истечения времени T, его взведут ещё раз, то пофиг.

Вот примерно так .

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вот что такое "просто свободен"? Равен 1 или пофиг чему он равен? Мы сами его хоть когда-нибудь делаем не нулём?

maxvalin
Offline
Зарегистрирован: 22.02.2016

тоисть его другие функции уже меняют как хотят. а пока взведен- он блокируется.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ооооо, тока щас дошло. Так его ещё и блокировать надо.

Без изменения других функций этого не сделать никак.

Вообще, тут нужен класс переопределённой операцией присваивания. Чтобы при присваивании проверялись условия и он соответсвенно менялся или нет.

maxvalin
Offline
Зарегистрирован: 22.02.2016

O_o ладно, тогда просто взводить на 0 при изменении сотояния кнопки на 1 сек. На остальное не смотреть. если после него что опять его изменит то пусть меняет. 

...мялть.. вот пишу и сам уже понимаю что дошел до  что сам могу себе ответить.,

if (старое состояние кнопки !=  сотоянию кнопки)

{

FlagAlarm = 0;

старое состояние кнопки = равно состоянию кнопки;

}

и какой нафиг одна секунда нужна, если МК и так это будет держать до нового события которе этот флаг заменит на то что ему надо и без указаной одной секунды. ведь суть регистров такова что они взяли и держут. сами не изменят.

ладно, тогда самый простой способ следить за изменинием кнопки ( в разделе про кнопки есть все кроме этого) 

maxvalin
Offline
Зарегистрирован: 22.02.2016

ЕвгенийП пишет:

Вообще, тут нужен класс переопределённой операцией присваивания. Чтобы при присваивании проверялись условия и он соответсвенно менялся или нет.

ага. еще один флаг

и в каждой функции в конце дописывать (где затронут флаг аварии) что если есть этот флаг верно то изменять флаг аварии на ноль. тогда получается мнимая блокировка. тоисть . это я сначала так думал развивать идею. Но так как у меня ловит помехи а не условия то сейчас если программно не удасться, то есть уже модули спец. там релюха с таймером (оф-делайн), наверное как раз для таких ситуаций сделано было.  

вообще сейчас вот поварил немного, оптимально будет так: что после изменения состояния кнопки переменная тупо внаглую пишется нолем пол секунды постоянно и все. даже если дальше по циклу ее в эти пол секунды все равно что-то попытается переписать то один фиг устройства не успеют сработать. 

вот как реализовать действие сие... Прошу подсобить. 

maxvalin
Offline
Зарегистрирован: 22.02.2016

Пока остановился на этом:

currentButtonFlag = KonvFlag;
  if(lastButtonFlag != currentButtonFlag) 
  {
    lastButtonFlag = currentButtonFlag;// предыдущий флаг равен текущему
        if( millis() - MilKonvPause > 500)
      {
        MilKonvPause = millis();
        FlagAlarm = 0;
        digitalWrite(Alarmlamp1, HIGH);
        digitalWrite(Alarmlamp2, HIGH);
        digitalWrite(Alarmlamp3, HIGH);
        digitalWrite(Alarmlamp4, HIGH);
        digitalWrite(Alarmlamp5, HIGH);
      }
    
  }

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

но вопрос выше остается актуален.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

maxvalin пишет:

и в каждой функции в конце дописывать 

Да, нет, конечно. Ничего дописывать не надо. Надо создать собственный тип данных, который адекватно реагирует на присваивание.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вот по этой причине я предлагаю переходить от связки "заказчик"-"программист" к связке "заказчик"-"посредник"-"программист". даже если все это один человек.  "Заказчик" четко должен выложить свои хотелки, потом "посредник" должен выявить структуру, и наконец "программист" приступить к коду, предварительно ознакомившись со структурой и выявить ту часть, где нужен код, а где просто контент. С одной стороны замедленый старт, но зато нет таких тупоков, которые показывает ТС.

maxvalin
Offline
Зарегистрирован: 22.02.2016

тс в первую очередь вообще то для себя пытается понять.

и показывает на что знаний хватает.

тут пол форума тупаки показывает и что? всех в заказчики?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Bот вам и говорю где у вас тупаки. У вас неправильный подход к написанию программы. Да и у большинства постящих на форуме посты тоже. Я тоже из таких тупаков вылазил.  Попробую на аналогиях. Вы наверно выдели... книгу в бумаге. Писатель написал, читатели читают. И где здесь аналогия работы "программиста".  Так вот наборщик,типографщик и переплетчик и есть эта работа. Получается блок бумаги- вот это и есть оптимальный код.  Как ардуинщики лепят программы. Так они лепят куски из разных источников. Где-то отрывок из конспекта, где-то бумага из под рыбы, где-то вообще кусок туалетной бумаги из мусорника. Залить клеем , скрепками и скотчем и готово. Вот только не все можно открыть и прочитать.   

Отвлекся . Отделяйте код программы от контента . И не надо это смешивать .

maxvalin
Offline
Зарегистрирован: 22.02.2016

qwone пишет:

Отвлекся . Отделяйте код программы от контента . И не надо это смешивать .

вон оно что...))

подскажите тогда как задавать подобные вопросы как в 14 посту. (последний вопрос) там нет кода но вопрос именно по программированию.

Вообще самому не нравится когда код в тексте. не читаемо. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

maxvalin. У вас проблемма не в программировании. Синтаксис Си и Си++ достаточно простой.  Что такое программирование- переложение решения задачи на язык кода.  Контент это не только текст, картинки, по и выполнение некоторой последовательности на внешнюю среду. С использованием delay() все просто . Там идет жесткая последовательность. С millis() немного иначе. Создается тип данных в которую пишется контент. И потом автомат ее проигрывает. Или перестает проигрывать и переключается на другой контент.

maxvalin
Offline
Зарегистрирован: 22.02.2016

: что после изменения состояния кнопки переменная тупо внаглую пишется нолем пол секунды постоянно и все. даже если дальше по циклу ее в эти пол секунды все равно что-то попытается переписать то один фиг устройства не успеют сработать.

Как же быть с этим вопросом? На пальцах можно хотя бы? Как работают миллисы я кое-как понял и активно использую. Но разница большая между тем как что-то сделать после определенного периода и делать что то определенный период.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

maxvalin пишет:
Как работают миллисы я кое-как понял и активно использую. Но разница большая между тем как что-то сделать после определенного периода и делать что то определенный период.

 Никакой. #147   Просто вы не до конца разобрались. Вот и разница у вас есть между тем, что вы кое как умеете и тем за что вы не брались.

ПС: это тоже не идеал. Но все же вам на подумать.

Logik
Offline
Зарегистрирован: 05.08.2014

maxvalin пишет:
:  Но разница большая между тем как что-то сделать после определенного периода и делать что то определенный период.
 Вобщем никакой разницы. Тему прочитал. Печально все. Не тужтесь, писать код - не Ваше. Мозги не так работают, не тот ход мысли. Потому и излогаете задачу так криво. Скорей всего переучиватся позно. Во мне весу за центнер, если я натяну лосины и балет танцевыть выйду что будет? Вот и Ваши рассуждения гдето так выглядят. Без обид, я просто пытаюсь Вам ваше время и силы экономить.

Logik
Offline
Зарегистрирован: 05.08.2014

qwone, кончайте издеватся со своим "от связки "заказчик"-"программист" к связке "заказчик"-"посредник"-"программист". даже если все это один человек. " У ТС и так мозги выворотом, а Вы ему еще свое мутное "3 in 1" парите. Проявите гуманизм.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Logik, это нормальное бушидо для программистов. Эсли человек не сможет разобраться в аллегориях и метафорах, то как он сможет разобраться в скетче. 

ПС: для "продвинутых" : программа это текст аллегорий и метафор написаных на языке программирования. Это так просто. 

maxvalin
Offline
Зарегистрирован: 22.02.2016

Елы палы и в третий раз он пошел в лез за елкой))
Вы можете отодвинуть свои алегории немного в сторону и ответить наконец то на совсем легкий вопрос (для вас)
Если (что то)
{
Сразу Выполняю одно и тоже действие Т время. Цыкл за циклом.
}

Я не претендую на что то если что. Все делаю для себя. И стараюсь как могу. Хотя бы за это проявите уважение)
Чтобы мне помочь не надо говорить какой я танцор, укажите где хирург лучше)))))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

maxvalin, в том то и дело, что нельзя пойти в лес за елкой только с помощью одной ноги и одной руки, а остальное оставить дома, что бы не мерзло. В лес приходится идти целиком.  А если еще рациональнее , то совмещать этот поход в лес с какой-то работой. А вот если вы совместите поход в лес с просмотром футбола на диване у телевизора. То или елки не будет , или футбол не увидите.  Это я к тому, что скетч должен быть целиком , а не кусочками.

Logik
Offline
Зарегистрирован: 05.08.2014

maxvalin пишет:
Елы палы и в третий раз он пошел в лез за елкой)) Вы можете отодвинуть свои алегории немного в сторону и ответить наконец то на совсем легкий вопрос (для вас) Если (что то) { Сразу Выполняю одно и тоже действие Т время. Цыкл за циклом. } Я не претендую на что то если что. Все делаю для себя. И стараюсь как могу. Хотя бы за это проявите уважение) Чтобы мне помочь не надо говорить какой я танцор, укажите где хирург лучше)))))

Один большой цикл в нем

{

   проверим выполняется ли действие, если да

  {

       проверим не истекло ли время выполнения действия если да

     {

        выполняем действие

     } иначе 

    {

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

    }

  } иначе  

  {

    проверим нужно ли начать делать Действие, если да

   {

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

   }

  }

}

 

Понаблюдайте за собой. По такому алгоритму люди делают практически все длительные операции: варят еду, сушат белье и т.д. Делеев в жизни почти нет, разве что в очереди ждать чего.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Добавлю код

/**/
unsigned long mill; // переменная под millis()
//--------------------------------
bool stat_Act1 = 0; // 1 делаем что-то длительно / 0 ничего не делаем
unsigned long past_Act1, time_Act1; // время начала и длительность 
//---main-----------------------------
int main() {
  init();
  //setup()
  Serial.begin(9600);
  stat_Act1 = 1;//запустить действие
  past_Act1 = mill;// зафиксировать начало
  time_Act1 = 500;// установить длительность 0,5 сек

  for (;;) {
    //loop()
    mill = millis();
    // обработка действия Act1
    if (stat_Act1) {
      if (mill - past_Act1 >= time_Act1)
        stat_Act1 = 0;// если время истекло, то остановить действие
      else
        Serial.print("Do_Act1"); // выполнить текущую часть длит процесса
    }
  }
}
/*Скетч использует 1534 байт (4%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 203 байт (9%) динамической памяти, оставляя 1845 байт для локальных переменных. Максимум: 2048 байт.
*/

Но вот какая проблема, код вроде есть и работает, но вот он скорее всего не впишется в вашу программу.

maxvalin
Offline
Зарегистрирован: 22.02.2016

домашние проблемы не дают присесть((

значит вот то что наскрябал я.(не хотелось это вываливать ибо читать все мало кому захочется.

Надеюсь не надо повторять кто это писал и если плевать то мысленно!

 

//OLED
#include <SPI.h>
#include <OLED_I2C.h>     // подключение библиотеки для OLED
OLED  myOLED(9, 10);       // подключение дисплея 9 SDA  10 SCK
extern uint8_t RusFont[]; // Русский шрифт
extern uint8_t SmallFont[];  // маленький шрифт
extern uint8_t MediumNumbers[]; //средний шрифт
extern uint8_t MegaNumbers[]; 
extern uint8_t MediumFont[];
extern uint8_t BigNumbers[];  //большой шрифт






#define pnewReflek1 2 //ВЫХОД реле включения рефлектора №1
#define pnewReflek2 3 //ВЫХОД реле включения рефлектора №2
#define pnewReflek3 4 //ВЫХОД реле включения рефлектора №3
#define pnewReflek4_5 5 //ВЫХОД реле включения рефлектора №4 5
#define testSwitchReflek  7 //ВХОД тест наличия напряжения 24 DC на концевики рефлекторов.
#define testPneumReflek  8 //ВХОД тест наличия напряжения 220 AC на пневмораспределители рефлекторов
#define BlinkReadGood 13//ВЫХОД Мигает на панели оператора символизируя что программа работает, с процессором все хорошо.

#define ButtonLamp1  22 //ВХОД кнопка ключения лампы №1
#define ButtonLamp2  23 //ВХОД кнопка ключения лампы №2
#define ButtonLamp3  24 //ВХОД кнопка ключения лампы №3
#define ButtonLamp4  25 //ВХОД кнопка ключения лампы №4
#define ButtonLamp5  26 //ВХОД кнопка ключения лампы №5

#define Tahometr  27 //ВХОД тахометры крутятся
#define ConveyorGo  28 //ВХОД Конвеер работает

#define OpenReflek1  29 //ВХОД рефлектор закрыт на 1 лампе
#define ClosedReflek1  30 //ВХОД рефлектор открыт на 1 лампе
#define OpenReflek2  31 //ВХОД рефлектор закрыт на 2 лампе
#define ClosedReflek2  32 //ВХОД рефлектор открыт на 2 лампе
#define OpenReflek3  33 //ВХОД рефлектор закрыт на 3 лампе
#define ClosedReflek3  34 //ВХОД рефлектор открыт на 3 лампе
#define OpenReflek4  35 //ВХОД рефлектор закрыт на 4 лампе
#define ClosedReflek4  36 //ВХОД рефлектор открыт на 4 лампе
#define OpenReflek5  37 //ВХОД рефлектор закрыт на 5 лампе
#define ClosedReflek5  38 //ВХОД рефлектор открыт на 5 лампе

#define GoLamp5 39 //ВЫХОД запуск лампы №5
#define GoLamp4 40 //ВЫХОД запуск лампы №4
#define GoLamp3 41 //ВЫХОД запуск лампы №3
#define GoLamp2 42 //ВЫХОД запуск лампы №2
#define GoLamp1 43 //ВЫХОД запуск лампы №1

#define Alarmlamp5  44 //ВЫХОД авария лампы 5
#define Alarmlamp4  45 //ВЫХОД авария лампы 4
#define Alarmlamp3  46 //ВЫХОД авария лампы 3
#define Alarmlamp2  47 //ВЫХОД авария лампы 2
#define Alarmlamp1  48 //ВЫХОД авария лампы 1
#define ButtonResset 49 //ВХОД Кнопка Сброса Аварии на пульту оператора Желтая

/////////////для мигания светодиода на панели оператора
uint8_t ledState = LOW;     // этой переменной устанавливаем состояние светодиода
uint32_t MillisLed = 0;  // храним время последнего переключения светодиода
uint16_t intervalLed = 1000;  //интервал мигания светодиода 

///////переменные
uint8_t FlagAlarm = 0; // флаг аварии 0 если все ok , от кнопки RESET тоже
boolean alarmMigFlag = false; // флаг для состояния сигнала миганий маяков, подставляю  нужный маяк под состояние этого флага
boolean PauseEror = false; //флаг, пока он есть то флаг аварии = 0
uint32_t MillPauseEror = 0; //переменная для милисов флага RESET 
///чтоб убрать аварии при пуске стопе конвеера
uint8_t currentButtonFlag = 0;  /////текущий флаг состояния конвеера
uint8_t  lastButtonFlag = 0; /// предыдущее состояние флага конвеера
uint32_t MilKonvPause = 0; //переменная для милисов флага RESET


boolean KonvFlag = false;// флаг для состояния конвеера
boolean BTNFlag1 = false;// флаг кнопки запуска лампы №1
boolean BTNFlag2 = false;// флаг кнопки запуска лампы №2
boolean BTNFlag3 = false;// флаг кнопки запуска лампы №3
boolean BTNFlag4 = false;// флаг кнопки запуска лампы №4
boolean BTNFlag5 = false;// флаг кнопки запуска лампы №5
boolean TesSwiRef24 = false;// флаг ЕСТЬ ЛИ НАПРЯЖЕНИЕ 24 НА КОНЦЕВИКИ РЕФЛЕКТОРОВ 
boolean TesPnewRef220 = false;// флаг есть ли 220 на пневмораспределители рефлекторов
boolean TahoFlag = false;// флаг состояние тахометров
boolean ConvFlag = false;// флаг состояние конвеера 
boolean OpeRefFlag1 = false;// флаг ОТКРЫТ РЕФЛЕКТОР 1
boolean ClosRefFlag1 = false;// флаг ЗАКРЫТ РЕФЛЕКТОР 1
boolean OpeRefFlag2 = false;// флаг ОТКРЫТ РЕФЛЕКТОР 2
boolean ClosRefFlag2 = false;// флаг ЗАКРЫТ РЕФЛЕКТОР 2
boolean OpeRefFlag3 = false;// флаг ОТКРЫТ РЕФЛЕКТОР 3
boolean ClosRefFlag3 = false;// флаг ЗАКРЫТ РЕФЛЕКТОР 3
boolean OpeRefFlag4 = false;// флаг ОТКРЫТ РЕФЛЕКТОР 4
boolean ClosRefFlag4 = false;// флаг ЗАКРЫТ РЕФЛЕКТОР 4
boolean OpeRefFlag5 = false;// флаг ОТКРЫТ РЕФЛЕКТОР 5
boolean ClosRefFlag5 = false;// флаг ЗАКРЫТ РЕФЛЕКТОР 5
boolean RessetFlag = false;// флаг нажатия кнопки RESSET








///ДЛЯ МИЛЛИСОВ НА ПРОВЕРКУ ПОСЛЕ ОСТАНОВКИ ТРАНСПОРТЕРА- ЗАКРЫЛИСЬ ЛИ СЕКЦИИ
uint32_t PrevMilStLamp1 = 0;  
uint32_t PrevMilStLamp2 = 0;
uint32_t PrevMilStLamp3 = 0;
uint32_t PrevMilStLamp4 = 0;
uint32_t PrevMilStLamp5 = 0;
///ДЛЯ МИЛЛИСОВ НА ПРОВЕРКУ ПОСЛЕ ЗАПУСКА ТРАНСПОРТЕРА- ОТКРЫЛИСЬ ЛИ СЕКЦИИ
uint32_t PrevMilGOLamp1 = 0;
uint32_t PrevMilGOLamp2 = 0;
uint32_t PrevMilGOLamp3 = 0;
uint32_t PrevMilGOLamp4 = 0;
uint32_t PrevMilGOLamp5 = 0;
/// ДЛЯ МИЛЛИСОВ ТАХОМЕТРОВ
uint32_t FullTaho = 0;
/// ДЛЯ МИЛЛИСОВ НА ВЫКЛЮЧЕНИЕ ЛАМПЫ ЕСЛИ СЕКЦИЯ НЕ ЗАКРЫЛАСЬ
uint32_t AlarmClosLam1 = 0;
uint32_t AlarmClosLam2 = 0;
uint32_t AlarmClosLam3 = 0;
uint32_t AlarmClosLam4 = 0;
uint32_t AlarmClosLam5 = 0;
uint32_t PauseAlarmkonveyor = 0; // Пауза при старте и пуске конвеера чтоб убрать в этот момент флаг аварии на 0



/////////для маяков аварии
//задаю ритм, запись в таком ввиде для того чтоб все биты были видны! с права на лево
/////////////////////////////////////Авария №1
const uint8_t Alarm1 = ( ((uint8_t)B00000001) <<8 ) + B00000001;// к аварии номер 1
const uint16_t AlarmPeriod1 = 200; //Длительность точки, мс для аварии номер 1
    uint32_t AlarmPast1 = 0; // время послед переключения для аварии номер 1
    uint32_t AlarmMask1 = 0; //  указатель на бит в последовательности мигания
/////////////////////////////////////Авария №2
const uint32_t Alarm2 = ( ((uint32_t)B00110011) << 24) + ( ((uint32_t)B00110011) <<16 ) + ( ((uint32_t)B00110011) <<8 ) + B00110011;//к аварии номер 2
const uint8_t AlarmPeriod2 = 150; //Длительность точки, мс для аварии номер 2
    uint32_t AlarmPast2 = 0; // время послед переключения для аварии номер 2
    uint32_t AlarmMask2 = 0; //  указатель на бит в последовательности мигания
/////////////////////////////////////Авария №3
const uint32_t Alarm3 = ( ((uint32_t)B0000010) << 24) + ( ((uint32_t)B00010000) <<16 ) + ( ((uint32_t)B10000100) <<8 ) + B00100001;//к аварии номер 3
const uint8_t AlarmPeriod3 = 500; //Длительность точки, мс для аварии номер 3
    uint32_t AlarmPast3 = 0; // время послед переключения для аварии номер 3
    uint32_t AlarmMask3 = 0; //  указатель на бит в последовательности мигания
/////////////////////////////////////Авария №4
const uint32_t Alarm4 = ( ((uint32_t)B00000000) << 24) + ( ((uint32_t)B11111111) <<16 ) + ( ((uint32_t)B00000000) <<8 ) + B11111111;//к аварии номер 4
const uint8_t AlarmPeriod4 = 300; //Длительность точки, мс для аварии номер 4
    uint32_t AlarmPast4 = 0; // время послед переключения для аварии номер 4
    uint32_t AlarmMask4 = 0; //  указатель на бит в последовательности мигания    
/////////////////////////////////////Авария №5
const uint8_t Alarm5 = B01001001;//к аварии номер 5
const uint8_t AlarmPeriod5 = 200; //Длительность точки, мс для аварии номер 5
    uint32_t AlarmPast5 = 0; // время послед переключения для аварии номер 5
    uint32_t AlarmMask5 = 0; //  указатель на бит в последовательности мигания 

////////////для отладки на порт
uint32_t PortPreviosMil = 0;





void setup() {

  pinMode(pnewReflek1, OUTPUT);digitalWrite(pnewReflek1,HIGH);
  pinMode(pnewReflek2, OUTPUT);digitalWrite(pnewReflek1,HIGH); 
  pinMode(pnewReflek3, OUTPUT);digitalWrite(pnewReflek1,HIGH);
  pinMode(pnewReflek4_5, OUTPUT);digitalWrite(pnewReflek1,HIGH);
   
  pinMode (testSwitchReflek, INPUT); 
  pinMode (testPneumReflek, INPUT); 
  pinMode (BlinkReadGood, OUTPUT); 
  
  pinMode (ButtonLamp1, INPUT); 
  pinMode (ButtonLamp2, INPUT); 
  pinMode (ButtonLamp3, INPUT); 
  pinMode (ButtonLamp4, INPUT); 
  pinMode (ButtonLamp5, INPUT); 

  pinMode (Tahometr, INPUT);
  pinMode (ConveyorGo, INPUT);

  pinMode (OpenReflek1, INPUT);
  pinMode (ClosedReflek1, INPUT);
  pinMode (OpenReflek2, INPUT);
  pinMode (ClosedReflek2, INPUT);
  pinMode (OpenReflek3, INPUT);
  pinMode (ClosedReflek3, INPUT);
  pinMode (OpenReflek4, INPUT);
  pinMode (ClosedReflek4, INPUT);
  pinMode (OpenReflek5, INPUT);
  pinMode (ClosedReflek5, INPUT);

  pinMode (GoLamp5, OUTPUT);digitalWrite(GoLamp5,HIGH);
  pinMode (GoLamp4, OUTPUT);digitalWrite(GoLamp4,HIGH);
  pinMode (GoLamp3, OUTPUT);digitalWrite(GoLamp3,HIGH);
  pinMode (GoLamp2, OUTPUT);digitalWrite(GoLamp2,HIGH);
  pinMode (GoLamp1, OUTPUT);digitalWrite(GoLamp1,HIGH);

  pinMode (Alarmlamp5, OUTPUT); digitalWrite(Alarmlamp5,HIGH);
  pinMode (Alarmlamp4, OUTPUT); digitalWrite(Alarmlamp4,HIGH);
  pinMode (Alarmlamp3, OUTPUT); digitalWrite(Alarmlamp3,HIGH);
  pinMode (Alarmlamp2, OUTPUT); digitalWrite(Alarmlamp2,HIGH);
  pinMode (Alarmlamp1, OUTPUT); digitalWrite(Alarmlamp1,HIGH);

  pinMode (ButtonResset, INPUT);

 // myOLED.begin(); // инициализация экрана.

  ///для маяков
  AlarmMask1,AlarmMask1, AlarmMask1, AlarmMask1, AlarmMask1 = 0; //устанавливаем послед мигания в начало
  AlarmPast1, AlarmPast1, AlarmPast1, AlarmPast1, AlarmPast1 = millis();








  Serial.begin(9600);



  
}

void loop() 
{
  
///////мигание светодиода на панели оператора
uint32_t LedMillisNow = millis();
  
  //проверяем не прошел ли нужный интервал, если прошел то
  if(LedMillisNow - MillisLed > intervalLed) {
    // сохраняем время последнего переключения
    MillisLed = LedMillisNow; 
 
    // если светодиод не горит, то зажигаем, и наоборот
    if (ledState == HIGH)
      ledState = LOW;
    else
      ledState = HIGH;
 
    // устанавливаем состояния выхода, чтобы включить или выключить светодиод
    digitalWrite(BlinkReadGood, ledState);
  }
///////////////////////////////////////////////////////СОСТОЯНИЕ ВХОДОВ ПЕРЕВОЖУ В ПЕРЕМЕННЫЕ///////////////////////////////////////////////////////////////////
              //состояние КОНВЕЕРА ДЛЯ ФЛАГА
if (digitalRead(ConveyorGo) == LOW)
   KonvFlag = true; //если конвеер едет то флаг верно  
  else
   KonvFlag = false;// иначе - неверно.
             // состояние КНОПОК ЗАПУСКА ЛАМПЫ №1
if (digitalRead(ButtonLamp1) == LOW)
   BTNFlag1 = true; //если КНОПКА ЗАПУСКА ЛАМПЫ №1 флаг верно  
  else
   BTNFlag1 = false;// иначе - неверно.
            // состояние КНОПОК ЗАПУСКА ЛАМПЫ №2
if (digitalRead(ButtonLamp2) == LOW)
   BTNFlag2 = true; //если КНОПКА ЗАПУСКА ЛАМПЫ №2 флаг верно  
  else
   BTNFlag2 = false;// иначе - неверно.
            // состояние КНОПОК ЗАПУСКА ЛАМПЫ №3
if (digitalRead(ButtonLamp3) == LOW)
   BTNFlag3 = true; //если КНОПКА ЗАПУСКА ЛАМПЫ №3 флаг верно 
  else
   BTNFlag3 = false;// иначе - неверно.
            // состояние КНОПОК ЗАПУСКА ЛАМПЫ №4
if (digitalRead(ButtonLamp4) == LOW)
   BTNFlag4 = true; //если КНОПКА ЗАПУСКА ЛАМПЫ №4 флаг верно  
  else
   BTNFlag4 = false;// иначе - неверно.
            // состояние КНОПОК ЗАПУСКА ЛАМПЫ №5
if (digitalRead(ButtonLamp5) == LOW)
   BTNFlag5 = true; //если КНОПКА ЗАПУСКА ЛАМПЫ №5 флаг верно  
  else
   BTNFlag5 = false;// иначе - неверно.  
/////  ЕСТЬ ЛИ 24 ВОЛЬТА НА КОНЦЕВИКИ РЕФЛЕКТОРОВ
if (digitalRead(testSwitchReflek) == LOW)
   TesSwiRef24 = true; //если есть 24 на концевики флаг верно  
  else
   TesSwiRef24 = false;// иначе - неверно.
///// ЕСТЬ ЛИ 220 ВОЛЬТ НА ПНЕВМОРАСПРЕДЕЛИТЕЛИ РЕФЛЕКТОРОВ
if (digitalRead(testPneumReflek) == LOW)
   TesPnewRef220 = true; //если есть 220 флаг верно  
  else
   TesPnewRef220 = false;// иначе - неверно.
///// ЕСТЬ ЛИ СИГНАЛ О ВРАЩЕНИИ ТАХОМЕТРОВ, ПОЛОТНО ДВИЖЕТСЯ
if (digitalRead(Tahometr) == LOW)
   TahoFlag = true; //если есть 220 флаг верно  
  else
   TahoFlag = false;// иначе - неверно.
 //////////////////////////////////ИЗ КОНЦЕВИКОВ РЕФЛЕКТОРОВ
if (digitalRead(OpenReflek1) == LOW)
   OpeRefFlag1 = true;   
  else
   OpeRefFlag1 = false;// иначе - неверно.

if (digitalRead(ClosedReflek1) == LOW)
   ClosRefFlag1 = true;   
  else
   ClosRefFlag1 = false;// иначе - неверно.

if (digitalRead(OpenReflek2) == LOW)
   OpeRefFlag2 = true;   
  else
   OpeRefFlag2 = false;// иначе - неверно.

if (digitalRead(ClosedReflek2) == LOW)
   ClosRefFlag2 = true;   
  else
   ClosRefFlag2 = false;// иначе - неверно.

if (digitalRead(OpenReflek3) == LOW)
   OpeRefFlag3 = true;   
  else
   OpeRefFlag3 = false;// иначе - неверно.

if (digitalRead(ClosedReflek3) == LOW)
   ClosRefFlag3 = true;   
  else
   ClosRefFlag3 = false;// иначе - неверно.
if (digitalRead(OpenReflek4) == LOW)
   OpeRefFlag4 = true;   
  else
   OpeRefFlag4 = false;// иначе - неверно.

if (digitalRead(ClosedReflek4) == LOW)
   ClosRefFlag4 = true;   
  else
   ClosRefFlag4 = false;// иначе - неверно.

if (digitalRead(OpenReflek5) == LOW)
   OpeRefFlag5 = true;   
  else
   OpeRefFlag5 = false;// иначе - неверно.

if (digitalRead(ClosedReflek5) == LOW)
   ClosRefFlag5 = true;   
  else
   ClosRefFlag5 = false;// иначе - неверно.
/////////////////// КНОПКА RESET
if (digitalRead(ButtonResset) == LOW)
   RessetFlag = true;   
  else
   RessetFlag = false;// иначе - неверно.




  
/////////////////////КОНТРОЛЬ ЛАМПЫ №1
if ((!ClosRefFlag1) && (BTNFlag1) && (FlagAlarm == 0)) // Если концевик "закрыт" сработал и кнопка пуска нажата И НЕТ АВАРИЙ- можно включать.
   {
    digitalWrite(GoLamp1, LOW); //включаю лампу ВАРИАНТ ВКЛЮЧЕНИЯ ЛАМПЫ КОГДА ЛИНИЯ СТОИТ И НЕТ АВАРИЙ.    
    }
if ((KonvFlag) && (BTNFlag1)&& (FlagAlarm == 0))//ЕСЛИ КОНВЕЕР ЕДЕТ, НАЖАТА КНОПКА И НЕТ АВАРИЙ
    {
    digitalWrite(GoLamp1, LOW); //включаю лампу     
    }
if (FlagAlarm == 4 || FlagAlarm == 21 ) // ЕСЛИ АВАРИЯ 4 ИЛИ 21
    {
      if (millis() - AlarmClosLam1 >3000)
           {
            AlarmClosLam1 = millis();
            digitalWrite(GoLamp1, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ    
            }
    }
if (!BTNFlag1)  // ВЫКЛЮЧАЮ ЛАМПУ ЕСЛИ КНОПКА ВЫКЛЮЧЕНА
    {
     digitalWrite(GoLamp1, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ  
    }
/////////////////////КОНТРОЛЬ ЛАМПЫ №2
if ((!ClosRefFlag2) && (BTNFlag2) && (FlagAlarm == 0)) // Если концевик "закрыт" сработал и кнопка пуска нажата И НЕТ АВАРИЙ- можно включать.
   {
    digitalWrite(GoLamp2, LOW); //включаю лампу ВАРИАНТ ВКЛЮЧЕНИЯ ЛАМПЫ КОГДА ЛИНИЯ СТОИТ И НЕТ АВАРИЙ.    
    }
if ((KonvFlag) && (BTNFlag2)&& (FlagAlarm == 0))//ЕСЛИ КОНВЕЕР ЕДЕТ, НАЖАТА КНОПКА И НЕТ АВАРИЙ
    {
    digitalWrite(GoLamp2, LOW); //включаю лампу     
    }
if (FlagAlarm == 4 || FlagAlarm == 22 ) // ЕСЛИ АВАРИЯ 4 ИЛИ 22
    {
      if (millis() - AlarmClosLam2 >3000)
           {
            AlarmClosLam2 = millis();
            digitalWrite(GoLamp2, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ    
            }
    }
if (!BTNFlag2)  // ВЫКЛЮЧАЮ ЛАМПУ ЕСЛИ КНОПКА ВЫКЛЮЧЕНА
    {
     digitalWrite(GoLamp2, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ  
    }
/////////////////////КОНТРОЛЬ ЛАМПЫ №3
if ((!ClosRefFlag3) && (BTNFlag3) && (FlagAlarm == 0)) // Если концевик "закрыт" сработал и кнопка пуска нажата И НЕТ АВАРИЙ- можно включать.
   {
    digitalWrite(GoLamp3, LOW); //включаю лампу ВАРИАНТ ВКЛЮЧЕНИЯ ЛАМПЫ КОГДА ЛИНИЯ СТОИТ И НЕТ АВАРИЙ.    
    }
if ((KonvFlag) && (BTNFlag3)&& (FlagAlarm == 0))//ЕСЛИ КОНВЕЕР ЕДЕТ, НАЖАТА КНОПКА И НЕТ АВАРИЙ
    {
    digitalWrite(GoLamp3, LOW); //включаю лампу     
    }
if (FlagAlarm == 4 || FlagAlarm == 23 ) // ЕСЛИ АВАРИЯ 4 ИЛИ 23
    {
      if (millis() - AlarmClosLam3 >3000)
           {
            AlarmClosLam3 = millis();
            digitalWrite(GoLamp3, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ    
            }
    }
if (!BTNFlag3)  // ВЫКЛЮЧАЮ ЛАМПУ ЕСЛИ КНОПКА ВЫКЛЮЧЕНА
    {
     digitalWrite(GoLamp3, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ  
    }
/////////////////////КОНТРОЛЬ ЛАМПЫ №4
if ((!ClosRefFlag4) && (BTNFlag4) && (FlagAlarm == 0)) // Если концевик "закрыт" сработал и кнопка пуска нажата И НЕТ АВАРИЙ- можно включать.
   {
    digitalWrite(GoLamp4, LOW); //включаю лампу ВАРИАНТ ВКЛЮЧЕНИЯ ЛАМПЫ КОГДА ЛИНИЯ СТОИТ И НЕТ АВАРИЙ.    
    }
if ((KonvFlag) && (BTNFlag4)&& (FlagAlarm == 0))//ЕСЛИ КОНВЕЕР ЕДЕТ, НАЖАТА КНОПКА И НЕТ АВАРИЙ
    {
    digitalWrite(GoLamp4, LOW); //включаю лампу     
    }
if (FlagAlarm == 4 || FlagAlarm == 24 ) // ЕСЛИ АВАРИЯ 4 ИЛИ 24
    {
      if (millis() - AlarmClosLam4 >3000)
           {
            AlarmClosLam4 = millis();
            digitalWrite(GoLamp4, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ    
            }
    }
if (!BTNFlag4)  // ВЫКЛЮЧАЮ ЛАМПУ ЕСЛИ КНОПКА ВЫКЛЮЧЕНА
    {
     digitalWrite(GoLamp4, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ  
    }
/////////////////////КОНТРОЛЬ ЛАМПЫ №5
if ((!ClosRefFlag5) && (BTNFlag5) && (FlagAlarm == 0)) // Если концевик "закрыт" сработал и кнопка пуска нажата И НЕТ АВАРИЙ- можно включать.
   {
    digitalWrite(GoLamp5, LOW); //включаю лампу ВАРИАНТ ВКЛЮЧЕНИЯ ЛАМПЫ КОГДА ЛИНИЯ СТОИТ И НЕТ АВАРИЙ.    
    }
if ((KonvFlag) && (BTNFlag5)&& (FlagAlarm == 0))//ЕСЛИ КОНВЕЕР ЕДЕТ, НАЖАТА КНОПКА И НЕТ АВАРИЙ
    {
    digitalWrite(GoLamp5, LOW); //включаю лампу     
    }
if (FlagAlarm == 4 || FlagAlarm == 25 ) // ЕСЛИ АВАРИЯ 4 ИЛИ 25
    {
      if (millis() - AlarmClosLam5 >3000)
           {
            AlarmClosLam5 = millis();
            digitalWrite(GoLamp5, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ    
            }
    }
if (!BTNFlag5)  // ВЫКЛЮЧАЮ ЛАМПУ ЕСЛИ КНОПКА ВЫКЛЮЧЕНА
    {
     digitalWrite(GoLamp5, HIGH); // ВЫКЛЮЧАЮ ЛАМПУ  
    }

     




     

///////////ПОВОРОТ РЕФЛЕКТОРА №1
if ((KonvFlag) && (BTNFlag1) && (FlagAlarm == 0))//ЕСЛИ ВКЛЮЧЕН ТРАНСПОРТЕР И ВКЛЮЧЕНА ЛАМПА И НЕТ АВАРИЙ
   digitalWrite(pnewReflek1, LOW); //ПОВОРАЧИВАЮ РЕФЛЕКТОР ВНИЗ. ОТКРЫВАЮ
if ((!KonvFlag) || FlagAlarm == 4 || FlagAlarm == 21) // ЕСЛИ ОСТАНОВЛЕН ТРАНСПОРТЕР ИЛИ ОБРЫВ ПОЛОТНА ИЛИ РЕФЛЕКТОР НЕ ЗАКРЫЛСЯ
   digitalWrite(pnewReflek1, HIGH); //ПОВОРАЧИВАЮ РЕФЛЕКТОР ВВЕРХ. ЗАКРЫВАЮ
///////////ПОВОРОТ РЕФЛЕКТОРА №2
if ((KonvFlag) && (BTNFlag2) && (FlagAlarm == 0))
   digitalWrite(pnewReflek2, LOW); //ПОВОРАЧИВАЮ РЕФЛЕКТОР ВНИЗ. ОТКРЫВАЮ
if ((!KonvFlag) || FlagAlarm == 4 || FlagAlarm == 22) // ЕСЛИ ОСТАНОВЛЕН ТРАНСПОРТЕР ИЛИ ОБРЫВ ПОЛОТНА ИЛИ РЕФЛЕКТОР НЕ ЗАКРЫЛСЯ
   digitalWrite(pnewReflek2, HIGH); //ПОВОРАЧИВАЮ РЕФЛЕКТОР ВВЕРХ. ЗАКРЫВАЮ
///////////ПОВОРОТ РЕФЛЕКТОРА №3
if ((KonvFlag) && (BTNFlag3) && (FlagAlarm == 0))
   digitalWrite(pnewReflek3, LOW); //ПОВОРАЧИВАЮ РЕФЛЕКТОР ВНИЗ. ОТКРЫВАЮ
if ((!KonvFlag) || FlagAlarm == 4 || FlagAlarm == 23) // ЕСЛИ ОСТАНОВЛЕН ТРАНСПОРТЕР ИЛИ ОБРЫВ ПОЛОТНА ИЛИ РЕФЛЕКТОР НЕ ЗАКРЫЛСЯ
   digitalWrite(pnewReflek3, HIGH); //ПОВОРАЧИВАЮ РЕФЛЕКТОР ВВЕРХ. ЗАКРЫВАЮ
///////////ПОВОРОТ РЕФЛЕКТОРА №4 И 5
if ((KonvFlag) && ((BTNFlag4)||(BTNFlag5))&& (FlagAlarm == 0))
   digitalWrite(pnewReflek4_5, LOW); //ПОВОРАЧИВАЮ РЕФЛЕКТОР ВНИЗ. ОТКРЫВАЮ
if ((!KonvFlag) || FlagAlarm == 4 || FlagAlarm == 24 || FlagAlarm == 25) // ЕСЛИ ОСТАНОВЛЕН ТРАНСПОРТЕР ИЛИ ОБРЫВ ПОЛОТНА ИЛИ РЕФЛЕКТОР НЕ ЗАКРЫЛСЯ НА 4 ИЛИ 5 СЕКЦИИ
   digitalWrite(pnewReflek4_5, HIGH); //ПОВОРАЧИВАЮ РЕФЛЕКТОР ВВЕРХ. ЗАКРЫВАЮ







//////////ВОЗНИКНОВЕНИЕ АВАРИИ ПЕРВОЙ КАТЕГОРИИ(ОПРОС КОНЦЕВИКОВ РЕФЛЕКТОРОВ ПРИ СТОЯЩЕЙ ЛИНИИ И ВЫКЛЮЧЕННЫМИ ЛАМПАМИ И ПОДАННЫМ 220 НА ПНЕВМАТИКУ.
//ПРИ ВЫКЛЮЧЕННЫХ ЛАМПАХ И ПОДАНЫМ НАПРЯЖЕНИЕМ НА ПНЕВМАТИКУ РЕФЛЕКТОРОВ= НА ОДНОМ ИЗ КОНЦЕВИКОВ РЕФЛЕКТОРОВ ОБРЫВ 
if ((!BTNFlag1) && (TesPnewRef220) && (!OpeRefFlag1) && (!ClosRefFlag1)                                                                             )
 {
  FlagAlarm = 11; // ВКЛЮЧАЮ ФЛАГ АВАРИИ ОБРЫВ ОДНОГО ИЗ КОНЦЕВИКОВ
 }
// РЕФЛЕКТОР НИ ТАМ НИ ТАМ
if ((!BTNFlag1) && (TesPnewRef220) && (OpeRefFlag1) && (ClosRefFlag1))  
 {
  FlagAlarm = 111; //   
 }
//////////ВОЗНИКНОВЕНИЕ АВАРИИ ПЕРВОЙ КАТЕГОРИИ(ОПРОС КОНЦЕВИКОВ РЕФЛЕКТОРОВ ПРИ СТОЯЩЕЙ ЛИНИИ И ВЫКЛЮЧЕННЫМИ ЛАМПАМИ И ПОДАННЫМ 220 НА ПНЕВМАТИКУ.
//ПРИ ВЫКЛЮЧЕННЫХ ЛАМПАХ И ПОДАНЫМ НАПРЯЖЕНИЕМ НА ПНЕВМАТИКУ РЕФЛЕКТОРОВ= НА ОДНОМ ИЗ КОНЦЕВИКОВ РЕФЛЕКТОРОВ ОБРЫВ 
if ((!BTNFlag1) && (TesPnewRef220) && (!OpeRefFlag2) && (!ClosRefFlag2)                                                                             )
 {
  FlagAlarm = 12; // ВКЛЮЧАЮ ФЛАГ АВАРИИ ОБРЫВ ОДНОГО ИЗ КОНЦЕВИКОВ
 }
// РЕФЛЕКТОР НИ ТАМ НИ ТАМ
if ((!BTNFlag2) && (TesPnewRef220) && (OpeRefFlag2) && (ClosRefFlag2))  
 {
  FlagAlarm = 122; //   
 }
//////////ВОЗНИКНОВЕНИЕ АВАРИИ ПЕРВОЙ КАТЕГОРИИ(ОПРОС КОНЦЕВИКОВ РЕФЛЕКТОРОВ ПРИ СТОЯЩЕЙ ЛИНИИ И ВЫКЛЮЧЕННЫМИ ЛАМПАМИ И ПОДАННЫМ 220 НА ПНЕВМАТИКУ.
//ПРИ ВЫКЛЮЧЕННЫХ ЛАМПАХ И ПОДАНЫМ НАПРЯЖЕНИЕМ НА ПНЕВМАТИКУ РЕФЛЕКТОРОВ= НА ОДНОМ ИЗ КОНЦЕВИКОВ РЕФЛЕКТОРОВ ОБРЫВ 
if ((!BTNFlag3) && (TesPnewRef220) && (!OpeRefFlag3) && (!ClosRefFlag3)                                                                             )
 {
  FlagAlarm = 13; // ВКЛЮЧАЮ ФЛАГ АВАРИИ ОБРЫВ ОДНОГО ИЗ КОНЦЕВИКОВ
 }
// РЕФЛЕКТОР НИ ТАМ НИ ТАМ
if ((!BTNFlag3) && (TesPnewRef220) && (OpeRefFlag3) && (ClosRefFlag3))  
 {
  FlagAlarm = 133; //   
 }
//////////ВОЗНИКНОВЕНИЕ АВАРИИ ПЕРВОЙ КАТЕГОРИИ(ОПРОС КОНЦЕВИКОВ РЕФЛЕКТОРОВ ПРИ СТОЯЩЕЙ ЛИНИИ И ВЫКЛЮЧЕННЫМИ ЛАМПАМИ И ПОДАННЫМ 220 НА ПНЕВМАТИКУ.
//ПРИ ВЫКЛЮЧЕННЫХ ЛАМПАХ И ПОДАНЫМ НАПРЯЖЕНИЕМ НА ПНЕВМАТИКУ РЕФЛЕКТОРОВ= НА ОДНОМ ИЗ КОНЦЕВИКОВ РЕФЛЕКТОРОВ ОБРЫВ 
if ((!BTNFlag4) && (TesPnewRef220) && (!OpeRefFlag4) && (!ClosRefFlag4)                                                                             )
 {
  FlagAlarm = 14; // ВКЛЮЧАЮ ФЛАГ АВАРИИ ОБРЫВ ОДНОГО ИЗ КОНЦЕВИКОВ
 }
// РЕФЛЕКТОР НИ ТАМ НИ ТАМ
if ((!BTNFlag4) && (TesPnewRef220) && (OpeRefFlag4) && (ClosRefFlag4))  
 {
  FlagAlarm = 144; //   
 }
//////////ВОЗНИКНОВЕНИЕ АВАРИИ ПЕРВОЙ КАТЕГОРИИ(ОПРОС КОНЦЕВИКОВ РЕФЛЕКТОРОВ ПРИ СТОЯЩЕЙ ЛИНИИ И ВЫКЛЮЧЕННЫМИ ЛАМПАМИ И ПОДАННЫМ 220 НА ПНЕВМАТИКУ.
//ПРИ ВЫКЛЮЧЕННЫХ ЛАМПАХ И ПОДАНЫМ НАПРЯЖЕНИЕМ НА ПНЕВМАТИКУ РЕФЛЕКТОРОВ= НА ОДНОМ ИЗ КОНЦЕВИКОВ РЕФЛЕКТОРОВ ОБРЫВ 
if ((!BTNFlag5) && (TesPnewRef220) && (!OpeRefFlag5) && (!ClosRefFlag5)                                                                             )
 {
  FlagAlarm = 15; // ВКЛЮЧАЮ ФЛАГ АВАРИИ ОБРЫВ ОДНОГО ИЗ КОНЦЕВИКОВ
 }
// РЕФЛЕКТОР НИ ТАМ НИ ТАМ
if ((!BTNFlag5) && (TesPnewRef220) && (OpeRefFlag5) && (ClosRefFlag5))  
 {
  FlagAlarm = 155; //   
 }


//////////ВОЗНИКНОВЕНИЕ АВАРИИ ВТОРОЙ КАТЕГОРИИ ПРИ ВКЛЮЧЕННОЙ ЛАМПЕ И ОДНОЙ СЕКУНДЫ ПОСЛЕ ОСТАНОВКИ ТРАНСПОРТЕРА = рефлектор на секции не закрылся.
// НА СЕКЦИИ №1
if (!KonvFlag && BTNFlag1)
        {
           if (millis() - PrevMilStLamp1 >2000 && FlagAlarm != 4)
           {
            PrevMilStLamp1 = millis();
             if (ClosRefFlag1)
                 {
                  FlagAlarm = 21;
                 }
            }          
          }
// НА СЕКЦИИ №2
if (!KonvFlag && BTNFlag2)
        {
           if (millis() - PrevMilStLamp2 >2000 && FlagAlarm != 4)
           {
            PrevMilStLamp2 = millis();
             if (ClosRefFlag2)
                 {
                  FlagAlarm = 22;
                 }
            }          
          }
// НА СЕКЦИИ №3
if (!KonvFlag && BTNFlag3)
        {
           if (millis() - PrevMilStLamp3 >2000 && FlagAlarm != 4)
           {
            PrevMilStLamp3 = millis();
             if (ClosRefFlag3)
                 {
                  FlagAlarm = 23;
                 }
            }          
          }
// НА СЕКЦИИ №4
if (!KonvFlag && BTNFlag4)
        {
           if (millis() - PrevMilStLamp4 >2000 && FlagAlarm != 4)
           {
            PrevMilStLamp4 = millis();
             if (ClosRefFlag4)
                 {
                  FlagAlarm = 24;
                 }
            }          
          }
// НА СЕКЦИИ №5
if (!KonvFlag && BTNFlag5)
        {
           if (millis() - PrevMilStLamp5 >2000 && FlagAlarm != 4)
           {
            PrevMilStLamp5 = millis();
             if (ClosRefFlag5)
                 {
                  FlagAlarm = 25;
                 }
            }          
          }    

//////////ВОЗНИКНОВЕНИЕ АВАРИИ ТРЕТЬЕЙ КАТЕГОРИИ ПРИ: ТРАНСПОРТЕР ЗАПУСТИЛСЯ И ЛАМПА ВКЛЮЧЕНА И ПРОШЛО 1 СЕКУНДА А СЕКЦИЯ НЕ ОТКРЫЛАСЬ.
// НА СЕКЦИИ №1
if (KonvFlag && BTNFlag1)
 {
  if (millis() - PrevMilGOLamp1 >1000 && FlagAlarm != 4)
     {
      PrevMilGOLamp1 = millis();
        if (OpeRefFlag1)
        {
          FlagAlarm = 31;
          }
      }
  }
// НА СЕКЦИИ №2
if (KonvFlag && BTNFlag2)
 {
  if (millis() - PrevMilGOLamp2 >1000 && FlagAlarm != 4)
     {
      PrevMilGOLamp2 = millis();
        if (OpeRefFlag2)
        {
          FlagAlarm = 32;
          }
      }
  }
// НА СЕКЦИИ №3
if (KonvFlag && BTNFlag3)
 {
  if (millis() - PrevMilGOLamp3 >1000 && FlagAlarm != 4)
     {
      PrevMilGOLamp3 = millis();
        if (OpeRefFlag3)
        {
          FlagAlarm = 33;
          }
      }
  }
// НА СЕКЦИИ №4
if (KonvFlag && BTNFlag4)
 {
  if (millis() - PrevMilGOLamp4 >1000 && FlagAlarm != 4)
     {
      PrevMilGOLamp4 = millis();
        if (OpeRefFlag4)
        {
          FlagAlarm = 34;
          }
      }
  }
// НА СЕКЦИИ №5
if (KonvFlag && BTNFlag5)
 {
  if (millis() - PrevMilGOLamp5 >1000 && FlagAlarm != 4)
     {
      PrevMilGOLamp5 = millis();
        if (OpeRefFlag5)
        {
          FlagAlarm = 35;
          }
      }
  }
/*/АВАРИЯ ЧЕТВЕРТОЙ КАТЕГОРИИ "ОБРЫВ ПОЛОТНА" КОГДА: ТРАНСПОРТЕР ЗАПУЩЕН И ВКЛЮЧЕНА ХОТЬ ОДНА ИЗ ЛАМП ТО + 5 СЕК И ЗАПУСК опрос ТАХОМЕТРОВ.
if ((KonvFlag) && BTNFlag1 || BTNFlag2 || BTNFlag3 || BTNFlag4 || BTNFlag5) 
  {
    if (millis() - FullTaho >3000)
      {
       FullTaho = millis();
       if (!TahoFlag)
        {
          FlagAlarm = 4;
          }
      }
  }*/
///////ВОЗНИКНОВЕНИЕ АВАРИИ ПЯТОЙ КАТЕГОРИИ "НА ПНЕВМОРАСПРЕДЕЛИТЕЛИ РЕФЛЕКТОРОВ НЕТ 220 ВОЛЬТ ИЛИ СГОРЕЛ F2" ТОИСТЬ ОНИ НЕ КОНТРОЛИРУЕМЫЕ.
if (!TesPnewRef220)
    {
     FlagAlarm = 5; 
    }
///ВОЗНИКНОВЕНИЕ АВАРИИ ШЕСТОЙ КАТЕГОРИИ "НА КОНЦЕВИКИ НЕТ 24ВОЛЬТ ИЛИ СГОРЕЛ F5"
if (!TesSwiRef24)
    {
     FlagAlarm = 6; 
    }



/// сброс аварий во время пуска-стопа  транспортера
currentButtonFlag = KonvFlag;
  if(lastButtonFlag != currentButtonFlag) 
  {
    lastButtonFlag = currentButtonFlag;// предыдущий флаг равен текущему
        if( millis() - MilKonvPause > 500)
      {
        MilKonvPause = millis();
        FlagAlarm = 0;
        digitalWrite(Alarmlamp1, HIGH);
        digitalWrite(Alarmlamp2, HIGH);
        digitalWrite(Alarmlamp3, HIGH);
        digitalWrite(Alarmlamp4, HIGH);
        digitalWrite(Alarmlamp5, HIGH);
      }
    
  }






////КНОПКА RESET ОБРАБОТКА. флаг PauseEror становится TRUE на 10 секунд
if (RessetFlag)
 {
  FlagAlarm = 0;
  digitalWrite(Alarmlamp1,HIGH);
  digitalWrite(Alarmlamp2,HIGH);
  digitalWrite(Alarmlamp3,HIGH);
  digitalWrite(Alarmlamp4,HIGH);
  digitalWrite(Alarmlamp5,HIGH);  
  }

///////мигалка для маяков аварии ПЕРВОЙ КАТЕГОРИИ
if (FlagAlarm == 11 || FlagAlarm == 111 || FlagAlarm == 12 || FlagAlarm == 122 || FlagAlarm == 13 || FlagAlarm == 133 || FlagAlarm == 14 || FlagAlarm == 144 || FlagAlarm == 15 || FlagAlarm == 155)
   {
        if(millis() - AlarmPast1 >= AlarmPeriod1) 
        {
        AlarmMask1 <<=1; // переход на след шаг последовательности
        if (AlarmMask1 == 0) AlarmMask1 = 1;//если послед закончилась,начать с начала
        if (Alarm1 & AlarmMask1) alarmMigFlag = false;
        else alarmMigFlag = true;
        AlarmPast1 = millis(); //<--- сохраняем время переключения
        }
   }
///////мигалка для маяков аварии ВТОРОЙ КАТЕГОРИИ
if (FlagAlarm ==21 || FlagAlarm == 22 || FlagAlarm == 23 || FlagAlarm == 24 || FlagAlarm == 25)
   {
        if (millis() - AlarmPast2 >= AlarmPeriod2) {
        AlarmMask2 <<=1; // переход на след шаг последовательности
        if (AlarmMask2 == 0) AlarmMask2 = 1;//если послед закончилась,начать с начала
        if (Alarm2 & AlarmMask2) alarmMigFlag = false;
        else alarmMigFlag = true;
        AlarmPast2 = millis(); //<--- сохраняем время переключения
        
      }
   }
///////мигалка для маяков аварии ТРЕТЬЕЙ КАТЕГОРИИ
if (FlagAlarm ==31 || FlagAlarm == 32 || FlagAlarm == 33 || FlagAlarm == 34 || FlagAlarm == 35)
   {
        if (millis() - AlarmPast3 >= AlarmPeriod3) {
        AlarmMask3 <<=1; // переход на след шаг последовательности
        if (AlarmMask3 == 0) AlarmMask3 = 1;//если послед закончилась,начать с начала
        if (Alarm3 & AlarmMask3) alarmMigFlag = false;
        else alarmMigFlag = true;
        AlarmPast3 = millis(); //<--- сохраняем время переключения
        
      }
   }
///////мигалка для маяков аварии ЧЕТВЕРТОЙ КАТЕГОРИИ
if (FlagAlarm ==4)
   {
        if (millis() - AlarmPast4 >= AlarmPeriod4) {
        AlarmMask4 <<=1; // переход на след шаг последовательности
        if (AlarmMask4 == 0) AlarmMask4 = 1;//если послед закончилась,начать с начала
        if (Alarm4 & AlarmMask4) alarmMigFlag = false;
        else alarmMigFlag = true;
        AlarmPast4 = millis(); //<--- сохраняем время переключения
        
      }
   }
///////мигалка для маяков аварии ПЯТОЙ И ШЕСТОЙ КАТЕГОРИИ
if (FlagAlarm ==5 || FlagAlarm == 6)
   {
        if (millis() - AlarmPast5 >= AlarmPeriod5) {
        AlarmMask5 <<=1; // переход на след шаг последовательности
        if (AlarmMask5 == 0) AlarmMask5 = 1;//если послед закончилась,начать с начала
        if (Alarm5 & AlarmMask5) alarmMigFlag = false;
        else alarmMigFlag = true;
        AlarmPast5 = millis(); //<--- сохраняем время переключения
        
      }
   }
/// ОБРАБОТКА АВАРИЙ МАЯКАМИ
if (FlagAlarm == 11 || FlagAlarm == 111 || FlagAlarm == 21 || FlagAlarm == 31)
   {
    digitalWrite(Alarmlamp1, alarmMigFlag);
    
    }
if (FlagAlarm == 12 || FlagAlarm == 122 || FlagAlarm == 22 || FlagAlarm == 32)
   {
    digitalWrite(Alarmlamp2, alarmMigFlag);
    
    }
if (FlagAlarm == 13 || FlagAlarm == 133 || FlagAlarm == 23 || FlagAlarm == 33)
   {
    digitalWrite(Alarmlamp3, alarmMigFlag);
    
    }
if (FlagAlarm == 14 || FlagAlarm == 144 || FlagAlarm == 24 || FlagAlarm == 34)
   {
    digitalWrite(Alarmlamp4, alarmMigFlag);
    
    }
if (FlagAlarm == 15 || FlagAlarm == 155 || FlagAlarm == 25 || FlagAlarm == 35)
   {
    digitalWrite(Alarmlamp5, alarmMigFlag);
    
    }
if (FlagAlarm == 4)
 {
  digitalWrite(Alarmlamp1, alarmMigFlag);
  digitalWrite(Alarmlamp2, alarmMigFlag);
  digitalWrite(Alarmlamp3, alarmMigFlag);
  digitalWrite(Alarmlamp4, alarmMigFlag);
  digitalWrite(Alarmlamp5, alarmMigFlag);
 }
if (FlagAlarm == 5 || FlagAlarm == 6)
 {
  digitalWrite(Alarmlamp1, alarmMigFlag);
  digitalWrite(Alarmlamp2, alarmMigFlag);
  digitalWrite(Alarmlamp3, alarmMigFlag);
  digitalWrite(Alarmlamp4, alarmMigFlag);
  digitalWrite(Alarmlamp5, alarmMigFlag);
 }



    
/////Отладка на порт

 if (millis() - PortPreviosMil > 100)
 {
  PortPreviosMil = millis();
  Serial.println(FlagAlarm);
  }
//FlagAlarm = 4;
}
 




 

maxvalin
Offline
Зарегистрирован: 22.02.2016

на 697 строке примерно и есть тема разговора, была точнее вчера. так вроди сейчас работает.

Но  мне как всега хочется для развития больше. тоисть понять как этот вопрос решается.

За все ответы что выше - Спасибо! но я сейчас только беглым взглядом могу пройтись. Даст Бог вечером может присяду и повнимательней пройдусь. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Мда,глядя на ваш скетч так и хочется воскликнуть ...Христос Воскресе! (шутка) .. Си++ жив и не надо записывать его в покойники.

ПС: Изучите это 

/**/
unsigned long mill;
typedef void (*handler)() ;
//------Cl_Led----------------------
// класс светодиод
class Cl_Led {
  protected:
    const byte pin;
    bool led;
    bool statBlink;
    unsigned long past, time;
  public:
    Cl_Led(byte pin_): pin(pin_) {}
    void setup() {
      pinMode(pin, OUTPUT);
      OFF();
    }
    void loop() {
      if (statBlink && mill - past >= time) {
        past = mill;
        digitalWrite(pin, led = !led);
      }
    }
    void ON() {
      digitalWrite(pin, led = HIGH);
      statBlink = 0;
    }
    void OFF() {
      digitalWrite(pin, led = LOW);
      statBlink = 0;
    }
    void blink(unsigned long time_ = 200) {
      statBlink = 1;
      time = time_;
      past = mill;
      digitalWrite(pin, led = !led);
    }
};
//------Cl_Btn----------------------
// класс кнопка
class Cl_Btn {
  protected:
    const byte pin;
    handler Do;
    bool bounce = 0;
    bool btn = 1, oldBtn;
    unsigned long past;
  public:
    Cl_Btn(byte pin_, handler Do_): pin(pin_), Do(Do_) {}
    void setup() {
      pinMode(pin, INPUT_PULLUP);
    }
    void loop() {
      bool newBtn = digitalRead(pin);
      if (!bounce && newBtn != btn) {
        bounce = 1;
        past = mill;
      }
      if (bounce && mill - past >= 10) {
        bounce = 0 ;
        oldBtn = btn;
        btn = newBtn;
        if (!btn && oldBtn) Do();
      }
    }
};
//-----компоновка----------------------
Cl_Led Led(/*пин*/13);
void DoBtn1() {
  Led.ON();
  Serial.println("DoBtn1");
}
void DoBtn2() {
  Led.OFF();
  Serial.println("DoBtn2");
}
void DoBtn3() {
  Led.blink();
  Serial.println("DoBtn3");
}
Cl_Btn Btn1(/*пин*/2,/*обработчик*/DoBtn1);
Cl_Btn Btn2(/*пин*/3,/*обработчик*/DoBtn2);
Cl_Btn Btn3(/*пин*/4,/*обработчик*/DoBtn3);
//-----main-----------------------
int main() {
  init();
  // setup()
  Serial.begin(9600);
  Led.setup();
  Btn1.setup();
  Btn2.setup();
  Btn3.setup();
  for (;;) {
    // loop()
    mill = millis();
    Led.loop();
    Btn1.loop();
    Btn2.loop();
    Btn3.loop();
  }
  return 0;
}
/*Скетч использует 2488 байт (7%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 251 байт (12%) динамической памяти, оставляя 1797 байт для локальных переменных. Максимум: 2048 байт.
*/