我可以使用此代码阅读多个订阅主题。但是,我订阅了许多不同的主题,而且长长的 if 语句正在减慢我的代码速度。我已经不得不在 PlcTask 中将循环滴答的数量增加到 20(这可能是矫枉过正,但 10 还不够)。我正在寻找一种更智能的解决方案,它可以在更少的周期滴答声中发挥作用。在下面显示的代码中,可以清楚地看到这个 IF 语句有多长,这甚至不是整个 if 语句(仅针对主题 machine 和 motion1)。
IF fbMessageQueue.nQueuedMessages > 0 THEN
IF fbMessageQueue.Dequeue(fbMessage:=fbMessage) THEN
IF fbMessage.CompareTopic(sTopic:='machine/on') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Machine.bOnPB := STRING_TO_BOOL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='machine/off') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Machine.bOffPB := STRING_TO_BOOL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/position') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Postion := STRING_TO_LREAL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/velocity') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Velocity := STRING_TO_LREAL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/acceleration') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Acceleration := STRING_TO_LREAL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/deceleration') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Deceleration := STRING_TO_LREAL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/execute') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Execute := STRING_TO_LREAL(sPayloadRcv);
// same for motion2 and motion3
END_IF
END_IF
END_IF
我的主题是像“motion1/position”、“motion1/acceleration”、“motion2/acceleration”等(我希望你明白)。所以我已经能够通过订阅“motion1/#”来订阅所有的motion1主题。因此,我尝试使用 fb.Message.CompareTopic(sTopic:='motion1/#') 来查找属于 motion1 的主题,而不是识别主题“motion1/somethingsomething”的 if 语句。但是 fb.Message.CompareTopic(sTopic:='motion1/#') 无法识别 motion1 主题。
IF fbMessageQueue.nQueuedMessages > 0 THEN
IF fbMessageQueue.Dequeue(fbMessage:=fbMessage) THEN
IF fbMessage.CompareTopic(sTopic:='machine/on') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Machine.bOnPB := STRING_TO_BOOL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='machine/off') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Machine.bOffPB := STRING_TO_BOOL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/#') THEN
IF fbMessage.CompareTopic(sTopic:='motion1/position') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Postion := STRING_TO_LREAL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/velocity') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Velocity := STRING_TO_LREAL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/acceleration') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Acceleration := STRING_TO_LREAL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/deceleration') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Deceleration := STRING_TO_LREAL(sPayloadRcv);
ELSIF fbMessage.CompareTopic(sTopic:='motion1/execute') THEN
fbMessage.GetPayload(pPayload:=ADR(sPayloadRcv), nPayloadSize:=SIZEOF(sPayloadRcv), bSetNullTermination:=TRUE);
Motion.nMotion1Execute := STRING_TO_LREAL(sPayloadRcv);
END_IF
// same for motion2 and motion3
END_IF
END_IF
END_IF
所以我展示的第一个代码确实从 MQTT 读取了我需要的所有消息,这真的很好。但是,应该有一种更有效的方法来做到这一点。我尝试了第二个代码中显示的方法,但是没有用。