Obsługa przycisków w SuplaDevice

User avatar
lukfud
Posts: 2480
Joined: Thu Nov 23, 2017 11:33 pm
Location: Warszawa
Has thanked: 13 times
Been thanked: 11 times

Post

klew wrote: Mon Jun 08, 2020 8:03 am Na EPS czy Arduino Mega?
Funkcje sieciowe na Arduino są niestety blokujące, więc pewnie stąd ten efekt. Pewnie trzeba będzie przerzucić obsługę większości rzeczy na przerwania.
ESP,
kiedyś o tym pisałem, jak ustawiałem miganie diody (na starej bibliotece jeszcze) viewtopic.php?p=53987#p53987.
Po przejściu na nową nie sprawdzałem już tego.
krycha88 wrote: Mon Jun 08, 2020 8:07 am też to zauważyłem, ustaw sobie setTimeout(500) w esp_wifi.h w setupie i będzie znaczna poprawa :)
dzięki, przetestuję wieczorem, aczkolwiek problemem nie jest połączenie z wifi, tylko z serwerem.
https://www.facebook.com/groups/supladiy
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/suplaauraton
https://smartnerzeczy.pl
User avatar
klew
Posts: 13907
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

lukfud wrote: Mon Jun 08, 2020 9:06 am ESP,
kiedyś o tym pisałem, jak ustawiałem miganie diody (na starej bibliotece jeszcze) viewtopic.php?p=53987#p53987.
Po przejściu na nową nie sprawdzałem już tego.
Z diodą będzie ten sam problem.
Niestety domyślne biblioteki do sieci mają blokujące metody do komunikacji sieciowej.
Można to obejść na dwa sposoby:
1. Używać dodatkowych bibliotek do asynchornicznej komunikacji (niestety, wymaga to instalowania dodatkowych bibliotek)
2. Przerzucić obsługę rzeczy, którę muszą być bardziej responsywne, na przerwania.
Najlepsze suple dla Twojego domu :mrgreen:
User avatar
lukfud
Posts: 2480
Joined: Thu Nov 23, 2017 11:33 pm
Location: Warszawa
Has thanked: 13 times
Been thanked: 11 times

Post

klew wrote: Mon Jun 08, 2020 9:17 am Z diodą będzie ten sam problem.
Niestety domyślne biblioteki do sieci mają blokujące metody do komunikacji sieciowej.
Można to obejść na dwa sposoby:
1. Używać dodatkowych bibliotek do asynchornicznej komunikacji (niestety, wymaga to instalowania dodatkowych bibliotek)
2. Przerzucić obsługę rzeczy, którę muszą być bardziej responsywne, na przerwania.
Z niepoprawnym miganiem diody da się żyć, ale przycisk powinien reagować w każdej sytuacji.
Czy planujesz przerzucić obsługę przycisku na przerwanie?

Co do:
"wait_for_iterate = millis() + "
dlaczego nie można tego czasu wydłużyć?
https://www.facebook.com/groups/supladiy
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/suplaauraton
https://smartnerzeczy.pl
User avatar
klew
Posts: 13907
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

lukfud wrote: Mon Jun 08, 2020 9:26 am Co do:
"wait_for_iterate = millis() + "
dlaczego nie można tego czasu wydłużyć?
Można to wydłużyć, tylko to nie rozwiązuje problemu. Jak zrobi się za długi czas, to niekórzy mogą narzekać, że moduł im się nie łączy, a problem braku reakcji na przycisk nadal może wystąpić.

Dodałem issue na githubie https://github.com/klew/arduino/issues/35
Najlepsze suple dla Twojego domu :mrgreen:
User avatar
lukfud
Posts: 2480
Joined: Thu Nov 23, 2017 11:33 pm
Location: Warszawa
Has thanked: 13 times
Been thanked: 11 times

Post

klew wrote: Mon Jun 08, 2020 9:36 am Można to wydłużyć, tylko to nie rozwiązuje problemu. Jak zrobi się za długi czas, to niekórzy mogą narzekać, że moduł im się nie łączy, a problem braku reakcji na przycisk nadal może wystąpić.
To prawda. Nie rozwiązuje, ale zwiększa szansę trafienia :)
klew wrote: Mon Jun 08, 2020 9:36 am Dodałem issue na githubie https://github.com/klew/arduino/issues/35
Dziękuję.
https://www.facebook.com/groups/supladiy
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/suplaauraton
https://smartnerzeczy.pl
User avatar
lukfud
Posts: 2480
Joined: Thu Nov 23, 2017 11:33 pm
Location: Warszawa
Has thanked: 13 times
Been thanked: 11 times

Post

krycha88 wrote: Mon Jun 08, 2020 8:07 am
lukfud wrote: Mon Jun 08, 2020 7:37 am @klew,
wczoraj zauważyłem, że przy braku połączenia z serwerem (wyłączone raspberry) przycisk nie działa za każdym naciśnięciem.
To jest normalne zachowanie, że musi się wstrzelić pomiędzy próbę połączenia, czy ja coś namieszałem?
też to zauważyłem, ustaw sobie setTimeout(500) w esp_wifi.h w setupie i będzie znaczna poprawa :)
@klew,
po sugestii @krycha88 ustawiłem i przetestowałem na kilku urządzeniach:

Code: Select all

static_cast<WiFiClientSecure*>(client)->setBufferSizes(1024, 256); // EXPERIMENTAL
static_cast<WiFiClientSecure*>(client)->setTimeout(50);
Wszystkie działają stabilnie i jest widoczna poprawa szybkości reakcji. Przy braku połączenia z serwerem czy wifi przyciski i diody działają prawidłowo. Może mógłbyś wrzucić do biblioteki podobne ustawienia jako domyślne?
https://www.facebook.com/groups/supladiy
https://www.facebook.com/groups/suplazamel
https://www.facebook.com/groups/suplaauraton
https://smartnerzeczy.pl
WinstonW
Posts: 22
Joined: Fri Jul 10, 2020 3:50 pm

Post

Obecnie posiadałem skrypt na arduino mega , który załączał po wciśnięciu przycisku ,przekaźnik na określony czas

Code: Select all

#define BTN_COUNT 25 // definiujemy ile ma być przycisków 

// obsługa przycisków
typedef struct {
  int pin;
  int relay_pin;
  int channel;
  int ms;
  char last_val;
  unsigned long last_time;
  String nazwa;
  unsigned int channelgroup[];
} _btn_t;

_btn_t btn[BTN_COUNT];

void supla_timer() {
char v;
unsigned long now = millis();
for(int a=0;a<BTN_COUNT;a++)
if (btn[a].pin > 0) {
v = digitalRead(btn[a].pin);
if (v != btn[a].last_val && now - btn[a].last_time ) {
btn[a].last_val = v;
btn[a].last_time = now;
if (v==0)
{
 if ( btn[a].ms > 0 ) {
                     SuplaDevice.relayOn(btn[a].channel, btn[a].ms);
                 } else {
                      if ( digitalRead(btn[a].relay_pin) > 0 ) {
                         SuplaDevice.relayOff(btn[a].channel);
                         Serial.print("BTN Switsh off relay ");
                         Serial.println(btn[a].relay_pin);
                      } else {
                         SuplaDevice.relayOn(btn[a].channel, 0);
                         Serial.print("BTN Switsh on relay ");
                         Serial.println(btn[a].relay_pin);
                      }    
                 }
             }
        }
  
    }
}

void supla_btn_init() {
for(int a=0;a<BTN_COUNT;a++)
if (btn[a].pin > 0) {
pinMode(btn[a].pin, INPUT);
btn[a].last_val = digitalRead(btn[a].pin);
btn[a].last_time = millis();
}
}
void setup() {

  Serial.begin(9600);
 
  // Replace the falowing GUID
  char GUID[SUPLA_GUID_SIZE] = xxxxxxxxxxx
  // with GUID that you can retrieve from https://www.supla.org/arduino/get-guid


  // Ethernet MAC address
  uint8_t mac[6] =xxxxxxxxxx


  memset(btn, 0, sizeof(btn)); 
  
 
  btn[0].pin = 24; //2
  btn[0].relay_pin = 26; //furtka (22)
  btn[0].channel = 0;
  btn[0].ms = 1000; //jak zero to ma być cały czas włączony 1000ms=1s
  btn[0].nazwa = "przycisk furtki";
  SuplaDevice.addRelay(btn[0].relay_pin, false); 
po wgraniu aktualizacji nowej supli

Code: Select all

................
Supla::Control::Relay relay_0(26, false); //przycisk furtki
Supla::Control::Button button_0(24, true);


...............
 button_0.willTrigger(relay_0, Supla::ON_PRESS, Supla::TOGGLE);
 button_0.setSwNoiseFilterDelay(50);

nie wiem jak zrobić ,aby po wsciśnieciu przycisku ,przekaźnik był załączony przez okresloną liczbę sekund
Czy ktoś pomoże? :(
User avatar
klew
Posts: 13907
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

WinstonW wrote: Sun Aug 16, 2020 9:47 pm nie wiem jak zrobić ,aby po wsciśnieciu przycisku ,przekaźnik był załączony przez okresloną liczbę sekund
Czy ktoś pomoże? :(
Obecnie nie ma jeszcze tego zaimplementowanego.
Wkrótce dodam opcję zapamiętywania czasu wysłanego ostatnio przez serwer (czyli np ustawiasz w cloud że to wyłącznik schodowy i ustawiasz 30 s, po wykonaniu tego serwera, urządzenie zapamięta czas i będzie go używać przy przyciskach).
Mogę też na szybko podpowiedzieć jak na sztywno ustawić czas dla przekaźnika.
Najlepsze suple dla Twojego domu :mrgreen:
WinstonW
Posts: 22
Joined: Fri Jul 10, 2020 3:50 pm

Post

klew wrote: Mon Aug 17, 2020 9:20 am
WinstonW wrote: Sun Aug 16, 2020 9:47 pm nie wiem jak zrobić ,aby po wsciśnieciu przycisku ,przekaźnik był załączony przez okresloną liczbę sekund
Czy ktoś pomoże? :(
Obecnie nie ma jeszcze tego zaimplementowanego.
Wkrótce dodam opcję zapamiętywania czasu wysłanego ostatnio przez serwer (czyli np ustawiasz w cloud że to wyłącznik schodowy i ustawiasz 30 s, po wykonaniu tego serwera, urządzenie zapamięta czas i będzie go używać przy przyciskach).
Mogę też na szybko podpowiedzieć jak na sztywno ustawić czas dla przekaźnika.
Poprosze
User avatar
klew
Posts: 13907
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław
Has thanked: 134 times
Been thanked: 137 times

Post

WinstonW wrote: Mon Aug 17, 2020 8:24 pm
Dodaj sobie tą definicję klasy w swoim programie (może być gdzieś przed sekcją setup() ):

Code: Select all

class FixedDurationRelay : public Supla::Control::Relay {
  public:
  FixedDurationRelay(int pin,
        bool highIsOn = true, long durationMs = 0) : Supla::Control::Relay(pin, highIsOn) {
          fixedDurationMs = durationMs;
        }

  void turnOn(_supla_int_t duration = 0) {
    Supla::Control::Relay::turnOn(fixedDurationMs);
  }
         
  protected:
   long fixedDurationMs;
};
Następnie możesz dodać swój przekaźnik w ten sposób:

Code: Select all

FixedDurationRelay relay_0(26, false, 5000); //przycisk furtki - 5000 ms
Klasa FixedDurationRelay ma nadpisaną metodę "turnOn()" z klasy Relay i wywołuję ją zawsze podając parametr "fixedDurationMs" jako czas włączenia przekaźnika.
Taka implementacja spowoduje, że niezależnie jak ustawiony będzie przekaźnik w cloud, będzie on załączany na taki czas, jaki określisz w kodzie.
Najlepsze suple dla Twojego domu :mrgreen:

Return to “Arduino IDE”