Skocz do zawartości

Problem ze zliczeniem impulsów przez przepływomierz


Mateusz0707

Pomocna odpowiedź

Cześć, 

Mam problem ze zliczeniem impulsów przez przepływomierz w układzie pompa, elektrozawór przepływomierz. 

Program działa na przerwaniach, gdzie zbocze opadające powoduje zwiększenie licznika impulsów w funkcji obsługującej przerwania, to jest jasne i zrozumiałe. 

Wartość z licznika impulsów wyswietlam na ekranie LCD. 

Za przepływomierz mam rurkę, no i za nią kubek o znanej pojemności. 

W danych katalogowych przepływomierza jest wyraźne napisane, że na 1L przypada 5880 impulsów, tu natomiast wartość ta jest osiągana już dla prawie 0,5 l wody. 

W czym tkwi problem, robię tak jak każdy, a jednak mam problem z poprawnym odczytem impulsów. 

Pozdrawiam 

Link do komentarza
Share on other sites

@Mateusz0707 witam na forum, chętnie pomożemy brakuje jednak kilku ważnych informacji:

  • co to dokładnie za przepływomierz,
  • jakiego mikrokontrolera używasz,
  • przydałby się też wgląd do kodu.

Najłatwiej odpowiedzieć, że wygląda na to, jakbyś wcale nie mierzył zbocza opadającego tylko oba, ale bez wglądu w program to wróżenie z kuli 🔮

Link do komentarza
Share on other sites

9 godzin temu, Mateusz0707 napisał:

W czym tkwi problem, robię tak jak każdy, a jednak mam problem z poprawnym odczytem impulsów. 

Obstawiam, że program reaguje na oba zbocza (podobnie jak pamięć DDR), ale tutaj jak Treker wspomniał: bez kodu lub kryształowej kuli raczej nie pomożemy... bo to tylko strzelanie w ciemno.

Link do komentarza
Share on other sites

Poprawny pomiar wymaga również ustabilizowanego przepływu, profil prędkości w rurce nie jest równy na całym przekroju, np. jak zobaczysz na wodomierz w domu to jest tam pewien odcinek prostej rury przed i za wodomierzem by zakłócenia były minimalne. Pompa  w szczególności powinna być oddalona.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

(edytowany)

Tak, przepraszam za brak kodu, już wstawiam, a płytka to typowe arduino UNO.

Opiszę po kolei co się dzieje w kodzie.

Na początku użytkownik wprowadza zadaną pojemność z klawiatury, ta wyświetlana jest na ekranie.

Klawiaturę obsługuje biblioteka OnewireKeypad.h wykorzystując tylko jedno wejście analogowe, gdzie piny z klawiatury podłączone są do odpowiednich rezystorów w odpowiedniej konfiguracji, to działa bez zarzutu, dzięki czemu oszczędzam masę pinów cyfrowych.

Po wprowadzanie pojemności i zatwierdzeniu gwiazdką '*', program przechodzi do stepp 1, gdzie zaczyna migać dioda co 1s i odczytywany jest stan przycisku.

Gdy użytkownik naciśnie przycisk uruchamiany jest przenośnik, a mianowicie silnik poprzez przekaźnik i regulator prędkości obrotowej, który zasilany jest z 12V.

Na przenośniku znajduje się czujnik IR, który wykrywa kubek i zatrzymuje przenośnik, a wysterowuje pompę i elektrozawór, też na 12V.

Aktualna wartość przelanej cieczy wyświetlana jest na ekranie, a osiągnięcie zadanej wartości wyłącz pompę i elektrozawór, sekwencja się powtarza.

Jest to ogólny zarys funkcjonowania programu, bez ulepszeń i zmian wprowadzanych w kodzie podczas testowania już na złożonym projekcie, dlatego mam lekki chaos w kodzie i skrzynce z połączeniami, za co przepraszam. Działało bez zarzutu gdy testowałem program bez fizycznych podłączeń silnika, pompy i elektrozaworu oraz przepływomierza, po złożeniu układu wszystko zaczęło się sypać.

Pierwszy problem

Zliczanie impulsów z przepływomierza. 

To jest ten przepływomierz: https://www.dfrobot.com/product-1531.html

Podane jest, że 1 l odpowiada 5880 impulsom, jednak tu, gdy wyświetlam na ekranie aktualną wartość zliczonych impulsów przy jednoczesnym nalewaniu cieczy w układzie jakim pokażę na zdjęciu, z zastosowaniem kubka 0,3l lub 0,5l, zauważyłem, iż przy kubku 0,5l impulsów mam około 6000. Nie wiem dlaczego tak się dzieje, niestety siedzę już trochę przy tym projekcie, a czasu mam już coraz mniej.

Przypuszczam także, że prawdopodobnie mam źle zamontowaną pompę, co sprawia, że przed elektrozaworem, nie ma wody, a jest powietrze, które po uruchomieniu pompy, przechodzi przez przepływomierz, a to nalicza nadmiarowe impulsy do czasu pojawienia się wody, prawdopodobnie będę musiał to przeprojektować albo uruchamiać elektrozawór po określonym upływie czasu.

Drugi problem, o którym nie wspomniałem.

Ujawnia się gdy wyłączam przekaźnik zasilające elektrozawór oraz pompę, wtedy następuje reset arduino, nie występuje gdy zasilę pompę i elektrozawór bezpośrednio z 12V. Przypuszczam, że występuje jakiś pik prądu, który wprowadza zakłócenia, przy rozwieraniu styków przekaźnika. Jest jakieś rozwiązanie tego problemu?

Chciałbym też zaznaczyć, że nie wprowadzałem żadnych zmian, ze względu na utknięcie właśnie z tymi dwoma problemami, proszę o wyrozumiałość i dziękuję za wszelaką pomoc.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OnewireKeypad.h> // bibliotek obsługjąca klawaiturę za pomocą pinu analogowego
#define Conveyor 10
#define Pomp 11
#define Valve 12
#define flowsensor 2
#define IR_Sensor A0
#define LED_Start 13
#define PB_Start 9

// dane do obsługi klawiatury
#define Rows 4
#define Cols 3
#define Pin A2
#define Row_Res 4700
#define Col_Res 1000




char KEYS[]= {
  '1','2','3',
  '4','5','6',
  '7','8','9',
  '*','0','#'
};

OnewireKeypad <Print, 12> klawiatura(Serial, KEYS, Rows, Cols, Pin, Row_Res, Col_Res);

volatile int flow_frequency;
float vol=0.0,one_l;
int vol_1=0;


void flow () // funkcja obsługująca przerwania
{
   flow_frequency++;
}


LiquidCrystal_I2C lcd(0x27,16,2);

unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas = 0;
unsigned long zapamietanyCzas_LED = 0;
unsigned long zapamietanyCzas_Break = 0;



int PBS;
char Data[7];
byte data_count = 0;
bool potwierdzenie;
String ml;
int ml_1;
int cursorColumn = 0;
int sensor_IR;
int stan_LED = LOW;
int stepp;
char key_push;

void setup()
{
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.print("Set Value:    ml");
  lcd.setCursor(0,1);
  lcd.print("Filled:       ml");
  pinMode(PB_Start, INPUT_PULLUP);
  pinMode(LED_Start, OUTPUT);
  pinMode(Conveyor, OUTPUT);
  digitalWrite(Conveyor, HIGH);
  pinMode(Pomp, OUTPUT);
  digitalWrite(Pomp, HIGH);
  pinMode(Valve, OUTPUT);
  digitalWrite(Valve, HIGH);
  pinMode(flowsensor, INPUT_PULLUP);
  //digitalWrite(flowsensor, HIGH); 
  attachInterrupt(digitalPinToInterrupt(flowsensor), flow, FALLING); // ustawienie przerwań
  aktualnyCzas = millis();
  zapamietanyCzas = aktualnyCzas;
  klawiatura.SetKeypadVoltage(5.0);
  klawiatura.SetHoldTime(200);
}


void loop()
{

  byte KState = klawiatura.Key_State();

  sensor_IR = analogRead(IR_Sensor);

  aktualnyCzas = millis();

  if(KState == PRESSED){
    if(key_push=klawiatura.Getkey()){
    if(key_push!='*'&&key_push!='#'&&data_count<4&&potwierdzenie==false){
      Data[data_count]=key_push;
      lcd.setCursor(data_count+10, 0);
      lcd.print(Data[data_count]);
      data_count++;}
      }
  
    
      if(data_count<5&&key_push=='*'){ // zatwierdzenie wprowadzenia przez użytkownika pojemności
        potwierdzenie = true;
        stepp=1;
        ml=String(Data);
        ml_1=ml.toInt();
        //memset(Data, ' ', 4*sizeof(char));
        }
  } 

  if(data_count<5&&key_push=='#'){ // warunek odpowiedzialny za kasowanie wprowadzonych danych z klawiatury
    lcd.setCursor(10,0);
    lcd.print("    ");
    data_count = 0;
    stepp = 0;
    memset(Data, ' ', 4*sizeof(char));
    potwierdzenie=false;
  }

   if(aktualnyCzas >= (zapamietanyCzas + 1000)) // aktualizacja co 1 s
   {
    zapamietanyCzas = aktualnyCzas; // Updates cloopTime
    if(flow_frequency != 0){

      one_l = flow_frequency/17.45; // wartosc 1 litra (wartosc 17.45 wyznaczona eksperymentalnie nalewając kubek 300ml do pełna, ale jest to mało dokładna wartosc, raz osiągana zadana wartosc, raz nie)
      
      vol = vol +one_l;
      vol_1 = vol; // przypisanie do zmiennej INT
      lcd.setCursor(7,1);
      lcd.print(vol_1);
      flow_frequency = 0;
      }
     }

   switch(stepp){
          case 1: // case odpowiedzialny za procedurę startu
                 if(aktualnyCzas - zapamietanyCzas_LED >= 1000UL){
                    zapamietanyCzas_LED = aktualnyCzas;
                    stan_LED = !stan_LED;
                    digitalWrite(LED_Start, stan_LED);
                 }
                 
                 PBS = digitalRead(PB_Start);
                 if(PBS == HIGH){
                  digitalWrite(LED_Start, HIGH);
                  stepp++;
                 }
          break;

          case 2:
                digitalWrite(Conveyor, LOW); // uruchomienie przenośnika
                if(sensor_IR<=900&&ml_1!=0){ // wykrycie przez czujnik IR kubka, wyłącza przenośnik i uruchamia pompę i elektrozawór
                  digitalWrite(Conveyor, HIGH);
                  digitalWrite(Pomp, LOW);
                  digitalWrite(Valve, LOW);
                  zapamietanyCzas_Break = aktualnyCzas; // pomiar czasu w każdym kroku wykorzystanym do późniejszej przerwy w ponownym uruchomieniu przenośnika
                  stepp++;
                }
          break;

          case 3:
                if(vol_1>=ml_1&&ml_1!=0){ // jeśli pojemność przelana osiągnęła wartość zadaną przez użytkownika, wyłącza pompę i elektrozawór
                  digitalWrite(Pomp, HIGH);
                  digitalWrite(Valve, HIGH);
                  zapamietanyCzas_Break = aktualnyCzas;
                  stepp++;
                }
          break;

          case 4:
                if(aktualnyCzas - zapamietanyCzas_Break >= 5000UL){ // przerwa 5s, wyzerowanie danych i wyczyszczenie ekranu
                zapamietanyCzas_Break = aktualnyCzas;
                vol_1 = 0;
                vol = 0;
                stepp = 2; // powrót do kroku 2 z ponownym załączeniem przenośnika
                lcd.setCursor(7,1);
                lcd.print("    ");}
          break;}

          Serial.println(stepp);

}

IMG20221215135219.jpg

Edytowano przez Mateusz0707
Link do komentarza
Share on other sites

Co do zakłóceń spróbuj dodać jakiś większy elektrolit jak najbliżej pinów zasilania Ardu...co do przerwań wydaje się że jest ok, czytasz tylko zbocze opadające..jeśli pomiary są powtarzalne to może poprostu uwzględnij to w kodzie i po problemie?🤔

Link do komentarza
Share on other sites

Zacznę najpierw od tego najprostszego.

21 minut temu, Mateusz0707 napisał:

Ujawnia się gdy wyłączam przekaźnik zasilające elektrozawór oraz pompę, wtedy następuje reset arduino, nie występuje gdy zasilę pompę i elektrozawór bezpośrednio z 12V. Przypuszczam, że występuje jakiś pik prądu, który wprowadza zakłócenia, przy rozwieraniu styków przekaźnika. Jest jakieś rozwiązanie tego problemu?

Najlepsze rozwiązanie byłoby takie, aby po prostu zasilać to z takiego źródła, dla którego ten pik nie będzie groźny. Są dwie opcje - albo układ jest resetowany przez cewkę przekaźnika, albo przez startującą pompę. Zapewne da się to naprawić odpowiednimi kondensatorami - tylko wypadaj najpierw co dokładnie resetuje układ.

Link do komentarza
Share on other sites

10 minut temu, farmaceuta napisał:

Co do zakłóceń spróbuj dodać jakiś większy elektrolit jak najbliżej pinów zasilania Ardu...co do przerwań wydaje się że jest ok, czytasz tylko zbocze opadające..jeśli pomiary są powtarzalne to może poprostu uwzględnij to w kodzie i po problemie?🤔

Co do zliczania impulsów, na każdym forum, które przeglądałem było właśnie wspomniane o współczynniku kalibracji, dobieranym w zależności od danego przepływomierza i jego zastosowania, więc raczej pokombinuję z tym w zakresie samego programu. 

Da się jakoś dobrać taki elektrolit? 

Link do komentarza
Share on other sites

12 minut temu, Treker napisał:

Zacznę najpierw od tego najprostszego.

Najlepsze rozwiązanie byłoby takie, aby po prostu zasilać to z takiego źródła, dla którego ten pik nie będzie groźny. Są dwie opcje - albo układ jest resetowany przez cewkę przekaźnika, albo przez startującą pompę. Zapewne da się to naprawić odpowiednimi kondensatorami - tylko wypadaj najpierw co dokładnie resetuje układ.

Tutaj mankamentem jest właśnie sama pompa, o ile wysterowanie pompy i elektrozaworu nie stanowi żadnego problemu, tak ich wyłączenie, czyli rozwarcie styków przekaźnika powoduje reset arduino.

Link do komentarza
Share on other sites

Na płytce przekaźników nie zasilaj cewek z 5V z Arduino, osobny zasilacz pomaga, można też zasilanie dać przez przetwornicę z 12V. Jak masz jakąś zworkę łączącą zasilanie cewek z Vcc logiki to ją zdejmij, ale to zależy jaki masz wariant tych przekaźników.

Zawór powinien być przy wylocie, wtedy woda nie będzie wykopywać z przepływomierza, a im bliżej wylotu tym mniejsza losowość pomiarów. Nie włączaj obu cewek w tym samym czasie, jak się pompa załączy kilkadziesiąt ms przed zaworem to nic się nie stanie, jak dodasz delay 20ms to świat się nie zawali.

Link do komentarza
Share on other sites

15 minut temu, kaczakat napisał:

Na płytce przekaźników nie zasilaj cewek z 5V z Arduino, osobny zasilacz pomaga, można też zasilanie dać przez przetwornicę z 12V. Jak masz jakąś zworkę łączącą zasilanie cewek z Vcc logiki to ją zdejmij, ale to zależy jaki masz wariant tych przekaźników.

Zawór powinien być przy wylocie, wtedy woda nie będzie wykopywać z przepływomierza, a im bliżej wylotu tym mniejsza losowość pomiarów. Nie włączaj obu cewek w tym samym czasie, jak się pompa załączy kilkadziesiąt ms przed zaworem to nic się nie stanie, jak dodasz delay 20ms to świat się nie zawali.

Dałem osobne zasilanie na przekaźniki, ale w takim układzie, czyli z takim wariantem modułu przekaźników jakie mam, diody na module lekko się żarzą się, wspólne masy oczywiście są. Jeszcze spróbuję z opóźnieniem wysterować wyjścia na przekaźniki.

Link do komentarza
Share on other sites

23 minuty temu, kaczakat napisał:

Na płytce przekaźników nie zasilaj cewek z 5V z Arduino, osobny zasilacz pomaga, można też zasilanie dać przez przetwornicę z 12V. Jak masz jakąś zworkę łączącą zasilanie cewek z Vcc logiki to ją zdejmij, ale to zależy jaki masz wariant tych przekaźników.

Zawór powinien być przy wylocie, wtedy woda nie będzie wykopywać z przepływomierza, a im bliżej wylotu tym mniejsza losowość pomiarów. Nie włączaj obu cewek w tym samym czasie, jak się pompa załączy kilkadziesiąt ms przed zaworem to nic się nie stanie, jak dodasz delay 20ms to świat się nie zawali.

Opóźnienie również nie pomogło, z moich obserwacji wynika, że wyłączenie pompy powoduje spadek napięcia, przez co arduino się resetuje.

Link do komentarza
Share on other sites

2 minuty temu, farmaceuta napisał:

Kondensator poprostu daj największy jaki masz w uF i może będzie git...choć lepiej jest to zasilić z osobnego zasilania

Spróbuję, natomiast jeśli chodzi o zasilanie, to mam 3 źródła. 

Jedno 12V, na elementy wykonawcze, 9V dla samego arduino oraz 5V na wyświetlacz, ponieważ pobierał on zbyt dużo prądu, w efekcie czego arduino również się resetowało, gdy wyświetlacz był podłączony bezpośrednio do 5V arduino. 

Link do komentarza
Share on other sites

34 minuty temu, Mateusz0707 napisał:

 

Jedno 12V, na elementy wykonawcze, 9V dla samego arduino oraz 5V na wyświetlacz

Jeśli wydajność 5v wystarczy na LCD i Ardu to podepnij pod 5v i wywal te 9v bo to przez stabilizator idzie i może dlatego się dzieje tak jak się dzieje...

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.