Potrzebny soft

Awatar użytkownika
PuteR
Posty: 972
Rejestracja: śr gru 06, 2017 10:07 am

czw gru 03, 2020 7:21 pm

Czy ktoś może posiada lub byłby w stanie napisać (choćby odpłatnie) soft działający w następujący sposób.

wersja 1:
Dwa lub cztery kanały i do tego dwa zewnętrzne przyciski (A i B). Wciskając przycisk A załącza się kanał pierwszy, wciskając kolejny raz załącza się kanał drugi itd. Wciskając przycisk B wyłącza się kanał czwarty następnie trzeci itd. Jeśli włączę tylko dwa kanały i wcisnę przycisk B to wyłącza się kanał drugi, a po kolejnym wciśnięciu kanał pierwszy.

wersja 2:
Dwa lub cztery kanały i do tego dwa zewnętrzne przyciski (A i B). Wciskając przycisk A załącza się kanał pierwszy, wciskając kolejny raz załącza się kanał drugi ale pierwszy się wyłącza, kolejny raz włącza się trzeci i wyłącza drugi. Przycisk B wyłącza się czwarty i włącza trzeci, kolejne naciśnięci wyłącza się trzeci i włącza drugi itd.

Ważne jest aby działało to bez konieczności połączenia z internetem. Czy takie działanie jest w ogóle możliwe do ogarnięcia??
Awatar użytkownika
klew
Posty: 1761
Rejestracja: czw cze 27, 2019 12:16 pm

czw gru 03, 2020 11:16 pm

Dorzuć sobie do programu gdzieś przed setup taki kod:

Kod: Zaznacz cały

#include <supla/triggerable.h>

class OneByOne : public Supla::Triggerable {
  public:
  OneByOne() : relays {}, relayCount(0), keepOneOn(false)  {
  }

  void addRelay(Supla::Control::Relay *relay) {
    if (relayCount < 10) {
      relays[relayCount] = relay;
      relayCount++;
    }
  }

  void setKeepOneOn(bool value = true) {
    keepOneOn = value;
  }
 
  protected:
   void runAction(int event, int action) {
     switch (action) {
      case Supla::TURN_ON : {
        Serial.println("TURN ON");
        int lastOnIndex = -1;
        for (int i = 0; i < 9 && relays[i] != nullptr; i++) {
          if (relays[i]->isOn()) {
            lastOnIndex = i;
            if (i == relayCount - 1) {
              lastOnIndex--;
            }
          }
        }
        if (keepOneOn) {
          for (int j = 0; j < 10 && relays[j] != nullptr; j++) {
            relays[j]->turnOff();
          }
        }
        if (relays[lastOnIndex + 1] != nullptr) {
          relays[lastOnIndex + 1]->turnOn();
        }
        break;
      }
      case Supla::TURN_OFF: {
        Serial.println("TURN OFF");
        for (int i = 9; i >= 0; i--) {
          if (relays[i] && relays[i]->isOn()) {
            relays[i]->turnOff();
            if (keepOneOn && i > 0) {
              relays[i-1]->turnOn();              
            }
            break;
          }
         }
        break;
      }
     }
   }

  Supla::Control::Relay *relays[10];
  int relayCount;
  bool keepOneOn;
};
Następnie w setup dodajesz normlanie jeden do dziesięciu przekaźników (powiedzmy: r1, r2, r3, r4) i konfigurujesz OneByOne oraz przyciski:

Kod: Zaznacz cały

auto r1 = new Supla::Control::Relay(....); // w nawiasach trzeba uzupełnić piny, i inne parametry
auto r2 = new Supla::Control::Relay(....);
auto r3 = new Supla::Control::Relay(....);
auto r4 = new Supla::Control::Relay(....);

auto b1 = new Supla::Control::Button(...);
auto b1 = new Supla::Control::Button(...);

auto oneByOne = new OneByOne;

oneByOne->addRelay(r1); // Dodawanie przekaznikow, ktorymi bedziemy sterowac
oneByOne->addRelay(r2); // kolejnosc jest wazna
oneByOne->addRelay(r3);
oneByOne->addRelay(r4);

// oneByOne->setKeepOneOn(); // odkomentuj jesli chcesz miec tylko jedna lampke wlaczona

// konfigurujemy przyciski:
b1->addAction(Supla::TURN_ON, oneByOne, Supla::ON_PRESS);
b2->addAction(Supla::TURN_OFF, oneByOne, Supla::ON_PRESS);
Mam nadzieję, że nic tutaj nie pomieszałem ;)
Sterowanie można też ogarnąć sobie na jednym przycisku - np. pojedyncze kliknięcie włącza, przytrzymanie wyłącza.
Awatar użytkownika
klew
Posty: 1761
Rejestracja: czw cze 27, 2019 12:16 pm

czw sty 07, 2021 12:01 pm

Przykładowy program

Kod: Zaznacz cały

#include <SPI.h>
#include <SuplaDevice.h>
#include <supla/sensor/DHT.h>

#include <supla/network/esp_wifi.h>
Supla::ESPWifi wifi("your_wifi_ssid", "your_wifi_password");

#include <supla/triggerable.h>

class OneByOne : public Supla::Triggerable {
  public:
    OneByOne() : relays {}, relayCount(0), keepOneOn(false)  {
    }

    void addRelay(Supla::Control::Relay *relay) {
      if (relayCount < 10) {
        relays[relayCount] = relay;
        relayCount++;
      }
    }

    void setKeepOneOn(bool value = true) {
      keepOneOn = value;
    }

  protected:
    void runAction(int event, int action) {
      switch (action) {
        case Supla::TURN_ON : {
                                Serial.println("TURN ON");
                                int lastOnIndex = -1;
                                for (int i = 0; i < 9 && relays[i] != nullptr; i++) {
                                  if (relays[i]->isOn()) {
                                    lastOnIndex = i;
                                    if (i == relayCount - 1) {
                                      lastOnIndex--;
                                    }
                                  }
                                }
                                if (keepOneOn) {
                                  for (int j = 0; j < 10 && relays[j] != nullptr; j++) {
                                    relays[j]->turnOff();
                                  }
                                }
                                if (relays[lastOnIndex + 1] != nullptr) {
                                  relays[lastOnIndex + 1]->turnOn();
                                }
                                break;
                              }
        case Supla::TURN_OFF: {
                                Serial.println("TURN OFF");
                                for (int i = 9; i >= 0; i--) {
                                  if (relays[i] && relays[i]->isOn()) {
                                    relays[i]->turnOff();
                                    if (keepOneOn && i > 0) {
                                      relays[i-1]->turnOn();              
                                    }
                                    break;
                                  }
                                }
                                break;
                              }
      }
    }

    Supla::Control::Relay *relays[10];
    int relayCount;
    bool keepOneOn;
};


void setup() {

  Serial.begin(9600);

  // Replace the falowing GUID with value that you can retrieve from https://www.supla.org/arduino/get-guid
  char GUID[SUPLA_GUID_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

  // Replace the following AUTHKEY with value that you can retrieve from: https://www.supla.org/arduino/get-authkey
  char AUTHKEY[SUPLA_AUTHKEY_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

  auto r1 = new Supla::Control::Relay(....); // w nawiasach trzeba uzupełnić piny, i inne parametry
  auto r2 = new Supla::Control::Relay(....);
  auto r3 = new Supla::Control::Relay(....);
  auto r4 = new Supla::Control::Relay(....);

  auto b1 = new Supla::Control::Button(...);
  auto b1 = new Supla::Control::Button(...);

  auto oneByOne = new OneByOne;

  oneByOne->addRelay(r1); // Dodawanie przekaznikow, ktorymi bedziemy sterowac
  oneByOne->addRelay(r2); // kolejnosc jest wazna
  oneByOne->addRelay(r3);
  oneByOne->addRelay(r4);

  // oneByOne->setKeepOneOn(); // odkomentuj jesli chcesz miec tylko jedna lampke wlaczona
 
  // konfigurujemy przyciski:
  b1->addAction(Supla::TURN_ON, oneByOne, Supla::ON_PRESS);
  b2->addAction(Supla::TURN_OFF, oneByOne, Supla::ON_PRESS);

  SuplaDevice.begin(GUID,              // Global Unique Identifier 
      "svr1.supla.org",  // SUPLA server address
      "email@address",   // Email address used to login to Supla Cloud
      AUTHKEY);          // Authorization key

}

void loop() {
  SuplaDevice.iterate();
}

ODPOWIEDZ

Wróć do „Ogólna dyskusja”