dontsovcmc / waterius

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

Blynk - incorrect delta values #61

Closed OloloevReal closed 5 years ago

OloloevReal commented 5 years ago

Добрый день!

Обратил внимание на то, что в Blynk отправляется разница показаний за интервал измерения:

        unsigned int delta0 = (channel0 - sett.channel0_previous)*1000;  // litres
        unsigned int delta1 = (channel1 - sett.channel1_previous)*1000;

В результате такого приведения типов 2 импульса преобразуются не в 20, а в 19, 5 импульсов в 49 и т.д.

Возможно, стоит сделать вот так:

        unsigned int delta0 = (channel0 - sett.channel0_previous)*1000 + .5;  // litres
        unsigned int delta1 = (channel1 - sett.channel1_previous)*1000 + .5;
dontsovcmc commented 5 years ago

Поясните подробнее =) 5 импульсов: дельта будет 0.05 * 1000 = 50. Откуда 49?

Если что, в Blynk графики считаются с синхронизацией с календарем, а Ватериус отправляет не строго по часам, поэтому числа на графике другие. p.s. +.5 - если 10л/имп.

OloloevReal commented 5 years ago

5 импульсов: дельта будет 0.05 * 1000 = 50. Откуда 49?

Преобразование float 50.00 в int дает результат 49, не всегда правда, в большинстве случаев.

dontsovcmc commented 5 years ago

Ааа вы про вычислительные потери. Так может переписать: unsigned int delta0 = channel0*1000 - sett.channel0_previous*1000 ?

OloloevReal commented 5 years ago

Либо так:

        unsigned int delta0 = roundf((channel0 - sett.channel0_previous) * 100 * sett.liters_per_impuls);  // litres
        unsigned int delta1 = roundf((channel1 - sett.channel1_previous) * 100 * sett.liters_per_impuls);
dontsovcmc commented 5 years ago

Некорректная формула. в channel0 хранятся кубометры. Мою используйте и напишите о результатах испытаний, пожалуйста.

OloloevReal commented 5 years ago

unsigned int delta0 = channel0*1000 - sett.channel0_previous*1000 Так преобразование происходит корректно

Некорректная формула. в channel0 хранятся кубометры. Мою используйте и напишите о результатах испытаний, пожалуйста.

Не понял, почему некорректная формула? в channel0/channel1 разве только кубометры? По коду смотрел вроде это показание счетчика со знаками после запятой, т.е. с литрами

dontsovcmc commented 5 years ago

Потому что в channel0 хранятся кубометры. *channel0 = sett.channel0_start + (data.impulses0 - sett.impules0_start) / 1000.0 * sett.liters_per_impuls;

Тут ошибка не накапливается, т.к. каждый раз пересчёт. Кстати, мы можем хранить предыдущее значение импульсов и рассчитывать литры вообще без потерь. Напишите код?

dontsovcmc commented 5 years ago

Написал сам =) В следующем релизе сегодня-завтра будет HTTPS и литры без погрешностей =)

dontsovcmc commented 5 years ago

Проверяйте. Теперь без делений. Только умножаем на кол-во литров/импульс.