Regensensor Relais erkennen

Hallo zusammen,

Bin noch relativ unerfahren mit Arduino, deswegen bitte ich um Nachsicht, falls dies eine dumme Frage ist. Aber ich würde mir ungern mein teures Board zerschiessen ::slight_smile:

Ich habe mir diesen Regensensor gekauft, welcher einen potentialfreien Schaltausgang hat und bei Nässe wahlweise als Schliesser/Öffner funktioniert. Diesen Sensor möchte ich an ein Z-Uno Board anschliessen, um Regen per Z-Wave an meine Hausautomatisierung zu melden, damit z.B. die Markisen autom. eingefahren werden können.

Wie bekomme ich es nun hin, dass der Z-Uno die Relais-Position erkennt? Der Z-Uno verträgt an den Pins max. 3,3V. Meine Überlegung war, dass ich den 3.3V Ausgang des Boards mit REL CO des Regensensors verbinde und REL NO mit einem Pin des Boards, sowie über einen 10k Ohm Widerstand mit GND des Z-Uno. Anschliessend müsste sich ja mittels digitalRead() das HIGH/LOW-Signal am Pin auslesen lassen. Würde das so funktionieren oder gibt es eine bessere Lösung?

Beste Grüsse aus der Schweiz,
Rob

Scheint mir ok zu sein....

Oder du verwendest einen internen Pullup und legst den GPIO auf einen Relaiskontakt. Der andere Kontakt kommt auf GND.
Im Sketch fragst du nach LOW ab.

Danke für eure Antworten. Da bin ich ja schon mal froh, dass meine Überlegung nicht grundfalsch war! :wink:

@HotSystems: D.h. ich verbinde lediglich einen Pin des Z-UNO mit REL CO und dann REL NO mit GND. Die Verbindung mit 3,3V und der Widerstand fallen dann weg? Das wäre natürlich viel einfacher! Und der Sketch würde dann ungefähr so aussehen...

#define REGENSENSOR_PIN 2

void setup() {
  pinMode(REGENSENSOR_PIN, INPUT_PULLUP);
}


void loop() {
  if (digitalRead(REGENSENSOR_PIN) == LOW) {
    // Meldung an ioBroker: Es regnet
  } else {
    // Meldung an ioBroker: Es ist trocken
  }

  // Abfrage auf alle 20 Sekunden reduzieren
  delay(20000);
}

korrekt?

Gibt es eine Möglichkeit, das ganze ohne Loop zu realisieren? Sprich wenn das Signal HIGH/LOW ändert, wird eine funktion ausgeführt?

Ja, das sieht gut aus.
Bis auf dein delay(). Das funktioniert auch, aber du blockierst damit den Sketch. Besser ist es mit der Funktion "millis()", sieh dir dazu BlinkWithoutDelay. Oder du verwendest eine Timerfunktion wie z.B. SimpleTimer o.ä.

Für den Ablauf geht es nicht ohne die Loop.

Gibt es eine Möglichkeit, das ganze ohne Loop zu realisieren? Sprich wenn das Signal HIGH/LOW ändert, wird eine funktion ausgeführt?

Natürlich!

Nennt sich dann Hardware Interrupt.

combie:
Natürlich!

Nennt sich dann Hardware Interrupt.

Ok, dann kann man auch auf den Controller komplett verzichten und einen NE555 o.ä. einsetzen.

HotSystems:
Ja, das sieht gut aus.
Bis auf dein delay(). Das funktioniert auch, aber du blockierst damit den Sketch. Besser ist es mit der Funktion "millis()", sieh dir dazu BlinkWithoutDelay. Oder du verwendest eine Timerfunktion wie z.B. SimpleTimer o.ä.

Für den Ablauf geht es nicht ohne die Loop.

Prima, vielen Dank für die Hilfe!!! Hab's jetzt so geändert...

#define REGENSENSOR_PIN 2

unsigned long letzteMillis = 0;
const long abfrageIntervall = 20000;

void setup() {
  pinMode(REGENSENSOR_PIN, INPUT_PULLUP);
}

void loop() {

  unsigned long aktuelleMillis = millis();

  if (aktuelleMillis - letzteMillis >= abfrageIntervall) {

    letzteMillis = aktuelleMillis;

    if (digitalRead(REGENSENSOR_PIN) == LOW) {
      // Meldung an ioBroker: Es regnet
    } else {
      // Meldung an ioBroker: Es ist trocken
    }
  }
}

Ok, sollte so auch funktionieren.
Danke für deine Rückmeldung.

const long abfrageIntervall = 20000;

const unsigned long abfrageIntervall = 20000;

Oder möchtest du da aus einem bestimmten Grund ein Vorzeichen haben?

combie:
const unsigned long abfrageIntervall = 20000;

Oder möchtest du da aus einem bestimmten Grund ein Vorzeichen haben?

Guter Punkt, danke für den Hinweis!

qmrk:
danke für den Hinweis!

Dann noch einen:

#define REGENSENSOR_PIN 2

const uint8_t REGENSENSOR_PIN=2;
Wobei das mit den Grossbuchstaben nicht unbedingt gefällt.

my_xy_projekt:
Dann noch einen:

#define REGENSENSOR_PIN 2

const uint8_t REGENSENSOR_PIN=2;
Wobei das mit den Grossbuchstaben nicht unbedingt gefällt.

Aha... again what learned!! Bisher habe ich mir bei der Verwendung von #define gar keine Gedanken darüber gemacht. Wenn ich meine Google-Recherche richtig verstanden habe, dann würde man lediglich bei alphanumerischen Pins #define verwenden, korrekt?

Nö, Du kannst auch const uint8_t analogInputPin=A0; schreiben.

Gruß Tommy

Wenn ich meine Google-Recherche richtig verstanden habe, dann würde man lediglich bei alphanumerischen Pins #define verwenden, korrekt?

Verstehe ich nicht.

#define verwendet man nur, wenn es keine Alternativen gibt.

Mantra:

Jedes vermeidbare **** ist ein böses ****
Jedes vermiedene **** ist ein gutes ****

Ersetze **** durch #define

Im Grunde gilt das für alle Sprachkonstrukte!
Was übrig bleibt ist dann ein Häuflein notwendiger Dinge, welche das Programm bilden.

qmrk:
dann würde man lediglich bei alphanumerischen Pins #define verwenden, korrekt?

Nein.
Wenn möglich gar nicht define für Pins.
Versuche folgendes:

const byte PIN=2;
const byte PIN=3;
const byte PIN=4;
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

und dann folgendes:

#define PIN 2;
#define PIN 3;
#define PIN 4;
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

zu compilieren.
Was ist der Unterschied?

Danke für eure Inputs. Da habe ich wohl ein Google-Ergebnis falsch interpretiert, dass ich das Gefühl hatte, mit alphanumerischen Pins würde die Deklarierung als const uint8_t nicht funktionieren.

In meinem Fall kennt der Z-Uno den Datentyp uint8_t nicht (https://z-uno.z-wave.me/reference/), also werde ich die #define Variablen durch unsigned int ersetzen...

@my_xy_projekt Danke, für die Veranschaulichung des Unterschieds bei der Verwendung von #define und const :+1:

Das kann ich nicht glauben!
uint8_t ist Teil der mit dem Compiler gelieferten C++ Libraries

Alle µC, welche 8 Bit pro Byte haben, kennen diesen Type.
Sicherlich auch deiner!

Zudem gibts in der (hoffnungslos unvollständigen) Liste auch byte.
Was gefällt dir an byte nicht?
byte dürfte mit uint8_t identisch sein.

Beim Versuch die Pins als const uint8_t zu deklarieren bekomme ich beim Kompilieren folgende Fehlermeldung:

default initialization of an object of const type 'const uint8_t' (aka 'const unsigned char')

An die Verwendung von byte hatte ich gar nicht gedacht, aber nach deinem Hinweis und dem Durchlesen der Doku (A byte stores an 8-bit unsigned number, from 0 to 255.) wäre dies wohl sogar die bessere Option als unsigned int...

Sorry, mein Fehler... Da hatte ich wohl Tomaten auf den Augen! :see_no_evil:

Mit const uint8_t RELAY_1_PIN 0; bekam ich o.g. Fehlermeldung, aber mit const uint8_t RELAY_1_PIN = 0; funktioniert's natürlich auch einwandfrei...