Длительность прерывания
- Войдите на сайт для отправки комментариев
Здравствуйте!
Программировать только учусь, поэтому не знаю гораздо больше, чем знаю.
Возникла необходимость в скетче для устройства точечной сварки. Энкодером задаётся длительность импульса (0.....3 сек.), после нажатия на кнопку контроллер должен выдавать в течении заданного времени меандр частотой 20.....30 кГц для работы инвертора.
С виду всё просто. Скетч для энкодера и таймера написал, но потом столкнулся с проблемой: меандр с такой частотой в функции loop получить невозможно из-за длительнсти выполнения как её самой, так и вложенных в неё других функций. Естественный выход - перенести генерацию меандра во внешнее прерывание от кнопки.
Проблема в том, что при работе прерывания функция loop не работает и отсчитывать время не может. С другой стороны - в прерывании не работают millis() и micros(). В итоге после нажатия на кнопку я получаю длящийся до бесконечности меандр.
Суть вопроса: можно ли программно ограничить длительность прерывания? Или, возможно, есть какие-то другие пути для решения стоящей задачи?
Ваш код секретен? Где бесконечный меандр?
Забыл сказать: контроллер Arduino. В наличии есть UNO, Nano, ProMini_16MHz и ProMini_8MHz. Все - китайские.
Никаких секретов! Но выложить то, что вышло, я смогу только в понедельник - писал на работе, забыл скинуть на флешку.
Код самого генератора генератора прост - тот же blink, только delay составляет 6 мкс .(с помощью библиотеки CiberLib). В реальности длительности импульса и паузы получились ~16 мкс. Вероятно, это связано с временем обработки команд.
Т.е. кода не будет?
Ну, тогда сами разбирайтесь, ибо хрустальные шары на этом форуме запрещены. Удачи!
Никаких секретов! Но выложить то, что вышло, я смогу только в понедельник - писал на работе, забыл скинуть на флешку.
А ВНИМАТЕЛЬНО прочитать начало сообщения?
Тогда б и до хрустальных шаров разговор не дошёл...
Как минимум 6мкс и 20..30кГц не вяжутся.
В реальности длительности импульса и паузы получились ~16 мкс. Вероятно, это связано с временем обработки команд.
Чтобу loop не вызывался часто - сделайте внутри него:
И всё. По факту получите - войдёт один раз в loop - и будет там крутиться до посинения, не будет затрат на выход из функции и повторный вызов.
Ну сделайте по клику свой for(), пересчитайте время в кол-во циклов и устройте дискотеку внутри него. Для полного счастья заблокируйте прерывания и делайте паузу через delayMicroseconds() или NOP-ы.
16мкс это какая частота?
Если хотите это делать в прерывании и при этом точно знаете частоту то выполняйте цикл определенное число раз и все. Например, частота у Вас 20кГц, экодером задали время 2 секунды, итого Ваш цикл должен выполниться 40000 раз и все.
Никаких секретов! Но выложить то, что вышло, я смогу только в понедельник - писал на работе, забыл скинуть на флешку.
Ну, тогда и тему не имело смысла создавать раньше понедельника.
А вообще, для генерации меандра нужно не прерывание, а таймер.
Вообще-то вопрос - чисто теоретический, для ответа на него скетч не нужен.
Суть вопроса: можно ли программно ограничить длительность прерывания?
Вообще-то вопрос - чисто теоретический, для ответа на него скетч не нужен.
Суть вопроса: можно ли программно ограничить длительность прерывания?
Это происходит автоматически: как только код прерывания закончился, прерывание заканчивается вместе с ним. Разумеется, если в коде прерывания нет бесконечных циклов.
Кроме того, меандр у меня работает.
Сложности вылезают из-за длительностей, на более низких частотах всё работает прекрасно. Если Вы внимательно перечитаете моё первое сообщение, то всё поймёте.
То, что мне здесь насоветовали, я уже пробовал - выполнение функций мешает работе генератора, причём очень значительно. Именно поэтому пришлось перенести его в прерывание.
Об этом и вопрос! Как ограничить время генерации при неработающих millis() и micros()?
Пока не проверял, но, похоже, путь решения мне подсказали (на другом форуме).
В понедельник попробую - тогда отпишусь. Со скетчем :-) ...
Об этом и вопрос! Как ограничить время генерации при неработающих millis() и micros()?
В библиотеке CyberLib функции задержки delay_us() и delay_ms() в прерываниях работают, millis() и micros() тем более.
Не понятно, в чем проблема...
Хм... В описании CiberLib я не увидел ничего про millis() и micros(). Если они действительно работают, то проблема решена.
Буду пробовать. Спасибо за подсказку!!!
Хм... В описании CiberLib я не увидел ничего про millis() и micros().
millis() и micros() это системные счетчики миллисекунд и микросекунд, прошедших от момента включения МК, им похрен библиотеки, они есть вещь-в-себе... :)
Привет JMA61!
Твою задачу надо разделить на две.
1 Получить меандр 30 кГц. Такую частоту PWM можно получить изменив настройки Таймера1. В конфигурационный регистр TCCR1B надо записать:
Что дает частоту PWM ~31.13 kHz на выходах 9,10. и соответственно.
analogWrite(9,127); или
analogWrite(10,127);
даст меандр выше указанной частоты. Столько показал мой осц-аф при эксперементах с таймерами.
2 задачу - выключить пин после необходимой задержки можно решить многими способами. Через контроль значения millis() например.
Если Вы внимательно перечитаете моё первое сообщение, то всё поймёте.
Для того, чобы оценить Вашу квалификацию, читать внимательно совершенно необязательно, это просто бросается в глаза. Например, это:
Естественный выход - перенести генерацию меандра во внешнее прерывание от кнопки.
Об этом и вопрос! Как ограничить время генерации при неработающих millis() и micros()?
Вы выдумываете несуществующие проблемы.
То, что у Вас возникают подобные вопросы, говорит о том, что Вы выбрали какой-то совершенно неподходящий алгоритм и, более того, считаете его единственно возможным. Но т.к. неправильных алгоритмов море, а код Вы не опубликовали, то как имено Вы пытаетесь решить свою проблему, мы не знаем.
Приавильное решение: для генерации нужной часты использовать таймер, который по надобности перепрограммировать из loop().
Я тут заглянул в хрустальный шар и он мне показал, будто Вы вызываете прерывания с определенной частотой (кстати, по тому же таймеру), только внутри прерывания вручную устанавливаете пин поочередно в разные состояния. И при этом пытаетесь определить, стоит ли Вам в очередной раз перекидывать пин в зависимости от текущего времени. Вы где-то вычитали, что это невозможно из-за того, что якобя в прерывании не работает millis(). Вероятно Вы даже что-то написали в коде и он у Вас не заработал. После чего Вы решили, что второе является следствием первого. Но это не так: неработоспособность Вашего кода связана с чем-то другим, ибо millis() внутри прерывания вполне себе работает (т.е. показывает время). Она лишь не обновляет его (т.е. приостанавливается при работе прерывания).
Соответственно, даже при Вашем кривом алгоритме (если не врет мой ХШ) он должен как-то работать. Так что дело в реализации, которую Вы так и не удосужились привести.
Увы, мой ХШ устаревшей модели и не может указато номера строк с ошибками при отсутствии исходного кода. Так что разбирайтесь со своей проблемой сами.
С виду всё просто.
tone(pin, frequency, duration)
Уважаемый andriano!
1.
Для того, чобы оценить Вашу квалификацию...
О своей квалификации я сказал в самом начале, оценивать её дополнительно бессмысленно.
2.
читать внимательно совершенно необязательно
Вот тут Вы ошибаетесь. Невнимательное чтение ведёт к недопониманию сути. Это прекрасно видно из Ваших ответов.
3.
Все остальные варианты - в лучшем случае костыли.
Вполне допускаю это. Ведь я ж и сам писал:
возможно, есть какие-то другие пути для решения стоящей задачи?
4.
говорит о том, что Вы выбрали какой-то совершенно неподходящий алгоритм
См. ответ из пункта 3.
5.
более того, считаете его единственно возможным
Неверно! Опять же - см. ответ из пункта 3.
6.
Приавильное решение: для генерации нужной часты использовать таймер, который по надобности перепрограммировать из loop().
Вот за эту КОНКРЕТНУЮ подсказку - спасибо!
7.
Вы вызываете прерывания с определенной частотой
Вот к чему приводит невнимательное чтение! Я ж писал:
внешнее прерывание от кнопки.
Такое прерывание вызывается однократно, периода не имеет.
8.
millis() внутри прерывания вполне себе работает (т.е. показывает время). Она лишь не обновляет его (т.е. приостанавливается при работе прерывания).
А вот это непонятно! Если приостанавливается и не обновляет, то какой мне толк в том, что продолжпет считать "про себя"?
9.
он должен как-то работать.
Разумеется, КАК-ТО работает!
В итоге после нажатия на кнопку я получаю длящийся до бесконечности меандр.
10.
которую Вы так и не удосужились привести.
Опять невнимательность!
смогу только в понедельник - писал на работе, забыл скинуть на флешку.
11.
Увы, мой ХШ устаревшей модели
Вы абсолютно правы! Он уже настолько помутнел, что не позволяет разглядеть написанного!
А люди, глядящие НЕ через ХШ, уже подсказали мне возможные пути решения проблемы, за что я им очень благодарен!
JMA61, я ВНИМАТЕЛЬНО прочитал ваше первое сообщение и меня родилось предположение о структуре вашего кода. Правда, предположение настолько чудовищное и нелепое, что я решил переспросить.
Верно ли я догадался, что всю генерацию импульса длиной в 1-3 секунды вы решили запихнуть в однократный вызов прерывания по кнопке?
Добавка - дайте ссылку на то, что вам посоветовали на другом форуме
Верно ли я догадался, что всю генерацию импульса длиной в 1-3 секунды вы решили запихнуть в однократный вызов прерывания по кнопке?
Я ещё вчера подумал, что в прерывание он засунул вообще бесконечноый цикл, а теперь думает как его прервать.
На мою просьбу о коде, получил совет читать внимательнее, да ещё и ОРОМ, так что не тему и на ТС забил, что и Вам советую :))))
Я ещё вчера подумал, что в прерывание он засунул вообще бесконечноый цикл, а теперь думает как его прервать.
я пока подожду ответа автора, так как мое предположениене совершенно дикое, а я не до конца потерял веру в человечество.
а я не до конца потерял веру в человечество.
Оптимист, однако!
я не до конца потерял веру в человечество.
вот так я и спился.
О своей квалификации я сказал в самом начале, оценивать её дополнительно бессмысленно.
Вы сами себе противоречите. Из Вашего поста №14:
Вот за эту КОНКРЕТНУЮ подсказку - спасибо!
Здрассте!
Это я уже писал еще в посте №13. В том самом на который Вы посоветовали мне читать Ваше первое сообщение внимательнее.
Лично я не вижу для себя никакой пользы внимательно читать Ваши сообщения.
Но почему Вы сначала задаете вопросы, а потом ВООБЩЕ не читаете на них ответы?
millis() внутри прерывания вполне себе работает (т.е. показывает время). Она лишь не обновляет его (т.е. приостанавливается при работе прерывания).
А вот это непонятно! Если приостанавливается и не обновляет, то какой мне толк в том, что продолжпет считать "про себя"?
Оно не "про себя".
Если уж Вы прибегаете к прерыванию, то должны быть четко уверены, что Ваше прерывание будет укладываться в период между приращениями millis(). Другими словами, Ваше прирывание НИКОГДА не должно превосходдить по длительности 1 мс. Если Вам КАЖЕТСЯ, что по логике работы Вашей программы оно должно быть больше, значит, неверна эта логика - следует отказаться от данного алгоритма и подобрать другой.
Чтобы найти жемчужину, всегда приходится разгрести кучу навоза. Так и здесь – я получил несколько конкретных практических советов и кучу флуда на тему моей компетентности (о которой я сам сказал в начале) и даже адекватности (спасибо, дураком не назвали!). Вероятно, все ламеры изучают программирование ещё в материнской утробе и никогда не были новичками. Их цель – поучать, чтоб показать себя «шибко умными». По опыту – редко кто из них разбирается в программировании глубоко, как правило – верхушек нахватались и враз поумнели.
Ну, да Бог с ними (верхний регистр – это выделение для невнимательных, а не ор)! Собаки лают – медведь пашет! В дальнейшем я не буду отвечать на ламерские выпады, чтоб не тешить их нездоровое самолюбие.
А тем, кто дал конкретные подсказки без флуда – спасибо! Пусть не все они работают с такими малыми длительностями, как в моём случае ( я многое перепробовал перед созданием темы), главное – ваша готовность помочь.
Отдельное огромное спасибо jurijt и SLKH – ваши советы наиболее конкретны и , похоже, действенны! В понедельник проверю и отпишусь.
JMA61/. если вы на легкий троллинг так возбуждаетесь, а на критику уши затыкаете - вы никогда ничему не научитесь. Чтобы извлечь урок из этого случая - вам надо было бы попросить умных людей обьяснить, почему ваш "естесственный способ" с прерыванием - дичь и бред. Вы же вместо этого изображаете из себя оскорбленную добродетель.
b707, на самом деле, я ведь человеку с самого начала объяснил, что без кода ничего не будет. Он же вместо того, чтобы успокоиться, и ждать до понедельника начал тут нам доказывать, что:
А того не понимает, что у нас тут то, блин, с ресета сигнал читают, то 1+2 получают 540, и что докапываться до глубин сознания новичка без кода - это даже не мастурбация, а ещё хлеще.
Ну, и получил "за что боролся". Объяснили же с самого начала, слушать надо было, чего теперь оскорблённую гимназистку-то разыгрывать.
ЕвгенийП, ну тут такая смесь социальной психологии, что и не знаешь, что и сказать. Для многих, чем справедливее критика - тем она обиднее. Парадокс.
Мне, кстати, интересно - что ж ему посоветовали "полезного" на другом форуме. Жалко, если он этого не ответит. Если наши предположения о коде ТС верны - из "полезного" тут мог быть только совет выкинуть код полностью и почитать даташит.
SLKH, спасибо огромное!
Именно tone() подошла для моих целей как нельзя лучше! Скетч работает, как только закончу с "железом" - сразу выложу в проекты. Может быть, кому-то пригодится!
Привет, jurijt!
В конце концов для моего устройства лучше всего подошла функция tone(), но опробовал я и твой вариант - всё работает прекрасно. Спасибо за помощь!