Go Down

Topic: ESP32 Semaphores to connect to wifi and MQTT error Help (Read 306 times) previous topic - next topic

Idahowalker

This code does not produce any errors,
Code: [Select]
#include "sdkconfig.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"

//#include <ESP32Ping.h>
#include <WiFi.h>

// Update these with values suitable for your network.
#include <PubSubClient.h>
#define WIFI_NETWORK "mywifi"
#define WIFI_PASSWORD "mypass"
#define WIFI_TIMEOUT_MS 30000 // 30 second WiFi connection timeout
#define WIFI_RECOVER_TIME_MS 10000 // Wait 30 seconds after a failed connection attempt

const char* mqtt_server = "myserver";
#define mqtt_port 11111
#define MQTT_USER "user1"
#define MQTT_PASSWORD "pass1"
#define MQTT_SERIAL_PUBLISH_CH "myapp/user1"
#define MQTT_SERIAL_RECEIVER_CH "myapp/user1"
WiFiClient wifiClient;
PubSubClient MQTT_client(wifiClient);
//end of mqtt and wifi settings

SemaphoreHandle_t sema_MQTT_ConnectListen;
SemaphoreHandle_t sema_InternetConnection;
SemaphoreHandle_t sema_InternetStatus;

bool isonline = false;

void MQTT_callback(char* topic, byte *payload, unsigned int length) {
  // Serial.println("-------new message from broker-----");
  // Serial.print("channel:");
  // Serial.println(topic);
  Serial.print("data:");
  // Serial.write(payload, length);
  //Serial.println(payload);
  Serial.println();
  int i = 0;
  char strPayload[300];
  for ( i; i < length; i++)
  {
    strPayload[i] = ((char)payload[i]);
  }
  strPayload[i] = NULL;
  MQTT_parser(topic, strPayload);
}

void setup() {

  Serial.begin(115200);
  // Set time out for
  Serial.setTimeout(500);


  sema_MQTT_ConnectListen = xSemaphoreCreateBinary();
  sema_InternetConnection = xSemaphoreCreateBinary();
  sema_InternetStatus = xSemaphoreCreateBinary();
  xSemaphoreGive(sema_MQTT_ConnectListen);

  //my task
  xTaskCreatePinnedToCore(InternetConnection, "InternetConnection", 5000, NULL, 2, NULL, 1);
  xTaskCreatePinnedToCore(MQTT_ConnectListen, "MQTT_ConnectListen", 30000, NULL, 2, NULL, 1);
  xTaskCreatePinnedToCore(InternetStatus, "InternetStatus", 5000, NULL, 2, NULL, 1);
  //end my task

}


void publishSerialData(char *serialData) {
  if (!MQTT_client.connected()) {
    // reconnect();
  }
  MQTT_client.publish(MQTT_SERIAL_PUBLISH_CH, serialData);
}

void loop() {
}

void MQTT_ConnectListen( void * pvParameters ) {
  MQTT_client.setServer(mqtt_server, mqtt_port);
  MQTT_client.setCallback(MQTT_callback);
  for (;;) {
    if (isonline = false) {
      vTaskDelay(10000 / portTICK_PERIOD_MS);
      continue;
    }
    if (!MQTT_client.connected()) {
      // Loop until we're reconnected
      while (!MQTT_client.connected()) {
        Serial.print("Attempting MQTT connection...");
        // Create a random client ID
        String clientId = "myuser1";
        //clientId += String(random(0xffff), HEX);
        // Attempt to connect
        if (MQTT_client.connect(clientId.c_str(), MQTT_USER, MQTT_PASSWORD)) {
          Serial.println("connected");
          //vTaskDelay(1000/portTICK_PERIOD_MS);
          //Once connected, publish an announcement...
          //client.publish("myapp/user1", "hello world");
          // ... and resubscribe
          MQTT_client.subscribe(MQTT_SERIAL_RECEIVER_CH, 1);
        } else {
          Serial.print("failed, rc=");
          Serial.print(MQTT_client.state());
          Serial.println(" try again in 5 secondssss");
          vTaskDelay(5000 / portTICK_PERIOD_MS);
          continue;
        }
      }
    }
    else {
      xSemaphoreTake(MQTT_ConnectListen, portMAX_DELAY);
      MQTT_client.loop();
      xSemaphoreGive(MQTT_ConnectListen);
    }
  }

}

void InternetConnection( void * pvParameters ) {

  int first = 0;
  for (;;) {
    if (first == 0) {
      Serial.println("initiallising");
      first = 1;
      vTaskDelay(1000 / portTICK_PERIOD_MS);
      continue;
    }
    if (WiFi.status() == WL_CONNECTED) {
      vTaskDelay(10000 / portTICK_PERIOD_MS);
      continue;
    }

    Serial.println("[WIFI] Connecting");
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD);

    unsigned long startAttemptTime = millis();

    // Keep looping while we're not connected and haven't reached the timeout
    while (WiFi.status() != WL_CONNECTED &&
           millis() - startAttemptTime < WIFI_TIMEOUT_MS) {}

    // When we couldn't make a WiFi connection (or the timeout expired)
    // sleep for a while and then retry.
    if (WiFi.status() != WL_CONNECTED) {
      Serial.println("[WIFI] FAILED");
      vTaskDelay(WIFI_RECOVER_TIME_MS / portTICK_PERIOD_MS);
      continue;
    }
  }

}
void InternetStatus( void * pvParameters ) {

  for (;;) {
    //        if(Ping.ping("google.com")) {
    //           isonline=true;
    //           Serial.println("hi,im online");
    //           vTaskDelay(250/portTICK_PERIOD_MS);
    //           continue;
    //        }
    //        else {
    //           isonline=false;
    //           Serial.println("not online");
    //           vTaskDelay(10000/portTICK_PERIOD_MS);
    //           continue;
    //        }
  }
}

void MQTT_parser(char * ttopic, char* ppayload)
{
  //print message just for test
  Serial.print(ppayload);
}

after uploading and running.
Receiving partial information does not help me help you and wastes my time.

chris700

This code does not produce any errors,
Code: [Select]
#include "sdkconfig.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"

//#include <ESP32Ping.h>
#include <WiFi.h>

// Update these with values suitable for your network.
#include <PubSubClient.h>
#define WIFI_NETWORK "mywifi"
#define WIFI_PASSWORD "mypass"
#define WIFI_TIMEOUT_MS 30000 // 30 second WiFi connection timeout
#define WIFI_RECOVER_TIME_MS 10000 // Wait 30 seconds after a failed connection attempt

const char* mqtt_server = "myserver";
#define mqtt_port 11111
#define MQTT_USER "user1"
#define MQTT_PASSWORD "pass1"
#define MQTT_SERIAL_PUBLISH_CH "myapp/user1"
#define MQTT_SERIAL_RECEIVER_CH "myapp/user1"
WiFiClient wifiClient;
PubSubClient MQTT_client(wifiClient);
//end of mqtt and wifi settings

SemaphoreHandle_t sema_MQTT_ConnectListen;
SemaphoreHandle_t sema_InternetConnection;
SemaphoreHandle_t sema_InternetStatus;

bool isonline = false;

void MQTT_callback(char* topic, byte *payload, unsigned int length) {
  // Serial.println("-------new message from broker-----");
  // Serial.print("channel:");
  // Serial.println(topic);
  Serial.print("data:");
  // Serial.write(payload, length);
  //Serial.println(payload);
  Serial.println();
  int i = 0;
  char strPayload[300];
  for ( i; i < length; i++)
  {
    strPayload[i] = ((char)payload[i]);
  }
  strPayload[i] = NULL;
  MQTT_parser(topic, strPayload);
}

void setup() {

  Serial.begin(115200);
  // Set time out for
  Serial.setTimeout(500);


  sema_MQTT_ConnectListen = xSemaphoreCreateBinary();
  sema_InternetConnection = xSemaphoreCreateBinary();
  sema_InternetStatus = xSemaphoreCreateBinary();
  xSemaphoreGive(sema_MQTT_ConnectListen);

  //my task
  xTaskCreatePinnedToCore(InternetConnection, "InternetConnection", 5000, NULL, 2, NULL, 1);
  xTaskCreatePinnedToCore(MQTT_ConnectListen, "MQTT_ConnectListen", 30000, NULL, 2, NULL, 1);
  xTaskCreatePinnedToCore(InternetStatus, "InternetStatus", 5000, NULL, 2, NULL, 1);
  //end my task

}


void publishSerialData(char *serialData) {
  if (!MQTT_client.connected()) {
    // reconnect();
  }
  MQTT_client.publish(MQTT_SERIAL_PUBLISH_CH, serialData);
}

void loop() {
}

void MQTT_ConnectListen( void * pvParameters ) {
  MQTT_client.setServer(mqtt_server, mqtt_port);
  MQTT_client.setCallback(MQTT_callback);
  for (;;) {
    if (isonline = false) {
      vTaskDelay(10000 / portTICK_PERIOD_MS);
      continue;
    }
    if (!MQTT_client.connected()) {
      // Loop until we're reconnected
      while (!MQTT_client.connected()) {
        Serial.print("Attempting MQTT connection...");
        // Create a random client ID
        String clientId = "myuser1";
        //clientId += String(random(0xffff), HEX);
        // Attempt to connect
        if (MQTT_client.connect(clientId.c_str(), MQTT_USER, MQTT_PASSWORD)) {
          Serial.println("connected");
          //vTaskDelay(1000/portTICK_PERIOD_MS);
          //Once connected, publish an announcement...
          //client.publish("myapp/user1", "hello world");
          // ... and resubscribe
          MQTT_client.subscribe(MQTT_SERIAL_RECEIVER_CH, 1);
        } else {
          Serial.print("failed, rc=");
          Serial.print(MQTT_client.state());
          Serial.println(" try again in 5 secondssss");
          vTaskDelay(5000 / portTICK_PERIOD_MS);
          continue;
        }
      }
    }
    else {
      xSemaphoreTake(MQTT_ConnectListen, portMAX_DELAY);
      MQTT_client.loop();
      xSemaphoreGive(MQTT_ConnectListen);
    }
  }

}

void InternetConnection( void * pvParameters ) {

  int first = 0;
  for (;;) {
    if (first == 0) {
      Serial.println("initiallising");
      first = 1;
      vTaskDelay(1000 / portTICK_PERIOD_MS);
      continue;
    }
    if (WiFi.status() == WL_CONNECTED) {
      vTaskDelay(10000 / portTICK_PERIOD_MS);
      continue;
    }

    Serial.println("[WIFI] Connecting");
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD);

    unsigned long startAttemptTime = millis();

    // Keep looping while we're not connected and haven't reached the timeout
    while (WiFi.status() != WL_CONNECTED &&
           millis() - startAttemptTime < WIFI_TIMEOUT_MS) {}

    // When we couldn't make a WiFi connection (or the timeout expired)
    // sleep for a while and then retry.
    if (WiFi.status() != WL_CONNECTED) {
      Serial.println("[WIFI] FAILED");
      vTaskDelay(WIFI_RECOVER_TIME_MS / portTICK_PERIOD_MS);
      continue;
    }
  }

}
void InternetStatus( void * pvParameters ) {

  for (;;) {
    //        if(Ping.ping("google.com")) {
    //           isonline=true;
    //           Serial.println("hi,im online");
    //           vTaskDelay(250/portTICK_PERIOD_MS);
    //           continue;
    //        }
    //        else {
    //           isonline=false;
    //           Serial.println("not online");
    //           vTaskDelay(10000/portTICK_PERIOD_MS);
    //           continue;
    //        }
  }
}

void MQTT_parser(char * ttopic, char* ppayload)
{
  //print message just for test
  Serial.print(ppayload);
}

after uploading and running.
Code: [Select]
initiallising
Attempting MQTT connection...failed, rc=-2 try again in 5 secondssss
[WIFI] Connecting
Attempting MQTT connection...connected
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c:1443 (xQueueGenericReceive)- assert failed!
abort() was called at PC 0x40088885 on core 1

Backtrace: 0x4008c434:0x3ffce8b0 0x4008c665:0x3ffce8d0 0x40088885:0x3ffce8f0 0x400d10bb:0x3ffce930 0x40088b7d:0x3ffce970

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
initiallising
Attempting MQTT connection...failed, rc=-2 try again in 5 secondssss
[WIFI] Connecting

This is what i get when i run this code.. (if i either have the server offline or wrong username/password and as a result a connection to the MQTT cannot be made then i do not get this reboot crash thing but only repeatedly Attempting MQTT connection...failed, rc=-2 try again in 5 secondssss )

Idahowalker

#32
Nov 21, 2020, 09:55 pm Last Edit: Nov 21, 2020, 09:59 pm by Idahowalker
As I do not see this working for you, it's time to go back to using the code you had that worked.
Receiving partial information does not help me help you and wastes my time.

chris700

Is this code working for you? Like connecting on wifi and on mqtt and receiving data?

Idahowalker

#34
Nov 21, 2020, 10:31 pm Last Edit: Nov 21, 2020, 10:36 pm by Idahowalker
So you gots to go back and really take a look at your code, without the freeRTOS stuff your code is missing stuff.

This is your PubSubClient construction.
Code: [Select]

PubSubClient MQTT_client(wifiClient);

Here is mine:
Code: [Select]
PubSubClient MQTTclient( mqtt_server, mqtt_port, wifiClient );
Notice a difference? How can your program connect to a MQTT Broker when its not told the what not about and stuff?

I thought you wrote you had working code?

After you fix that issue post the new code and your new issues.


Quote
Quote from: chris700 Sat Nov 21 2020 06:16:42 GMT-0700 (Mountain Standard Time)
Code was working untill i tried the semaphore things:
Receiving partial information does not help me help you and wastes my time.

chris700

i have inside MQTT_ConnectListen (before the loop)
Code: [Select]
 MQTT_client.setServer(mqtt_server, mqtt_port);
  MQTT_client.setCallback(MQTT_callback);


code works and connect to mqtt and receives data if i remove the give and take before and after loop.. so i guess the problem is with the semaphores and not with the code itself

edit:
i replaced the pubsubclient declaration with yours and i removed those 2 lines however still same things..crashes etc

gfvalvo

You like candy, I have candy. When I put a candy on a table, you take it. If I do not put candy on the table for you to take then how can you take candy that is not there for you to take?
I can wait for you to put the candy on the table. Which is the whole point of semaphores:





At that point portMax_DELAY will time out ...
How can portMax_DELAY "time out"?
No technical questions via PM. They will be ignored. Post your questions in the forum so that all may learn.

Go Up