" title="Написать письмо">Написать письмо

Статистика

Пользователи : 1
Статьи : 1969
Просмотры материалов : 7192642
 
Таймер Arduino 1437.5нс (07.02.2023). Печать E-mail
2023 - Февраль
07.02.2023 17:25
Save & Share
Предыдущая попытка создать высокочастотный таймер Arduino с периодом 10мкс закончилась провально. Сейчас же получилось реализовать таймер с периодом 62.5нс и погрешностью +1437.5нс - что позволяет создать часы реального времени без покупки отдельного аппаратного модуля (погрешность составит +45.333с/год). Получилось лишь условно: погрешность составляет 1ч/2мес - но при этом время всегда находится в этом диапазоне - не позволяя ему смещаться, например, изо дня в ночь.


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

Arduino имеет несколько таймеров - акцент сделан на TIMER2, т.к. для него корректно отключается предделитель (понижатель частоты). TIMER2 является 8-битным - обнуляется каждые 256 тиков. В связи с этим, был создан счетчик таких обнулений. Соответственно, формула общего числа тиков - умноженное на 256 число обнулений, сложенное со счетчиком таймера TCNT2. Смещение на 8 битов вправо не работает - поэтому используется именно умножение.

Далее, при попытке выйти на период 1с, эмпирически выяснилось: таймер с отключенным предделителем становится счетчиком тиков процессора - определен период работы 62.5нс. Однако сама регистрация количества тиков занимает много времени при выполнении. И именно с этого момента начинается главное: адаптация этого таймера под конкретную задачу или умение писать быстрый код - и из этого определится его погрешность.

Например, из полученного примера можно исключить unsigned long int в пользу более быстрого unsigned int, если количество тиков не превысит 65535. Или эмпирически вычисляется, что перетипирование TCNT2 в unsigned long int обходится в 2 процессорных тика - и ну его нафик.

В моем случае, исходный код в системе защиты от протечек выполняется ~70мс - необходимо реализовать задержку ~30мс с высокой точностью. Итого, на ровно 100мс потребует 1.600.000 тиков - годится только unsigned long int.

Строка "while (g_uliTIMER2_OVF*256 + TCNT2 < F_CPU) {}" выполняется 23 тика - погрешность таймера при такой реализации составляет +1437.5нс, в 23 раз больше периода. Переменные uliBegin и uliEnd именно volatile: замедляют работу - но считают точно (если убрать volatile от g_uliTIMER2_OVF - цикл 1с вообще перестает работать).

При макетировании еще раз подтвердилось, что delay и delayMicroseconds непостоянны в своих задержках, даже при одном и том же входном параметре. Здесь же, при одинаковом исходном коде без delay, - всегда реализуется одинаковое количество тиков.

(добавлено 08.02.2023) Никто не мешает в формуле сравнения из 1.600.000 тиков вычесть 23...

(добавлено 09.02.2022) Никто не мешает вычесть в формуле большую половину тиков - превратив погрешность в ±12 тиков, ±750нс.

(добавлено 19.02.2022) Так и сделал, обновив исходники.

(добавлено 05.12.2023) К сожалению, долговременное тестирование системы защиты от протечек показало: погрешность составляет -26мин за 2мес и еще -31мин за 2мес (прошло 2 длительных цикла). Причины - неизвестны. Сюда включены вероятные задержки посыла SMS оператором и разница во времени посыла SMS самим модулем Arduino - но все равно очень много. Мало того, погрешность еще и колбасит.

Для первого случая получается погрешность -30093нс/цикл, для второго -35880нс/цикл. "Никто не мешает вычесть в формуле" - похоже, довычитался... -12 тиков стоит в формуле (g_uliTicks_Needed = F_CPU/10 - 12) - похоже, это лишнее. Возможно, перепрограммирую исходники, залью - и через 4-6мес отпишу сюда еще раз.

(добавлено 27.02.2024) Ещё хлеще. Повторный тест - +50мин в месяц. Именно в момент внедрения в исходный код проекта исходного кода таймера что-то пошло не так. Возможно, хаотичность выбора "в плюс или в минус" в момент включения Arduino возникает.

(добавлено 12.05.2024) Последив за поведением исходников, пришёл к выводу, что не всё так плохо. Если вместо них использовать стандартный delay - время всё время будет или расти, или вычитаться, - в зависимости от числа в скобках функции, порождающего погрешность. А с этими исходниками - время скачет и в минус, и в плюс. Но при этом, поведение исходников за 2мес ничем не отличается от исходников во время тестирования с меньшим периодом. То есть, время всё время скачет то в минус, то в плюс, - но оставаясь при этом в каком-то конкретном временном интервале.

Если функция delay копит погрешность, и она становится всё больше и больше, - то эти исходники никогда не превысят погрешности в 1ч, сохранив правильную точку отсчета времени. А это означает, что диагностическая SMS, отправляемая защитой от протечек, куда внедрены данные исходники, - всегда будет приходить днём, а не смещаться всё ближе к ночи, - лишь с интервалом [-1;1]ч.
Обновлено ( 12.05.2024 12:11 )
 
 

Последние новости


©2008-2024. All Rights Reserved. Разработчик - " title="Сергей Белов">Сергей Белов. Материалы сайта предоставляются по принципу "как есть". Автор не несет никакой ответственности и не гарантирует отсутствие неправильных сведений и ошибок. Вся ответственность за использование материалов лежит полностью на читателях. Размещение материалов данного сайта на иных сайтах запрещено без указания активной ссылки на данный сайт-первоисточник (ГК РФ: ст.1259 п.1 + ст.1274 п.1-3).

Много статей не имеет срока устаревания. Есть смысл смотреть и 2011, и даже 2008 год. Политика сайта: написать статью, а потом обновлять ее много лет.
Открыта карта ВТБ для донатов на дорогостоящие эксперименты: 5368 2902 0040 0838.

Рекламодателям! Перестаньте спамить мне на почту с предложениями о размещении рекламы на этом сайте. Я никогда спамером/рекламщиком не был и не буду!
Top.Mail.Ru