micros()
- Войдите на сайт для отправки комментариев
Сб, 09/06/2012 - 20:05
в аглицком не силён, а в переведённом варианте функция описана слабо.
а вопрос вот в чём:
//переменные unsigned long t=0; unsigned long t_interval=0; void setup() { // установки } void loop() { unsigned long t =micros(); f1(t); f2(t); // и т.д. набор функций } void f1(unsigned long t1) { if (t1-t_interval>1000) {t_interval=t1; } //исполнять каждые 1000 мкс } void f2(unsigned long t2) { if (t2 % 2000==0) { } //исполнять каждые 2000 мкс }
почему f1() будет работать почти корректно, а f2() нет? при разбирательстве вышло что f1() срабатывает не на 0, 1004, 2008... мкс, а на 1004+n, 2008+ещё и т.д. а вариант f2() в качестве мигалки диодом вообще генератор случайных чисел.. хотя по логике если интервал повторения кратен 4 мкс, должно работать.. заменил на функцию millis(), аналогично.
очень хотелось организовать срабатывание разных функций на разные интервалы (от нескольких минут, до милисекунд) без введения дополнительных переменных... и чтобы всё это работало параллельно.
Первое: Определитесь что вам нужно, все-таки миллисекунды или микросекунды?
Второе: Крайне плохая идея давать глобальной и локальной переменные одинаковые имена (строчки 01 и 10) - мозги вывихните где какая используется (похоже первая сейчас нигде не используется, сугубо что-бы было сложней понять скетч).
Третье: обозвать переменную, в которой фактически хранится время последней сработки условия, t_interval это тоже "что-бы враги не догадались"? Imho что-то типа lastActionTime было-бы более "говорящим именем". Кстати переменные t1,t2 тоже можно обозвать понятней, например currentTime (так как обе - локальные, то использовать для них однаковое имя - нормально, тем более что суть у них одна).
Четвертое: строка 22 у вас будет срабатывать "при большом везении". Что вы в ней проверяете? То что текущие время В ТОЧНОСТИ кратно 2000. Микросекунда туда, микросекунда сюда - и все. Условие не сработает. Что-бы эту функция работала верно, нужно что-бы 10-тая строка вызывалась гарантированно каждую микросекунду . А это - нереально. Возможно на пустом скетче и получится, но в реальном, где loop будет делать что-то полезное - облом. Быстродействия не хватит. Если же у вас есть какая-то логика, и loop может где-то "задержатся" - все. Точного совпадения - не будет.
Пятое: вообщем крутясь в loop и проверяем текущие время вы всегда как-бы чуть-чуть "проскакиваете" мимо точного момента (это и есть вот эта ваше +n). Это примерно как чем-то заниматесь и поглядываете на часы (время от времени), естественно "точно в момент" вы не попадаете никогда. Всег-да чуток "о уже время прошло пару микросекунд назад". Если же вам важно начать действие "точно как только возможно" - смотрите в строну библиотеки Timer (или читайте даташит, как использовать аппаратный таймер). В этом случае слежение за временем идет "аппаратно". И когда "настало время", скетч приостанавливается, чем бы он не занимался, и запускается ваше действие.
> в переведённом варианте функция описана слабо
Вообщем то перевод соответсвует оригиналу. Даже не зная английсого это можно увидеть не вооруженным глазом. Объем совпадает :)
называю переменные так как мне удобнее, объявление локальной и глобальной переменной, в оригинале она только глобальная, это тут уже при перепечатке упрощённого образца кода ашипся..
какая нужна будет скорость работы я ещё не знаю, потому ориентируюсь на самую быструю (а уж из ней медленную сделать легко)
по задачам будет передача 4 бит на DTMF кодер, и приём 4х бит с DTMF декодера соответственно. плюс заведомо низкоскоростные задачи типа контроль заряда аккумулятора и т.п...
про таймер работы в общем понял, буду думать как и чем лучше пользоваться.
спасибо.
какая нужна будет скорость работы я ещё не знаю, потому ориентируюсь на самую быструю (а уж из ней медленную сделать легко)
А вот с этим следовало бы еще до начала всех ваших брыканий определиться.
Если эта "скорость работы" соответствует частоте опросов в районе мегагерца (те самые микросекунды), то вам элементарно не хватит быстродействия AVR (даже если вы созреете до использования таймеров) и надо искать что-нибудь вроде STM32xxx c тактовой частотой 72 МГц, а то и какую-нибудь 400-мегагерцовую Самсунгу...
Ну или модель соответствующим образом корректировать, чтобы снизить потребности в скоростях до разумного (перевариваемого используемыми в Ардуинах микроконтроллерами) уровня...
DTMF относится к звуковым сигналам... потому какие там могут быть мегагерци? Если бы декодер был софтовый, ещё может быть.. таки разложение сигнала на спектр это много считать.. но мои познания во всяких там преобразованиях Фурье, Лапласа и т.п.. в общем не осилю. потому декодер аппаратный.
скорость может потребоваться для выявления и обработки ошибок.
DTMF относится к звуковым сигналам... потому какие там могут быть мегагерци?
Ух ты! А мужики то не знают...
Так зачем вам микросекунды?
стёб начался
Конечно.... вам же сказали что микросекунды нужны при частоте опроса в мегагерцы. Вы тут же заявляете что "ну очевидно же что мегагерцы не нужны", тогда опять возвращаемся к "а зачем микросекунды тогда?".
Итого: решите, все-таки, что вам нужно микросекунды или милисекунды?
"А пусть будет про запас" - не пойдет. Разные порядок точности подразумевает совершенно разные порядок проблем, гимороев и способов решения задачи. Это все равно что начать строить супер-точные весы, которые могут взвесить пару молекул (а уж из нех не точные сделать легко), а потом обнаружить что нужно взвешивать груженные камазы.
>называю переменные так как мне удобнее
Ах, ну простите. Это конечно сильный довод. Обычно подобный стиль называется "быдло-код". На работе за такое бьют по руками, и увольняют в случае упроства. Если вы пишите только сами для себя - обзывайте переменные как хотите, хоть именами своих любовниц (и то, не уверен что через год,посмотрев свой скетч, вы сразу поймете что он делает). Но если предполагается что его будут смотреть другие - нужно старатся облегчить им понимание. Не называть переменные которые хранят момент времени "интервал". Это не значит что нужно срочно все бросить и переименовывать точно как я предложил (на вкус и цвет - фломастеры разны). Но прислушатся что другие говорят "ваш код трудно понимаем" - стоило, а не занимать позицию "а мне плевать, я гений". Если вы так классно знаете как нужно писать - помогайте другим. Чего вопросы задаете?
Быдло-код все мы пишем, время от времени, куда ж от этого деться, у всех стиль не идеален. Но при таком подходе к замечаниям... что-ж думаю вы уже поняли в какую категорию вы себя определили, по крайней мере в моих глазах. И сами догадаетесь можете ли расчитывать, по крайней мере от меня, на что-то иное кроме стеба.
и гением назвали и быдло-кодером... хотя про любовниц эт чрезмерно, небыло такого. считаете код, стиль написания или вопрос столь возмутительным, что фломастеры из рук выпадают - не отвечайте. а правописаниен на публику и научным обоснованием: почему именно этим микроскопом нужно гвозди забивать, займусь позже, когда раскраски закончатся.
да и делать все эти личностные выводы на основании нескольких фраз - довольно по фрейдовски. не хотите извиниться?
> не хотите извиниться?
Да запросто. Причем искрене. Цели обидеть - не ставил.
Тем более если вы внимательно прочитаете мое сообщение - увидите. От оценки вас, как личности, я воздержался. Оставил вам самому догадатся.
"Быдло-код" - не оценка автора (опять-таки я упомянул что все его пишут), а устоявшийся термин характеризующий качество написанного кода.
Гением - тоже не обзывал, назвать человека гений и "занял позицию" - разные вещи.
Замечания к коду - не что-бы вас лишний раз носом ткнуть, а указать на более приемлемый стиль. Тем более если вы хотите что-бы другие понимали ваши скетчи. Сами-то вы "в контексте", писали его пару минут назад, а посторонним человеком он будет восприниматся совсем по другому. Многие сами просят "покритикуйте".
Возможно моя реакция была излишне цветасто-эмоциональна. Еще раз простите. Но вызвана она была не кодом, а ответом, который я воспринял как "это ваши личные трудности". Лучше бы, даже, просто проигнорировали замечание.
Хотите писать код трудный для восприятия другими - пишите. Безусловно это ваше право. Так что еще раз, простите, что побеспокоил и потратил ваше время.
При построении такого типа задач действительно очень важно определить граничные условия и никогда не пользоваться принципом "запас карман не тянет", потому что ресурсы контроллера - штука сильно ограниченная, где-то сделаете запас - потом не хватит на что-то другое, очень нужное. Перекапывать всю программу - очень грустно.
1. Определитесь с минимальным квантом времени. Иначе говоря, максимальный интервал времени, который можно умножить на целое число и получить все, нужные Вам интервалы. Не стоит брать его меньше 1 миллисекунды, обычно 10 мс (частота срабатывания 100 раз в секунду) вполне достаточно.
2. Организуйте счетчик интервалов и в цикле при вызове функций уже можете пользоваться проверкой деления нацело.
3. Приращение счетчика лучше поручить прерыванию по таймеру, но если не хотите связываться с таймерами (хотя опыт очень полезный, да и сделать нужно будет всего 1 раз), то возмите 1 мс, но пользуйтесь первым вариантом Вашей функции. Только в переменной лучше хранить не время последнего срабатывания, а время следующего срабатывания (будет быстрее работать проверка) и прибавлять каждый раз интервал, а с текущим временем только сравнивать.