-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Hi Stefan
As a beginner with Codesys and MQTT, I have found your repository extremely helpful in understanding and implementing MQTT communication in my PLC project. I have successfully set up some logic with my devices and controller, but I'm facing a challenge in making the system work continuously based on incoming MQTT messages.
My goal is to have the PLC execute a specific logic sequence whenever it receives a message on a predefined topic from the MQTT broker. This logic should then publish the corresponding steps continuously in a loop until a new message is received, triggering a different logic sequence.
Currently, I can only manage to run the system once and publish the results, but I want the PLC to execute the logic immediately after receiving a message from the broker and keep publishing the logic steps in a loop until a new message arrives. I followed the following Function blocks:
//Function Block
FUNCTION_BLOCK FirstPublish
//VAR
VAR
publisher_1:MQTT.MQTTPublish;
publisher_2:MQTT.MQTTPublish;
publisher_3:MQTT.MQTTPublish;
doPublish: BOOL:=True ;
init: BOOL;
//Sinit: BOOL;
sendPayload_1:STRING :='PsTL: 1';
sendPayload_2:STRING :='PsTL: 2';
sendPayload_3:STRING :='PsTL: 3';
END_VAR
IF PLC_PRG.sPayload = 1 THEN
init := TRUE;
publisher_1.SetMqttInOut(MQTT_IN_OUT := PLC_PRG.MQTT_IN_OUT);
ELSIF PLC_PRG.sPayload = 2 THEN
init := TRUE;
publisher_2.SetMqttInOut(MQTT_IN_OUT := PLC_PRG.MQTT_IN_OUT);
ELSIF PLC_PRG.sPayload = 3 THEN
init := TRUE;
publisher_3.SetMqttInOut(MQTT_IN_OUT := PLC_PRG.MQTT_IN_OUT);
init := FALSE;
END_IF;
publisher_1(
Topic:= ADR('Test/PsTL_1'), PayloadString:= ADR(sendPayload_1), PublishAsString:= TRUE, QoSIn:= MQTT.QoS.ExactlyOnce,
MRetain:= FALSE, send:= doPublish);
publisher_2(
Topic:= ADR('Test/PsTL_2'), PayloadString:= ADR(sendPayload_2), PublishAsString:= TRUE, QoSIn:= MQTT.QoS.ExactlyOnce,
MRetain:= FALSE, send:= doPublish);
publisher_3(
Topic:= ADR('Test/PsTL_3'), PayloadString:= ADR(sendPayload_3), PublishAsString:= TRUE, QoSIn:= MQTT.QoS.ExactlyOnce,
MRetain:= FALSE, send:= doPublish);
FUNCTION_BLOCK FirstSubscription
//VAR
VAR
collector:MQTT.CallbackCollector;
SUB1:MQTT.MQTTSubscribe;
init: BOOL;
receiver:MQTT.ReceiveString;
fPayload : INT ;
END_VAR
IF NOT init THEN
init := TRUE;
SUB1.SetMqttInOut(MQTT_IN_OUT:= PLC_PRG.MQTT_IN_OUT);
collector.put(instance:= receiver);
receiver.initAsFindTopic(compString:= ADR('Test/PsTL_1'), returnHit:= TRUE);
END_IF
fpayload := STRING_TO_INT(receiver.MQTTReceived);
SUB1(
Subscribe:= TRUE, Topic:= ADR('Test/PsTL_1'), QoSSubscribe:= MQTT.QoS.ExactlyOnce, ExpectingString:= TRUE,
Callback:= collector);
In PLC_PRG I did this logic for publishing
//After getting message from Broker
IF FirstSubscription.fPayload = 1 THEN
lastTouchedSensor := 0; // Initialize last touched sensor
// Initialize values and colors at the start of the program
END_IF
IF In THEN
IF lastTouchedSensor = 0 OR lastTouchedSensor = 1 THEN
lastTouchedSensor := 1; // Update last touched sensor
FirstPublish();
END_IF
END_IF
IF In2 THEN
IF lastTouchedSensor = 1 THEN
FirstPublish();
END_IF
END_IF
IF In3 THEN
IF lastTouchedSensor = 2 THEN
FirstPublish();
END_IF
END_IF
Can you please help me in which way I can run this process continuously?