15.1 AWS MQTT 실습 - sunbang123/Smart_device GitHub Wiki
- AWS 인증서
- AWS 인증서는 AWS IoT 서비스를 사용하여 디바이스를 인증하는 데 사용되는 디지털 인증서
- 공개키/개인키 쌍으로 구성되어 있으며, 보안 소켓 계층(SSL/TLS) 프로토콜을 통해 디바이스와 AWS IoT 서비스 간의 안전한 통신을 제공
- AWS 정책
- AWS 정책은 AWS 리소스와 서비스에 대한 액세스 제어를 정의하는 규칙의 집합
- AWS Identity and Access Management (IAM)을 통해 구성할 수 있음.
- JSON(JavaScript Object Notation) 형식으로 작성됨.
- 특정 사용자, 그룹, 또는 역할에 대한 허용되거나 거부되는 작업과 리소스를 지정함.
- 특정 작업에 대한 권한을 부여하거나 제한하여 보안을 강화할 수 있음.
- AWS 콘솔에 접속, 로그인
- IoT Core 서비스 접속
- 모든 서비스 -> 사물인터넷 -> IoT Core
- 사물 생성
- 관리 -> 사물 을 클릭, 사물 생성
- 인증키 다운로드

- 정책 생성, 연결
- 보안 -> 정책 탭, 정책 생성 버튼을 클릭
- 관리 -> 사물 -> YourThingName -> 인증서 에서 인증서 ID를 클릭

- 라이브러리 다운
- 아두이노 라이브러리 관리 에 들어가서 ArduinoJson 과 lwmqtt 를 검색해 다운
- 코드 실행, 시리얼 모니터 확인

- secrets.h파일을 생성.
- 아래는 코드 내용.
#include <pgmspace.h>
#define SECRET
#define THINGNAME "[사물 이름]"
const char WIFI_SSID[] = "[와이파이 이름]";
const char WIFI_PASSWORD[] = "[와이파이 비밀번호]";
const char AWS_IOT_ENDPOINT[] = "[디바이스 데이터 endpoint].amazonaws.com"; //amazon endpoint
// Amazon Root CA 1
static const char AWS_CERT_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
[CA1 Key]
-----END CERTIFICATE-----
)EOF";
// Device Certificate
static const char AWS_CERT_CRT[] PROGMEM = R"KEY(
-----BEGIN CERTIFICATE-----
[Device 인증서]
-----END CERTIFICATE-----
)KEY";
// Device Private Key
static const char AWS_CERT_PRIVATE[] PROGMEM = R"KEY(
-----BEGIN RSA PRIVATE KEY-----
[Private key]
-----END RSA PRIVATE KEY-----
)KEY";
- 메인 코드
#include "secrets.h"
#include <WiFiClientSecure.h>
#include <MQTTClient.h>
#include <ArduinoJson.h>
#include "WiFi.h"
// The MQTT topics that this device should publish/subscribe
#define AWS_IOT_PUBLISH_TOPIC "esp32/pub"
#define AWS_IOT_SUBSCRIBE_TOPIC "esp32/sub"
WiFiClientSecure net = WiFiClientSecure();
MQTTClient client = MQTTClient(256);
void connectAWS()
{
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.println("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
// Configure WiFiClientSecure to use the AWS IoT device credentials
net.setCACert(AWS_CERT_CA);
net.setCertificate(AWS_CERT_CRT);
net.setPrivateKey(AWS_CERT_PRIVATE);
// Connect to the MQTT broker on the AWS endpoint we defined earlier
client.begin(AWS_IOT_ENDPOINT, 8883, net);
// Create a message handler
client.onMessage(messageHandler);
Serial.print("Connecting to AWS IOT");
while (!client.connect(THINGNAME)) {
Serial.print(".");
delay(100);
}
if(!client.connected()){
Serial.println("AWS IoT Timeout!");
return;
}
// Subscribe to a topic
client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);
Serial.println("AWS IoT Connected!");
}
void publishMessage()
{
StaticJsonDocument<200> doc;
doc["time"] = millis();
doc["sensor_a0"] = analogRead(0);
char jsonBuffer[512];
serializeJson(doc, jsonBuffer); // print to client
client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
}
void messageHandler(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
// StaticJsonDocument<200> doc;
// deserializeJson(doc, payload);
// const char* message = doc["message"];
}
void setup() {
Serial.begin(9600);
connectAWS();
}
void loop() {
publishMessage();
client.loop();
delay(1000);
}

원인 불분명한 문제로 결과가 작동하지 않음.
- 핫스팟으로 실행했을때 연결이 안되는 상황 발생.
- 집 와이파이(5G/2G)를 시도해서 연결해봄.
- 2G에서 연결이 되는것을 확인.
- AWS IoT연결이 안되는 상황 발생 connecting to AWS IOT 이후에 . 만 출력됨.
- #define THINGNAME 뒤에 사물 이름을 적지 않아서 연결이 안된 것을 확인.
#define THINGNAME "ESP32"
- 이후에도 계속 연결이 안되서 #define SECRET 뒤에 코드를 작성함.
- Acess key 발급
- AWS Management -> 내 보안 자격 증명 -> 보안 자격 증명 -> 액세스 키 (Access keys) 섹션 -> 액세스 키 만들기 클릭.
#define SECRET "{\"aws_key\":\"[액세스 키 ID]\",\"aws_secret\":\"[시크릿 액세스 키]\",\"aws_region\":\"us-east-2\",\"thing_name\":\"esp32\"}"

- 재시도 결과

#define SECRET 은 원래대로 돌려놓음.
설정에서 보안 정보를 IoTSecurityPolicy_TLS12_1_0_2016_01로 바꿔줌.
다른 부분에 이상이 없으므로 wifi를 핫스팟으로 변경해서 재시도.
- 재시도 결과

연결 성공!
- MQTT 테스트창에 esp32 구독 생성
- 코드 업로드, 시리얼 모니터 확인
- 테스트창에서 MQTT 연결 확인.

- 코드 업로드, 시리얼 모니터 확인
- 테스트창에서 MQTT 연결 확인.

- 온습도값이 출력되는지 확인.

온습도값 보내기 성공!
#include "secrets.h"
#include <WiFiClientSecure.h>
#include <MQTTClient.h>
#include <ArduinoJson.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <WiFi.h>
// AWS IoT 설정
#define AWS_IOT_PUBLISH_TOPIC "esp32/pub"
#define AWS_IOT_SUBSCRIBE_TOPIC "esp32/sub"
// DHT11 센서 설정
#define DHT_PIN 13 // DHT11 데이터 핀
#define DHT_TYPE DHT11 // DHT11 센서
WiFiClientSecure net = WiFiClientSecure();
MQTTClient client = MQTTClient(256);
DHT dht(DHT_PIN, DHT_TYPE);
void connectAWS()
{
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.println("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
// Configure WiFiClientSecure to use the AWS IoT device credentials
net.setCACert(AWS_CERT_CA);
net.setCertificate(AWS_CERT_CRT);
net.setPrivateKey(AWS_CERT_PRIVATE);
// Connect to the MQTT broker on the AWS endpoint we defined earlier
client.begin(AWS_IOT_ENDPOINT, 8883, net);
// Create a message handler
client.onMessage(messageHandler);
Serial.print("Connecting to AWS IoT");
while (!client.connect(THINGNAME)) {
Serial.print(".");
delay(100);
}
if(!client.connected()){
Serial.println("AWS IoT Timeout!");
return;
}
// Subscribe to a topic
client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);
Serial.println("AWS IoT Connected!");
}
void publishMessage(float temperature, float humidity)
{
StaticJsonDocument<200> doc;
doc["temperature"] = temperature;
doc["humidity"] = humidity;
char jsonBuffer[512];
serializeJson(doc, jsonBuffer);
client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
}
void messageHandler(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
}
void setup() {
Serial.begin(9600);
connectAWS();
dht.begin();
}
void loop() {
// 온습도 데이터 읽기
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
Serial.println(temperature);
Serial.println(humidity);
// 유효한 값인지 확인
// if (isnan(temperature) || isnan(humidity)) {
// Serial.println("Failed to read from DHT sensor!");
// return;
// }
// 온습도 데이터를 AWS IoT에 전송
publishMessage(temperature, humidity);
// AWS IoT 클라이언트 루프
client.loop();
delay(1000);
}
- 첫번째 시도때 집 와이파이와 핫스팟 모두 사용해봤지만 connected가 뜨지 않아서 실습을 끝맺지 못한 점이 아쉬웠음.
- 재시도 하면서 사물 이름을 입력하지 않은 것 처럼 코드 실수로 연결이 안될수 있다는 점을 앞으로 더 유의하자.
- aws 연결에 필요한 기초 개념(인증서, 보안)을 실습을 통해서 체험할 수 있어서 만족.
- 실습을 통해 개념에 대한 이해가 쌓일 수 있음.