ESP8266订阅AWS IOT主题 [英] ESP8266 Subscribe to AWS IOT topic

查看:144
本文介绍了ESP8266订阅AWS IOT主题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个lambda函数,该函数将访问AWS事物并发布MQTT消息,我想在ESP8266上也获得与该事物相连的已发布消息,并控制打开/关闭ESP8266上的LED指示灯.到目前为止,我已经完全将private.der,cert.der和ca.der上传到ESP8266,但它无法订阅AWS IOT,请在正确的提示中指出我,然后分享.

Hi I need to create a lambda function which will access the AWS thing and publish MQTT message, I'd like to get the published message on the ESP8266 which was connected to the thing as well, and controlled turn on/off the LED on ESP8266. So far I have uploaded the private.der, cert.der and ca.der to the ESP8266 absolutely, but it couldn't subscribed AWS IOT, please point me in the right tips then please share.

代码:

       #include <ESP8266WiFi.h>
       #include <PubSubClient.h>
       #include <NTPClient.h>
       #include <WiFiUdp.h>
       #include <ArduinoJson.h>
       #define OUT_TOPIC "$aws/things/devices/shadow/update"
       #define IN_TOPIC "$aws/things/devices/shadow/update/delta"
        const char* ssid = "sid";
        const char* password = "password";

        WiFiUDP ntpUDP;
        NTPClient timeClient(ntpUDP, "pool.ntp.org");

        const char* AWS_endpoint = "endpoint.amazonaws.com";//MQTT broker ip

        const char* json = "{\"state\":{\"reported\":{\"led\":\"off\"}}}";

        StaticJsonDocument<1024> doc;

        WiFiClientSecure espClient;
        PubSubClient mqttClient(espClient);//set MQTT port number to 8883 as per standard
        PubSubClient client(AWS_endpoint, 8883, espClient); 
        long lastMsg = 0;
        char msg[50];
        int value = 0;

        void setup_wifi() {

        delay(10);// We start by connecting to a WiFi network
        espClient.setBufferSizes(512, 512);
        Serial.println();
        Serial.print("Connecting to ");
        Serial.println(ssid);

        WiFi.begin(ssid, password);

        while (WiFi.status() != WL_CONNECTED) 
    {
        delay(500);
        Serial.print(".");
        }
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());

        timeClient.begin();
        while(!timeClient.update()){
        timeClient.forceUpdate();
        }

        espClient.setX509Time(timeClient.getEpochTime());

        int qos = 0;//Maximum size of data that can be communicated
        Serial.println(MQTT_MAX_PACKET_SIZE);
        if(mqttClient.subscribe(IN_TOPIC, qos)){
        Serial.println("Subscribed.");
        Serial.println("Success!!");
        }

        deserializeJson(doc, json);
        JsonObject obj = doc.as<JsonObject>();

        if(mqttClient.publish(OUT_TOPIC, json)){
        Serial.println("Published!!");
        }

        }

        void setup() {

        Serial.begin(115200);
        Serial.setDebugOutput(true);
        // initialize digital pin LED_BUILTIN as an output.
        pinMode(LED_BUILTIN, OUTPUT);
        setup_wifi();
        delay(1000);
        if (!SPIFFS.begin()) {
        Serial.println("Failed to mount file system");
        return;
        }

        Serial.print("Heap: "); Serial.println(ESP.getFreeHeap());

        //replace cert.crt eith your uploaded file name
        File cert = SPIFFS.open("/cert.der", "r"); 
        if (!cert) {
        Serial.println("Failed to open cert file");
        }
        else
        Serial.println("Success to open cert file");

        delay(1000);
        if (espClient.loadCertificate(cert))
        Serial.println("cert loaded");
        else
        Serial.println("cert not loaded");

        // Load private key file
        File private_key = SPIFFS.open("/private.der", "r");//replace private eith your uploaded file name
        if (!private_key) {
        Serial.println("Failed to open private cert file");
        }
        else
        Serial.println("Success to open private cert file");

        delay(1000);

        if (espClient.loadPrivateKey(private_key))
        Serial.println("private key loaded");
        else
        Serial.println("private key not loaded");
        // Load CA file
        File ca = SPIFFS.open("/ca.der", "r"); 
        //replace ca eith your uploaded file name
        if (!ca) {
        Serial.println("Failed to open ca ");
        }
        else
        Serial.println("Success to open ca");

        delay(1000);

        if(espClient.loadCACert(ca))
        Serial.println("ca loaded");
        else
        Serial.println("ca failed");
        Serial.print("Heap: "); 
        Serial.println(ESP.getFreeHeap());
        }

        void callback (char* topic, byte* payload, unsigned int length) {

        Serial.println("Received. topic=");
        Serial.println(topic);
        char subsc[length];
        for(int i=0; i<length; i++){
        subsc [i]=(char)payload[i];
        subsc [length]='\0';
        Serial.print(subsc);
        }
        Serial.print("\n");
        digitalWrite(LED_BUILTIN, HIGH);
        }

        void mqttLoop() {
        mqttClient.loop();
        delay(100);
        //digitalWrite(LED_pin, LOW);
        digitalWrite(LED_BUILTIN, LOW); 
        Serial.print(".");
        }
        void loop() {

推荐答案

您似乎正在使用 WiFiClientSecure 证书处理的较旧形式.我认为这可以正常工作,并且您能够建立SSL连接.

It looks like you're using the older forms of WiFiClientSecure certificate handling. I'll assume that's working OK and you're able to establish an SSL connection.

您的 IN_TOPIC 需要稍微更新为: $ aws/things/& lt;您的事物的名称& gt;/shadow/update/accepted (希望您知道& lt;您的事物的名称& gt; 是什么).您可以从AWS控制台上的事物阴影中获得此信息.

Your IN_TOPIC needs to be updated slightly to: $aws/things/&lt;name-of-your-thing&gt;/shadow/update/accepted (where hopefully you know what &lt;name-of-your-thing&gt; is). You can get this from the thing shadow on your AWS console.

类似地, AWS_endpoint 需要更新:它的格式应为& lt;随机材料特定于您< .iot.& lt; region& gt; .amazonaws.com .您还可以在与MQTT主题相同的地方找到它.

Similarly AWS_endpoint needs updating: it should be of the form &lt;random-stuff-specific-to-you&gt;.iot.&lt;region&gt;.amazonaws.com. You can also find it from the same place as the MQTT topics.

您只需要一个 PubSubClient 实例.我假设您删除 client 并保留 mqttClient .您需要像对客户端所做的那样更新实例以包括AWS终端节点和端口.

You only want one instance of PubSubClient. I'll assume you delete client and keep mqttClient. You'll need to update the instantiation to include the AWS endpoint and port as you have done for client.

在调用 mqttClient.subscribe(...)之前,您需要注册回调:

Before calling mqttClient.subscribe(...) you need to register the callback:

  mqttClient.setCallback(::callback);

然后连接到AWS:

  mqttClient.connect("some-unique-name");

最后,您需要编辑 PubSubClient.h (在Arduino/libraries/PubSubClient/src中查找)以更新MQTT_MAX_PACKET_SIZE.默认值为128,我发现AWS消息太小了.我已经把我的1024了:

Finally, you need to edit PubSubClient.h (look for it in Arduino/libraries/PubSubClient/src) to update MQTT_MAX_PACKET_SIZE. The default is 128 and I've found that too small with AWS's messages. I've made mine 1024:

  #define MQTT_MAX_PACKET_SIZE 1024

而且看起来足够.

一旦编译并运行,您将开始看到以您已订阅的主题调用的callback(...),您可以实现该函数以执行所需的任何操作.

Once that compiles and runs you'll start seeing callback(...) called with the topics you've subscribed to and you can implement the function to do whatever you need.

PubSubClient不会执行太多错误报告来帮助诊断正在发生的事情.我目前正在对其进行一些重构,包括更多的诊断信息,最终将发出拉取请求.在此之前,请告诉我您是否想要被黑的版本.

The PubSubClient doesn't do much error reporting to help diagnose what's going on. I'm currently refactoring it a bit and including more diagnostic information and will eventually issue a pull request. Let me know if you'd like my hacked version before I get that far.

这篇关于ESP8266订阅AWS IOT主题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆