Arduino schéma - arduino.sk

Meteostanica - Webclient

Kompletné projekty s návodom a zdrojovým kódom
Príspevky: 26
Registrovaný: Uto 23. Dec 2014 2:15:50

Meteostanica - Webclient

Poslaťod martinius96 » Sob 03. Jún 2017 0:50:49

Ahojte, prinášam vám projekt, s ktorým som bojoval veľmi dlho, najmä s HTTP requestom, ako ho správne zostaviť no už je mi to jasné a po uistení sa, že všetko funguje ako má vám prinášam návod, ako vykonať správy HTTP request na stránku s trošku komplexnejším konceptom projektu.
Moja meteostanica bola vyvinutá ako taký test po kúpe Arduina. Časom sa k tomu pridal Ethernet Shield a chcel som vyskúšať niečo automatizovať smerom do internetu niečo na štýl IoT, i keď vieme, že toto nie je MQTT ale simple HTTP request, ktorým môžeme istú časť automatizovať. Domácnosť bude mať svoj web, prípadne subdoménu, napríklad domacnost336.firmavytvarajucaautomatizaciu.sk.

Čo je poslaním projektu? Čo sa naučím?
- monitorovať teploty v domácnosti (vonkajšiu i vnútornú)
- vlhkosť,
- atmosférický tlak
- uložiť namerané dáta do MySQL databázy cez .PHP súbor s Arduinom v režime Webclient a to v pravidelnom cykle.

Čo budeme na projekt potrebovať? -->
Obrázok
Arduino (UNO),
Obrázok
Ethernet Shield W5100,
Obrázok Obrázok
2x DS18B20 (indoor a outdoor vyhotovanie),
Obrázok
DHT12 (meranie tlaku, odporúčam DHT22 je presnejší a meria vlhkosť až do 100%, tento čínsky len do 85%),
Obrázok
BMP280 alebo BME280 (meranie tlaku,(teploty), jeden z nich má aj merač vlhkosti)

Schéma zapojenia
Obrázok

Kód s komentármi k zapojeniu
Kód: Vybrať všetko
#include <OneWire.h>                 //KNIZNICA ONEWIRE PRE VYUZITIE ONEWIRE ZBERNICE
#include <DallasTemperature.h>       //KNIZNICA PRE TEPLOTNE CIDLA DS18B20
#define ONE_WIRE_BUS 6               //DEFINICIA PINU AKO ZBERNICE PRE ONEWIRE ZARIADENIA.. TU ZBIERAME UDAJE
OneWire oneWire(ONE_WIRE_BUS);       //ONEWIRE ČÍTAŤ IBA NA PORTE DEFINOVANOM VYSSIE
DallasTemperature sensors(&oneWire); //PRIRADENIE SENZOROV DALLAS DS18B20 NA ONEWIRE ZBERNICU
#include <SPI.h>                     //KNIZNICA SPI.H, PODPORUJE AJ I2C PRIPOJENIA PRE BMP280
#include <DHT12.h>                   //KNIŽNICA NA SENZOR DHT12 PRE ZAZNAM VLHKOSTI
#include "Adafruit_BMP280.h"         //LOKALNA KNIZNICA SENZORA BMP
#include <Ethernet.h>                //KNIZNICA ETHERNET.H PRE MOZNOST VYUZITIA ETHERNET SHIELDU
#define Hostname "Meno zariadenia v sieti"            //DEFINICIA MENA V SIETI
Adafruit_BMP280 bmp;                 // BMP280 NA ZBERNICI I2C
byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };            //MAC ADRESA --> VOLITELNA
char server[] = "www.mojastranka.sk";      //ADRESA WEBSERVERA (MOZE BYT AJ IP ADRESA, AK NEVYUZIVA DNS)
IPAddress ip(192, 168, 1, 100);                               //IP ADRESA ZARIADENIA V SIETI V LOKALNEJ SIETI
EthernetClient client;                                          //SPUSTENIE ETHERNETU AKO CLIENTA
DHT12 dht12;                                                    //INICIALIZACIA SENZORU DHT12
void setup() {                                                  //FUNKCIA NA DEFINICIU VSTUPOV A VYSTUPOV ZAPNUTIE
  sensors.begin();                                              //START SENZOROV POD ONEWIRE (DALLASTEMPERATURE)
  bmp.begin();                                                  //SPUSTENIE SNIMACA BMP280
  delay(2000);                                                  //POZDRZANIE PROGRAMU 2 SEKUNDY POKYM SA INICIALIZUJE BMP280 a SENZORY
  Serial.begin(9600);                                           //SPUSTENIE SERIOVEJ LINKY NA CITACIU RYCHLOST 9600
  while (!Serial) {
    ;                                                           //CAKA POKYM SA SERIOVY PORT NEZAPNE
  }



}

void loop() {                                      //ZACIATOK SLUCKY
  if (Ethernet.begin(mac) == 0) {                  //V PRIPADE ZLYHANIA NASTAVENIA MAC ADRESY VYPIŠ
    Serial.println("Chyba konfiguracie cez DHCP"); //SERIOVY VYPIS CHYBY KONFIGURACIE DHCP
    Ethernet.begin(mac, ip);                       //NASTAVENIE IP A MAC ADRESY PRE ETHERNET MODUL
  }
                             
  if (client.connect(server, 80)) {               // AK SA NAPOJI NA SERVER NA PORTE 80 (HTTP)
    sensors.requestTemperatures();                //VYZIADANIE HODNOT ZO SENZOROV
    Serial.println("Pripojenie uspesne na webserver"); //VYPIS NA SERIOVU LINKU
    client.print("GET /add.php?temp1=");         //ZAČIATOK HTTP REQUEST --> client.print GET METODOU s oznacenim premennej, do ktorej pridame hodnotu v URL
    client.print(sensors.getTempCByIndex(0));    // VYPIS HODNOTY 1. SENZORU NA INDEXE 0 DO URL
    client.print("&temp2=");                     //TEXTOVE DOPLNENIE DRUHEJ PREMENNEJ DO KTOREJ UVEDIEME COMU SA ROVNA TAKTIEZ V URL
    client.print(sensors.getTempCByIndex(1));    // VYPIS HODNOTY 2. SENZORU NA INDEXE 1 DO URL
    client.print("&hum1=");                      //TEXTOVE DOPLNENIE TRETEJ PREMENNEJ DO KTOREJ UVEDIEME COMU SA ROVNA TAKTIEZ V URL
    client.print(dht12.readHumidity());          // VYPIS VLHKOMERU DO LINKU, HODNOTA, KTOREJ SA ROVNA PREMENNA HUM1
    client.print("&pres1=");                     //TEXTOVE DOPLNENIE STVRTEJ PREMENNEJ DO KTOREJ UVEDIEME COMU SA ROVNA TAKTIEZ V URL
    client.print((bmp.readPressure() / 100) + 30, 120481927710843373493975903614); // VYPIS BAROMETRA DO LINKU + PRIPOCITANA KONSTANTA NA ZAKLADE NADMORSKEJ VYSKY PRE SPRAVNY PREPOCET NA RELATIVNY TLAK
    client.println(" HTTP/1.1");                 // UKONCENIE REQUESTU ZALOMENIM RIADKA A DOPLNENIM HLAVICKY HTTP S VERZIOU
    client.println("Host: www.mojastranka.sk"); // ADRESA HOSTA, NA KTOREHO BOL MIERENY REQUEST (NIE PHP SUBOR)
    client.println("Connection: close");         //UKONCENIE PRIPOJENIA ZA HTTP HLAVICKOU
    client.println();                            //ZALOMENIE RIADKA KLIENTSKEHO ZAPISU
    client.stop();                                   // UKONCENIE PRIPOJENIA ETHERNET SHIELDU
    Serial.println("Odoslane hlavicky s datami: ");  //SERIOVY VYPIS O STAVE USPESNOSTI PRENOSU
    Serial.println("Teplota von: ");                 //SERIOVY VYPIS TEXT O TEPLOTE
    Serial.println(sensors.getTempCByIndex(0));      //SERIOVY VYPIS STAV TEPLOTY NA SENZORE EVIDOVANOM NA INDEXE 0
    Serial.println("Teplota dnu: ");                 //SERIOVY VYPIS TEXT O TEPLOTE
    Serial.println(sensors.getTempCByIndex(1));      //SERIOVY VYPIS STAV TEPLOTY NA SENZORE EVIDOVANOM NA INDEXE 1
    Serial.println("Vlhkost vzduchu: ");             //SERIOVY VYPIS TEXT O VLHKOSTI VZDUCHU
    Serial.println(dht12.readHumidity());            //SERIOVY VYPIS STAVU VLHKOSTI
    Serial.println("Atmosfericky tlak: ");           //SERIOVY VYPIS TEXT O TLAKU VZDUCHU
    Serial.println((bmp.readPressure() / 100) + 30, 120481927710843373493975903614); //SERIOVY VYPIS STAVU RELATIVNEHO TLAKU 30,... je konstanta pre nadmorsku vysku, ktora sa prirata k teplote. (Použite pri nadmorskej do 1000m nadmorska vyska/8,3 tuto hodnotu napiste namiesto 30,...)
    Serial.println("Odpojenie uspesne.");            //SERIOVY VYPIS O STAVE USPESNOSTI PRENOSU
  } else {                                           // AK SA PRIPOJENIE NA SERVER NEPODARI
    Serial.println("Pripojenie zlyhalo");            //SERIOVY VYPIS O NEUSPESNOSTI PRIPOJENIA --> ŽIADNY HTTP REQUEST NEBOL VYKONANY
  }




  delay(15000); //15 SEKUND PAUZA POKYM NANOVO POBEZI SLUCKA PRE NOVE PRIPOJENIE A ODOSLANIE DALSICH HODNOT
}


Arduino môžete kontrolovať. Ako vidíte v kóde, to, čo sa odošle do internetu (ak vôbec) tak sa vypíše aj na sériovej linke. Nezabudnite na predefinovanú rýchlosť 9600. Cez Putty je možné sledovať čo do internetu odišlo, aby ste vedeli, či máte pripojenie z Arduina aktívne. Odporúčam nastaviť IP napríklad na 192.168.1.254 kde nehrozí kolízia z rozsahu DHCP, ktorý je najčastejeiše 192.168.1.100-192.168.1.150. Nezabudnite, že pri čidlách DS18B20 je nutné použiť 4,7Kohm odpor pre možnosť využitia OneWire protokolu. Jedným vodičom prúdi napájanie i dáta na PIN 6. Neoficiálne zdroje hovoria, že ak napojíte onewire na krútenú dvojlinku, tak je možné je využiť až na 300 metrov. Niečo o OneWire protokole si môžete prečítať TU: https://cs.wikipedia.org/wiki/1-Wire
Následuje aj server-side časť. V scripte pre Arduino je spomenutý add.php súbor, na ktorý sa robí požiadavka GET metódou cez ? kde napr: temp1=20.34&temp2=21.88&hum1=47.58&pres1=1014.28 Takýto request môže byť uložený do databázy, ak je na PHP súbore nastavená metóda GET a na ňu je vytvorený MySQL request. Pre lepší výkon využívam súčasne najpoužívanejšie MySQLi. Súbor nie je dobré prezrádzať. Ak ho otvoríte na prázdno, tak sa všade uloží 0. V prípade, že niekto zistí link napríklad vasastranka.sk/add.php tak môže uložiť čo chce, napríklad temp1=5000 a podobne, nehovoriac o tom, že script nemá žiadne bezpečnostné prvky.

Add.php bude pre nás vyzerať následovne:
Kód: Vybrať všetko
<?php
header('Content-Type: text/html; charset=utf-8');
include ("connect.php");
   $temp1=$_GET["temp1"];
  $temp2=$_GET["temp2"];
  $pres1=$_GET["pres1"];
  $hum1=$_GET["hum1"];
 
$ins = mysqli_query($con,"INSERT INTO `TempOutside` (`temperature`) VALUES ('".$_GET["temp1"]."')") or die (mysqli_error($con));
$ins2 = mysqli_query($con,"INSERT INTO `TempLivingRoom` (`temperature`) VALUES ('".$_GET["temp2"]."')") or die (mysqli_error($con));
$ins3 = mysqli_query($con,"INSERT INTO `PressureOutside` (`pressure`) VALUES ('".$_GET["pres1"]."')") or die (mysqli_error($con));
$ins4 = mysqli_query($con,"INSERT INTO `Humidity` (`humidity`) VALUES ('".$_GET["hum1"]."')") or die (mysqli_error($con)); 
   
?>

V kóde sa vykonávajú 4 INSERTY do 4 rôzných tabuliek. K databáze ako takej si musím vytvoriť connect.php súbor.
Obsah súboru connect.php:
Kód: Vybrať všetko
<?php
header('Content-Type: text/html; charset=utf-8');
$con = mysqli_connect("localhost","pouzivatelskemeno","heslo","nazovdatabazy(nie tabulky)");
     mysqli_set_charset($con,"utf8");
     
if (mysqli_connect_errno())
  {
  echo "Problém s napojením na MySQL: " . mysqli_connect_error();
  }

   
?>



Tabuľka vyzerá následovne:
id s parametrami(A_I) PRIMARY KEY
temperature temperature pressure humidity (jedna z týchto hodnôt pre každú tabuľku tabulka TempOutside s položkou temperature, TempLivingRoom s položkou temperature, tabuľka PressureOutside s položkou pressure a tabuľka Humidity s položkou humidity)
time TYPU TIMESTAMP S UPDATE ACTUAL ON REQUEST

Po uložení týchto tabuliek je možné navrhnúť webstránku, kde budete vaše údaje zobrazovať. Pridávam screenshoty mojej, ktorú som si vytvoril vrátane .PHP kódov pre výpočet priemerov, vykreslenie naj hodnoty dňa, prognóza počasia... atď. V prípade záujmu pošlem do SS.
Obrázok
Obrázok
Obrázok
Obrázok
Obrázok
Obrázok
Týmto sme sa naučili, ako hodnoty do databázy dostať. S hodnotami môžete prostredníctvom kódu pracovať napríklad tak, že môžete vytvárať grafy (v mojom prípade JsCharts, či GoogleCharts) Jednoduchým predaním dát z PHP do JS kódu je možné vykresliť krásne stĺpcové grafy za obdobia, ktoré si sami zvolíte --> Dáte JS dáta iba za určitý časový úsek.

Vyhotovenie
V mojom prípade som zvolil krabičku od žiaroviek do auta, kde som umiestnil breadboard s čidlom DS18B20 (outdoor) + DHT12 + BMP280, na druhom breadborde (žltom) je umiestnený DS18B20 (indoor). Všetko je prepojené podľa schémy vyššie.
Obrázok
Obrázok

UPOZORNENIE NA ZÁVER: Ethernet Shield minimálne ten, ktorý som tu popísal W5100 nepodporuje HTTPS protokol. Jeho procesor nezvláda šifrovanie. Preto, ak chcete tento koncept vyskúšať, siahnite po HTTP hostingu. V prípade, že chcete testovať na HTTPS, zakúpte si Wifi Shield 101.
HTTPS hosting free: PHP5.sk --> doména 3. radu zdarma, teda vasastranka.php5.sk je to ale na HTTPS! Nepoužívať s Ethernet Shieldom W5100.
Pre HTTP vyskúšajte Endoru, alebo Hostinger, prípadne Studenthosting.
Pridávam aj knižnice: Ethernet.h, SPI.h je obsiahnutá v každom Arduino IDE od nainštalovania.
Heslo na stiahnutie je: arduino.sk
https://ulozto.sk/!pkxqIyTKu2uH/meteostanica-arduinosk-rar

Obrázok užívateľa
Príspevky: 42
Registrovaný: Str 25. Feb 2015 22:19:54
Bydlisko: Fintice

Re: Meteostanica - Webclient

Poslaťod dzooky » Pia 11. Aug 2017 14:01:00

Celkom pekny projektik.
O meteostanicu sa snazim dlho len okrem toho aj ine veci.
Inak pouzivam cinsku nahradu za ethernetshield ENC28J60 ci ako sa to vola a volanie stranky na update som mal pekne zbuchane do jedneho riadku :D
Inak ked to updatujes kazdych 15s je dajak dost casto, db sa hodne rychlo plni co :)
Podla mna zbytocnost tie hodnoty sa asi velmi nemenia asi to nema zmysel tak casto aktualizovat.

Späť na Hotové projekty