Хочу использовать функцию millis() для синхронизации времени через заданный интервал. К самой синхронизации вопросов нет. Использую GPRS-шилд и регулярно снимаю с него время командой AT+CCLK?. Все работает, как надо, но... Боюсь, проблемы, с которыми я столкнулся, когда попытался сделать ежечасовую синхронизацию с помощью отсчета прошедшего количества миллисекунд, выходят за пределы моих скромных познаний в электронике. Если кратко, то в одной секунде не 1000 миллисекунд, а чуть больше 1002. Я бы хотел попросить вас подсказать мне максимально точное число, основанное на характеристиках контроллера Arduino Uno или на тонкостях функционирования программ. Подробнее. Если я использую каноничные значения, то Ардуино производит синхронизацию времени несколько раньше, чем нужно. Путем приблизительных расчетов сделал вывод, что погрешность составляет примерно 125 миллисекунд на минуту или секунда в 8 минут. Соответственно на уровне часа отставание уже больше (примерно 7 секунд). Хотя код способен самоподстраиваться и в целом погрешность не будет выходить за пределы часа, хотелось бы заставить Ардуино более точно отсчитывать время. Про код. На этапе setup я провожу первичную синхронизацию времени вышеназванной командой, вывод которой переводится в int формат и вставляется в формулу определения времени, прошедшего с начала часа: Код (Text): synchTime = (unsigned long) ((m[0]-'0')*10+m[1]-'0')*60*1000+((s[0]-'0')*10+s[1]-'0')*1000; Затем высчитывается, сколько осталось времени до конца часа: Код (Text): synchPeriod += 3600000UL-synchTime; // += Потому что ранее в теряется секунда на delay и она там же компенсируется // увеличением значения synchPeriod на 1000 И полученное значение используется в условии: Код (Text): if (currMillis - synchMillis >= synchPeriod){ synchMillis = currMillis; // Здесь повторяется код для синхронизации, но только synchPeriod // задается уже конктретно 3600000, а не прибавлением. // Потерянная секунда почему-то перестает играть роль } К функционированию кода претензий нет. Они есть к моменту срабатывания условия.
на счет 1002 милисекунды. единица измерения 1 секунда = 1000мс. А в ардуино эта частота я так понимаю задается кварцем на 16mhz, у этих кварцевых резонаторов есть своя погрешность, вот эта погрешность и дает о себе знать
А поточнее определить эту погрешность можно? Гуглил, но ничего понятного не нашел. Кстати, у меня там выше в коде ляп: перевод символа в int неправильно работал из-за кривого задания unsigned long. Исправился.
я не уверен но я так понимаю что эта погрешность в каждом резонаторе своя. у кого то быстрее на доли мегагерц у кого то медленее и в итоге у одного 1 секунда (реального времени) = 998мс, а у кого то 1002.
У кварцев настройка точнее, так не должно быть. Там типичные значения погрешности 10^-6 ~ 10^-9. т.е. за одну секунду они могут уйти максимум на такт, но никак не на несколько миллисекунд, это же не керамические резонаторы с точностью 10^-3 и тем более не 5% конденсаторы.
В реальности погрешность частоты может определяться емкостью в цепи резонатора. А это может быть в итоге и больше 5% конденсатора.