Задачка для новичков
- Войдите на сайт для отправки комментариев
Задача родилась из занятий с ребёнком.
Собственно задача простая. Требуется, чтобы некая функция исполнялась с заданной частотой (для определённости, скажем – 40Гц). Функция может делать что угодно, например, для определённости, пусть инвертирует светодиод на 13-ом пине (получится 20-тигерцный «блинк»).
Работа не должна зависеть от задержек (delay() или долгих вычислений) в основном цикле программы. Т.е. вот такая программа должна нормально работать:
// // Светодиод мигает с частотой 20Гц // void ledInvert(void) { digitalWrite(LED_BUILTIN, ! digitalRead(LED_BUILTIN)); } void setup(void) { // здесь что-то делаем } void loop(void) { while(true); }
При этом нельзя пользоваться сторонними библиотеками (типа TimerOne и т.п.) и нельзя напрямую работать с регистрами МК (например, нельзя вручную конфигурировать таймеры). Всё должно быть в рамках wiring, т.е. средствами, описанными в общем руководстве.
Попробуйте – проверьте свои знания! Удачи!
Ах, ну, да, основной цикл (loop()) должен выполняться, не надо писать обычный блинк с делэями в цикле в setup - это читерство.
По "общим руководством" подразумевается вот эта страница - http://arduino.ru/Reference
Просто уточняю из любопытства: допускается ли стреноживание ардуины?
И все?))
И все?))
Ну, можно и так :)
Ну, можно и так :)
то есть это не было тем решением, которое вы держали в уме, задавая вопрос? :)
С помощью millis? Как то так?
и при вызове можно задавать длительность! То есть например для 40 герц нужно прописать там 25? Верно?
и при вызове можно задавать длительность! То есть например для 40 герц нужно прописать там 25? Верно?
Ну, можно и так :)
то есть это не было тем решением, которое вы держали в уме, задавая вопрос? :)
Мой ХР подсказывает, что под решением подразумевалось сцепить с меандром на таймере )))
Вот мой вариант скетча
Оцените пожалуйста!
Вот мой вариант скетча
Так не выполнено условие
Работа не должна зависеть от задержек (delay() или долгих вычислений) в основном цикле программы.
Стоит поставить в loop какой-нибудь делэй и всё поломается.
Евгений Петрович! А на чём еще, кроме tone() можно паразитировать? (средствами wiring)
AnalogWrite еще годится, но хуже.
AnalogWrite еще годится, но хуже.
так там частота вроде 50 герц - фиксированная
490Гц.
Так делитель использовать никто не запрещал. Нельзя задержки. Вот тоже самое на нем. Из-за не удобной частоты шима частота будем примерно равно заданой.
6 и 7 строки не понимаю, как работает этот делитель?
6 и 7 строки не понимаю, как работает этот делитель?
Коэффициент деления задается в строке 6, а в стороке 7 происходит декремент и на каждом обнулении - реакция + восстановление значения счетчика.
6 и 7 строки не понимаю, как работает этот делитель?
Коэффициент деления задается в строке 6, а в стороке 7 происходит декремент и на каждом обнулении - реакция + восстановление значения счетчика.
почитал про static, теперь понятно, красиво, компактно, но не работает, ашипки, а вот так будет )))
Сами-то проверяли? Неужели работает? Боюсь, что нет :)
Сами-то проверяли? Неужели работает? Боюсь, что нет :)
Мастерство не пропьёшь )))
ЗЫ(я об умении беглым взглядом находить ошибки)
Так по памяти правил)) Как уже правильно показали на INT1 работать будет.
Вот мой вариант скетча
Так не выполнено условие
Работа не должна зависеть от задержек (delay() или долгих вычислений) в основном цикле программы.
Стоит поставить в loop какой-нибудь делэй и всё поломается.
Если интервал не прошел, то происходит мгновенный выход из функции. Верно?
И ещё я не совсем понял несколько строчек в скетче
Вот эту функцию
Со строкой if(!i--)
Как это по русски? Если переменная i не равна??? Знак "!" значит не равно? То есть, если бы значка не было, там могло бы быть что угодно кроме нуля и условие бы выполнялось! Также как while(1). А так получается, что должно быть наоборот, то есть для срабатывания условия там должен быть 0 (ноль)? Верно? То есть можно написать эту строку так:
Я прав?
490 примерная частота шим по умолчанию. Она делиться на 40. Получается примерно 12 . Остаток ведь отбрасывается. А в переменную типа int попадает число 12.
Получается, что каждый раз оно всё уменьшается и уменьшается на 1 за каждым проходом цикла. И вот когда станет 0 (ноль) состояние светодиода изменяется
а в переменную i опять попадает 12. Верно?
Вызов функции происходит по прерыванию 1
Параметр там указан RISING то есть по изменению уровня с низкого на высокий.
В следующей строке
стоит число 0x80 или 128. Это значит, что скважность шим будет примерно 50%? Верно?
Функция ledInvert будет вызываться примерно 490 раз в секунду и проверять сработало ли условие, это что-то типа собственного таймера?
Скорее всего эти конструкции равнозначны, так как при компиляции длина кода одинаковая
Скорее всего эти конструкции равнозначны, так как при компиляции длина кода одинаковая
Насколько я помню - не то, что неравнозначны, но и противоположны.
Идентичны. Сначала i уменьшается на 1, а затем проверяется на равенство 0.
Если мне не изменяет память, то у Архата помнится такое решалось примерно так (проверять сейчас не на чем):
А вообще-то у него была полноценная библиотека для конечных автоматов, которой достаточно долго пользовался с успехом.
Идентичны. Сначала i уменьшается на 1, а затем проверяется на равенство 0.
Тогда что делает --i ?
Если мне не изменяет память, то у Архата помнится такое решалось примерно так (проверять сейчас не на чем):
Это не будет работать в коде из условия задачи.
Идентичны. Сначала i уменьшается на 1, а затем проверяется на равенство 0.
Тогда что делает --i ?
Это то, о чём я подумал (предусловие/постусловие?)
Идентичны. Сначала i уменьшается на 1, а затем проверяется на равенство 0.
Тогда что делает --i ?
Это то, о чём я подумал (предусловие/постусловие?)
условие не бувает ни пред ни пост. декремент бывает
Идентичны. Сначала i уменьшается на 1, а затем проверяется на равенство 0.
Тогда что делает --i ?
Это то, о чём я подумал (предусловие/постусловие?)
условие не бувает ни пред ни пост. декремент бывает
это я так выразился ))) то-есть если --i сначала декремент, затем проверка, а если i-- то сначала проверка на условие затем декремент?
это я так выразился ))) то-есть если --i сначала декремент, затем проверка, а если i-- то сначала проверка на условие затем декремент?
Да
это я так выразился ))) то-есть если --i сначала декремент, затем проверка, а если i-- то сначала проверка на условие затем декремент?
Да
а как это проверить?
Сам догадался -
4 3
3 2
2 1
1 0
0 -1 490
490 489
489 488
Если мне не изменяет память, то у Архата помнится такое решалось примерно так (проверять сейчас не на чем):
Это не будет работать в коде из условия задачи.
поясните "почему не будет работать"?
Если мне не изменяет память, то у Архата помнится такое решалось примерно так (проверять сейчас не на чем):
Это не будет работать в коде из условия задачи.
поясните "почему не будет работать"?
Вставьте после вызова вашей функции любой блокирующий while() или тот же delay(1000) и на этом 20 герц закончатся
Ну .. так не интересно .. таймеры не трогать (виринг их конфигурять не умеет) .. ну, как тут уже предложено - повесьте на прерывание, а вход прерывания подключите к выходу PWM, канал которого "по умолчанию" настроен на 490гц и считайте в прерывании сколько натикало. Да, не забудьте analogWrite() в сетап со скважностью 50%, а то считать придется каждый раз по-своему..
Одно нипонятно: ЗАЧЕМ отжирать целое прерывание и аж ДВЕ ноги микроконтроллера плюсом ШИМ-канал для такой ерунды? Чесать левой пяткой правое ухо разве что.. ;)
.. и ещё нипанятно: а если надо не 20Гц а 1кГц .. что делать? :)
Да потому что задачка на сообразительность, а не на универсальное применение.
Задачка на сообразительность - тут прямо в соседнем топике: каким способом результат вычитания двух беззнаковых целых внезапно становится знаковым. :)
А о том, ка в одном байте может хранится как uint8_t, так и int8_t, не размышляли?
Задачка на сообразительность - тут прямо в соседнем топике: каким способом результат вычитания двух беззнаковых целых внезапно становится знаковым. :)
А если оно отрицательным стало после вычитания, что с ним делать-то, с беззнаковым?
.. и ещё нипанятно: а если надо не 20Гц а 1кГц .. что делать? :)
Применить первую конструкцию с tone() )))
Задачка на сообразительность - тут прямо в соседнем топике: каким способом результат вычитания двух беззнаковых целых внезапно становится знаковым. :)
оно беззнаковое пока вы перед ним минус не поставили )))
Задачка на сообразительность - тут прямо в соседнем топике: каким способом результат вычитания двух беззнаковых целых внезапно становится знаковым. :)
А если оно отрицательным стало после вычитания, что с ним делать-то, с беззнаковым?
Задачка на сообразительность - тут прямо в соседнем топике: каким способом результат вычитания двух беззнаковых целых внезапно становится знаковым. :)
оно беззнаковое пока вы перед ним минус не поставили )))
Так уже интересней. То есть операции "вычитание" в языке нет и вовсе, несмотря на то что пишут в стандартах, а есть сложение с унарным минусом .. так штоли? :)
Вообще заинтриговали. Что по-вашему будет сложено в таком случае: unsigned long a = - 1UL;
Для человека это вычитание, для машины сложение. И никакого парадокса.
а это называется область входных значений аргумента, их надо обрабатывать до функции )))
Задачка на сообразительность - тут прямо в соседнем топике: каким способом результат вычитания двух беззнаковых целых внезапно становится знаковым. :)
А я Вам там ответил. Нет там никакой сообразительности - есть незнание языка. Архат на этом тоже долго лужу газировал. Могу даже найти эпичный срач, если сильно хотите.
Задачка на сообразительность - тут прямо в соседнем топике: каким способом результат вычитания двух беззнаковых целых внезапно становится знаковым. :)
А я Вам там ответил. Нет там никакой сообразительности - есть незнание языка. Архат на этом тоже долго лужу газировал. Могу даже найти эпичный срач, если сильно хотите.
У всех есть ошибки, КЛАПА тоже вон сколько срача развёл, когда ему указал на логическую ошибку в его часиках на миллис )))
Человеку надо почитать представление чисел в процессоре и вопросы пропадут. Заодно станет понятно в какую тыкву превратится char c=127 после прибавления к нему единицы.
И как лабораторная работа - Запустить этот код и вдумчиво изучить резальтаты)))
У всех есть ошибки
Когда человек ничтоже сумнящеся заявляет, что компилятор кривой, а когда ему показывают, что компилятор полностью соответсвует языку, заявляет, что язык кривой - это уже не ошибка, это клиника.
У всех есть ошибки
Когда человек ничтоже сумнящеся заявляет, что компилятор кривой, а когда ему показывают, что компилятор полностью соответсвует языку, заявляет, что язык кривой - это уже не ошибка, это клиника.
компилятор точно не может быть кривым, уже бы давно вылезло и поправили, тем паче GCC )))
Скорее всего эти конструкции равнозначны, так как при компиляции длина кода одинаковая
Насколько я помню - не то, что неравнозначны, но и противоположны.
или так
То есть нужно ли там else или не обязательно?