【问题标题】:AWS iot with esp32 receives messages from some topics but not others?带有 esp32 的 AWS iot 接收来自某些主题但不接收其他主题的消息?
【发布时间】:2020-04-23 01:39:26
【问题描述】:

我正在使用this aws-iot library for esp32,但我无法接收来自某个主题的消息。

我的代码:

if (device.connect(HOST_ADDRESS, const_cast<char*>(client_id.c_str())) == 0) {
    Serial.println("Connected To AWS");
    delay(1000);

    char getAcceptedTopic[60];
    strcpy(getAcceptedTopic, "Lamps/"); //these ones need to be strcpy to get it started
    strcat(getAcceptedTopic, const_cast<char*>(myLampCred.username.c_str()));
    strcat(getAcceptedTopic, "/rga");

    Serial.print("\ngetAcceptedTopic: ");
    Serial.print(getAcceptedTopic);


    char republishedShadowTopic[60];
    strcpy(republishedShadowTopic, "Lamp/");
    strcat(republishedShadowTopic, const_cast<char*>(myLampCred.username.c_str()));
    strcat(republishedShadowTopic, "/rs");



    if (0==device.subscribe(getAcceptedTopic, mySubCallBackHandler)) {
    //if (0==device.subscribe("Lamps/SamHang/rs", mySubCallBackHandler)) { //try just doing it with the string? 
    Serial.print("Subscribe Successful");
    } else {
    Serial.println("Subscribe Failed, Check The Thing Name and Certificates");
    while(1);
    } 

    if (0==device.subscribe("testchannel", mySubCallBackHandler)) {
    Serial.println("Subscribe Successful");
    } else {
    Serial.println("Subscribe Failed, Check The Thing Name and Certificates");
    while(1);
    } 
    //will need to add in effects/channel topic at some point, but since none of the effects code is set up yet anyways, theres no point in adding a topic now

    Serial.println(republishedShadowTopic);
    if (0 == device.subscribe(republishedShadowTopic, mySubCallBackHandler)){
        Serial.println("Subscribe Successful");
    } else {
        Serial.println("Subscribe Failed, Check The THing Name and Certificates");
        while(1);
    }

    delay(500);
    //send get request
    gettingShadow = true;
    std::string shadowGetTopic = "$aws/things/" + myLampCred.username + "Lamp/shadow/get";
    publishFunc(shadowGetTopic.c_str(), "");
} else {
    //could add error for this but unless the host address changes and EVERYTHING breaks or wifi isn't connected, then there shouldn't be a problem
    Serial.println("AWS connection failed, check the HOST address");
    while(1);
}

我订阅了三个主题,testchannel、Lamps/user/rga(在变量 getAcceptedTopic 中)和 Lamp/user/rs(在变量 republishedShadowTopic 中)。

在这些主题中,用户可以根据代码上传到的设备进行更改,并使用 myLampCred.username(返回 std::string)检索用户名。所以如果myLampCred.username = actualUsername,那么它应该订阅的getAccepted主题名称是“Lamps/actualUsername/rga”

我始终能够接收关于我的 getAccepted 主题和我的 testchannel 主题的消息,但没有接收关于 republishedShadow 主题的消息。如果我用“Lamp/actualUsername/rs”替换 republishedShadowTopic 变量,那么它可以正常工作并接收应有的消息。我认为问题在于我如何声明/构建变量,但我以相同的方式制作 getAccepted 主题变量并且那个工作正常?

我还通过每个主题发送了不同长度的消息,并且每个消息相对于它的主题得到相同的结果,所以我认为它与消息的内容无关。 我还检查了配置文件,我认为不会有任何限制? 我很确定任何问题都在我共享的代码段中,因为收到的任何消息都会在它到达时宣布。

我目前的理论是某处存在数据类型问题?但是 device.subscribe() 方法要求一个 char*,据我所知,这就是我要给它的(我仍然不是 100% 了解所有 char[] vs char* 和 const,我明白what 每个都是,但不是我想如何使用它们)。我尝试了各种形式的字符和 std::string 转换,但除非基于字符串文字,否则似乎都不起作用。

我对此感到非常困惑,任何帮助将不胜感激,谢谢! :D

【问题讨论】:

    标签: c++ c iot aws-iot esp32


    【解决方案1】:

    创建republishedShadowTopic 的代码看起来不错。这段代码创建的字符串应该和字符串文字"Lamp/actualUsername/rs"一样,看看here

    我不是 Arduino 专家,但据我所知,字符串文字可能存储在只读存储器中(如果是 Arduino,我猜是闪存)。

    尝试修改字符串文字结果是未定义的行为:它们可能存储在只读存储中(例如 .rodata)或与其他字符串文字组合。

    当您使用字符串文字时它起作用的原因可能是它的静态存储持续时间。

    字符串字面量具有静态存储持续时间,因此在程序的整个生命周期内都存在于内存中。

    另一方面,您的数组有一个自动存储期限,这意味着它可能在退出当前范围后无效。

    当您查看here 时,您会看到您的字符串地址已被转发并存储在right here

    在这个 if 语句中退出作用域后:

    if (device.connect(HOST_ADDRESS, const_cast&lt;char*&gt;(client_id.c_str())) == 0)

    你不能再依赖这个指针了。我假设您在退出该 if 语句后会收到一条消息。

    你可以很容易地检验我的假设。只需将此数组设为静态或全局并检查它是否有效。你应该对第一个数组做同样的事情,因为你可能很幸运它工作了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-19
      • 2019-04-24
      • 2011-12-12
      • 2018-05-05
      • 1970-01-01
      • 2015-06-26
      • 2021-12-10
      • 1970-01-01
      相关资源
      最近更新 更多