Witam,
Zrobiłem oprogramowanie na Arduino MEGA2560 do sterowania przekaźnikami. Płytka jest podłączona do modułu Ethernet W5500 przez SPI.
Ogólnie skrypt działa i steruje przekaźnikami tak jak powinien, ale mam problem.
Problem polega na tym ze wiadomości MQTT wysyłane z HA czasem są odbierane natychmiast przez Arduino i reakcja jest natychmiastowa a czasem są opóźnienia rzędu paru sekund (raczej nie jest to związane z reconnection ponieważ było by widać po UART, że próbuje ponownie się podłączyć).
Przy sterowaniu oświetleniem może to być mocno denerwujące.
Zrobiłem diagnostykę i obsługę zdarzeń po UART i skłaniam się do tego, że może jest za duży ruch stąd opóźnienia, aczkolwiek MQTT jest projektowany jako wersja prosta i lekka więc nie powinien generować aż takich problemów.
Nie mam już pomysłu stąd wrzucam problem może wy coś obserwowaliście u siebie i rozwiązaliście problem.
/*
Sterowanie przekaźnikami ogrzewanie Arduino
versia 0.0.1
Data 14.10.2021
1x Ethernet - W5500
1xArduino - MEGA2550
*/
#include <SPI.h>
#include <Ethernet2.h>
#include <PubSubClient.h>
#include <Bounce2.h>
// Update these with values suitable for your network.
byte mac[] = { xxxx };
IPAddress ip(xxxx);
IPAddress server(xxxx);
const char* arduino = "xxxx";
const char* user = "xxxx";
const char* pass = "xxxx";
const char* A100 = "xxxx";
const char* A100_status = "xxxx";
int reset=1;
// Set led variables to Arduino digital pins
int relay1 = A0;
int relay2 = A1;
int relay3 = A2;
int relay4 = A3;
// Set variable values initially to LOW (and not HIGH)
int relay1Value = LOW;
int relay1ValueStatus = LOW;
int relay2Value = LOW;
int relay2ValueStatus = LOW;
int relay3Value = LOW;
int relay3ValueStatus = LOW;
int relay4Value = LOW;
int relay4ValueStatus = LOW;
// Set button variables to Arduino digital pins
int button1 = 8;
// Initiate a bouncer instance for each button
Bounce bouncer1 = Bounce();
void callback(char* topic, byte* payload, unsigned int length)
{
// handle message arrived
String content="";
char character;
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int num=0;num<length;num++) {
character = payload[num];
content.concat(character);
}
Serial.println(content); // message sent out by button actions is returned from broker and serial printed
// Set specific virtual switches on basis of specific incoming messages ----------------------------
if (content == "1on")
{
relay1Value = HIGH;
Serial.println("Przekaźnik 1 = ZAŁĄCZ");
}
if (content == "1off") {
relay1Value = LOW;
Serial.println("Przekaźnik 1 = WYŁĄCZ");
}
// Set digital pin states according to virtual switch settings
digitalWrite(relay1,relay1Value);
if (content == "2on")
{
relay2Value = HIGH;
Serial.println("Przekaźnik 2 = ZAŁĄCZ");
}
if (content == "2off")
{
relay2Value = LOW;
Serial.println("Przekaźnik 2 = WYŁĄCZ");
}
// Set digital pin states according to virtual switch settings
digitalWrite(relay2,relay2Value);
if (content == "3on")
{
relay3Value = HIGH;
Serial.println("Przekaźnik 3 = ZAŁĄCZ");
}
if (content == "3off")
{
relay3Value = LOW;
Serial.println("Przekaźnik 3 = WYŁĄCZ");
}
// Set digital pin states according to virtual switch settings
digitalWrite(relay3,relay3Value);
if (content == "4on")
{
relay4Value = HIGH;
Serial.println("Przekaźnik 4 = ZAŁĄCZ");
}
if (content == "4off")
{
relay4Value = LOW;
Serial.println("Przekaźnik 4 = WYŁĄCZ");
}
// Set digital pin states according to virtual switch settings
digitalWrite(relay4,relay4Value);
}
EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);
void reconnect()
{
// Loop until we're reconnected
while (!client.connected())
{
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(arduino, user, pass))
{
Serial.println("connected"); // Podłączono - komunikacja szeregowa
client.publish(A100,"xxxxx"); // Publikacja po ponownym nawiązaniu połączenia
Serial.print("Temat: ");
Serial.print(A100);
Serial.println(" Arduino-IP:xxxx");
client.subscribe(A100); // Subskrybuj temat
if (relay1Value==LOW){ client.publish(A100_status,"1OFF");}
else{ client.publish(A100_status,"1ON");}
if (relay2Value==LOW){ client.publish(A100_status,"2OFF");}
else{ client.publish(A100_status,"2ON");}
if (relay3Value==LOW){ client.publish(A100_status,"3OFF");}
else{ client.publish(A100_status,"3ON");}
if (relay4Value==LOW){ client.publish(A100_status,"4OFF");}
else{ client.publish(A100_status,"4ON");}
}
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); //57600
Ethernet.begin(mac, ip);
// Note - the default maximum packet size is 128 bytes. If the
// combined length of clientId, username and password exceed this use the
// following to increase the buffer size:
// client.setBufferSize(255);
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
if (client.connect(arduino, user, pass))
{
client.publish(A100,"hello world");
Serial.println("Hello world");
client.subscribe(A100);
}
// setup led, button, bouncer 1 -----------------------
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
pinMode(button1,INPUT);
digitalWrite(button1,HIGH);
bouncer1 .attach(button1);
bouncer1 .interval(5);
}
void loop()
{
if (!client.connected())
{
reconnect();
}
if (reset==1)
{
Serial.println("Reset przekaźników 1-4");
digitalWrite(relay1,LOW);
client.publish(A100_status,"1OFF");
digitalWrite(relay2,LOW);
client.publish(A100_status,"2OFF");
digitalWrite(relay3,LOW);
client.publish(A100_status,"3OFF");
digitalWrite(relay4,LOW);
client.publish(A100_status,"4OFF");
reset=0;
}
if (bouncer1.update())
{
if (bouncer1.read() == HIGH)
{
client.publish(A100_status,"S1-on");
}
else
{
client.publish(A100_status,"S1-off");
}
}
if (relay1Value != relay1ValueStatus)
{
if (relay1Value == HIGH)
{
client.publish(A100_status,"1ON");
Serial.println("Przekaźnik 1 = ZAŁĄCZONY");
}
else
{
client.publish(A100_status,"1OFF");
Serial.println("Przekaźnik 1 = WYŁĄCZONY");
}
relay1ValueStatus=relay1Value;
}
if (relay2Value != relay2ValueStatus)
{
if (relay2Value == HIGH)
{
client.publish(A100_status,"2ON");
Serial.println("Przekaźnik 2 = ZAŁĄCZONY");
}
else
{
client.publish(A100_status,"2OFF");
Serial.println("Przekaźnik 2 = WYŁĄCZONY");
}
relay2ValueStatus=relay2Value;
}
if (relay3Value != relay3ValueStatus)
{
if (relay3Value == HIGH)
{
client.publish(A100_status,"3ON");
Serial.println("Przekaźnik 3 = ZAŁĄCZONY");
}
else
{
client.publish(A100_status,"3OFF");
Serial.println("Przekaźnik 3 = WYŁĄCZONY");
}
relay3ValueStatus=relay3Value;
}
if (relay4Value != relay4ValueStatus)
{
if (relay4Value == HIGH)
{
client.publish(A100_status,"4ON");
Serial.println("Przekaźnik 4 = ZAŁĄCZONY");
}
else
{
client.publish(A100_status,"4OFF");
Serial.println("Przekaźnik 4 = WYŁĄCZONY");
}
relay4ValueStatus=relay4Value;
}
client.loop();
}