Closed svpcom closed 2 years ago
Список изменений:
Воу, спасибо! Кажется я понял, почему так не делал - сложный код на ум приходил. Есть идеи, как его протестировать? Может на С++ написать программу, которая на вход array из 01011 получает и смотреть, выдаст ли цикл импульс?
Придумал сейчас еще алгоритм:
mask = [1, 1, 0, 0, 0] cur = 0
if close && mask[cur] || open && !mask[cur]: cur++; else: cur = 0;
return cur == len(mask)
Ну тогда можно еще проще:
static uint8_t state_history = 0;
на каждом шаге:
state_history = (state_history << 1) & 31;
state_history |= (int)is_closed;
if (state_history == 24) // b11000
{
// new impulse found;
}
@dontsovcmc Я поправил pull-request с использованием битовых операций
Класс! Кажется это называется изящным решением. А можешь протестировать свои счетчики с ним?
хорошо
Версия с битовой маской не распознает такой случай: "1111111110101000000000" (то есть дребезг контактов) Я откатил обратно в версию со счетчиком.
Дополнительные исправления:
В такой кофигурации лишние импульсы не появляются. Как были получены эти константы:
К сожалению больше ничего добавить не получится, так как для attiny45 (в моем случае) остается 22 байта свободного места.
Ух, спасибо за тест и рассчет! Одно «но»: 111111010100000 - это не дребезг, это бракованный счетчик. Поясню: дребезг это когда геркон замыкается (при размыкании он меньше если вообще есть) и длится ~5мс. У нас опрос каждые 250мс, поэтому никакого дребезга там не встретится. А ты не пробовал обычный светодиод с батарейкой подключить к счетчику и посмотреть корректно ли он замыкается? Удобно на замедленное видео записать.
нет, не пробовал. Тут проблема в том, что лишние показания набегают в случайный момент времени. При ручном тестировании у меня не удавалось такой момент поймать. Но судя по тому, что помогло сильное увеличение TRIES_OPEN, то проблема с дребезгом есть, причем на обоих счетчиках. У меня есть подозрение, что это происходит на очень слабор расходе воды, так как на сильном (при тестировании) я еще ни разу этой проблемы не встречал.
@svpcom на дребезг не должен влиять расход воды, потому что шестеренки в одну сторону вращаются и магнит слишком быстро замыкает контакты =(. я допускаю, что с TRIES_OPEN лучше работает, но это может говорить что где-то замыкание рядом с основным замыканием. Всё же лучше проверить светодиодом счетчик. Крайне желательно через резистор 150-1000 ом. Можешь использовать сам ватериус для этого: вынь крайнюю батарейку где черный провод. подключи счетчик к LOG около светодиода и к минусу 2й батарейки. При замыкании светодиод загорится.
Я провел измерения в режиме "сухой контакт". Питание 3v через резистор 47кОм (эквивалент встроенной подтяжки attiny). Напряжение на контактах геркона:
начало импульса:
конец импульса:
В режиме namur осцилограф показывает очень много шума, так как подтяжка очень слабая (47k vs 10k резистора намура). https://www.lcard.ru/lexicon/namur Мне кажется, что нужно уходить от встроенной подтяжки и использовать одну из ног attiny в push-pull режиме и резисторы сильно меньшего номинала. А также сделать явное переключение namur/сухой контакт. Так как сейчас даже при подключении счетчика как сухого контакта шум может восприниматься как уровни намура.
@svpcom Вау! Спасибо за исследование. Встроенная подтяжка где-то 20 кОм (см комментарий в коде относительно цифр компаратора относительно 1024 = 3В).
Очень странные импульсы. Но даже с такой картиной мой софтовый дребезг теоретически должен справляться =(... Я в замешательстве.
Кстати, а какой у вас период отправки был указан? Потому что 65мс периода в момент пробуждения это не 250мс... Если раз в сутки, то вряд ли, но если чаще, то я готов поставить на то, что в этом может быть причина.
Период опроса - 250мс. Пробуждение для отправки - раз в сутки. Судя по логам mqtt почти ровно 26 часов. Похоже частота встроеного rc-генератора неправильно стоит или уходит с температурой.
Резистор там может было от 20 до 50 кОм.
В большинстве случаев импульсы считаются старым кодом правильно, то есть вероятность появления плохого сигнала довольно мала (несколко процентов) и поймать я на осцилографе его естественно не смог.
Помимо дребезга, на механике довольно часто присутствует "обратный поток", и если на ПУ отсутствует обратный клапан, лишние импульсы гарантированы.
Обратного клапана действительно нет. Но с моим фиксом стало считать все правильно.
@dubanoze ого, отличная информация, спасибо! Мне сантехник сказал "не надо его ставить, а то засоряются". Я вспоминаю ,что мне рассказывали кейсы, когда счетчик при определенных проблемах в водопроводе крутился назад. Хм, что теперь делать приписку "использовать только при установленных обратных клапанах" =(
@svpcom Я ничего не имею против 500ms + 6s, но меня смущают правки в таком ответственном месте и пугает объём кода при наличии высокой погрешности только вас =(.
"от 20 до 50 кОм." оокей... код прожуёт.
Возможно другие просто не замечают погрешность (данные раз сутки передаются и если погрешность меньше суточного расхода, то она будет незаметна). Большинство людей смотрит только целую часть (м^3), а литры игнорируют.
@svpcom Добрый день! С прошедшими праздниками! Расскажите, точно ли теперь у вас считает и с каким кодом? Обнаружился некорректный подсчёт у 1л/имп счетчика, при потреблении до кубометра в день - гипотеза, пропускаются импульсы.
@dontsovcmc Добрый день! Считает теперь точно - за два месяца погрешность +3 импульса у ГВС и +2 импульса у ХВС. То есть относительная погрешность ~ 0.1% - 0.2%. Код: https://github.com/svpcom/waterius/tree/pull-request
Из пожеланий я бы еще исправил детекцию замыкания отдельно для намур и для сухих контактов. Так как сейчас даже в режиме сухого контакта счетчик может считать шум принимая его за уровни намура. Но если это делать через приложение, то оно уже не влезает в attiny45 (то есть тип счетчика придется задавать на этапе компиляции прошивки).
@svpcom у вас на графиках time=100ms - это 1 клетка или весь экран?
@dontsovcmc 100ms одна клетка
@svpcom о! это любопытно, потому что у вас не "дребезг" контактов, который бывает 5мс ну 10мс... У вас что-то странное...
When reading inputs with impedance > 10k some additional delay is needed to allow ADC to charge its internal capacitors. See for reference: https://github.com/arduino/Arduino/issues/5646