嗨,我需要创建一个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() {
答案 0 :(得分:0)
您似乎正在使用WiFiClientSecure
证书处理的较旧形式。我认为这可以正常工作,并且您能够建立SSL连接。
您的IN_TOPIC
需要稍微更新为:$aws/things/<name-of-your-thing>/shadow/update/accepted
(希望您知道<name-of-your-thing>
是什么)。您可以从AWS控制台上的事物阴影中获得此信息。
类似地,AWS_endpoint
需要更新:它的格式应为<random-stuff-specific-to-you>.iot.<region>.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不会执行太多错误报告来帮助诊断正在发生的事情。我目前正在对其进行一些重构,并包含更多诊断信息,并将最终发出请求请求。在此之前,请告诉我您是否想要被黑的版本。