Skocz do zawartości

Automatyczna pompa do wody


Pomocna odpowiedź

Napisano

Automatycznie włączająca się pompa umieszczona w zbiorniku na deszczówkę. Między pompą a kranem zamocowany jest czujnik przepływu hallotronowy. Zasada działania tego układu polega na tym że:

Podczas otwarcia kranu woda leje się z przepływem ok 10l/h (zbiornik jest wyżej od kranu dzięki czemu woda leje się sama). W tym momencie powinna się włączyć pompa, przepływ wynosi wtedy ok 1200l/h bez obciążenia. Gdy zamknę kran lub myjka ciśnieniowa nie pracuje (nie pobiera wody), następuje wtedy wzrost ciśnienia i przepływ spada gwałtownie do wartości 400l/h a nawet mniej. W tej sytuacji pompa powinna się wyłączyć.

Problem Mojego programu jest taki że w czasie otwarcia kranu (włączenia pompy), zamknięcia kranu (wyłączenie pompy) powinien być czas na ustabilizowanie się przepływu (wartości odczytanej). Przy włączeniu 1,5s i przy wyłączeniu 5s (jeśli nagle wartość przepływu wynosi 300 powinno nastąpić wyłączenie na 5s niezależnie czy w ciągu 1s wartość zmieni się na 40 co powoduje włączenie się.  Nie wiem jak to zrobić, roszę o pomoc.

volatile int NbTopsFan; 
int przeplyw;                               
int hallsensor = 2;    //Sensor

unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas = 0;

void rpm ()     
{ 
 NbTopsFan++;  
} 

void setup()
{ 
 pinMode(10, OUTPUT); 
 pinMode(hallsensor, INPUT); 
 Serial.begin(9600); 
 attachInterrupt(0, rpm, RISING);
} 

void loop ()    
{
 aktualnyCzas = millis();
  
 NbTopsFan = 0;
 sei();            
 if (aktualnyCzas - zapamietanyCzas >= 1000UL) {
 zapamietanyCzas = aktualnyCzas;
 cli();            
 przeplyw = (NbTopsFan * 60 / 7.5); 

 Serial.print (przeplyw, DEC); 
 Serial.print (" L/godzr\r\n"); 

  if (przeplyw > 1 && przeplyw < 50 ){ //otwarcie kranu - włączenie pompy      na 1,5s zostaje włączona pompa niezależnie od zmiany wartości
  digitalWrite(10, HIGH); 
  delay(1500); // ta przerwa na 1,5s nie działa
 }

 if (przeplyw > 411){ //pompa pracuje
  digitalWrite(10, HIGH); 
 }
 
 if (przeplyw > 51 && przeplyw < 410 ){ //zamknięcie kranu - wyłączenie pompy      na 5s zostaje wyłączona pompa niezależnie od zmiany wartości
  digitalWrite(10,LOW); 
  delay(5000); // ta przerwa na 5s nie działa
 }
 }

}

 

(edytowany)

A moze lepiej by bylo wywalic to przerwanie bo jest w tym kodzie nie potrzebne(przez sekunde i tak sprawdzasz tylko stan pinu, a po wejsciu do if przestajesz) i do if'ow dorzucic zmienna ktora bedzie zarzadzac w jakiej kolejnosci maja sie te if'y wykonywac??

Edytowano przez farmaceuta
(edytowany)
26 minut temu, farmaceuta napisał:

A moze lepiej by bylo wywalic to przerwanie bo jest w tym kodzie nie potrzebne(przez sekunde i tak sprawdzasz tylko stan pinu, a po wejsciu do if przestajesz) i do if'ow dorzucic zmienna ktora bedzie zarzadzac w jakiej kolejnosci maja sie te if'y wykonywac??

To przerwanie na 1s musi być bo bez tego są błędne dane z liczenia impulsów przepływu wody. Jak program wykonuje jeden z trzech warunków to cały czas monitor portu szeregowego pokazuje aktualne wartości zmieniające się co 1s.

Edytowano przez Krtstian
14 minut temu, Krtstian napisał:

To przerwanie na 1s musi być bo bez tego są błędne dane z liczenia impulsów przepływu wody. 

Pewnie dlatego ze kod wykonuje petle za szybko i podczas jednego impulsu ten zostaje wykryty kilka razy...mozna to rozwiazac tak..

if (czujnik == HIGH && stan == 0) {
  przeplyw++;
  stan = 1;
  }
if (czujnik == LOW) {
  stan = 0;
  }

Teraz jeden stan wysoki jest wykryty tylko raz..ponownie dopiero wtedy gdy przejdzie w niski i znow w wysoki...

Taki program zapewne przez ta sekunde wykona sie ciut wiecej razy niz 150 (impulsow)(1200l) 

26 minut temu, farmaceuta napisał:

Pewnie dlatego ze kod wykonuje petle za szybko i podczas jednego impulsu ten zostaje wykryty kilka razy...mozna to rozwiazac tak..


if (czujnik == HIGH && stan == 0) {
  przeplyw++;
  stan = 1;
  }
if (czujnik == LOW) {
  stan = 0;
  }

Teraz jeden stan wysoki jest wykryty tylko raz..ponownie dopiero wtedy gdy przejdzie w niski i znow w wysoki...

Taki program zapewne przez ta sekunde wykona sie ciut wiecej razy niz 150 (impulsow)(1200l) 

Dziękuję za radę. Wymyśliłem trochę inny sposób ale spróbuje też wykorzystać kod powyżej.

Dnia 2.04.2021 o 17:05, Krtstian napisał:

volatile int NbTopsFan; int przeplyw;

Jeśli później robisz działanie:

Dnia 2.04.2021 o 17:05, Krtstian napisał:

przeplyw = (NbTopsFan * 60 / 7.5);

To te zmienne powinny być typu float chociaż radzę unikać 😉

1 godzinę temu, _LM_ napisał:

To te zmienne powinny być typu float

A niby to dlaczego?

Ja bym raczej dał coś w stylu:

przeplyw = NbTopsFan * 8; // ciekawe, ile to jest 60/7.5

Jakby szybsze i na jedno wychodzi...

 

 

56 minut temu, ethanak napisał:

A niby to dlaczego?

Napisałem też trzeba unikać operacji na float a tego już nie zacytowałeś. 

 

57 minut temu, ethanak napisał:

Jakby szybsze i na jedno wychodzi...

Proste i skuteczne 

  • Lubię! 1
(edytowany)
9 minut temu, _LM_ napisał:

Napisałem też trzeba unikać operacji na float a tego już nie zacytowałeś. 

Chodziło mi dokładnie o to co napisałem: dlaczego Twoim zdaniem te zmienne powinny być typu float. Koniec. Kropka. Ja nie widzę powodu dlaczego miałyby być typu float, jeśli nawet gdzieś po drodze w obliczeniach ów float występuje, więc może wyjaśnisz dlaczego Twoim zdaniem jest inaczej. Tutaj jeśli nawet nie byłoby możliwe sprowadzenie działania do intów doczepiłbym się nawiasowania (bo może wystąpić przepełnienie), ale nie do typu zmiennych.

I nieważne czy trzeba floatów unikać czy nie, bo na małych Arduinkach owszem, ale np. na ESP32 ze sprzętowym wspomaganiem działań na floatach już nie. Tyle, że nie ma to nic do rzeczy.

Edytowano przez ethanak
  • Pomogłeś! 1
(edytowany)
27 minut temu, ethanak napisał:

Chodziło mi dokładnie o to co napisałem: dlaczego Twoim zdaniem te zmienne powinny być typu float

Bo nie każda liczba podzielona przez 8 da w wyniku liczbę naturalną a skoro kolega @Krtstian dzieli przez 7.5 to oznacza że spodziewa się wyniku zmiennoprzecinkowego

 przeplyw = (NbTopsFan * 60 / 7.5); 

Upssss tu jest mnożenie, przepraszam mój błąd. Faktycznie nie trzeba floatów zakręciłem się. Jeszcze raz przepraszam za zamiesznie

Edytowano przez _LM_
(edytowany)

Już tłumaczę z kąd to 7,5. 1l wody przepływający przez czujnik przepływu halla obraca łopatki tego czujnika 450 razy. 450 podzielone przez 60=1godzina, daje częstotliwość 7,5. Z tąd też wynik jest w l/h

Edytowano przez Krtstian
6 minut temu, Krtstian napisał:

 1l wody przepływający przez czujnik przepływu halla obraca łopatki tego czujnika 450 razy. 

Az tyle?? Z twojego kodu wynika ze jeden impuls na sekunde jest rowne 8 litrom na godzine..

(edytowany)

Ja sie pogubilem...😉 napisz konkretnie ile impulsow masz przy przeplywie jednego litra np. I cos sie wymysli z tym kodem...

Ok zalapalem...te 450 to jest ilosc impulsow w ciagu godziny przy przeplywie 1l/h..no i to by sie zgadzalo z powyzszym kodem...no i jakos rozwiazales problem kodu czy nie? I druga sprawa to z tego co mi wiadomo to funkcja delay() nie bedzie dzialac poprawnie po wywolaniu cli() bo wylaczasz wszystkie przerwania a delay() na nich dziala..

Edytowano przez farmaceuta
  • Lubię! 1
2 minuty temu, farmaceuta napisał:

Ja sie pogubilem...😉 napisz konkretnie ile impulsow masz przy przeplywie jednego litra np. I cos sie wymysli z tym kodem...

1l wody to 450 impulsów, 450 podzielone przez 60 daje częstotliwość 7,5 wyni w tedy jest w l/min a 7,5 razy 60 daje wtedy wynik w l/h

13 minut temu, farmaceuta napisał:

Ja sie pogubilem...😉 napisz konkretnie ile impulsow masz przy przeplywie jednego litra np. I cos sie wymysli z tym kodem...

Ok zalapalem...te 450 to jest ilosc impulsow w ciagu godziny przy przeplywie 1l/h..no i to by sie zgadzalo z powyzszym kodem...no i jakos rozwiazales problem kodu czy nie? I druga sprawa to z tego co mi wiadomo to funkcja delay() nie bedzie dzialac poprawnie po wywolaniu cli() bo wylaczasz wszystkie przerwania a delay() na nich dziala..

Kod poprawiłem w mniejszym stopniu, musze to jeszcze przetestować. W najbliższych dniach wstawie cały program.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...