2017년 2월 1일 수요일

[Arduino] 온습도센서 값을 mysql에 저장

[ 출처 : http://blog.naver.com/sealclear/ ]

[정보]
 - DHT11 온습도센서
 - DHT 라이브러리를 추가하였음
 - 이더넷 쉴드를 장착함.
 - PHP사용하여 DB에 온습도 값 저장
 - MYSQL 테이블 세팅 







[증상 그리고 시도해본 것들]
 - 웹페이지에 접속할 때마다 db에 0값이 들어감
 - 자바스크립트로 자동 refresh 기능을 넣었는데... refresh될 때마다 db에 0값이 들어감
 - 자바스크립트 문제라 판단하여 자바스크립트 소스를 삭제하고 수동으로 refresh를 해보면 똑같이 db에 0이 들어간다.
 - 웃긴 건 php insert 쪽 쿼리문에 if문을 삽입하여 온습도 변수 값이 0인경우 쿼리문을 삽입하지 마라는 조건을 넣었는데... 그 조건을 넣으면 db에 아무런 값이 입력되지 않음.
   근데 지금은 됨... ㅡ ㅅ ㅡ... 저기서 추측컨데 아두이노에서 그럼 0을 보내는건가? 해서 아두이노 소스에 리딩값이 0이면 보내지 마 라는 조건문을 넣었지만 실패...
 - 커넥시간으로 인하여... 즉 온습도 값을 db에 삽입해, 그리고 소팅해서 맨 마지막 레코드를 출력해라는 쿼리가 있는데.. 두번째 쿼리인 경우 시간이 걸린다.. 근데.. 소팅이 완
   료되기 전에 다음 문장을 읽는다면.. 로스가 생기기때문에 0이들어간다고 생각하여 sleep문을 삽입하여 딜레이를 줬었다.. 그래도 db에 여전히 0값이 들어갔었었다...
 - php안에 전역변수와 함수를 만들고  소팅해서 맨 마지막 레코드를 읽을 때 0이 아닌것을 읽어라 라는 소스를 만들었었는데... 함수 외부에 있는 전역변수는 결론적으로 loop
   되는 문장안에 있어서 언젠가는 값이 날라가게 되어 있다... 그래서 슈퍼 전역변수를 사용하려고 했는데... 생각해보면... db에 원인을 알수 없지만 0이 들어간다.. 그런데 해
   결을 못하겠다... 그래서... 0이 아닌것을 읽곘다... 이러면... 트러블슈팅을 하는게 아니라.. 회피하는거라서... 이 방법은 아니라고 생각하고 포기함



[결론]
 - 웹페이지 refresh 마다 db에 0이 들어가는 문제가 해결되었음



[소스]
- 아두이노-
#include "DHT.h"  //DHT 온습도 센서 라이브러리 사용
#include <SPI.h>
#include <Client.h>
#include <Ethernet.h>
#define DHTPIN 2        //디지털 2번 핀 사용
#define DHTTYPE DHT11   // DHT11 사용
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0xF1, 0x67 };
char server[] = "192.168.0.222"; //접속할 서버 주소 APMSETUP이 실행중인 컴퓨터의 ip
IPAddress ip(192,168,0,215);     //아두이노에 부여하는 ip (고정ip부여함)
IPAddress gateway(192,168,0,1);
IPAddress subnet(255,255,255,0);
EthernetClient client;
DHT dht(DHTPIN, DHTTYPE);  //DHT 라이브러리에 포함된 함수 형태정의
void setup() {
  dht.begin();  //온습도 센서 동작시작
  Serial.println("Sensor Ready");

  Ethernet.begin(mac, ip, gateway, subnet); //이더넷 연결 시작
  Serial.begin(9600);  //시리얼 통신 시작
  delay(1000);
  Serial.println("connecting...");
}
void loop() {
  int humidity = dht.readHumidity();         //습도 읽어
  int temperature = dht.readTemperature();   //온도 읽어
  if(humidity!=0 && temperature!=0) //온습도가 0이면 MYSQL에 값 보내지 마
  {
    if (client.connect(server, 80)) {   // Http 요청 헤더
      client.print( "GET /test6.php?"); //읽을 PHP 파일
      client.print("humidity=");
      client.print( humidity );
      client.print("&&");
      client.print("temperature=");
      client.print( temperature );      //여기까지는 PHP에서 받기로한 데이터들이다
      client.println( " HTTP/1.1");
      client.println( "Host: 192.168.0.222" ); //요청을 보낼 서버의 주소
      client.println( "Content-Type: application/x-www-form-urlencoded" );   
      client.println( "Connection: close" );
      client.println();
      client.stop();
      Serial.print("Current humdity = "); 
      Serial.print(humidity);
      Serial.print("%  ");
      Serial.print("temperature = ");
      Serial.print(temperature);
      Serial.println("C  ");
      Serial.println("OK");
    }  
  }
  delay(5000); //5초에 한번씩 센서 리딩
}

-php-
<?php
  //php info
  $mysql_hostname = 'localhost';
  $mysql_username = 'root';
  $mysql_password = 'apmsetup';
  $mysql_database = 'arduino';

  //DB연결
  $connect = new mysqli($mysql_hostname, $mysql_username, $mysql_password, $mysql_database);
  //DB연결 확인
  if($connect->connect_errno){
 echo '[연결실패] : '.$connect->connect_error.'<br>';
  } else {
 echo '[연결성공]<br>';
  }
   $humidity = $_GET['humidity'];         //습도 읽어와
   $temperature = $_GET['temperature'];   //온도 읽어와
 
   if($humidity!=0){    //온습도 값을 DB에 삽입하는 쿼리
    $query = "insert into temp(humidity, temperature) values('$humidity', '$temperature')";
    $connect->query($query);  //쿼리실행
   }
 
   do {  //맨 마지막 레코드를 읽는 쿼리
 $query3 = "select * from temp order by no desc limit 1;";
    $result = $connect->query($query3);  //쿼리실행
    $row = mysqli_fetch_object($result); //실행된 쿼리값을 읽음
   } while($row->humidity == 0);

   echo date("Y-m-d H:i:s") . "<br />\n";  //날짜와 시간 표시
   echo "$row->no  ";
   echo "$row->humidity  ";
   echo "$row->temperature";
   if($row->temperature>27) { //온도가 27도 넘으면 경보음 울림(로컬 컴퓨터 하단경로에 MP3파일 넣을 것)
 echo '<embed src="c:\test.mp3" loop=-1> </embed>';  
   }

 //하단 자바스크립트: 웹페이지 자동 REFRESH기능
?>
<script language='javascript'>
  window.setTimeout('window.location.reload()',6000); //1초마다 리플리쉬 시킨다 1000이 1초가 된다.
</script>

댓글 없음:

댓글 쓰기