Прерывание прерывания
- Войдите на сайт для отправки комментариев
Вс, 22/05/2016 - 18:35
int rele = 6; int rele2 = 7; volatile int state = HIGH; void setup() { pinMode(rele, OUTPUT); pinMode(rele2, OUTPUT); attachInterrupt(1, grink, RISING); attachInterrupt(0, srink, RISING); } void loop() { digitalWrite(rele, state); digitalWrite(rele2, state); } void grink() { digitalWrite(rele, LOW); delay(10000); digitalWrite(rele, HIGH); delay(10000); digitalWrite(rele, LOW); delay(10000); digitalWrite(rele, HIGH); delay(10000); digitalWrite(rele, LOW); delay(10000); digitalWrite(rele, HIGH); delay(10000); digitalWrite(rele, LOW); delay(10000); digitalWrite(rele, HIGH); delay(10000); digitalWrite(rele, LOW); delay(10000); digitalWrite(rele, HIGH); delay(10000); digitalWrite(rele, LOW); delay(10000); digitalWrite(rele, HIGH); delay(10000); digitalWrite(rele, LOW); delay(10000); digitalWrite(rele, HIGH); delay(10000); } void srink() { digitalWrite(rele2, LOW); delay(10000); digitalWrite(rele2, HIGH); delay(10000); digitalWrite(rele2, LOW); delay(10000); digitalWrite(rele2, HIGH); delay(10000); digitalWrite(rele2, LOW); delay(10000); digitalWrite(rele2, HIGH); delay(10000); digitalWrite(rele2, LOW); delay(10000); digitalWrite(rele2, HIGH); delay(10000); digitalWrite(rele2, LOW); delay(10000); digitalWrite(rele2, HIGH); delay(10000); digitalWrite(rele2, LOW); delay(10000); digitalWrite(rele2, HIGH); delay(10000); digitalWrite(rele2, LOW); delay(10000); digitalWrite(rele2, HIGH); delay(10000); digitalWrite(rele2, LOW); delay(10000); digitalWrite(rele2, HIGH); delay(10000); digitalWrite(rele2, LOW); delay(10000); digitalWrite(rele2, HIGH); delay(10000); }
Есть такой код, скажите, пожалуйста, можно ли как то сделать так, чтобы при выполнении функции grink при нажатии на кнопку второго прерывания тут же активизировлась бы функция srink. Или такое дело решается по другому? Задача такая - 12 датчиков, при срабатывании любого из них активизируется подпрограмма, которая в запрограммированном порядке обрабатывает четыре реле. Нужно, чтобы при работе подпрограммы, при срабатывании другого датчика сразу же выполнялась бы дргая подпрограмма а эта завершалась.
Нельзя прервать одно прерывание другим. Второе прерывание не сработает, пока не вышли из обработчика первого. Точнее взведётся флаг второго прерывания и будет ждать в очереди завершения первого, т.е. второе прерывание не потеряется.
У Вас неправильная концепция. Нельзя в обработчики прерывания пихать большие задержки, они должны выполняться как можно быстрее. Заведите переменные-флаги и только меняйте их состояние в обработчике прерывания. А в цикле loop проверяйте состояние этих переменных и в зависимости от него выполняйте нужные действия, например вызов функций. Но всё равно, пока не завершиться функция с кучей delay, другая не вызовется. Отказывайтесь от delay и используйте millis. И не обязательно кучу раз подряд повторять digitalWrite(rele, HIGH); digitalWrite(rele, LOW), можно просто инвертировать уровень.
Можно, но не так. И да, концепция неверна.
Тогда смысла нет заводить переменные - флаги, раз всё равно ждать конца обработки подпрограммы. А делей стоит просто для наглядности - примерно столько времени будет работать каждая из 12 подпрограмм - там ничего сложного - просто последовательное включение мощных нагрузок. Если вместо делей использовать миллис - будет ли работать прерывание как нужно? Можно даже не завершать предыдущую полпрограмму - главное, при пересечении датчика включить следующую, а та пусть завершается. Жека-M, не могли бы выслать свой идентификатор личной связи в одной из доступных для общения систем на почту krosslove@gmail.com? У меня для вас есть предложение.
ТС привёл шедевральный пример того, как не надо работать с прерываниями вообще :) Ничего, что в прерываниях millis не работает? А вы там delay устраивать пытаетесь?
Читать до посинения: https://www.arduino.cc/en/Reference/AttachInterrupt
Это я что первое в голову пришло написал. Значит в этом случае нужно делать код в лупе, плата дуе, хватит мощности всё быстро обрабатывать? Почитал про прерывания - получается, что никак нельзя сделать многозадачность.
krosslove, вам нужно СИ подучить, хотя бы основные операторы if, for, while. Тогда и мощности сразу на всё хватит, и многозадачность заработает :)
Вот, почитав по теме материалов, сделал вот такой код - пока для того, чтобы управлять временем включения каждого реле без использования делей. На плате не проверял еще - правильно ли я сделал? Достаточно ли будет быстродействия платы для отслеживания еще 12 таких блоков? Теперь мне надо объединить эти реле в группу (функцию?), чтобы вызывать их поочередное включение с помощью нажатия кнопки...
А ведь можете, когда хотите. Быстродействия хватит и на 120. А если еще заметить 3 однотипных куска кода (а должно быть вроде 12), которые так и просят чтоб с ними чтото сделали... можна функцию, но в данном случае лучше массив и цикл.
Я как понимаю - нужно как то работать с классами? До них еще не дошел... Если не трудно, дайте ссылку, буде изучать после того, как внедрю управление группами реле по кнопке. Массив и цикл для объединения в группу?. Почитаю.
Вот с помощью классов убрал повторяющийся код - так называемое объектно-ориентированное программирование в С++. Не могу пока проверить, интересно - заработает на железе?
Вопрос по 62 строке - могут имена классов объявлять переменные?
Объявляем переменные (почему нельзя объявить переменные до объявления имени класса?)
и, правда, почему нельзя? кто запретил?
лично мне разрешено объявлять переменные хоть на соседском заборе - пишу "Обама-чмо", но оно-зараза работает внутри класса Великая Россия, но никак не Америка.
кто знает, на каком заборе нужно написать, что бы в классе "Цивилизованное человечество" заработало?
Значит переменные класса объявляются внутри класса. Это правило языка или необходимость? Просто если классов несколько, переменные могут быть все с разными именами и перехлеста между работой классов быть не должно. Или как?
Значит переменные класса объявляются внутри класса. Это правило языка или необходимость? Просто если классов несколько, переменные могут быть все с разными именами и перехлеста между работой классов быть не должно. Или как?
походу, сам себя запутал... переменные с разными именами и, внезапно, перехлёст. чего с чем перехлёст?
*почему бы самому себе не ответить на свой простой вопрос, написав два класса и заюзав в этих классах переменные с разными и совпадающими именами?
чисто теоретически, смогут ли как-то конфликтовать две переменные class1.а и class2.а или class1.а и class2.b ?
Пока проверить не могу. Но чисто теоретически конфликта быть не может - программа при работе читает имена переменных. Но пример с одного из сайтов на с++ показывает, что переменные объявляются а классе. Хоя, там не написано, что это обязательно. Вот я и пытаюсь выяснить, пока руки не дошли самому проверить, имеет ли это значение, раз в примере было сделано именно так.
Еще мне непонятно, что происходит в строках 19-27. Для чего нужно присваивать в 23 строке переменной rele значение переменной pin, если в 27 строке можно вместо rele просто вставить pin?
думаю, что ты находишься в состоянии лёгкого бреда.
думаю, что ты находишься в состоянии лёгкого бреда.
Думаю, что здесь не место тешить свое эго. Для этого есть другие сайты, а если не хотите подсказать в правильном направлении - нечего амортизировать клавиатуру зряшными потугами выделиться перед новичком в программировании. Я и без вас знаю, что нужно работать над изучением языка.
здесь не место для публикации своего бреда.
Давайте закругляться с холиварами, мало их тут было? Я вам выделил то, что предыдущий автор назвал "бредом". Это иначе - не называется, и обижаться тут не на что. Никакая скомпилированная (а тут это только так) программа никогда не читает имена никаких переменных. Имена замещаются адресами в ОЗУ ещё на стадии компиляции. Собственно они нужны только автору, а никак не "вычислителю".
И далее. Переменные конечно могут "объявляться в классе", но только статические глобалы всего класса, то бишь "единые" для всех объектов этого класса. У объектов в классах объявляются СВОЙСТВА (поля структуры переменной - объекта) и методы работы с ними.
Про такое в объявлении класса "писать не принято".. в смысле это некий "нонсенс" в целом.
Отсюда, давайте отделим "мух от котлет":
1. Имя переменной - это человекоудобное представление АДРЕСА некоторого места в памяти, где можно "что-то хранить" и возможно даже "изменять" через оператор присваивания .. некий "ящичек" в комоде всего ОЗУ микроконтроллера.
2. Размещение имен в памяти (назначение им адресов) производится постепенно, в процессе компиляции, сборки и даже выполнения программы (локальные переменные и/или динамическая куча). И, чем раньше в этом процессе возникает решение "куда поместить" - тем лучше, и в этом смысле: глобальные и статические в блоках переменные - предпочтительней динамического размещения, в т.ч. и неявным размещением через new. Локалы, как обычно разговор отдельный и "тихо курят в сторонке".
3. статические, общие переменные класса, а равно как свойства объектов класса - создаются (учитываются компилятором и системой сборки) автоматически, как только Вы указываете использование того или иного класса. Так сказать и вовсе "без спросу": обязательно оно вам или нет.
Давайте закругляться с холиварами, мало их тут было? Я вам выделил то, что предыдущий автор назвал "бредом". Это иначе - не называется, и обижаться тут не на что. Никакая скомпилированная (а тут это только так) программа никогда не читает имена никаких переменных. Имена замещаются адресами в ОЗУ ещё на стадии компиляции. Собственно они нужны только автору, а никак не "вычислителю".
И далее. Переменные конечно могут "объявляться в классе", но только статические глобалы всего класса, то бишь "единые" для всех объектов этого класса. У объектов в классах объявляются СВОЙСТВА (поля структуры переменной - объекта) и методы работы с ними.
Про такое в объявлении класса "писать не принято".. в смысле это некий "нонсенс" в целом.
Отсюда, давайте отделим "мух от котлет":
1. Имя переменной - это человекоудобное представление АДРЕСА некоторого места в памяти, где можно "что-то хранить" и возможно даже "изменять" через оператор присваивания .. некий "ящичек" в комоде всего ОЗУ микроконтроллера.
2. Размещение имен в памяти (назначение им адресов) производится постепенно, в процессе компиляции, сборки и даже выполнения программы (локальные переменные и/или динамическая куча). И, чем раньше в этом процессе возникает решение "куда поместить" - тем лучше, и в этом смысле: глобальные и статические в блоках переменные - предпочтительней динамического размещения, в т.ч. и неявным размещением через new. Локалы, как обычно разговор отдельный и "тихо курят в сторонке".
3. статические, общие переменные класса, а равно как свойства объектов класса - создаются (учитываются компилятором и системой сборки) автоматически, как только Вы указываете использование того или иного класса. Так сказать и вовсе "без спросу": обязательно оно вам или нет.
Cпасибо большое, про классы более менее понял, читаю усиленно, когда время есть. На очереди статические-динамические переменные.
Проверил последний код - не заработал на железе, пришлось подправить и немного модернизировать. Вот, что получилось. В этом коде - должно:
- при замыкании датчика на 8 ноге платы последовательно включиться 4 реле с заданным пользователем временем.
Сейчас же это происходит только если датчик включить сразу, после подачи питания на плату. Это из - за того, что привязка отсчета сделана на millis. Соответственно, если мы подождем после включения платы некоторое время, которое равняется сумме установленного пользователем времени на всех 4 реле - то при нажатии датчика они сработают все одновременно. А нужно так, что если даже плата стояла включенной час - реле начинали отсчет времени относительно датчика и друг друга только по срабатыванию датчика. Копаю в этом направлении сейчас, но пока туго((...
Почему не работает включение реле с дежурного режима? То есть, если подождать после включения минуту, например и нажать кнопку - то включаться все реле, вместо того, чтобы включаться согласно задержкам в строках 70-73.
Почему не работает вот этот участок кода? Всю голову сломал...