아두이노 nodemcu 을 이용해서 기상청에서 날씨을 가져오는 프로그램 소스 공유합니다.


아래의 프로그램을 간단히 설명하면, 

1. 와이파이로 인터넷에 접속한다.

2. 기상청에 접속해서 우리 동네 날짜를 xml로 가져온다.

3. 가져온 xml을 파싱해서 현재 온도, 날씨, 습도를 String에 저장하고 출력한다.


해외 날씨 api을 이용해 날씨 정보를 가져오는 공개된 아두이노 프로그램은 있으나,

국내 기상청 api을 이용해 날씨를 가져오는 프로그램은 찾지 못해서  만들어서 올려봅니다.

소스는 간단하나 oled, lcd, led 등을 이용해 현재 날씨 정보을 다양하고 재미있는 방법으로 표현해 보세요.


필요한 준비물은

5불짜리 nodemcu 하나와 usb 케이블

아래 주소는 구매처

http://ko.aliexpress.com/item/V2-4M-4FLASH-NodeMcu-Lua-WIFI-Networking-development-board-Based-ESP8266/32448662166.html?detailNewVersion=3


소스의 xml 는 아래와 같습니다. 맨뒤에 zone은 동을 숫자로 나타내고 있습니다.

http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1162058500


xml 주소를 가져오는 방법은 아래의 url로 접속하셔서,

시구동을 선택하고 rss을 누르면, 해당 지역의 url 주소를 아실 수 있습니다.

http://www.kma.go.kr/weather/lifenindustry/sevice_rss.jsp?sido=1100000000&gugun=1129000000&dong=1129052500&x=25&y=8



--------------------------- 소스 시작--------------------------


#include <ESP8266WiFi.h>


// 와이파이 ssid을 입력해주세요.

const char* ssid     = "XXXXXXX";

//와이파이 비밀번호를 입력해주세요.

const char* password = "XXXXXX";


const char* host = "www.kma.go.kr";


void setup() {

  Serial.begin(115200);

  delay(10);


  // We start by connecting to a WiFi network


  Serial.println();

  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());

}


int value = 0;


void loop() {


  ++value;


  Serial.print("connecting to ");

  Serial.println(host);

  

  // Use WiFiClient class to create TCP connections

  WiFiClient client;

  const int httpPort = 80;

  //http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1162058500

  

  if (!client.connect(host, httpPort)) {

    Serial.println("connection failed");

    return;

  }

  

  // We now create a URI for the request

//zone을 일종의 지역 정보입니다.


  String url = "/wid/queryDFSRSS.jsp?zone=1162058500";

  

  Serial.print("Requesting URL: ");

  Serial.println(url);

  

  // This will send the request to the server

  client.print(String("GET ") + url + " HTTP/1.1\r\n" +

               "Host: " + host + "\r\n" + 

               "Connection: close\r\n\r\n");

  delay(10);

  

  // Read all the lines of the reply from server and print them to Serial

  String weather_str="";


  //온도

  String wt_temp="";

  //오늘의날씨

  String wt_wfKor="";

  String wt_wfEn="";

  //습도

  String wt_reh="";

  int i=0;

  

  while(client.available()){

    i++;

//라인을 기준으로 문자열을 저장한다.

    String line = client.readStringUntil('\n');


    int temp33= line.indexOf("seq=\"1\"");

    if(temp33>0)

    {

      break;

    }


//온도 xml 에서 파싱    

    int temp= line.indexOf("</temp>");

    if(temp>0)

    {


      String tmp_str="<temp>";

      String wt_temp = line.substring(line.indexOf(tmp_str)+tmp_str.length(),temp);

      Serial.println(wt_temp);  

    }


//날씨 정보 영문으로 가져오기

    int wfEn= line.indexOf("</wfEn>");

    if(wfEn>0)

    {


      String tmp_str="<wfEn>";

      String wt_twfEn = line.substring(line.indexOf(tmp_str)+tmp_str.length(),wfEn);

      Serial.println(wt_twfEn);  

    }


//날씨 정보 으로 가져오기

    int wfKor= line.indexOf("</wfKor>");

    if(wfKor>0)

    {

      String tmp_str="<wfKor>";

      String wt_wfKor = line.substring(line.indexOf(tmp_str)+tmp_str.length(),wfKor);

      Serial.println(wt_wfKor);  

    }


    int reh= line.indexOf("</reh>");

    if(reh>0)

    {

      String tmp_str="<reh>";

      String wt_reh = line.substring(line.indexOf(tmp_str)+tmp_str.length(),reh);

      Serial.println(wt_reh);  

    }

    

  }


  //int ln_num= weather_str.indexOf("\n");

    

  

  Serial.println();

  Serial.println("closing connection");

  delay(20000);

}

--------------------------- 소스 끝 --------------------------

실행결과 화면
-2.6  <---- 현재 온도
援щ쫫 留롮쓬 <--- 현재 날씨 한글이라 깨짐
Mostly Cloudy <---현재 날씨 영문 표기
68 <-- 현재 습도




관련문서:

NodeMCU V1.0 Arduino IDE 환경 구축하기

NodeMCU 소개


  1. 대학생 2016.02.02 14:51

    안녕하세요. 유용하고 좋은 정보 감사합니다. 기상청 파싱에 대해서 검색하다가 글을 보았습니다.
    저는 학교프로젝트로 아두이노로 기상청 정보를 파싱해서 받아오는 기능을 구현하고 있는데요. 그런데 제가 많이 부족해서 궁금한 점이 있어 질문 드립니다.
    nodeMCU라는 기기가 생소한데요, 부끄럽지만 소개 특징을 읽어봤습니다만 잘모르겠습니다. nodeMCU라는 기기는 아두이노의 종류중 하나인 건가요? 저는 '와이파이 사용에 특화된 아두이노'라고 이해했는데 맞는지 모르겠습니다.
    그렇다면 제가 사용하려는 아두이노 uno r3 에서도 인터넷에 연결된 상태(LAN 이용)라면 이 자료를 이용해서 적용할 수 있는것인가요?

    만약 아두이노 우노 r3와 다른점(코딩방법이나 필요한 것)이 있다면 어떤것이 있을까요?

    그리고 본문 정보에서는 현재온도, 현재날씨(한,영), 현재습도 총 4가지 정보를 받아올 수 있는데요, 혹시 다른정보(날짜,시간,최고기온,
    강수확률 등 기상청에서 제공하는 다른정보들)을 받아올 수 도 있나요? 가능하다면 다른 변수를 선언하고 요청하면 되는걸까요?

    감사합니다

    • Favicon of https://ilikesan.com BlogIcon 산좋아해 2016.02.06 11:12 신고

      nodeMCU라는 기기는 아두이노의 종류중 하나인 건가요?
      아두이노의 한 종류는 아닙니다. 아두이노 sdk을 이용할수 있습니다.
      그렇다면 제가 사용하려는 아두이노 uno r3 에서도 인터넷에 연결된 상태(LAN 이용)라면 이 자료를 이용해서 적용할 수 있는것인가요?
      esp8266 에서 사용하는 라이블러리를 사용하는 소스라 바꾸셔야 합니다.
      만약 아두이노 우노 r3와 다른점(코딩방법이나 필요한 것)이 있다면 어떤것이 있을까요?
      일단 GPIO 핀이 틀립니다. MCU 자체도 틀리고요.
      그리고 본문 정보에서는 현재온도, 현재날씨(한,영), 현재습도 총 4가지 정보를 받아올 수 있는데요, 혹시 다른정보(날짜,시간,최고기온,
      강수확률 등 기상청에서 제공하는 다른정보들)을 받아올 수 도 있나요? 가능하다면 다른 변수를 선언하고 요청하면 되는걸까요?
      기상청 rss에서 제공하는 정보는 다양합니다. 기상청 사이트를 방문해 보세요.
      http://www.kma.go.kr/weather/lifenindustry/sevice_rss.jsp

  2. 바른말 2016.02.14 17:06

    능력이 엄청 부럽습니다 .
    라즈베리파이에 웹서버 설치하고 nodeMcu의 wifi로 웹서버에 접속하여 온도습도 저장하는 것 한번 해보고 싶은데 프로그램 실력이 딸려서 못하고 있는데
    능력자 신것 같은데 다음에 시간나면 한번 해보시고 방법 부탁드립니다.

    • Favicon of https://ilikesan.com BlogIcon 산좋아해 2016.02.18 11:45 신고

      취미로 공부하고 있는 아마추어입니다.
      좋게 봐 주셔서 감사합니다.^^
      응원의 메세지로 알고 좀더 신경써서 포스트 올리도록 하겠습니다.

  3. 2017.02.16 20:49

    비밀댓글입니다

  4. 젠토 2017.10.22 18:16

    오래된 게시물에 늦은 질문을 하여 대단히 죄송합니다.
    궁금한 점이 있는데 이 와이파이모듈을 아두이노 우노 보드에 연결하여 날씨 정보 등을 또 다른 기능이 가능하도록 연결이 가능할까요?

지마켓에서 oled(SSD1306 i2c)  을 구매했다.

바로 다음날 배송해 주셔서 감사해서 링크 올립니다.

http://gmkt.kr/gpjM0i

싼 가격을 원하시면 알리익스프레스로 고고.

 

 

 

 

위의 사진 처럼 생겼는데,

128X64 화소이고 무지 작지만, 밝고 선명하다.

이 녀석은 다음과 같이 연결하면 되다.

 

OLED -> 아두이노 핀

VCC -> 5V
GND -> GND
SCL -> A5
SDA -> A4

 

 

아두이노 프로그램에서 hellow word을 출력해 보는 예제는 다음과 같다.

 

 

----- 예제 -----------------
#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);

void draw() {

  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 0, 20, "Hello World!");
}

void setup() {
}

void loop() {

  u8g.firstPage(); 
  do {
    draw();
  } while( u8g.nextPage() );
    delay(1000);
}
------ 예제 ----------------------------

 

 

U8glib 라이블러리을 다운 받는다.

메뉴>스케치> Include library> manage libraris 을 선택하고 "U8glib" 검색하고 인스톨을 누른다.

 

인스톨이 정상적으로 끝났으면 아두이노 프로그램을 재시작한다.

 

https://github.com/olikraus/u8glib/

요기 가면 자세한 설명과 라이블러리를 직접 다운 받아 설치할수도 있다.

꼭 한번 가보시기를 ^^

 

oled "Hellow World!" 라고 나오면 성공이다.

다양한 예제를 제공하니 분석해 보기 바란다.

예제 실행시 주의할 점은 상단부분에서 "U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);" 이부분이 주석 처리 되어 있으면, 주석 제거해줘야 한다.

 

다음에는 nodemcu와 oled을 사용해볼 계획이다.

 

 

 

 

방수형 온도센서 DB18B20 회로구성과 ,

라즈베리파이 기반에서 파이썬을 이용해 온도을 출력하는 프로그램에 대한 강좌을 할까 합니다.


아래 링크 정말 잘 정리되어 있습니다. 하지만 영문이죠? 핵심만 뽑아서 설명하도록 하겠습니다.

해도 한번 꼭 가서 보시기 바랍니다.

https://learn.adafruit.com/downloads/pdf/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing.pdf

 

브레드보드 연결 하는 법은 아래 그림을 참고하세요.

  

 그림을 보면 빨간색선은 3.3V 전압에 연결되어 있고, 

파란색선 그라운드에  이고,

노란색선은 온도 데이타를 전송 받는 선입니다.

저항은 3.3V 에서 4.7K-10K 을 쓰면 되는데, 4.7k가 정석이고 10k도 정상 동작되는 것은 확인했습니다.

 

아래 이미지는 방수형 온도센서 연결한 사진입니다.

위의 회로도와 크게 다르지는 않습니다. 어차피 같은 센서를 이용하는 제품이라 동일 합니다.


 

 

 

 

DS18B20는  특별한 1-wire 직렬 인터페이스 제어 로직 온도 센서 자체 포함 되어 있다고 합니다.


DB18B20은 칩에서 디지털신호로 노란선을 통해서 디지털  데이타를 보냅니다.

그 데이타를 하나의 디바이스로 인식 시키면 데이터값을 일종의 디바이스롤 인식해서 온도값을 가져올수 있다.


아날로그로 온도값을 입력받을 수 있는 센서의 경우는,

라즈베리파이는 별도의 장치가 필요하다.

그이유는 라즈베리파이는 아두이노처럼 ADC(아날로그 디지털 변환기)을  포함하고 있지 못해서,

자세한 내용은 아래 링크 참고.

http://blog.naver.com/warit/10190221742

 


온도센서 값을 읽기 위해 설정하는 법에 대해서 다르겠다.

 

Root 권한으로 라즈베리 관련 설정파일 맨 밑에

/boot/config.txt

아래와 같이 추가하고 리부팅(sudo reboot)해주세요.

dtoverlay=w1-gpio

 

리부팅하고 나서 아래와 같은 명령어를 입력하자.

sudo modprobe w1-gpio

sudo modprobe w1-therm


아래의 명령어로 디렉토리를 이동해 보면 두개의 디렉토리가 있다.

cd /sys/bus/w1/devices

-------------- 인용 ----------------

pi@raspberrypi /sys/bus/w1/devices $ ls -la
total 0
drwxr-xr-x 2 root root 0 May 13 06:16 .
drwxr-xr-x 4 root root 0 May 13 06:16 ..
lrwxrwxrwx 1 root root 0 May 13 06:16 28-02150015bcff -> ../../../devices/w1_bus_master1/28-02150015bcff
lrwxrwxrwx 1 root root 0 May 13 06:16 w1_bus_master1 -> ../../../devices/w1_bus_master1
-------------- 인용 ----------------

 

28-XXXX 로 시작되는 폴더로  이동해서 "w1-slave" 파일의 내용을 확인해 보면,

t=22187 부분이 온도를 나타낸다.  해당 값을 1/1000으로 처리하면 22.187도라는 온도가 나온다.

 

-------------- 인용 ----------------

pi@raspberrypi /sys/bus/w1/devices $ cd 28*
pi@raspberrypi /sys/bus/w1/devices/28-02150015bcff $ cat w1_slave
63 01 55 00 7f ff 0c 10 ec : crc=ec YES
63 01 55 00 7f ff 0c 10 ec t=22187

-------------- 인용 ----------------

 

 

 

센서가 제대루 작동하는지 간단한 방법은 테스트 할수 있다.

온도센서 부분을 손으로 잡으면 인용과 같이 온도가 천천히 올라간다.

-------------- 인용 ----------------
pi@raspberrypi /sys/bus/w1/devices/28-02150015bcff $ cat w1_slave
63 01 55 00 7f ff 0c 10 ec : crc=ec YES
63 01 55 00 7f ff 0c 10 ec t=22187
pi@raspberrypi /sys/bus/w1/devices/28-02150015bcff $ cat w1_slave
91 01 55 00 7f ff 0c 10 4d : crc=4d YES
91 01 55 00 7f ff 0c 10 4d t=25062
pi@raspberrypi /sys/bus/w1/devices/28-02150015bcff $ cat w1_slave
9d 01 55 00 7f ff 0c 10 72 : crc=72 YES
9d 01 55 00 7f ff 0c 10 72 t=25812
pi@raspberrypi /sys/bus/w1/devices/28-02150015bcff $ cat w1_slave
c5 01 55 00 7f ff 0c 10 45 : crc=45 YES
c5 01 55 00 7f ff 0c 10 45 t=28312
pi@raspberrypi /sys/bus/w1/devices/28-02150015bcff $ cat w1_slave
dd 01 55 00 7f ff 0c 10 3b : crc=3b YES
dd 01 55 00 7f ff 0c 10 3b t=29812
pi@raspberrypi /sys/bus/w1/devices/28-02150015bcff $

-------------- 인용 ----------------


 

파이썬언어를 이용해서 온도를 출력하는 프로그램을 작성하겠다.


 

아래는 소스파일 첨부

ds18b20.py

 

 

 

 

필자는 파이썬 프로그램에 대해서 전혀 모른다.

하지만, 포트란,BASIC,펄, C, 자바,php, 기타 등등에 대한 경험을 해보았다.

그래서 이정도 간단한 프로그램  딱보면 감으로 알겠다.


import 를 이용해서 프로그램에 필요한 라이블러리를 블려들인다.

os.system을 이용해서 시스템 명령어를 실행하고,

그밑에는 온도센스의 데이타가 들어 있는, 폴더와 파일에 대해서 선언 되어 있다.


그밑에 두개의 함수가  선언 되어 있는데.

read_temp_raw 함수는  온도센서의 값이 들어 있는 파일을 읽어 들어 문자열로 리턴한다.


read_temp 함수는 read_tem_raw 함수를 호출해서 문자열을 리턴 받고,

온도값이 들어있는 부분 "t=" 뒷 부분을 기준으로 문자열을 배열로 나누고,

그값은 temp_string에 저장한다.

temp_c는 섭씨(C) 온도를 저장하고,

temp_f는  화씨(F) 온도를 저장한 변수이다.

두 온도값은 리턴해준다.

 

일종의 메인프로그램에서 (C에서main)

read_temp 함수를 호출해서 온도값을 리턴받아 1초 간격으로 출력해준다.

 

 

실행해 보면 아래와 같다.


 sudo python ds18b20.py

 

 

 

끝까지 읽어주셔서 감사합니다.


 

다음 포스트는 웹프로그래밍(PHP)을 이용해서 온도센서의 값을 읽어들여  DB(Mysql)에 저장하는 법에 대해서 강좌 하겠다.


 

 

  1. BlogIcon 하소 2015.08.20 15:57

    안녕하세요 라즈베리 초보입니다. 님 블러그 보고 열공하고있습니다. ㅎㅎ ㄳㄳ
    온도센서를 따라하는 도중에 cd /sys/bus/w1/devices폴더로 이동하려니 bus 폴더안에 w1이라는 하위 폴더가 저는 없던데 만들어야하는건가요? 아님 원래 있는데 저만 없는건가요? 너무 초보라 한번 막히니 멘붕이네요 ㅜㅜ

    • Favicon of https://ilikesan.com BlogIcon 산좋아해 2015.08.27 10:25 신고

      온도센서를 인식하지 못하는 것 같습니다.
      설정 부분 다시 확인해 보시구요.
      Root 권한으로 라즈베리파이 관련 설정 다시확인해 보시고요.
      브레인보드쪽 연결 확인해 보세요.
      그래도 안 되면, 아래의 메뉴얼 번역하면서 확인해보세요 ^^
      https://learn.adafruit.com/downloads/pdf/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing.pdf

  2. 김하경 2015.09.05 00:19

    안녕하세요 강좌 너무쉽게 설명되어있어서 넘 좋아요
    한가지 궁금한게 있는데 아파치 웹서버에서 PHP 웹페이지에 GPIO GPIO21 핀의 상태값을 받을수 있는가요?
    <?php
    $re=exec("cat /sys/bus/w1/devices/28-00043e55b9ff/w1_slave" );
    echo "<font style=font-size:30pt align=center> 온도값 : $re </font> " ;
    ?>

    이렇게 온도값을 받고 있는데

    혹시 이렇게 GPIO 상태값 1 or 0 을 받을수 있는가요?

    <?php
    $re=exec("cat /sys/class/gpio/gpio21/value" ) ;
    echo "<font style=font-size:30pt align=center> 상태값 : $re </font> " ;
    ?>

    테스트 해보니깐 빈화면만 출력되네요 권한문제인가요 어떻게 해야하나요 도와주세요

  3. BlogIcon 나그네 2015.11.08 20:29

    먼저 정확하게 온도계를 설치하고
    modprobe w1-gpio
    modprobe w1-therm을 치면 자동으로 만들어지는 것들입니다.

라즈베리파이용 온도센서를 찾다, 방수형 DS18B20 알리익스플레스를 통해서 구매했습니다.

개당 2천원 선 아주아주 착한 가격.

2-3 주동안 인내하면 싼 가격에 구매할수 있습니다.

링크 공개 하겠습니다. 본인은 중국 판매자와 아무관계 없습니다.

http://www.aliexpress.com/snapshot/6596771410.html?orderId=66739600462047


국내에서도 싸게 파는 곳 있네요. 지마켓입니다. 

http://gmkt.kr/goUWXs


 

 

 

 

상품설명  해석으로 대신 하겠다.

-------------------------------------------------

Probe DS18B20 temperature sensor chip using original

DS8B20는  방수 온도 센서 칩을 사용한다.

 

High quality stainless steel pipe anti- rust waterproof package

고품질 스테인레스 파이프는 방수로 녹이 생기지 않는다. 

 
Stainless steel housing (6 * 50mm), lead length 100cm

스테인레스 부분은 (6 * 50mm)이고, 전체길이는 일미터

 
fter rigorous testing each probe individually wrapped

각 상품들은 엄격한 상품 테스트를 받았다.

 
3.0V ~ 5.5V power supply

3.0V~5.5v 전압에서 지원한다.

 
9 to 12 adjustable resolution

9~12개  해결 가능하다

 
Temperature range -55 ° ~ +125 °

온도 측정범위  -55 ° ~ +125 °

 
No external components , the unique single- bus interface
외부 부품 없이 독특한 단일 버스 인터페이스로 동작한다.

 

Output leads : Red (VCC), yellow (DATA), black (GND) (may be have other color,but the output not change)

빨간선은 VCC 이고 노란선은 DATA 전송, 검정색은 GND 그라운이다. (다른 색깔일수도 있지만, output은 변경되지 않는다.)  

-------------------------------------------------

 

그리고 온도 편차에 대해 안 나와 있는데, 대략 +- 0.5도 이다.


아래의 링크로 가보시면, 파이썬 언어 기반에 대한 자세한 강좌를 볼수 있습니다. 

https://learn.adafruit.com/downloads/pdf/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing.pdf

 

DS18B20에 사용법에 대해서 다루겠다.



공부하려 아두이노(http://blog.arduino.cc) 메인 홈페이지에 떠있는 감동적인 글을 보았습니다.

 

원문링크: http://blog.arduino.cc/2015/03/24/having-fun-with-music-in-a-science-class/

 

 

분당경영고등학교에서 물리교사님이 아두이노를 활용해 아이들과 다양한 악기를 만드는 수업을 진행하고 있습니다.

수업은 아래와 같은 단계로 이루어집니다.

1. 각종 센서에 대해서 공부하고.

2. 아누이노 악기를 디자인하고 설계하고.

3.  함께 만들고

4.  아누이노 악기에 대해서 발표합니다.

 

 

 

 

이수업을 진행하는 분당경영고등학교 물리교사님에게 응원의 메세지를 보냅니다.

" 선생님 화이팅 하시고요.

선생님 같은 분이 있어 세상이 살맛 납니다.

지식보다는 인성이 바른 학생들로 가르쳐 주셨으면 합니다."

 

물리교사님이 운영하는 블로그의 해당 링크입니다.

http://wool.pe.kr/220209398449

 

+ Recent posts