Mehrere Relays EInbinden

Gast #7804826
Lesenswert?

Hier ist mein Sketch: #include <Wire.h> #include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

int sensor_pin; //Sensor Pin int relay_pin; //Relay Pin

void setup() { Serial.begin(9600); lcd.init(); // initialize the lcd lcd.init();

lcd.backlight(); pinMode(sensor_pin, INPUT); pinMode(relay_pin, OUTPUT); } // Relais 1 void loop() { int sensor_data = analogRead(sensor_pin = A0); Serial.print("Wert 1:"); Serial.print(sensor_data); Serial.print("\t | ");

if(sensor_data < 400) { Serial.println("Erde ist trocken"); digitalWrite(relay_pin = 7, HIGH); lcd.setCursor(0,0); lcd.print("Anlage Ein"); lcd.setCursor(0,1); lcd.print("Motor ON "); } else if(sensor_data > 600) { Serial.println("Erde ist nass"); digitalWrite(relay_pin = 7, HIGH); lcd.setCursor(0,0); lcd.print("Anlage Aus"); lcd.setCursor(0,1); lcd.print("Motor OFF"); }

delay(20000); }

Persönliche Seite #7804867
Lesenswert?

Hallo Volker,

das funktioniert so schon, ist aber nicht sehr sinnvoll.

Die Idee ist, den zu verwendenden Pin im Vorfeld in einer Variable abzulegen: int relay_pin = 7; //Relay Pin

Und diese Variable dann im digitalWrite zu verwenden: digitalWrite(relay_pin, HIGH);

Wenn Du mehrere Relais ansteuern möchtest, wäre zunächst die Frage, ob diese einfach parallel schalten sollen oder unter andern Bedingungen als das erste Relay.

Parallel ist einfach:

  1. Weitere Variablen deklarieren und belegen: int relay2_pin = 8; int relay3_pin = 9; int relay4_pin = 10; (hinter der Deklaration von relay_pin)

  2. Die Pins als Ausgänge konfigurieren: pinMode(relay2_pin, OUTPUT); pinMode(relay3_pin, OUTPUT); pinMode(relay4_pin, OUTPUT); (in setup() )

  3. An den passenden Stellen setzen (hier nur als Beispiel) digitalWrite(relay2_pin, HIGH);

Brauchst Du andere Schaltbedingungen, muss man diese erst mal kennen...aber im Wesentlichen wird es auf ein Kopieren und Anpassen der if...else if Geschichte rauslaufen.

Gruß Jens

Persönliche Seite #7804876
Lesenswert?

Volker S. schrieb:

Jedes Relay hat einen eigenen Sensor

Dann brauchst Du für jeden Sensor und für jedes Relay alles neu.

ABER: keine zwei Funktionen setup oder loop, sondern nur deren Inhalte mehrfach in der Loop. Mit neuen Namen ist es am einfachsten. Die Position Deines Kommentars // Relais 1 lässt böses ahnen (nicht schlimm, typischer Anfängeransatz).

Ich versuche es mal auf die Schnelle (ohne Anpassung der LCD-Ausgabe, das musste selbst rausforschen):

int sensor_pin; //Sensor Pin int relay_pin; //Relay Pin int sensor2_pin; //Sensor2 Pin int relay2_pin; //Relay2 Pin

void setup() { Serial.begin(9600); lcd.init(); // initialize the lcd lcd.init(); lcd.backlight(); pinMode(sensor_pin, INPUT); pinMode(relay_pin, OUTPUT); pinMode(sensor2_pin, INPUT); pinMode(relay2_pin, OUTPUT); }

void loop() { // Relais 1 int sensor_data = analogRead(sensor_pin); Serial.print("Wert 1:"); Serial.print(sensor_data); Serial.print("\t | ");

if(sensor_data < 400) { Serial.println("Erde ist trocken"); digitalWrite(relay_pin = 7, HIGH); lcd.setCursor(0,0); lcd.print("Anlage Ein"); lcd.setCursor(0,1); lcd.print("Motor ON "); } else if(sensor_data > 600) { Serial.println("Erde ist nass"); digitalWrite(relay_pin = 7, LOW); lcd.setCursor(0,0); lcd.print("Anlage Aus"); lcd.setCursor(0,1); lcd.print("Motor OFF"); }

// Relais 2 int sensor2_data = analogRead(sensor2_pin); Serial.print("Wert 2:"); Serial.print(sensor2_data); Serial.print("\t | ");

if(sensor2_data < 400) { Serial.println("Erde ist trocken"); digitalWrite(relay2_pin, HIGH); lcd.setCursor(0,0); lcd.print("Anlage Ein"); lcd.setCursor(0,1); lcd.print("Motor ON "); } else if(sensor2_data > 600) { Serial.println("Erde ist nass"); digitalWrite(relay2_pin, LOW); lcd.setCursor(0,0); lcd.print("Anlage Aus"); lcd.setCursor(0,1); lcd.print("Motor OFF"); }

delay(20000); }

#7805299
Lesenswert?

Jens M. schrieb:

das funktioniert so schon

Wenn das der echte Quelltext ist, nicht. Zumindest nachdem der Sensor das erste Mal einen hohen oder tiefen Wert liefert.

Jens M. schrieb:

Die Idee ist, den zu verwendenden Pin im Vorfeld in einer Variable abzulegen:

In der Regel eine Konstante, denn die Pinnummer irgendeiner Hardware ändert sich später ja nicht wieder. Geht aber beides. Mich interessiert, ob C ein Problem damit hat und die Zuweisung "Pin = 7" in der Funktion nicht als "1" oder "true" interpretiert wird....

Dein Code könnte besser gehen als das Original, aber die Pumpe läuft immer mindestens 20 Sekunden.

Da wäre eine Steuerung innerhalb der Sensormessung sinnvoller, a la

1
do
2
Sensor 1 messen
3
Wert unter "trocken"? Dann call gießen1
4
Sensor 2 messen
5
Wert unter "trocken"? dann call gießen2
6
...
7
...
8
loop
9

10
gießen1:
11
Timer starten/merken
12
Pumpe1 an
13
while Sensor1 < Nass and Timer nicht abgelaufen
14
Warte 1 Sekunde
15
Wert messen
16
end while
17
Pumpe1 aus
18
return
19

20
gießen2:
21
wie oben, nur eben 2...

Ist natürlich nur Pseudocode, ich will das Projekt ja nicht entwickeln...

#7805309
Lesenswert?

Jens M. schrieb:

Mich interessiert, ob C ein Problem damit hat und die Zuweisung "Pin = 7" in der Funktion nicht als "1" oder "true" interpretiert wird....

Nö, das funktioniert wie erwartet; C kennt Mehrfachzuweisungen:

1
a = b = c = 3;

Sieht hässlich aus, ist es auch. Und im Funktionsaufruf so eine Zuweisung zu machen, ist natürlich praktisch nie sinnvoll, und vor allem für Menschen, die den Code lesen und verstehen sollen, sehr unerwartet.

Und hier ist es extrem ungünstig, da die Zuweisung erst bei digitalWrite, und nicht bei pinMode erfolgt. Solange keine Zuweisung erfolgt, enthalten die Variablen den Wert 0 ...

Man kann die Variable auch einfach weglassen, und erhält genauso schlecht wartbaren Code (mit "magic numbers", d.h. Konstanten irgendwo im Quelltext).

1
    digitalWrite(7, LOW);

Das ist natürlich auch Mist, weil überhaupt nicht mehr erkennbar ist, welche Bedeutung die 7 hier hat.

Da aber zur Laufzeit der Wert unverändert bleiben soll, ist eine Variable hier gar nicht nötig. Da kann man auch ein Macro (#define) verwenden:

Statt

1
int sensor_pin;       //Sensor Pin
2
int relay_pin;        //Relay Pin

sowas:

1
#define SENSOR_PIN A0   // Sensor Pin
2
#define RELAY_PIN 7     // Relay Pin

und entsprechend

1
    digitalWrite(RELAY_PIN, LOW);

Macronamen werden in VERSALIEN geschrieben, das ist eine Konvention, die man unbedingt einhalten sollte.

Übrigens: "Relay" schreibt man im Deutschen "Relais" (das Wort kommt aus dem Französischen und wird auch im Deutschen so ausgesprochen wie "Gelée", also /ohne/ s). Auch der Plural wird im Deutschen "Relais" geschrieben.

Persönliche Seite #7805615
Lesenswert?

Jens M. schrieb:

Dein Code könnte besser gehen als das Original, aber die Pumpe läuft immer mindestens 20 Sekunden.

Da hat der 'kluge' Jens Recht. Wenn dieses Verhalten nicht gewünscht ist, würde ich aber einfach die delay-Zeit herabsetzen...

Harald K. schrieb:

Stattint sensor_pin; //Sensor Pin int relay_pin; //Relay Pin

sowas: #define SENSOR_PIN A0 // Sensor Pin #define RELAY_PIN 7 // Relay Pin

und entsprechend digitalWrite(RELAY_PIN, LOW);

Und auch Harald stimme ich hier völlig zu, ich wollte aber nicht zu viel ändern.

Die Verwendung von Konstanten, die sinnvoll benannt sind, ist ein wichtiger Bestandteil von Code, der einfach lesbar ist - selbst-kommentierend sozusagen...

Gruß vom nicht so schlauen Jens M.

#7805634
Lesenswert?

Jens M. schrieb:

Mich interessiert, ob C ein Problem damit hat und die Zuweisung "Pin = 7" in der Funktion nicht als "1" oder "true" interpretiert wird....

No, sir. "Pin = 7" ist ein Ausdruck vom selben Typ wie 'Pin' (also Typ 'int') und ergibt '7'. "Pin == 7" ist ein Ausdruck vom Typ 'bool' und ergibt je nach Wert von Pin 'true' oder 'false'.

C und C++ sind, was Typen von Variablen und Ausdrücken angeht, keine Hobbyisten-Sprachen. SCNR.

#7805653
Lesenswert?

Rolf schrieb:

C und C++ sind, was Typen von Variablen und Ausdrücken angeht, keine Hobbyisten-Sprachen.

Ja, so firm bin ich mit C/Arduino nicht. Meine Idee war das der Compiler sagt "Pin = 7" und das dann auch ausführt, und da dann "wurde fehlerfrei zugewiesen" rauskommt, also z.B. "True" bzw. "-1", was dann als Pinnummer interpretiert werden könnte. Das ist ja eine der Fallen in C, das jemand "ist der Wert mit Namen Pin gleich sieben" machen will aber "setze die Variable namens Pin auf sieben" macht.

Das doppelte "digitalwrite high" ist ja ebenso wie die erst beim digitalwrite zugewiesene Pinnummer nicht aufgefallen, d.h. Pinmode war noch auf 0 oder NaN. Was mich aber auch wieder dazu bringt: ist Arduino/digitalWrite so schlau, den Pinmode gleich mitzusetzen?

#7805858
Lesenswert?

Volker S. schrieb:

Danke für Eure Antworten Bie Antworten haben alles nichts mit meiner Frage zutun

So pauschal kann man das aber nicht sagen. Dein hingerotzter Eingangspost löst hier normalerweise andere Reaktionen aus. Nachdem Du den Quelltext gepostet hast wurde Dir schon 4 Posts später hier Beitrag "Re: Mehrere Relays EInbinden" geholfen. Man muß natürlich auch verstehen was da geschieben wurde und ganz offensichtlich hapert es bei Dir genau da. Du bist genau so ein Fall wo einer glaubt, er könne mit deutlich Weniger als Halbwissen ein elektronisches/softwaretechnisches Problem lösen. Es braucht eben doch ein paar Grundlagen, auch wenn der Arduinokram in erster Linie dazu geschaffen wurde den Einstieg in die Elektronik und die Programmierung von µC's zu erleichtern. Ohne ein gewisses Basiswissen bzw. der Bereitschaft sich mit der Thematik intensiv auseinander zu setzen funktioniert es halt auch mit Arduino nicht. Es soll ja Leute geben die einen Beruf erlernen oder ein Studium machen, damit sie am Ende eben genau so etwas umsetzen können. Es ist nicht so einfach wie es von der Makerszene suggeriert wird. Natürlich kann man Elektronik und Software auch als Hobby machen, die meisten hier haben wohl genauso angefangen, aber auch dann muß man sich in die Materie einarbeiten und das ist nicht in ein paar Stunden erledigt. Wir reden hier eher von Wochen oder gar Monaten und man wird bei dem Prozeß durch viele Täler der Tränen gehen.

Du hast eigentlich nur eines bewiesen: Das ist nichts für Dich. Du bist auch nicht Willens die Hinweise anzunehmen, die Dir hier bezüglich Deines Programmierstiels gegeben wurden. Also wirst Du wohl alleine weiter wurschteln müssen oder es jemanden machen lassen müssen der es besser kann als Du. Das Problem ist nicht so riesig und ein Geübter hat das Ganze softwaretechnisch wahrscheinlich in weniger als einer Stunde abgehakt.

Da hätte ich auch eine Wand fragen können

Dann frag doch einfach mal die Wand.

(Firma: Gast) #7806171
Lesenswert?

Frank M. schrieb:

Habs verschoben.

Und dadurch habe ich es jetzt gefunden.

Erstmal, es wird viel von C gesprochen, das ist nicht richtig. Es ist C++!

Jens M. schrieb:

Dann brauchst Du für jeden Sensor und für jedes Relay alles neu.

Mit C++ ist es problemlos möglich die einzelnen Dinge in eine Klasse zu stopfen, Damit vermeidet man die Code Duplikate, was die Wartung/Anpassungen sehr erleichtert, weil es immer nur an einer Stelle erfolgen muss.

Die Instanzen der Klasse können alle in einem Array landen und darüber kann man hinweg iterieren.

Beitrag #7806190 wurde von einem Moderator gelöscht.
(Firma: Gast) #7806196
Lesenswert?

Obelix X. schrieb:

Das wird dem TO aber auch egal sein,

Ähmmm.. Ich habe mich gar nicht auf den TO bezogen, sondern auf die vielen fleißigen Helfer hier.

z.B. wg. sowas:

Harald K. schrieb:

Stattint sensor_pin; //Sensor Pin int relay_pin; //Relay Pin

sowas: #define SENSOR_PIN A0 // Sensor Pin #define RELAY_PIN 7 // Relay Pin

In C++ sollte das dann eher so aussehen:

1
constexpr uint8_t sensorPin {A0};     
2
constexpr uint8_t relayPin  { 7};

Unterstriche eher nicht verwenden, und die Kommentare sind hier auch nicht sinnvoll

#7806283
Lesenswert?

Volker S. schrieb:

wenn ich den wert auf 100 setze schaltet das relay if(sensor_data < 400) der sensor im seriellen monitor meldet 310

Das hast du nur der Gutmütigkeit der digitalWrite()-Funktion des Arduino Frameworks zu verdanken.

Die Zeile

1
  pinMode(relay_pin, OUTPUT);

tut bestimmt nicht, was du möchtest, weil zu dem Zeitpunkt die Variable relay_pin noch den Wert 0 besitzt.

Volker S. schrieb:

ok, DigitalWrite

bestimmt nicht https://docs.arduino.cc/language-reference/de/funktionen/digital-io/digitalwrite/

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren