티스토리 뷰

앞으로 어플리케이션 카테고리에는

조금이라도 응용을 한 것이라면 올리도록 하겠습니다.


누군가에게 조금이라도 레퍼런스가 되길 바라며 진행하겠습니다.





Weather Station


우리 말로 하면, 기상관측소입니다.

사실 직접 관측하는 것도 아닌데, 이런 이름을 붙이는게 마음에 안드시는 분들도 있을지 모릅니다.


하지만 어쨌든, 기상청에서 관측한 데이터를 가지고 나만의 디바이스에 출력하는 것이니 부적절한 이름은 아닌것 같습니다.



그렇다면 왜 이런걸 만들까요?

사실 스마트폰으로 날씨정보 받아서 보면 그만이긴 하지만,

뭔가 이러한 데이터를 활용하는 방법을 통해서 이것저것 만들어보고 싶은게 Maker의 마음이 아닐까요?


예를들어 이런 게 있더라구요.

https://www.hackster.io/windowsiot/picture-of-the-weather-a4c5c2





어떤가요?

공공데이터를 활용해서 이러한 작품을 만들어 집에 둔다면, 집이 조금 더 느낌있지 않을까요?

제품 이름이 기억나지 않아.. 링크 드릴수는 없지만,

일본에서는 이런 데이터를 활용해서 아주 예쁜 제품도 만들었답니다.

비가오면 빗물이 그대로 내리고, 구름이 끼면 정말 구름이 끼게 하는.. 그런 제품!

보여드리고 싶은데.. 도무지 못찾겠네요...






대한민국 기상청


http://www.kma.go.kr/index.jsp


보통 OpenWeatherMap 이라고, 전세계 주요도시의 날씨 정보를 알려주는 사이트가 있습니다.

여기서 Parsing을 많이 하죠!

하지만, 뭔가 우리나라의 구석구석의 날씨정보를 받고싶다면, 이러한 사이트는 좀.. 그렇겠죠?


그래서! 대한민국 기상청에서 제공하는 공공데이터를 활용하려고 합니다.

그 중에 시간단위로 볼 수 있는 동네예보를 보려고 하는데요.

단점이랄까? 말그대로 예보만 해줍니다. 계속 업데이트 되기는 하지만, 현재 시간으로부터 최소 3시간 뒤부터의 날씨 정보를 받을 수 있습니다. 기상예보기가 되버리겠군요 ! 그것도 3시간 단위로 ( ex. 0, 3, 6, 9, 12 ....) 3일치 예보 데이터를 줍니다.


기상청 홈페이지로 들어오시면, 메인화면이 보이실 겁니다.

글을 짧게 하기 위해 그림 하나로 대체하겠습니다.


홈페이지에 접속하셔서, [날씨] -> [생활과 산업] -> [서비스] -> [인터넷] -> [RSS]  순서로 클릭하시면 됩니다.

그리고 나서는 하단에 보이는것처럼 자신이 원하는 동네를 검색합니다.

아참! 여기서 검색방법은... 서울특별시 고르고 검색버튼 누르셔야 다음 내용이 변경이 됩니다...

그러니까.. 총 검색버튼을 매번 눌러주셔야겠죠 .. 하핳...

요즘스럽지 않은 인터페이스에 놀랐습니다만.. 뭐 데이터를 사용하는 입장에서는 그냥 쓸수밖에요....



주소를 선택한 후, 오른쪽의 [RSS] 를 클릭하면 아래와 같은 창이 뜨는데요. 미리 복사하셔도 되고 다음 화면에서 복사하셔도 됩니다.



[확인] 버튼을 누르시면 아래와 같이 XML 파일을 브라우저에서 보실 수 있습니다.

자! 이제 여기서 우리가 필요한 데이터만 쏙쏙 빼가면 됩니다.

그. 런. 데. 몇 개는 대충 짐작이 가지만 무슨 값인지 알 수 없는 것들도 있습니다.

그리고 짐작만 하면 위험하니 정확히 해야겠죠?



우선, Url에 나온 zone을 보세요. 누가봐도 이건.. 지역.. 이구나... 알 수 있습니다

다음은 dongCode 인데요.... 이쯤되면 아시겠죠..?

그래도 확인해 봅니다. 아래가 제공되는 내용들인데 Json으로 되어 있습니다.


도(광역시) 코드http://www.kma.go.kr/DFSROOT/POINT/DATA/top.json.txt

시/군/구 코드http://www.kma.go.kr/DFSROOT/POINT/DATA/mdl.41.json.txt

읍/면/동 코드 : http://www.kma.go.kr/DFSROOT/POINT/DATA/leaf.41135.json.txt


자세히 보시면, top, mdl, leaf 라는 표현이 있습니다.


Top 가장 높은 곳일테고(가장 상위),

mdl , Middle의 약어겠죠. 중간층..

leaf , 잎사귀네요.. 말단이겠죠?


그리고 그 뒤에 나오는 숫자들은 우선 도(광역시) 코드를 보시면 압니다.

경기도의 경우 41의 값을 가지는데, 시/군/구 코드의 mdl.41은 이런 뜻입니다. 41. 즉 경기도의 시/군/구를 나타낸다는 것이죠.

다음 leaf에 있는 41135는 앞서 mdl에서 선택한 시/군/구 코드입니다. 즉 여기서는 "경기도 성남시 분당구"의 읍/면/동을 나타낸다는 것이죠.


사실 이건 몰라도 되요.

왜냐면, 어차피 RSS 데이터를 얻을 때, 우리는 홈페이지에서 하나하나 클릭해서 정보를 받았으니까요 :) 

그래도 필요할 때 정보가 있어야 하므로 이렇게 남겨놓습니다.



다음은 도대체 어떤 데이터가 우리가 원하는 데이터인지 명확하게 확인해보죠.

아래의 Url로 가시면 RSS 정의 문서를 보실 수 있습니다. 여기서 필요한 데이터가 무엇인지 확인할 수 있겠죠?

http://www.kma.go.kr/images/weather/lifenindustry/timeseries_XML.pdf


결국 이러한 데이터를 기상청 홈페이지에서 예쁘게 만든게 아래 링크와 같은 화면입니다.

http://www.kma.go.kr/weather/forecast/timeseries.jsp?searchType=INTEREST&dongCode=4113552000


즉, 데이터만 제공될 뿐이고 나머지는 사용자 하기 나름이라는 거죠.

저는 여기서 이쁘게 꾸밀 생각은 없습니다 :))))






H/W 구성


보드는 WizArduino 를 사용했습니다.

다른걸 다 떠나서, 일단 Ethernet Shield 2의 기능이 한 보드에 들어가 있거든요..

전 부피가 커지거나 실드를 쌓아 올려가는걸 별로 좋아하질 않습니다...


Ethernet Shield 2에는 WIZnet의 W5500 칩이 사용되었는데요.

칩이 다르기때문에 라이브러리 또한 상이합니다.

따라서 Ethernet2 라이브러리를 추가해주셔야 합니다.

예전 org IDE에는 기본 포함이 되어 있었고, 요즘 통합 이후의 1.8.0 부터는 라이브러리 매니저를 통해 추가할 수 있습니다.


기존 W5100이나 W5200이 사용된 Ethernet Shield의 경우는 그대로 Ethernet 라이브러리를 사용하시면 되겠습니다.


아, 그리고 WizArduino는 32bit ARM 아키텍쳐를 사용하기 때문에 기존 아두이노 보드와는 다릅니다.

따라서 보드 매니저에서 Arduino m0 보드를 추가해주어야 하죠.


이 포스팅에서 제공하는 코드에서의 차이점은

Serial print할 때, Serial이 아니라 SerialUSB라는 차이점만 있습니다.

만약 Uno와 같은 8bit AVR 보드를 사용하시는 분들은 이걸 Serial로 바꿔주시면 됩니다.


원래는 매크로를 사용해서, 하나만 변경하면 수정되게 하려고 했습니다만...

그렇게 하면 오히려 만들어진 매크로로 인해 나중에 혼란이 오는 것보다 하나씩 이해하면서 스스로 바꾸시는게 나을것이라 판단되어 이렇게 진행했습니다.

물론 나중에 가면 특정 라이브러리들이 MCU에 따라 호환이 안되는 것이 있어서,

그 때는 정확히 분리해서 올리거나 할 것 같습니다. 하지만 일단은 이렇게 올리도록 하겠습니다.



정리하자면,


Ethernet / Ethernet2 라이브러리를 꼭 확인하시고 (자신이 어떤 보드를 사용하는지)

32bit MCU 보드를 사용하는 것이 아니라면, SerialUSBSerial로 바꿔주시면 됩니다.


혹시나 라이브러리 추가나 보드 추가방법을 모르시는 분들을 위해 별도로 포스팅 하겠습니다.

( 잘 모르시겠으면 편하게 문의 주세요! )



어쨌든, 보드 하나 준비하시고 (Ethernet Shield 포함)

LAN 케이블을 준비해서, 공유기와 보드를 연결해 주시면 됩니다.

물론 usb케이블로 PC와 연결되어 있어야겠죠?


부품을 더 늘리고 싶지 않아서 WizArduino 를 Ethernet Cable로 연결했지만,

WIFI를 사용하셔도 됩니다. 물론 그러면 코드를 수정해주셔야겠죠!






Arduino Code


https://create.arduino.cc/editor/OpusK/75659764-b069-4491-b448-c288a9de638d/preview


Arduino Create를 사용해서 올려두었습니다. 아무래도 이래야 소스 최신화도 쉽고 공유에도 용이하니까요 :)

코딩 스킬에 대해서는 따로 언급하지 않겠습니다.

그렇게 잘 짠 코드도 아닐 뿐더러... 파싱스킬 같은걸 알려드리려는 포스팅이 아니니까요!




먼저, 파싱을 위해 특별히 체크한 내용이 있습니다.


서두에 설명드린 것처럼, 이 데이터는 3일의 데이터를 3시간씩 예보해줍니다.

XML 파일을 보신분들은 눈치 채셨겠지만, 뭔가 같은 프레임이 계속 반복됩니다.

네.. 맞습니다. 만약 지금 시각이 8시면, 12, 15, 18, 21 ... 이러한 형태로 데이터가 제공됩니다.

8시로부터 3시간인 11시가 아니라 0, 3, 6, 9, 12... 처럼 이미 3의 배수로 된 시각의 예보만 제공되는 것이죠.


근데, 이걸 다 받는다고 생각해보세요. 바로 앞의 예보만 알고 싶은 사람에게는 불필요한 데이터가 되겠죠?

물론 다 필요한 분들도 있을 겁니다. 어찌 되었든 그 사용법을 알아보도록 하시죠.


위에서 드린 RSS정의 링크에서 확인 가능한 것처럼, <data seq="0">가 그 역할을 합니다.

사실 위의 PDF정보가 없더라도 쉽게 알 수 있어요. 데이터를 보면, 이 data seq 를 기준으로 동일한 구조가 계속 반복되거든요.

심지어 <hour> </hour> 안에 있는 정보가 3시간 단위로 변하고 있는데... 조금만 관심 가지면 알 수 있습니다.


그래서 소스에서도, 먼저 저 부분을 파싱합니다.

가장 1번째 시퀀스인 "0"을 찾는 것이죠.


1
2
3
4
5
6
7
8
9
10
11
12
   //Check Data Sequence
   int seq = line.indexOf("<data seq=\"");
   if(seq >= 0)
   {
        tmp_str = "<data seq=\"";
        int seq_end = line.indexOf("\">");
        data_seq = line.substring(seq+tmp_str.length(), seq_end);
        // SerialUSB.println(data_seq);
   }
   
   if(data_seq == "0")
   {  
cs


indexOf() 함수는 String Class의 함수이구요.

()안에 있는 문자열이 있는 곳의 index를 반환해줍니다.

먼저 저걸 찾고, substring()이라는 함수를 통해 앞뒤를 툭툭 잘라내는 것이죠.

내가 원하는 값의 위치의 앞, 뒤를 툭툭 잘라내면 내가 원하는 값만 얻을 수 있겠죠?


사실 이 함수가 마음에 들진 않습니다. 하지만 Arduino를 사용하면서 Arduino 함수를 쓰지 않는 것은 Arduino를 쓰는 의미가 없다고 해야할까요? 아무래도 누구나 함수에 대한 이해만 하면 사용할 수 있는 건데, 누구나 따라할 수 있게 하려면 제공되는 기본 함수를 최대한 사용해야한다는게 제 개인적인 견해입니다 :)



자, 그래서 그 잘라내고 얻은 데이터를 data_seq 라는 String 버퍼에 복사해두었습니다.

그리고, 그녀석이 "0" 인지 체크하는 것이지요. 그게 아니면 넘어가는걸로!


나머지 시간값 같은 데이터를 가져오는 내용은 앞서 data seq 를 파싱하는 방법과 동일합니다.

어렵지 않죠? 포인터에 대한 이해가 필요한 함수이긴 하지만, 그건 원론적인 것이고 Type만 주의하시면 쉽게 사용하실 수 있습니다.

indexOf(찾고자 하는 문자열)

substring(자를위치(앞), 자를위치(뒤))  -> 이건 예를 들면 이런거에요. "Hello"가 있어요. 이 문자열에 대해 substring(2,4); 를 하게 되면,

3번째 글자인 "l"만 남게 되는겁니다. 이렇게만 이해하고 사용하시면 되요.



자 그럼 소스를 넣고 그대로 돌려보겠습니다.

공공 데이터이고 별도의 Key가 필요없어도 다른 설정을 할 필요도 없습니다.

아, 물론 지역을 바꾸고 싶다면 숫자를 변경해 주셔야겠죠 ?

( 참고로 MAC주소를 지정해주셔야 합니다. 제공된 소스 그대로 업로드 하시려고 하면 에러가 나와요!

  MAC에 대해서는 관련 포스팅 글을 읽어보시거나 검색을 해보셔요.

  그래도 잘 모르시겠다면 댓글이나 메일 주시면 링크를 드리거나 답변 드리도록 하겠습니다 )


잘 업로드가 되었다면 아래와 같이 나옵니다.



위 그림에 나온것처럼 데이터 인터벌은 위의 숫자를 변경해서 사용하시면 됩니다.

다만, ms 단위로 되어 있고, unsigned long 이기 때문에 32bit 크기만큼 입력할 수 있어요.

대략... 초(sec)로 하면, 최대 4,294,967 초 정도 되겠네요.

물론 최대치로 쓰는건 권장하지 않습니다. 혹시나 Loop 어딘가에 잡혀서 1초정도 날려버린다면 저 값은 다시 0이 되어 있을테니... 또 저만큼의 시간을 기다려야겠죠? 자세한 것은 bit 연산의 원리에 대해 공부를 더 해보시길 바랍니다.






정리


 사실 이더넷 통신을 사용하거나 파싱이니 뭐니 하는 내용들 자체가 어느정도 아두이노에 익숙해지시고 다양한 프로젝트 경험을 해보신 분들이 할만한 내용입니다. 게다가 WizArduino 라는 32bit 보드를 사용하면서, 기존 Arduino 소스처럼 복사 붙여넣기만 해서 실행되는 예제도 아니죠... 익숙치 않으신 분들을 위해서는 지금보다 굉장히 자세하게 써야하지만, 하나의 포스팅에 그렇게 작성하는 것은 쉽지 않네요!

해서, 혹시나 궁금하신 사항들이 있다면 댓글로 연락 주시면 답변 드리도록 하겠습니다 :)




저작자 표시 비영리
신고
댓글
댓글쓰기 폼