Door opener with 4x4 keypad via MQTT.

good morning everyone,

I want to open an electric lock (already working and managed by domoticz) remotely via a wifi wemos ESP12F module to which a 4x4 keypad is connected. I managed to put together pieces of arduino code to form a key, but I can't give the mqtt command to make domoticz open the electric lock.
If someone has some information or can give me a hand I attach below the code for arduino IDE.

include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Keypad.h>


const char* ssid = "XXX";
const char* password = "xxxxxxxx";
const char* mqtt_server = "10.0.255.202";
const char* mqtt_topic = "/dashbutton/#";
const char* mqtt_topic_state = "/domoticz/in";
const char* mqtt_client = "dashbutton";


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





// inizio codice tastiera
const byte ROWS = 4; //quattro righe
const byte COLS = 4; //quattro colonne
char keyInsert[6];
// Queste variabili servono come verifica del corretto inserimento del codice
int i = 0;
int j = 0;
int s = 0;
int x = 0;
// Codice segreto
char code[7] = "112233";
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {D7, D6, D5, D4}; //i Pin a cui sono connesse le righe del KeyPad
byte colPins[COLS] = {D3, D2, D1, D0}; // i Pin a cui sono connesse le colonne del KeyPad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
  // seriale
  Serial.begin(115200);
  //pinMode(LED,OUTPUT);
  //wifi
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(200);

  }
}

void loop(){
  char key = keypad.getKey();
  if (i==0){
    Serial.println("Insert PIN to verify...");
    i++;
  }
  if (key != NO_KEY && j<6){
    Serial.print("*");
    //Serial.println(key);
    keyInsert[j]=key;
    j++;
  }
   if(key == '*') {
      Serial.println();
      Serial.println("Verifyng the code...");
      delay(1000);
      for(s=0; s<6;s++){
        if(keyInsert[s]==code[s]){
          x++;
      }
    } 
      if(x==6){
      Serial.println("The code is correct"); 
    
      //TODO possibili ulteriori implementazioni
      client.setServer(mqtt_server, 1883);
        while (!client.connected()) {
    if (client.connect(mqtt_client)) {
      client.subscribe(mqtt_topic_state);
      delay(300);
      // ?????? HOW TO ENTER the code {"idx": 25,"nvalue": 1}?????
      client.publish(mqtt_topic_state,"testswitch 1");
      }
      }
      {delay(2000);
         x=0;
         i=0;
         j=0;
       }
       //TODO
      }else{
         Serial.println("The code is incorrect, please retry");
         delay(2000);
         x=0;
         i=0;
         j=0;
       }

      }  
    if(key == '#'){
        x=0;
        i=0;
        j=0;
        //digitalWrite(LED,LOW); 
    }    
}

The description of what you are trying to do is unclear, could you restate the objective?

As a note this code

    client.setServer(mqtt_server, 1883);
        while (!client.connected()) {
    if (client.connect(mqtt_client)) {
      client.subscribe(mqtt_topic_state);
      delay(300);
      // ?????? HOW TO ENTER the code {"idx": 25,"nvalue": 1}?????
      client.publish(mqtt_topic_state,"testswitch 1");

needs some grooming.

You'll never receive a subscription and, with the way the connection MQTT connection is made, you may have lost the connection by the time delay(3000) is up.

Here is some ESP code I wrote that opens WiFi, connects to a MQTT Broker, maintains an open connection and publishes stuff.

#include <WiFi.h>
#include <PubSubClient.h>
#include "certs.h" // include the connection infor for WiFi and MQTT
#include "sdkconfig.h" // used for log printing
#include "esp_system.h"
#include "freertos/FreeRTOS.h" //freeRTOS items to be used
#include "freertos/task.h"
#include <SPI.h> // ada fruity needs this ...
#include <Adafruit_Sensor.h> // and this ...
#include <Adafruit_BME280.h> // to run this library
#include <driver/adc.h>
#include "esp32-hal-ledc.h"
////
Adafruit_BME280 bme280( GPIO_NUM_5 ); // use hardware SPI, set GPIO pin to use
WiFiClient      wifiClient; // do the WiFi instantiation thing
PubSubClient    MQTTclient( mqtt_server, mqtt_port, wifiClient ); //do the MQTT instantiation thing
////
#define evtDoParticleRead   ( 1 << 0 ) // declare an event
#define evtWaitForBME       ( 1 << 1 )
#define evtDoBlue           ( 1 << 2 )
#define evtDoRed            ( 1 << 3 )
#define evtDoGreen          ( 1 << 4 )
EventGroupHandle_t eg; // variable for the event group handle
////
String AirQuality;
////
esp_timer_handle_t oneshot_timer; //veriable to store the hardware timer handle
////
////
void IRAM_ATTR oneshot_timer_callback( void* arg )
{
  BaseType_t xHigherPriorityTaskWoken;
  xEventGroupSetBitsFromISR( eg, evtDoParticleRead, &xHigherPriorityTaskWoken ); 
} //void IRAM_ATTR oneshot_timer_callback( void* arg )
////
/*
   This semaphore is used to stop or prevent a publish from happening during client.loop()
*/
SemaphoreHandle_t sema_MQTT_KeepAlive;
////
// interrupt service routine for WiFi events put into IRAM
void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
{
  switch (event) {
    case SYSTEM_EVENT_STA_CONNECTED:
      log_i("Connected to access point");
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      log_i("Disconnected from WiFi access point");
      break;
    case SYSTEM_EVENT_AP_STADISCONNECTED:
      log_i("WiFi client disconnected");
      break;
    default: break;
  }
} // void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
////
void setup()
{
  // red
  ledcSetup( 6, 12000, 8 ); // ledc: 4  => Group: 0, Channel: 2, Timer: 1, led frequency, resolution  bits // blue led
  ledcAttachPin( GPIO_NUM_14, 6 );   // gpio number and channel
  ledcWrite( 6, 0 ); // write to channel number 6
  // green
  ledcSetup( 5, 12000, 8 ); // ledc: 5  => Group: 0, Channel: 2, Timer: 1, led frequency, resolution  bits // blue led
  ledcAttachPin( GPIO_NUM_13, 5 );   // gpio number and channel
  ledcWrite( 5, 0 ); // write to channel number 5
  // blue
  ledcSetup( 4, 12000, 8 ); // ledc: 4  => Group: 0, Channel: 2, Timer: 1, led frequency, resolution  bits // blue led
  ledcAttachPin( GPIO_NUM_12, 4 );   // gpio number and channel
  ledcWrite( 4, 0 ); // write to channel number 4
  //
  eg = xEventGroupCreate(); // get an event group handle
  //
  gpio_config_t io_cfg = {}; // initialize the gpio configuration structure
  io_cfg.mode = GPIO_MODE_OUTPUT; // set gpio mode
  //bit mask of the pins to set
  io_cfg.pin_bit_mask = ( (1ULL << GPIO_NUM_4) ); // assign gpio number to be configured
  //configure GPIO with the given settings
  gpio_config(&io_cfg); // configure the gpio based upon the parameters as set in the configuration structure
  gpio_set_level( GPIO_NUM_4, LOW); // set air particle sensor trigger pin to LOW
  // set up A:D channels
  // https://dl.espressif.com/doc/esp-idf/latest/api-reference/peripherals/adc.html
  adc1_config_width(ADC_WIDTH_12Bit);
  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);// using GPIO 36
  //
  // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_timer.html?highlight=hardware%20timer High Resoultion Timer API
  esp_timer_create_args_t oneshot_timer_args = {}; // initialize High Resoulition Timer (HRT) configuration structure
  oneshot_timer_args.callback = &oneshot_timer_callback; // configure for callback, name of callback function
  esp_timer_create( &oneshot_timer_args, &oneshot_timer ); // assign configuration to the HRT, receive timer handle
  //
  xTaskCreatePinnedToCore( MQTTkeepalive, "MQTTkeepalive", 20000, NULL, 5, NULL, 1 ); // create and start the two tasks to be used, set those task to use 20K stack
  xTaskCreatePinnedToCore( DoTheBME280Thing, "DoTheBME280Thing", 20000, NULL, 4, NULL, 1);
  xTaskCreatePinnedToCore( fDoBlue, "fDoBlue", 4000, NULL, 3, NULL, 1 );
  xTaskCreatePinnedToCore( fDoRed, "fDoRed", 4000, NULL, 3, NULL, 1 );
  xTaskCreatePinnedToCore( fDoGreen, "fDoGreen", 4000, NULL, 3, NULL, 1 );
  xTaskCreatePinnedToCore( fDoParticleDetector, "fDoParticleDetector", 6000, NULL, 3, NULL, 1 ); // assign all to core 1
  
} //void setup()
////
void fDoRed( void * paramater )
{
  bool UpDown = true;
  int countUpDown = 0;
  for( ;; )
  {
     xEventGroupWaitBits (eg, evtDoRed, pdTRUE, pdTRUE, portMAX_DELAY );
     // send led data, increment led count, determine end stops and direction
    if ( UpDown )
    {
      countUpDown++;
    } else {
      countUpDown--;
    }
    if ( countUpDown <= 0 )
    {
      UpDown = true;
    }
    if ( countUpDown >= 255 )
    {
      UpDown = false;
    }
    //log_i( "red %d", countUpDown );
    ledcWrite( 6, countUpDown ); // write to channel number 4
    //
  }
   vTaskDelete( NULL );
} // void fDoRed( void * paramater )
////
void fDoGreen( void * paramater )
{
  bool UpDown = true;
  int countUpDown = 0;
  for( ;; )
  {
     xEventGroupWaitBits (eg, evtDoGreen, pdTRUE, pdTRUE, portMAX_DELAY );
     // send led data, increment led count, determine end stops and direction
    if ( UpDown )
    {
      countUpDown++;
    } else {
      countUpDown--;
    }
    if ( countUpDown <= 0 )
    {
      UpDown = true;
    }
    if ( countUpDown >= 255 )
    {
      UpDown = false;
    }
    //log_i( "green %d", countUpDown );
    ledcWrite( 5, countUpDown ); // write to channel number 4
    //
  }
   vTaskDelete( NULL );
} // void fDoGreen( void * paramater )
////
void fDoBlue( void * paramater )
{
  bool UpDown = true;
  int countUpDown = 0;
  for( ;; )
  {
     xEventGroupWaitBits (eg, evtDoBlue, pdTRUE, pdTRUE, portMAX_DELAY );
     // send led data, increment led count, determine end stops and direction
    if ( UpDown )
    {
      countUpDown++;
    } else {
      countUpDown--;
    }
    if ( countUpDown <= 0 )
    {
      UpDown = true;
    }
    if ( countUpDown >= 255 )
    {
      UpDown = false;
    }
    // log_i( "blue %d", countUpDown );
    ledcWrite( 4, countUpDown ); // write to channel number 4
    //
  }
   vTaskDelete( NULL );
} // void fDoBlue( void * paramater )
//

part 2

void fDoParticleDetector( void * parameter )
{
  /*
    ug/m3     AQI                 Lvl AQ (Air Quality)
             (air Quality Index)
    0-35     0-50                1   Excellent
    35-75    51-100              2   Average
    75-115   101-150             3   Light pollution
    115-150  151-200             4   moderate
    150-250  201-300             5   heavy
    250-500  >=300               6   serious
  */
  float ADbits = 4095.0f;
  float uPvolts = 3.3f;
  float adcValue = 0.0f;
  float dustDensity = 0.0f;
  float Voc = 0.6f; // Set the typical output voltage in Volts when there is zero dust.
  const float K = 0.5f; // Use the typical sensitivity in units of V per 100ug/m3.
  int publishCount = 0;
  
  xEventGroupWaitBits (eg, evtWaitForBME, pdTRUE, pdTRUE, portMAX_DELAY ); // event will be triggered by the timer expiring, wait here for the 280uS
  for (;;)
  {
    //enable sensor led
    gpio_set_level( GPIO_NUM_4, HIGH ); // set gpio 4 to high
    esp_timer_start_once( oneshot_timer, 280 ); // trigger one shot timer for a 280uS timeout
    xEventGroupWaitBits (eg, evtDoParticleRead, pdTRUE, pdTRUE, portMAX_DELAY ); // event will be triggered by the timer expiring, wait here for the 280uS
    adcValue = float( adc1_get_raw(ADC1_CHANNEL_0) ); //take a raw ADC reading from the dust sensor
    gpio_set_level( GPIO_NUM_4, LOW );//Shut off the sensor LED
    adcValue = ( adcValue * uPvolts ) / ADbits; //calculate voltage
    dustDensity = (adcValue / K) * 100.0; //convert volts to dust density
    if ( dustDensity < 0.0f )
    {
      dustDensity = 0.00f; // make negative values a 0
    }
    //
    if ( dustDensity <= 36.0f )
    {
      AirQuality = "LVL1";
    }
    if ( (dustDensity > 36.0f) && (dustDensity <= 75.0f) )
    {
      AirQuality = "LVL2";
    }
    if ( (dustDensity > 75.0f) && (dustDensity <= 115.0f) )
    {
      AirQuality = "LVL3";
    }
    if ( (dustDensity > 115.0f) && (dustDensity <= 150.0f) )
    {
      AirQuality = "LVL4";
    }
    if ( (dustDensity > 150.0f) && (dustDensity <= 250.0f) )
    {
      AirQuality = "LVL5";
    }
    if ( dustDensity >= 250.0f )
    {
      AirQuality = "LVL6";
    }
    publishCount++;
    xEventGroupSetBits( eg, evtDoBlue );
    //log_i( "ADC volts %f Dust Density = %fug/m3 %s", adcValue, dustDensity, AirQuality ); // print the calculated voltage and dustdensity
    if ( publishCount >= 4 )
    {
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
      //log_i( "ADC volts %f Dust Density = %fug/m3 %s", adcValue, dustDensity, AirQuality ); // print the calculated voltage and dustdensity
      MQTTclient.publish( topicInsidePM, String(dustDensity).c_str() );
      xSemaphoreGive( sema_MQTT_KeepAlive );
      publishCount = 0;
    }
   //
    vTaskDelay( 100 ); //good refresh rate of the amg88
    //log_i( " high watermark %d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete( NULL );
}// end fDoParticleDetector()
////
void DoTheBME280Thing( void *pvParameters )
{
  SPI.begin(); // initialize the SPI library
  // begin the BME280 show
  if (!bme280.begin()) {
    log_i("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
  float temperature = 0.0f;
  float pressure    = 0.0f;
  float humidity    = 0.0f;
  //wait for a mqtt connection
  while ( !MQTTclient.connected() )
  {
    vTaskDelay( 250 );
  }
  xEventGroupSetBits( eg, evtWaitForBME );
  for (;;)
  {
    temperature = ( 1.8f * bme280.readTemperature() ) + 32.0f;
    pressure    = bme280.readPressure() / 133.3223684f; // mmHg
    humidity    = bme280.readHumidity();
    log_i( " temperature %f, Pressure %f, Humidity %f", temperature, pressure, humidity);
    xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
    if ( MQTTclient.connected() )
    {
      MQTTclient.publish( topicInsideTemp, String(temperature).c_str() );
      vTaskDelay( 2 ); // gives the Raspberry Pi 4 time to receive the message and process
      MQTTclient.publish( topicInsideHumidity, String(humidity).c_str() );
      vTaskDelay( 2 ); // delay, RPi is still processing previous message
      MQTTclient.publish( topicInsidePressure, String(pressure).c_str() );
    }
    xSemaphoreGive( sema_MQTT_KeepAlive );
    xEventGroupSetBits( eg, evtDoGreen );
    vTaskDelay( 1000 * 15 );
    // log_i( "DoTheBME280Thing high watermark %d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete ( NULL );
}
////
/*
    Important to not set vTaskDelay to less then 10. Errors begin to develop with the MQTT and network connection.
    makes the initial wifi/mqtt connection and works to keeps those connections open.
*/
void MQTTkeepalive( void *pvParameters )
{
  sema_MQTT_KeepAlive   = xSemaphoreCreateBinary();
  xSemaphoreGive( sema_MQTT_KeepAlive ); // found keep alive can mess with a publish, stop keep alive during publish
  // setting must be set before a mqtt connection is made
  MQTTclient.setKeepAlive( 90 ); // setting keep alive to 90 seconds makes for a very reliable connection, must be set before the 1st connection is made.
  for (;;)
  {
    //check for a is-connected and if the WiFi 'thinks' its connected, found checking on both is more realible than just a single check
    if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
    {
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY ); // whiles MQTTlient.loop() is running no other mqtt operations should be in process
      MQTTclient.loop();
      xSemaphoreGive( sema_MQTT_KeepAlive );
    }
    else {
      log_i( "MQTT keep alive found MQTT status %s WiFi status %s", String(wifiClient.connected()), String(WiFi.status()) );
      if ( !(WiFi.status() == WL_CONNECTED) )
      {
        connectToWiFi();
      }
      connectToMQTT();
    }
    xEventGroupSetBits( eg, evtDoRed );
    vTaskDelay( 250 ); //task runs approx every 250 mS
  }
  vTaskDelete ( NULL );
}
////
void connectToMQTT()
{
  // create client ID from mac address
  byte mac[5];
  WiFi.macAddress(mac); // get mac address
  log_i( "mac address %d.%d.%d.%d.%d", mac[0], mac[1], mac[2], mac[3], mac[4]  );
  String clientID = String(mac[0]) + String(mac[4]) ; // use mac address to create clientID
  log_i( "connect to mqtt as client %s", clientID );
  while ( !MQTTclient.connected() )
  {
    MQTTclient.connect( clientID.c_str(), mqtt_username, mqtt_password );
    log_i( "connecting to MQTT" );
    vTaskDelay( 250 );
  }
  log_i("MQTT Connected");
}
//
void connectToWiFi()
{
  log_i( "connect to wifi" );
  while ( WiFi.status() != WL_CONNECTED )
  {
    WiFi.disconnect(); // if connected disconnect, more importantly clear the WiFi stack space.
    WiFi.begin( SSID, PASSWORD );
    log_i(" waiting on wifi connection" );
    vTaskDelay( 4000 );
  }
  log_i( "Connected to WiFi" );
  WiFi.onEvent( WiFiEvent );
}
////
void loop() { }

The description of what you are trying to do is unclear, could you restate the objective?

I wanted to open the electric lock by means of this device shown below.
By entering the correct code on the keypad, the electric lock on the door opens; I do not wish to connect a relay card directly to the device.

now everything works almost correctly I inserted this correct line

client.publish(mqtt_topic_state,"{"idx":25, "nvalue":1}");

I modified the wifi lines for when it loses connection.

I still have 1 problems:

  • I have to wait about 6 seconds if I make a mistake in the code and retype it.
    how can i do this?
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Keypad.h>


const char* ssid = "xx";
const char* password = "xxxx";
const char* mqtt_server = "192.x.x.x";
const char* mqtt_topic = "/keypaddoor";
const char* mqtt_topic_state = "domoticz/in";
const char* mqtt_client = "keypaddoor";


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





// inizio codice tastiera
const byte ROWS = 4; //quattro righe
const byte COLS = 4; //quattro colonne
char keyInsert[6];
// Queste variabili servono come verifica del corretto inserimento del codice
int i = 0;
int j = 0;
int s = 0;
int x = 0;
// Codice segreto
char code[7] = "112233";
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {D7, D6, D5, D4}; //i Pin a cui sono connesse le righe del KeyPad
byte colPins[COLS] = {D3, D2, D1, D0}; // i Pin a cui sono connesse le colonne del KeyPad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
  // seriale
  Serial.begin(115200);
  //pinMode(LED,OUTPUT);
  //wifi
  WiFi.begin(ssid, password);
  WiFi.softAPdisconnect (true);
  while (WiFi.status() != WL_CONNECTED) {
    delay(200);
    if (millis() > 6000) exit();
  }
}

void loop(){
  char key = keypad.getKey();
  if (i==0){
    Serial.println("Insert PIN to verify...");
    i++;
  }
  if (key != NO_KEY && j<6){
    Serial.print("*");
    //Serial.println(key);
    keyInsert[j]=key;
    j++;
  }
   if(key == '*') {
      Serial.println();
      Serial.println("Verifyng the code...");
      delay(1000);
      for(s=0; s<6;s++){
        if(keyInsert[s]==code[s]){
          x++;
      }
    } 
      if(x==6){
      Serial.println("The code is correct"); 
    
      //TODO possibili ulteriori implementazioni
      client.setServer(mqtt_server, 1883);
        while (!client.connected()) {
    if (client.connect(mqtt_client)) {
      client.subscribe(mqtt_topic_state);
      delay(300);
      client.publish(mqtt_topic_state,"{\"idx\":25, \"nvalue\":1}");
      }
      }
      if (millis() > 6000) exit();
      {delay(2000);
         x=0;
         i=0;
         j=0;
       }
       //TODO
      }else{
         Serial.println("The code is incorrect, please retry");
         delay(2000);
         x=0;
         i=0;
         j=0;
       }

      }  
    if(key == '#'){
        x=0;
        i=0;
        j=0;
        //digitalWrite(LED,LOW); 
    }    
}
void exit() {
  //never reaching this
}

When complaining about waiting for 6 seconds and one does not want to wait 6 seconds one might look at what code does the 6 second thing, no?

if (millis() > 6000) exit();

One may remember 1 second is 1000 milli seconds, and so it stands to reason that 6000 milli seconds would be about 6 seconds, right? And so if there is code causing a 6 second issue, it might the the code that does the 6 second thing?

Why not look at the millis examples on this site?

If I wanted to wait one second I would look at a clock and see if one second has passed, rights?

So if the current millis is 2099 and I want to wait 6000 more millis from the current millis then I would do something like this:
global:
int timetowait = 6000;
int millisPast=millis()

in loop():

if( (millis()-millisPast) >= timetowait )
{ then I do the fricking things and
millisPast=millis();
}


You'd put millisPast=millis; at the end of the if (client.connect(mqtt_client)) code.

 if (client.connect(mqtt_client))

Why keep opening up a mqtt connection without properly closing the newly opened connection, after its use?

if (millis() > 6000) exit();

I thought that inserting this code would close the mqtt connection.
So how would you do it, and why is a wifi accesspoint created?

giannivannucci:

if (millis() > 6000) exit();

I thought that inserting this code would close the mqtt connection.
So how would you do it

See post #6.

I'm sorry, I'm new to this, but I don't understand how it works.
2099 is the time it takes to connect to mqtt;
why did you do the subtraction between the variables
and why did you do millisPast=millis() to close the connection and not exit? ::slight_smile:

using millis for timing

int timetowait = 6000;
int millisPast=millis();
    .....
    if (client.connect(mqtt_client)) {
      client.subscribe(mqtt_topic_state);
      delay(300);
      client.publish(mqtt_topic_state,"{\"idx\":25, \"nvalue\":1}");
      }
      }
     
 if( (millis()-millisPast) >= timetowait );  //if the period 
is>or= continues by resetting the variables? and so closes the mqtt 
connection?   ???????
            {delay(2000);
         x=0;
         i=0;
         j=0;
         millisPast=millis();
       }
..........

so it could work it's not as easy as a walk ...is correction

Did you put the exit code:

 if( (millis()-millisPast) >= timetowait );  //if the period
is>or= continues by resetting the variables? and so closes the mqtt
connection?   ???????
            {
//delay(2000); <<<<<<<<<<<< remove that, please
         x=0;
         i=0;
         j=0;

put mqtt disconnect call here.

         millisPast=millis();
       }
[/code
........      
//TODO possibili ulteriori implementazioni
      client.setServer(mqtt_server, 1883);
      while (!client.connected()) {
        if (client.connect(mqtt_client)) {
          client.subscribe(mqtt_topic_state);
          delay(300);
          client.publish(mqtt_topic_state, "{\"idx\":25, \"nvalue\":1}");
        }
      }
      if ( (millis() - millisPast) >= timetowait );
      {
        x = 0;
        i = 0;
        j = 0;
        client.disconnect(); // Is it correct to close the connection in this way?
        millisPast = millis();
      }
      //TODO
......

I tried to compile and load it on the esp12 and it seems to work, sorry for the banality but how many times can I load a scketch without damaging the esp?

10,000

ok for>10000,
it has been under test for a few hours, it works well, tomorrow I will fix it to the wall permanently, thank you for your help and patience!

As a note:

........     
//TODO possibili ulteriori implementazioni
      client.setServer(mqtt_server, 1883);
      while (!client.connected()) {
        if (client.connect(mqtt_client)) {
          client.subscribe(mqtt_topic_state);
          delay(300);
          client.publish(mqtt_topic_state, "{\"idx\":25, \"nvalue\":1}");
        }
      }
      if ( (millis() - millisPast) >= timetowait );
      {
        x = 0;
        i = 0;
        j = 0;
        client.disconnect(); // Is it correct to close the connection in this way?
        millisPast = millis();
      }
      //TODO
......

This part

        client.disconnect(); // Is it correct to close the connection in this way?
        millisPast = millis();

Do you really want to start the count again at this point? I'd start the count millisPast = millis(); in after making a successful connection and only after making a successful connection.

tentatively...

........     
//TODO possibili ulteriori implementazioni
      client.setServer(mqtt_server, 1883);
      while (!client.connected()) {
        if (client.connect(mqtt_client)) {
if ( (millis() - millisPast) >= timetowait );
 {
        x = 0;
        i = 0;
        j = 0;
        millisPast = millis();
      }
          client.subscribe(mqtt_topic_state);
          delay(300);
          client.publish(mqtt_topic_state, "{\"idx\":25, \"nvalue\":1}");
        }
      }
        
        client.disconnect(); 
         
      //TODO
......

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.