Wątek przeniesiony 2018-12-15 16:58 z C/C++ przez furious programming.

Jak sprawdzić czy zmienna zmieniła stan?

0

Chciałbym aby w konsoli wypisało mi raz kiedy zmienna zmieni stan z 0 na 1 i z 1 na 0. Co zmienić w kodzie bo cały czas wywala stan zmiennej, a chciałbym tylko raz powiadomienie gdy zmieni stan

boolean status_pojemnika;
boolean stan=false;
int czujnik_SW520D = 2;

void setup() {
     pinMode(czujnik_SW520D, INPUT);
     Serial.begin(9600);
}

void loop() {

    while(1){
      
      status_pojemnika=stan;

      boolean odczyt = digitalRead(czujnik_SW520D);
    
        if(odczyt == 0){
          status_pojemnika = !status_pojemnika;
        }

        if(stan != status_pojemnika){
          Serial.println("przewrocil sie");
        }else{
          Serial.println("jest ok");
        }

    delay(500);
    } 
}
2

Nie widzę innej opcji, jak dokonać pomiaru raz przed pętlą, ustawić zmienną pomocniczą (wystarczy jedna) i teraz rozpocząc nieskończoną pętlę. Kod jest równoważny, bo, jak wiadomo, jeden plus nieskończoność = nieskończoność:)

void loop() {
	boolean odczyt;
	boolean stan;
	odczyt = digitalRead(czujnik_SW520D);
	if (odczyt) stan = 1; else stan = 0;
	delay(500);
    while(1){

        odczyt = digitalRead(czujnik_SW520D);

        if(odczyt){
			if (stan){
				delay(500);
				continue;
				}
			else{
				stan = 1;
				print("Change!\n");
				delay(500);
				continue;
			}
        }
		else {
			if (! stan){
				delay(500);
				continue;
			}
			else{
				stan = 0;
				print("Change!\n");
				delay(500);
				continue;
			}	
        } 
	}
}
0

Możesz też cały czas posiadać dwie zmienne i traktować je jak taki mały bufor cykliczny. Jedna zmienna przechowuje stan bieżący, a druga poprzedni. Przed modyfikacją najpierw przepisujesz wartość z jednej zmiennej do drugiej, a następnie wpisujesz nową wartość do tej pierwszej. Dość proste rozwiązanie:

boolean status_prev = false;  // poprzedni stan
boolean status_curr = false;  // bieżący stan

// pobranie nowej wartości
status_prev = status_curr;
status_curr = digitalRead(czujnik_SW520D);

Te dwie instrukcje będą szły ze sobą w parze, więc nie będziesz musiał jednej wykonywać przed np. pętlą, a drugiej po. Ewentualnie możesz sobie napisać funkcję do ustawiania statusu, która przyjmować będzie w parametrze nową wartość (bieżącą) i która będzie ustawiać w ten sposób te dwie zmienne.

A jeszcze lepiej będzie napisać funkcję bezparametrową, która w wewnątrz siebie będzie pobierać stan czujnika i aktualizować obie zmienne. W tym przypadku wystarczy tylko wywołać funkcję, bez pamiętania o dodatkowych czynnościach.

boolean status_prev = false;
boolean status_curr = false;

// ..

void updateStatus()
{
  status_prev = status_curr;
  status_curr = digitalRead(czujnik_SW520D);
}
0

Zamiast używać zmiennej możesz podpiąć czujnik wprost pod wejście przerwaniowe i ustawić reakcję na zbocze. Nie wiem tylko, czy
a. toto nie drga.
b. można to oprogramować z poziomu Arduino. Na pewno można korzystając z narzędzi Atmela.

0

jak się pisze gettery i settery to wtedy nie ma z tym problemów:

void ustaw_stan(bool nowyStan)
{
    if (stan != nowyStan) {
        stan = nowyStan;
        gdy_stan_sie_zmienia(stan);
    }
}

void gdy_stan_sie_zmienia(bool stan)
{
     std::cout << "Nowy stan: " << stan << '\n';
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1