Programação de um cliente MQTT em C (Paho MQTT) no Linux Embarcado

Apesar de ser uma linguagem de programação com uma significativa idade, a linguagem C está constantemente evoluindo e seu uso continua muito relevante no desenvolvimento de software embarcado, como mostrado no Ranking das Linguagens de Programação mais usadas em 2018 (IEEE Spectrum). O próprio Kernel Linux (e, também, outros softwares importantes para uma distribuição Linux) é desenvolvido majoritariamente em linguagem C, reforçando portanto a importância desta linguagem de programação. Além disso, os compiladores C estão cada vez melhores (sobretudo os destinados às plataformas e arquiteturas embarcadas), garantindo que os softwares compilados tenham desempenho excelente. Logo, faz pleno sentido desenvolver software embarcado em linguagem C.

Nesta linha de raciocínio, este artigo mostra como desenvolver em C um cliente MQTT utilizando a biblioteca open-source Paho MQTT, abrindo portanto para o leitor a possibilidade de integração com as plataformas de Internet das Coisas a partir de programas escritos em C no Linux Embarcado.

Hardware utilizado

Como o título deste artigo sugere, este artigo pode ser aplicado em diversas distribuições Linux para sistemas embarcados. Porém, para poder exemplificar, mostrar e validar todo o processo de compilação e instalação da biblioteca e a programação de um cliente MQTT, foi escolhido como hardware-alvo a placa de desenvolvimento Beaglebone Black. O motivo da escolha foi devido a esta ser uma das placas de desenvolvimento mais empregadas em projetos em nível mundial, tanto como hobby quanto no âmbito de projetos comerciais. A figura 1 mostra a Beaglebone Black (Rev. C).

Beaglebone Black (Rev. C).
Figura 1 – Beaglebone Black (Rev. C).

O protocolo MQTT – Linhas gerais

O protocolo MQTT (Message Queue Telemetry Transport) é um protocolo criado no final dos anos 90 pela IBM, destinado à comunicação M2M (Machine-to-Machine). Apesar de não ser algo novo, possui larga utilização atualmente devido a ser um protocolo classificado como lightweight (utiliza poucos recursos computacionais dos seus clientes e utiliza pouco tráfego de dados para funcionar). Desta forma, configura-se como um dos mais adequados protocolos para projetos IoT em clientes embarcados, onde poder computacional, consumo energético, memória, armazenamento e quantidade de dados a serem trafegados são sempre diminutos.

Em linhas gerais, o MQTT utiliza um servidor (chamado broker), o qual faz a mediação / direcionamento de comunicação entre N clientes, os quais podem enviar (publish) e/ou receber (subscribe) dados. Ou seja, todos os dados trafegam obrigatoriamente pelo broker, e este é o responsável por receber as mensagens dos remetentes e enviá-las aos destinatários. Tal controle de remetentes e destinatários é feito através de tópicos MQTT, os quais servem para os clientes informarem aos brokers o que desejam receber e para quem desejam enviar dados. Observe a figura 2.

Diagrama de comunicação do MQTT.
Figura 2 – Diagrama de comunicação do MQTT (fonte: https://embarcados.com.br/mqtt-protocolos-para-iot/).

Ainda, o broker pode estar em uma rede local ou em uma rede de alcance maior (como em um servidor com acesso à Internet), permitindo, portanto, a comunicação entre clientes a nível mundial.

Para mais detalhes sobre o MQTT, leia o artigo MQTT – Protocolos para IoT, do autor Marcelo Barros.

A biblioteca Paho MQTT

A biblioteca Paho MQTT trata-se de uma biblioteca open-source para desenvolvimento de clientes MQTT (e, mais recentemente, desenvolvimento de clientes MQTT-SN também). Esta biblioteca é um projeto do iot.eclipse.org e possui como principais características ser leve, suportar comunicação MQTT segura (TLS/SSL) e por possuir versões para várias linguagens de programação dominantes, tais como Java, C e Python. Além disso, computacionalmente falando, trata-se de uma biblioteca muito leve (tanto em consumo de memória, armazenamento, quanto processamento requerido).

Logo oficial da biblioteca Paho MQTT.
Figura 3 – Logo oficial da biblioteca Paho MQTT.

Com o boom do IoT mundo afora, esta biblioteca é uma ótima escolha àqueles que desejam acrescentar em seus projetos conectividade com as plataformas IoT (Amazon AWS, Microsoft Azure, etc.), uma vez que a grande maioria delas permite o envio e recepção de dados por MQTT.

A documentação da biblioteca para a linguagem C pode ser lida neste link.

Procedimento de compilação e instalação – Paho MQTT C client

Antes de partir para a programação do cliente MQTT e C, é necessária a compilação e instalação da biblioteca Paho MQTT (para linguagem C). Para isso, siga o procedimento abaixo:

Atualização dos pacotes já existentes

Como primeiro passo, é altamente recomendável atualizar os pacotes instalados. Isso evita possíveis incompatibilidades ou erros nas instalações de pacotes deste procedimento. Para isso, execute os comandos a seguir:

sudo apt-get update
sudo apt-get upgrade

Instalação dos pacotes de desenvolvimento do OpenSSL

A bibloteca Paho MQTT da suporte à comunicação segura com MQTT (utilizando TLS/SSL), logo os pacotes de desenvolvimento do OpenSSL são necessários para sua compilação e funcionamento. Para instalar os pacotes de desenvolvimento do OpenSSL, execute os comandos a seguir:

sudo apt-get install libssl-dev

Instalação do Doxygen

O Doxygen também precisa ser instalado. Ele fará com que toda a documentação da biblioteca possa ser gerada, algo muito importante para quem quiser desenvolver aplicações com esta biblioteca (sobretudo para trabalhos mais sérios, já que a documentação é bem completa). Para fazer esta instalação, execute o comando a seguir:

sudo apt-get install doxygen

Obtenção do repositório da biblioteca

A biblioteca Paho MQTT, conforme dito anteriormente neste mesmo artigo, é open-source. Desta forma, para utilizá-la, precisaremos baixar seu código-fonte e, posteriormente, fazer a compilação do mesmo. Para isso, execute o comando abaixo:

git clone https://github.com/eclipse/paho.mqtt.c.git

Compilação e instalação

Agora é a etapa de compilação e instalação da biblioteca. Para isso, vá ao diretório do repositório (o qual foi baixado no item anterior):

cd paho.mqtt.c

Em seguida, faça a compilação da biblioteca e de sua documentação com os comandos abaixo:

make
make html

Uma vez compilada, a biblioteca pode ser instalada. Para isso, utilize o comando abaixo:

sudo make install

A partir deste ponto, a biblioteca Paho MQTT (C client) está pronta para uso.

Programando um cliente MQTT simples em C

É chegada a hora de desenvolver um cliente MQTT em C, utilizando a biblioteca Paho MQTT. Tal cliente terá como finalidade fazer echo da mensagem MQTT recebida de um tópico em outro tópico. Para isso, considere o código-fonte a seguir. É fortemente recomendada a leitura de seus comentários para maior compreensão do mesmo.

/*
* Includes
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <MQTTClient.h>

/*
* Defines
*/
/* Caso desejar utilizar outro broker MQTT, substitua o endereco abaixo */
#define MQTT_ADDRESS   "tcp://iot.eclipse.org"
/* Substitua este por um ID unico em sua aplicacao */
#define CLIENTID       "MQTTCClientID"  

/* Substitua aqui os topicos de publish e subscribe por topicos exclusivos de sua aplicacao */
#define MQTT_PUBLISH_TOPIC     "MQTTCClientPubTopic"
#define MQTT_SUBSCRIBE_TOPIC   "MQTTCClientSubTopic"

/*
*  Variaveis globais
*/
MQTTClient client;

/*
* Prototipos de funcao
*/
void publish(MQTTClient client, char* topic, char* payload);
int on_message(void *context, char *topicName, int topicLen, MQTTClient_message *message);

/*
* Implementacoes
*/

/* Funcao: publicacao de mensagens MQTT
 * Parametros: cleinte MQTT, topico MQTT and payload
 * Retorno: nenhum
*/
void publish(MQTTClient client, char* topic, char* payload) {
    MQTTClient_message pubmsg = MQTTClient_message_initializer;

    pubmsg.payload = payload;
    pubmsg.payloadlen = strlen(pubmsg.payload);
    pubmsg.qos = 2;
    pubmsg.retained = 0;
    MQTTClient_deliveryToken token;
    MQTTClient_publishMessage(client, topic, &pubmsg, &token);
    MQTTClient_waitForCompletion(client, token, 1000L);
}

/* Funcao: callback de mensagens MQTT recebidas e echo para o broker
 * Parametros: contexto, ponteiro para nome do topico da mensagem recebida, tamanho do nome do topico e mensagem recebida
 * Retorno : 1: sucesso (fixo / nao ha checagem de erro neste exemplo)
*/
int on_message(void *context, char *topicName, int topicLen, MQTTClient_message *message) {
    char* payload = message->payload;

    /* Mostra a mensagem recebida */
    printf("Mensagem recebida! \n\rTopico: %s Mensagem: %s\n", topicName, payload);

    /* Faz echo da mensagem recebida */
    publish(client, MQTT_PUBLISH_TOPIC, payload);

    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

int main(int argc, char *argv[])
{
   int rc;
   MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;

   /* Inicializacao do MQTT (conexao & subscribe) */
   MQTTClient_create(&client, MQTT_ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
   MQTTClient_setCallbacks(client, NULL, NULL, on_message, NULL);

   rc = MQTTClient_connect(client, &conn_opts);

   if (rc != MQTTCLIENT_SUCCESS)
   {
       printf("\n\rFalha na conexao ao broker MQTT. Erro: %d\n", rc);
       exit(-1);
   }

   MQTTClient_subscribe(client, MQTT_SUBSCRIBE_TOPIC, 0);

   while(1)
   {
       /*
        * o exemplo opera por "interrupcao" no callback de recepcao de 
        * mensagens MQTT. Portanto, neste laco principal eh preciso fazer
        * nada.
        */
   }
}

Para compilar, deve ser considerada a biblioteca Paho MQTT. Assumindo que o código-fonte seja salvo como main.c e que o binário final irá se chamar mqtt_exemplo, o comando de compilação é o seguinte:

gcc main.c -o mqtt_exemplo -lpaho-mqtt3c -Wall

E, para executar, utilize o seguinte comando:

./mqtt_exemplo

Pronto! Agora basta testar com um cliente MQTT de sua preferência. A figura 4 mostra o teste do programa em ação, utilizando o cliente MQTT MQTT Lens e o terminal com o programa rodando na Beaglebone Black.

Teste do programa.
Figura 4 – Teste do programa.

Saiba mais

MQTT-SN: MQTT para rede de sensores

Exibindo valores de temperatura e umidade no app MQTT Dash com o sensor DHT11

Raspberry Pi 3 na IoT – MQTT e Python

Referências

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
10 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Carlos Eduardo Olivieri
Carlos Eduardo Olivieri
03/04/2020 00:29

Muito Interessante. Valeu. 😉

Lucas
Lucas
02/12/2018 17:49

Gostaria de fazer um projeto onde uso um broker local, no codigo diz para modificar #define MQTT_ADDRESS , minha pergunta é como devo modifica-lo

Emanuel Vidal
Emanuel Vidal
13/10/2018 01:36

Ola, tenho uma placa com reles que conectada a rede cabeada aciona reles quando recebe o comando pelo browser tipo 192.168.1/1/low e gostaria q o cliente mqtt q vc ensinou em vez de fazer o echo chamasse este ip para a placa acionar o rele? mas sem browser ou abrir janela alguma, como faço ?? parece simples mas sou iniciante e ainda estou engatinhando, agradeço se detalhar.

Emanuel Vidal
Emanuel Vidal
13/10/2018 01:23

Olá, sou iniciante no mundo IOT, e tenho visto vários posts seus, devo parabeniza-lo e pedir sua ajuda, possuo uma placa que aciona os seus reles por comandos de rede tipo 192.168.1.10/1, e gostaria de usar um Raspberry com servidor mosquito para aciona-los, para isso teria o servidor mosquito rodando no rasp, e tbm o cliente sub q deveria escutar e mandar o comando chamando o ip 192.168.1.10/1, gostaria de um exemplo de como chamar este ip sem abrir nenhuma janela, para q a placa acione o rele? ai poderia usar o código do seu post acima, mas em vez… Leia mais »

Jordana_Carvalho
Membro
15/09/2018 17:40

Pedro, cumprimentos pelo artigo. Você usou qual imagem no seu Beaglebone Black? Pode indicar o link por favor? Você salvou na memória da própria placa ou foi via cartão SD? Qual a vantagem dessa rede sobre a rede CAN? Obrigada!

Jordana_Carvalho
Reply to  Pedro Bertoleti
27/09/2018 19:50

Obrigada pela resposta, Bruno! 🙂

fabitencourt63
fabitencourt63
10/09/2018 13:06

Legal Pedro, segui todas as etapas e funcionou. Agora estou curioso em saber o que eu posso fazer com isso. Sera que eu posso criar um broker MQTT local ? Usando um esp8266 como propõe o Fabio Souza em seus artigos ?

Home » Beaglebone Black » Programação de um cliente MQTT em C (Paho MQTT) no Linux Embarcado

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: