Skocz do zawartości

Odniesienie się do konkretnego obiegu pętli for


Philip

Pomocna odpowiedź

#define PRZYCISK 6
#define LED 7
#define BUZZER 8
#define WYJ 9

#include "Bounce2.h"
Bounce debouncer = Bounce();                                            //Debouncing

enum {
  czyWcisnietoPrzycisk = 1,
  zapytanie1,
  zapytanie2,
  alarm1,
  stopAlarm,
  alarm2,
  podanieNapiecia,
  oczekiwanieNaWylaczenie,
  czyWylaczyc
};
boolean state = false;
int stan = 1;
String odebraneDane = "";

int aktualnyCzas = 0;
int zapamietanyCzas = 0;
int zapamietanyCzas2 = 0;

void setup() {
  Serial.begin(9600); //Inicjalizacja komunikacji szeregowej

  //Deklaracja 
  pinMode(PRZYCISK,INPUT_PULLUP);
  pinMode(LED,OUTPUT);
  pinMode(BUZZER,OUTPUT);
  pinMode(WYJ,OUTPUT);

  debouncer.attach(PRZYCISK);
  debouncer.interval(5);

  digitalWrite(LED,!state);     //Test leda i buzzera
  digitalWrite(BUZZER,!state);
  delay(1000);
  digitalWrite(LED,state);
  digitalWrite(BUZZER,state);
  delay(1000);
}

void loop() {
  aktualnyCzas = millis();
  debouncer.update();
  int wartosc = debouncer.read();
    if(Serial.available()>0) {
    odebraneDane = Serial.readStringUntil('\n');
  }
      
      switch(stan){ 
    case czyWcisnietoPrzycisk:
    if(aktualnyCzas - zapamietanyCzas == 5000UL){
      zapamietanyCzas = aktualnyCzas;
      Serial.println("...");
    }
    if(wartosc == LOW){
    stan = zapytanie1;
  }
  break;

 /////////////////////////////////////////////////////

  case zapytanie1:
 if(aktualnyCzas - zapamietanyCzas == 5000UL){
      zapamietanyCzas = aktualnyCzas;
      Serial.println("Do you want to switch on the power supply?");
    }
 if(odebraneDane == "yes"){
    Serial.println("Attention! The power supply will be switched on!");  //Akceptacja zapytania 
    stan = zapytanie2;
 }

 if(odebraneDane == "no"){
    Serial.println("Mistake! I go to observance state.");
    stan = czyWcisnietoPrzycisk; 
}   
  break;

 /////////////////////////////////////////////////////
 
  case zapytanie2: 
 if(aktualnyCzas - zapamietanyCzas == 5000UL){
      zapamietanyCzas = aktualnyCzas;
      Serial.println("230V will be switched on! Keep hands out of metal and live parts. Please accept.");
    }
 if(odebraneDane == "ok"){
  zapamietanyCzas = aktualnyCzas;
    Serial.println("Accepted");
    stan = alarm1;
   }
  break;

    
 /////////////////////////////////////////////////////
 
  case alarm1:
 for(int t=0;t<6;t++){
  if(aktualnyCzas - zapamietanyCzas2 == 1000UL){
    Serial.println("hmm");
    zapamietanyCzas2 = aktualnyCzas;
    state = !state;
    digitalWrite(BUZZER,state); 
    } 
   if(t==6){
      stan = stopAlarm;
    }
  } 
  break;

 /////////////////////////////////////////////////////
   
  case stopAlarm:
  //noTone(BUZZER);
  digitalWrite(BUZZER,LOW);
  stan = alarm2;
  break;

 /////////////////////////////////////////////////////
 
  case alarm2:
  int i;
  if(aktualnyCzas - zapamietanyCzas == 1000UL){
    i++;
    zapamietanyCzas = aktualnyCzas;
    state = !state;
    digitalWrite(LED,state);
    } 
   if(i==6){
   stan = podanieNapiecia;
   }
 break;

 /////////////////////////////////////////////////////
 
 case podanieNapiecia:
 Serial.println("jest");
 //digitalWrite(WYJ,HIGH);
  stan = oczekiwanieNaWylaczenie;
  break;

 /////////////////////////////////////////////////////

 case oczekiwanieNaWylaczenie:
 if(wartosc == LOW){
  stan = czyWylaczyc;
 }
 break;

 /////////////////////////////////////////////////////

 case czyWylaczyc:
 if(aktualnyCzas - zapamietanyCzas == 5000UL){
      zapamietanyCzas = aktualnyCzas;
      Serial.println("Are you sure to switch off the power supply?");
    }
     
    if(odebraneDane == "yes"){
  Serial.println("nie ma");
  //digitalWrite(WYJ,LOW);
  stan = czyWcisnietoPrzycisk;
 }
 
 if(odebraneDane == "no"){
  Serial.println("There was mistake. I go back to work state.");
  stan = alarm2;
 }
 break;

 /////////////////////////////////////////////////////
   } 
  }

Wrzucam cały kod. Próbowałem różnych rzeczy. Ciekawi mnie dlaczego cały czas jest ta pętla for i jeszcze z takim kilkusekundowym opóźnieniem zanim się rozpocznie.

Link do komentarza
Share on other sites

Spróbuję przerobić cały kod na kod z przerwaniami. Możliwe, że kod się dziwnie zatrzymuje w niektórych stanach i nie umie od razu w nie wejść. 

Link do komentarza
Share on other sites

Zmienne typu int i oraz t muszą być zadeklarowane jako globalne, nie lokalne dla pętli for czy danego stanu, bo cały czas się zerują. W każdym nowym obiegu ich wartość jest zero. Wrzuciłem sobie wszystko do seriala i ładnie widać co się dzieje. Druga sprawa zapis inkrementacji i++ nie działa, ale to już nieważne.  Wrzucam kawałek kodu jak to wygląda, jak by ktoś miał podobny problem. 😉

int i = 0;
int t = 0;

void setup () {
...
  }
void loop (){
  ...
    case jakisStan: 
 if(aktualnyCzas - zapamietanyCzas == 1000UL){
    i = i+1;
    zapamietanyCzas = aktualnyCzas;
    state = !state;
    digitalWrite(LED,state);
    Serial.println(i); 
   if(i==7){
   stan = podanieNapiecia;
   digitalWrite(LED,LOW);
      }
    }  
  break;
  ...
}

Sam sobie poradziłem. Przerwania też pomogły, więc problemu już nie ma. Dzięki za pomoc  🙂 @Elvis @ethanak i @Hudyvolt

Pozdrawiam

Philip

Link do komentarza
Share on other sites

31 minut temu, Philip napisał:

globalne, nie lokalne dla pętli for czy danego stanu, bo cały czas się zerują.

Mogą być statyczne. Poza tym nie tyle się zerują, co dostają jakąś śmieciową wartość (zmienne lokalne nie zerują się jeśli im explicite nie każesz), a że to zero... cóż, szansa jak 1 do 65536 🙂

32 minuty temu, Philip napisał:

Druga sprawa zapis inkrementacji i++ nie działa,

Popsułeś kompilator? 🙂

A tak na poważnie: jak to nie działa? Możesz podać kawałek kodu z wyprintowanymi wartościami i przed i po inkrementacji?

 

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)

Aktualny kod jak powyżej, a serial port:

...
...
Do you want to switch on the power supply?
Attention! The power supply will be switched on!
230V will be switched on! Keep hands out of metal and live parts. Please accept.
Accepted
0
1
2
3
4
5
1
2
3
4
5
6
7
jest

Wcześniejszego kodu nie mam, bo wszystko w jednym sketchu😁, ale było coś takiego dla tych dwóch stanów (od buzzera i ledzika):

 case alarm1:
  int t = 0;
 for(t;t>=6;t++){
  if(aktualnyCzas - zapamietanyCzas == 1000UL){
    Serial.println(t);
    zapamietanyCzas = aktualnyCzas;
    state = !state;
    digitalWrite(BUZZER,state);
    if(t>=6){
      stan = alarm2;
      digitalWrite(BUZZER,LOW);
    }
  }  
 }
  break;

 /////////////////////////////////////////////////////
 
  case alarm2:
  int i = 0;
for(i;i>=6;i++){
  if(aktualnyCzas - zapamietanyCzas == 1000UL){
    zapamietanyCzas = aktualnyCzas;
    state = !state;
    digitalWrite(LED,state);
    Serial.println(i); 
   if(i==7){
   stan = podanieNapiecia;
   digitalWrite(LED,LOW);
      }
    } 
}
 break;

Serial wyglądał tak:

...
Do you want to switch on the power supply?
Attention! The power supply will be switched on!
230V will be switched on! Keep hands out of metal and live parts. Please accept.
Accepted
0
0
0
0
0
0
0
0
0
0  
  

Program cały czas był w jednym miejscu i wyświetlały się zera i buzzer cały czas brzęczał i nie było wyjścia z pętli for i przejścia do stanu alarm2 diody

Edytowano przez Philip
Link do komentarza
Share on other sites

Hm... a jak to miało Twoim zdaniem działać?

 

for(i;i>=6;i++){
  

To znaczy:

  1. zrób coś ze zmienną i (nie wiadomo co, pewnie nic)
  2. sprawdź, czy i jest większe lub równe sześć; jeśli nie to wyjdź z pętli
  3. a na końcu pętli zwiększ i o jeden

Czyli jeśli i dostało wartość zero gdzieś tam z jakichś przyczyn wcześniej, to nie będzie ani większe ani równe sześć (nawet jeśli to będzie takie małe, maciupcie sześć) - i pętla się nie wykona.

Może miałeś na myśli coś takiego:

for (i=0; i<=6; i++) {

co?

Link do komentarza
Share on other sites

(edytowany)

Tak moja pomyłka i tak też było wcześniej w kodzie. Teraz tylko przepisywałem to dla poprzedniego posta.

Edytowano przez Philip
Link do komentarza
Share on other sites

A tak przy okazji to kompilator nic nie mówił na temat zmiennych dynamicznych wstawianych po case? Czy może wyłączyłeś ostrzeżenia kompilatora albo uznałeś te czerwone napisy za mało interesujące?

 

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.