Расходомер жидкости

Sosisochnik
Offline
Зарегистрирован: 18.06.2013

 

Друзья, нуждаюсь в вашей помощи с программным кодом. Сейчас нахожусь в процессе создания аппарата по смешению напитков. Недавно пришли посылки ebay с насосами, датчиками расхода жидкости, Ардуино Мега, Уно и набором для начинающих, включающий в себя кучу сенсоров и всяких электронных мелочей. Расходомеры или датчики холла на фото ниже:

Теперь мне нужно проверить работоспособность и параметры насосов и датчиков расхода жидкости - нашел скетч специально для таких датчиков:

// reading liquid flow rate using Seeeduino and Water Flow Sensor from Seeedstudio.com
// Code adapted by Charles Gantt from PC Fan RPM code written by Crenn @thebestcasescenario.com
// http:/themakersworkbench.com http://thebestcasescenario.com http://seeedstudio.com
 
volatile int NbTopsFan; //measuring the rising edges of the signal
int Calc;                               
int hallsensor = 2;    //The pin location of the sensor
 
void rpm ()     //This is the function that the interupt calls 
{ 
  NbTopsFan++;  //This function measures the rising and falling edge of the hall effect sensors signal
} 
// The setup() method runs once, when the sketch starts
void setup() //
{ 
  pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
  Serial.begin(9600); //This is the setup function where the serial port is initialised,
  attachInterrupt(0, rpm, RISING); //and the interrupt is attached
} 
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop ()    
{
  NbTopsFan = 0;   //Set NbTops to 0 ready for calculations
  sei();      //Enables interrupts
  delay (1000);   //Wait 1 second
  cli();      //Disable interrupts
  Calc = (NbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate 
 
in L/hour 
  Serial.print (Calc, DEC); //Prints the number calculated above
  Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a  new line
}

 

Код взял отсюда: http://www.seeedstudio.com/wiki/index.php?title=G1/2_Water_Flow_sensor

Подключил – все работает, но выдает скорость потока (показания в литрах в час). Подскажите, пожалуйста, как подправить код, чтобы показания были в миллилитрах (или литрах), т.е. мне нужна не скорость потока, а объем жидкости после прогонки через датчик.

Diemon
Offline
Зарегистрирован: 18.11.2011

NbTopsFan - переменная в которую пишется кол-во импульсов с расходомера за секунду.

Calc = (NbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5)Q, = flow rate - формула, которая на основании кол-ва имульсов за секунду считает расход.

Сможете посчитать, сколько жидкости прошло через расходомер за секунду?

Sosisochnik
Offline
Зарегистрирован: 18.06.2013

 

Diemon, если я правильно понимаю, нужно раделить значение calc на 3600000 (т.к. в часе 3600 секунд или 3 600 000 милисекунд) и тогда получится расход в секунду. Примерно так:

Calc = (NbTopsFan * 60 / 7.5/3600)

Но тогда нужно чтобы последнее значение складывалось каждую секунду - а это уже сложно для меня)

Diemon
Offline
Зарегистрирован: 18.11.2011

Для начала скажите модель вашего расходомера. Я догадываюсь, что число 7.5 это весовой коэффициент импульса, но хотелось бы уточнить.

Создайте новую числову переменную volume. и в void_loop плюсуйте в неё каждую секунду значение объема. Вот вам и общий объем. Правда это не очень правильно.

В идеале вы должны знать, сколько нужно налить жидкости, и по прерыванию сравнивать уже налитый объем с заданием, а по достижению заданного объема выключать насос. Но это пока сложно для вас, начните с малого.

 

spa-sam
Offline
Зарегистрирован: 14.12.2012
 

Посмотри в сторону этого кода, найдешь для себя наметки под свой код или возмешь сразу этот 

https://github.com/adafruit/Adafruit-Flow-Meter/blob/master/Adafruit_Flo...

Sosisochnik
Offline
Зарегистрирован: 18.06.2013

spa-sam, спасибо, то что нужно - уже во всю тестирую)

Diemon, спасибо - это будет следующим шагом. Эти китайские датчики ноунэймы на них почти нет спецификации и коэффициента я не нашел. Как раз вычислением этой цифры я сейчас и занимаюсь.

romster
Offline
Зарегистрирован: 15.04.2013

тоже на почте лежит расходомер из китая, все некогда сходить )

а на фотке у вас один расходомер, а второй насос ? и что за насос ? видел в китае тока расходомеры и клапана, насосы как-то не попадались.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

romster пишет:

видел в китае тока расходомеры и клапана, насосы как-то не попадались.

Такие насосы бывают двух типов: мембранные и шестеренчатые. Первые дают приличное давление, вторые - расход. Стоят в районе $5 - $20. Шестеренчатые довольно широко применяются в качестве насосов для автомобильных омывателей стекол и фар...

mumrik
Offline
Зарегистрирован: 27.06.2014

  Calc = (NbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate

а что за значение 7,50 ? количество импульсов в минуту  ?

в паспорте водомера написанно написано 4380, насчитал 2966.

расходомер

http://www.dx.com/p/hs01-high-precision-flow-meter-white-black-226937#.U6x_u_4hZko

насос

http://www.dx.com/p/wt-030-sc600b-type-cooling-single-water-pump-w-speed-test-line-and-base-black-silver-12v-286964#.U6yAHv4hZko

gevor
Offline
Зарегистрирован: 23.09.2015

[quote=Sosisochnik]

spa-sam, спасибо, то что нужно - уже во всю тестирую)

Diemon, спасибо - это будет следующим шагом. Эти китайские датчики ноунэймы на них почти нет спецификации и коэффициента я не нашел. Как раз вычислением этой цифры я сейчас и занимаюсь.

Добрый день. У меня такие же датчики. Получилось у Вас с показаниями? У меня не получается счетч на 2 датчика. Если возможно, полелитесь готовым скетчем. Спасибо.

neolead
Offline
Зарегистрирован: 24.09.2015

Привет, найди плиз меня вконтакте vk.com /neolead

собираю такой же девайс.)

gevor
Offline
Зарегистрирован: 23.09.2015

spa-sam пишет:

 

Посмотри в сторону этого кода, найдешь для себя наметки под свой код или возмешь сразу этот 

https://github.com/adafruit/Adafruit-Flow-Meter/blob/master/Adafruit_Flo...

Код хороший, не получается адаптировать под 2 сетчика. Вот,что получилось:

/**********************************************************
This is example code for using the Adafruit liquid flow meters. 
Tested and works great with the Adafruit plastic and brass meters
Connect the red wire to +5V, 
the black wire to common ground 
and the yellow sensor wire to pin #2
Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!
Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above must be included in any redistribution
**********************************************************/
//#include "LiquidCrystal.h"
//LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
 
// which pin to use for reading the sensor? can use any pin!
#define FLOWSENSORPIN 2
#define FLOWSENSORPIN2 3
 
 
volatile uint16_t pulses = 0;// count how many pulses!
volatile uint8_t lastflowpinstate;// track the state of the pulse pin
volatile uint32_t lastflowratetimer = 0;// you can try to keep time of how long it is between pulses
volatile float flowrate;// and use that to calculate a flow rate
 
 
volatile uint16_t pulses2 = 0;// count how many pulses!
volatile uint8_t lastflowpinstate2;// track the state of the pulse pin
volatile uint32_t lastflowratetimer2 = 0;// you can try to keep time of how long it is between pulses
volatile float flowrate2;// and use that to calculate a flow rate
 
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);
  uint8_t y = digitalRead(FLOWSENSORPIN2);
  
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }
  
    if (y == lastflowpinstate2) {
    lastflowratetimer2++;
    return; // nothing changed!
  }
 
  
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  
  if (y == HIGH) {
    //low to high transition!
    pulses2++;
  }
  
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer;  // in hertz
  lastflowratetimer = 0;
  
  lastflowpinstate2 = y;
  flowrate2 = 1000.0;
  flowrate2 /= lastflowratetimer2;  // in hertz
  lastflowratetimer2 = 0;
 
  
}
 
void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
  }
}
 
void setup() {
   Serial.begin(9600);
   Serial.print("Flow sensor test!");
//   lcd.begin(16, 2);
   
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
      
      pinMode(FLOWSENSORPIN2, INPUT);
   digitalWrite(FLOWSENSORPIN2, HIGH);
   lastflowpinstate2 = digitalRead(FLOWSENSORPIN2);
 
useInterrupt(true);
   
   
}
 
void loop()                     // run over and over again
//  lcd.setCursor(0, 0);
//  lcd.print("Pulses:"); lcd.print(pulses, DEC);
//  lcd.print(" Hz:");
//  lcd.print(flowrate);
  //lcd.print(flowrate);
  Serial.print("Freq1: "); Serial.println(flowrate);
  Serial.print("Pulses1: "); Serial.println(pulses, DEC);
  
  Serial.print("Freq2: "); Serial.println(flowrate2);
  Serial.print("Pulses2: "); Serial.println(pulses2, DEC);
  
  
  // if a plastic sensor use the following calculation
  // Sensor Frequency (Hz) = 7.5 * Q (Liters/min)
  // Liters = Q * time elapsed (seconds) / 60 (seconds/minute)
  // Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60
  // Liters = Pulses / (7.5 * 60)
  float liters = pulses;
  liters /= 7.5;
  liters /= 60.0;
 
 
  float liters2 = pulses2;
  liters2 /= 7.5;
  liters2 /= 60.0;
 
/*
  // if a brass sensor use the following calculation
  float liters = pulses;
  liters /= 8.1;
  liters -= 6;
  liters /= 60.0;
*/
  Serial.print(liters); Serial.println(" Liters");
  Serial.print(liters2); Serial.println(" Liters2");
 
  
//  lcd.setCursor(0, 1);
//  lcd.print(liters); lcd.print(" Liters        ");
 
  delay(100);
}
 
Проблема наверное тут: void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
 
разобраться в этом коде не получается.
vassja-d
Offline
Зарегистрирован: 25.09.2016
Підправив код. Тепер можна знімати дані з 2-х датчиків одночасно
 
/**********************************************************
This is example code for using the Adafruit liquid flow meters. 
Tested and works great with the Adafruit plastic and brass meters
Connect the red wire to +5V, 
the black wire to common ground 
and the yellow sensor wire to pin #2
Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!
Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above must be included in any redistribution
**********************************************************/
/**************
Доопрацьовано Дичкевич В.М. 
вересень 2016р.
 
Змінено:
- внесено коефіцієнт для датчика потоку YF-S402
- доданно можливасть знімання парометрів з двох датчиків одночасно.
- є можливість вираховування різниці між даними першого і другого датчика потоку
 
**************/
 
 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
 
// which pin to use for reading the sensor? can use any pin!
#define FLOWSENSORPIN 2
#define FLOWSENSORPIN2 3
 
 
volatile uint16_t pulses = 0;// count how many pulses!
volatile uint8_t lastflowpinstate;// track the state of the pulse pin
volatile uint32_t lastflowratetimer = 0;// you can try to keep time of how long it is between pulses
volatile float flowrate;// and use that to calculate a flow rate
 
 
volatile uint16_t pulses2 = 0;// count how many pulses!
volatile uint8_t lastflowpinstate2;// track the state of the pulse pin
volatile uint32_t lastflowratetimer2 = 0;// you can try to keep time of how long it is between pulses
volatile float flowrate2;// and use that to calculate a flow rate
 
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
  uint8_t x = digitalRead(FLOWSENSORPIN);
  
  if (x == lastflowpinstate) {
    lastflowratetimer++;
    return; // nothing changed!
  }
  
  if (x == HIGH) {
    //low to high transition!
    pulses++;
  }
  lastflowpinstate = x;
  flowrate = 1000.0;
  flowrate /= lastflowratetimer;  // in hertz
  lastflowratetimer = 0;
}
 
    
    
  SIGNAL(TIMER1_COMPB_vect)
  {
 
   uint8_t y = digitalRead(FLOWSENSORPIN2);
    if (y == lastflowpinstate2) {
    lastflowratetimer2++;
    return; // nothing changed!
  }
 
  
    
  if (y == HIGH) {
    //low to high transition!
    pulses2++;
  }
  
    
  lastflowpinstate2 = y;
  flowrate2 = 1000.0;
  flowrate2 /= lastflowratetimer2;  // in hertz
  lastflowratetimer2 = 0;
 
  
}
 
void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
  }
}
void use_Interrupt(boolean n) {
  if (n) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0B = 0xAF;
    TIMSK1 |= _BV(OCIE0B);
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK1 &= ~_BV(OCIE0B);
  }
}
 
void setup() {
   Serial.begin(9600);
   Serial.print("Flow sensor test!");
lcd.init(); 
   lcd.backlight();
   
   pinMode(FLOWSENSORPIN, INPUT);
   digitalWrite(FLOWSENSORPIN, HIGH);
   lastflowpinstate = digitalRead(FLOWSENSORPIN);
      
      pinMode(FLOWSENSORPIN2, INPUT);
   digitalWrite(FLOWSENSORPIN2, HIGH);
   lastflowpinstate2 = digitalRead(FLOWSENSORPIN2);
 
useInterrupt(true);
use_Interrupt(true);
   
   
}
 
void loop()                     // run over and over again
// lcd.setCursor(0, 0);
//  lcd.print("Pulses:"); lcd.print(pulses, DEC);
//  lcd.print(" Hz:");
//  lcd.print(flowrate);
  //lcd.print(flowrate);
  Serial.print("Freq1: "); Serial.println(flowrate);
  Serial.print("Pulses1: "); Serial.println(pulses, DEC);
  
  Serial.print("Freq2: "); Serial.println(flowrate2);
  Serial.print("Pulses2: "); Serial.println(pulses2, DEC);
  
  
  // if a plastic sensor use the following calculation
  // Sensor Frequency (Hz) = 7.5 * Q (Liters/min)
  // Liters = Q * time elapsed (seconds) / 60 (seconds/minute)
  // Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60
  // Liters = Pulses / (7.5 * 60)
 
  /*
    float liters = pulses;
  liters /= 7.5;
  liters /= 60.0;
 
 
  float liters2 = pulses2;
  liters2 /= 7.5;
  liters2 /= 60.0;
   */
  
  
  float liters = pulses;
  liters /= 73;
  liters /= 60.0;
 
 
  float liters2 = pulses2;
  liters2 /= 73;
  liters2 /= 60.0;
  
     float rizn = (liters - liters2);
 
 
/*
  // if a brass sensor use the following calculation
  float liters = pulses;
  liters /= 8.1;
  liters -= 6;
  liters /= 60.0;
*/
  Serial.print(liters); Serial.println(" Liters");
  Serial.print(liters2); Serial.println(" Liters2");
  Serial.print(rizn); Serial.println(" riznycja");
 
lcd.setCursor(0, 0);
  lcd.print(liters); lcd.print(" Litres R       ");
   lcd.setCursor(0, 1);
  lcd.print(liters2); lcd.print(" L "); lcd.print(rizn);
 
  delay(100);
}
 
 
hambo
Offline
Зарегистрирован: 25.09.2016
Добрый вечер! Использую указанный выше скетч для включения компрессора. Все работает. flowrate = 0.6 соответствует 1 л/мин. Подскажите плиз, как организовать таймер, чтобы реле срабатывало не сразу, а с задержкой 5 секунд после flowrate > 1 л/мин. Спасибо
 
if (flowrate > 0.6) {
    digitalWrite(relay, HIGH); // реле включено
  }
  else {
    digitalWrite(relay, LOW); // реле выключено
  }
 
diakin
diakin аватар
Offline
Зарегистрирован: 04.06.2016

Sosisochnik пишет:

Подключил – все работает, но выдает скорость потока (показания в литрах в час). Подскажите, пожалуйста, как подправить код, чтобы показания были в миллилитрах (или литрах), т.е. мне нужна не скорость потока, а объем жидкости после прогонки через датчик.

 

Ну так надо скорость умножить на время и получится путь объем

cyber-jet
cyber-jet аватар
Offline
Зарегистрирован: 17.10.2017

Стесняюсь спросить, а зачем был нужен весь этот гемор с высчитыванием скорости потока(профит), если в итоге нужно посчитать сколько воды прошло через датчик? Это все= что дергать зубы через задницу! :)

Вопрос прост как 3 копейки:

У меня было так, взял электронные весы, обнулил тару, прогнал через датчик энное количество воды, чем больше тем лучше, больше точность. Посчитал количество "тиков" датчиком холла в мониторе порта, потом в переменную объёма одного тика записал количество жидкости (1 литр - 1 кг) деленное на количество тиков. Это число в прерывании на датчике холла прибавляется к счетчику литров. В дальнейшем уже в готовом устройстве сделал пункт меню калибровки датчика, где после прогона жидкости нужно было забить в окошко показатель количества шидкости, программа делает нужные вычисления, и обновляет значнеие переменной в EEPROM.

PS: Датчик потока нужно ставить перед клапаном, т.е. вход -> датчик -> клапан -> выход.

udavst
udavst аватар
Offline
Зарегистрирован: 29.11.2013

Я тоже делал проще, я не знал вообще коэффициент датчика протока на колонке Ariston Fast Evo.

Ардуиной зацпился внутрь колонки, чтоб температуру воды показывать (на колонке нет индикатора, а я по прошлой привык), ну к батарейкам зацепился - заряд измерять, ну и раз такое дело зацепился и к датчику протока, хотя и не знал делителя. В программе просто сделал измерение количества импульсов за секунду, но это мне ничего не говорило. Тогда сделал напор, чтоб показывало 100 имп в сек (просто для удоства расчёта), получил за 40 сек 3 литра при потоке 100 имп в сек, посчитал, в итоге получилось 4.5 л/мин или 1 импульс это 0.045 л/м, всё, умножаю в программе количество импульсов в секунду на 0.045 и получаю литров в минуту.