프로젝트/2021-2022 포밍부스 프로젝트

[포밍부스] AWS IoT Core 사용해보기 2탄 - 사운드 인터렉션

sleesm 2022. 4. 16. 15:25

 

 

 

오늘은 저번에 이어서 NodeJsArduino에 사용하는 과정을 적어놓을 것이다!!!!

 

 

 

저번 블로그 👉👉

2022.01.28 - [프로젝트/2021-2022 포밍부스 프로젝트] - [포밍부스] AWS IOT Core 사용해보기 - 사운드 인터렉션

 

[포밍부스] AWS IOT Core 사용해보기 - 사운드 인터렉션

오늘은 포밍부스 체험 중 사운드 인터렉션을 구현할 때 사용한 AWS IOT Core에 대해 적어보려고 한다!!! https://aws.amazon.com/ko/iot-core/ AWS IoT Core 디바이스 섀도우를 통해 언제든 확인하거나 설정할 수..

sleecode.tistory.com

 

 

 

 

 

 

 


 

 

 

먼저, NodeJS에서 AWS IoT Core를 연결하는 방법이다!

 

생각보다 뚝딱하면 뚝딱 완성된다!!!

 

 

 

☝ aws-iot-device-sdk를 설치해준다!

npm i --save aws-iot-device-sdk
npm i --save-dec @types/aws-iot-device-sdk

 

 

 

 

 

✌ aws private 정보를 넣어둔다!

formingbooth code 안에 private 정보 관리

이름을 변경해서 넣어두었는데,

저번 시간에 받아온 key값들을 넣어주면 된다!!

이 중 root-CA.crt는 구글링 해서 저장해 주었다!

( root-CA.crt는 AWS IoT 루트 CA)

 

 

 

 

 

 

 

 

 

 

🤟 코드를 작성해 준다!

 

 

먼저 AWS IoT Core와 연결할 device를 선언해 준다!!

위에 저장한 내용들과 client id 그리고 host 주소를 적어줘야 한다

 

사용할 변수 device 설정해주기

 

 

 

이제 device를 연결하고 원하는 topic을 구독해서 이벤트 처리를 해주면 된다!!!

 

 

 

 

 

device.on()을 통해 각각의 상황에 맞게 이벤트 처리를 할 수 있다

  • connect
  • close
  • reconnect
  • offlinet
  • error
  • message

 

여기서 message 부분을 통해 토픽에 따라 원하는 행위를 처리할 수 있는데

그전에 device.subscribe()를 통해 어떤 토픽을 구독하는지 설정해줘야 한다!!

 

프로젝트 상황에 맞춰 'offline' 토픽으로 받은 메시지에 따라 thing(사물#) 값에 따른 신호를 0 혹은 1로 변화해 줬다!

( 이는 후에 유니티에서 mqtt를 위한 웹통신을 했을 때 전달해줘야 하는 값이기도 하다 )

 


우리 프로젝트는 기본적으로 'offline'과 'online'토픽을 사용할 것이다

( 'offline'은 아두이노에서 가져오는 값이고 'online'은 유니티에서 웹통신으로 받는 값이다 )

 

'offline' 토픽의 메시지 형태를 다음과 같이 정했다

{"thing" : id# , "sign" : sign#}

 

이때 id#는 미리 설정해 둔 사물의 숫자를 의미하고 정수로 구성되어 있다

sign#은 0과 1로 구성되며 사물에 따른 값을 의미한다

 


 

 

 

AWS IoT Core를 통해 받은 내용을 바탕으로 어떻게 사용하는지 보여주기 위해 코드를 가져와봤다!

 

포밍부스 프로젝트 같은 경우 /untact 일 때 2가지 일을 한다

 

  1. 'offline' 토픽을 통해 받은 값을 response로 전달
  2. device.publish()를 통해 online 토픽으로 body로 전달받은 thing(사물#) 값과 함께 0 혹은 1로 이루어진 상태값을 발행

 

유니티와 mqtt를 위한 API 처리 2

 

 

 

 

 

 

 

이렇게 하면 NodeJS에서 해줘야 할 일은 모두 끝난다!!

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

다음으로 Arduino에서 AWS IoT Core를 연결하는 방법이다!

 

 

 

아두이노에서도 AWS IoT Core와 통신하려면 와이파이 연결이 필수적이다

또한 구독과 발행을 위한 헤더파일을 추가적으로 작성해야 한다!

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

 

 

 

 

이후에는 와이파이와 AWS IoT Core를 사용하기 위한 값들을 선언해 준다

const char *ssid = "";  // 와이파이 이름
const char *pass = "";      // 와이파이 비밀번호
const char *thingId = "";          // 사물 이름 (thing ID) 
const char *host = ""; // AWS IoT Core 주소

// 사물 인증서 (파일 이름: xxxxxxxxxx-certificate.pem.crt)
const char cert_str[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
)EOF";
// 사물 인증서 프라이빗 키 (파일 이름: xxxxxxxxxx-private.pem.key)
const char key_str[] PROGMEM = R"EOF(
-----BEGIN RSA PRIVATE KEY-----

-----END RSA PRIVATE KEY-----
)EOF";
// Amazon Trust Services(ATS) 엔드포인트 CA 인증서 (서버인증 > "RSA 2048비트 키: Amazon Root CA 1" 다운로드)
const char ca_str[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
)EOF";


X509List ca(ca_str);
X509List cert(cert_str);
PrivateKey key(key_str);
WiFiClientSecure wifiClient;
PubSubClient client(host, 8883, callback, wifiClient);

 

 

 

 

 

 

 

이제 아두이노에서 스케치를 시작할 때 불리는 setup()에서 

위에서 선언한 값을 토대로 와이파이 연결을 하고 AWS IoT Core와 연결하고자 한다!

 

  1. 위에 선언한 값을 토대로 와이파이 연결을 해준다
  2. 와이파이가 연결되면 wifiClient에 CA와 Private Key를 설정해 준다
  3. PubSubClient 객체인 client를 AWS IoT Core hostname과 포트#로 연결해 준다
  4. message를 받았을 때 반환해 줄 callback() 함수를 설정해 준다

 

그리고 기본적으로 아두이노는 loop() 함수를 통해 유니티의 update() 함수와 같이

지속적으로 루프를 돌면서 같은 행위를 한다 

 

loop() 함수 내에 reconnect() 함수를 통해 우리는 mqtt 연결을 하고 토픽에 따른 값처리를 하려고 한다

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);

  // We start by connecting to a WiFi network
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  // After connecting a WiFi
  // Setting the certifications and key
  wifiClient.setTrustAnchors(&ca);
  wifiClient.setClientRSACert(&cert, &key);

  setClock();
  
  // Connecting to AWS Iot Core's server host
  client.setServer(host, 8883);
  client.setCallback(callback);
}

void loop() {
  
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

 

 

 

 

먼저, callback() 함수는 기본적으로 다음과 같은 파라미터를 가지고 있다

AWS IoT Core로부터 메시지를 받았을 때 callback() 함수가 불리므로 여기에 원하는 이벤트 처리를 해주면 된다!!

 

 

그리고 중요한 reconnect() 함수는 PubSubClient 객체인 client가 연결되었을 때를 기본으로 동작한다

이후 미리 설정한 AWS IoT Core 사이트에서 설정한 사물 id와 연결된다면, 원하는 토픽인 'online'을 구독하게 한다!!

 

이렇게 하면 callback() 함수가 불릴 때 구독한 토픽에 대한 메시지만 받을 수 있다!!

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(thingId)) {
      Serial.println("connected");
      client.subscribe("online");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");

      char buf[256];
      wifiClient.getLastSSLError(buf,256);
      Serial.print("WiFiClientSecure SSL error: ");
      Serial.println(buf);

      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

 

 

 

 

구독은 위에서 보여줬으니 발행하는 방법을 보여주겠다!!

 

간단하게 client.publish() 함수를 통해 원하는 부분에서 발행을 해주면 된다!

client.publish("topic", msg);

 

 

 

 


 

참고로 포밍부스 프로젝트에서는 메시지 내용을 통일해야 하기 때문에 따로 함수를 만들었다!

메시지 발행 예시 코드

 


 

 

 

이렇게 하면 아두이노에서 해줘야 할 일은 모두 끝난다!!

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

참고 자료

https://github.com/jaestory/blog_logs/blob/fa1df5a5afa6216c042af21e14ceb817255ae7ee/IoT/aws-iot-device-sdk-js/src/device.js#L76

 

https://www.youtube.com/watch?v=4eF6bfIURN0

 

 

 

 

 

 

 

 

 

 

 

 


 

이렇게 해서 성공적으로 연결을 끝낼 수 있었다!!

생각보다 NodeJS보다는 아두이노를 설정하는데 더 많은 시간이 걸렸다

와이파이 연결이 잘 안 됐던 것과 인증서를 어떤 포맷으로 넣어야 할지 몰라서 많이 헤맸었다

 

그래도 다행히 관련 레퍼런스 자료들을 찾고 여러 번 도전한 덕에 해결할 수 있었다!!

 

다른 분들은 우리처럼 헤매지 않기를 바라면서,, 

 

 

 

 

그럼 안녕!!!!!! 🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌