JAndrassy / WiFiEspAT

Arduino networking library. Standard Arduino WiFi networking API over ESP8266 or ESP32 AT commands.
GNU Lesser General Public License v2.1
271 stars 44 forks source link

Failed MQTT Publish Messages #116

Open PelaGB17 opened 3 months ago

PelaGB17 commented 3 months ago

Hello, I am trying to make a Raspberry Pico with an ESP8266 with AT 2.2 send data from an SD via MQTT. I have succesfully connected to WiFi and to an MQTT broker, I have been also able to subscribe to some topics. However it is impossible for me to publish. Here is the code:

#include <Arduino.h>
#include <SPI.h> 
#include <SD.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <mbedtls/base64.h>

#define SD_SS_PIN 5 

// Configuración de WiFi
char ssid[] = "##########";
char password[] = "#########";
char server[] = "192.168.1.201";
int port = 1883;

// Configuración de MQTT
char clientID[] = "picoClient";
char topic[] = "Entrada_Img";

// Instancias de clases
WiFiClient espClient;
PubSubClient mqttClient(espClient);

//Variables auxiliares usadas a lo largo del codigo
int aux = 0;
File rootdir;
int var = 0;
char datos[40];
char datos2[40000];
uint16_t keep = 120;

// Funcion encargada de iniciar la conexion wifi 
void wifiInit()
{
  WiFi.init(&Serial1);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("Conectado a WiFi");
  Serial.println(WiFi.localIP());
}

//Funcion encargada de detectar la entrada de un mensaje por parte del usuario
void callback(char *topic, byte *payload, unsigned int length)
{ 
  //Funcion encargada de detectar la entrada de un mensaje por parte del usuario
  Serial.println("Mensaje recibido");

  char *payload_string=(char *)malloc(length+1);
  if (payload_string != nullptr) {

    memcpy(payload_string, payload, length);
    payload_string[length] = '\0';

    int resultI = atoi(payload_string);

    aux = 1;
    var = resultI;

    Serial.println("Salida de callback");

    free(payload_string);
  }
  else{
        Serial.println("Error: Failed to allocate memory for payload_string");
  }
}

//Funcion para volver a conectarse al servidor MQTT en caso de desconexion 

void reconnect() {
  // Loop until we're reconnected
  while (!mqttClient.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "PicoClient";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (mqttClient.connect(clientId.c_str())) {
      Serial.println("connected");
      mqttClient.subscribe("Entrada_Img");
    } else {
      Serial.print("failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

// Función principal de configuración
void setup() {
    delay(2500);
    // Inicio de comunicacion serial
    Serial.begin(112500);
    Serial1.begin(115200);
    Serial1.setTimeout(2000);

    // Inicio de comunicacion con la SD 
    bool inicio = SD.begin(SD_SS_PIN);
    // Comprobacion de inicio de comunicacion exitoso
    if (inicio != true)
    {
      Serial.print("No es posible abrir la SD");
      return;
    }
    rootdir = SD.open("/", FILE_READ);
    delay(3000); 
    // Comprobacion de inicio de comunicacion exitoso
    if (inicio != true)
    {
      Serial.print("No es posible abrir la SD");
      return;
    }
    rootdir = SD.open("/", FILE_READ);
    delay(3000); 

    Serial.println("Inicio de WiFi");

    //Inicio de conexion wifi y MQTT
    wifiInit(); 

    delay(3000);
    Serial.println("Inicio de MQTT");

    mqttClient.setServer(server, port);
    mqttClient.setCallback(callback); 
    mqttClient.setKeepAlive(keep);
    mqttClient.setSocketTimeout(keep);
    mqttClient.setStream(espClient);
    mqttClient.subscribe("Entrada_Img");
  }

// Función principal de bucle
void loop() {
  //Comprobacion de que la conexion MQTT siga estable 
  if (!mqttClient.connected())
  {
    reconnect();
  }
  mqttClient.loop();

  //En caso de recibir un "1" por parte del usuario 
  if (var == 1 && aux == 1)
  {  
    Serial.println("Entrada envio mensaje");
    //Se abrira una imagen almacenada en la SD y se enviara por MQTT
    File file = rootdir.openNextFile();
    if (!file)
    {
      Serial.println("No hay mas archivos en el directorio raiz");
      rootdir.rewindDirectory();
      return;
    }
    Serial.print(file.name());
    Serial.print(", Size: ");
    Serial.println(file.size());

    int bytesRead; 
    int segmentSize = 24;
    uint8_t *buffer = new uint8_t[segmentSize];
    int numSegments = file.size() / segmentSize;

    for (int i = 0; i < numSegments; i++) {
      size_t encoded_size = 0;
      bytesRead = file.read(buffer, segmentSize);
      int ret = mbedtls_base64_encode(nullptr, 0, &encoded_size, buffer, bytesRead);

      if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) {
        Serial.println("Error en la codificación... 1");
      } else {
        char *encoded_buffer = new char[encoded_size + 1];
        encoded_buffer[encoded_size] = '\0';

        ret = mbedtls_base64_encode((unsigned char*)encoded_buffer, encoded_size, nullptr, buffer, bytesRead);

        if (ret == 0) {
          Serial.print("Cadena ");
          Serial.print(i);
          Serial.print(": ");
          Serial.println(encoded_buffer);
          if(!mqttClient.publish("Salida_Img", encoded_buffer)){
            Serial.println("Error en el envío...");
            exit(0);
          }
          delay(1500);
          delete[] encoded_buffer;
        }
      }
    }

    if (file.size() % segmentSize != 0) { 
      size_t encoded_size = 0;
      int remainingBytes = file.size()-(segmentSize*numSegments);
      bytesRead = file.read(buffer, remainingBytes);
      int ret = mbedtls_base64_encode(nullptr, 0, &encoded_size, buffer, bytesRead);

      if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) {
        Serial.println("Error en la codificación... 1");
      } else {
        char *encoded_buffer = new char[encoded_size + 1];
        encoded_buffer[encoded_size] = '\0';

        ret = mbedtls_base64_encode((unsigned char*)encoded_buffer, encoded_size, nullptr, buffer, bytesRead);

        if (ret == 0) {
          if(!mqttClient.publish("Salida_Img", encoded_buffer)){
            Serial.println("Error en el envío...");
            exit(0);
          }
        } 

        delete[] encoded_buffer;
      }
    }

    file.close();

    sprintf(datos, "%s", file.name());
    Serial.println("Creado mensaje");
    delay(10);
    mqttClient.publish("Salida_Img", datos);

    Serial.println("Mensaje enviado");
    aux = 0; 

  }  
  else if(var == 2){  //Si se recibe un 2 en el topico subscrito se cerrara el programa 
    Serial.println("Cerrando programa"); 
    exit(0);
  }
}

And here you can see the log output

Inicio de WiFi
esp> @ ...ignored
esp INFO: soft reset
esp> AT+RST ...sent
esp> AT+RST ...ignored
esp> ERROR ...error
esp ERROR: expected ready got ERROR
esp> ATE0 ...sent
esp> ATE0 ...ignored
esp> OK ...matched
esp> AT+CIPMUX=1 ...sent
esp> OK ...matched
esp> AT+CIPRECVMODE=1 ...sent
esp> OK ...matched
esp> AT+SYSSTORE=0 ...sent
esp> OK ...matched
esp> AT+CWMODE? ...sent
esp> +CWMODE:3 ...matched
esp> OK ...matched
esp INFO: join AP GAIA_GATEWAY current
esp> AT+CWJAP="GAIA_GATEWAY","TSKpassNest20!" ...sent
esp> WIFI DISCONNECT ...ignored
esp> ?
esp> busy p... ...ignored
esp> WIFI CONNECTED ...ignored
esp> ?
esp> busy p... ...ignored
esp> WIFI GOT IP ...ignored
esp> OK ...matched
esp INFO: wifi status
esp> AT+CIPSTATUS ...sent
esp> STATUS:2 ...matched
esp> OK ...matched

Conectado a WiFi
esp INFO: STA IP query
esp> AT+CIPSTA? ...sent
esp> +CIPSTA:ip:"192.168.1.226" ...matched
esp> +CIPSTA:gateway:"192.168.1.1" ...matched
esp> +CIPSTA:netmask:"255.255.255.0" ...matched
esp> OK ...matched
192.168.1.226
Inicio de MQTT
Attempting MQTT connection...
esp INFO: free linkId is 4
esp INFO: start TCP to 192.168.1.201:1883 on link 4
esp> AT+CIPSTART=4,"TCP","192.168.1.201",1883 ...sent
esp> 4,CONNECT ...ignored
esp> OK ...matched
esp INFO: BuffManager new buff.stream at 0 for linkId 4 rx 64 tx 64
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: send data on link 4
esp> AT+CIPSEND=4,28 ...sent
esp> OK ...ignored
esp> > ...matched
esp> Recv 28 bytes ...matched
esp> SEND OK ...matched
esp INFO:   sent 28 bytes on link 4
esp> +IPD,4,4 ...processed
esp INFO: get data on link 4
esp> AT+CIPRECVDATA=4,64 ...sent
esp> +CIPRECVDATA ...matched
esp> OK ...matched
esp INFO:   got 4 bytes on link 4
connected
esp INFO: send data on link 4
esp> AT+CIPSEND=4,18 ...sent
esp> OK ...ignored
esp> > ...matched
esp> Recv 18 bytes ...matched
esp> SEND OK ...matched
esp INFO:   sent 18 bytes on link 4
esp> +IPD,4,5 ...processed
esp INFO: get data on link 4
esp> AT+CIPRECVDATA=4,64 ...sent
esp> +CIPRECVDATA ...matched
esp> OK ...matched
esp INFO:   got 5 bytes on link 4
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp INFO: sync
esp> AT+CIPRECVLEN? ...sent
esp> +CIPRECVLEN:-1,-1,-1,-1,0 ...matched
esp> OK ...matched
esp> +IPD,4,16 ...processed
esp INFO: get data on link 4
esp> AT+CIPRECVDATA=4,64 ...sent
esp> +CIPRECVDATA ...matched
esp> OK ...matched
esp INFO:   got 16 bytes on link 4
Mensaje recibido
Salida de callback
Entrada envio mensaje
PC(1).JPG, Size: 3031
Cadena 0: /9j/4QBWRXhpZgAATU0AKgAAAAgABAES
Cadena 1: AAMAAAABAAEAAAEaAAUAAAABAAAAPgEb
esp INFO: send data on link 4
esp> AT+CIPSEND=4,64 ...sent
esp> OK ...ignored
esp> > ...matched
esp> Recv 64 bytes ...matched
esp> SEND OK ...matched
esp INFO:   sent 64 bytes on link 4
Cadena 2: AAUAAAABAAAARgEoAAMAAAABAAIAAAAA
esp> 4,CLOSED ...processed
esp INFO: closed linkId 4
Error en el envío...