Forum: Mikrocontroller und Digitale Elektronik Mehrere Relays EInbinden


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Volker S. (Gast)


Lesenswert?

Hallo zusammen
Wie bekomme ich ein zweites, drittes und viertes Relay im Code 
eingebunden?
Das erste schaltet.
Ich habe keine Ahnung wie und wo die anderen im Code vom Arduino Uno 
eingetragen werden.
Danke für Eure Hilfe

: Verschoben durch Moderator
von Jens M. (schuchkleisser)


Lesenswert?

Einfach Zeile 42 duplizieren und aus der 1 dort 2, 3, 4 oder jede 
beliebige andere Zahl machen.

: Bearbeitet durch User
von Mario M. (thelonging)


Lesenswert?

Geht es immer noch um die Bewässerungssteuerung? Dann kümmere Dich um 
den angefangenen Thread und stelle weitere Fragen dort, aber mit ein 
paar mehr Details. Auch wenn viele hier eine Kristallkugel besitzen 
können wir nicht alles sehen.

Beitrag "Relais einschalten mit einem Lichtsensor"

von Volker S. (Gast)


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);
}

von Jens M. (schuchkleisser)


Lesenswert?

Das mit dem DigitalWrite üben wir aber nochmal.
Achja: analogRead auch. Pinzuordnungen. Wie IFs funktioneren. Und LCDs.

Und dann überlegen wir auch gleich, wie die anderen Relais schalten 
sollen, dann gibt sich da schon viel.

: Bearbeitet durch User
von Volker S. (Gast)


Lesenswert?

ok,  DigitalWrite

von Volker S. (Gast)


Lesenswert?

das funktioniert alles

von Sebastian R. (sebastian_r569)


Lesenswert?

Volker S. schrieb:
> das funktioniert alles

Unwahrscheinlich.

von Volker S. (Gast)


Lesenswert?

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

von Jens M. (dl4aas) Benutzerseite


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

von Jens M. (dl4aas) Benutzerseite


Lesenswert?

Noch was: ein digitalWrite sollte LOW setzen, oder? Sonst passiert dem 
Relay gar nichts. Vermutlich das zweite, wenn die Erde nass ist...

von Volker S. (Gast)


Lesenswert?

die anderen Relays sollen nicht parallel schalten.
Jedes Relay hat einen eigenen Sensor

von Jens M. (dl4aas) Benutzerseite


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);
}

von Jens M. (schuchkleisser)


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...

von Harald K. (kirnbichler)


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.

von Jens M. (dl4aas) Benutzerseite


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.

von Jens M. (schuchkleisser)


Lesenswert?

Jens M. schrieb:
> Gruß vom nicht so schlauen Jens M.

LOL :D
Jeder bringt was anderes ein.
Dein Code war die einfache Erweiterung um das Problem zu zeigen.
"richtig" hätte man das ganz anders aufgerollt.
So gesehen ist doch alles ok...

von Rolf (rolf22)


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.

von Jens M. (schuchkleisser)


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?

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

warum ist denn in den Textmeldungen die

"Anlage Aus"
aber der
"Motor OFF"

Auch die anderen Textmeldungen sind eher deutsch. Ich bin hier nicht die 
Sprachpolizei, wunder mich halt einfach dass manchmal Dinge, die das 
selbe sagen/machen, anders benannt sind.

von Jens M. (schuchkleisser)


Lesenswert?

Wegstaben V. schrieb:
> selbe sagen/machen, anders benannt sind.

Und das beide Signale immer gleich stehen (ein/on <-> aus/off))

Bei einem System mit 4 Pumpen und einem Display mit 2 Zeilen a 16 
Zeichen böte sich an je 7-8 Zeichen pro Kanal ins Display zu bringen.
"1: OK   2: Pumpt"
"3: OK   4: Alarm"

von Volker S. (Gast)


Lesenswert?

Danke für Eure Antworten
Bie Antworten haben alles nichts mit meiner Frage zutun
Da hätte ich auch eine Wand fragen können

von Jens M. (schuchkleisser)


Lesenswert?

Volker S. schrieb:
> Bie Antworten haben alles nichts mit meiner Frage zutun

Oh, wenn du dich da man nicht derbe vertust.
Einige der Antworten hier haben sehr sehr viel mit deiner Frage zu tun, 
und die anderen Antworten haben sehr sehr viel mit den anderen Problemen 
in "deinem" Programm zu tun.

von Hans (ths23)


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.

von Harald K. (kirnbichler)


Lesenswert?

Was übrigens hat das hier unter "Projekte & Code" verloren?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Harald K. schrieb:
> Was übrigens hat das hier unter "Projekte & Code" verloren?

Habs verschoben.

von Arduino F. (Firma: Gast) (arduinof)


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.

von Obelix X. (obelix)


Lesenswert?

Arduino F. schrieb:
> Erstmal, es wird viel von C gesprochen, das ist nicht richtig.
> Es ist C++!

Das wird dem TO aber auch egal sein, da er ja die grundlegendsten Dinge 
eh nicht lernen möchte und Rat eh nicht annimmt.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Der TO hat sich mittlerweile auch abgemeldet.

Beitrag #7806190 wurde von einem Moderator gelöscht.
von Arduino F. (Firma: Gast) (arduinof)


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

: Bearbeitet durch User
von Jens M. (schuchkleisser)


Lesenswert?

Arduino F. schrieb:
> In C++ sollte das dann eher so aussehen:

Das ist dann aber nicht mehr Arduino/Maker-Dialekt ;)

von Rainer W. (rawi)


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/

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.