MQTT subscribes

salve a tutti
non riesco a capire perche' queste due funzioni mi attivano lo stesso rele':

void callback_luci(char* topic, byte* payload, unsigned int length) {

  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  // Switch on the RELAY if an "1" was received as first character or OFF if first character was a "0" or toggle relay when received a "2"
  if (((char)payload[1] == 'F')  {
  digitalWrite(relay_luci, LOW);   // Turn the RELAY OFF
    relayState_luci = LOW;
  } else if ((char)payload[1] == 'N') {
  digitalWrite(relay_luci, HIGH);  // Turn the RELAY ON by making the voltage HIGH
    relayState_luci = HIGH;
  }
}
void callback_foto(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the RELAY if an "1" was received as first character or OFF if first character was a "0" or toggle relay when received a "2"
  if (((char)payload[1] == 'F')  {
  digitalWrite(relay_foto, LOW);   // Turn the RELAY OFF
    relayState_foto = LOW;
  } else if ((char)payload[1] == 'N') {
  digitalWrite(relay_foto, HIGH);  // Turn the RELAY ON by making the voltage HIGH
    relayState_foto = HIGH;
  }
}

grazie per l'aiuto

Non mi pare che da quel pezzo di codice si possa dire molto.

Quanto vale relay_luci e quanto relay_foto ?
Stampa su seriale i valori delle due variabili nelle due funzioni per controllarle/debuggarle

intendi questo?

int relay_luci = D1;
int relay_foto = D7;

hanno lo stesso valore....13 :o

evidentemente da qualche parte c'è una assegnazione sbagliata,
il modo più semplice per trovarla è cambiare quelle due righe di prima con:

const int relay_luci = D1;
const int relay_foto  = D7;

vedrai che l'errore lo becchi subito :wink:

macche'...provato, non e' cambiato niente

E dove stanno le define di D1 e D7 ??

non so che scheda stai usando... ma visto l'uso dei nomi d1 e d7 presumo sia un nodemcu :slight_smile:
se non lo è allora come dice nid69ita devi definire a cosa corrispondono d1 e d7 prima di poterli usare

sono prima del setup:

const int relay_luci = D1;
const int button_luci = D6;
const int relay_foto = D7;
const int button_foto = D0;

Non ci siamo capiti.
Se hai Arduino Uno, Mega o Nano NON esistono le costanti D1, D7 etc.

Mancano info, come ti ho già detto al primo post. Solo pezzo di codice, non spieghi che Arduino usi, cosa è collegato, etc.

Hai ragione, non avevo capito.
Scheda NodeMCU alimentata con alimentatore, questo e' il codice completo:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Bounce2.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

IPAddress staticIP(xxx, xxx, x, xxx); //ESP static ip
IPAddress gateway(xxx, xxx, x, x);
IPAddress subnet(255, 255, 255, 0);//IP Address of your WiFi Router (Gateway)

const char* ssid = "xxxxxxx"; //SSID WIFI Access Point
const char* password = "xxxxxxxx"; //Access Point Password
const char* mqtt_server = "xxxxxxxxx"; //IP address MQTT server

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

const char* inTopic_luci = "openhab/out/ufficio/luci/command";  // MQTT Topic this switch subscribes
const char* inTopic_foto = "openhab/out/ufficio/foto/command";  // MQTT Topic this switch subscribes
const char* switchTopic_luci = "openhab/in/ufficio/luci/state"; //MQTT Topic wall switch publish
const char* switchTopic_foto = "openhab/in/ufficio/foto/state"; //MQTT Topic wall switch publish

const int relay_luci =   D1; //Pin for Relay
const int button_luci = D6; //Pin for button
const int relay_foto  = D7; //pin fotocopiatore
const int button_foto = D0; //Pin for

bool relayState_luci = HIGH;
bool relayState_foto = HIGH;

Bounce debouncer = Bounce(button_luci, 50);
Bounce debouncer2 = Bounce(button_foto, 50);

unsigned long previousMillis = 0;  // will store last time STATUS was send to MQTT
const long interval = 60000; //one minute for status refresh

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.config(staticIP, gateway, subnet);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    for (int i = 0; i < 500; i++) {
      delay(1);
    }
    Serial.print(".");
  }
  digitalWrite(2, LOW);
  delay(500);
  digitalWrite(2, HIGH);
  delay(500);
  digitalWrite(2, LOW);
  delay(500);
  digitalWrite(2, HIGH);
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback_luci(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  // Switch on the RELAY if an "1" was received as first character or OFF if first character was a "0" or toggle relay when received a "2"
  if ((char)payload[1] == 'F')  {
    digitalWrite(relay_luci, LOW);
    Serial.println(relay_luci);// Turn the RELAY OFF
    relayState_luci = LOW;
  } else if ((char)payload[1] == 'N') {
    digitalWrite(relay_luci, HIGH);  // Turn the RELAY ON by making the voltage HIGH
    relayState_luci = HIGH;
    Serial.println();
  }
}

void callback_foto(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  // Switch on the RELAY if an "1" was received as first character or OFF if first character was a "0" or toggle relay when received a "2"
  if ((char)payload[1] == 'F')  {
    digitalWrite(relay_foto, LOW);
    Serial.println(relay_foto);// Turn the RELAY OFF
    relayState_foto = LOW;
  } else if ((char)payload[1] == 'N') {
    digitalWrite(relay_foto, HIGH);  // Turn the RELAY ON by making the voltage HIGH
    relayState_foto = HIGH;
  }
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ufficio", "openhab", "Spirou@01")) {
      Serial.println("connected");
      //Subscribe to incoming commands
      client.subscribe(inTopic_luci);
      client.subscribe(inTopic_foto);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      for (int i = 0; i < 5000; i++) {
        // extButton_luci();
        // extButton_foto();
        delay(1);
      }
    }
  }
}

void extButton_luci() {
  debouncer.update();
  if ( debouncer.fell() ) {
    Serial.println("Debouncer luci");
    relayState_luci = !relayState_luci;
    digitalWrite(relay_luci, relayState_luci);
    if (relayState_luci == 1) {
      client.publish(switchTopic_luci, "ON", false);
    }
    else if (relayState_luci == 0) {
      client.publish(switchTopic_luci, "OFF", false);
    }
  }
}

void extButton_foto() {
  debouncer2.update();
  if ( debouncer2.fell() ) {
    Serial.println("Debouncer foto");
    relayState_foto = !relayState_foto;
    digitalWrite(relay_foto, relayState_foto);
    if (relayState_foto == 1) {
      client.publish(switchTopic_foto, "ON", false);
    }
    else if (relayState_foto == 0) {
      client.publish(switchTopic_foto, "OFF", false);
    }
  }
}

void setup() {
  String line = "";
  pinMode(relay_luci, OUTPUT);     // Initialize the relay pin as an output
  pinMode(button_luci, INPUT);     // Initialize the relay pin as an input
  pinMode(relay_foto, OUTPUT);
  pinMode(button_foto, INPUT);
  pinMode(2, OUTPUT);            // Initialize the onboard LED as output

  debouncer.attach(button_luci);   // Use the bounce2 library to debounce the built in button
  debouncer.interval(50);         // Input must be low for 50 ms
  debouncer2.attach(button_foto);
  debouncer2.interval(50);

  digitalWrite(2, LOW);          // Blink to indicate setup
  delay(50);
  digitalWrite(2, HIGH);
  delay(50);

  Serial.begin(115200);
  setup_wifi();                   // Connect to wifi

  client.setServer(mqtt_server, 1883); //connect to MQTT
  client.setCallback(callback_luci);
  client.setCallback(callback_foto);

  // Port defaults to 8266: ArduinoOTA.setPort(8266);
  ArduinoOTA.setHostname("  ufficio ");
  ArduinoOTA.setPassword((const char *)"xxxxx");
  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

}

void loop() {
  ArduinoOTA.handle();

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

Togli quelle costanti e prova a mettere i numeri dei pin direttamente (come hai fatto per il led al pin 2)

Oppure... sicuro che sta richiamando la callback giusta ? Non conosco questa libreria
client.setCallback(callback_luci);
client.setCallback(callback_foto);
se stampa sempre 13, ovvero D7, potrebbe essere che chiama sempre la callback_foto
Nel programma hai scritto:
Serial.println(relay_foto);// Turn the RELAY OFF
aggiungi una frase che faccia capire quel 13 de che è

Serial.print("relay_foto="); Serial.println(relay_foto);// Turn the RELAY OFF

Serial.print("relay_luci="); Serial.println(relay_luci);// Turn the RELAY OFF

infatti. Chiama sempre la callback foto. Se provo a decommentarla funziona correttamente la funzione "luci" e stampa 5 (D1) e il problema si inverte

Non conosco la libreria. Forse hai solo 1 callback possibile

per me non puoi sottoscrivere contemporaneamente a più topic

      client.subscribe(inTopic_luci);
      client.subscribe(inTopic_foto);

no, sbagliavo però prova a seguire questo

Patrick_M:
no, sbagliavo però prova a seguire questo

P.S. interessante sito

Ho chiesto aiuto sulla community di OpenHab con esito positivo.

Posto la soluzione cosi' che possa essere di aiuto a qualcuno.
Il mio errore era nel fare due chiamate contemporaneamente, (e non e' possibile) e quindi ne veniva eseguita sempre e soltanto una.
A quel punto il problema si risolve in un unica funzione che comprende i topic necessari eseguiti in base alla struttura if...else
ecco il codice:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Bounce2.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

IPAddress staticIP(xxxxx); //ESP static ip
IPAddress gateway(xxxxx);
IPAddress subnet(255, 255, 255, 0);//IP Address of your WiFi Router (Gateway)

const char* ssid = "xxxxx"; //SSID WIFI Access Point
const char* password = "xxxxx"; //Access Point Password
const char* mqtt_server = "xxxxx"; //IP address MQTT server

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

const char* inTopic_luci = "openhab/out/ufficio/luci/command";  // MQTT Topic this switch subscribes
const char* inTopic_foto = "openhab/out/ufficio/foto/command";  // MQTT Topic this switch subscribes
const char* switchTopic_luci = "openhab/in/ufficio/luci/state"; //MQTT Topic wall switch publish
const char* switchTopic_foto = "openhab/in/ufficio/foto/state"; //MQTT Topic wall switch publish

const int relay_luci = 0;   //D3 Pin for Relay
const int button_luci = 12; //D6 Pin for button
const int relay_foto  = 13; //D7 pin fotocopiatore
const int button_foto = 16; //D0 Pin for

bool relayState_luci = HIGH;
bool relayState_foto = HIGH;

Bounce debouncer = Bounce(button_luci, 50);
Bounce debouncer2 = Bounce(button_foto, 50);

unsigned long previousMillis = 0;  // will store last time STATUS was send to MQTT
const long interval = 60000; //one minute for status refresh
String topicString = "";

void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.config(staticIP, gateway, subnet);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    for (int i = 0; i < 500; i++) {
      delay(1);
    }
    Serial.print(".");
  }
  digitalWrite(2, LOW);
  delay(500);
  digitalWrite(2, HIGH);
  delay(500);
  digitalWrite(2, LOW);
  delay(500);
  digitalWrite(2, HIGH);
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  topicString = topic;
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  if (topicString == "openhab/out/ufficio/luci/command") {
    if ((char)payload[1] == 'F')  {
      digitalWrite(relay_luci, LOW);
      Serial.println(relay_luci);// Turn the RELAY OFF
      relayState_luci = LOW;
    } else if ((char)payload[1] == 'N') {
      digitalWrite(relay_luci, HIGH);
      Serial.println(relay_luci);// Turn the RELAY ON by making the voltage HIGH
      relayState_luci = HIGH;
    }
  }
  // foto
  if (topicString == "openhab/out/ufficio/foto/command") {
    if ((char)payload[1] == 'F')  {
      digitalWrite(relay_foto, LOW);
      Serial.println(relay_foto);// Turn the RELAY OFF
      relayState_luci = LOW;
    } else if ((char)payload[1] == 'N') {
      digitalWrite(relay_foto, HIGH);
      Serial.println(relay_foto);// Turn the RELAY ON by making the voltage HIGH
      relayState_foto = HIGH;
    }
  }
}

/*
  void callback_luci(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  if ((char)payload[1] == 'F')  {
    digitalWrite(relay_luci, LOW);
    Serial.println(relay_luci);// Turn the RELAY OFF
    relayState_luci = LOW;
  } else if ((char)payload[1] == 'N') {
    digitalWrite(relay_luci, HIGH);
    Serial.println(relay_luci);// Turn the RELAY ON by making the voltage HIGH
    relayState_luci = HIGH;
    Serial.println();
  }
  }

  void callback_foto(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  if ((char)payload[1] == 'F')  {
    digitalWrite(relay_foto, LOW);
    Serial.println(relay_foto);// Turn the RELAY OFF
    relayState_foto = LOW;
  } else if ((char)payload[1] == 'N') {
    digitalWrite(relay_foto, HIGH);
    Serial.println(relay_foto);// Turn the RELAY ON by making the voltage HIGH
    relayState_foto = HIGH;
  }
  }
*/
void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("pippo")) {
      Serial.println("connected");
      //Subscribe to incoming commands
      client.subscribe(inTopic_luci);
      client.subscribe(inTopic_foto);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      for (int i = 0; i < 5000; i++) {
        // extButton_luci();
        // extButton_foto();
        delay(1);
      }
    }
  }
}

void extButton_luci() {
  debouncer.update();
  if ( debouncer.fell() ) {
    Serial.println("Debouncer luci");
    relayState_luci = !relayState_luci;
    digitalWrite(relay_luci, relayState_luci);
    if (relayState_luci == 1) {
      client.publish(switchTopic_luci, "ON", false);
    }
    else if (relayState_luci == 0) {
      client.publish(switchTopic_luci, "OFF", false);
    }
  }
}

void extButton_foto() {
  debouncer2.update();
  if ( debouncer2.fell() ) {
    Serial.println("Debouncer foto");
    relayState_foto = !relayState_foto;
    digitalWrite(relay_foto, relayState_foto);
    if (relayState_foto == 1) {
      client.publish(switchTopic_foto, "ON", false);
    }
    else if (relayState_foto == 0) {
      client.publish(switchTopic_foto, "OFF", false);
    }
  }
}

//*************************************SETUP*****************************************//
//***********************************************************************************//
void setup() {
  String line = "";

  pinMode(relay_luci, OUTPUT);     // Initialize the relay pin as an output
  pinMode(button_luci, INPUT);     // Initialize the relay pin as an input
  pinMode(relay_foto, OUTPUT);
  pinMode(button_foto, INPUT);
  pinMode(2, OUTPUT);            // Initialize the onboard LED as output

  debouncer.attach(button_luci);   // Use the bounce2 library to debounce the built in button
  debouncer.interval(50);         // Input must be low for 50 ms
  debouncer2.attach(button_foto);
  debouncer2.interval(50);

  digitalWrite(2, LOW);          // Blink to indicate setup
  delay(50);
  digitalWrite(2, HIGH);
  delay(50);

  Serial.begin(115200);
  setup_wifi();                   // Connect to wifi

  client.setServer(mqtt_server, 1883); //connect to MQTT
  //client.setCallback(callback_luci);
  client.setCallback(callback);

  // Port defaults to 8266: ArduinoOTA.setPort(8266);
  ArduinoOTA.setHostname("Domotica ");
  ArduinoOTA.setPassword((const char *)"xxxxx");
  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

}

void loop() {
  ArduinoOTA.handle();

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

grazie a tutti

Cencio:
grazie a tutti

E grazie a te per aver postato la soluzione.