STM32CubeIDE 上的 MQTT(硬件 STM32F756ZGT6 nucleo-144)

问题描述 投票:0回答:1

我对 stm32cubeIDE 非常陌生,正在尝试与我的 stm 创建 mqtt 连接,首先用我的计算机进行尝试,然后将其与树莓派一起使用。我已经在 Raspberry Pi 上运行了一个状态机,但没有足够的端口用于我的应用程序,这就是我需要迁移到 stm32 的原因。

我已经设置了以太网,并且可以使用 LwIP(v2.1.2) ping 为我的 stm 声明的静态 IP 地址。我还使用 USB 端口进行调试,并将输出 printf 重定向到该端口。我按照 this 和一些 lwip doc 并成功创建了一个 mqtt 客户端,连接到代理(对于我的测试,我将使用 mosquitto 代理:“test.mosquitto.org”->91.121.93.94)并发送一条消息,至少是日志中所说的内容。问题是我看不到消息。

我的方法是:我连接到命令行并运行它

mosquitto_sub -h 91.121.93.94 -t pub_topic

当我尝试从另一个命令行发布时,我在第一个命令行上收到消息,但由于某种原因,它无法从我的 stm32 接收消息。 另外,当我尝试发送多条消息时,它停在 4 处,我得到

Publish err: -1

这是一个内存不足错误,即使我修改 MQTT_REQ_MAX_IN_FLIGHT (例如从 4 到 10),我也发现这一点,所以我猜我的消息没有真正发送,因为它应该清空缓冲区? 而且我很恼火的是 mqtt_publish() 和 mqtt_output_send() 都不能真正帮助检查消息是否真的发送,所以我不知道现在该怎么办。

这是我的参考代码,不知道我是否也应该发送我的配置

创建我的 mqtt 客户端并连接到代理

void mqtt_new(mqtt_client_t *client){
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, 0);
    HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, 0);
    HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, 1);
    HAL_Delay(2500);//let time to open app to see output from printf redirected to usb
    HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, 0);
    printf("mqtt_new client\n");
    client = mqtt_client_new();
    if (NULL != client){
        mqtt_connect(client);
    }
    else{
        printf("impossible to create a mqtt client\n");
    }
}

//1.2: Establish Connection with server

void mqtt_connect(mqtt_client_t *client){
  ip_addr_t broker_ip;
  struct mqtt_connect_client_info_t ci;
  err_t err;
  memset(&ci, 0, sizeof(ci));
  ci.client_id = "lwip_test";
  IP4_ADDR(&broker_ip, 91,121,93,94);//ipaddr_aton("91.121.93.94",&broker_ip);
  err = mqtt_client_connect(client, &broker_ip, MQTT_PORT, mqtt_connection_cb, 0, &ci);
  while (err != ERR_OK)
  {
      printf("mqtt_connect err : %d ; retry\n",err);
      err = mqtt_client_connect(client, &broker_ip, MQTT_PORT, mqtt_connection_cb, 0, &ci);
      HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
      HAL_Delay(500);
  }
  if(ERR_OK == err){
      printf("mqtt_connect: connected to broker\n");
      HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, SET);
      for(int i=0;i<15;i++){
          example_publish(client, 0);
      }
      //example_publish(client, 0);
  }
}

连接订阅的回调函数

static void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
    //HAL_Delay(300);
    err_t err;
    if(status == MQTT_CONNECT_ACCEPTED) {
        /* Setup callback for incoming publish requests */
        mqtt_set_inpub_callback(client, mqtt_incoming_publish_cb, mqtt_incoming_data_cb, arg);

        /* Subscribe to a topic named "subtopic" with QoS level 1, call mqtt_sub_request_cb with result */
        err = mqtt_subscribe(client, "cb_subtopic", 1, mqtt_sub_request_cb, arg);

        if(err != ERR_OK) {
            printf("mqtt_subscribe return: %d\n", err);
        }
        else{
            printf("mqtt_subscribe in cb\n");
        }
    }
    else {
          printf("mqtt_connection_cb: Disconnected, reason: %d\n", status);//status = 256 = MQTT_CONNECT_DISCONNECTED
          HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
          /* Its more nice to be connected, so try to reconnect */
          mqtt_connect(client);
    }
}

这与之前有关 mqtt 的链接保持不变

static int inpub_id;
static void mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
    printf("Incoming publish at topic %s with total length %u\n", topic, (unsigned int)tot_len);

    /* Decode topic string into a user defined reference */
    if(strcmp(topic, "print_payload") == 0) {
        inpub_id = 0;
    } else if(topic[0] == 'A') {
        /* All topics starting with 'A' might be handled at the same way */
        inpub_id = 1;
    } else {
        /* For all other topics */
        inpub_id = 2;
    }
}

static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
    {
    printf("Incoming publish payload with length %d, flags %u\n", len, (unsigned int)flags);

    if(flags & MQTT_DATA_FLAG_LAST) {
        /* Last fragment of payload received (or whole part if payload fits receive buffer
        See MQTT_VAR_HEADER_BUFFER_LEN)  */
        /* Call function or do action depending on reference, in this case inpub_id */
        if(inpub_id == 0) {
            /* Don't trust the publisher, check zero termination */
            if(data[len-1] == 0) {
                printf("mqtt_incoming_data_cb: %s\n", (const char *)data);
            }
        } else if(inpub_id == 1) {
            /* Call an 'A' function... */
        } else {
            printf("mqtt_incoming_data_cb: Ignoring payload...\n");
        }
     } else {
        /* Handle fragmented payload, store in buffer, write to file or whatever */
     }
}

然后是发布部分

void example_publish(mqtt_client_t *client, void *arg)
{
      const char *pub_payload= "this is the message";
      err_t err;
      u8_t qos = 2; /* 0 1 or 2, see MQTT specification */
      u8_t retain = 0;
      err = mqtt_publish(client, "pub_topic", pub_payload, strlen(pub_payload), qos, retain, mqtt_pub_request_cb, arg);
      if(err != ERR_OK) {
          printf("Publish err: %d\n", err);
      }
      else{
            printf("Published\n");
            for(int i=0;i<2;i++){
                HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, 1);
                HAL_Delay(100);
                HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, 0);
                HAL_Delay(100);
            }
      }
}
/* Called when publish is complete either with success or failure */
static void mqtt_pub_request_cb(void *arg, err_t result)
{
      if(result != ERR_OK) {
          printf("Publish result: %d\n", result);
      }
}

如果我做错了或者您知道我应该更改代码中的哪些内容,请告诉我。感谢您提供的所有帮助。

mqtt ethernet stm32cubeide lwip stm32f7
1个回答
0
投票

我解决了这个问题,卡上的所有内容都正常,我只是在公共代理 test.mosquitto.org 上没有正确的权限,我尝试在我的 Rpi 上配置代理,现在我可以从 stm 接收消息在命令行上。现在我将尝试将信息从我的计算机发送到 stm,我会及时通知您。

© www.soinside.com 2019 - 2024. All rights reserved.