Sterowanie LEDem w zależności od stanu przekaźnika

radzik_r
Posts: 404
Joined: Sun Aug 11, 2019 5:32 pm

Post

klew wrote: Wed Jan 20, 2021 10:39 am
Kolejne dwie nowości to Supla::Control::InternalPinOutput oraz Supla::Control::PinStatusLed.
InternalPinOutput to coś w rodzaju wewnętrznego przekaźnika (wewnętrznego w sensie, że nie informujemy o jego istnieniu serwera Supli), którego stan możemy zmieniać używając wewnętrznej logiki. Można tutaj podłączać fizyczny przekaźnik, LED, buzzer - cokolwiek co da się sterować cyfrowym wyjściem. InternalPinOutput jest sterowalny przez "addAction", jak również może być sterowany przez akcje z innych elementów programu. Dodałem przykład użycia InternalPinOutput w przykładach w bibliotece dla ImpulseCounter (mruganie diodą, przy każdym zliczeniu impulsu).
InternalPinOutput ma dostępną metodę "setDurationMs(czas_w_ms)", która spowoduje, że akcja TURN_ON (lub inne włączenie), spowoduje włączenie tylko na czas_w_ms podany w setDurationMs. Można tego użyć np. do generowania mrugnięć diodą po każdej zmianie stanu licznika impulsów.
Można również ustawić stan początkowy (po uruchomieniu programu) metodami setDefaultStateOn, setDefaultStateOff. Domyślnie stan jest ustawiony na OFF.
Konstruktor przyjmuje dwa argumenty: pin, oraz highIsOn - informujący o tym, jaki stan wyjścia (HIGH, czy LOW) oznacza ON (czyli włączony).

PinStatusLed jest natomiast bardzo prostym elementem, który kopiuje stan jednego pinu na inny. Można go użyć np. do diody informującej o stanie innego pinu (np. przekaźnika, rolet, sensora binarnego). Nie da się nim inaczej sterować i sam niczego więcej nie robi. Dodałem do przykładu RollerShutter dwie takie "diody", które będą kopiować stan wyjść sterownika rolet - czyli informują użytkownika o aktualnie załączonym kierunku ruchu rolety.
PinStatusLed akceptuje 3 parametry w konstruktorze: pin źródłowy (czyli ten do skopiowania), pin docelowy (ten, który ustawiamy), oraz odwrócenie logiki (domyślnie wartość wynosi false - czyli nie odwracamy logiki, więc jeśli pin źródłowy ma HIGH, to na pin docelowy zapiszemy też HIGH).
Zalecałbym tworzenie PinStatusLed jako ostatnich elementów używanych w programie, dlatego, że stan tego elementu zostanie ustawiony w metodzie "onInit" w SuplaDevice.begin, która wywołuje inicjalizację pozostałych elementów zgodnie z kolejnością ich stworzenia. Oznacza to, że jeśli kopiujemy stan pinu 5 na pin 6, to jeśli PinStatusLed dla pin 6 zostanie stworzony przed elementem sterującym pinem 5, to pin 6 zostanie zainicjalizowany pinem 5, który nie jest jeszcze zainicjalizowany. W efekcie mogą pojawić się krótkie mignięcia diody - do czasu aż program nie wejdzie w normalną pętlę i nie zaktualizuje stanu.
@klew czy jest możliwość dorobienia by powyższe dwie funkcje działały również na ekspanderze (klasach ekspandera)
User avatar
klew
Posts: 8763
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

radzik_r wrote: Sun Nov 05, 2023 5:44 pm
@klew czy jest możliwość dorobienia by powyższe dwie funkcje działały również na ekspanderze (klasach ekspandera)
Wydaje mi się że możliwość dodania innego interfejsu już GPIO, była tam dodana.
Pytanie więc jakiej implementacji ekspandera używasz (bo w bibliotece nie ma chyba żadnego) i czy dobrze przygotowałeś go do pracy z klasą Supla:Io?
Widzimy się na Supla Offline Party vol. 2 :!:
radzik_r
Posts: 404
Joined: Sun Aug 11, 2019 5:32 pm

Post

klew wrote: Sun Nov 05, 2023 5:48 pm
radzik_r wrote: Sun Nov 05, 2023 5:44 pm
@klew czy jest możliwość dorobienia by powyższe dwie funkcje działały również na ekspanderze (klasach ekspandera)
Wydaje mi się że możliwość dodania innego interfejsu już GPIO, była tam dodana.
Pytanie więc jakiej implementacji ekspandera używasz (bo w bibliotece nie ma chyba żadnego) i czy dobrze przygotowałeś go do pracy z klasą Supla:Io?

Code: Select all

class ExtMCP23017 : public Supla::Io {
 public:
  ExtMCP23017(uint8_t i2c_addr = 0x20)
                               : i2c_addr(i2c_addr), Supla::Io(false) {
    mcp.begin_I2C(i2c_addr);
  }

  void customPinMode(int channelNumber, uint8_t pin, uint8_t mode) override {
    mcp.pinMode(pin, mode);
  }

  void customDigitalWrite(int channelNumber, uint8_t pin,
                                                        uint8_t val) override {
    mcp.digitalWrite(pin, val);
  }

  int customDigitalRead(int channelNumber, uint8_t pin) override {
    return mcp.digitalRead(pin);
  }

 private:
  ::Adafruit_MCP23X17 mcp;
  uint8_t i2c_addr;
};
no mam klasę mcp23017 jw.

Code: Select all

  new Supla::Control::PinStatusLed(ExtMCP23017, pin_relay, ExtMCP23017, pin_led); 
to nie zadziała, byc może ja to źle konstruuję, lub nie rozumiem jak powinno być poprawnie

cel jest taki aby odczytać status przekaźnika na jednym ekspanderze, i wystawić go na drugim ekspanderze
User avatar
klew
Posts: 8763
Joined: Thu Jun 27, 2019 12:16 pm
Location: Wrocław

Post

Tam się podaje wskaźnik na instancję klasy przekaźnika. Do tego kolejność parametrów jest inna. Zerknij tutaj:
https://github.com/SUPLA/supla-device/b ... _led.h#L29
Widzimy się na Supla Offline Party vol. 2 :!:
radzik_r
Posts: 404
Joined: Sun Aug 11, 2019 5:32 pm

Post

klew wrote: Sun Nov 05, 2023 7:05 pm Tam się podaje wskaźnik na instancję klasy przekaźnika. Do tego kolejność parametrów jest inna. Zerknij tutaj:
https://github.com/SUPLA/supla-device/b ... _led.h#L29
ok, dzięki, działa.

kolega @lukfud dał mi porządny wykład, wiec co nieco po tym zrozumiałem, chwała mu za to

Return to “Arduino IDE”