Edit:
Wollte das zunächst über USB machen, Ethernet ist doch schlauer, Thema angepasst
Hi,
gibt es was fertiges?
Ich brauche folgendes:
Arduino Mega
16-Relaisplatine (für Steckdosen und Lampen)
16 Eingänge (da hängen Taster dran)
Soll:
autark funktionieren (also ohne irgend einen Steuercomputer / Server)
Optional per USB an nem RasPi angeschlossen werden, so dass fhem über den Status der Relais bescheid weiß und die Relais auch schalten kann
Wichtig ist, dass das ganze auch ohne irgend einen anderen Server funktioniert. Nur Arduino + Strom.
Gibt es da etwas fertiges?
MySensors könnte sowas in die Richtung. Für einen teilautarken Betrieb muß aber eine Option definiert sein bzw. eine max. Wartezeit, siehe MY_TRANSPORT_WAIT_READY_MS.
Könntest Du als serielles GW umsetzen.
Homebrewired ging evtl. auch, da kenn e ich mich aber nicht aus.
Gruß, Beta-User
Mercy.
Nach einigem einlesen habe ich beschlossen, das mit dem USB zu streichen und ein W5100 Shield zu nehmen.
Nachdem es auch da nichts wirklich fertiges gibt, schreibe ich das Ding selber:
Beschreibung:
Arduino Mega
16x Relais Platine (5V Schaltspannung, nicht 12V), per Optokoppler isoliert
W5100 Ethernetshield
Zielsetzung:
Zu jedem Input Port soll ein Output Port zugeordnet sein
An den Inputs werden normale Taster angeschlossen
autarker Betrieb
Wenn per Netzwerk mit fhem verbunden, soll fhem den Zustand der Outputs kennen (Licht an / aus) sowie selber die Ports steuern können
Was geht bis jetzt:
Hardware:
läuft
Software:
Statemachine für die I/O Paare läuft
Umschalten Licht an / aus dementsprechend auch
Taster sind mit bis zu 20m an Cat 6 Kabel an Arduino Mega angeschlossen, 5V eingebauter PullUp, scheint auch zu laufen (kurzer Test war jedenfalls erfolgreich)
Debouncing wird gefiltert
Reconnect zum Broker läuft auch, non blocking
aktuellen state publishen => läuft auf Arduio Seite (bekomme ihn aber noch nicht in fhem sichtbar, ist andere Baustelle)
ToDo:
Subscriben der Topics und Einbau in die Schaltlogik
ToDo (später):
Absichern MQTT mit Username / Passwort
Ich nenne es mal Hausautomatisierung für Arme:
Die Mehrkosten / Taster belaufen sich quasi auf ca. 2 €...
Wenn jemand mit etwas Erfahrung im Umgang it GitHub hat, würde ich gerne den Code zur Verfügung stellen, damit wir gemeinsam daran basteln können. Ich denke, das macht mehr Sinn als ihn hier in einem Thread zu posten?
Falls es wen interessiert, hier mal mein aktueller Code:
/*
Liesmich
Gedacht für einen Arduino Mega
16 Tastereingänge
16 Relaisausgänge
W5100 Ethernetshield
MQTT (Nonblocking)
Im Skript eigene Werte anpassen:
byte mac
IPAddess ip
IPAdress server
Taster taster_1(38, 22, InputTopic, OutputTopic); <= hier Input Pin und Output Pin angeben, Befehle werden von InputTopic angenommen, Zusatnd aufOutputTopic geschrieben
Name ist im Prinzip egal;
Wichtig ist, im Skript unter void loop() auch die Namen anpassen, bzw. nicht benötigte Aufrufe auszukommentieren
*/
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
// Update these with values suitable for your hardware/network.
byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 5, 10);
IPAddress server(192, 168, 5, 2);
void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
}
EthernetClient ethClient;
PubSubClient client(ethClient);
long lastReconnectAttempt = 0;
boolean reconnect() {
if (client.connect("arduinoClient1")) {
// Once connected, publish an announcement...
client.publish("outTopic","hello world");
// ... and resubscribe
client.subscribe("inTopic");
}
return client.connected();
}
class Taster
{
//Definieren der Namen für die Input PINs
int Input_PIN;
//Definieren der Namen für die Output Pins
int Output_PIN;
//Definieren der Sates
int state = HIGH;
//Readings der Input Pins
int reading;
//Previous Reading Input Pins
int previous = HIGH;
//Variablen für die Zeit
long debounce = 1500;
long time_1 = 0;
//String fuer Input und Output Topics
const char* InputTopic;
const char* OutputTopic;
//
public:
Taster(int input, int output, const char* mqttInput, const char* mqttOutput)
{
Input_PIN = input;
Output_PIN = output;
pinMode(Input_PIN, INPUT_PULLUP);
digitalWrite(Output_PIN, HIGH); // verhindert das Schalten wenn der RelaisPin auf OUTPUT gesetzt wird
pinMode(Output_PIN, OUTPUT);
InputTopic = mqttInput;
OutputTopic = mqttOutput;
}
void Update()
{
reading = digitalRead(Input_PIN);
// if the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
// habe LOW und HIGH umgedreht, um invertierter Logik gerecht zu werden
// https://www.arduino.cc/en/tutorial/switch
if (reading == LOW && previous == HIGH && millis() - time_1 > debounce) {
if (state == LOW)
state = HIGH;
else
state = LOW;
time_1 = millis();
Serial.println();
Serial.println("*****");
Serial.println("Arbeit!");
Serial.println("Taster auf folgendem Pin");
Serial.println(Input_PIN);
Serial.println("Hat folgenden PIN geschaltet");
Serial.println(Output_PIN);
Serial.println("Die Laufzeit ist");
Serial.println(time_1);
Serial.println("Der Zustand des Output PINs ist jetzt");
Serial.println(state);
Serial.println("Achtung, fuer das Relais ist es invertiert!");
Serial.println();
Serial.println("Der wirkliche Status wurde in folgendes Topic published:");
Serial.println(OutputTopic);
digitalWrite(Output_PIN, state);
previous = HIGH;
if (state == LOW)
client.publish(OutputTopic,"on");
else
client.publish(OutputTopic,"off");
}
//Hier kommt der Teil für MQTT subscribe
//client.subscribe(InputTopic);
}
};
Taster taster_1(38, 22, "Wohnort/Wohnhaus/1_OG/Kueche/Licht/set", "Wohnort/Wohnhaus/1_OG/Kueche/Licht/state");
//Taster taster_2(39, 23);
//Taster taster_3(40, 24);
//Taster taster_4(41, 25);
//Taster taster_5(42, 26);
//Taster taster_6(43, 27);
//Taster taster_7(44, 28);
//Taster taster_8(45, 29);
//Taster taster_9(46, 30);
//Taster taster_10(47, 31);
//Taster taster_11(48, 32);
//Taster taster_12(49, 33);
//Taster taster_13(50, 34);
//Taster taster_14(51, 35);
////Taster taster_15(52, 36);
//Taster taster_16(53, 37);
void setup() {
// put your setup code here, to run once:
//********************************************************************************
//******************** Ausgabe auf der seriellen Schnittstelle *******************
//********************************************************************************
Serial.begin(9600);
Serial.println("Configuration:");
Serial.println(" ");
Serial.println("Output: PIN 22 - 37");
Serial.println("Jeder Output Pin wird bei Start des Aduinos auf HIGH gelegt");
Serial.println("d.h. durch die Optokoppler auf der Relaisplatine gehen alle Lichter AUS");
Serial.println(" ");
Serial.println("Input: PIN 38 - 53");
Serial.println("die Input Pins verwenden den eingebauten PullUp");
Serial.println("d.h. es liegen immer 5V an");
Serial.println("Ein Tasterdruck bewirkt einen Spannungsabfall und dann wird geschaltet");
Serial.println(" ");
Serial.println("Ethernet:");
Serial.println("Die IP Adresse des Arduinos ist:");
Serial.println(ip);
Serial.println("Die MQTT Broker Adresse muss eingestellt sein auf:");
Serial.println(server);
Serial.println("der Reconnect ist non-blocking, ein Ausfall des MQTT Servers hat keine Konsequenzen");
Serial.println("Prinzipiell braucht man also auch gar keinen");
Serial.println("sobald er da ist, wird er nach spaetestens 5 Sekunden benutzt");
//*********************************************************************************
client.setServer(server, 1883);
client.setCallback(callback);
Ethernet.begin(mac, ip);
delay(1500);
lastReconnectAttempt = 0;
//*********************************************************************************
}
void loop() {
//********** Prüfen, ob Verbindung besteht ***********************
if (!client.connected()) {
long now = millis();
if (now - lastReconnectAttempt > 5000) {
lastReconnectAttempt = now;
// Attempt to reconnect
if (reconnect()) {
lastReconnectAttempt = 0;
}
}
} else {
// Client connected
client.loop();
}
//*****************************************************************
taster_1.Update();
//taster_2.Update();
//taster_3.Update();
//taster_4.Update();
//taster_5.Update();
//taster_6.Update();
//taster_7.Update();
//taster_8.Update();
//taster_9.Update();
//taster_10.Update();
//taster_11.Update();
//taster_12.Update();
//taster_13.Update();
//taster_14.Update();
////taster_15.Update();
//taster_16.Update();
}