Длительность прерывания

JMA61
Offline
Зарегистрирован: 03.09.2017

Здравствуйте!

Программировать только учусь, поэтому не знаю гораздо больше, чем знаю.

Возникла необходимость в скетче для устройства точечной сварки. Энкодером задаётся длительность импульса (0.....3 сек.), после нажатия на кнопку контроллер должен выдавать в течении заданного времени меандр частотой 20.....30 кГц для работы инвертора.

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

Проблема в том, что при работе прерывания функция loop не работает и отсчитывать время не может. С другой стороны - в прерывании не работают millis() и  micros(). В итоге после нажатия на кнопку я получаю длящийся до бесконечности меандр.

Суть вопроса: можно ли программно ограничить длительность прерывания? Или, возможно, есть какие-то другие пути для решения стоящей задачи?

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

Ваш код секретен? Где бесконечный меандр?

JMA61
Offline
Зарегистрирован: 03.09.2017

Забыл сказать: контроллер Arduino. В наличии есть UNO, Nano, ProMini_16MHz и ProMini_8MHz. Все - китайские.

JMA61
Offline
Зарегистрирован: 03.09.2017

Никаких секретов! Но выложить то, что вышло, я смогу только в понедельник - писал на работе, забыл скинуть на флешку.

Код самого генератора генератора прост -  тот же blink, только delay составляет 6 мкс .(с помощью библиотеки CiberLib). В реальности длительности импульса и паузы получились ~16 мкс. Вероятно, это связано с временем обработки команд.

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

Т.е. кода не будет?

Ну, тогда сами разбирайтесь, ибо хрустальные шары на этом форуме запрещены. Удачи!

JMA61
Offline
Зарегистрирован: 03.09.2017

JMA61 пишет:

Никаких секретов! Но выложить то, что вышло, я смогу только в понедельник - писал на работе, забыл скинуть на флешку.

 

 

А ВНИМАТЕЛЬНО прочитать начало сообщения?

Тогда б и до хрустальных шаров  разговор не дошёл...

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Как минимум 6мкс и 20..30кГц не вяжутся.

JMA61
Offline
Зарегистрирован: 03.09.2017

JMA61 пишет:

 В реальности длительности импульса и паузы получились ~16 мкс. Вероятно, это связано с временем обработки команд.

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

Чтобу loop не вызывался часто - сделайте внутри него:

void loop()
{
  while(1)
  {
     // тут ваш код
  }
}

И всё. По факту получите - войдёт один раз в loop - и будет там крутиться до посинения, не будет затрат на выход из функции и повторный вызов.

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

Ну сделайте по клику свой for(), пересчитайте время в кол-во циклов и устройте дискотеку внутри него. Для полного счастья заблокируйте прерывания и делайте паузу через delayMicroseconds() или NOP-ы.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

16мкс это какая частота?

Если хотите это делать в прерывании и при этом точно знаете частоту то выполняйте цикл определенное число раз и все. Например, частота у Вас 20кГц, экодером задали время 2 секунды, итого Ваш цикл должен выполниться 40000 раз и все.

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

JMA61 пишет:

Никаких секретов! Но выложить то, что вышло, я смогу только в понедельник - писал на работе, забыл скинуть на флешку.

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

А вообще, для генерации меандра нужно не прерывание, а таймер.

JMA61
Offline
Зарегистрирован: 03.09.2017

Вообще-то вопрос - чисто теоретический, для ответа на него скетч не нужен.

JMA61 пишет:

Суть вопроса: можно ли программно ограничить длительность прерывания?

 

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

JMA61 пишет:

Вообще-то вопрос - чисто теоретический, для ответа на него скетч не нужен.

JMA61 пишет:

Суть вопроса: можно ли программно ограничить длительность прерывания?

 

Это происходит автоматически: как только код прерывания закончился, прерывание заканчивается вместе с ним. Разумеется, если в коде прерывания нет бесконечных циклов.

JMA61
Offline
Зарегистрирован: 03.09.2017

Кроме того, меандр у меня работает.

Сложности вылезают из-за длительностей, на более низких частотах всё работает прекрасно. Если Вы внимательно перечитаете моё первое сообщение, то всё поймёте.

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

 

JMA61
Offline
Зарегистрирован: 03.09.2017

Об этом и вопрос! Как ограничить время генерации при неработающих millis() и micros()?

JMA61
Offline
Зарегистрирован: 03.09.2017

Пока не проверял, но, похоже, путь решения мне подсказали (на другом форуме).

В понедельник попробую - тогда отпишусь. Со скетчем  :-) ...

zilk
Offline
Зарегистрирован: 09.08.2017

JMA61 пишет:

Об этом и вопрос! Как ограничить время генерации при неработающих millis() и micros()?

В библиотеке CyberLib функции задержки delay_us() и delay_ms() в прерываниях работают, millis() и micros() тем более.

Не понятно, в чем проблема...

JMA61
Offline
Зарегистрирован: 03.09.2017

Хм... В описании CiberLib я не увидел ничего про millis() и micros(). Если они действительно работают, то проблема решена.

Буду пробовать. Спасибо за подсказку!!!

zilk
Offline
Зарегистрирован: 09.08.2017

JMA61 пишет:

Хм... В описании CiberLib я не увидел ничего про millis() и micros().

millis() и micros() это системные счетчики миллисекунд и микросекунд, прошедших от момента включения МК, им похрен библиотеки, они есть вещь-в-себе... :)

jurijt
Offline
Зарегистрирован: 27.07.2016

Привет JMA61!

Твою задачу надо разделить на две.

1  Получить меандр 30 кГц.  Такую частоту PWM можно получить изменив настройки Таймера1. В конфигурационный регистр    TCCR1B надо записать:

TCCR1B=B00000001;

Что дает частоту PWM ~31.13 kHz на выходах 9,10. и соответственно. 

analogWrite(9,127); или
analogWrite(10,127); 

даст меандр выше указанной частоты. Столько показал мой осц-аф при эксперементах с таймерами. 

2 задачу - выключить пин после необходимой задержки можно решить многими способами.  Через контроль значения millis() например.

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

JMA61 пишет:

Если Вы внимательно перечитаете моё первое сообщение, то всё поймёте.

Для того, чобы оценить Вашу квалификацию, читать внимательно совершенно необязательно, это просто бросается в глаза. Например, это:

JMA61 пишет:

Естественный выход - перенести генерацию меандра во внешнее прерывание от кнопки.

Я уже писал в посте №11, что для Вашей задачи практически безальтернативно подходит таймер. Все остальные варианты - в лучшем случае костыли.
 

JMA61 пишет:

Об этом и вопрос! Как ограничить время генерации при неработающих millis() и micros()?

Вы выдумываете несуществующие проблемы.

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

 

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

 

Я тут заглянул в хрустальный шар и он мне показал, будто Вы вызываете прерывания с определенной частотой (кстати, по тому же таймеру), только внутри прерывания вручную устанавливаете пин поочередно в разные состояния. И при этом пытаетесь определить, стоит ли Вам в очередной раз перекидывать пин в зависимости от текущего времени. Вы где-то вычитали, что это невозможно из-за того, что якобя в прерывании не работает millis(). Вероятно Вы даже что-то написали в коде и он у Вас не заработал. После чего Вы решили, что второе является следствием первого. Но это не так: неработоспособность Вашего кода связана с чем-то другим, ибо millis() внутри прерывания вполне себе работает (т.е. показывает время). Она лишь не обновляет его (т.е. приостанавливается при работе прерывания).

Соответственно, даже при Вашем кривом алгоритме (если не врет мой ХШ) он должен как-то работать. Так что дело в реализации, которую Вы так и не удосужились привести.

Увы, мой ХШ устаревшей модели и не может указато номера строк с ошибками при отсутствии исходного кода. Так что разбирайтесь со своей проблемой сами.

SLKH
Offline
Зарегистрирован: 17.08.2015

JMA61 пишет:
... Энкодером задаётся длительность импульса (0.....3 сек.), после нажатия на кнопку контроллер должен выдавать в течении заданного времени меандр частотой 20.....30 кГц для работы инвертора.

С виду всё просто. 

tone(pin, frequency, duration)

JMA61
Offline
Зарегистрирован: 03.09.2017

Уважаемый andriano!

1.

andriano пишет:

Для того, чобы оценить Вашу квалификацию...

О своей квалификации я сказал в самом начале, оценивать её дополнительно бессмысленно.

2.

andriano пишет:

читать внимательно совершенно необязательно

Вот тут Вы ошибаетесь. Невнимательное чтение ведёт к недопониманию сути. Это прекрасно видно из Ваших ответов.

3.

andriano пишет:

Все остальные варианты - в лучшем случае костыли.

Вполне допускаю это.  Ведь я ж и сам писал:

JMA61 пишет:

возможно, есть какие-то другие пути для решения стоящей задачи?

4.

andriano пишет:

говорит о том, что Вы выбрали какой-то совершенно неподходящий алгоритм

См. ответ из пункта 3.

5.

andriano пишет:

более того, считаете его единственно возможным

Неверно! Опять же - см. ответ из пункта 3.

6.

andriano пишет:

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

Вот за эту КОНКРЕТНУЮ подсказку - спасибо!

7.

andriano пишет:

Вы вызываете прерывания с определенной частотой

Вот к чему приводит невнимательное чтение! Я ж писал:

JMA61 пишет:

внешнее прерывание от кнопки.

Такое прерывание вызывается однократно, периода не имеет.

8.

andriano пишет:

millis() внутри прерывания вполне себе работает (т.е. показывает время). Она лишь не обновляет его (т.е. приостанавливается при работе прерывания).

А вот это непонятно! Если приостанавливается и не обновляет, то какой мне толк в том, что продолжпет считать "про себя"?

9.

andriano пишет:

он должен как-то работать.

Разумеется, КАК-ТО работает!

JMA61 пишет:

В итоге после нажатия на кнопку я получаю длящийся до бесконечности меандр.

10.

andriano пишет:

которую Вы так и не удосужились привести.

Опять невнимательность!

JMA61 пишет:

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

11.

andriano пишет:

Увы, мой ХШ устаревшей модели

Вы абсолютно правы! Он уже настолько помутнел, что не позволяет разглядеть написанного!

А люди, глядящие НЕ через ХШ, уже подсказали мне возможные пути решения проблемы, за что я им очень благодарен!

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

JMA61, я ВНИМАТЕЛЬНО прочитал ваше первое сообщение и меня родилось предположение о структуре вашего кода. Правда, предположение настолько чудовищное и нелепое, что я решил переспросить.

Верно ли я догадался, что всю генерацию импульса длиной в 1-3 секунды вы решили запихнуть в однократный вызов прерывания по кнопке?

 

Добавка - дайте ссылку на то, что вам посоветовали на другом форуме

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

b707 пишет:

Верно ли я догадался, что всю генерацию импульса длиной в 1-3 секунды вы решили запихнуть в однократный вызов прерывания по кнопке?

Я ещё вчера подумал, что в прерывание он засунул вообще бесконечноый цикл, а теперь думает как его прервать.

На мою просьбу о коде, получил совет читать внимательнее, да ещё и ОРОМ, так что не тему и на ТС забил, что и Вам советую :))))

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

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

Я ещё вчера подумал, что в прерывание он засунул вообще бесконечноый цикл, а теперь думает как его прервать.

я пока подожду ответа автора, так как мое предположениене совершенно дикое, а я не до конца потерял веру в человечество.

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

b707 пишет:

а я не до конца потерял веру в человечество.

Оптимист, однако!

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

b707 пишет:

 я не до конца потерял веру в человечество.

вот так я и спился. 

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

JMA61 пишет:

О своей квалификации я сказал в самом начале, оценивать её дополнительно бессмысленно.

Вы сами себе противоречите. Из Вашего поста №14:

JMA61 пишет:
 
Если Вы внимательно перечитаете моё первое сообщение, то всё поймёте.
 
 
следует, что в Вашем первом посте написано что-то осмысленное. Увы, это не так. Как-то не очень тактично писать ТС, что у него в посте бред, но раз уж он с одной стороны признается в скоей невысокой квалификации (и первый пост это подтверждает), а с другой - требует тщательно перечитывать его бред, как будто из него что-то можно понять, то помимо квалификации возникают сомнения еще и в адекватности автора.
 
Цитата:

Вот за эту КОНКРЕТНУЮ подсказку - спасибо!

Здрассте!

Это я уже писал еще в посте №13. В том самом на который Вы посоветовали мне читать Ваше первое сообщение внимательнее.

Лично я не вижу для себя никакой пользы внимательно читать Ваши сообщения.

Но почему Вы сначала задаете вопросы, а потом ВООБЩЕ не читаете на них ответы?

Цитата:

andriano пишет:

millis() внутри прерывания вполне себе работает (т.е. показывает время). Она лишь не обновляет его (т.е. приостанавливается при работе прерывания).

А вот это непонятно! Если приостанавливается и не обновляет, то какой мне толк в том, что продолжпет считать "про себя"?

Оно не "про себя".

Если уж Вы прибегаете к прерыванию, то должны быть четко уверены, что Ваше прерывание будет укладываться в период между приращениями millis(). Другими словами, Ваше прирывание НИКОГДА не должно превосходдить по длительности 1 мс. Если Вам КАЖЕТСЯ, что по логике работы Вашей программы оно должно быть больше, значит, неверна эта логика - следует отказаться от данного алгоритма и подобрать другой.

JMA61
Offline
Зарегистрирован: 03.09.2017

Чтобы найти жемчужину, всегда приходится разгрести кучу навоза. Так и здесь – я получил несколько конкретных практических советов и кучу флуда на тему моей компетентности (о которой я сам сказал в начале) и даже адекватности  (спасибо,  дураком не назвали!). Вероятно,  все ламеры изучают программирование  ещё в материнской утробе и никогда не были новичками.  Их цель – поучать, чтоб показать себя «шибко умными». По опыту – редко кто из них разбирается в программировании глубоко, как правило – верхушек нахватались и враз поумнели.

Ну, да Бог с ними (верхний регистр – это выделение для невнимательных, а не ор)! Собаки лают – медведь пашет! В дальнейшем я не буду отвечать на ламерские выпады, чтоб не тешить их нездоровое самолюбие.

А тем, кто дал конкретные подсказки без флуда – спасибо! Пусть не все они работают с такими малыми длительностями, как в моём случае ( я многое перепробовал перед созданием темы), главное – ваша готовность помочь.

Отдельное огромное спасибо  jurijt  и SLKH – ваши советы наиболее конкретны и , похоже, действенны! В понедельник проверю и отпишусь.

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

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

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

b707, на самом деле, я ведь человеку с самого начала объяснил, что без кода ничего не будет. Он же вместо того, чтобы успокоиться, и ждать до понедельника начал тут нам доказывать, что:

JMA61 пишет:
скетч не нужен.

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

Ну, и получил "за что боролся". Объяснили же с самого начала, слушать надо было, чего теперь оскорблённую гимназистку-то разыгрывать.

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

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

Мне, кстати, интересно - что ж ему посоветовали "полезного" на другом форуме. Жалко, если он этого не ответит. Если наши предположения о коде ТС верны - из "полезного" тут мог быть только совет выкинуть код полностью и почитать даташит.

 

JMA61
Offline
Зарегистрирован: 03.09.2017

SLKH, спасибо огромное!

Именно tone() подошла для моих целей как нельзя лучше! Скетч работает, как только закончу с "железом" - сразу выложу в проекты. Может быть, кому-то пригодится!

JMA61
Offline
Зарегистрирован: 03.09.2017

Привет, jurijt!

В конце концов для моего устройства лучше всего подошла функция tone(), но опробовал я и твой вариант - всё работает прекрасно. Спасибо за помощь!