Integracja Arduino Mega + Ethernet Shield z HA przez MQTT

Dodałem kolejny czujnik do mojego projektu tym razem detektor światła na LM393.
Co prawda ma on tylko stan 0 lub 1 (jasno/ciemno) ale potencjometrem można sterować czułość przy jakim natężeniu światła czujnik zadziała.
Czujnik przyda się w automatyzacjach np. jeśli jest ciemno zapal lampy. Koszt sensora to aż 2,90 zł :wink:
Czujnik podpiamy do Arduino do 3,3V lub 5V, GND, Pin 5.

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <DHT.h>
#define humidity_topic "arduino01/humidity"
#define temperature_topic "arduino01/temperature"
#define contactron_topic "arduino01/door"
#define light_topic "arduino01/light"
#define DHTPIN 2 // 2 Pin Arduino do ktorego podlaczony jest czujnik
#define DHTTYPE DHT22 //21 or 22 w zaleznosci od czujnika
#define KONTAKTRON 3 //3 pin Arduino do kontaktronu
#define CZUJNIKSWIATLA 5 //5 pin Arduino do czujnika światła

DHT dht(DHTPIN, DHTTYPE);
unsigned long readTime;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAD };
IPAddress ip(192, 168, 2, 225); // Adres IP Arduino
IPAddress server(192, 168, 2, 1); // Adres IP bramki z serwerem MQTT
char message_buff[100];
EthernetClient ethClient;
PubSubClient client(ethClient);
void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  for (int i = 0; i < length; i++) {
  Serial.print((char)message[i]);
  messageTemp += (char)message[i];
  }
}

void reconnect() {
  // Oczekowani na polaczenie z serwerem
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
     Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Czekaj 5 sekund przed ponownym polaczeniem
      delay(5000);
    }
  }
}

void setup()
{
  Serial.begin(9600);
  client.setServer("192.168.2.1", 1883); // Adres serwera MQTT - bramka
  client.setCallback(callback);
  Ethernet.begin(mac);
  dht.begin(); // Start sensor DHT
  pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
  pinMode(CZUJNIKSWIATLA, INPUT); // Czujnik światła
  Serial.println(Ethernet.localIP()); //Wyswietlenie adresu IP Arduino
  readTime = 0;
}

bool checkBound(float newValue, float prevValue, float maxDiff) {
  return !isnan(newValue) &&
         (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff);
}
long lastMsg = 0;
float temp = 0.0;
float hum = 0.0;
float diffhum = 1.0; // częstotliwość odswierzania co 1 %
float diff = 0.1;
int KONT = 2; // stan 2 przy pierwszym odczycie
int light = 2; // stan 2 przy pierwszym odczycie

void loop()
{
  if (!client.connected()) {
  reconnect();
  }

  client.loop();
  long now = millis();
  if (now - lastMsg > 1000) {
    lastMsg = now;
    float newTemp = dht.readTemperature();
    float newHum = dht.readHumidity();
    int newKONT = digitalRead(KONTAKTRON);
    int newlight = digitalRead(CZUJNIKSWIATLA);
     
    // ODCZYT TEMPERATURY
    if (checkBound(newTemp, temp, diff)) {
      temp = newTemp;
      Serial.print("Temperatura: ");
      Serial.println(String(temp).c_str());
      client.publish(temperature_topic, String(temp).c_str(), true);
    }
    // ODCZYT WILGOTNOSCI
    if (checkBound(newHum, hum, diffhum)) {
      hum = newHum;
      Serial.print("Wilgotność: ");
      Serial.println(String(hum).c_str());
      client.publish(humidity_topic, String(hum).c_str(), true);
    }
    // STAN KONTAKTRONU PRZY URUCHOMIENIU
    if (KONT == 2) {     
      if (newKONT == 0){
        Serial.println("Stan kontaktronu: ZAMKNIETY");
        client.publish(contactron_topic, "close", true);
      }
      if (newKONT == 1){
        Serial.println("Stan kontaktronu: OTWARTY");
        client.publish(contactron_topic, "open", true);
      }  
    }
    // STAN KONTAKTRONU PRZY ZMIANIE
    if (newKONT != KONT) {     
      KONT = newKONT;
      if (KONT == 0){
        Serial.println("Stan kontaktronu: ZAMKNIETY");
        client.publish(contactron_topic, "close", true);
      }
      if (KONT == 1){
        Serial.println("Stan kontaktronu: OTWARTY");
        client.publish(contactron_topic, "open", true);
      }
    }
    // ODCZYT NATEZENIA SWIATLA
    if (light == 2) {     
      if (newlight == 0){
        Serial.println("Swiatlo: JASNO");
        client.publish(light_topic, "light", true);
      }
      if (newlight == 1){
        Serial.println("Swialo: CIEMNO");
        client.publish(light_topic, "dark", true);
      }  
    }
    // STAN CZUJNIKA PRZY ZMIANIE
    if (newlight != light) {     
      light = newlight;
      if (light == 0){
        Serial.println("Swiatlo: JASNO");
        client.publish(light_topic, "light", true);
      }
      if (light == 1){
        Serial.println("Swiatlo: CIEMNO");
        client.publish(light_topic, "dark", true);
      }
    }
   
  }
} 

image


Mam jeszcze kilka czujników :slight_smile: wkrótce ciąg dalszy…

3 polubienia

Oczywiście powyższe linie w programie są zbędne (wszystkie komendy Serial.print i Serial.println) jeśli używamy połączenia Ethernet i MQTT a służą jedynie do diagnostyki jakie dane są wysyłane z Arduino. Finalnie możemy je usunąć z programu a wysyłanie do Jolki nadal będzie działać gdyż realizuje to komenda client.publish(light_topic, "dark", true);

Fachowców w dziedzinie programowania w c++ proszę o wyrozumiałości gdyż są to moje początki z Arduino IDE. Efekt finalny osiągnięty i to jest najważniejsze :slight_smile:
Część kodu zaczerpnięta jest z innych projektów dostępnych w necie.

Kolejna wersja projektu MultiSensorsJolka v0.0.3 :slight_smile:

Co nowego doszło:

  • dodałem sterowanie dwoma przekaźnikami “arduino01/cmnd/POWER1” ON/OFF
  • dodałem wysyłanie statusu Arduino “arduino01/tele/LWT” Aktywny/Nieaktywny
  • dodałem ustawianie statusu przekaźników “arduino01/stat/POWER1” po odbiorze komendy ON / OFF wykorzystywane do ustalenia ostatniego stanu przekaźników
  • dodałem wysyłanie statusu do HASS “arduino01/tele/HASS_STATE” z wersją projektu.

Co planuję w kolejnych wersjach:

  • Zrobienie MultiSensora bardziej HA i Sonoff/tasmota friendly :slight_smile: tzn. używanie podobnych nazw wysyłanych/odbieranych komend MQTT;
  • Zrobienie funkcji autodiscovery tak jak mają Sonoffy z oprogramowaniem Tasmota, tzn. wysyłanie informacji jakie czujniki posiada i jakie mają zostać utworzone w HA;
  • Dodanie webservera do Arduino wyświetlającego stan czujników i przekaźników oraz możliwość przełączania (wersja beta serwera web już w trakcie testów);
  • Odczyt ostatniego stanu przekaźników z homeassistant i przekazanie do Arduino;
  • Dodanie kolejnych czujników np. Miernik energii, detektor gazu/czadu itp…
  • Zrobienie bramki do odbioru kodów RF 433 jako odpowiednik Sonoff RF Bridge i wysyłanie ich do Jolki;
  • Jeśli kody odbiera to może i wysyłać i sterować urządzeniami RF 433 :slight_smile:
  • Może i obsługa IRda odbiór i wysyłanie ?
  • Dodanie zmiennej debug on/off - włączającej i wyłączającej wysyłanie komunikatów do portu szeregowego;
  • Zapis loga na kartę MicroSD w Ethernet Shield;
  • sugestie mile widziane :slight_smile:
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <DHT.h>
#define SoftVersion "MultiSensorsJolka v0.0.3 by Iron "
#define SoftBuildDate "2020-02-04T21:09:00"
#define ModuleType "Arduino Mega 2560+Ethernet Shield"
#define humidity_topic "arduino01/tele/SENSORhumidity"
#define temperature_topic "arduino01/tele/SENSORtemperature"
#define contactron_topic "arduino01/tele/SENSORdoor"
#define light_topic "arduino01/tele/SENSORlight"
#define availability_topic "arduino01/tele/LWT" // Aktywny / Nieaktywny
#define state_topic "arduino01/tele/HASS_STATE" 
#define statestatus_topic "arduino01/stat/STATUS"
#define statepower1_topic "arduino01/stat/POWER1" // ON/OFF
#define statepower2_topic "arduino01/stat/POWER2" // ON/OFF
#define command1_topic "arduino01/cmnd/POWER1"
#define command2_topic "arduino01/cmnd/POWER2"
#define DHTPIN 2 // 2 Pin Arduino do ktorego podlaczony jest czujnik
#define DHTTYPE DHT22 //21 or 22 w zaleznosci od czujnika
#define KONTAKTRON 3 //3 pin Arduino do kontaktronu
#define CZUJNIKSWIATLA 5 //5 pin Arduino do czujnika światła
#define PRZEKAZNIK1 6 //6 pin Arduino do przekaźnika 1
#define PRZEKAZNIK2 7 //7 pin Arduino do przekaźnika 2
volatile byte relayState = LOW;

DHT dht(DHTPIN, DHTTYPE);
unsigned long readTime;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAD };
IPAddress ip(192, 168, 2, 225); // Adres IP Arduino
IPAddress server(192, 168, 2, 1); // Adres IP bramki z serwerem MQTT
char message_buff[100];
String AddIP;
String AddMAC;
EthernetClient ethClient;
PubSubClient client(ethClient);

void callback(char* topic, byte* payload, unsigned int length) {
  String payloadmsg;
  for (int i=0;i<length;i++) {
    payloadmsg += (char)payload[i];
  }
  // Zalaczenie przekaznika 1   
  if (strcmp (topic, command1_topic) == 0) {
    Serial.print("Przekaźnik 1 = ");
    if (payloadmsg == "ON") {
      Serial.println("ZAŁĄCZ");
      digitalWrite(PRZEKAZNIK1, LOW); // Załącz przekaźnik 1
      client.publish(statepower1_topic, "ON", true);    
    }
    if (payloadmsg == "OFF") {
      Serial.println("WYŁĄCZ");
      digitalWrite(PRZEKAZNIK1, HIGH); // Wyłącz przekaźnik 1
      client.publish(statepower1_topic, "OFF", true);    
    }
  }
  // Zalaczenie przekaznika 2
  if (strcmp (topic, command2_topic) == 0) {
    Serial.print("Przekaźnik 2 = ");
    if (payloadmsg == "ON") {
      Serial.println("ZAŁĄCZ");
      digitalWrite(PRZEKAZNIK2, LOW); // Załącz przekaźnik 2
      client.publish(statepower2_topic, "ON", true);    
    }
    if (payloadmsg == "OFF") {
      Serial.println("WYŁĄCZ");
      digitalWrite(PRZEKAZNIK2, HIGH); // Wyłącz przekaźnik 2
      client.publish(statepower2_topic, "OFF", true);    
    }
  }
}
void reconnect() {
  // Oczekowani na polaczenie z serwerem
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
     Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Czekaj 5 sekund przed ponownym polaczeniem
      delay(5000);
    }
  }
}

void setup()
{
  Serial.begin(9600);
  client.setServer("192.168.2.1", 1883); // Adres serwera MQTT - bramka
  client.setCallback(callback);
  Ethernet.begin(mac, ip);
  dht.begin(); // Start sensor DHT
  pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
  pinMode(CZUJNIKSWIATLA, INPUT); // Czujnik światła
  pinMode(PRZEKAZNIK1, OUTPUT); // Ustawienie Pinu przekaznika 1 jako Wyjscie
  pinMode(PRZEKAZNIK2, OUTPUT); // Ustawienie Pinu przekaznika 2 jako Wyjscie
  digitalWrite(PRZEKAZNIK1, HIGH); // Wyłacz przekaźnik 1 przy starcie , HIGH - wyłącz, LOW = włącz
  digitalWrite(PRZEKAZNIK2, HIGH); // Wyłacz przekaźnik 2 przy starcie , HIGH - wyłącz, LOW = włącz
  Serial.println(Ethernet.localIP()); //Wyswietlenie adresu IP Arduino
  AddIP = String(Ethernet.localIP()).c_str();

  byte macBuffer[6];  // create a buffer to hold the MAC address
  //Ethernet.MACAddress(macBuffer); // fill the buffer
  Ethernet.MACAddress(macBuffer); //Wyswietlenie MAC Arduino
  for (byte octet = 0; octet < 6; octet++) {
    AddMAC += macBuffer[octet], HEX;
    Serial.print(macBuffer[octet], HEX); 
    if (octet < 5) {
      Serial.print('-');
    }
  }
  Serial.println();  
  readTime = 0;
}

bool checkBound(float newValue, float prevValue, float maxDiff) {
  return !isnan(newValue) &&
         (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff);
}
long lastMsg = 0;
long lastMsg1 = 0;
float temp = 0.0;
float hum = 0.0;
float diffhum = 1.0; // częstotliwość odswierzania co 1 %
float diff = 0.1;
int KONT = 2; // stan 2 przy pierwszym odczycie
int light = 2; // stan 2 przy pierwszym odczycie

void loop()
{
  if (!client.connected()) {
  reconnect();
  }
  client.loop();
  long now1 = millis();
  if (now1 - lastMsg1 > 40000) {
    lastMsg1 = now1;   
   //Wyslij status
    String statemsg = "";
    statemsg += "{\"Version\":\"";
    statemsg += SoftVersion;
    statemsg += "\",\"BuildDateTime\":\"";
    statemsg += SoftBuildDate;
    statemsg += "\"}";
    client.publish(state_topic, String(statemsg).c_str(), true);
    Serial.println(String(statemsg).c_str());
    client.publish(statestatus_topic, "{\"Status\":{\"Module\":0,\"FriendlyName\":[\"Arduino01_lampa1\",\"Arduino01_lampa2\"],\"Topic\":\"Arduino01\"}}", true);
    client.publish(availability_topic, "Aktywny", true);
  }   
  long now = millis();
  if (now - lastMsg > 1000) {
    lastMsg = now;
    float newTemp = dht.readTemperature();
    float newHum = dht.readHumidity();
    int newKONT = digitalRead(KONTAKTRON);
    int newlight = digitalRead(CZUJNIKSWIATLA);
    boolean rc1 = client.subscribe(command1_topic); // Oczykiwanie na topic dla przekaźnika 1
    boolean rc2 = client.subscribe(command2_topic); // Oczykiwanie na topec dla przekaźnika 2    
    // ODCZYT TEMPERATURY
    if (checkBound(newTemp, temp, diff)) {
      temp = newTemp;
      Serial.print("Temperatura: ");
      Serial.println(String(temp).c_str());
      client.publish(temperature_topic, String(temp).c_str(), true);
    }
    // ODCZYT WILGOTNOSCI
    if (checkBound(newHum, hum, diffhum)) {
      hum = newHum;
      Serial.print("Wilgotność: ");
      Serial.println(String(hum).c_str());
      client.publish(humidity_topic, String(hum).c_str(), true);
    }
    // STAN KONTAKTRONU PRZY ZMIANIE
    if (newKONT != KONT) {     
      KONT = newKONT;
      if (KONT == 0){
        Serial.println("Stan kontaktronu: ZAMKNIETY");
        client.publish(contactron_topic, "close", true);
      }
      if (KONT == 1){
        Serial.println("Stan kontaktronu: OTWARTY");
        client.publish(contactron_topic, "open", true);
      }
    }
    // STAN KONTAKTRONU PRZY URUCHOMIENIU
    if (KONT == 2) {     
      if (newKONT == 0){
        Serial.println("Stan kontaktronu: ZAMKNIETY");
        client.publish(contactron_topic, "close", true);
      }
      if (newKONT == 1){
        Serial.println("Stan kontaktronu: OTWARTY");
        client.publish(contactron_topic, "open", true);
      }  
        client.publish(availability_topic, "online", true);
    } 
    // STAN CZUJNIKA PRZY ZMIANIE
    if (newlight != light) {     
      light = newlight;
      if (light == 0){
        Serial.println("Swiatlo: JASNO");
        client.publish(light_topic, "light", true);
      }
      if (light == 1){
        Serial.println("Swiatlo: CIEMNO");
        client.publish(light_topic, "dark", true);
      }
    }
    // ODCZYT NATEZENIA SWIATLA
    if (light == 2) {     
      if (newlight == 0){
        Serial.println("Swiatlo: JASNO");
        client.publish(light_topic, "light", true);
      }
      if (newlight == 1){
        Serial.println("Swiatlo: CIEMNO");
        client.publish(light_topic, "dark", true);
      }  
    }
  }
}  

Sensors.yaml

  • platform: mqtt
    name: “Arduino01 Status”
    state_topic: “arduino01/tele/HASS_STATE”
    availability_topic: “arduino01/tele/LWT”
    expire_after: 1000
    payload_available: “Aktywny”
    payload_not_available: “Nieaktywny”
    qos: 0
    json_attributes_topic: “arduino01/tele/HASS_STATE”
    value_template: “{{ value_json.Version }}”
- platform: mqtt
  name: "Arduino01 Temp test"
  state_topic: "arduino01/tele/SENSORtemperature"
  availability_topic: "arduino01/tele/LWT"
  payload_available: "Aktywny"
  payload_not_available: "Nieaktywny"
  qos: 0
  unit_of_measurement: "°C"
  value_template: '{{ value | round(1) }}'

- platform: mqtt
  name: "Arduino01 Wilgotność test"
  state_topic: "arduino01/tele/SENSORhumidity"
  availability_topic: "arduino01/tele/LWT"
  payload_available: "Aktywny"
  payload_not_available: "Nieaktywny"
  qos: 0
  unit_of_measurement: "%"

binary_sensors.yaml

  • platform: mqtt
    name: ‘JasnoCiemno’
    state_topic: ‘arduino01/tele/SENSORlight’
    availability_topic: “arduino01/tele/LWT”
    payload_on: “light”
    payload_off: “dark”
    device_class: light
    payload_available: “Aktywny”
    payload_not_available: “Nieaktywny”
- platform: mqtt
  name: 'Drzwi'
  state_topic: 'arduino01/tele/SENSORdoor'
  availability_topic: "arduino01/tele/LWT"
  payload_on: "open"
  payload_off: "close"
  device_class: door
  payload_available: "Aktywny"
  payload_not_available: "Nieaktywny"

switch,yaml

- platform: mqtt
  name: "Arduino Switch1"
  command_topic: "arduino01/cmnd/POWER1"
  payload_on: "ON"
  payload_off: "OFF"
  state_topic: "arduino01/stat/POWER1"
  state_on: "ON"
  state_off: "OFF"
  optimistic: true
  qos: 0
  retain: false
  availability_topic: "arduino01/tele/LWT"
  payload_available: "Aktywny"
  payload_not_available: "Nieaktywny"

- platform: mqtt
  name: "Arduino Switch2"
  command_topic: "arduino01/cmnd/POWER2"
  payload_on: "ON"
  payload_off: "OFF"
  state_topic: "arduino01/stat/POWER2"
  state_on: "ON"
  state_off: "OFF"
  optimistic: true
  qos: 0
  retain: false
  availability_topic: "arduino01/tele/LWT"
  payload_available: "Aktywny"
  payload_not_available: "Nieaktywny"
2 polubienia

Znalazłem ciekawy projekt http://cactus.io/

Bez problemu można by wykorzystać mój projekt do integracji stacji pogodowej z Jolką :slight_smile: pewnie w przyszłości zrobię taką stację pogodową .

1 polubienie

Z takich pomysłów co by można jeszcze przydatnego zrobić :slight_smile:

  • Zrobienie bramki do odbioru kodów RF 433 jako odpowiednik Sonoff RF Bridge i wysyłanie ich do Jolki;
  • Jeśli kody odbiera to może i wysyłać i sterować urządzeniami RF 433 - zastąpi to Broadlink RM Pro który do tanich nie należy :slight_smile:
  • Może i obsługa IRda odbiór i wysyłanie ? Tego nie ma ani Sonoff RF Bridge ani Broadlink RM Pro żeby sterować urządzeniami dowolnymi pilotami IRda :slight_smile:
    Broadlink może sam wysyłać kody IRda i uczyć się ich ale nie ma możliwości w trybie ciągłym odbioru kodów IRda a Sonoff RF Bridge nie obsługuje odbioru kodów IRda.
1 polubienie

Kolejna wersja projektu tym razem z autowykrywaniem sensorów przez Home Assistant. Nie ma już potrzeby definiowania w plikach sensor,switch,binary_sensor. Po uruchomieniu Arduino - Jolka automatycznie wykryje sensory i przełączniki.

image

temp wilg

/* 
 ====== MultiSensorsJolka by Iron ======
 ======      Testing platform     ======
 Arduino Mega 2560 + Ethernet Shield

 ====== Changelog ======
 v0.0.8
 - optymalizacja programu;
 v0.0.7
 - poprawa kilku features związanych z nowym HA 105;
 v0.0.6
 - autoDiscovery Home Assistant;
 v0.0.5
 - zmiana precyzji do 1 mijsca po przecinku;
 - dodanie zmiennej int SerialPrint = 0 - wyłącza debug do portu szeregowego, int WebServer = 0 - wyłącza WebServer;
 v0.0.4
 - dodanie webservera do Arduino
 - odczyt ostatniego stanu przekaźników z homeassistant
 v0.0.3
 - sterowanie dwoma przekaźnikami "arduino01/cmnd/POWER1" ON/OFF;
 - wysyłanie statusu Arduino "arduino01/tele/LWT" Aktywny/Nieaktywny;
 - ustawianie statusu przekaźników “arduino01/stat/POWER1” po odbiorze komendy ON / OFF wykorzystywane do ustalenia ostatniego stanu przekaźników;
 - porządek w topicach według struktury by tasmota: "arduino01/tele/SENSORtemperature", "arduino01/tele/SENSORhumidity", "arduino01/tele/SENSORdoor", "arduino01/tele/SENSORlight", 
 - wysyłanie statusu do HASS "arduino01/tele/HASS_STATE" z wersją projektu;
 v0.0.2
 - odczyt wilgotności co 1% a nie co 0.10 - ustawienie można zmienić w float diffhum = 1.0; // częstotliwość odswierzania co 1 %, float diff = 0.1; - tempratura co 0.1 stopień
 - dodanie obsługi kontaktronu (Kontaktron podpinamy pod PIN 3 Arduino, drugi przewód do GND. - #define KONTAKTRON 3)
 - wysyłanie statusu otwarte/zamknięte w topicu "arduino01/door"
 - dodanie obsługi czujnika/detektora światła LM393 -  Czujnik podpiamy do Arduino do Pinu 5 oraz 5V i GND;
 - czujnik ma on tylko stan 0 lub 1 (jasno/ciemno) ale potencjometrem można sterować czułość przy jakim natężeniu światła czujnik zadziała.
 v0.0.1
 - dodanie obsługi czujnika temperatury i wilgotności AM2302 lub DHT21, DHT22 (Czujnik podłączamy pod 2 pin Arduino oraz 5V i GND - #define DHTPIN 2) #define DHTTYPE DHT22 //21 or 22 w zaleznosci od czujnika
 - odczyt temperatury i wilgotności i publiowanie w topicu arduino01/tempertura, arduino01/humidity;
 - przesyłanie tylko różnicy wartości wcześniej odczytej
 ====== ToDo List ======
 - dodanie kolejnych czujników np. Miernik energii, detektor gazu/czadu itp…
 - zapis loga na kartę MicroSD w Ethernet Shield;
 ================================================================================================================================================================================================*/
#include <SPI.h>
#include <Ethernet.h>
#define MQTT_KEEPALIVE 10
#include <PubSubClient.h>
#include <DHT.h>
#define SoftVersion "MultiSensorsJolka v0.0.8 by Iron"
#define SoftBuildDate "2020-02-10T21:20:00"
#define ModuleType "Arduino Mega 2560+Ethernet Shield"
#define sensors_topic "dom-88fd54db6487cd19_arduino01/tele/SENSOR"
#define contactron_topic "dom-88fd54db6487cd19_arduino01/tele/SENSORdoor01"
#define light_topic "dom-88fd54db6487cd19_arduino01/tele/SENSORlight01"
#define availability_topic "dom-88fd54db6487cd19_arduino01/tele/LWT" // Aktywny / Nieaktywny
#define state_topic "dom-88fd54db6487cd19_arduino01/tele/HASS_STATE"
#define statestatus_topic "dom-88fd54db6487cd19_arduino01/stat/STATUS"
#define statepower1_topic "dom-88fd54db6487cd19_arduino01/tele/POWER1" // ON/OFF
#define statepower2_topic "dom-88fd54db6487cd19_arduino01/tele/POWER2" // ON/OFF
#define command1_topic "dom-88fd54db6487cd19_arduino01/cmnd/POWER1"
#define command2_topic "dom-88fd54db6487cd19_arduino01/cmnd/POWER2"
#define autodiscovery_send_topic "dom/cmnd/SetOption19"
#define autodiscovery_light_topic "homeassistant/light/arduino01/light/config"
#define autodiscovery_switch1_topic "homeassistant/switch/arduino01_RL_1/config"
#define autodiscovery_switch2_topic "homeassistant/switch/arduino01_RL_2/config"
#define autodiscovery_binary1_topic "homeassistant/binary_sensor/arduino01_BTN_1/config"
#define autodiscovery_binary2_topic "homeassistant/binary_sensor/arduino01_BTN_2/config"
#define autodiscovery_sensor1_topic "homeassistant/sensor/arduino01_AM2302_Temperature/config"
#define autodiscovery_sensor2_topic "homeassistant/sensor/arduino01_AM2302_Humidity/config"
#define autodiscovery_status_topic "homeassistant/sensor/arduino01_status/config"
#define DHTPIN 8 // 8 Pin Arduino do ktorego podlaczony jest czujnik
#define DHTTYPE DHT22 //21 or 22 w zaleznosci od czujnika lub AM2302 = DTH22
#define KONTAKTRON 3 //3 pin Arduino do kontaktronu
#define CZUJNIKSWIATLA 5 //5 pin Arduino do czujnika światła
#define PRZEKAZNIK1 6 //6 pin Arduino do przekaźnika 1
#define PRZEKAZNIK2 7 //7 pin Arduino do przekaźnika 2
#define PRZEKAZNIK3 8 //8 pin Arduino do przekaźnika 3
#define PRZEKAZNIK4 9 //9 pin Arduino do przekaźnika 4
//USE PIN Mega Ethernet Shield 0,1, 4,10, 50,51,52,53
//USE PIN UNO  Ethernet Shield 0,1, 4,10, 11,12,13

int SerialPrint = 1; // 0 - nie wysyłaj nic do portu szeregowego, 1 - debug log do portu szeregowego
int WebServer = 0;   // 0 - nie uruchamiaj WebServera, 1 - uruchom webserver
int AutoRestart = 0; // 0 - bez restaru, 1 - autorestart
int RestartTime = 1800000; // 1800000 = 30 minut
volatile byte relayState = LOW;

DHT dht(DHTPIN, DHTTYPE);
unsigned long readTime;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAD };
IPAddress ip(192, 168, 2, 225); // Adres IP Arduino
IPAddress server(192, 168, 2, 1); // Adres IP bramki z serwerem MQTT
char message_buff[100];
String AddIP;
String AddMAC;
String przekaznik1stan;
String przekaznik2stan;
int startprg = 1;
long MQTTread;

void callback(char* topic, byte* payload, unsigned int length);
EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);
//EthernetServer serverweb(80);

void callback(char* topic, byte* payload, unsigned int length) {
  String payloadmsg;
  for (int i=0;i<length;i++) {
    payloadmsg += (char)payload[i];
  }
 if (SerialPrint == 1) {
        Serial.print("topic received = ");
        Serial.println(topic);}
    // Autodiscovery po starcie HA
  if (strcmp (topic, autodiscovery_send_topic) == 0) { autodiscoveryHA(); }
  
  // Pierwsze włączenie arduino - odczyt stanów przekaźników z HA
  if (startprg == 1 || startprg == 2){
    if (strcmp (topic, statepower1_topic) == 0) {
      startprg = 2;
      MQTTread += 1;
      if (SerialPrint == 1) {
        Serial.print("Stan przekaźnika 1 = ");
        Serial.println(payloadmsg);}
      if (payloadmsg == "ON") {
        przekaznik1stan = "ZAŁĄCZONY";
        digitalWrite(PRZEKAZNIK1, LOW); // Załącz przekaźnik 1
      }else {
        przekaznik1stan = "WYŁĄCZONY";
        digitalWrite(PRZEKAZNIK1, HIGH); // Wyłącz przekaźnik 1
      }
    }
    if (strcmp (topic, statepower2_topic) == 0) {
      startprg = 3;
      MQTTread += 1;
      if (SerialPrint == 1) { Serial.print("Stan przekaźnika 2 = ");
        Serial.println(payloadmsg);}
      if (payloadmsg == "ON") {
        przekaznik2stan = "ZAŁĄCZONY";
        digitalWrite(PRZEKAZNIK2, LOW); // Załącz przekaźnik 1
      }else {
        przekaznik2stan = "WYŁĄCZONY";
        digitalWrite(PRZEKAZNIK2, HIGH); // Wyłącz przekaźnik 1
      }
    }
  }
    // Zalaczenie przekaznika 1   
    if (strcmp (topic, command1_topic) == 0) {
      MQTTread += 1;
      if (SerialPrint == 1) {Serial.print("Przekaźnik 1 = ");}
      if (payloadmsg == "ON") {
        przekaznik1stan = "ZAŁĄCZONY";
        if (SerialPrint == 1) {Serial.println("ZAŁĄCZ");}
        digitalWrite(PRZEKAZNIK1, LOW); // Załącz przekaźnik 1
        client.publish(statepower1_topic, "ON", true);
      }
      if (payloadmsg == "OFF") {
        przekaznik1stan = "WYŁĄCZONY";
        if (SerialPrint == 1) {Serial.println("WYŁĄCZ");}
        digitalWrite(PRZEKAZNIK1, HIGH); // Wyłącz przekaźnik 1
        client.publish(statepower1_topic, "OFF", true);    
      }
    }
  
    // Zalaczenie przekaznika 2
    if (strcmp (topic, command2_topic) == 0) {
      MQTTread += 1;
      if (SerialPrint == 1) {Serial.print("Przekaźnik 2 = ");}
      if (payloadmsg == "ON") {
        przekaznik2stan = "ZAŁĄCZONY";
        if (SerialPrint == 1) {Serial.println("ZAŁĄCZ");}
        digitalWrite(PRZEKAZNIK2, LOW); // Załącz przekaźnik 2
        client.publish(statepower2_topic, "ON", true);    
      }
      if (payloadmsg == "OFF") {
        przekaznik2stan = "WYŁĄCZONY";
        if (SerialPrint == 1) {Serial.println("WYŁĄCZ");}
        digitalWrite(PRZEKAZNIK2, HIGH); // Wyłącz przekaźnik 2
        client.publish(statepower2_topic, "OFF", true);    
      }
    }
  } 



void reconnect() {
  // Oczekowani na polaczenie z serwerem
  while (!client.connected()) {
    if (SerialPrint == 1) {Serial.print("Attempting MQTT connection...");}
    // Attempt to connect
    if (client.connect("dom-88fd54db6487cd19_arduino01","dom-88fd54db6487cd19_arduino01/tele/LWT",1,true,"Nieaktywny")) {
    if (SerialPrint == 1) {Serial.println("connected");}
    autodiscoveryHA(); // Przedstawienie się autodiscovery przy starcie
    boolean rc1 = client.subscribe(command1_topic); // Oczykiwanie na topic dla przekaźnika 1
    boolean rc2 = client.subscribe(command2_topic); // Oczykiwanie na topic dla przekaźnika 2
    boolean rcst1 = client.subscribe(statepower1_topic); // Oczekiwanie na topic ze statusem dla przekaźnika 1
    boolean rcst2 = client.subscribe(statepower2_topic); // Oczekiwanie na topic ze statusem dla przekaźnika 2
    boolean rcst3 = client.subscribe(autodiscovery_send_topic); // Oczykiwanie na topic ze statusem dla przekaźnika 2
    } else {
      if (SerialPrint == 1) {Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");}
      // Czekaj 5 sekund przed ponownym polaczeniem
      delay(500);
    }
  }
}

void setup()
{
  if (SerialPrint == 1) {Serial.begin(9600);}
  client.setServer("192.168.2.1", 1883); // Adres serwera MQTT - bramka
  client.setCallback(callback);
  Ethernet.begin(mac, ip);
  //if (WebServer==1){  serverweb.begin();}
  dht.begin(); // Start sensor DHT
  pinMode(KONTAKTRON, INPUT_PULLUP); //Kontaktron jako wejście
  pinMode(CZUJNIKSWIATLA, INPUT); // Czujnik światła
  pinMode(PRZEKAZNIK1, OUTPUT); // Ustawienie Pinu przekaznika 1 jako Wyjscie
  pinMode(PRZEKAZNIK2, OUTPUT); // Ustawienie Pinu przekaznika 2 jako Wyjscie
  digitalWrite(PRZEKAZNIK1, HIGH); // Wyłacz przekaźnik 1 przy starcie , LOW = włącz
  digitalWrite(PRZEKAZNIK2, HIGH); // Wyłacz przekaźnik 2 przy starcie , LOW = włącz       
  if (SerialPrint == 1) {Serial.println(Ethernet.localIP());} //Wyswietlenie adresu IP Arduino
  AddIP = String(Ethernet.localIP()).c_str();
  byte macBuffer[6];  // create a buffer to hold the MAC address
  //Ethernet.MACAddress(macBuffer); // fill the buffer
  Ethernet.MACAddress(macBuffer); //Wyswietlenie MAC Arduino
  for (byte octet = 0; octet < 6; octet++) {
    AddMAC += macBuffer[octet], HEX;
    if (SerialPrint == 1) {Serial.print(macBuffer[octet], HEX);}
    if (octet < 5) {
      if (SerialPrint == 1) {Serial.print('-');}
    }
  }
  if (SerialPrint == 1) {Serial.println();}
  readTime = 0;

}

bool checkBound(float newValue, float prevValue, float maxDiff) {
  return !isnan(newValue) &&
         (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff);
}
  long lastMsg = 0;
  long lastMsg1 = 0;
  float temp = 0.0;
  float hum = 0.0;
  float diffhum = 1.0; // częstotliwość odswierzania co 1 %
  float diff = 0.1;
  int newKONT = 0; //
  int KONT = 2; // stan 2 przy pierwszym odczycie
  int newlight = 0; //
  int light = 2; // stan 2 przy pierwszym odczycie

void loop()
{
  if (!client.connected()) {
  reconnect();
  }
  client.loop();
  
  long now1 = millis();
  long czekaj;
  if (light == 2 ) {czekaj = 100;} else {czekaj = 60000;}
  if (now1 - lastMsg1 > czekaj) {
    lastMsg1 = now1;
    if (SerialPrint == 1) {Serial.print("Free RAM: "); Serial.println(freeRam());}
    if (SerialPrint == 1) {Serial.print("Minutes : "); Serial.println(millis()*0.000016666666666667);}
    
   //Wyslij status
    String statemsg = "";
    statemsg += "{\"Version\":\"";
    statemsg += SoftVersion;
    statemsg += "\",\"BuildDateTime\":\"";
    statemsg += SoftBuildDate;
    statemsg += "\",\"MqttReadCount\":";
    statemsg += MQTTread;
    statemsg += ",\"UptimemSec\":";
    statemsg += millis();
    statemsg += ",\"Module\":\"";
    statemsg += ModuleType;
    //statemsg += "\",\"IPAddress\":\"";
    //statemsg += String(AddIP).c_str();
    //statemsg += "\",\"MACAddress\":\"";
    //statemsg += String(AddMAC).c_str();
    statemsg += "\"}";
     client.publish(state_topic, String(statemsg).c_str(), true);
    if (SerialPrint == 1) {Serial.println(String(statemsg).c_str());}
    client.publish(availability_topic, "Aktywny", true);
 }
    
  long now = millis();
  if (now - lastMsg > 1000) {
    lastMsg = now;
    float newTemp = dht.readTemperature();
    float newHum  = dht.readHumidity();
    int newKONT = digitalRead(KONTAKTRON);
    int newlight = digitalRead(CZUJNIKSWIATLA);
    String msgSendMQT;
    int changeTEHU = 0;
    
    // ODCZYT TEMPERATURY
    if (checkBound(newTemp, temp, diff)) {
      temp = newTemp;
      changeTEHU = 1;
      if (SerialPrint == 1) {Serial.print("Temperatura: ");
        Serial.println(newTemp,1);}
    }
    // ODCZYT WILGOTNOSCI
    if (checkBound(newHum, hum, diffhum)) {
      hum = newHum;
      changeTEHU = 1;
      if (SerialPrint == 1) {Serial.print("Wilgotność: ");
        Serial.println(newHum,1);}
      //client.publish(humidity_topic, String(newHum,1).c_str(), true);
    }
      if (changeTEHU == 1 ) {
        msgSendMQT = "{\"Time\":\"\",\"AM2302\":{\"Temperature\":"+String(newTemp)+",\"Humidity\":"+String(newHum)+"},\"TempUnit\":\"C\"}";
        client.publish(sensors_topic, String(msgSendMQT).c_str(), true);
      }
    
    // STAN KONTAKTRONU PRZY ZMIANIE
    if (newKONT != KONT) {     
      KONT = newKONT;
      if (KONT == 0){
        if (SerialPrint == 1) {Serial.println("Stan kontaktronu: ZAMKNIETY");}
        client.publish(contactron_topic, "off", true);
      }
      if (KONT == 1){
        if (SerialPrint == 1) {Serial.println("Stan kontaktronu: OTWARTY");}
        client.publish(contactron_topic, "on", true);
      }
    }
    // STAN KONTAKTRONU PRZY URUCHOMIENIU
    if (KONT == 2) {     
      if (newKONT == 0){
        if (SerialPrint == 1) {Serial.println("Stan kontaktronu: ZAMKNIETY");}
        client.publish(contactron_topic, "off", true);
      }
      if (newKONT == 1){
        if (SerialPrint == 1) {Serial.println("Stan kontaktronu: OTWARTY");}
        client.publish(contactron_topic, "on", true);
      }  
        client.publish(availability_topic, "online", true);
    } 

    // STAN CZUJNIKA PRZY ZMIANIE
    if (newlight != light) {     
      light = newlight;
      if (light == 0){
        if (SerialPrint == 1) {Serial.println("Swiatlo: JASNO");}
        client.publish(light_topic, "on", true);
      }
      if (light == 1){
        if (SerialPrint == 1) {Serial.println("Swiatlo: CIEMNO");}
        client.publish(light_topic, "off", true);
      }
    }
    // ODCZYT NATEZENIA SWIATLA
    if (light == 2) {     
      if (newlight == 0){
        if (SerialPrint == 1) {Serial.println("Swiatlo: JASNO");}
        client.publish(light_topic, "on", true);
      }
      if (newlight == 1){
        if (SerialPrint == 1) {Serial.println("Swiatlo: CIEMNO");}
        client.publish(light_topic, "off", true);
      }  
    }  
  }

  if (Serial.available() > 0)
  {
    if (Serial.read() == '@')
    {
      if (SerialPrint == 1) {Serial.println("Rebooting. . .");}
      client.publish(availability_topic, "Nieaktywny", true);
      delay(100); // Give the computer time to receive the "Rebooting. . ." message, or it won't show up
      void (*reboot)(void) = 0; // Creating a function pointer to address 0 then calling it reboots the board.
      reboot();
    }
  }
 if ( AutoRestart == 1 ) {
    if (millis() >= RestartTime){
      if (SerialPrint == 1) {Serial.println("Rebooting. . .");}
      void (*reboot)(void) = 0;
      reboot();
    }
 }
  
  /* WEB SERVER
  if (WebServer==1){
    EthernetClient client = serverweb.available();
    if (client) {
      if (SerialPrint == 1) {Serial.println("new client");}
      // an http request ends with a blank line
      boolean currentLineIsBlank = true;
      while (client.connected()) {
        if (client.available()) {
          char c = client.read();
          if (SerialPrint == 1) {Serial.write(c);}
            if (c == '\n' && currentLineIsBlank) {
            // send a standard http response header
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connection: close");
            client.println();
            client.println("<!DOCTYPE HTML>");
            client.println("<html>");
            // add a meta refresh tag, so the browser pulls again every 10 seconds:
            client.println("<meta http-equiv=\"refresh\" content=\"10\">");
            client.print("Temperatura: ");
            client.print(String(temp).c_str());
            client.print("<BR>Wilgotnosc: ");
            client.print(String(hum).c_str());
  
            if (KONT == 0) {client.print("<BR>Kontaktron: ZAMKNIETY");}
            if (KONT == 1) {client.print("<BR>Kontaktron: OTWARTY");}
            if (light == 0) {client.print("<BR>Swiatlo: JASNO");}
            if (light == 1) {client.print("<BR>Swiatlo: CIEMNO");}
  
            client.print("<BR>Przekaznik1: ");
            client.print(przekaznik1stan);
            client.print("<BR>Przekaznik2: ");
            client.print(przekaznik2stan);
            client.println("<br />");       
            client.println("</html>");
            break;
          }
          if (c == '\n') {
            // you're starting a new line
            currentLineIsBlank = true;
          } 
          else if (c != '\r') {
            // you've gotten a character on the current line
            currentLineIsBlank = false;
          }
        }
      }
      // give the web browser time to receive the data
      delay(1);
      // close the connection:
      client.stop();
      if (SerialPrint == 1) {Serial.println("client disonnected");}
    }
  }
  delay(100);*/
}

void autodiscoveryHA() {
    // Autodiscovery HomeAssistant
    if (SerialPrint == 1) {Serial.println("Sending autodiscovery to HA");Serial.println("Send @ to restart Arduino"); }
    client.publish(autodiscovery_status_topic, "{\"name\":\"Arduino01 status\",\"stat_t\":\"~HASS_STATE\",\"avty_t\":\"~LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"json_attributes_topic\":\"~HASS_STATE\",\"unit_of_meas\":\" \",\"val_tpl\":\"{{value_json['MqttReadCount']}}\",\"ic\":\"mdi:information-outline\",\"uniq_id\":\"arduino01_status\",\"device\":{\"identifiers\":[\"arduino01\"],\"connections\":[[\"mac\",\"DE:AD:BE:EF:FE:AD\"]],\"name\":\"arduino01\",\"model\":\"arduino01\",\"sw_version\":\"0.0.8\",\"manufacturer\":\"Iron\"},\"~\":\"dom-88fd54db6487cd19_arduino01/tele/\"}", true);
    client.publish(autodiscovery_sensor1_topic, "{\"name\":\"AM2302 Temperature Arduino01\",\"stat_t\":\"~SENSOR\",\"avty_t\":\"~LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"uniq_id\":\"Arduino01_AM2302_Temperature\",\"device\":{\"identifiers\":[\"arduino01\"],\"connections\":[[\"mac\",\"DE:AD:BE:EF:FE:AD\"]]},\"~\":\"dom-88fd54db6487cd19_arduino01/tele/\",\"unit_of_meas\":\"°C\",\"val_tpl\":\"{{value_json['AM2302'].Temperature}}\",\"dev_cla\":\"temperature\"}", true);
    client.publish(autodiscovery_sensor2_topic, "{\"name\":\"AM2302 Humidity Arduino01\",\"stat_t\":\"~SENSOR\",\"avty_t\":\"~LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"uniq_id\":\"Arduino01_AM2302_Humidity\",\"device\":{\"identifiers\":[\"arduino01\"],\"connections\":[[\"mac\",\"DE:AD:BE:EF:FE:AD\"]]},\"~\":\"dom-88fd54db6487cd19_arduino01/tele/\",\"unit_of_meas\":\"%\",\"val_tpl\":\"{{value_json['AM2302'].Humidity}}\",\"dev_cla\":\"humidity\"}", true);
    client.publish(autodiscovery_switch1_topic, "{\"name\":\"Arduino01 Switch 01\",\"cmd_t\":\"~cmnd/POWER1\",\"stat_t\":\"~tele/POWER1\",\"pl_off\":\"OFF\",\"pl_on\":\"ON\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"uniq_id\":\"arduino01_RL_1\",\"device\":{\"identifiers\":[\"arduino01\"],\"connections\":[[\"mac\",\"DE:AD:BE:EF:FE:AD\"]]},\"~\":\"dom-88fd54db6487cd19_arduino01/\"}", true);
    client.publish(autodiscovery_switch2_topic, "{\"name\":\"Arduino01 Switch 02\",\"cmd_t\":\"~cmnd/POWER2\",\"stat_t\":\"~tele/POWER2\",\"pl_off\":\"OFF\",\"pl_on\":\"ON\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"uniq_id\":\"arduino01_RL_2\",\"device\":{\"identifiers\":[\"arduino01\"],\"connections\":[[\"mac\",\"DE:AD:BE:EF:FE:AD\"]]},\"~\":\"dom-88fd54db6487cd19_arduino01/\"}", true);
    client.publish(autodiscovery_binary1_topic, "{\"name\":\"Arduino01 Drzwi 01\",\"stat_t\":\"~tele/SENSORdoor01\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"uniq_id\":\"arduino01_BTN_1\",\"device\":{\"identifiers\":[\"arduino01\"],\"connections\":[[\"mac\",\"DE:AD:BE:EF:FE:AD\"]]},\"~\":\"dom-88fd54db6487cd19_arduino01/\",\"device_class\":\"door\",\"pl_on\":\"on\",\"pl_off\":\"off\"}", true);
    client.publish(autodiscovery_binary2_topic, "{\"name\":\"Arduino01 Światło 01\",\"stat_t\":\"~tele/SENSORlight01\",\"avty_t\":\"~tele/LWT\",\"pl_avail\":\"Aktywny\",\"pl_not_avail\":\"Nieaktywny\",\"uniq_id\":\"arduino01_BTN_2\",\"device\":{\"identifiers\":[\"arduino01\"],\"connections\":[[\"mac\",\"DE:AD:BE:EF:FE:AD\"]]},\"~\":\"dom-88fd54db6487cd19_arduino01/\",\"device_class\":\"light\",\"pl_on\":\"on\",\"pl_off\":\"off\"}", true);
}

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
1 polubienie

Dałeś to na github?
I pytanie czy działa przez USB?

Jeszcze nie wstawiałem na Gita bo to na razie wersja beta. Jak przejdzie testy to wtedy zamieszczę :slight_smile:
Założenie było takie żeby działało przez sieć LAN. Tak jak w opisie Arduino komunikuje się z HA przez MQTT. Nie ma potrzeby łączenia Arduino przez USB bo to ogranicza zasięg/długość kabla a z reguły kable od czujników układa się w inne miejsce niż jest zlokalizowana bramka z MQTT, dlatego po sieci LAN jest wygodniej. Dla rozwiązania po USB jest gotowiec mySensors.

Zamieść na github przyspiesza to rozwój projektu.
Ja proponuję opis funkcji aby np wiedzieć wy zahashowac aby nie mieć gdy ktoś chce mieć tylko np kontaktrony.
Oraz
Też opis aby wiedzieć jak dodać więcej danych urządzeń z danego typu.

Kolejna wersja 0.0.8 - poprawione wysyłanie autodiscovery po restarcie HA, optymailizacja programu.

co myślicie o takim czymś zamiast dokładać ethernet shield? https://allegro.pl/oferta/mega2560-klon-wifi-esp8266-32mb-flash-arduino-ide-8486046925?fromVariant=8459105042

1 polubienie

Projekt dotyczy wersji przewodowej bo takie było jego założenie żeby z HA było połączenie po kablu, a to co zaproponowałeś to ma tylko WiFi. Jeśli chodzi o wifi to można to taniej zrobić na Wemos które maja więcej pamięci niż Arduino oraz na całej masie innych modułów z WiFi np. Sonoff, ESP32, ESP8266, NodeMCU, itp… To ja znalazłem ciekawsze rozwiązanie :slight_smile: https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware

(wpis wycofany przez autora, zostanie automatycznie usunięty za 24 godziny, chyba że zostanie oflagowany)

Kurde jestem zielony w tym. Mam pi4 a chce zrobić sterowanie oświetleniem przez HA jak również sterowanie zwykłymi klawiszami. Więc muszę połączyć Pi4 z Andruino mega plus chyba takie coś np moduł 8 przekaźnikowy
[/quote]

To rozwiązanie z Ethernet Shield nie wymaga łączenia Arduino z Rpi czy AIS wystarczy tylko wpiąć Arduino w sieć Ethernet i komunikacja jest po MQTT który jest zainstalowany na RPi czy AIS. W programie dla Arduino wystarczy tylko podać adres serwera MQTT na bramce. No i do mojego projektu dodać dwa wyjścia przekaźnikowe analogicznie jak switch1 i switch2. W sumie to mam właśnie taki moduł 4 przekaźnikowy jak widać na fotkach z optoizolacją podłączony do Arduino.

Dokładnie ten: https://botland.com.pl/pl/przekazniki/2579-modul-przekaznikow-4-kanaly-z-optoizolacja-styki-10a250vac-cewka-5v.html

No tak tylko 4 kanałowego to ja mogę sonoffa kupić. Minimum 16 kanałów do oświetlenia potrzebuję plus do tego odczyty temp i wilg. z dht22 z 4szt by mi stykło. Andruino mega z wifi kosztuje tyle co andruino+ethernet shield ale tego z wifi chyba jeszcze nikt nie testował więc nie wiadomo czy będzie działał. Więc teraz pytanie czy iść obecnym tematem i będe pewny że wszystko będzie działać bez problemu? Tylko czy napewno te 16 przekaźników obsłuży.
Coś takiego: https://botland.com.pl/pl/przekazniki/6941-modul-przekaznikow-16-kanalow-z-optoizolacja-styki-10a250vac-cewka-12v.html

Albo takie 2 moduły nawet taniej wychodzi: https://botland.com.pl/pl/przekazniki/2966-modul-przekaznikow-8-kanalow-z-optoizolacja-styki-10a250vac-cewka-5v-niebieski.html

Nie ma problemu czy 2x8 czy 1x16 tylko należy pamiętać o prawidłowym zasilaniu. Przy tylu przekaźnikach samo zasilanie cewek to około 1A - jest osobne gniazdo do tego ale lepiej zasilić to z mocniejszego zasilacza niż tego który jest do zasilania Arduino no chyba że jakiś kilku amperowy masz ale to jeszcze kwesta wydajności wyścia 5V arduino. To w przypadku 2x8 ale 1x16 i tam musi mieć dodatkowy zasilacz bo cewki potrzebują 12V za to mniejszy amperaż. Jeszcze kwestie bezpieczeństwa. Wszystkie mają optoizolację ale… Ten 4 przekaźnikowy który mam ma np. szerokie ścieżki i oddalone od elektroniki i dodatkowo otwory separujące na płytce elektroniki. Nie wiem jak te które podałeś.

Jeśli chodzi o Arduino z Wifi - trudno powiedzieć jak to działa jeśli chodzi o stabilność. Ja bym czegoś takiego nie używał jeśli zależało by mi na stabilności. Bramka z HA i główny sterownik czytaj Arduino po kablu to połowa sukcesu :wink:

Kolejna kwestia to czujniki DHT22. Tutaj kolejne schody jeśli długość kabla >1m… ;-( wpisz w neta DHT22 wire length… znajdziesz sporo odpowiedzi o problemach z odczytem… Ja myślę o innym rozwiązaniu właśnie ze względu na problem z długością kabli do czujników. Pierwsze rozwiązanie to czujniki bezprzewodowe albo… przy każdym czujniku moduł ESP32 z Ethernet np https://nettigo.pl/products/modul-olimex-esp32-poe lub Arduino nano + Ethernet + wszystkie czujniki podpięte do Arduino Mega po RS485 2 przewodowym i zasięg do ponad 1000m !!!

Dzieki za odpowiedź dziś zamawiam. Jak bede miał wszystko odezwę się. No chyba że wczesnje zamieścisz informacje jak podłączyć i skonfigurować te przekaźniki z kontaktami pod andruino.

Cześć, co do DHT22 to spokojnie pociągnie nawet na 20 m tylko trzeba odpowiednio dopasować rezystor podciągający.

które brać?
https://botland.com.pl/pl/przekazniki/3285-modul-przekaznikow-8-kanalow-z-optoizolacja-styki-10a250vac-cewka-12v-niebieski.html?results=223&search_query=przekaznik czy

https://botland.com.pl/pl/przekazniki/2966-modul-przekaznikow-8-kanalow-z-optoizolacja-styki-10a250vac-cewka-5v-niebieski.html

Rożnią się napięciem.