Relaiskarte über Webserver steuern

Hallo liebe Community,
ich habe nach folgender Anleitung eine Schaltung aufgebaut, die auch funktioniert, nur leider nicht so, wie ich das gerne hätte:
https://esp8266-server.de/8-I2C-WiFi-Relais.html

Nun kann man über den Webserver die Relais ein und ausschalten.
Ich möchte aber gerne wenn ich ein Relais einschalte, alle anderen ausschalten, sodass immer nur ein Relais eingeschaltet sein kann. Wenn beispielsweise Relais 7 eingeschaltet wird, sollen die Relais 1-6 und 8 ausgeschaltet werden. Viell eicht wäre auch das folgende Szenario denkbar: Relais 1 und 5 werden eingeschaltet und 2-4 und 6-8 aus. Demnach wären die Relais 1+5, 2+6, 3+7, 4+8 "gekoppelt".
Ich habe den Ersteller der Anleitung per E-Mail angeschrieben, er konnte mir aber leider nicht helfen, da er wohl seit vielen Jahren nichts mehr mit Arduino bzw. dem ESP8266 gemacht hat. Und keine Ahnung mehr vom Code dieser Schaltung hat.
Hat jemand ne Idee, wie ich den Code entsprechend anpassen kann?
Es wäre vielleicht auch denkbar, die Schaltzustände zu wechseln, wenn an einem Relais eine Änderung vorgenommen wird.
Ich möchte mit dieser Relaisschaltung mehrere Lautsprecher an einem Verstärker betreiben und in meinem Abhörraum über Tablet/PC oder Handy über die Webseite den gewünschten Lautsprecher anwählen können.
Wäre echt super, wenn mir da jemand weiterhelfen kann!
Herzliche Grüße
Oliver

Wenn der Code von der Webseite verwendet wird, steht in Zeile 76 und 77:

if (zustand == "1") bitSet(output, z);            // Wenn Einschalten gewuenscht Bit setzen
if (zustand == "0") bitClear(output, z);          // Wenn Ausschalten gewuenscht Bit zuruecksetzen 

Das ist die Stelle, an der Du eingreifen könntest - hier mal ein verbesserungsfähiger Versuch.
Alle Bits ausschalten außer dem einen, das eingeschaltet werden soll (weder kompiliert noch getestet - nur quick & dirty runtergetippt):

if (zustand == "1") {
  for (byte relaisCount = 0; relaisCount < 8; relaisCount++) {
    if (relaisCount == z) {
      bitSet(output, z);
    }
    else {
      bitClear(output, relaisCount);  
    }
  }
}
else {
  bitClear(output, z);          // Wenn Ausschalten gewuenscht Bit zuruecksetzen 
}

Die Funktionsaufrufe und Kommentare in Zeile 76 und 77 (1=Set=ein) passen allerdings nicht zum Kommentar in Zeile 19:

  // Anfangszustand 1111 11111 (Relais ausgeschaltet)

Ggf. musst Du die Schaltlogik umkehren.

Ist nicht schön... ich weiß.

 if (zustand == "2") output ^= bitSet(k, z);       // Umschalten den gewaelten Relay mit XOR

statt XOR-Operation alle Bits auf null setzen und dann nur das aktuell übertragene Bit setzen

Wow, das ging aber echt schnell. Vielen Dank für die Antworten.
Ich muss nun zuerst die Schaltung anstöpseln und mein Programmier-Interface anschließen. Ist derzeit noch verliehen. Sobald ich es zurück habe, versuche ich den Code zu testen. Wäre super, wenn das klappt!
Vielen Dank an wno158 und StefanL38 für eure Unterstützung!

a) nur "Ein Relay"
das könnte mit einer kleinen Änderung gehen.
Zeile 76

if (zustand == "1") output = (1<<z);            // nur das eine bit setzen

invertiert wird das ganze sowieso bei der I2C Übertragung.
Zustand 0 löscht nur und
Zustand 2 wird meiner Meinung nach auf der Webseite nie aufgerufen

und dann einfach zwei Relais an einen Ausgang anschließen.

b) "zwei Relays"
0/4, 1/5, 2/6, 3/7
ungeprüft:

void Ereignis_Befehl()      // Wird ausgefuehrt wenn "http://<ip address>/schalte.php" aufgerufen wurde
{
  String relaisNr = server->arg("relais");          // Relais Nr. empfangen
  int z = relaisNr.toInt();                         // String zu Integer konvertieren
  z--;                                              // 1 abzien, weil bits im Byte werden ab 0 gezaelt
  String zustand = server->arg("schalte");
  //if (zustand == "1") bitSet(output, z);            // Wenn Einschalten gewuenscht Bit setzen 
  if (zustand == "1") {                             // einschalten setzt immer zwei bits
    if (z < 4) 
      output = (1 << z) | (1 << (z + 4));
    else
      output = (1 << z) | (1 << (z - 4));
  }
  //if (zustand == "0") bitClear(output, z);          // Wenn Ausschalten gewuenscht Bit zuruecksetzen
  if (zustand == "0") output = 0;
  //char k = 0;                                       // Temporere Variable fuer XOR Operation
  //if (zustand == "2") output ^= bitSet(k, z);       // Umschalten den gewaelten Relay mit XOR
  Wire.beginTransmission(IC);                       // I2C IC-Adresse
  Wire.write(~output);                              // Byte Invertieren, bei "0" sind Relais an
  Wire.endTransmission();                           // Stop-Bedingung I2C
  // Serial.println(String(int(output)));
  server->send(200, "text/plain", String(int(output)) ); // Antwort an Internet Browser senden
}

das z-- schaut eigenartig aus, weil die Webseite die Relais meiner Meinung nach als 0 bis 7 schickt, aber ich lass das mal so wie im originalem Sketch.

ich würde das eher mit einem fertigen Board (ohne PCF) machen:
https://werner.rothschopf.net/microcontroller/202108_esp8266_esp12f_relay_x8_en.htm

Jetzt habe ich mir das Board Mal bestellt und muss sehen,ob ich das so zum laufen bekomme. Bin derzeit allerdings ans Krankenbett gefesselt, da ich nach meiner Knie-OP 6 Wochen nicht belasten darf ;-(
Ich lese jetzt viel und versuche das irgendwie testen zu können - Zeit habe ich ja jetzt.
Danke für die Unterstützung!
Gruß, Oliver

Ideale Randbedingungen um deinen Code mit dem WOKWI-simulator weiter zu entwickeln. Zumindest die Programm-Logik. Ob der Simulator auch Webseiten nachbilden kann habe ich noch nie ausprobiert.

Der WOKWI-Simulator hat den ESP32 aber keinen ESP8266. Aber der ESP32 ist sowieso der bessere ESP8266.

Wenn du das Programm in Teile unterteilst dann gibt es einen Logik-Teil der völlig unabhängig davon ist ob das nachher ein ESp8266, ESP32 oder auch Ardiuno-Uno oder sonst etwas ist.

Und den Teil des Programms kannst du auf dem WOKWI-Simulator entwickeln.

vgs

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.