개발자/Arduino

Decoding and Encoding JSON with Arduino Nano 33 IoT 1

지구빵집 2020. 10. 10. 01:30
반응형

 

Arduino로 JSON 데이터 주고받기와 OpenWeatherMap API  

 

스마트 팩토리 분야 중 인쇄장비 데이터 송수신 장치를 개발 중입니다. 센서 데이터 수집 서버로 JSON 형식의 데이터를 주고받아야 하는 데 잘 안되네요. 센서 데이터 수집 서버하고 프로토콜 맞추는 일도 한참 걸리고, JSON은 알지도 못하니 배우면서 해야 하거든요. 이런. 아래 자료의 출처는 Decoding and Encoding JSON with Arduino or ESP8266 임을 알립니다. 정리가 잘 되어 있습니다.

 

관련 포스팅은 아래를 참고하십시요.

ArduinoJson 데이터의 Decoding / Ecoding 예제

Decoding and Encoding JSON with Arduino Nano 33 IoT 2

Decoding and Encoding JSON with Arduino Nano 33 IoT 1

Decoding and Encoding JSON with Arduino Nano 33 IoT 3

 

여기서는 ESP8266을 사용하지 않고 Arduino Nano 33 IoT를 사용해 실습을 진행합니다. 코드도 물론 약간 틀려집니다. 이더넷이 아니라 WiFi를 사용하니까요. 크게 달라지는 부분은 없습니다. 통신 환경만 바뀌는 거니까 라이브러리 함수만 약간 달라지니 크게 어려움은 없을 겁니다.

 

이 블로그 게시물에서는 이더넷 실드가 포함된 Arduino를 사용하여 ArduinoJson 라이브러리로 디코딩 (JSON 문자열 구문 분석) 및 인코딩 (JSON 문자열 생성)하는 방법을 배우게 됩니다. 이 가이드는 작은 변경 사항이 있는 ESP8266 및 ESP32 Wi-Fi 모듈에서도 작동합니다. 

 

*중요: 이 튜토리얼은 ArduinoJSON 라이브러리 5.13.5 와만 호환됩니다. 

 

아두이노 IDE 환경에서 ArduinoJson 라이브러리를 버전에 따라 다른 다른 라이브러리로 설치가 가능하니 참고하시기 바랍니다.

 

JSON이란?

 

JSON은 JavaScript Object Notation을 나타냅니다. JSON은 데이터 교환을 위한 가벼운 텍스트 기반 개방형 표준 디자인입니다.

JSON은 주로 네트워크 연결을 통해 구조화 된 데이터를 직렬화하고 전송하는 데 사용됩니다. 서버와 클라이언트 간에 데이터를 전송합니다. API (Application Programming Interfaces)와 같은 서비스 및 공용 데이터를 제공하는 웹 서비스에서 자주 사용됩니다.

 

JSON 구문 기본 사항

 

JSON에서 데이터는 특정 방식으로 구조화됩니다. JSON은 {}, :””[]와 같은 기호를 사용하며 다음 구문을 사용합니다.

  • 데이터는 키 / 값 쌍으로 표시됩니다.
  • 콜론 (:)은 키에 값을 할당합니다.
  • 키 / 값 쌍은 쉼표 (,)로 구분됩니다.
  • 중괄호는 개체를 포함합니다 ({}).
  • 대괄호는 배열 ([])을 포함합니다.

예를 들어 JSON으로 데이터를 나타 내기 위해 키 / 값 쌍은 다음과 같습니다.

 

{"key1":"value1", "key2":"value2", "key3":"value3"}

 

JSON 예: 실제 예에서는 사용자에 대한 구조 데이터가 필요할 수 있습니다. 

 

{"name":"Rui", "country": "Portugal", "age":24}

 

혹은 IoT 에서는 센서로부터 얻은 데이터를 구조화할 수도 있습니다.

 

{"temperature":27.23, "humidity":62.05, "pressure":1013.25}

 

JSON에서는 값들은 또 다른 오브젝트(sports) 혹은 배열(pets)이 될 수 있습니다. 예를 들면

 

{
  "name": "Rui",
  "sports": {
    "outdoor": "hiking",
    "indoor": "swimming"
  },
  "pets": [
    "Max",
    "Dique"
  ]
}

 

여기에서는 사용자에 대한 데이터를 구조화하고 있으며 "이름", "스포츠" 및 "애완동물"과 같은 몇 가지 키가 있습니다.

이름에는 Rui가 할당 한 값이 있습니다. Rui는 그들이 수행되는 장소와 관련하여 다른 스포츠를 연습할 수 있습니다. 따라서 Rui가 좋아하는 스포츠를 저장하기 위해 또 다른 JSON 개체를 만듭니다. 이 JSON 개체는 "스포츠"키의 값입니다.

"pets"키에는 Rui의 애완 동물 이름이 포함된 배열이 있으며 내부에 "Max"및 "Dique"값이 있습니다.

 

대부분의 API는 JSON으로 데이터를 반환하며 대부분의 값은 JSON 객체 자체입니다. 다음 예는 weather API에서 제공하는 데이터를 보여줍니다. 이 API는 많은 정보를 제공합니다. 예를 들어 첫 번째 줄은 경도와 위도와 함께 좌표를 저장합니다. 

 

{  
  "coord":{  
     "lon":-8.61,
     "lat":41.15
  },
  "weather":[  
    {  
      "id":803,
      "main":"Clouds",
      "description":"broken clouds",
      "icon":"04d"
    }
  ],
  "base":"stations",
  "main":{  
    "temp":288.15,
    "pressure":1020,
    "humidity":93,
    "temp_min":288.15,
    "temp_max":288.15
  },
  (...)
}

 

우선 WiFi 혹은 이더넷 쉴드를 갖춘 아두이노를 준비해야 합니다. 저는 Arduino Nano 33 IoT를 사용하려고 합니다. 따라서 아래 코드나 실습에 필요한 프로그램은 Nano 33 IoT에 맞게 수정해서 올리겠습니다.

 

Arduino IDE 준비

 

Arduino IDE로 JSON 문자열을 디코딩하고 인코딩하는 가장 쉬운 방법은 가장 직관적인 JSON 라이브러리로 설계된 ArduinoJson 라이브러리 5.13.5를 사용하는 것입니다. 이 라이브러리는 Arduino를 위한 가장 작은 풋 프린트와 가장 효율적인 메모리 관리를 제공합니다.

 

Arduino를 염두에두고 작성되었지만 Arduino 라이브러리에 연결되어 있지 않으므로 다른 C ++ 프로젝트에서 이 라이브러리를 사용할 수 있습니다. 예제 및 API 참조가 있는 라이브러리에 대한 설명서 웹 사이트도 있습니다.

 

FEATURE

  • JSON 디코딩 (주석이 지원됨)
  • JSON 인코딩 (선택적 들여 쓰기 포함)
  • 사용하기 매우 쉬운 우아한 API
  • 고정 메모리 할당 (malloc)
  • 데이터 중복 없음 (무 복사)
  • 이식성 (C ++ 98로 작성)
  • 자체 포함 (외부 종속성 없음)
  • 작은 설치 공간
  • 헤더 전용 라이브러리
  • MIT 라이선스

호환 가능

  • Arduino 보드 : Uno, Due, Mini, Micro, Yun…
  • ESP8266, ESP32 및 WeMos 보드
  • Teensy, RedBearLab 보드, Intel Edison 및 Galileo
  • PlatformIO, 입자 및 에너지

 

지금 설명하는 1번 라이브러리 설치는 예전 방식이니 참고만 하십시요. 우리는 2번 방식을 따라 설치합니다. 버전을 선택하는데 주의합니다.

 

1. ArduinoJson 라이브러리 설치 이 프로젝트의 경우 Arduino IDE에 ArduinoJson 라이브러리를 설치해야 합니다.

 

  1.  ArduinoJson 버전 5.13.5를 다운로드하려면 여기를 클릭하십시오. 다운로드 폴더에 .zip 폴더가 있어야 합니다.
  2. .zip 폴더의 압축을 풀면 ArduinoJson-master 폴더가 표시됩니다.
  3. ArduinoJson-master에서 ArduinoJson으로 폴더 이름을 바꿉니다.
  4. ArduinoJson 폴더를 Arduino IDE 설치 라이브러리 폴더로 이동하십시오.
  5. 마지막으로 Arduino IDE를 다시 엽니다. 

 

2. 아래 이미지와 같이 Arduino IDE 환경의 라이브러리 관리에서 Arduino Json을 찾아 설치하시면 됩니다.

 

 

 

JSON 디코딩 – JSON 문자열 구문 분석

 

다음 JSON 문자열을 디코딩 / 파싱하여 시작하겠습니다.

 

{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}

 

ArduinoJson 라이브러리를 가져옵니다.

 

#include <ArduinoJson.h>

 

Arduino JSON은 사전 할당 된 메모리 풀을 사용하여 JsonObject 트리를 저장합니다.이 작업은 StaticJsonBuffer에 의해 수행됩니다. ArduinoJson Assistant를 사용하여 정확한 버퍼 크기를 계산할 수 있지만이 예에서는 200이면 충분합니다.

 

StaticJsonBuffer<200> jsonBuffer;

 

샘플 JSON 문자열을 저장하기 위해 json[ ]이라는 char 배열을 만듭니다.

 

char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";

 

parseObject( ) 함수를 사용하여 JSON 문자열을 root라는 JsonObject로 디코딩 / 파싱합니다.

 

JsonObject& root = jsonBuffer.parseObject(json);

 

디코딩 / 파싱이 성공했는지 확인하려면 root.success( )를 호출하면 됩니다.

 

if(!root.success()) {
  Serial.println("parseObject() failed");
  return false;
}

 

결과는 다음 세 가지 이유로 거짓 일 수 있습니다.

  • JSON 문자열에 잘못된 구문이 있습니다.
  • JSON 문자열은 객체를 나타내지 않습니다.
  • StaticJsonBuffer가 너무 작습니다. ArduinoJson Assistant를 사용하여 버퍼 크기를 계산하십시오.

이제 객체 또는 배열이 메모리에 있으므로 데이터를 쉽게 추출 할 수 있습니다. 가장 간단한 방법은 JsonObject 루트를 사용하는 것입니다.

 

const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];

 

디코딩 된 변수 센서, 시간, 위도 또는 경도를 코드 로직에서 사용할 수 있습니다.

 

OpenWeatherMap API

 

이더넷 실드와 함께 Arduino를 사용하는 실제 예를 들어, OpenWeatherMap의 무료 API를 사용하여 선택한 위치에 대한 오늘의 일기 예보를 요청합니다.

 

API 사용 방법을 배우는 것은 현재 주가, 환율, 최신 뉴스, 트래픽 업데이트 등과 같이 지속적으로 변경되는 다양한 정보에 액세스 할 수있게 해주기 때문에 훌륭한 기술입니다.

 

API 사용

 

OpenWeatherMap의 무료 요금제는 단순한 예제에 필요한 모든 것을 제공합니다. API를 사용하려면 APIID라고하는 API 키가 필요합니다. APIID를 얻으려면 :

  1. 브라우저를 열고 OpenWeatherMap으로 이동합니다.
  2. 가입 버튼을 누르고 무료 계정을 만드세요.
  3. 계정이 생성되면 여러 탭이 포함 된 대시 보드가 표시됩니다 (아래 그림 참조).
  4. API 키 탭을 선택하고 고유 키를 복사하십시오.

 

 

사이트에서 정보를 가져 오는 데 필요한 고유 키입니다. 이 키를 복사하여 어딘가에 붙여 넣으세요. 잠시 후 필요합니다.

 

선택한 위치의 날씨 정보를 가져 오려면 중괄호로 묶인 섹션을 선택한 위치 정보와 고유한 API 키로 바꾼 다음 URL을 입력하세요.

 

http://api.openweathermap.org/data/2.5/weather?q={your city},{your country code}&APPID={your API Key}

 

{your city}를 데이터를 원하는 도시로, {your country code}를 해당 도시의 국가 코드로, {your API key}를 이전에 찾은 고유 API 키로 바꿉니다. 예를 들어 포르투갈의 Porto 마을에 대한 API URL은 세부 정보로 바꾼 후 다음과 같습니다. 우리는 여기서 서울시로 바꾸어 실습을 진행합니다. 그 세부 코드는 아래와 같습니다. 궁금해 하는 도시코드(이름)는 상단 메뉴 maps으로 들어가면 도시 이름이 나옵니다.

 

상단 메뉴에서  Maps를 통해 확인

 

대문자 소문자 상관 없습니다. 국가 코드는 여리 링크로 들어가 가장 아래 부분에 나옵니다. 여기서 도시는 seoul로 하고 국가는 kr로 하였고, 부여받은 api 코드를 넣어 아래와 같은 요청 URL을 만들었습니다.

 

http://api.openweathermap.org/data/2.5/weather?q=seoul,KR&APPID=34b3527445f4bb5a2b---------

 

참고 : API를 사용하여 날씨 정보를 얻는 방법에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

 

URL을 브라우저에 복사하면 현지 날씨 정보에 해당하는 많은 정보가 제공됩니다. 우리의 경우, 지금 작성한 날의 서울 날씨 정보를 반환합니다. 아래 크롬의 주소줄에 위 코드를 넣습니다. API 키는 반드시 자신의 것을 발급 받아야 합니다.

 

서울시 날씨 정보를 반환

텍스트는 아래에 있습니다.

 

{"coord":{"lon":126.98,"lat":37.57},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"stations","main":{"temp":289.55,"feels_like":287.63,"temp_min":289.15,"temp_max":290.15,"pressure":1022,"humidity":51},"visibility":10000,"wind":{"speed":1.5,"deg":40},"clouds":{"all":75},"dt":1602251865,"sys":{"type":1,"id":8117,"country":"KR","sunrise":1602192868,"sunset":1602234236},"timezone":32400,"id":1835848,"name":"Seoul","cod":200}

 

위 데이터를 JSON 데이터 형식으로 바꾸어 정리하면 아래와 같습니다.

 

{
	"coord": {
    	"lon":126.98,
        "lat":37.57
        },
        "weather":[
        {
        	"id":803,
            "main":"Clouds",
            "description":"broken clouds",
            "icon":"04n"
            }
        ],
        "base":"stations",
        "main":{
        	"temp":289.55,
            "feels_like":287.63,
            "temp_min":289.15,
            "temp_max":290.15,
            "pressure":1022,
            "humidity":51},
            "visibility":10000,
            "wind":{
            	"speed":1.5,
                "deg":40
            },
            "clouds":{
            "all":75
            },
            (......)
}

 

포스팅이 길어져 여기서 마치고 "Arduino 로 API 요청을 만들기" 편은 다음 포스팅에서 시작하겠습니다. 여기까지 봐주셔서 감사합니다. 요즈음은 통 놀 시간이 없어서 우울합니다. 언제는 우울하지 않았던 적이 있었나? 하는 생각에 일만 열심히 하게 됩니다. 가을이 점점 가득한 곳으로 갑니다. 많이 즐기시길 바랍니다. ^^

 

 

참고자료

Decoding and Encoding JSON with Arduino or ESP8266 

OpenWeatherMap API - OpenWeather global services 

ArduinoJson Assistant 

ArduinoJson - The best JSON library for embedded C++ 

Serialization tutorial - Learn how to generate a JSON document on Arduino 

Getting Started with Node-RED on Raspberry Pi 

Node-RED

 

 

 

 

 

 

반응형