반응형


아두이노에 연결된 온도센서의 값을 읽어서 ESP8266과 PHP를 이용하여 MySQL에 저장하는 예제입니다.



2016.  5. 21. 최초작성

2018. 10. 17. 마지막 업데이트




1. 다음 포스팅에 Arduino Uno와 ESP8266 연결하는 방법과 필요한 라이브러리를 설치하는 방법이 소개되어있습니다.

먼저 진행을 해야 합니다.



Arduino Uno에 ESP8266 WiFi 모듈을 연결하여 사용하는 방법

http://webnautes.tistory.com/755





2. 다음 포스팅에 Arduino Uno와 DB18B20 연결 방법과 필요한 라이브러리를 설치하는 방법이 소개되어 있습니다.

먼저 진행을 해야 합니다.



Arduino Uno에서 DS18B20 1-Wire 온도 센서 사용하기

http://webnautes.tistory.com/631





2.  윈도우 또는 리눅스에 아파치 웹서버, MySQL, PHP를 설치합니다.



Ubuntu 16.04에 LAMP ( Apache2, MySQL , PHP7) 설치하는 방법

http://webnautes.tistory.com/1028


Ubuntu 18.04에 LAMP ( Apache2, MySQL , PHP 7) 설치하는 방법

http://webnautes.tistory.com/1185


윈도우 기반 웹 개발 환경 만들기 ( Apache2, PHP, MySQL, PhpMyAdmin )

http://webnautes.tistory.com/1206


Raspberry Pi 3에 LAMP (Linux, Apache, MySQL, PHP) 설치하는 방법

http://webnautes.tistory.com/842





3. 데이터를 저장할 테이블을 생성합니다.


mysql> create database db;
Query OK, 1 row affected (0.00 sec)

mysql> use db;
Database changed
mysql> create table data(num int(10));
Query OK, 0 rows affected (0.01 sec)




4. 데이터베이스에 값을 넣을때 사용할 PHP 파일을 생성하여 다음 내용을 복사하여 붙여넣기 해줍니다.


리눅스

sudo nano /var/www/html/insert_data.php


윈도우

C:\wamp64\www 위치에 insert_data.php 파일 생성



<?php
$con = mysqli_connect("localhost", "MySQL 계정 아이디", "MySQL 계정 패스워드", "사용할 데이터베이스 이름");

if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

  $num = $_GET["num"];

  $sql = "insert into db.data(num) values($num)";
  mysqli_query($con, $sql);

  mysqli_close($con);
?>




5. 다음 아두이노 코드를 업로드 합니다.


#include <OneWire.h>    
#include <DallasTemperature.h>    
#include <string.h>  

#include "ESP8266.h"
#include <SoftwareSerial.h>  
   

#define SSID        "공유기의 SSID"

#define PASSWORD    "공유기의 비밀번호"

#define SERVERIP   "서버 아이피"

 

//SoftwareSerial mySerial(11, 10); /* RX:D11, TX:D10 */

SoftwareSerial mySerial(10, 9); /* RX:D10, TX:D9 */


   
     
//DS18B20 온도 센서의 데이터선인 가운데 핀을 아두이노 3번에 연결합니다.     
#define ONE_WIRE_BUS 3  
     
//1-wire 디바이스와 통신하기 위한 준비    
OneWire oneWire(ONE_WIRE_BUS);    
     
// oneWire선언한 것을 sensors 선언시 참조함.    
DallasTemperature sensors(&oneWire);    
     
//다비아스 주소를 저장할 배열 선언    
DeviceAddress insideThermometer;    
     
     
     
char * floatToString(char * outstr, double val, byte precision, byte widthp){  
char temp[16]; //increase this if you need more digits than 15  
byte i;  
 
temp[0]='\0';  
outstr[0]='\0';  
 
if(val < 0.0){  
  strcpy(outstr,"-\0");  //print "-" sign  
  val *= -1;  
}  
 
if( precision == 0) {  
  strcat(outstr, ltoa(round(val),temp,10));  //prints the int part  
}  
else {  
  unsigned long frac, mult = 1;  
  byte padding = precision-1;  
    
  while (precision--)  
    mult *= 10;  
 
  val += 0.5/(float)mult;      // compute rounding factor  
    
  strcat(outstr, ltoa(floor(val),temp,10));  //prints the integer part without rounding  
  strcat(outstr, ".\0"); // print the decimal point  
 
  frac = (val - floor(val)) * mult;  
 
  unsigned long frac1 = frac;  
 
  while(frac1 /= 10)   
    padding--;  
 
  while(padding--)   
    strcat(outstr,"0\0");    // print padding zeros  
 
  strcat(outstr,ltoa(frac,temp,10));  // print fraction part  
}  
 
// generate width space padding   
if ((widthp != 0)&&(widthp >= strlen(outstr))){  
  byte J=0;  
  J = widthp - strlen(outstr);  
 
  for (i=0; i< J; i++) {  
    temp[i] = ' ';  
  }
 
  temp[i++] = '\0';  
  strcat(temp,outstr);  
  strcpy(outstr,temp);  
}  
 
return outstr;  
}  
 
 
     
void setup(void)    
{    
   
 //시리얼 포트 초기화    
 Serial.begin(9600);    
 
  
/////////////////////////////////////////////////////////////////////////  
 Serial.setTimeout(5000);  
 mySerial.begin(9600);   
 Serial.println("ESP8266 connect");  
 
   
  boolean connected=false;  
  for(int i=0;i<10;i++)  
  {
      if(connectWiFi())  
      {
        connected = true;  
        break;  
      }
  }
    
  if (!connected){while(1);}  
  delay(5000);  
   
  mySerial.println("AT+CIPMUX=0");  
 ///////////////////////////////////////////////////////////////////////////     
      
        
 //1-wire 버스 초기화    
 sensors.begin();    
       
 //발견한 디바이스 갯수    
 Serial.print("Found ");    
 Serial.print(sensors.getDeviceCount(), DEC);    
 Serial.println(" devices.");    
     
 // parasite power 모드일 때에는  2핀(GND와 DQ 핀)만 연결하면 됨.
 Serial.print("Parasite power is: ");     
 if (sensors.isParasitePowerMode()) Serial.println("ON");    
 else Serial.println("OFF");    
       
      
 //버스에서 첫번째 장치의 주소를 가져온다.    
 if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0");     
       
 //버스에서 발견한 첫번째 장치의 주소 출력    
 Serial.print("Device 0 Address: ");    
 printAddress(insideThermometer);    
 Serial.println();    
     
 //데이터시트에서 확인결과 9~12비트까지 설정 가능    
 sensors.setResolution(insideThermometer, 10);    
      
 Serial.print("Device 0 Resolution: ");    
 Serial.print(sensors.getResolution(insideThermometer), DEC);     
 Serial.println();    
}    
     
     
// 온도를 출력하는 함수    
void printTemperature(DeviceAddress deviceAddress)    
{    
 //섭씨 온도를 가져옴    
 float  tempC = sensors.getTempC(deviceAddress);    
       
 Serial.print("Temp C: ");    
 Serial.print(tempC);    
 Serial.print(" Temp F: ");    
       
 //화씨 온도로 변환    
 Serial.println(DallasTemperature::toFahrenheit(tempC));  
 
 
 
    String cmd = "AT+CIPSTART=\"TCP\",\"";  
    cmd += SERVERIP;  
    cmd += "\",80";  
    Serial.println(cmd);  
    mySerial.println(cmd);  
    if(mySerial.find("Error"))  
   {
     Serial.println( "TCP connect error" );  
     return;  
   }
    
 
   char test[20];  
   String temp(floatToString(test,tempC, 2, 0));  
     
    cmd = "GET /insert_data.php?num="+temp+"\r\n";  
    mySerial.print("AT+CIPSEND=");  
    mySerial.println(cmd.length());  
         
      
    Serial.println(cmd);  
      
      
    if(mySerial.find(">"))  
    {
      Serial.print(">");  
      }else  
      {
        mySerial.println("AT+CIPCLOSE");  
        Serial.println("connect timeout");  
        delay(1000);  
        return;  
      }
        
      mySerial.print(cmd);  
      delay(2000);  
      //Serial.find("+IPD");  
      while (Serial.available())  
      {
        char c = Serial.read();  
        mySerial.write(c);  
        if(c=='\r') mySerial.print('\n');  
      }
      Serial.println("====");  
      delay(1000);  
}    
     
//디바이스 주소를 출력하는 함수    
void printAddress(DeviceAddress deviceAddress)    
{    
 for (uint8_t i = 0; i < 8; i++)    
 {   
   if (deviceAddress[i] < 16) Serial.print("0");    
       Serial.print(deviceAddress[i], HEX);    
 }   
}    
     
     
void loop(void)    
{     
 Serial.print("Requesting temperatures...");    
 //sensors.requestTemperatures();   //연결되어 있는 전체 센서의 온도 값을 읽어옴
 sensors.requestTemperaturesByIndex(0); //첫번째 센서의 온도값 읽어옴    
 Serial.println("DONE");    
      
 //센서에서 읽어온 온도를 출력    
 printTemperature(insideThermometer);    
}    
 
 
boolean connectWiFi()  
{  
  //mySerial.println("AT+CWMODE=1");  
    
  String cmd="AT+CWJAP=\"";  
  cmd+=SSID;  
  cmd+="\",\"";  
  cmd+=PASSWORD;  
  cmd+="\"";  
  mySerial.println(cmd);  
  Serial.println(cmd);  
  delay(3000);  
   
  if(mySerial.find("OK"))  
  {
    Serial.println("OK, Connected to WiFi.");  
    return true;  
  }
  else  
  {
    Serial.println("Can not connect to the WiFi.");  
    return false;  
  }
}  





6. 아두이노 IDE에서 툴 > 시리얼모니터를 선택합니다.


공유기에 접속 성공하면 “OK, Connected to WiFi” 메시지가 보입니다.

아두이노에 연결된 DB18B20를 찾았다면 “Found 1 devices”라는 메시지가 보입니다.


이후 온도를 가져오고(Requesting temperatures...Done)

웹서버에 온도를 저장하는 것(GET /insert_data.php?num=온도)을 반복합니다.





7. MySQL을 확인해보면 데이터가 입력되는 것을 볼 수 있습니다.



문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts