PLC IDE - PubSub Sketch (MQTT)

I have attempted to a PubSubClient going in the PLC IDE. I a MQTT connection over WiFi it in the normal Arduino IDE with no issues. But in the PLC IDE I am not able to reuse the same sketch. I have however modified it to use wired ethernet. The issue I'm having is that the connection to the MQTT broker is unstable, it takes forever to establish the connection, and once established it is lost almost immediately. I have managed to publish a few values to the broker, but not 4 times a minute like i wanted.

// shared variables can be accessed with PLCIn.varname and PLCOut.varname

#include <PubSubClient.h>
#include <PortentaEthernet.h>
arduino::EthernetClass eth(&m_netInterface);

const char* mqtt_server = "192.168.0.199";
EthernetClient ethClient;
PubSubClient client(ethClient);

int32_t millisLast = 0;

void setup()
{
/*
    // Configure static IP address
	IPAddress ip(192, 168, 0, 188);
	IPAddress dns(8, 8, 8, 8);
	IPAddress gateway(192, 168, 0, 1);
	IPAddress subnet(255, 255, 255, 0);
	// If cable is not connected this will block the start of PLC with about 60s of timeout!
	eth.begin(ip, dns, gateway, subnet);
*/
    eth.begin();
    
    PLCIn.status = 1;

    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
    
    PLCIn.status = 4;
    PLCIn.LB = true;
    // Allow the hardware to sort itself out
    delay(1500);
    PLCIn.status = 5;
}

void loop()
{
    PLCIn.status = 6;

    if (!client.connected()) {
        PLCIn.LR = true;
        PLCIn.status = 7;
        reconnect();
        PLCIn.LR = false;
    }
    client.loop();

    int32_t diff = millis() - millisLast;
    PLCIn.diff = diff;
    if(diff >= 15000){
        PLCIn.status = 8;
        millisLast = millis();
        PLCIn.LB = publish(PLCOut.cnt);
    }
    
}


void callback(char* topic, byte* payload, unsigned int length) {
  ;
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    // Attempt to connect
    if (client.connect("arduinoClient")) {
      // Once connected, publish an announcement...
      //client.publish("Opta/outTopic","hello world");
      // ... and resubscribe
      //client.subscribe("inTopic");
    } else {
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


bool publish(int32_t val){
   char buff[20];
   int n = sprintf(buff, "%d", val);

   return client.publish("Opta/Value", buff, n);
}
1 Like

Hello @Koppit

Cool!

Have you tried to use WiFi? (Just curious)

At the moment that seems normal: ethernet with TCP connection within the PLC IDE Runtime is not as stable as a "raw" Arduino sketch, basically inside the PLC IDE Runtime, there are several threads on the background so the timing of it is different (slower).

We are working on improving the PLC IDE Runtime, so the ethernet with TCP is more stable.

1 Like

Hi,

I have tried the sketch with wifi. But the problem got worse, but maybe I've made a mistake.

// shared variables can be accessed with PLCIn.varname and PLCOut.varname

// shared variables can be accessed with PLCIn.varname and PLCOut.varname

#include <PubSubClient.h>
#include <WiFi.h>

char ssid[]  = "[SECRET]";
char pass[]  = "[SECRET]";
const char* mqtt_server = "192.168.0.199";

WiFiClient wclient;
PubSubClient client(wclient);

int status = WL_IDLE_STATUS;

int32_t millisLast = 0;

void setup()
{

    PLCIn.state = 1;
    // attempt to connect to Wifi network:
    if (WiFi.status() == WL_NO_SHIELD) {
        PLCIn.state = 2;
        while (true);
    }
  

      
    // check for the WiFi module:
    while (status != WL_CONNECTED) {
        PLCIn.state = 3;
        // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
        status = WiFi.begin(ssid, pass);
        // wait 3 seconds for connection:
        delay(3000);
    }
    PLCIn.state = 4;


    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
    

    // Allow the hardware to sort itself out
    delay(500);

}

void loop()
{
    client.loop();
    PLCIn.state = 5;
    PLCIn.LB = WL_CONNECTED == WiFi.status();

    if (!client.connected()) {
        PLCIn.LR = true;
        PLCIn.state = 6;
        reconnect();
        publish(millis());
    }
    else {
        PLCIn.LR = false;
    }
    
    int32_t diff = millis() - millisLast;
    PLCIn.diff = diff;

    if(diff >= 15000){
        PLCIn.state = 7;
        publish(millis());
        millisLast = millis();
    }
    
}


void callback(char* topic, byte* payload, unsigned int length) {
  ;
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    // Attempt to connect
    if (client.connect("Opta")) {
      // Once connected, publish an announcement...
      //.publish("Opta/outTopic","hello world");
      // ... and resubscribe
      //client.subscribe("inTopic");
    } else {
      // Wait 2 seconds before retrying
      delay(2000);
    }
  }
}


bool publish(int32_t val){
   char buff[20];
   int n = sprintf(buff, "%d", val);

   return client.publish("Opta/Value", buff, n);
}

I am currently facing similar problems with my Opta Wifi: Sketches utilizing the PubSubClient library work fine over normal IDE. However, after uploading the same sketch via the PLC IDE, the connection takes a long time to establish or it does not work at all. For example, the following sketch should toggle a test bit (and an LED on the opta) on/off every second, and update its state to my MQTT server over Wifi. When uploaded via PLC IDE, connecting to the server takes a long time, and the test bit is toggled every 20-25 seconds instead of 1. More often than not, the sketch gets stuck in the "reconnect" function:


#include <PubSubClient.h>
#include <WiFi.h>

char ssid[]  = "[secrets]";
char pass[]  = "[secrets]";
const char* mqtt_server = "192.168.1.151";

WiFiClient wificlient;
PubSubClient client(wificlient);

int status = WL_IDLE_STATUS;

int32_t millisLast = 0;

void setup()
{
    if (WiFi.status() == WL_NO_SHIELD) {
        while (true);
    }
    while (status != WL_CONNECTED) {
        status = WiFi.begin(ssid, pass);
        delay(3000);
    }
    client.setServer(mqtt_server, 1883);
    client.setCallback(callback);
    delay(500);

}

void loop()
{
    client.loop();
    if (!client.connected()) {
        reconnect();
    }
    client.publish("PLC_Test" ,"ON");
    digitalWrite(LED_D0, HIGH);
    delay(1000);   
    client.publish("PLC_Test" ,"OFF");
    digitalWrite(LED_D0, LOW); 
    delay(1000);
}

void callback(char* topic, byte* payload, unsigned int length) {
  ;
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    if (client.connect("PLC")) {
    } else {
      delay(2000);
    }
  }
}

I found this post from the Portenta Machine Control forums stating that MQTT integration via the PLC IDE is not possible at the moment. I'd assume this the case with Opta as well? Easy MQTT integration through sketches alongside PLC control would be a huge benefit for this PLC. Tbh it was one of the reasons I even got myself one...

3 Likes

@hehala You are right, within the PLC IDE runtime is not implemented yet.

Best regards!

News about using mqtt in PLC IDE?

1 Like

Is there any movement on this? Or information on development and upcoming changes? Are they going to open up the library integration for the PLC IDE in the near future or do I need to stop holding my breath and focus on using this OPTA through other means?

1 Like

@PMarquinez

1 Like

Looks like the PubSub library is working in the latest PLC IDE .
Connection to broker is quick, and the publishing is consistent so far.

1 Like

Hi, I am new to the PLC IDE.
Can you please explain to me what are:
PLCIn.status
PLCIn.LR
PLCIn.LB

Thanks!
Stephane.

Hi,

They are just variables I have declared (LB = LED Blue LR = LED Red).

ok, thanks.
So PLCIn is a function?

Hi again,
I have the sketch working but I have the same issue where the connection takes a long time and fails.
Did you change your sketch?
What version of the IDE and the libraries are you using?
Thanks!

Hi, I belive I'm using 1.0.4, it's unclear because the about windows says 1.0.3.1 but in windows settings it says I have 1.0.4 installed.

The library I'm using is ArduinoMqttClient 0.1.7
The connection appears to be stable on Wifi (have not tested wired ethernet):
My test data is posted to broker on a regular interval.

Edit:
Noticed that I in my first post were using PubSubClient library 2.8.0
Just did a quick test now and it looks ok now also.

I have your original code (using PubSubClient) working but the connection is eratic and therefore not usable.
The Opta is connected directly to a Raspberry Pi via ethernet.
I am using the Aedes mqtt server from within Node Red.

My next step is to try with the Arduino MQTT library.

I just don't get why, with a stable ethernet connection, the connection to the mqtt server is not stable.

1 Like

Could you olease publish your code using the ArduinoMqttClient?

Thanks!

Any update yet on the mqtt struggles in PLC IDE? I am trying to connect to my broker, and in setup it says it has a connection, but it takes forever to load the PLC part, and when that loads finally, and the loop starts, it does not receive messages. So do i need to just forget about this going to work? Same goes for the strange thing that when you use Modbus TCP, you can't use the Ethernet anymore .. so no MQTT ... it works on other devices, so why not on the OPTA? I got this device for the benefit of having a separate layer doing the modbus stuff, and connecting to my backend with mqtt ... please let us know when the OPTA will be mature?

Hi,

Using the latest 1.0.3.1 PLC IDE. Also, trying to get MQTT(over Ethernet) and ModbusTCP to work in same sketch in PLC IDE.

AlPlc_Opta library is shown as 1.0.3 but I think 1.0.4 is available.

(1) Would 1.0.4 runtime make any improvmeents?
(2) How do I upgrade to use 1.0.4 in the PLC IDE? Adding it as a library doesn't just pull it in and use it.

Thanks,
Steve Cunnagin

1 Like

Does anyone have an update on this?
thanks