MQTT Publish from Simulink model to mosquitto broker

16 visualizaciones (últimos 30 días)
Joyeeta Chatterjee
Joyeeta Chatterjee el 27 de Oct. de 2020
Respondida: Stefan Fischer el 6 de Ag. de 2024
I want to publish MQTT messages from my model in Simulink to the mosquitto broker. So far I have been able to publish messages successfully from MATLAB script to the mosquitto broker using the MQTT in MATLAB toolbox. I would like to do the same through my Simulink model.
I understand that there is a MQTT Publish block in Simulink for Raspberry Pi that publishes message to a ThingSpeak broker. Is there a way to use this block for any other Simulink model (that does not use Raspberry Pi) and also for any other broker like mosquitto in my case?
If the MQTT Publish block cannot be used for this purpose, should I use a MATLAB function block and write the MATLAB code for MQTT in a .m file and include it in Simulink?
Is there any other way to implement MQTT Publish in Simulink models (without Raspberry Pi and for brokers other than ThingSpeak)?

Respuestas (2)

Reeno Joseph
Reeno Joseph el 12 de Nov. de 2020
Hello Joyeeta ,
The MQTT blocks in the Raspberry Pi Simulink support package can work with other brokers as well.
You can configure the broker details within the model config setting.
Please refer to the image below and the doc for the same.
  2 comentarios
Joyeeta Chatterjee
Joyeeta Chatterjee el 12 de Nov. de 2020
Thank you for your reply. I will try this in my model.
For now, I used the MQTT in MATLAB toolbox, wrote a MATLAB code for MQTT Publish and used it in the Simulink model in a MATLAB function block.
dhanavaradhan M
dhanavaradhan M el 16 de Feb. de 2021
can you say how u did that ( " I used the MQTT in MATLAB toolbox, wrote a MATLAB code for MQTT Publish and used it in the Simulink model in a MATLAB function block " )

Iniciar sesión para comentar.


Stefan Fischer
Stefan Fischer el 6 de Ag. de 2024
sorry for the poor english and for the poor explanation. It is my first time answering a Question in it's whole.
I can answer the question in its whole after speaking to the Mathworks support for over 4 hours an E-mailing back and forth over days. I try to keep the solution as simple as possible. Hopefully as many people as possible will find it usefull.
First Things first, i am using version 23.2.0.2459199 (R2023b) Update 5 of Matlab.
The following informations are informations i got during my communication with the Mathworks support in August 2024.
Changes are possible since that time:
  1. The MQTT Blocks that states Hardware like Raspberry Pi or Jetson only work with additionally hardware. They are thought that the simulation runs on that hardware. So this is no option for complex models in Simulink. That makes the answer of Reeno Joseph, although not incorrect, mute.
  2. If your PC with the Simulink model should publish and subscribe directly to topics, and you want to use the information from the messages in Simulink this is the minimal workaround to achieve it:
Use a Matlab Function Block in Simulink with the following Code:
function y = mqttRead()
% Defines external Functions, so Code Generation will not throw errors.
% Without these lines the Simulink Model will not compile.
coder.extrinsic("mqttRead_commands");
coder.extrinsic("strings");
%Initialise the String with enough characters so every MQTT Message
%will fit into it. Dynamic Size adjustments are not supported.
y = "InitStringaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
%Call the Function defined in a Matlab Script File. It has to lay in
%the working directory of your simulink model.
y = mqttRead_commands();
end
Connect the Output "y" with a display Block.
Use a Matlab Script file in matlab with the following Code:
function newMessage = mqttRead_commands()
% Define persistent variables
% Persistend, because they need to stay valid between function calls
persistent mqttClient
persistent outMessage
% Initialize MQTT client and subscribe to a topic
% Warning: There still is a debricated Function called mqtt() that can
% be used for Generating a MQTT Client. Use the function mqttclient(),
% it is the new still supported version.
if isempty(mqttClient) % To execute the code only once
mqttClient = mqttclient('tcp://192.168.17.200', Port=1883); %tcp:// because the client and broker are connected via ethernet
mySub = subscribe(mqttClient, "rf/m1/o1"); % write the topic string directly into the parameter. No Variables.
outMessage = "NoOutput";
end
% Empfangen der MQTT Nachricht
% The "Topic=" is on purpose. The Syntax between read and write commands is differently.
% This is also confirmed by the Mathworks Support.
% Keep the syntax exactly the same.
mqttMsg = read(mqttClient, Topic="rf/m1/o1");
% Sending of a MQTT Message to a Dead Topic to keep Client alive.
% Otherwise the Client will shutdown after 50-60 seconds.
% Keep the syntax exactly the same.
mqttMsg_writeTest = "DeadMessageString";
write(mqttClient, "deadTopic/keepClientAlive", mqttMsg_writeTest);
if isempty(mqttMsg)
% Case for if no message is received in that topic.
disp("mqttMsg is empty");
else
% Converts the mqtt Message JSON String into a struct.
% "*.Data(end)" attachment chooses always the last Data of the last received message.
mqttMsg_struct = jsondecode(mqttMsg.Data(end));
end
% Transfer received Message JSON String to Output Parameter
% "newMessage" if a MQTT Message was received.
if isempty(mqttMsg)
newMessage = outMessage;
else
newMessage = mqttMsg.Data(end);
outMessage = newMessage;
end
end
This is the mininmal example of an mqtt client implementation for a simulink model that can receive messages during simulation.
For the solver we use the following configuration:
Type = Fixed-step
Solver = ode14x (Extrapolation)
Fixed-step size = 0.004
We tested the solvers ode1be, ode14x, ode1, ode2, ode3, ode4, ode5, ode8, discrete, auto with the StepSizes 1ms, 3ms, 4ms, 5ms, 6ms, 10ms.
In our Application messages get sent every 10ms, so 4ms was found empirically as sweet spot.
The above solution for receiving messages was found together with the Matworks Support over a period of days and multiple ideas for solution and practical experiments. It contains a lot of internal support knowledge like the depricated mqtt Command, which for example does not throw an error if the old one is used. Not even a warning. That means a lot of the syntax has to stay exactly how it is, otherwise Matlab or simulink will throw an arrow out of no logically reason. The support and me did also not find an explanation for a lot of these behaviours, but they confirmed to me that they will work on an update to implement that functionallity more easily (maybe as Block?) and they are thinking about adding an example to the simulink documentation for this use case.
I highly recommend studying the above solution for everybody who wants to send or receive mqtt messages inside a simulink model.
We still have issues in our application with loosing mqtt messages. We still search why that is. In a stand alone matlab script application there are no lost messages, so the suspicion lays on Simulink itself in combination of the message frequency of 10ms and faster in our application. I am in contact with the support about that.
I hope this helps other people to implement their MQTT Communication into their model.
Yours sincerely,
Stefan Fischer

Comunidades de usuarios

Más respuestas en  ThingSpeak Community

Categorías

Más información sobre Run on Target Hardware en Help Center y File Exchange.

Productos


Versión

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by