Как получить импульс с датчика расхода воды?

Sirocco
Offline
Зарегистрирован: 28.09.2013

Я задачу с счётчиком решил иначе. В моём случае был просто геркон. И первые 10л он замкнут, следующие 10л разомкнут, и так по кругу. Одно изменение состояния контакта на противоположное - 10 литров. Если влупить воду на всю катушку, то смена состояний происходит не чаще ~ 15 сек., то есть частота низкая, можно несколько счётчиков опрашивать. Ну и делаете цикл, счётчик +1, и считаете литры. Меня интересовала больше динамика расхода, а не общее кол-во потребляемой воды, поэтому данные кидал в базу get запросом, через изернет модуль в режиме клиента. 

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

Андрей01
Offline
Зарегистрирован: 04.11.2013

Просто я согласен с интересами, но дом - это то, что надо береч. Я делаю проекты по организации учёта расхода гвс, хвс, отопления. Приборов море по доступным ценам и открытым протоколом, можно подключить модем и пожалуста.

Ардуину я только начал использовать но кое кто дал понять - нужна перезагрузка ее, питание тоже надо 24ч и непрерывно, разработка интерфейса .

Во сколько тут люди готовы за  решение именно этой прооблемы взять денег??

Я лучше пойду проверенным путём и простым. А сами сигналы у нас сами приборы выдают, тотже тмк-н20. Промприбор Калуга.

Если надо то могу подсказать по интерфейсу, но лучше зайдите на сайт того кто производит их и упростите для себя их интерфейс. В программе надо вводить такой параметр как импульс на литр. Потом время, усреднение часовое и суточное. Отчёт по часам, дням, месяцам и годовой отчёт (у нас так принято, для принятия в теплоснабжайку). 

y2kill
y2kill аватар
Offline
Зарегистрирован: 17.09.2014

Счетчик сделал на основе простого делителя (так же можно и в Омметр переделать :) ).

Сами счетчик замыкаются при переходе с 0 на 9 и размыкание происходит при переходе с 2 на 3.

Алгоритм выполняется при срабатывании счетчиков последовательно, а так же если сробатывает один из счетчиков при замкнутом другом (то есть одновременное замыкание) 

Схема

#include <LiquidCrystal.h>
#define R0 1.0      // Номинал резистора общего
#define R1 5.1    // Номинал резистора холодной воды
#define R2 10.0   // Номинал резистора горячей воды


LiquidCrystal lcd(4, 5, 8, 9, 10, 11);

float nom = 5.0; //Номинальный вольтаж при отсутствии замыкания геркона
float startup_v = 4.99;
int s_cold = 0; // Счетчик холодной воды
int s_hot = 0; // Счетчик горячей воды
float k = 0.0048875855327468; //Коэфициен перевода из разрядов. 5В - 1023 => k= 5/1023
float tolerance = 5.0; // Допуск, %
boolean cold_on = false;
boolean hot_on = false;
boolean start = true;

  float v_low_cold = nom * (R1/(R0+R1));
  float v_low_hot = nom * (R2/(R0+R2));
  float v_low_summ = nom * (R1*R2/(R0*(R1+R2)+R1*R2));
  
  float v_low_cold_min = v_low_cold * (1 - (tolerance/100));
  float v_low_cold_max = v_low_cold * (1 + (tolerance/100));
  
  float v_low_hot_min = v_low_hot * (1 - (tolerance/100));
  float v_low_hot_max = v_low_hot * (1 + (tolerance/100));
  
  float v_low_summ_min = v_low_summ * (1 - (tolerance/100));
  float v_low_summ_max = v_low_summ * (1 + (tolerance/100));

void setup()
{
  lcd.begin(16, 2);
  /* Serial.begin(115200);
        while(!Serial);
        Serial.println("Start");
  */
}

void loop()
{
  float voltage = analogRead(A0) * k;
   /* Serial.print ("COLD: ");
    Serial.print(v_low_cold);
    Serial.print(" HOT: ");
    Serial.print(v_low_hot);
    Serial.print("; Min_cold: ");
    Serial.print(v_low_cold_min);
    Serial.print(" Max_cold: ");
    Serial.print(v_low_cold_max);
    
    Serial.print("; Min_hot: ");
    Serial.print(v_low_hot_min);
    Serial.print(" Max_hot: ");
    Serial.print(v_low_hot_max);
    Serial.print("\n");
    */
    
  
  if (voltage < startup_v && start == true) {
    lcd.setCursor (0,0);
    lcd.print("Starting..."); 
    lcd.setCursor(0,1);
    lcd.print(voltage);
    lcd.print("V  ");
  } else
  {
    start = false;
    
    if (voltage >= v_low_cold_min && voltage <= v_low_cold_max && cold_on == false) {
      ++s_cold;
      cold_on = true;
    }
    if (voltage >= v_low_hot_min && voltage <= v_low_hot_max && hot_on == false) {
      ++s_hot;
      hot_on = true;
    }
    if (voltage >= v_low_summ_min && voltage <= v_low_summ_max && cold_on == true && hot_on == false) {
      ++s_hot;
      hot_on = true;
    }
    if (voltage >= v_low_summ_min && voltage <= v_low_summ_max && hot_on == true && cold_on == false) {
      ++s_cold;
      cold_on = true;
    }
    if (nom - voltage < 0.01) {
       cold_on = false;
       hot_on = false;
    }
    lcd.setCursor(0, 0);
    lcd.print(voltage);
    lcd.print("V      ");
    lcd.setCursor(0,1);
    lcd.print("Cold:");
    lcd.print(s_cold);
    lcd.print(" Hot:");
    lcd.print(s_hot);
  
  }
  delay(1000);
  
}

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Посмотрите по поиску тиграэлектроникс только по аглицки. Я их железкипользую давно, вполне устраивают...

evgen66
Offline
Зарегистрирован: 19.06.2015

Помогите разобраться, пожалуйста.

Подключил счетчик воды, со схемой НАМУРа внутри, через компаратор MAX942 к ATTiny85

На выходе с компаратора появляется 0 или 1,7В в зависимости от состояния схему Намура.

Как получить на выходе 0 и 3 В?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

evgen66, не поверите -самый простой способ выкинуть Max942, и воспользоваться встроенным компаратором Tiny85

evgen66
Offline
Зарегистрирован: 19.06.2015

А просыпание контроллера по прерыванию тоже можно осуществить? Не могли бы посоветовать, где почитать про это.

axill
Offline
Зарегистрирован: 05.09.2011

evgen66 пишет:
А просыпание контроллера по прерыванию тоже можно осуществить? Не могли бы посоветовать, где почитать про это.

первоистоник информации - даташит от атмела http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny2...

у вас геркон внутри датчика? я делал без компаратора, используя цифровой вход

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

evgen66, в принципе можно сделать очень хитрый ход, настроив отрицательный вход компаратора на ту же ногу, где сидит INT0 (главный по пробудке), в режиме компаратора будет сравниваться напряжение на этой ноге, и опорное 1,1 вольта, с этим вообще нет проблем.  Но в режиме пробудки через INT0  важно что-бы сигнал с датчика давал чёткую единицу на входе, это примерно 60% от величины напряжения питания. На компараторах я уже собаку сьел, могу помочь, но совмещать всё это с режимами сна и просыпанием  через внешнее прерывания, - это совсем другая история.

axill
Offline
Зарегистрирован: 05.09.2011

Компаратор тоже имеет прерывания, но он здесь лишний ИМХО

Есть три варианта:

1. Привести входной сигнал к цифровому и по прерываниям на него реагировать. достаточно правильно подобрать сопротивление в верхнем плече. В крайнем случае можно npn транзистор на вход. Плюс этого варианта в простоте и схемы и программы

2. Использовать аналоговый вход. Просыпаться по таймеру и делать замер. Плюс в возможности обнаруживать обрыв провода к датчику. Минус в отсутствии прерывания по входу. 

1+2 скомбинировать оба варианта, использовать аналоговый вход. В обычном режиме использовать его как вход прерываний PCINT. И периодически перенастраивать на АЦП и проверять обрыв

3. Компаратор. Прерывания будут, но в настройке сложнее чем 1.

mir_bez_arduino
Offline
Зарегистрирован: 04.02.2016

Ой, и напридумали тут, компараторы, аналоговый вход... Здесь надо то всего-то по возрастающему фронту импульс засечь. Дискретный сигнал, что может быть проще?

alex_r61
Offline
Зарегистрирован: 20.06.2012

mir_bez_arduino пишет:

Ой, и напридумали тут, компараторы, аналоговый вход... Здесь надо то всего-то по возрастающему фронту импульс засечь. Дискретный сигнал, что может быть проще?

TIMER1 в режиме захвата.

Pochemushka
Offline
Зарегистрирован: 12.12.2014

leja пишет:

Я конечно новичек ,но от ваших схем уши вянут! я подкличил через прерывания и без них очень просто!

тут все расписано прямо в скетче с прерыванием :

//
// светодиод, подключённый к digital pin 13 будет изменять своё 
// состояние при изменении напряжения на digital pin 2
//
//  1 пин со счетчика воды  на +5v ( он белый)
// 3 пин(синий) на землю -  без резистора там он уже есть
// 4 пин(красный) на pin2 ардуина 
// 2 пин (серый) не нужен
int r=0;
int pin = 13;
volatile int x = LOW;
void setup()
{
  pinMode(pin, OUTPUT);              // пин как выход
  attachInterrupt(0, blink,CHANGE ); // привязываем 0-е прерывание к функции blink().
  
//  mode: определяет, когда должно сработать прерывание. Определены следующие константы:
//LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения;
//CHANGE – прерывание вызывается при изменении значения на входе;
//RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH)
//FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)
}
 
void loop() 
{
  digitalWrite(pin, x);// выводим х
   
}
 
void blink()
{
    
  x = !x;  // меняем значение на противоположное
 r=r++;
}

Позвольте поинтересоваться на  на какое значение вы умножаете свою r чтобы получить кол-во воды в литрах , :) 

Вопрос конечно с подвохом..  Потому как у вас два раза за 10 литров воды  будет прерывание CHANGE. 

Синий зачем на землю? Он при релейном подкючении не нужен. При релейной схеме используются белый и красный. Белый - верно на +5V arduino, красный - сигнал, НО нужно притянуть его через 10 кОм на землю, иначе  на 20 метрах кабеля  воду будут расодовать зеленные человечки - проходили знаем.. 

По всей теме конечно  удивился.. Таких городулин понагородили - труба просто.. 

У меня год счетчик работает без всяки прерываний.. У меня loop   проскакивает за 27-57 мс,  у счетчика  от 0 до 1 - 4литра воды, от 1 до 0 соотвественно 6, чтобы я за 57мс не поймал так назыаваемый "импульс", то нужно 0,057/4=0,01425 нужно времени чтобы проскочил 1 литр воды, соотвественно 1сек/0,01425= 70,175 ЛИТРА В СЕКУНДУ!!! Или 70,175*60=4 207,5 ллитра в минуту!!! Час даже считать не буду :)  Впечатляет?  Дальше становиться понятно, что ардуино должна быть наглухо тупая и медленная чтобы не успеть, поэтому я отказался от прерываний. все просто как в танке - ниже кусок из 10 000 срочек моего умного дома, работает год  - нареканий нет, что в базе, то и  на счетчике  - цифры одинковые: (Вчера вечером приехали на дом в баню, взрослые всю ночь гульвасили,  дети с утра "хочу джакузю" - результат по воде на графике ниже :) ) 

//===============Куда воткнут счетчик============
#define pinVoda_tick        12 //счетчик воды
//=================переменная для предыдущего состояния счетчика воды
boolean stateCheck_voda;
//=============Считаем расход воды================
void voda_tick(){
 boolean current_status=digitalRead(pinVoda_tick);
   if (stateCheck_voda && !current_status){
       // ВОТ ТУТ ПОЛУЧИЛИ ЗАВЕТНЫЕ 10 ЛИТРОВ  пишем действия для этого события
        stateCheck_voda=current_status;                 
                        }
 if (!stateCheck_voda && current_status)stateCheck_voda=current_status;
              }
void setup(){
//  уравниваем предыдущего и начального состояния иначе каждый запуск arduino будет  расходовать 10 литров воды :)
stateCheck_voda=digitalRead(pinVoda_tick); 
                    
   }
void loop(){
    voda_tick();                
 }