Problem z blokowaniem się funkcji w delay()

marcin
Posty: 1
Rejestracja: ndz lis 27, 2016 9:34 pm

Witam.

Postanowiłem przetestować Suple dla modułu ESP8266 kompilowanego w Arduino IDE i trafiłem na drobny problem. Przykładowo podczas zerwania połączenia z serwerem Supli, w bibliotece SuplaDevice, w metodzie iterate() wołany jest delay(), co skutkuje nieprawidłowym działaniem dalszej części mojego kodu zawartego w funkcji loop().

W moim przypadku, oświetlenie sterowane jest nie tylko poprzez Suple, ale także przez fizyczny włącznik dzwonkowy zwierający po prostu do masy, co jest odczytywane przez uC a następnie włączany lub wyłączany jest układ wykonawczy np. przekaźnik.
Ponieważ chciałbym zamienić mój dotychczasowy system automatyki na Suple ale w związku z tym, że obecne zachowanie SuplaDevice jest dla mnie nie do przyjęcia, ponieważ nie wyobrażam sobie sytuacji, w której to awaria switcha, routera, serwera, etc. uniemożliwia domownikom normalne włączenie światła np. w łazience za pomocą ściennego włącznika do czasu ponownego nawiązania połączenia z serwerem, postanowiłem napisać drobną poprawkę do biblioteki, która nie blokuje funkcji iterate() podczas czekania. Jak narazie testuje u siebie ale może komuś się przyda.

Plik SuplaDevice.h

Przed klasą SuplaDeviceClass dopisałem:

Kod: Zaznacz cały

typedef struct {
	bool waiting;
	uint16_t wait_ms;
	uint32_t time_stamp;
} wait_t;
W specyfikatorze dostępu protected klasy SuplaDeviceClass dodałem:

Kod: Zaznacz cały

wait_t _wait;
void wait_clean();
void wait(uint16_t ms);
bool wait();
Teraz plik SuplaDevice.cpp.

Na końcu konstruktora SuplaDeviceClass::SuplaDeviceClass() dopisałem

Kod: Zaznacz cały

wait_clean();
Kolejno wszystkie wywołania delay(...) w metodach zmieniełem na wait(...), czyli np.

Kod: Zaznacz cały

delay(2000);
zmienione na

Kod: Zaznacz cały

wait(2000);
Następnie, na początku metody void SuplaDeviceClass::iterate(void) dopisałem

Kod: Zaznacz cały

if (wait()) return;
co powoduje brak wykonywania tej metody jeśli nie minął czas zadany przez wait(ms).

Pozostał jeszcze kod dla metod:

Kod: Zaznacz cały

void SuplaDeviceClass::wait_clean() {
	_wait.waiting = false;
	_wait.wait_ms = 0;
	_wait.time_stamp = 0;
}

void SuplaDeviceClass::wait(uint16_t ms) {
	_wait.waiting = true;
	_wait.wait_ms = ms;
	_wait.time_stamp = millis();
}

bool SuplaDeviceClass::wait() {

	if (_wait.waiting) {
		if ((_wait.time_stamp + _wait.wait_ms) > millis())
			return true;
		else {
			wait_clean();
			return false;
		}
	}

	return false;
}
Mam nadzieję, że jest to zrozumiałe.
Oczywiście po ponownym nawiązaniu połączenia z serwerem Supli, należy wysłać aktualny stan kanałów ale to już nie jest problem.

Pozdrawiam.
ODPOWIEDZ

Wróć do „supla-dev”