首页 > 解决方案 > setup() 中的 Arduino 和对象实例化

问题描述

我对 C 和 Arduino 很陌生,但在高级语言方面经验丰富。我试图在文档中找到解决方案,但找不到足够复杂的东西来理解 arduino 的基础

所以,这里是我试图理解的例子: https ://learn.adafruit.com/mqtt-adafruit-io-and-you/arduino-plus-library-setup

该示例称为 mqtt_esp8266

相关部分:

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

#define AIO_USERNAME    "your AIO username"

WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");

void setup() {
...
}

void loop() {
...
photocell.publish(something);
}

我的问题:

我想要实现的是使用运行时信息来构建主题。简化,我想发布到 AIO_USERNAME "/feeds" + WiFi.macAddress() + "/photocell" 但没有任何财富。特别是,我不知道如何在全局范围内定义 Adafruit_MQTT_Publish 以便我可以在 setup() 和 loop() 函数中使用它,但在 setup 函数中实例化以便我可以使用 WiFi.macAddress()输出以作为提要名称的前缀

标签: c++arduinomqtt

解决方案


WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");

以上三行实例化了全局范围的新变量。该变量client使用类的默认构造函数进行实例化WiFiClientmqtt使用一个构造函数实例化,该构造函数接受一个指向客户端的指针、一些服务器常量等。

查看以下代码后Adafruit_MQTT_Publishhttps ://github.com/adafruit/Adafruit_MQTT_Library/blob/master/Adafruit_MQTT.cpp 我看到它只是一个方便的包装类,它包含一个指向Adafruit_MQTT对象的指针,qos(默认为0)和topic. 它实现了几种不同publish的方法,这些方法因接收到的参数类型而异。例如,这是以下方法uint32_t

bool Adafruit_MQTT_Publish::publish(uint32_t i) {
  char payload[11];
  ultoa(i, payload, 10);
  return mqtt->publish(topic, payload, qos);
}

您可以简单地自己实现相同的功能:

WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
char whatever[] = "What ever";

void loop()
{
  char topic[64]; //Note, if the input can be longer than 64 characters long, change to topic[128] for example...
  strcpy(topic, AIO_USERNAME);
  strcat(topic, whatever);
  char something[] = "asdf";
  mqtt.publish(topic,something,0);
}

至于你的语法问题

AIO_USERNAME "/feeds/photocell"

预处理器会将其变成:

"your AIO username" "/feeds/photocell"

然后编译器变成一个长字符串:

"your AIO username/feeds/photocell"

这种连接仅适用于字符串文字(例如"string")。要在运行时连接内容,您必须使用库函数,例如strcatstrcpy。请参考string.hhttps ://en.cppreference.com/w/c/string/byte


推荐阅读