Sto realizzando uno sketch per comandare delle luci (strip led) sia da interruttore/pulsante che da comandi mqtt.
Lo sketch funziona ma lo sto ottimizzando. Quel che vorrei, è che anche in caso di assenza di connessione di rete (cavo staccato, router spento ecc.), il funzionamento continui comunque, quindi se premo il pulsante (o interruttore) la mia striscia led si deve accendere o spegnere.
Come dicevo, lo sketch funziona ma se ad esempio avvio arduino con il cavo di rete staccato per circa 60 secondi (ho fatto una misura con i millis() ) è impossibile comandare i led da pulsante/interruttore. Sembra che il micro si blocchi ad un punto, presumo sia in attesa della connessione ethernet (o mqtt?).
C'è modo di ovviare a questo inconveniente?
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
const char* mqtt_server = "192.168.178.20";
const char* mqtt_username = "mqtt******";
const char* mqtt_password = "mqtt*****";
byte server[] = { 192, 168, 178, 20 };
EthernetClient ethClient;
PubSubClient client(ethClient);
String strTopic;
String strPayload;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE };
IPAddress ip(192, 168, 178, 238);
int attesaDebounce = 50;
unsigned long tempo_riconnesione = millis();
int interruttore_SALA = 14;
int luce_SALA = 15;
bool stato_luce_SALA;
bool stato_interruttore_SALA;
bool lettura_interruttore_SALA;
unsigned long ultimoTempoDebounce_SALA = 0;
bool ultimaLettura_interruttore_SALA = LOW;
String str_luce_SALA;
void callback(char* topic, byte * payload, unsigned int length) {
payload[length] = '\0';
strTopic = String((char*)topic);
if (strTopic == "board1/cmnd/luce_SALA")
{
str_luce_SALA = String((char*)payload);
if (str_luce_SALA == "ON")
{
Serial.println("mqtt --> ON");
digitalWrite(luce_SALA, HIGH);
client.publish("board1/stat/luce_SALA", "ON");
stato_luce_SALA = HIGH;
}
else
{
Serial.println("mqtt --> OFF");
digitalWrite(luce_SALA, LOW);
client.publish("board1/stat/luce_SALA", "OFF");
stato_luce_SALA = LOW;
}
}
}
void reconnect() {
// Loop di riconnessione
if (!client.connected()) {
Serial.print("In attesa della connessione MQTT...");
unsigned long tempo = millis();
tempo = tempo/1000;
Serial.print(tempo); //solo debug per vedere dopo quanto si connette
// In attesa della connessione
if (client.connect("arduinoClient", mqtt_username, mqtt_password)) {
Serial.println("connesso");
// Once connected, publish an announcement...
client.subscribe("board1/#");
} else {
Serial.println(" connessione fallita.");
Serial.print(" stato scheda=");
Serial.print(client.state());
Serial.println(" riprovo tra 15 secondi");
}
}
}
void setup()
{
Serial.begin(115200);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
Ethernet.begin(mac);
//stato_luce_SALA = EEPROM.read(1); //togli commento se vuoi ricordare ultimo stato prima del riavvio
stato_luce_SALA = LOW;
pinMode(luce_SALA, OUTPUT);
pinMode(interruttore_SALA, INPUT_PULLUP);
digitalWrite(luce_SALA, stato_luce_SALA);
lettura_interruttore_SALA = digitalRead(interruttore_SALA);
stato_interruttore_SALA = digitalRead(interruttore_SALA);
}
void loop()
{
lettura_interruttore_SALA = digitalRead(interruttore_SALA);
if (lettura_interruttore_SALA != ultimaLettura_interruttore_SALA) {
ultimoTempoDebounce_SALA = millis();
}
if ((millis() - ultimoTempoDebounce_SALA) > attesaDebounce) {
if (lettura_interruttore_SALA != stato_interruttore_SALA) {
stato_luce_SALA = !stato_luce_SALA;
digitalWrite(luce_SALA, stato_luce_SALA);
if (stato_luce_SALA == 1) {
client.publish("board1/stat/luce_SALA", "ON");
Serial.println("luce --> ON");
} else {
client.publish("board1/stat/luce_SALA", "OFF");
Serial.println("luce --> OFF");
}
//EEPROM.write(1, stato_luce_SALA);
}
stato_interruttore_SALA = lettura_interruttore_SALA;
}
ultimaLettura_interruttore_SALA = lettura_interruttore_SALA;
if (!client.connected()) {
if ((millis() - tempo_riconnesione) > 15000) {
tempo_riconnesione = millis();
reconnect();
}
}
client.loop();
}
Ho notato che in caso di disconnessione, ogni 15 secondi, quando si tenta la riconnessione, ho uno sto di circa 1 o 2 secondi. Anche in questo caso, è possibile baypassare il problema?
Come detto, vorrei dare priorità al codice di controllo pin ingresso (interruttore) e relativa uscita...