Только лично мне не понятно почему работает именно, когда здесь пишешь микро, а не endSignalTime: if (micros() - startSignalTime >= CONTROL_PERIOD)
Так правильно. Это ж Вы для определения таймаута пишете. Вам нужно текущее время. а endSignalTime в начале то ещё и не определён!
DmitryR пишет:
и ещё есть такая странность, при выдаче результата, он его пишет, пока не сделаешь сброс:
Ну, это-то понятно. Когда я советовал добавить состояние "Аминь" - имелось в виду, что это состояние когда ВСЕ ЗАКОНЧЕНО. Ваше же Ready - означает, что закончено, но ещё не отпечатано.
Поэтому,
1. либо завдените ещё одно состояние таки "ВСЁ ЗАКОНЧЕНО" и устанваливайте его после строки 46. Тогда if в строке 43 сработает только щдин раз.
2. либо оставьте как есть, но печать перенесите "после строки 39", а нынешние строки 42-48 тогда не нужны вовсе.
Искал ответ на вопрос, как внутри прерывания получить текущее время, наткнулся на данную дискуссию. Вам бы стоило, друзья мои, внимательней прочесть "Замечание по использованию" функции attachInterrupt():
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. ...
Ладно, ладно, просто мимо проходил, решил поумничать. xD
Увидел последовательность одинаковых результатов, думать было лень, но у меня была другая проблема - из прерывания читал время в массив, а в результате выводил только первый элемент из него.
Но конкретно по приведенному коду (последнему), не вижу особого смысла разрешать прерывания внутри обработчика - до входа в обработчик они все равно разрешены, а micros() их все равно запрещает. Здесь разрешение прерываний перед функцией повышает точность всего на ~4 мкс относительно входа. И плюс, не совсем понятно зачем надо было volatile делать static - в описании attachInterrupt указано только volatile.
Искал ответ на вопрос, как внутри прерывания получить текущее время, наткнулся на данную дискуссию. Вам бы стоило, друзья мои, внимательней прочесть "Замечание по использованию" функции attachInterrupt():
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. ...
Здравствуйте, можно объяснение для не ведующих, относительно фразы: значения возвращаемые millis() не изменяются. ... ?
Дело в том, что внутренние часы (точнее счетчик, сделанный кратным микросекундам) обновляются по прерыванию внутреннего таймера, а при входе в обработчик прерывания, все остальные прерывания преостанавливаются и возобновляются только после выхода из текущего обработчика (в один момент времени обрабатывается только одно прерывание). Соответственно, без какого-либо воздействия на обработку прерываний внутри обработчика, многократный вызов функций millis() и micros() будет возвращать одно и тоже значение. То есть, если появится желание измерить время работы кода внутри обработчика прерывания (читаем время в начале, читаем время в конце - разность значений и есть время), то результат будет "0", так как внутри обработчика не вызываются другие обработчики, в частности прерывания по таймеру. Здесь как раз и полезно вызвать разрешение прерываний sei() или interrupts() перед последним (в конце кода) вызовом функции millis() или micros().
Это просто грамотная привычка - не расширять область видимости без необходимости.
Если я правильно понял из описания volatile:
Переменная должна быть объявлена volatile, когда её значение может быть изменено чем-либо за пределами того участка программы, где она объявлена, например, параллельно выполняющимся процессом. В Arduino единственным местом, где это может проявиться, является участок программы, ассоциированным с прерываниями, вызванный программой обработки прерываний. См. AttachInterrupt()
это было сделано сугубо для прерываний. Не влияет ли значение static на компилятор, заставляя его сохранять переменную в регистр, а не в ОЗУ? Тогда, по идее, внутри обработчика она может не обновляться. На мой взгляд, нет необходимости использовать static там, где он неприменим.
Ну, вот Вы про volatile прочитали. А теперь прочитайте ещё что означает static для глобальной переменной, а уж потом будете рассуждать где он применим, а где - нет.
Это приведет к разрешению обработки прерываний, стоящих в очереди - таймер там уже есть, просто еще не выполнялся.
Вы знаете, что Совецкий союз развалился, когда правительство начало экспериментировать с очередями и разрешениями? Так что давайте, не тово... А то все ваши ардуины распадутся на транзисторы и шины данных
Это приведет к разрешению обработки прерываний, стоящих в очереди - таймер там уже есть, просто еще не выполнялся.
Вы знаете, что Совецкий союз развалился, когда правительство начало экспериментировать с очередями и разрешениями? Так что давайте, не тово... А то все ваши ардуины распадутся на транзисторы и шины данных
В данном конкретном случае: гонка вооружений - занятие достаточно веселое. ;-)
Ожидать могут все, а вот как только разрешение поднять, то будет выполнена самая приорететная. При этом , цитата, The user software can write logic one to the I-bit to enable nested interrupts. All enabled interrupts can then interrupt the current interrupt routine. Что будет дальше даже боюсь предположить, потому что, цитата, The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed. И получается, к процедуре прерывания , в которой принудительно разрешили прерывания будет завершена только после выполнения всех прерываний стоящих в очереди.
Да, это как в закрытый супермаркет придти, через служебный вход, набрать товара, встать на кассу и в час пик открыть магазин, а потом пропустить всю очередь за тобой, чтобы посмотреть кто, что купил. Само собой, льготники пойдут первыми. xD
Данный механизм создан исключительно для тех случаев, когда это крайне необходимо. Гараздо сложнее бывает там, где такой механизм в принципе не реализован, а других вариантов для решения уже не осталось.
Да, чисто поржать. А если серьезно, то я в то время особо не ведал, что творю, потому что только только начинал в этом всем разбираться и это надо было сделать в довольно сжатые сроки. С помощью участников форума был написан какой-то код, который дал какой-то результат. Сейчас я не связываюсь непосредственно с ардуино и копаться в том, что там было особо желания нет.
ок, ждём понедельник
так, ну раз у Вас железо не дома, мы сейчас плотно поработать не сможем?
Давайте согласуем время, когда сможем?
Да, до понедельника доступа к железу нет. Я думаю можно в понедельник в 6 утра по москве?
Помилуйте, в 6 утра по Москве я сплю как убитый. В 19 по Москве?
У меня просто часовой пояс UTC+7, т.е. в 19 у меня 23, доступ к железу могу получить с 6 (мск) до 15 (мск), здание закрывают, меня выгонят
Хреново. А домой забрать нельзя?
Осциллограф надо тащить с магнитопроводом, могут не разрешить
Давайте я в понедельник попробую, там либо заберу всё домой, либо отпишусь о результатах
Код работает:
Только лично мне не понятно почему работает именно, когда здесь пишешь микро, а не endSignalTime: if (micros() - startSignalTime >= CONTROL_PERIOD)
и ещё есть такая странность, при выдаче результата, он его пишет, пока не сделаешь сброс:
Код работает:
Отлично, согласитеь, здорово самому дожать!
Только лично мне не понятно почему работает именно, когда здесь пишешь микро, а не endSignalTime: if (micros() - startSignalTime >= CONTROL_PERIOD)
Так правильно. Это ж Вы для определения таймаута пишете. Вам нужно текущее время. а endSignalTime в начале то ещё и не определён!
и ещё есть такая странность, при выдаче результата, он его пишет, пока не сделаешь сброс:
Ну, это-то понятно. Когда я советовал добавить состояние "Аминь" - имелось в виду, что это состояние когда ВСЕ ЗАКОНЧЕНО. Ваше же Ready - означает, что закончено, но ещё не отпечатано.
Поэтому,
1. либо завдените ещё одно состояние таки "ВСЁ ЗАКОНЧЕНО" и устанваливайте его после строки 46. Тогда if в строке 43 сработает только щдин раз.
2. либо оставьте как есть, но печать перенесите "после строки 39", а нынешние строки 42-48 тогда не нужны вовсе.
//Отлично, согласитеь, здорово самому дожать!
Да, с этим не поспоришь, главное что стал понимать работу кода
Осталось теперь довести всё измерительное устройство до ума, но это уже не так сложно.
Спасибо большое за помощь!
Уф, даже попкорн кончился ... надеюсь на осеннюю пересдачу автор таки успел. Абыдна будет, если отчислят.. ведь разобрался. ;)
Уф, даже попкорн кончился ...
Нельзя тах халатно подходить к запасам. надо вовремя пополнять!
//Уф, даже попкорн кончился ... надеюсь на осеннюю пересдачу автор таки успел. Абыдна будет, если отчислят.. ведь разобрался. ;)
Не расстраивайтесь, эту задачу доделаю, за новую возьмусь, так что запасайтесь
Искал ответ на вопрос, как внутри прерывания получить текущее время, наткнулся на данную дискуссию. Вам бы стоило, друзья мои, внимательней прочесть "Замечание по использованию" функции attachInterrupt():
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. ...
Тоже самое относится и к micros().
Обоже! Наконец то стало ясно!
Ненуачо, хорошо же, еще один Шрёдингер просветлел.
А если он узнает, что при входе в прерывание можно их опять разрешить одной командой - вапще в нирвану впадёт.
Ладно, ладно, просто мимо проходил, решил поумничать. xD
Увидел последовательность одинаковых результатов, думать было лень, но у меня была другая проблема - из прерывания читал время в массив, а в результате выводил только первый элемент из него.
Но конкретно по приведенному коду (последнему), не вижу особого смысла разрешать прерывания внутри обработчика - до входа в обработчик они все равно разрешены, а micros() их все равно запрещает. Здесь разрешение прерываний перед функцией повышает точность всего на ~4 мкс относительно входа. И плюс, не совсем понятно зачем надо было volatile делать static - в описании attachInterrupt указано только volatile.
Ненуачо, хорошо же, еще один Шрёдингер просветлел.
"Kater" - разговорное, может означать как похмелье, так и кота в частности. xD
не совсем понятно зачем надо было volatile делать static - в описании attachInterrupt указано только volatile.
Это просто грамотная привычка - не расширять область видимости без необходимости.
Искал ответ на вопрос, как внутри прерывания получить текущее время, наткнулся на данную дискуссию. Вам бы стоило, друзья мои, внимательней прочесть "Замечание по использованию" функции attachInterrupt():
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. ...
Тоже самое относится и к micros().
Здравствуйте, можно объяснение для не ведующих, относительно фразы: значения возвращаемые millis() не изменяются. ... ?
А что Вам непонятно в этой фразе? "Не изменяются" означает "остаются теми же самыми". Сколько не вызывай, всегда возвращает одно и тоже.
Здравствуйте, можно объяснение для не ведующих, относительно фразы: значения возвращаемые millis() не изменяются. ... ?
Дело в том, что внутренние часы (точнее счетчик, сделанный кратным микросекундам) обновляются по прерыванию внутреннего таймера, а при входе в обработчик прерывания, все остальные прерывания преостанавливаются и возобновляются только после выхода из текущего обработчика (в один момент времени обрабатывается только одно прерывание). Соответственно, без какого-либо воздействия на обработку прерываний внутри обработчика, многократный вызов функций millis() и micros() будет возвращать одно и тоже значение. То есть, если появится желание измерить время работы кода внутри обработчика прерывания (читаем время в начале, читаем время в конце - разность значений и есть время), то результат будет "0", так как внутри обработчика не вызываются другие обработчики, в частности прерывания по таймеру. Здесь как раз и полезно вызвать разрешение прерываний sei() или interrupts() перед последним (в конце кода) вызовом функции millis() или micros().
Это просто грамотная привычка - не расширять область видимости без необходимости.
Если я правильно понял из описания volatile:
Переменная должна быть объявлена volatile, когда её значение может быть изменено чем-либо за пределами того участка программы, где она объявлена, например, параллельно выполняющимся процессом. В Arduino единственным местом, где это может проявиться, является участок программы, ассоциированным с прерываниями, вызванный программой обработки прерываний. См. AttachInterrupt()
это было сделано сугубо для прерываний. Не влияет ли значение static на компилятор, заставляя его сохранять переменную в регистр, а не в ОЗУ? Тогда, по идее, внутри обработчика она может не обновляться. На мой взгляд, нет необходимости использовать static там, где он неприменим.
Ну, вот Вы про volatile прочитали. А теперь прочитайте ещё что означает static для глобальной переменной, а уж потом будете рассуждать где он применим, а где - нет.
Это приведет к разрешению обработки прерываний, стоящих в очереди - таймер там уже есть, просто еще не выполнялся.
Это приведет к разрешению обработки прерываний, стоящих в очереди - таймер там уже есть, просто еще не выполнялся.
Да? Ну, если Вы в это верите, то делайте :))))
Это приведет к разрешению обработки прерываний, стоящих в очереди - таймер там уже есть, просто еще не выполнялся.
Вы знаете, что Совецкий союз развалился, когда правительство начало экспериментировать с очередями и разрешениями? Так что давайте, не тово... А то все ваши ардуины распадутся на транзисторы и шины данных
Это приведет к разрешению обработки прерываний, стоящих в очереди - таймер там уже есть, просто еще не выполнялся.
Да? Ну, если Вы в это верите, то делайте :))))
А вы, я смотрю, скептически относитесь к способностям Котов Шрёдингера. xD
Ну и результат, соответственно:
Timer successfully updated (56)
Timer successfully updated (56)
Timer successfully updated (56)
Timer successfully updated (56)
Timer successfully updated (52)
Timer successfully updated (56)
Timer successfully updated (56)
Это приведет к разрешению обработки прерываний, стоящих в очереди - таймер там уже есть, просто еще не выполнялся.
Вы знаете, что Совецкий союз развалился, когда правительство начало экспериментировать с очередями и разрешениями? Так что давайте, не тово... А то все ваши ардуины распадутся на транзисторы и шины данных
В данном конкретном случае: гонка вооружений - занятие достаточно веселое. ;-)
Насчёт котов не знаю, а вот насчёт очереди ... и каков же её размер? Сколько прерываний могут одновременно ожидать?
А вот результат, если убрать первое разрешение interrupts():
Timer successfully updated (56)
Timer successfully updated (60)
Timer successfully updated (60)
Timer successfully updated (64)
Несколько микросекунд уходит на вход в обработчик.
Насчёт котов не знаю, а вот насчёт очереди ... и каков же её размер? Сколько прерываний могут одновременно ожидать?
К сожалению мне лень искать, посмотрите здесь, раздел 14 описывает непосредственно прерывания: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2549-8-bit-AVR-Mic...
Ожидать могут все, а вот как только разрешение поднять, то будет выполнена самая приорететная. При этом , цитата, The user software can write logic one to the I-bit to enable nested interrupts. All enabled interrupts can then interrupt the current interrupt routine. Что будет дальше даже боюсь предположить, потому что, цитата, The I-bit is automatically set when a Return from Interrupt instruction – RETI – is executed. И получается, к процедуре прерывания , в которой принудительно разрешили прерывания будет завершена только после выполнения всех прерываний стоящих в очереди.
Да, это как в закрытый супермаркет придти, через служебный вход, набрать товара, встать на кассу и в час пик открыть магазин, а потом пропустить всю очередь за тобой, чтобы посмотреть кто, что купил. Само собой, льготники пойдут первыми. xD
Данный механизм создан исключительно для тех случаев, когда это крайне необходимо. Гараздо сложнее бывает там, где такой механизм в принципе не реализован, а других вариантов для решения уже не осталось.
Код работает:
Строки SIGNAL_PIN - 2 это прикол такой?
Да, чисто поржать. А если серьезно, то я в то время особо не ведал, что творю, потому что только только начинал в этом всем разбираться и это надо было сделать в довольно сжатые сроки. С помощью участников форума был написан какой-то код, который дал какой-то результат. Сейчас я не связываюсь непосредственно с ардуино и копаться в том, что там было особо желания нет.
Строки SIGNAL_PIN - 2 это прикол такой?
Типа да, а что - не прикольно? Вам больше нравится макрос digitalPinToInterrupt?