[출처 : http://arduinotronics.blogspot.kr/ ]
Build your own IOT service! Collect sensor data and send it to a web/database server.
Today's project uses an Arduino equipped with a Ethernet shield, and a DHT-11 temperature / humidity sensor.
Arduino UNO
Arduino Ethernet Shield
DHT-11 Module
The Arduino reads the DHT-11, and submits the data to a php script on a hosted web server. That php page inserts the data into a mySQL database, and another php page creates a web page displaying the data as you can see below.
(ESP8266 / BME280 Version)
(UNO / WiFi BME280 Version)
- Arduino 부분
It's Alive, It's Alive. Ok, sounds better if done with a Dr. Frankenstein accent, but the Arduino WiFi wireless weather Server is alive. Starting with a Arduino UNO, we then stacked a Arduino WiFi shield, a adafruit Lithium Polymer battery shield, and a Sparkfun Protoshield with a Embedded Adventures BME280 breakout and a 3.3v - 5v level shifter. A 5v solar panel is on it's way to keep this charged,
Arduino UNO
Arduino WiFi
Adafruit LIPO
Sparkfun Protoshield
Embedded Adventures BME280 (schematics)
Embedded Adventures Level Shifter
Code (Video below)
#include <SPI.h>
#include <WiFi.h>
#include <BME280_MOD-1022.h>
#include <Wire.h>
IPAddress dns(192, 168, 254, 254);
IPAddress ip(192, 168, 254, 16);
IPAddress gateway(192, 168, 254, 254);
IPAddress subnet(255, 255, 255, 0);
float temp, humidity, pressure, pressureMoreAccurate, tempF, inHg, rH;
double tempMostAccurate, humidityMostAccurate, pressureMostAccurate;
char ssid[] = "your ssid"; // your network SSID (name)
char pass[] = "your password"; // your network password
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
WiFiServer server(80);
// print out the measurements
void printCompensatedMeasurements(void) {
char buffer[80];
temp = BME280.getTemperature();
humidity = BME280.getHumidity();
pressure = BME280.getPressure();
pressureMoreAccurate = BME280.getPressureMoreAccurate(); // t_fine already calculated from getTemperaure() above
tempMostAccurate = BME280.getTemperatureMostAccurate();
humidityMostAccurate = BME280.getHumidityMostAccurate();
pressureMostAccurate = BME280.getPressureMostAccurate();
Serial.print("Temperature ");
tempF = tempMostAccurate * 1.8 + 32.0;
Serial.print(tempF);
Serial.print(" ");
Serial.print(char(176));
Serial.println("F");
Serial.print("Humidity ");
rH = humidityMostAccurate;
Serial.print(rH);
Serial.println(" %");
Serial.print("Pressure ");
inHg = pressureMostAccurate * 0.0295299830714;
Serial.print(inHg, 2);
Serial.println(" in. Hg");
}
void setup() {
Wire.begin();
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while (true);
}
String fv = WiFi.firmwareVersion();
if ( fv != "1.1.0" )
Serial.println("Please upgrade the firmware");
// attempt to connect to Wifi network:
WiFi.config(ip, dns, gateway, subnet);
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
server.begin();
// you're connected now, so print out the status:
printWifiStatus();
}
void loop() {
uint8_t chipID;
chipID = BME280.readChipId();
// find the chip ID out just for fun
//Serial.print("ChipID = 0x");
//Serial.print(chipID, HEX);
// need to read the NVM compensation parameters
BME280.readCompensationParams();
// Need to turn on 1x oversampling, default is os_skipped, which means it doesn't measure anything
BME280.writeOversamplingPressure(os1x); // 1x over sampling (ie, just one sample)
BME280.writeOversamplingTemperature(os1x);
BME280.writeOversamplingHumidity(os1x);
// example of a forced sample. After taking the measurement the chip goes back to sleep
BME280.writeMode(smForced);
while (BME280.isMeasuring()) {
Serial.println("Measuring...");
delay(50);
}
Serial.println("Done!");
// read out the data - must do this before calling the getxxxxx routines
BME280.readMeasurements();
// Example for "indoor navigation"
// We'll switch into normal mode for regular automatic samples
BME280.writeStandbyTime(tsb_0p5ms); // tsb = 0.5ms
BME280.writeFilterCoefficient(fc_16); // IIR Filter coefficient 16
BME280.writeOversamplingPressure(os16x); // pressure x16
BME280.writeOversamplingTemperature(os2x); // temperature x2
BME280.writeOversamplingHumidity(os1x); // humidity x1
BME280.writeMode(smNormal);
while (1) {
while (BME280.isMeasuring()) {
}
// read out the data - must do this before calling the getxxxxx routines
BME280.readMeasurements();
printCompensatedMeasurements();
delay(2000); // do this every 5 seconds
Serial.println();
// listen for incoming clients
WiFiClient client = server.available();
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// output the value of each sensor
client.print("Temperature ");
client.println(tempF);
client.print("°");
client.print("F");
client.println("<br />");
client.print("Humidity ");
client.println(rH);
client.print(" %");
client.println("<br />");
client.print("Pressure ");
client.println(inHg);
client.print(" in. Hg");
client.println("<br />");
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disonnected");
}
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
- 서버 설정 [Source]
Last week we connected a ICStation BME280 temperature / humidity / barometric pressure sensor to a a ICStation NodeMCU ESP8266. We displayed the collected data (along with Dew Point and Heat Index calculations) in the serial monitor.
This week we modified the sketch to post those variables to a linux server (could be your own local Raspberry Pi) running MySQL and PHP. We have it set to take a reading every 30 seconds, and post the data to a php page that inserts the data into the MySQL database. The index page displays a table of that data. The time and date stamp has been modified to display the data in the timezone of the location of the sensor. We are working on live gauges and graphs to display this data in real time.''
See the live data at http://theiot.zone/templog/
All code can be downloaded from https://drive.google.com/open?id=0ByRIq5k2wjcSXzVvamZ1dk9yQVU
Thanks to Nuno Santos and his tutorial at https://techtutorialsx.com/2016/07/21/esp8266-post-requests/ for some fine tuning of my code.