Integracja Arduino Mega + Ethernet Shield z HA przez MQTT

Jak masz zasilane ESP z baterii/zasilacza? Jeśli na wyjściu do czujnika jest poniżej 3,3V to cuda się dzieją. najlepiej DHT22 zasilacz z 5V ale w przypadku ESP jest problem. Dlatego używam Arduino nano :slight_smile:

mam normalne zasilanie przez zasilacz

Cześć
Chciałbym identycznie zrobić coś takiego tyle że z samym czujnikiem magnetycznym (kontaktron) i na nodemcu? Czy mam postępować w identyczny sposób i również podpiąć pod pin3?

Jeśli masz na myśli pin D3 to tak.

Moduł przekaźnikowy https://allegro.pl/oferta/przekaznik-polprzewodnikowy-ssr-8-kanalowy-7636950328 występuje w dwóch wersjach. Sterowany stanem niskim i wysokim czy to ma jakieś znaczenie np wtedy gdy padnie rasbery lub arduino to nada będzie można zwykłym przyciskiem włączyć światło?

W przypadku Arduino to nie ma to dużego znaczenia bo możesz sam wybrać czy załączasz stanem HIGH czy LOW. Jeśli chodzi o przekaźniki to nie da się sterować nimi ręcznie i automatycznie. Albo jedno albo drugie. Aby sterować dwoma sposobami to muszą być przekaźniki bistabilne które zmieniają stan po krótkim impulsie np. z przycisku tzw. dzwonkowego. Ewentualnie przy tych zwykłych można załączyć przyciskiem zwykłym ręcznie ale wtedy nie będzie można sterować przy pomocy Arduino. No chyba że takie rozwiązanie Ci odpowiada.

https://www.youtube.com/watch?v=PxS7yA272kU&t=596s tutaj działają przyciski i sterowanie z aplikacji

Tak pod warunkiem, że działa Arduino bo przekaźniki i przycisk są podłączone do Arduino i w przypadku jego awarii nie zadziała załączanie manualne z przycisku!

Wiem ale przemyślałem temat i taniej wyjdzie w razie awarii podmienic Arduino niż te przekaźniki zamontować. Nawet nie mam tyle miejsca na nie. I jeszcze koszmarnie drogie są.

Tak bistabilne są drogie ale są najpewniejsze bo wszystko działa niezależnie od Arduino. Chociaż z drugiej strony Arduino to można uszkodzić jeśli nie zapewni się optoizolacji bo tutaj za bardzo nie ma co się zepsuć…

Co to jest ta optoizolacja i jak należy ją wykonać

W tym twoim projekcie nie są uwzględnione przyciski fizyczne? Mógłbyś podrzucić szkic z uwzględnieniem ich.? Taki przykładowy dla 4 przkaznikòw. Byłbym wdzięczny.

pab11o

Użyj google tam jest sporo informacji o optoizolacji - ogólnie chodzi o odseparowanie optyczne części wykonawczej od mikrokontrolera (Arduino) aby nie było przepięć i nie uszkodzić go. W układzie przekaźników masz taką optoizolację. Jeśli chodzi o mój projekt to nie dotyczy on tego typu rozwiązania. Ja u siebie będę to robił na bistabilnych. Mój projekt to odczyt danych z kilkunastu sensorów rozmieszczonych w budynku i przesyłanie danych do HA po MQTT. Część kodu tak jak wcześniej pisałem odpowiedzialna za odczyt statusu kontaktronu i załączanie przekaźników pasuje do Twojego rozwiązania.

Bardzo podoba mi się twój projekt i chciałbym go wykorzystać u siebie ale brakuje mi tych przycisków fizycznych w szkicu jak byś jej dodał i udostępnił postawie :beer: :grin:. Znalazłem taki szkic ale pod domoticza więc się nie nada.
Pozdrawiam

OK tylko na razie zajmuję się multisensorem jak tylko skończę ten projekt to zajmę się sterowaniem oświetleniem.

Właśnie zakończyłem testy pierwszego multisensora przekazującego dane po RS485 do Arduino Mega i dalej po MQTT do HA. W projekcie użyłem Arduino Nano a z drugiej strony Arduino Mega 2560.

Co potrafi multisensor:

(Linki do poszczególnych modułów wykorzystanych w projekcie po najechaniu kursorem myszy)

Filmik jak działa detekcja płomieni oraz sterowanie oświetleniem LED:


Kod dla całego projektu znajduje się tutaj:
https://github.com/ironek69/Arduino-to-Home-Assistant-MQTT-multisensor

Schemat blokowy:

Schemat połączeń:

szkic dla Arduino nano:

 //Version0.0.5 - Send sensor data after server request
//Version0.0.4 - OLED 0.91, RF433 receiver
//Version0.0.3 - LCD 4x20
//Version0.0.2 - Add BME280 sensor
//Version0.0.1 - Light Sensor
//
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
#define I2C_ADDRESS 0x3C // 0X3C+SA0 - 0x3C or 0x3D 0x3C - Wyświetlacz OLED
#define RST_PIN -1 // Define proper RST_PIN if required.
#include "RS485_protocol.h"
#include <SoftwareSerial.h>
#include <RCSwitch.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
#define LED_LIGHT 7 //Light LED D7
const byte ENABLE_PIN = 6; //D6 RS485 Enable pin DE+RE
char light_sensor_pin = A0; // led lamp
char fire_sensor_pin = A3; // flame/fire sensor
int siren_pin = 3; //D3 Buzzer
int fire_sensor;
byte light_on = false;

/*Register Map:
byte  Desc 
 0    status (slave status)
 1    sensor Id
 2    temperature (float)
 3    temperature
 4    temperature
 5    temperature
 6    humidity (float)
 7    humidity (float)
 8    humidity (float)
 9    humidity (float)
 10   pressure (float)
 11   pressure (float)
 12   pressure (float)
 13   pressure (float)
 14   altitude (float)
 15   altitude (float)
 16   altitude (float)
 17   altitude (float)
 18   set temperature (float)
 19   set temperature (float)
 20   set temperature (float)
 21   set temperature (float)
 22   light (int)
 23   fire (int)
 24   lamp (int)
*/
typedef struct sensorData_t {
  byte stat;
  byte sensorId;
  float temp;
  float hum;
  float pressure;
  float alt;
  float settemp;
  byte light;
  byte fire;
  byte lamp;
};
#define PACKET_SIZE sizeof(sensorData_t)
typedef union rs485_Packet_t{
 sensorData_t sensor;
 byte rs485Packet[sizeof(sensorData_t)];
};
rs485_Packet_t leakinfo;  

int sensorValue = 0;
long lastMsg = 0;
long lastMsgrcv = 0;
int nowrcv = 0;
int minut;
int godzin;
int dni;
int srverr = 0;
long srvTotalerr = 0;
String Serwer = "";
int srvrecv = 0;

float bmetemp = 0.00;
float bmehum = 0.00;
float bmepress = 0.00;
float bmealt = 0.00;
int light = 0;
float settemp = 20.0;
byte fire = false;
byte lamp = false;

SSD1306AsciiAvrI2c oled;
RCSwitch mySwitch = RCSwitch();
Adafruit_BME280 bme;
SoftwareSerial rs485 (4, 5);  // receive pin, transmit pin

void fWrite (const byte what)
  {
  rs485.write (what);  
  }
int fAvailable ()
  {
  return rs485.available ();  
  }
int fRead ()
  {
  return rs485.read ();  
  }

void setup()
{
  Serial.begin(9600);
  delay(1);
  rs485.begin (9600);
  Serial.println("Serial Begin Arduino Nano");
  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
  mySwitch.enableReceive(0);  //pin D2 433in
  pinMode(fire_sensor_pin,INPUT); // Fire sensor
  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
  pinMode (LED_BUILTIN, OUTPUT);  // built-in LED
  pinMode (LED_LIGHT, OUTPUT);  // built-in LED
  pinMode (siren_pin, OUTPUT);  // Buzzer pin

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0
  
  bmetemp = bme.readTemperature();
  bmehum = bme.readHumidity();
  bmepress = bme.readPressure() / 100.0F;
  bmealt = bme.readAltitude(SEALEVELPRESSURE_HPA); 
  sensorValue = analogRead(light_sensor_pin); //Swiatlo
  light = map(sensorValue, 1016, 5, 0, 100);
  
}  // end of setup

void loop()
{
   // RF433 receive
  if (mySwitch.available()) {
    output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(),mySwitch.getReceivedProtocol());
    if ( mySwitch.getReceivedValue() == 6792738) { 
      digitalWrite (LED_BUILTIN, HIGH);  // turn on LED if received
      settemp = settemp+0.5;
      Serial.print("SET TEMP + : ");  
      Serial.println(settemp);}
    if ( mySwitch.getReceivedValue() == 6792737) { 
      digitalWrite (LED_BUILTIN, HIGH);  // turn on LED if received
      settemp = settemp-0.5;
      Serial.print("SET TEMP - : ");  
      Serial.println(settemp);}
    if ( mySwitch.getReceivedValue() == 6792740) { 
      fire= false;
      if (light_on == true){
        digitalWrite(LED_LIGHT, LOW); // gasimy Lampkę
        light_on = false;
        lamp = false;
        noTone(siren_pin);
        digitalWrite (siren_pin, LOW);
      }else {
        digitalWrite(LED_LIGHT, HIGH); // zapalamy Lampkę
        light_on = true;
        lamp = true;
        }
      
      }

    mySwitch.resetAvailable();
    delay(1);
    digitalWrite (LED_BUILTIN, LOW);  // turn off LED
  }
  
 // receive invitation from Server
  byte rbuf [2];
  byte received = recvMsg (fAvailable, fRead, rbuf, sizeof rbuf);
  if (received) {
    if (rbuf[0] == 1){
      if (rbuf[1] == 1){
        Serial.println("");  
        Serial.println("OK - Response invitation from Server!");
        Serwer = "OK !";
        srverr = 0;   
        srvrecv++;   
        // Send sensors state
        sendData(1); // Send data to master from sensor 1 
        digitalWrite (LED_BUILTIN, LOW);  // turn off LED if OK
      }
    }
  } else {
      srverr++; 
      // If no response from server 10 times
      if (srverr >= 50){       
        srvTotalerr++;
        srverr=0;
        Serial.println("NO - Response from Server 10 times!");                   
        Serial.print("Total errors: ");
        Serial.println(srvTotalerr);
        digitalWrite (LED_BUILTIN, HIGH);  // turn on LED if error
        Serwer = "ERR!";
        }
  }// end !received


 

  // run every 3 sec
  long now = millis();
  if (now - lastMsg > 3000) {
    lastMsg = now;
    minut = millis()/1000 / 60;
    godzin = millis()/1000 / 3600;
    dni = godzin/24;
    fire_sensor = analogRead(fire_sensor_pin);
    if (fire_sensor < 1019){
      fire = true;
      digitalWrite(LED_LIGHT, HIGH); // zapalamy Lampkę
      digitalWrite(LED_BUILTIN, HIGH); // zapalamy LED
    }
    if (fire == true){Siren();}
    
    bmetemp = bme.readTemperature();
    bmehum = bme.readHumidity();
    bmepress = bme.readPressure() / 100.0F;
    bmealt = bme.readAltitude(SEALEVELPRESSURE_HPA); 
    sensorValue = analogRead(light_sensor_pin); //Swiatlo
    light = map(sensorValue, 1016, 5, 0, 100);
    displayoled(Serwer); // Display OLED
    displayserial();
  } //end 3s

}  // end of main loop

void displayserial(){
  // Send sensors state
  Serial.print("Temperature = ");
  Serial.print(bmetemp);
  Serial.println("*C");
  Serial.print("Humidity = ");
  Serial.print(bmehum);
  Serial.println("%");
  Serial.print("Pressure = ");
  Serial.print(bmepress);
  Serial.println("hPa");
  Serial.print("Approx. Altitude = ");
  Serial.print(bmealt);
  Serial.println("m");  
  Serial.print("Light = ");
  Serial.print(light);
  Serial.println("%");
  Serial.print("SetTemp = ");
  Serial.print(settemp);
  Serial.println("*C");  
  Serial.print("Fire = ");
  Serial.println(fire_sensor);
  Serial.print("Fire = ");
  Serial.println(fire);
  Serial.print("Lamp = ");
  Serial.println(lamp);
}       

void displayoled(String srv) {
  oled.setFont(Adafruit5x7);
  oled.clear();
  oled.setInvertMode(0%2);
  oled.set2X();
  oled.print(bmetemp);
  oled.print( "*C ");
  oled.setCol(221);
  oled.print(light);
  oled.println("%"); 
  oled.setCol(0);
  oled.print(bmehum);
  oled.println( " %");
  if (fire == true){
    oled.setCol(221);
    oled.print(" FIR");}
  oled.setCol(221);
  oled.print(bmepress);
  oled.println(" hPa"); 

  for (int i = 0; i < 4; i++) {
  // Toggle invert mode for next line of text.
    oled.setInvertMode((0)%2);
    oled.print("S:");
    oled.setInvertMode(i%2);
    oled.print(srv);
    oled.setInvertMode((0)%2);
    oled.print("E:");
    oled.println(srvTotalerr);
    delay(300);
  }
}// End DisplayOLED

// Send data to Master Arduino Mega 
int sendData(int sensorID)
{
  byte byteArray[PACKET_SIZE];    
  leakinfo.sensor.stat = 1; 
  leakinfo.sensor.sensorId = sensorID; 
  leakinfo.sensor.temp = bmetemp; 
  leakinfo.sensor.hum =  bmehum; 
  leakinfo.sensor.pressure = bmepress; 
  leakinfo.sensor.alt = bmealt; 
  leakinfo.sensor.light = light; 
  leakinfo.sensor.settemp = settemp; 
  leakinfo.sensor.fire = fire; 
  leakinfo.sensor.lamp = lamp; 
    
  delay (1);  // give the master a moment to prepare to receive
  digitalWrite (ENABLE_PIN, HIGH);    // enable sending
  sendMsg (fWrite, leakinfo.rs485Packet, PACKET_SIZE);  // send confirmation  
  digitalWrite (ENABLE_PIN, LOW);     // disable sending   
} // end sendData

void Siren(){
  digitalWrite(siren_pin, HIGH);
 delay(300);
for(int i=3;i<=6;i++)
noTone(siren_pin);
tone(3,494,500);
delay(300);

noTone(siren_pin);
tone(siren_pin,523,300);
delay(200);

delay(50);

delay(50);
noTone(siren_pin);
}

Problemy do rozwiązania:

Do zrobienia:

  • Dodanie nadajnika RF 433 aby umożliwić sterowanie urządzeniami 433 w pomieszczeniu;
  • Dodanie diody nadawczej IRda aby umożliwić sterowanie np. telewizorami w pomieszczeniach;
    W pomieszczeniach typu łazienka i kuchnia dodanie sensorów zalania. Pomysł jest taki żeby wykorzystać tanie sensory: Czujnik zalania z anteną RF 433 MHz Odczyt może być dualny poprzez RF 433 oraz podpięcie kablem wyjścia diody led pod arduino oprócz tego zasilenie czujnika aby nie trzeba wymieniać baterii.

Super projekt. :+1:
Jak zrealizowałeś sprzętowo czujnik płomieni/ognia?

Nie zapomniałeś o mnie?


Obecnie od 3 lat mam coś takiego więc tylko podmnienie Arduino mega plus moduły przekaźnikowe i po temacie 15 min roboty