ESP8266订阅AWS IOT主题

时间:2019-12-04 16:44:59

标签: mqtt iot esp8266

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

代码:

       #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() {

1 个答案:

答案 0 :(得分:0)

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

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

类似地,AWS_endpoint需要更新:它的格式应为&lt;random-stuff-specific-to-you&gt;.iot.&lt;region&gt;.amazonaws.com。您还可以在与MQTT主题相同的地方找到它。

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

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

  mqttClient.setCallback(::callback);

然后连接到AWS:

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

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

  #define MQTT_MAX_PACKET_SIZE 1024

而且看起来足够。

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

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

相关问题