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??
Potrzebny soft
Dorzuć sobie do programu gdzieś przed setup taki kod:
Następnie w setup dodajesz normlanie jeden do dziesięciu przekaźników (powiedzmy: r1, r2, r3, r4) i konfigurujesz OneByOne oraz przyciski:
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.
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;
};
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);

Sterowanie można też ogarnąć sobie na jednym przycisku - np. pojedyncze kliknięcie włącza, przytrzymanie wyłącza.
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();
}