아두이노 피지컬컴퓨팅 교구로 활용할 수 있는 실 생할용품 메이킹 프로젝트(워터맨IOT) 여섯번째.

 

1) STA(Station)모드 :  ESP8266이 스마트폰이나 일반기기 처럼 WIFI Client로 작동하는 모드이다.  따라서 다른 WIFI공유기를 통하여 인터넷 접속을 할 수 있는 상태이다.  본 프로젝트에서는 기본적으로 이 STA모드로 인터넷 클라우드 서비스에 접속하고 통신한다.

 

 

 

 

2) AP(Acess Point) 모드 : ESP8266 자신이 AP 즉, 공유기 역할을 하는 모드이다.  따라서 스마트폰 등 다른 기기에서 ESP8266을 공유기로 인식하여 접속할 수 있고 서로 통신할 수 있다. 하지만 ESP8266 자체는 인터넷에 연경되어 있지 않기 떄문에 이를 통해 외부 인터넷에 접속할 수는 없는 상태이다. 외부기기에서 ESP8266에 접속하여 설정값을 지정해 주는 설정기능 등을 구현할 때 사용한다.  

 

 

 

 

 STA(Station) 모드 테스트

 

  1. #include <ESP8266WiFi.h>  
  2. WiFiClient client;   
  3. char  ssid[30] = "pnit";  
  4. char  password [30] = "cointoppnit";  
  5. const char* test_server = "www.naver.com";   
  6. void setup() {  
  7.    Serial.begin(115200);  
  8.    Serial.println("==waterman IOT  START==");  
  9.    WiFi.mode(WIFI_STA);  
  10.    WiFi.disconnect();  
  11.    Serial.println("Try connectting AP ");   
  12.    WiFi.begin(ssid, password);   
  13.    for ( int i= 0; i < 10; i++ ) {  
  14.        Serial.print(".");  
  15.        if ( WiFi.status() == WL_CONNECTED ) {  
  16.           break;  
  17.       }  
  18.       delay(1000);  
  19.     }   
  20.     if ( WiFi.status() != WL_CONNECTED ) {  
  21.        Serial.println("connectting AP-- FAIL ");   
  22.        return;  
  23.     }  
  24.     Serial.println("connectting AP-- SUCCESS ");  
  25.     if (client.connect(test_server, 80)) {   
  26.         Serial.println("Test Server connected ");   
  27.         client.print("GET ");   
  28.         client.print("HTTP/1.1\r\n");  
  29.         client.print("Host: " + String(test_server) + "\r\n");   
  30.         client.print("Connection: close\r\n\r\n");   
  31.         delay(500);   
  32.         String line= client.readString();  
  33.         Serial.println(line);   
  34.         client.stop();   
  35.      }  
  36.     else {  
  37.          Serial.println("Test Server connect FAIL");   
  38.     }  
  39. }  
  40. void loop() {  
  41. }  

 

3~4  line:  인터넷에 연결하기 위해 접속하고자 하는 공유기의 명칭과 password를 지정
5     line:  인터넷으로 접속하고자 하는 서버 주소
9     line:  WIFI모드를 STA 모드로 지정
10    line:  WIFI 초기화
12    line:  AP(공유기)에 접속하기
13~19 line:  AP접속상태가 정상이 될때 까지 재시도 ( 10회 재시도)
20~24 line:  AP접속 성공여부 확인
25   line:  인터넷상의 서버 접속하기 (서버URL, 포트번호 80:웹서비스 )
27~30 line:  접속된 서버에 http 데이터 전송 (웹브라우저에서  서버로 전송하는 데이터 형식)
32~33 line:  서버에서 응답되는 데이터를 받아 시리얼 모니터로 표시해 보면 다음과 같음


HTTP/1.1 302 Moved Temporarily
Server: NWS
Date: Sun, 16 Sep 2018 06:06:53 GMT
Content-Type: text/html
Connection: close
Location: https://www.naver.com/err/notfound.html
Vary: Accept-Encoding,User-Agent

<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center> NWS </center>
</body>
</html>

 

위와 같이 html형식 데이터가 포함된 응답이 되돌아 오는데 웹브라우저에서는 이를  보기좋게 화면에 표시하는 것임.

 

 

 

 

AP(Access Point)모드 테스트

 

  1. #include <ESP8266WiFi.h>  
  2. #include <ESP8266WebServer.h>  
  3. ESP8266WebServer server(80);   
  4. const char *ap_ssid = "WatermanIOT_1";  
  5. const char *ap_pass = "";  
  6.   
  7. void procAProot() {  
  8.    String strHtml = "<!DOCTYPE html><head><meta name='viewport' content='width=device-width,initial-scale=1.0' /></head>";  
  9.    strHtml = strHtml+  "<form action='/setting' method='POST'><table width=100%><tr><td align=center><h3> Setting Waterman IOT</h3><br></td></tr>";  
  10.    strHtml = strHtml+ "<tr><td>ID: <input type=text name='ID' /><br></td></tr>";   
  11.    strHtml = strHtml+ "<tr><td>Password: <input type=text name='PW' /><br></td></tr><tr><td align=center> <input type=submit value='confirm' /></td></tr></table></form>";   
  12.    server.send(200,"Text/html",strHtml);  
  13. }  
  14.   
  15. void procAPsetting() {  
  16.   server.send(200,"Text/html","<br><h1>Registered OK!<h1>");  
  17.   String inputID = server.arg("ID");  
  18.   String inputPW = server.arg("PW");  
  19.   Serial.print("procAPsetting ID=");  
  20.   Serial.print(inputID .c_str());  
  21.   Serial.print("=,PW=");  
  22.   Serial.print(inputPW.c_str());    
  23.   Serial.println("====");  
  24. }  
  25. void setup() {  
  26.    Serial.begin(115200);  
  27.    Serial.println("==waterman IOT  START==");  
  28.    WiFi.mode(WIFI_AP);  
  29.    Serial.println("strart AP MODE ");  
  30.    WiFi.softAP(ap_ssid,ap_pass );  
  31.    IPAddress myIP = WiFi.softAPIP();  
  32.    Serial.print("AP mode ip=");  
  33.    Serial.println(myIP);  
  34.    server.on("/",procAProot);  
  35.    server.on("/setting",procAPsetting);  
  36.    server.begin();  
  37.    Serial.println("AP mode Server start");   
  38. }  
  39.   
  40. void loop() {  
  41.    server.handleClient();  
  42.    delay(500);  
  43. }  

 

7~13  line:  웹서버의 역할을 정의하는 모듈. 데이터를 입력하기 위한 화면을 출력한다.
8~11 line: 출력될 화면을 HTML형식으로 작성해서 strHTML에 저장
12  line: 웹서버로서 데이터를 전송한다 ( 코드, 형식,전송할 데이터 )
15~24 line:  웹서버의 역할을 정의하는 모듈. 입력된 데이터를 처리한다.
16 line: 웹서버에서 데이터를 잘 전송받았다는 메시지를 응답한다. 
17 line: 입력데이터 중에서 name이 ID인 항목의 데이터를 받아 inputID라는 이름으로 저장
18 line: 입력데이터 중에서 name이 PW인 항목의 데이터를 받아 inputPW라는 이름으로 저장
19~23 line:  String을 변환하여 시리얼 모니터에 출력
28  line:  WIFI mode를 AP모드로 지정
30 line: 기동될 AP의 SSID(명칭)과 password를 지정. 스마트폰으로 WIFI검색해 보면 이 SSID 명칭이 접속대상 공유기LIST에 표시된다. 따라서 주변의 다른 AP들의 명칭과 중복되지 않는 고유한 이름으로 지정해 주어야 한다.
31 line: AP 자신의 IP Address를 읽어낸다. ESP8266의 경우 192.168.4.1 이라는 주소가 기본적으로 할당되므로 스마트폰에서 AP에 접속한 후 웹브라우저로 http://192.168.4.1 로 접속하면 본 AP에 웹서버기능으로 접속할 수 있게 된다.
34 Line: 웹서버로서의 기능을 정의한다. 아무 지정없이 접속하면 procAProot라는 함수를 호출하여 수행하라는 의미이다.(  7~13 line 기능) 
35 Line: 웹서버로서의 기능을 정의한다. /setting으로 접속하면 procAPsetting이라는 함수를 호출하여 수행하라는 의미이다.( 15~24 line 기능) 
36 line: 웹서버 기능 Start
41 line: 접속된 Client 단말로부터 입력된 데이터를 처리한다.

 

 

 

아두이노 피지컬컴퓨팅 교구로 활용할 수 있는 실 생할용품 메이킹 프로젝트(워터맨IOT) 다섯번째.

 

 온습도 센서

 

 

 

 

 

  1. #include "DHT.h"  
  2. #define DHTTYPE DHT11    
  3. #define DHTPIN D6  
  4. DHT dht(DHTPIN , DHTTYPE);  
  5. int temp;  
  6. int humid;  
  7.   
  8. void setup() {    
  9.    Serial.begin(115200);  
  10.    dht.begin();  
  11. }  
  12.   
  13. void loop() {  
  14.     temp  = dht.readTemperature();  
  15.     humid = dht.readHumidity();  
  16.     Serial.print("temp="); Serial.print(temp);  
  17.     Serial.print(",humid="); Serial.println(humid);     
  18.     delay(1000);  
  19. }  

 

 1) 필요라이브러리 : DHT 라이브러리
   - IDE 스케치 메뉴 -> 라이브러리 포함하기 -> 라이브러리관리하기 화면에서"DHT" 를검색하여 설치
   - ”Adafruit_Sensor.h: No such file or directory” 에러가 발생하면 다음 사이트에서 zip파일을 다운로드 받아 [스케치] -> [라이브러리포함하기]->[.zip라이브러리추가]메뉴에서 설치
       https://github.com/adafruit/Adafruit_Sensor

 2) DHT.h 해더파일 include

 3) 센서가 연결된 핀번호( Digital 6번핀) 와 센서타입을 지정

 4) 센서 초기화    

 5) 센서값이 필요할 때 eadTemperature() 함수로 온도를, readHumidity() 함수로 습도값을 integer로 읽어 낼 수 있다.

 

 

 

 

조도 센서

 

 

 

 

 

  1. #include <BH1750.h>  
  2. BH1750 lightMeter;  
  3. uint16_t lux;  
  4.   
  5. void setup() {  
  6.   Wire.begin();  
  7.    Serial.begin(115200);  
  8.    lightMeter.begin();  
  9.  }  
  10.   
  11.   
  12. void loop() {  
  13.     lux = lightMeter.readLightLevel();  
  14.     Serial.print("lux="); Serial.println(lux);  
  15.     delay(1000);  
  16. }  

 

 

 1) 필요라이브러리 : BH1750
   - https://github.com/claws/BH1750  사이트에서 zip파일을 다운로드 받아 [스케치] -> [라이브러리포함하기]->[.zip라이브러리추가]메뉴에서 설치
  
 2) BH1750.h 해더파일 include

 3) 본 센서는 I2C방식으로 데이터를 전송하므로 별도로 핀번호를 지정할 필요는 없다.( D1 Mini에는 D1,D2핀이 이미 할당 되어 있음 )

 4) 센서 초기화    

 5) 센서값이 필요할 때 readLightLevel()함수로 조도값을 읽는다. BH1750조도센서에서는 조도값을 LUX단위로 변환해서 보내주기 때문에 별도 변환작업 없이 LUX값으로 사용할 수 있다.

 

 

 

토양수분센서

 

 

 

  1. #include <Wire.h>  
  2. int pinPower = D5;   
  3. int moist;  
  4. int moistr;  
  5. void setup() {  
  6.    Serial.begin(115200);  
  7. }  
  8. void loop() {  
  9.     Wire.begin();  
  10.     digitalWrite(pinPower, HIGH);  
  11.     delay(500);  
  12.     moistr = analogRead(A0);  
  13.     moist = map(moistr,1023,0,0,100) ;   
  14.     digitalWrite(pinPower, LOW);  
  15.     Serial.print("moist="); Serial.println(moist);  
  16.      delay(1000);  
  17. }  

 

 

 1) 필요라이브러리 : 없음
    - 토양수분센서는 두 전극사이의 저항값을 측정하는 방식이므로 별도 라이브러리 불필요

 2) 전극사이의 저항값을 측정하기 위해서는 전압을 가해 주어야 하는데, 이 전압을 항상 가해 전류가 계속 흐르면 구리로된 전극이 부식될 수 있고 불필요하게 전력이 낭비된다. 따라서 토양수분을 측정할 때에만 D5 핀에 전압을 가해준다. (line10)
  
 3) A0 핀을 통해 저항값을 측정하는데 이 값은 0 ~ 1023 사이의 값이다.

 4) 이 0~1023 사이의 저항값을 100에서 0의 수분량값으로 mapping한다.

 

 

 

 

 센서통합테스트

 

 

 

  1. #include <Wire.h>  
  2. #include <BH1750.h>  
  3. BH1750 lightMeter;  
  4. #include "DHT.h"  
  5. #define DHTTYPE DHT11    
  6. int pinPower = D5;   
  7. int pinRelay = D7;   
  8. #define DHTPIN D6  
  9. DHT dht(DHTPIN, DHTTYPE);  
  10. uint16_t lux;  
  11. int temp;  
  12. int humid;  
  13. int moist;  
  14. int moistr;  
  15. long time_blink = 0;  
  16. int  flag_blink =  0;  
  17.   
  18. void procReadSensors(){  
  19.     digitalWrite(pinPower, HIGH);  
  20.     delay(500);  
  21.     for ( int i= 0; i < 30; i++ ) {  
  22.       delay(100);  
  23.       temp  = dht.readTemperature();  
  24.       humid = dht.readHumidity();  
  25.       if ( temp < 100 && humid < 101 ) break;  
  26.     }  
  27.     lux = lightMeter.readLightLevel();  
  28.     moistr = analogRead(A0);  
  29.     moist = map(moistr,1023,0,0,100) ;   
  30.     digitalWrite(pinPower, LOW);  
  31.     Serial.print("temp="); Serial.print(temp);  
  32.     Serial.print(",humid="); Serial.print(humid);  
  33.     Serial.print(",lux="); Serial.print(lux);  
  34.     Serial.print(",moist="); Serial.println(moist);  
  35. }  
  36. void setup() {  
  37.    Wire.begin();  
  38.    pinMode(pinPower, OUTPUT);  
  39.    digitalWrite(pinPower, LOW);  
  40.    pinMode(pinRelay, OUTPUT);  
  41.    digitalWrite(pinRelay, LOW);  
  42.    pinMode(LED_BUILTIN, OUTPUT);    
  43.    lightMeter.begin();  
  44.    dht.begin();  
  45.    Serial.begin(115200);  
  46.    Serial.println("==waterman IOT  START==");  
  47. }  
  48. void loop() {  
  49.   if ( millis() - time_blink  > 1000 * 3 ) {  
  50.        procReadSensors();  
  51.       if ( flag_blink == 1 ) {  
  52.          digitalWrite(LED_BUILTIN, HIGH);  
  53.          digitalWrite(pinRelay, HIGH);  
  54.          flag_blink = 0;  
  55.       }  
  56.       else {  
  57.          digitalWrite(LED_BUILTIN, LOW);  
  58.          digitalWrite(pinRelay, LOW);  
  59.          flag_blink = 1;   
  60.       }  
  61.       time_blink = millis();  
  62.   }  
  63. }  

 

 

18~35 line:  전체 센서값들을 읽는 기능들을 모아 별도 함수로 설정
21~26 line:  온습도 센서값이 비정상으로 읽히는 현상이 있기 때문에 정상적인 값이 읽힐 때까지 반복.
49~62 line:  3초 간격으로 내장LED 를 깜박이고 워터펌프의 전원을 공급하여 가동시킨다.

 

따라서 본 프로그램으로 워터맨IOT 모듈에 장착된 온습도센서,조도센서,토양수분센서와 워터펌프 전원장치가 제대로 작동되는지 확인할 수 있다. 

 

 


 

아두이노 피지컬컴퓨팅 교구로 활용할 수 있는 실 생할용품 메이킹 프로젝트(워터맨IOT) 네번째

 

 

 

 

 

1)조도센서 : 빛의 세기를 측정해서 LUX단위 값을 I2C방식으로 값으로 보내주는데 D1-mini 보드의 SCL신호용 핀은 D1, SDA신호용 핀은 D2 이므로 이에 맞추어 연결한다.  

 

2)토양수분센서 : 필요시 D5핀으로 HIGH신호를 보내 5V전압을 가해주면 전류가 흐르는데  토양의 수분함유 정도에 따라 저항값이 바뀌므로 흐르는 전류량이 바뀌게 된다. 이 전류량을 A0핀을 통해 측정함 으로써 토양의 수분량을 가늠해 볼 수 있다.   

 

3)온습도센서 : 온도와 습도를 측정해서 D6 핀으로 전송한다.
     
4)셋팅모드 스위치 : 필요시 스위치를 누르면 D3핀이 GND에 연결( LOW신호가 전달)되어 인터럽트가 발생된다.   

 

5)펌프전원 제어회로  : 
   -MOSFET :  G(Gate)에 전압을 가해주면 D(Drain)과 S(Source) 사이가 연결되어 전류가 흐르는 특성을 가진 반도체. 즉 릴레이와 비슷한 기능으로 사용할 수 있다.
   -따라서 필요시 MOSFET G에 연결된 D7핀에 전압을 가해 주면  MOSFET D->S가 연결되므로 워터펌프에 전류가 흐르게 된다.
   -워터펌프는 일종의 모터로서 ON/OFF시 역전류가 발생될 수 있는데 이 역전류가 보드에 흐르지 않도록 하기 위해 다이오드를 연결하여 역전류룰 by-pass시킨다.   

 

 

 

배선작업을 간편하게 하고 접촉불량을 줄이기 위해 본 프로젝트 전용으로 제작된 PCB.

 

 

 

 

전용 PCB에 위와 같이 부품을 배치하고 납땜하여 회로를 구성한다.

 

 

 

 

 

+ Recent posts