Работа с датчиками и реле, вопросы

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

Ученик пишет:
Таймер написан неправильно, где-то еще ошибка.
Ясно где. я не наблюдаю у Вас millis().

bwn
Offline
Зарегистрирован: 25.08.2014

Ученик пишет:

А вот всё равно не работает. Т.е. при любых значениях в 33 строке меньше 35000 после включения выход отключается через менее полсекунды...

одна из степеней двойки == 32768, далее Экклезиаст: "Нельзя впихать ......".

Ну а с таймером, сами себе злобный Буратино.

sva_khv
Offline
Зарегистрирован: 19.12.2016

За неделю перейти с Бейсика 30 летней давности на Си - Это круто!  :-)  

Если у ТС  хоть что то реально получится - респект и уважуха.  :-)

Пару советов. В отличии от Бейсика ТИПЫ данных задаются  ЯВНО и менют очень четкие ограничения. И за выходом за допустиные пределы никто кроме тябя не следит. И не предупредит.

А вместо GO TO  используются блоки операторов заключеные в скобки {}  Прчем скобка открывается сдесь, а закрывается на 40 строк ниже, а в нутри еще штук пять - десять таких комплетов скобок!  8-((((

К этому надо привыкнуть. Сперва без GO TO очень сложно. Особенно напрягает каскад вложеных if.... else. с этими скобками, будь они не ладны! :-))))

Ученик
Offline
Зарегистрирован: 19.09.2018

sadman41

У Агата был сильно урезанный Бейсик. Ну и...

Как дают задания детям:

- Взять деньги и записку что купить

- ЕСЛИ горит красный свет, стоять ждать на переходе, не перебегать

_ЕСЛИ загорелся зеленый GOTO магазин 1

- ЕСЛИ в магазине 1 хлеба нет, GOTO в магазин 2

- ЕСЛИ хлеб кпулен GOTO в ларек за газетой

- ЕСЛИ газеты там нет, GOTO во второй ларек

- ЕСЛИ газета куплена, GOTO домой

 

Вот точно так же я написал и программу игрушки для Агата :lol:

Ученик
Offline
Зарегистрирован: 19.09.2018

[b]sva_khv[/b]

Спасибо, да, именно так.

Готовый код, ВСЁ РАБОТАЕТ

int knopka1=0; //переменная состояние кнопки 1 /пока неизвестно что/ 
 
int state1=0; //запуск функции выхода 1 вкл или выкл
int state2=0; //запуск функции выхода 2 вкл или выкл
unsigned long timeStarted = 0;
 
 
void setup() {
   pinMode(2, INPUT); //кнопка 1
   pinMode(3, INPUT); //кнопка 2
 
   pinMode(6, OUTPUT); // выход 1
   pinMode(7, OUTPUT); // выход 2
 
}
 
void loop() 
{  
  if(digitalRead(2)&&!knopka1) // если кнопка 1 нажата, переменная кнопка1=0
 {
  delay(10); // защита от дребезга
  digitalWrite(6, HIGH); // выход 1 ВКЛ
  state1=1; // признак включённого реле 1
  timeStarted = millis();
 } 
  if(digitalRead(3)&&!knopka1&&state1) // если кнопка 2 нажата, переменная кнопка1=0, реле1 вкл
 {
  delay(10); // защита от дребезга
  digitalWrite(7, HIGH); // выход 2 ВКЛ
 } 
 
  if( millis() - timeStarted >= 20000 ) // 10 seconds passed
 {
  digitalWrite(6, LOW); // выход 1 ВЫКЛ
  digitalWrite(7, LOW); // выход 2 ВЫКЛ
  state1=0;
  
 }
  
}

 

Ученик
Offline
Зарегистрирован: 19.09.2018

На самом деле это часть задания.

Теперь надо обслужить одним Ардуино ТРИ аналогичные группы по две кнопки и два реле.

Программа: (выкинуты ненужные для данной проги хвосты копи-паст откуда-то "Кнопка1=1"...)

int state1=0; //состояние выхода 1 вкл или выкл
int state2=0; //состояние выхода 3 вкл или выкл
int state3=0; //состояние выхода 5 вкл или выкл
unsigned long timeStarted = 0;
 
void setup() {
   pinMode(2, INPUT); //кнопка 1
   pinMode(3, INPUT); //кнопка 2
   pinMode(4, INPUT); //кнопка 3
   pinMode(5, INPUT); //кнопка 4
   pinMode(14, INPUT); //кнопка 5
   pinMode(15, INPUT); //кнопка 6

   pinMode(6, OUTPUT); // выход 1
   pinMode(7, OUTPUT); // выход 2
   pinMode(8, OUTPUT); // выход 3
   pinMode(9, OUTPUT); // выход 4
   pinMode(10, OUTPUT); // выход 5
   pinMode(11, OUTPUT); // выход 6
}
void loop() 
{  
  if(digitalRead(2) ) // если кнопка 1 нажата, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(6, HIGH); // выход/реле 1 ВКЛ
  state1=1; // признак включённого реле 1
  timeStarted = millis();
 } 
  if(digitalRead(3)&&state1) // если кнопка 2 нажата, реле1 вкл, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(7, HIGH); // выход/реле 2 ВКЛ
 } 
 
  if( millis() - timeStarted >= 20000 ) // 18 seconds passed
 {
  digitalWrite(6, LOW); // выход/реле 1 ВЫКЛ
  digitalWrite(7, LOW); // выход/реле 2 ВЫКЛ
  state1=0;
  
 }
   if(digitalRead(4) ) // если кнопка 3 нажата, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(8, HIGH); // выход/реле 3 ВКЛ
  state2=1; // признак включённого реле 3
  timeStarted = millis();
 } 
  if(digitalRead(5)&&state2) // если кнопка 4 нажата, реле3 вкл, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(9, HIGH); // выход/реле 4 ВКЛ
 } 
 
  if( millis() - timeStarted >= 20000 ) // 18 seconds passed
 {
  digitalWrite(8, LOW); // выход/реле 3 ВЫКЛ
  digitalWrite(9, LOW); // выход/реле 4 ВЫКЛ
  state2=0;
 }  
 if(digitalRead(14) ) // если кнопка 5 нажата, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(10, HIGH); // выход/реле 5 ВКЛ
  state3=1; // признак включённого реле 5
  timeStarted = millis();
 } 
  if(digitalRead(3)&&state3) // если кнопка 6 нажата, реле5 вкл
 {
  delay(10); // защита от дребезга
  digitalWrite(11, HIGH); // выход/реле 6 ВКЛ
 } 
 
  if( millis() - timeStarted >= 20000 ) // 18 seconds passed
 {
  digitalWrite(6, LOW); // выход/реле 5 ВЫКЛ
  digitalWrite(7, LOW); // выход/реле 6 ВЫКЛ
  state3=0;
 }
}

Явный дефект программы, который нужно править: счетчик... ОДИН!

А между прочим, каждая из трех групп должна работать независимо - то есть возмонжы ситуации когда группа 1 начинает работать в момент времени N, а группа 2 - в момент времени N+15 секунд.

Тогда счетчик/таймер для 1 группы должен закончиться в N+50 сек, а для второй - N+65 сек... сел думать и читать... "курить форумы"...

sadman41
Offline
Зарегистрирован: 19.10.2016

timeStarted1 = millis(); ... timeStarted2 = millis(); ... timeStartedX = millis(); ...

Ученик
Offline
Зарегистрирован: 19.09.2018

sadman41

Спасибо.

Последний вариант: (всё работает)
int state1=0; //состояние выхода 1 вкл или выкл
int state2=0; //состояние выхода 3 вкл или выкл
int state3=0; //состояние выхода 5 вкл или выкл
unsigned long timeStarted1 = 0;
unsigned long timeStarted2 = 0;
unsigned long timeStarted3 = 0;
 
void setup() {
   pinMode(2, INPUT); //кнопка 1
   pinMode(3, INPUT); //кнопка 2
   pinMode(4, INPUT); //кнопка 3
   pinMode(5, INPUT); //кнопка 4
   pinMode(14, INPUT); //кнопка 5
   pinMode(15, INPUT); //кнопка 6

   pinMode(6, OUTPUT); // выход 1
   pinMode(7, OUTPUT); // выход 2
   pinMode(8, OUTPUT); // выход 3
   pinMode(9, OUTPUT); // выход 4
   pinMode(10, OUTPUT); // выход 5
   pinMode(11, OUTPUT); // выход 6
}
void loop() 
{  
  if(digitalRead(2) ) // если кнопка 1 нажата, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(6, HIGH); // выход/реле 1 ВКЛ
  state1=1; // признак включённого реле 1
  timeStarted1 = millis();
 } 
  if(digitalRead(3)&&state1) // если кнопка 2 нажата, реле1 вкл, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(7, HIGH); // выход/реле 2 ВКЛ
 } 
 
  if( millis() - timeStarted1 >= 20000 ) // 18 seconds passed
 {
  digitalWrite(6, LOW); // выход/реле 1 ВЫКЛ
  digitalWrite(7, LOW); // выход/реле 2 ВЫКЛ
  state1=0;
  
 }
   if(digitalRead(4) ) // если кнопка 3 нажата, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(8, HIGH); // выход/реле 3 ВКЛ
  state2=1; // признак включённого реле 3
  timeStarted2 = millis();
 } 
  if(digitalRead(5)&&state2) // если кнопка 4 нажата, реле3 вкл, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(9, HIGH); // выход/реле 4 ВКЛ
 } 
 
  if( millis() - timeStarted2 >= 20000 ) // 18 seconds passed
 {
  digitalWrite(8, LOW); // выход/реле 3 ВЫКЛ
  digitalWrite(9, LOW); // выход/реле 4 ВЫКЛ
  state2=0;
 }  
 if(digitalRead(14) ) // если кнопка 5 нажата, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(10, HIGH); // выход/реле 5 ВКЛ
  state3=1; // признак включённого реле 5
  timeStarted3 = millis();
 } 
  if(digitalRead(15)&&state3) // если кнопка 6 нажата, реле5 вкл
 {
  delay(10); // защита от дребезга
  digitalWrite(11, HIGH); // выход/реле 6 ВКЛ
 } 
 
  if( millis() - timeStarted3 >= 20000 ) // 18 seconds passed
 {
  digitalWrite(10, LOW); // выход/реле 5 ВЫКЛ
  digitalWrite(11, LOW); // выход/реле 6 ВЫКЛ
  state3=0;
 }
 
}

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ученик пишет:

sadman41

У Агата был сильно урезанный Бейсик. Ну и...

Как дают задания детям:

- Взять деньги и записку что купить

- ЕСЛИ горит красный свет, стоять ждать на переходе, не перебегать

_ЕСЛИ загорелся зеленый GOTO магазин 1

- ЕСЛИ в магазине 1 хлеба нет, GOTO в магазин 2

- ЕСЛИ хлеб кпулен GOTO в ларек за газетой

- ЕСЛИ газеты там нет, GOTO во второй ларек

- ЕСЛИ газета куплена, GOTO домой

 

Вот точно так же я написал и программу игрушки для Агата :lol:

Переписываем на Си:

Взять деньги и записку что купить;

(ЕСЛИ горит красный свет) { стоять ждать на переходе, не перебегать; }

(ЕСЛИ загорелся зеленый) { магазин 1; }

(ЕСЛИ в магазине 1 хлеба нет) { в магазин 2; }

(ЕСЛИ хлеб кпулен) { в ларек за газетой; }

(ЕСЛИ газеты там нет) { во второй ларек; }

(ЕСЛИ газета куплена) { домой; }

 

b707
Offline
Зарегистрирован: 26.05.2017

Ученик,  в принципе неплохо, только там где написано "защита от дребезга - строчки 27, 34, 47 и тд - на самом деле никакой защиты нет, эти строчки можно смело выкинуть , они бесполезны

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

b707. Вот здесь вы не правы. Вы просто не понимаете , как работает эта защита. И да ТС не понимает как должен бы правильным код для обработки кнопки.

jdigreze
Offline
Зарегистрирован: 14.01.2018

sadman41 пишет:

Как же вы на бейсике писали, если select case не знаете... Сложно вам придется в Си. Тут до датчиков еще с полгода учебы...

Это в более поздних васюках появилось, а ТС работал с нумероваными строками, там этого небыло ещё.

Цитата:
Шнур длиной до кнопки два метра, кабелем для 220в (0,7 кубика), он тупо дает наводки из воздуха (такие наводки??? кошмар).Укоротил шнур до полметра и убрал резистор между входом и корпус или 5v с 1 кОм до 200 Ом - стало стабатывать очень четко.Ну я не дома, это производство, просто не думал, что такое ОГРОМНЫЕ наводки идут.Это кстати в таких электромагнитных полях может и работать вредно (кошмарный смайлик)

Работать вообще вредно, говорят "от работы даже кони пухли и дохли".

Если поделие для производства, то кнопки располагать не более чем на 10 см от вывода МК, включая длину дорожки на печатной плате ардуино. Желательно вообще не более 3 см. Особенно если поделие управляет какой либо серьёзной нагрузкой, а не просто лампочками в кабинете. И антидребезг сделать как положено, а не через delay(). В противном - поделие будет представлять серьёзную опасность для жизни и здоровья персонала.

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

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

b707. Вот здесь вы не правы. Вы просто не понимаете , как работает эта защита.

Да ну? обьясните мне?

sadman41
Offline
Зарегистрирован: 19.10.2016

jdigreze пишет:

sadman41 пишет:

Как же вы на бейсике писали, если select case не знаете... Сложно вам придется в Си. Тут до датчиков еще с полгода учебы...

Это в более поздних васюках появилось, а ТС работал с нумероваными строками, там этого небыло ещё.

Да? Ну, может быть, конечно. Надо на МК-85 посмотреть доку - там же бейсик должен быть возраста Агата, думаю.

sadman41
Offline
Зарегистрирован: 19.10.2016

b707 пишет:

qwone пишет:

b707. Вот здесь вы не правы. Вы просто не понимаете , как работает эта защита.

Да ну? обьясните мне?

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

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

b707 пишет:
Да ну? обьясните мне?
А вот в этом и забавно. Если идет дождь и у вас нет зонта, то дождь можно пережать, особенно если он кратковременный. Так и с дребезгом. Дребезг он кратковременем во и его пережидают c помощью delay. Разумеется если у вас есть время и от вашего участия не стоит безопасность страны или корпорации.  Но надо ловить дребег нажатия и отжатия кнопки. Именно это обязательно.

/**/
const byte btnPin =/*пин кнопки*/2;
bool btn;
//-----------------------------
void setup() {
  Serial.begin(9600);
  pinMode(btnPin, INPUT_PULLUP);
  btn = digitalRead(btnPin);
}

void loop() {
  if (btn && !digitalRead(btnPin)) {
    btn = LOW;
    delay(10);
    Serial.println("tuk");
  }
  if (!btn && digitalRead(btnPin)) {
    btn = HIGH;
    delay(10);
  }
}
/**/

ПС:В некритичных проектах где прерывания вешаются на дребезжащие кнопки тоже можно сделать задержку на время дребезжания внутри обработчика прерывания. Но фукцию delay лучше не использовать.

вот така ху ...малята

sadman41
Offline
Зарегистрирован: 19.10.2016

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

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

sadman41, одним кондером не полутся надежно.Надо учитывать всякие паразитные сопротивления в цепи. Так что просится еще резистор.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Одного резистора маловато.

Ученик
Offline
Зарегистрирован: 19.09.2018

b707

Ну хорошо, назовем иначе - защита от помех.

На длинном проводе я наблюдал мерцание светодиода (неопределенное, часто произвольно меняющееся состояние выхода). Т.е. это защита от ЛОЖНЫХ срабатываний от помехи, а не нажатия кнопки.

Раскрываю секрет.

а) нет, скорее всего никто ничего делать не будет - мне просто задан ТЕСТ. Я даже управился раньше времени - в четверг впервые в жизни увидел Ардуино и впервые в жизни начал писать прогу на его урезанном Си, сдать надо к среде, а я управился с готовой программой в субботу...

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

Итак, с домфона снимаем сигнал, он выше обозначен как "Кнопка 1". Естественно от домофона до устройства - метров 200. Выход 1 - это проключение аудиотракта с одной стороны от домофона, с другой - как "снятие трубки" безнаборного аппарата. назначенного по снятию на такой-то номер.

Далее если владелец номера, куда идет звонок, поговорил и захотел открыть дверь, он нажимает "1", устройство должно поймать код DTMF в аудиотракте и включить замок двери (вернее открыть дверь). Это обозначено как "Кнопка 2" (сигнал с выхода приемника DTМF), а выход 2 - открыть дверь.

И таких линий три - то есть один Ардуино обслуживает три домофона и три независимых вызова и ответа/открывания дверей.

От сюда вопрос. если вдруг мне зададут вопрос - программа ОК, а на практике оно заработает? - что я должен ответить насчет кнопок? Располагать на 10 см не предлагать - реально 1-й дофомой может быть и рядом, но тогда 2-й домофой в другом полъезде - метров 100, а третий домофой в третьем подъезде - метров 200.

Как заставить сработать кнопку... вернее как уйти от помех?

Впрочем можете и не отвечать - вопрос к именно ПРОГРАММИРОВАНИЮ никакого отношения уже не имеет, это схемотехника и я ее в люблм случае делать не буду. Так же как и гальванические развязки для аудиотракта - их же нельзя соединять гальванически - домофонную аудиолинию и линию станции.

PS. Подумал. На самый крайний случай можно сделать через дополнительное реле - сигнал с домофона включает реле, оттуда мощная силовая линия 12в идет непосредственно до Ардуино, а рядом с Ардуино в 10 см от этих 12 в включается реле и замыкающие контакты реле включают уже подачу сигнала на пин Ардуино... лишнее реле и лишнее питание не гуд, но уйти от помех должно.

Ученик
Offline
Зарегистрирован: 19.09.2018

andriano пишет:

Одного резистора маловато.

То есть delay лучше выкинуть, а посадить кондерчик с резистром (некую развязку)?

sadman41
Offline
Зарегистрирован: 19.10.2016

12V в линию + оптрон около ног ардуины.

А каким образом ваш delay от помех защитит - я что-то никак не пойму.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ученик пишет:

andriano пишет:

Одного резистора маловато.

То есть delay лучше выкинуть, а посадить кондерчик с резистром (некую развязку)?

В простейшем случае - да. (т.е. когда все в одном корпусе и провода не длиннее 10-20 см)

Ну а если посерьезнее - то развязывать оптронами.

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

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

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А всего-то GOTO обсуждали, а какие страсти!

Я этот оператор только в ассемблере использую (там без него никак). И лет 30 назад в фортране. Забудьте про него навсегда! С ним программа становится нечитаемая.

jdigreze
Offline
Зарегистрирован: 14.01.2018

Ученик пишет:

От сюда вопрос. если вдруг мне зададут вопрос - программа ОК, а на практике оно заработает? - что я должен ответить насчет кнопок? Располагать на 10 см не предлагать - реально 1-й дофомой может быть и рядом, но тогда 2-й домофой в другом полъезде - метров 100, а третий домофой в третьем подъезде - метров 200.

Как заставить сработать кнопку... вернее как уйти от помех?

Впрочем можете и не отвечать - вопрос к именно ПРОГРАММИРОВАНИЮ никакого отношения уже не имеет, это схемотехника и я ее в люблм случае делать не буду. Так же как и гальванические развязки для аудиотракта - их же нельзя соединять гальванически - домофонную аудиолинию и линию станции.

PS. Подумал. На самый крайний случай можно сделать через дополнительное реле - сигнал с домофона включает реле, оттуда мощная силовая линия 12в идет непосредственно до Ардуино, а рядом с Ардуино в 10 см от этих 12 в включается реле и замыкающие контакты реле включают уже подачу сигнала на пин Ардуино... лишнее реле и лишнее питание не гуд, но уйти от помех должно.

Программные решения по защите от помех зависят от применённой схемотехники.

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

С учётом более детально озвученного ТЗ, если работает "на коленках", то должно работать и в готовом виде. Но для самообразования неплохо почитать про антидребезг и по возможности вставить в проект.

А вообще - респект и уважуха!

Ученик
Offline
Зарегистрирован: 19.09.2018

Утрясение хвостов.

Мне тут сказали - имеется ошибка: сигнал на открытие двери не имеет права быть дольше 1 сек.

Ок - ИСПРАВЛЕНИЕ (теперь сигнал выходов 2, 4, 6 не длинее 1 сек)

int state1=0; //состояние выхода 1 вкл или выкл
int state2=0; //состояние выхода 3 вкл или выкл
int state3=0; //состояние выхода 5 вкл или выкл
unsigned long timeStarted1 = 0;
unsigned long timeStarted2 = 0;
unsigned long timeStarted3 = 0;
unsigned long timeStarted4 = 0;
unsigned long timeStarted5 = 0;
unsigned long timeStarted6 = 0;
 
void setup() {
   pinMode(2, INPUT); //кнопка 1
   pinMode(3, INPUT); //кнопка 2
   pinMode(4, INPUT); //кнопка 3
   pinMode(5, INPUT); //кнопка 4
   pinMode(14, INPUT); //кнопка 5
   pinMode(15, INPUT); //кнопка 6

   pinMode(6, OUTPUT); // выход 1
   pinMode(7, OUTPUT); // выход 2
   pinMode(8, OUTPUT); // выход 3
   pinMode(9, OUTPUT); // выход 4
   pinMode(10, OUTPUT); // выход 5
   pinMode(11, OUTPUT); // выход 6
}
void loop() 
{  
  if(digitalRead(2) ) // если кнопка 1 нажата, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(6, HIGH); // выход/реле 1 ВКЛ
  state1=1; // признак включённого реле 1
  timeStarted1 = millis(); // включаем таймер первой группы
 } 
  if(digitalRead(3)&&state1) // если кнопка 2 нажата, реле1 вкл, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(7, HIGH); // выход/реле 2 ВКЛ
  timeStarted4 = millis(); // включаем краткий таймер выхода 2
 } 
  if( millis() - timeStarted4 >= 1000 ) // таймер выключится через 1 секунду
 {
  digitalWrite(7, LOW); // выход/реле 2 ВЫКЛ
  
 }
 
  if( millis() - timeStarted1 >= 20000 ) // таймер выключится через 18 секунд 
 {
  digitalWrite(6, LOW); // выход/реле 1 ВЫКЛ
  digitalWrite(7, LOW); // выход/реле 2 ВЫКЛ
  state1=0;
  
 }
   if(digitalRead(4) ) // если кнопка 3 нажата, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(8, HIGH); // выход/реле 3 ВКЛ
  state2=1; // признак включённого реле 3
  timeStarted2 = millis(); // включаем таймер второй группы
 } 
  if(digitalRead(5)&&state2) // если кнопка 4 нажата, реле3 вкл, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(9, HIGH); // выход/реле 4 ВКЛ
  timeStarted5 = millis(); // включаем краткий таймер выхода 4
 } 
   if( millis() - timeStarted5 >= 1000 ) // таймер выключится через 1 секунду
 {
  digitalWrite(9, LOW); // выход/реле 4 ВЫКЛ
  
 }
 
  if( millis() - timeStarted2 >= 20000 ) // таймер выключится через 18 секунд 
 {
  digitalWrite(8, LOW); // выход/реле 3 ВЫКЛ
  digitalWrite(9, LOW); // выход/реле 4 ВЫКЛ
  state2=0;
 }  
 if(digitalRead(14) ) // если кнопка 5 нажата, то:
 {
  delay(10); // защита от дребезга
  digitalWrite(10, HIGH); // выход/реле 5 ВКЛ
  state3=1; // признак включённого реле 5
  timeStarted3 = millis(); // включаем таймер третьей группы
 } 
  if(digitalRead(15)&&state3) // если кнопка 6 нажата, реле5 вкл
 {
  delay(10); // защита от дребезга
  digitalWrite(11, HIGH); // выход/реле 6 ВКЛ
  timeStarted6 = millis(); // включаем краткий таймер выхода 6
 } 
   if( millis() - timeStarted6 >= 1000 ) // таймер выключится через 1 секунду
 {
  digitalWrite(11, LOW); // выход/реле 2 ВЫКЛ
  
 }
 
  if( millis() - timeStarted3 >= 20000 ) // таймер выключится через 18 секунд 
 {
  digitalWrite(10, LOW); // выход/реле 5 ВЫКЛ
  digitalWrite(11, LOW); // выход/реле 6 ВЫКЛ
  state3=0;
 }
 
}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ученик, глянь

https://github.com/DetSimen/Arduino-

мошт поможет убрать череду бесконечных миллисов. 

Ученик
Offline
Зарегистрирован: 19.09.2018

Глянул. Главный вопрос - зачем? ТУт - НАГЛЯДНО.

Для новичка, который затрудняется держать в голове все эти переменные, одним из важным факторов является наглядность программы, когда каждый шаг можно представить в уме наглядно

Шаг 1 - включаем выход, шаг 2 - считаем счетчик, шаг три - счетчик сработал, выключаем выход ...

 

Может быть потом, когда буду как рыба в воде, и использую код по этой ссылке.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ученик пишет:

Для новичка, который затрудняется держать в голове все эти переменные, одним из важным факторов является наглядность программы, когда каждый шаг можно представить в уме наглядно

Это верно. И, собственно, это - основная идея структурного программирования.

Собственно, для достижения этой цели нужно: 

1. Осмысленно называть переменные.

2. Однотипные переменные собирать в массивы.

3. Разбивать код на функционально законченные фрагменты - функции.

Теперь смотрим, что у Вас:

- Почему переменная, описывающая состояние выхода 3 называется state2? И почему, если она принимает 2 значения, она имеет тип int?

- Почему timeStarted* не собраны в массив?

- Почему постоянно по тексту попадаются похожие фрагменты по 3-4 строки с однотипными же условиями?

Ученик
Offline
Зарегистрирован: 19.09.2018

[i]- Почему переменная, описывающая состояние выхода 3 называется state2? И почему, если она принимает 2 значения, она имеет тип int?

- Почему timeStarted* не собраны в массив?

- Почему постоянно по тексту попадаются похожие фрагменты по 3-4 строки с однотипными же условиями?[/i]

- Из истории. Выхода, которые требуют фиксции состояния - не 6, а всего 3. Таким образом, выход1, 2 и 3.

Но когда наименовывал выходы, забыл просто, вернее подумал, что выходы лучше именовать ГРУППАМИ - выходы 1-2 это 1 группа, выходы 3-4 это 2-я группа, выходы 5-6 - это 3 группа.

Получилось некрасиво, согласен. Вернее это если кто посторонний мою прогу для чего-то использует, он запутается - почему state2 определяет выход 3...

- Не изучил еще вопрос. Что такое массивы? (вопрос риторический, нахожусь в процессе изучения... на пару лет...)

- потому что мне так наглядно. Если их куда-то запихать, я не буду видеть и понимать, как оно работает.

Ученик
Offline
Зарегистрирован: 19.09.2018

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

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

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

Если отбой - это 450 гц, то за 1 сек должно произойти 450 пиков, то есть логических единиц.

Как вы думаете, это сработает?

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

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

jdigreze
Offline
Зарегистрирован: 14.01.2018

Ученик пишет:

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

...

Если отбой - это 450 гц, то за 1 сек должно произойти 450 пиков, то есть логических единиц.

Как вы думаете, это сработает?

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

Сигнал с линии, после гальванической развязки, превращаем (например компаратором) в цифровой.

Обнуляем счетчик "линия занята". Далее всё происходит в глобальном цикле.

Анализируем, есть ли тон 450 Гц, в противном случае идёт разговор и мы продолжаем ждать появления тона, при этом опять обнуляем счетчик (как раз на случай неверного определения тона в предыдущей итерации).

Как только нашли тон, определяем его длительность, и если она существенно больше 1 сек (на сколько я помню), то это сигнал "ожидания вызова" и мы ожидаем начала паузы и опять обнуляем счетчик, и так крутимся пока не поймаем тон длительностью менее или равным 1 сек. После чего увеличиваем счетчик на 1. 

Как только счетчик насчитал до 3 - выдаем сигнал на отключение.

Это общий размышлизм, но суть, я надеюсь, понятна.