dontsovcmc / waterius

Передача показаний воды по Wi-Fi. Watermeter Wi-Fi transmitter.
https://waterius.ru
GNU Lesser General Public License v3.0
564 stars 108 forks source link

Added ADC delay for reliable read of high-impedance inputs. #201

Closed svpcom closed 2 years ago

svpcom commented 2 years ago

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

svpcom commented 2 years ago

Список изменений:

  1. Добавлен дополнительный вызов analogRead, так как сопротивление подтягивающего резистора > 10k. См.: https://github.com/arduino/Arduino/issues/5646
  2. Добавлено ожидание начала импульса. То есть импульс считается начатым, если он длится как минимум один период считывания.
  3. Изменено начальное состояние при включении питания (или при reset от watchdog'а) с CLOSED на OPEN.
dontsovcmc commented 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)

svpcom commented 2 years ago

Ну тогда можно еще проще:

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;
}
svpcom commented 2 years ago

@dontsovcmc Я поправил pull-request с использованием битовых операций

dontsovcmc commented 2 years ago

Класс! Кажется это называется изящным решением. А можешь протестировать свои счетчики с ним?

svpcom commented 2 years ago

хорошо

svpcom commented 2 years ago

Версия с битовой маской не распознает такой случай: "1111111110101000000000" (то есть дребезг контактов) Я откатил обратно в версию со счетчиком.

Дополнительные исправления:

  1. TRIES_CLOSE=2 (500ms), TRIES_OPEN=24 (6s)
  2. В разбуженом состоянии counting() вызывается как обычно: интервал (250ms), а не 65ms

В такой кофигурации лишние импульсы не появляются. Как были получены эти константы:

К сожалению больше ничего добавить не получится, так как для attiny45 (в моем случае) остается 22 байта свободного места.

паспорт VLF-15-1,5

dontsovcmc commented 2 years ago

Ух, спасибо за тест и рассчет! Одно «но»: 111111010100000 - это не дребезг, это бракованный счетчик. Поясню: дребезг это когда геркон замыкается (при размыкании он меньше если вообще есть) и длится ~5мс. У нас опрос каждые 250мс, поэтому никакого дребезга там не встретится. А ты не пробовал обычный светодиод с батарейкой подключить к счетчику и посмотреть корректно ли он замыкается? Удобно на замедленное видео записать.

svpcom commented 2 years ago

нет, не пробовал. Тут проблема в том, что лишние показания набегают в случайный момент времени. При ручном тестировании у меня не удавалось такой момент поймать. Но судя по тому, что помогло сильное увеличение TRIES_OPEN, то проблема с дребезгом есть, причем на обоих счетчиках. У меня есть подозрение, что это происходит на очень слабор расходе воды, так как на сильном (при тестировании) я еще ни разу этой проблемы не встречал.

dontsovcmc commented 2 years ago

@svpcom на дребезг не должен влиять расход воды, потому что шестеренки в одну сторону вращаются и магнит слишком быстро замыкает контакты =(. я допускаю, что с TRIES_OPEN лучше работает, но это может говорить что где-то замыкание рядом с основным замыканием. Всё же лучше проверить светодиодом счетчик. Крайне желательно через резистор 150-1000 ом. Можешь использовать сам ватериус для этого: вынь крайнюю батарейку где черный провод. подключи счетчик к LOG около светодиода и к минусу 2й батарейки. При замыкании светодиод загорится.

svpcom commented 2 years ago

Я провел измерения в режиме "сухой контакт". Питание 3v через резистор 47кОм (эквивалент встроенной подтяжки attiny). Напряжение на контактах геркона:

начало импульса: начало импульса

конец импульса: конец импульса

В режиме namur осцилограф показывает очень много шума, так как подтяжка очень слабая (47k vs 10k резистора намура). https://www.lcard.ru/lexicon/namur Мне кажется, что нужно уходить от встроенной подтяжки и использовать одну из ног attiny в push-pull режиме и резисторы сильно меньшего номинала. А также сделать явное переключение namur/сухой контакт. Так как сейчас даже при подключении счетчика как сухого контакта шум может восприниматься как уровни намура.

dontsovcmc commented 2 years ago

@svpcom Вау! Спасибо за исследование. Встроенная подтяжка где-то 20 кОм (см комментарий в коде относительно цифр компаратора относительно 1024 = 3В).

Очень странные импульсы. Но даже с такой картиной мой софтовый дребезг теоретически должен справляться =(... Я в замешательстве.

Кстати, а какой у вас период отправки был указан? Потому что 65мс периода в момент пробуждения это не 250мс... Если раз в сутки, то вряд ли, но если чаще, то я готов поставить на то, что в этом может быть причина.

svpcom commented 2 years ago

Период опроса - 250мс. Пробуждение для отправки - раз в сутки. Судя по логам mqtt почти ровно 26 часов. Похоже частота встроеного rc-генератора неправильно стоит или уходит с температурой.

Резистор там может было от 20 до 50 кОм. rpu

В большинстве случаев импульсы считаются старым кодом правильно, то есть вероятность появления плохого сигнала довольно мала (несколко процентов) и поймать я на осцилографе его естественно не смог.

dubanoze commented 2 years ago

Помимо дребезга, на механике довольно часто присутствует "обратный поток", и если на ПУ отсутствует обратный клапан, лишние импульсы гарантированы. WhatsApp Image 2021-11-23 at 23 30 20

svpcom commented 2 years ago

Обратного клапана действительно нет. Но с моим фиксом стало считать все правильно.

dontsovcmc commented 2 years ago

@dubanoze ого, отличная информация, спасибо! Мне сантехник сказал "не надо его ставить, а то засоряются". Я вспоминаю ,что мне рассказывали кейсы, когда счетчик при определенных проблемах в водопроводе крутился назад. Хм, что теперь делать приписку "использовать только при установленных обратных клапанах" =(

@svpcom Я ничего не имею против 500ms + 6s, но меня смущают правки в таком ответственном месте и пугает объём кода при наличии высокой погрешности только вас =(.

"от 20 до 50 кОм." оокей... код прожуёт.

svpcom commented 2 years ago

Возможно другие просто не замечают погрешность (данные раз сутки передаются и если погрешность меньше суточного расхода, то она будет незаметна). Большинство людей смотрит только целую часть (м^3), а литры игнорируют.

dontsovcmc commented 2 years ago

@svpcom Добрый день! С прошедшими праздниками! Расскажите, точно ли теперь у вас считает и с каким кодом? Обнаружился некорректный подсчёт у 1л/имп счетчика, при потреблении до кубометра в день - гипотеза, пропускаются импульсы.

svpcom commented 2 years ago

@dontsovcmc Добрый день! Считает теперь точно - за два месяца погрешность +3 импульса у ГВС и +2 импульса у ХВС. То есть относительная погрешность ~ 0.1% - 0.2%. Код: https://github.com/svpcom/waterius/tree/pull-request

svpcom commented 2 years ago

Из пожеланий я бы еще исправил детекцию замыкания отдельно для намур и для сухих контактов. Так как сейчас даже в режиме сухого контакта счетчик может считать шум принимая его за уровни намура. Но если это делать через приложение, то оно уже не влезает в attiny45 (то есть тип счетчика придется задавать на этапе компиляции прошивки).

dontsovcmc commented 2 years ago

@svpcom у вас на графиках time=100ms - это 1 клетка или весь экран?

svpcom commented 2 years ago

@dontsovcmc 100ms одна клетка

dontsovcmc commented 2 years ago

@svpcom о! это любопытно, потому что у вас не "дребезг" контактов, который бывает 5мс ну 10мс... У вас что-то странное...