Inkrementacja zmiennej

Masz problem, z którym nie możesz sobie poradzić? Pisz śmiało!
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 17 gru 2019, 19:57

Przychodzi mi do głowy coś takiego

Kod: Zaznacz cały

if(t < a) while(1);
while(1){}, to jest pętla nieskończona, jeśli coś takiego napiszesz w programie, to program już z tego nie wyjdzie i w praktyce będzie tak jakby się zatrzymał, bo i tak nic nie dasz do wykonywania w tej pętli.
while() różni się od if() tym, że jeśli w ifie będzie warunek zwracający prawdę, lub wartość 1, to if wykona się raz i program idzie dalej, a while jest wykonywany dopóki warunek jest prawdziwy, lub będzie wartość 1.
Ostatnio zmieniony 17 gru 2019, 20:11 przez stiven, łącznie zmieniany 1 raz.

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 17 gru 2019, 20:08

No ok a jak potem zmusić program do działania za pomocą przycisku?
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 17 gru 2019, 20:13

Aha, w ten sposób. To zaraz sprawdzę, wydaje mi się, że przerwać taką pętlę nieskończoną można funkcją break.
Ostatnio zmieniony 17 gru 2019, 20:26 przez stiven, łącznie zmieniany 1 raz.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 17 gru 2019, 20:17

Probowałem BREAK ale jak pisałeś wcześniej, że na arduino jest nakładka C więc nei zawsze wszystko dziala jak nalezy....
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 17 gru 2019, 20:25

Jako wyjście z nieskończonej pętli while, break działa.

Kod: Zaznacz cały

if(t < a) 
{
  while(1) if(digitalRead(przycisk1) == LOW || digitalRead(przycisk2) == LOW) break;
}

Jak if zadziała, to potem będzie się już wykonywać cały czas to co w while, czyli czekanie na przyciśnięcie któregoś z przycisków. Po naciśnięciu któregoś przycisku, zadziała break i program wyjdzie z while i zacznie działać normalnie, aż do następnego zadziałania ifa.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 17 gru 2019, 20:55

Działa to nawet:) Przycisk bez funkcji (tylko samo naciśnięcie) powoduje start programu. Dziękuję za wszelką pomoc :) będę działał z nowym projektem :)
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 17 gru 2019, 21:03

hazi18 pisze:
17 gru 2019, 20:55
Przycisk bez funkcji (tylko samo naciśnięcie) powoduje start programu.
Naciśnięcie któregoś przycisku powoduje zadziałanie funkcji break, która przerwie pętle nieskończoną, a do tego właśnie jest funkcja break.
Tu sobie przeczytaj o break i pętlach nieskończonych https://pl.wikibooks.org/wiki/C/Instruk ... uj%C4%85ce

Pętla loop jest w rzeczywistości pętlą nieskończoną i jeśli brake bezpośrednio w niej w ogóle zadziała, to spowoduje po prostu uruchomienie programu od początku, łącznie z setup i tym, co jest wcześniej.
Awatar użytkownika
Marhef
Złota rączka
Posty: 1236
Rejestracja: 18 lis 2011, 02:18

Re: Inkrementacja zmiennej

Post autor: Marhef » 18 gru 2019, 10:34

Żeby ponownie uruchomić program można też podłączyć przycisk do pinu reset i po prostu restartować arduino
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 9 sty 2020, 18:42

Hej,
szczęśliwego nowego roku wszystkim :)
Mam problem, znalazłem na forum kod (działający), który zlicza mi ilość przepłyniętej wody. Chciałem aby po jednoczesnym przepłynięciu 30 litrów program się wyłączył i woda przestała lecieć. Jednak mam dylemat, zostały rozpisane flowRate (nazwijmy to na 3 sposoby) i każdy z nim coś oznacza, poniżej jest użyty flowRate jednak skąd wiadomo który jest ten do zliczania ilości wody jeśli jeden to konwersja z ml na L ( domyślam się ze to w serialu są litry) a inna na czas (też w serialu to pokazuje?) Na załączniku jak to wygląda w serialu.

Kod: Zaznacz cały

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  
int przycisk = 3; 
void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  
  Serial.begin(9600);  //Start Serial
}
void loop() {
  // put your main code here, to run repeatedly:  
  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second 
  noInterrupts(); //Disable the interrupts on the Arduino
   
  //Start the math
  flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL 
  flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
  flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
 
  Serial.println(flowRate);         //Print the variable flowRate to Serial
 if(flowRate > 0,1) 
{
  while(1) if(digitalRead(przycisk) == LOW || digitalRead(przycisk) == LOW) break;
}
}
void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 10 sty 2020, 12:37

Z tego programu wynika, że żeby wyliczyć wartość w litrach, to potrzebne są te 3 operacje, ktoś to rozpisał na 3 linijki, ale mogłoby to być zapisane w jednej.

Kod: Zaznacz cały

  flowRate = ((count * 2.25) * 60)/1000;
tylko problem w tym, że program zlicza przepływ w danej sekundzie

Kod: Zaznacz cały

  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second 
  noInterrupts(); //Disable the interrupts on the Arduino
a w przerwaniu wykonywana jest funkcja

Kod: Zaznacz cały

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
i potem z ilości odebranych impulsów wyliczona jest ilość mililitrów, która przepłynęła przez sekundę (*2.25, nie wiem czemu akurat taka wartość, pewnie jest podana w dokumentacji czujnika), potem wyliczona ilość mililitrów jaka przepłynie przez minutę (*60), a potem zamieniona ta ilość mililitrów na litry na minutę (/1000). Czyli ta wartość flowRate nie jest ostatecznie ilością litrów, która przepłynęła, tylko mniej więcej informacją ile litrów przepłynie przez minutę, po obliczeniu szybkości przepływu w danej sekundzie.


Teoretycznie taki program liczyłby rzeczywisty przepływ i sprawdzał czy przepłynęło już 30 litrów

Kod: Zaznacz cały

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  
int przycisk = 3; 
void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  
  Serial.begin(9600);  //Start Serial
}
void loop() {
  // put your main code here, to run repeatedly:  
  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  
  while(1)
  {
    flowRate = (count * 2.25)/1000;
    Serial.println(flowRate);         //Print the variable flowRate to Serial
	
    if(flowRate >= 30) 
    {
      //wyłączenie przepływu wody
    }
	
    if(digitalRead(przycisk) == LOW) 
    {
      noInterrupts(); //Disable the interrupts on the Arduino
      break;
    }
  }
  
}
void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
Ostatnio zmieniony 10 sty 2020, 23:04 przez stiven, łącznie zmieniany 1 raz.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 10 sty 2020, 15:18

@Stiven Dzięki za szybką odpowiedź, niestety teraz nie liczy mi nic jak sprawdzam przepływ. Czy jeśli zostało to tak napisane (chodzi mi o flowRate) to jest możliwość aby jedna dana została wyświetlona na wyświetlaczu jako całkowity przepływ wody ( sumujący się od dnia działania programu), a druga dana flowRate liczyłaby tylko aktualny przepływ?
W chlewni mam karmiki z poidłami dla świń i chcę aby program monitorował przepływ wody na zasadzie, jeśli awaria (woda leci ciągle) to ma odciąć dopływ wody poprzez elektrozawór po upływie np. 30 litrów ciągłego przepływu wody. Po usunięciu awarii przyciskiem uruchamiam program i znowu działa.
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 10 sty 2020, 23:05

Nie usunąłem jednej linijki gdzie była wcześniej, bo teraz jest w innym miejscu. Poprawiłem w poprzednim komentarzu kod. Zobacz jak to będzie teraz działać. Jak będzie dobrze, to pomyślimy jak to połączyć w jeden program.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 11 sty 2020, 09:16

sprawdziłem i nadal nie liczy, wywaliłem pętlę while i nadal nie zlicza, jedyną różnicę to widzę, że usunąłeś kod

Kod: Zaznacz cały

 delay (1000);   //Wait 1 second 
  noInterrupts(); //Disable the interrupts on the Arduino
Dlaczego?
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 11 sty 2020, 12:58

hazi18 pisze:
11 sty 2020, 09:16
sprawdziłem i nadal nie liczy, wywaliłem pętlę while i nadal nie zlicza, jedyną różnicę to widzę, że usunąłeś kod

Kod: Zaznacz cały

 delay (1000);   //Wait 1 second 
  noInterrupts(); //Disable the interrupts on the Arduino
Dlaczego?
Wcześniej było tak:

Kod: Zaznacz cały

  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second 
  noInterrupts(); //Disable the interrupts on the Arduino
czyli włączane było przerwanie, zatrzymywane działanie programu na sekundę i potem wyłączenie przerwanie. Przez tą sekundę, chociaż program był zatrzymany, to "w tle" działało przerwanie(tak działają właśnie przerwania, bez względu na to, co dzieje się w głównym programie) czyli po otrzymaniu impulsu z czujnika wywoływana jest funkcja

Kod: Zaznacz cały

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
zmienna count była zwiększana o 1 przy otrzymaniu impulsu od czujnika przepływu. Jeśli chciałoby się zrobić zliczanie przepływu łącznego, to takie rozwiązanie pomijałoby część impulsów w czasie, kiedy przerwanie będzie wyłączone. No ale jakoś nie chce to działać.

Myślałem teraz o zastosowaniu millis() zamiast delay() i akurat też znalazłem w internecie program, w którym właśnie to millis() jest wykorzystane do obliczania przepływu z odebranych impulsów z tego czujnika.
http://www.hobbytronics.co.uk/yf-s201-water-flow-meter
http://www.hobbytronics.co.uk/download/YF-S201.ino
Tutaj obliczany jest przepływ w ciągu godziny, ale to nie ma znaczenia, to samo można zastosować do zliczania przepływu przez minutę tak jak wcześniej miałeś i przy okazji nie ma tu tej wady, że gubione byłoby część impulsów i da się obliczyć rzeczywisty łączny przepływ. I tak może teraz wyglądać Twój program:

Kod: Zaznacz cały

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  
int przycisk = 3; 
unsigned long currentTime;
unsigned long cloopTime;
double razem = 0;
double razem_litrow = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  
  Serial.begin(9600);  //Start Serial
  
  interrupts();   //Enables interrupts on the Arduino
  currentTime = millis();
  cloopTime = currentTime;
}
void loop() {
  currentTime = millis();
  
  if(currentTime >= (cloopTime + 1000))
  {     
    cloopTime = currentTime;              // Updates cloopTime
	
    flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL 
    razem = razem + flowRate;
    razem_litrow = razem/1000;
    flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
    flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
	
    count = 0;      // Reset the counter so we start counting from 0 again
	
    Serial.print(flowRate);
    Serial.println(" litrów na minutę");
	
    Serial.print(razem_litrow);
    Serial.println(" litrów łącznie");
  }  
    
}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
Jak ten łączny przepływ będzie działać dobrze, to można zrobić tak to zabezpieczenie przy przepływie 30 litrów w ciągu minuty

Kod: Zaznacz cały

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  
int przycisk = 3; 
unsigned long currentTime;
unsigned long cloopTime;
unsigned long pTime;
double razem = 0;
double razem_litrow = 0;
double p_razem = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  
  Serial.begin(9600);  //Start Serial
  
  interrupts();   //Enables interrupts on the Arduino
  currentTime = millis();
  cloopTime = currentTime;
}
void loop() {
  currentTime = millis();
  
  if(currentTime >= (cloopTime + 1000))
  {     
    cloopTime = currentTime;              // Updates cloopTime
	
    flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL 
    razem = razem + flowRate;
    razem_litrow = razem/1000;
    flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
    flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
	
    count = 0;      // Reset the counter so we start counting from 0 again
	
    Serial.print(flowRate);
    Serial.println(" litrów na minutę");
	
    Serial.print(razem_litrow);
    Serial.println(" litrów łącznie");
  }  
    
  if(currentTime >= (pTime + 60000))	//60000 to minuta
  {
    pTime = millis();
	
    if(razem > (p_razem + 30000/2.25))	//30000 ml, czyli 30 litrów, if wykona się, jeśli w ciągu ostatniej minuty przepłynęło więcej niż 30 litrów wody
    {  
      while(1) 
      if(digitalRead(przycisk) == LOW)
      {
        //wyłączenie przepływu wody
        break;
      }
    }
    p_razem = razem;
  }  
}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 13 sty 2020, 19:27

Hej,
Działa tak jak pisałeś, pokazuje litrów na minutę oraz łącznie. Nie wiem czy dobrze mnie zrozumiałeś, mi chodzi o ciągłe 30l wody gdyby leciało.
Tłumaczę co mam na myśli, świnki pobierają sobie wodę spokojnie przez poidełko, ja powiedzmy napuszczam do wiadra 10l wody ( czyli woda leci ciągle). Zakręcam kurek i ok. ale gdyby była awaria smoczka, że woda leci ciągle( nieprzerwanie) i gdy "ucieknie" 30l. to wtedy program powinien dać sygnał do elektrozaworu "zamknij się" i program kończy swe działanie (liczenie przepływu). Po usunięciu awarii przyciskam start i program daje znać do elektrozaworu "otwórz się" i woda leci. Tylko pytanie brzmi, jak zrobić z ciągłościa wody? Czy obliczyć czas w jaki przepłynie woda w ilości 30l i uzależnić od tego czasu, czy wystarczy wpisać 30l ciągłego poboru wody i program sie zatrzymuje?
znalazłem takie dane tej przepływki
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 14 sty 2020, 13:55

No to może zrobić dodatkowe trzecie zliczanie, które będzie zliczaniem ciągłego przepływu, ale w momencie jeśli w danej sekundzie nie będzie w ogóle przepływu, to zliczanie do 30 litrów zacznie się od nowa?

Kod: Zaznacz cały

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  
int przycisk = 3; 
unsigned long currentTime;
unsigned long cloopTime;
double razem = 0;
double razem_litrow = 0;
double p_razem = 0;
double p_razem_litrow = 0;


void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  
  Serial.begin(9600);  //Start Serial
  
  interrupts();   //Enables interrupts on the Arduino
  currentTime = millis();
  cloopTime = currentTime;
}
void loop() {
  currentTime = millis();
  
  if(currentTime >= (cloopTime + 1000))
  {     
    cloopTime = currentTime;              // Updates cloopTime
	
    flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL 
	
    razem = razem + flowRate;
    razem_litrow = razem/1000;
	
    if(flowRate == 0) p_razem = 0;		//jeśli brak przepływ, wyzerowanie zmiennej zliczającej jednorazowy przepływ
    else p_razem = p_razem + flowRate;	//w innym przypadku dodanie aktualnego chwilowego przepływu
    p_razem_litrow = p_razem/1000;
	
    flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
    flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
	
    count = 0;      // Reset the counter so we start counting from 0 again
	
    Serial.print(razem_litrow);
    Serial.println(" litrów łącznie");
	
    Serial.print(flowRate);
    Serial.println(" litrów na minutę");
	
    Serial.print(p_razem_litrow);
    Serial.println(" litrów aktualnego przepływu");
  }  
  
    
  if(p_razem > 30000/2.25)	//jeśli jednorazowy przepływ większy niż 30 litrów
  {  
    p_razem = 0;	//wyzerowanie zmiennej zliczającej jednorazowy przepływ
    while(1) 	//pętla nieskończona
    if(digitalRead(przycisk) == LOW)	//oczekiwanie na wciśnięcie przycisku
    {
      //wyłączenie przepływu wody
      break;	//wyjście z pętli nieskończonej
    }
  }
 
}

void Flow()
{
  count++; //Every time this function is called, increment "count" by 1
}
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 14 sty 2020, 18:47

Tak zliczanie powinno zacząć się od nowa bo nie mogę pozwolić na to aby świnie miały przerwaną dostawę wody jeśli nie będzie awarii. Pomyślałem sobie dzisiaj, że jeśli na tym czujniku jest maksymalny przepływ 25l/min to jeśli ja chcę ustawić 30l to należałoby obliczyć w jakim czasie przepłynie te 30l i od czasu uzależnić wyłączenie dopływu wody. Nie wiem czy dobrze myślę.
NA podstawie Twojego kodu (zmieniłem przepływ na 1l) doszedłem w ciągu 2 sek ( zmieniłem czas) do ponad 1l przepływu jednorazowego ale program się nie zatrzymał. Czy to zerowanie powinno tutaj być? Bo wydaje mi się, że ono zeruje i dlatego nigdy program się nie zatrzyma.

Kod: Zaznacz cały

 if(p_razem > 1000/2.25)  //jeśli jednorazowy przepływ większy niż 30 litrów
  {  
    p_razem = 0;  //wyzerowanie zmiennej zliczającej jednorazowy przepływ
    while(1)  //pętla nieskończona
    if(digitalRead(przycisk) == LOW)  //oczekiwanie na wciśnięcie przycisku
    {
      //wyłączenie przepływu wody
      break;  //wyjście z pętli nieskończonej
    }
  }
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 14 sty 2020, 21:14

To zerowanie zmiennej jest dobrze tak. Tymi 25 litrami chyba nie ma się co przejmować. Na serialu zeruje się pewnie zliczanie? Nie ma pinMode() w setup() dla pinu z przyciskiem, to pewnie dlatego program nie zatrzymuje się. Dodaj i powinno już być już dobrze.

Kod: Zaznacz cały

pinMode(przycisk, INPUT_PULLUP);
EDIT

Pisałem wcześniej na telefonie na szybko. Teraz trochę dopiszę.

Po zerowaniu zmiennej jest while(1), i tak program wejdzie w tą pętlę nieskończoną i będzie zatrzymanie w niej programu i oczekiwanie na wciśnięcie przycisku. Można ewentualnie dać to zerowanie po while, ale to niczego nie zmieni. Właściwie wyłączenie zaworu też lepiej dać przed while, bo niepotrzebnie będzie się to tam w kółko wykonywać. Prawdopodobnie przez brak pinMode() było od razu wychodzenie z while, bo pin nie był prawidłowo ustawiony. I właściwie tam powinno być INPUT_PULLUP, a nie samo INPUT, poprawiłem.

Ten zakres 1-25l/min, to moim zdaniem dotyczy tego, co czujnik jest w stanie zliczyć, czyli nie może być za małe ciśnienie wody ani za duże. Jeśli będzie zbyt duże ciśnienie i w ciągu minuty przepłynie więcej niż 25 litrów, to czujnik już tego nie będzie w stanie wykryć, policzyć. Więc najlepiej, żebyś miał przepływ przynajmniej trochę większy niż 1 litr i na przykład nie większy niż 24 litry ma minutę, to wtedy będzie to prawidłowo zliczane.

Kod: Zaznacz cały

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  
int przycisk = 3; 
unsigned long currentTime;
unsigned long cloopTime;
double razem = 0;
double razem_litrow = 0;
double p_razem = 0;
double p_razem_litrow = 0;


void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  pinMode(przycisk, INPUT_PULLUP);
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  
  Serial.begin(9600);  //Start Serial
  
  interrupts();   //Enables interrupts on the Arduino
  currentTime = millis();
  cloopTime = currentTime;
}
void loop() {
  currentTime = millis();
  
  if(currentTime >= (cloopTime + 1000))
  {     
    cloopTime = currentTime;              // Updates cloopTime
	
    flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL 
	
    razem = razem + flowRate;
    razem_litrow = razem/1000;
	
    if(flowRate == 0) p_razem = 0;		//jeśli brak przepływ, wyzerowanie zmiennej zliczającej jednorazowy przepływ
    else p_razem = p_razem + flowRate;	//w innym przypadku dodanie aktualnego chwilowego przepływu
    p_razem_litrow = p_razem/1000;
	
    flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
    flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
	
    count = 0;      // Reset the counter so we start counting from 0 again
	
    Serial.print(razem_litrow);
    Serial.println(" litrów łącznie");
	
    Serial.print(flowRate);
    Serial.println(" litrów na minutę");
	
    Serial.print(p_razem_litrow);
    Serial.println(" litrów aktualnego przepływu");
  }  
  
    
  if(p_razem > 30000/2.25)	//jeśli jednorazowy przepływ większy niż 30 litrów
  {  
    p_razem = 0;	//wyzerowanie zmiennej zliczającej jednorazowy przepływ
	//wyłączenie przepływu wody
    while(1) 	//pętla nieskończona
    if(digitalRead(przycisk) == LOW)	//oczekiwanie na wciśnięcie przycisku
    {
      break;	//wyjście z pętli nieskończonej
    }
	//włączenie przepływu wody
  }
  
 }

void Flow()
{
  count++; //Every time this function is called, increment "count" by 1
}
Aha, przydałoby się jeszcze dodać wyłączenie i włączenie przerwania, zapisanie czasu z millis() do zmiennej i wyzerowanie zmiennej count.

Kod: Zaznacz cały

if(p_razem > 30000/2.25)	//jeśli jednorazowy przepływ większy niż 30 litrów
  {  
    p_razem = 0;	//wyzerowanie zmiennej zliczającej jednorazowy przepływ
    noInterrupts();
	//wyłączenie przepływu wody
    while(1) 	//pętla nieskończona
    if(digitalRead(przycisk) == LOW)	//oczekiwanie na wciśnięcie przycisku
    {
      break;	//wyjście z pętli nieskończonej
    }
	//włączenie przepływu wody
   count = 0;
   cloopTime = millis();
   interrupts();
  }
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 15 sty 2020, 19:16

Hej,
Zastosowałem się do Twoich zmian i osiągnąłem aktualny przepływ ponad 1l ( znowu zmieniłem dane do testów) i program się nie zatrzymał mimo zaimplementowania kawałka kodu o przycisku. Nie mam pojęcia co jest grane...
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 16 sty 2020, 01:09

A zeruje się wartość aktualnego przepływu wyświetlana na serial? Jeśli tak, to może pinMode() nie dodałeś, albo do tego pinu 3 od przycisku masz coś źle połączone, że jest od razu wyjście z while.
Jeśli się nie zeruje, to sprawdź tak napisanego ifa

Kod: Zaznacz cały

  if(p_razem_litrow > 30.0)	//jeśli jednorazowy przepływ większy niż 30 litrów (dla litra 1.0 zamiast 30.0)
  {  
    p_razem = 0;	//wyzerowanie zmiennej zliczającej jednorazowy przepływ
    p_razem_litrow = 0; 
    noInterrupts();
	//wyłączenie przepływu wody
    while(1) 	//pętla nieskończona
    if(digitalRead(przycisk) == LOW)	//oczekiwanie na wciśnięcie przycisku
    {
      break;	//wyjście z pętli nieskończonej
    }
	//włączenie przepływu wody
   count = 0;
   cloopTime = millis();
   interrupts();
  }
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 16 sty 2020, 18:51

Hej, dzięki za pomoc, nadal nie zatrzymuje się. Osiągnąłem 1 litrów i dalej hula program. Testowałem z zakomentowaniem p_razem=0; i program zatrzymuje się. Więc przypuszczam, ze problem leży przy tym zerowaniu. Albo przez to zerowanie nie zatrzymuje się ( za szybko się zeruje i program leci dalej, choć na screenie jest ponad 1l aktualnego przepływu) lub przed zerowaniem może jakiś warunek sprawdzający i w nim zerowanie? Nie wiem czy tak można robić :)
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 17 sty 2020, 12:32

Dziwne to jest. Nie może tak być, że zmiana wartości zmiennej w pierwszej linijce w ifie, występującej też w warunku ifa, powodowała, że już pozostała część ifa się nie wykona. Przenieś niżej to zerowanie, za linijkę z count = 0; może to coś zmieni.

Widzę też po tych wartościach z seriala, że zerowanie było wcześniej niż przed przepływem 1 litra. Jest "0.59 litrów aktualnego przepływu", potem "1.21" i musiało być zerowanie pomiędzy, czyli poniżej 1 litra, bo "litrów łącznie" zwiększa się właśnie o wartość 1.21 - z 1.29 do 2.50. Powinna wyświetlić się suma 0.59 i 1.21 "litrów aktualnego przepływu" (1.80) i dopiero wtedy zatrzymanie programu i wyzerowanie.

Jeszcze kolejna rzecz, "34.29 litrów na minutę", "72 litrów na minutę". To są te wartości, które nie powinny przekroczyć 25 litrów według Twojego obrazka. Patrzę po poprzednich komentarzach i nigdzie nie napisałeś jaki masz ten czujnik przepływu. Ja chyba po kodzie programu wcześniej znalazłem, że to może być YF-S201, ale on zlicza przepływ do 30l/minutę. Ty dałeś obrazek, że do 25 litrów. Ale po tych wartościach widać, że jednak masz inny czujnik, bo nawet 72 litry obliczone, więc to chyba jest czujnik do 100 litrów na minutę. Gdyby to był czujnik do 25 litrów, to przy większym przepływie i tak powinna być obliczana wartość 25, a nie większa, albo jest jakiś błąd w kodzie, że takie wartości są obliczane, lub ja źle rozumiem ten maksymalny przepływ jaki może być wykryty przez czujnik.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 17 sty 2020, 14:57

Dokładnie mam taki czujnik. Kod sprawdzę później.
https://termoregulatory.pl/pl/przeplywo ... cp1-2.html
stiven
Złota rączka
Posty: 1629
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 18 sty 2020, 12:38

I jak?
Możesz zobaczyć czy lepiej będzie przy tak napisanym programie

Kod: Zaznacz cały

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  
int przycisk = 3; 
unsigned long currentTime;
unsigned long cloopTime;
double razem = 0;
double razem_litrow = 0;
double p_razem = 0;
double p_razem_litrow = 0;
boolean blokada = 0;


void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  pinMode(przycisk, INPUT_PULLUP);
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  
  Serial.begin(9600);  //Start Serial
  
  interrupts();   //Enables interrupts on the Arduino
  currentTime = millis();
  cloopTime = currentTime;
}
void loop() {
  currentTime = millis();
  
  if(currentTime >= (cloopTime + 1000))
  {     
    cloopTime = currentTime;              // Updates cloopTime
	
    flowRate = (count * 2.25);        //Take counted pulses in the last second and multiply by 2.25mL 
	
    razem = razem + flowRate;
    razem_litrow = razem/1000;
	
    if(flowRate == 0) p_razem = 0;		//jeśli brak przepływ, wyzerowanie zmiennej zliczającej jednorazowy przepływ
    else p_razem = p_razem + flowRate;	//w innym przypadku dodanie aktualnego chwilowego przepływu
    p_razem_litrow = p_razem/1000;
	
    flowRate = flowRate * 60;         //Convert seconds to minutes, giving you mL / Minute
    flowRate = flowRate / 1000;       //Convert mL to Liters, giving you Liters / Minute
	
    count = 0;      // Reset the counter so we start counting from 0 again
	
    Serial.print(razem_litrow);
    Serial.println(" litrów łącznie");
	
    Serial.print(flowRate);
    Serial.println(" litrów na minutę");
	
    Serial.print(p_razem_litrow);
    Serial.println(" litrów aktualnego przepływu");

  }  
  
  if(p_razem_litrow > 30.0) blokada = 1;   //jeśli jednorazowy przepływ większy niż 30 litrów (dla litra 1.0 zamiast 30.0)
  
  if(blokada == 1)	
  {  
    noInterrupts();
	//wyłączenie przepływu wody
    while(blokada == 1) 	
    if(digitalRead(przycisk) == LOW)	//oczekiwanie na wciśnięcie przycisku
    {
      blokada = 0;
    }
	//włączenie przepływu wody
   count = 0;
   p_razem = 0;	//wyzerowanie zmiennej zliczającej jednorazowy przepływ
   p_razem_litrow = 0; 
   cloopTime = millis();
   interrupts();
  }
  
 }

void Flow()
{
  count++; //Every time this function is called, increment "count" by 1
}
Wydaje mi się, że przy Twoim czujniku zamiast linijki

Kod: Zaznacz cały

  flowRate = (count * 2.25);  
powinno być

Kod: Zaznacz cały

  flowRate = (count * 1.65);  
bo skoro 606 impulsów na litr (1000 ml), to 0.606 impulsu, to 1 ml, a wtedy 1 impuls to 1.65 ml. Chociaż i tak te wartości będą za duże, 72 litry zmniejszyłyby się na 53.

Chociaż porównując z tym
http://www.hobbytronics.co.uk/yf-s201-water-flow-meter
http://www.hobbytronics.co.uk/download/YF-S201.ino
to wychodzi, że powinno być

Kod: Zaznacz cały

  flowRate = (count/11);  
Sprawdź, czy w którymś przypadku wartości wyświetlane są zbliżona do ilości wody, która przepłynęła. Ta linijka ma wpływ na wszystkie 3 wyświetlane wartości.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 19 sty 2020, 21:59

Hej, "przepływ wody" testuję poprzez dmuchanie w czujnik :) narazie tylko tak sprawdzam czy jak leci i dojdzie do wartości czy program się zatrzyma.
Próbowałem Twój kod ( po zmianie wartości 2.25 na 1.65) nadal nie blokuje programu po osiągnięciu wartości podaje w if.
I nie wiem czemu miałem głupie błędy, że nie zadeklarowano zmiennych i musiałem je zadeklarować

Kod: Zaznacz cały

int flowPin;
float flowRate;
int count;
co miałby oznaczać?

Kod: Zaznacz cały

 flowRate = (count/11); 
ODPOWIEDZ

Strony partnerskie: