Bir IoT Sistemi Tasarlamak
Bu yazımızda, bir IoT sistemi tasarlamaya çalışacağız. Bir örnek belirleyeceğiz ve bunu nasıl IoT sistemi haline getirebiliriz sorusunun yanıtını arayacağız.
Klasik web sunucularda bulunan yüklü yazılımları kullanarak tasarlayacağımız bu uygulamanın adı, “GPS takip sistemi”.
Web sunucumuzda Apache.exe, MySQL.exe, Php.exe programları kurulu ve çalışıyor olacak. Örnek site olarak da iot.milivolt.news domainini belirledik.
Sistemin, donanımsal ve yazılımsal bileşenleri aşağıdaki gibi olacak.
- Mikrodenetleyici + Wifi Modül + GPS modülü
- Mikrodenetleyici kodları
- Web server tarafındaki php uzantılı veri kayıt kodları
- Web server tarafındaki, haritada gerçek zamanlı konum gösterici html kodları
Sistemin şematik anlatımı aşağıda:
Proje genel şema
Mikrodenetleyici olarak pek çok alternatif var. Fakat bu uygulamada Arduino Uno veya Arduino Nano kullanacağımızı varsayıyoruz.
Hemen, mikrodenetleyici kodlarına bakalım:
Sisteme modül bağlantıları yapıldıktan sonra bu modülleri kullanabilmek için ilkin modül kütüphanelerini “#include” ifadesi ile eklemememiz gerekiyor. Hemen anlaşılacağı üzere, “TinyGPS++” GPS modülüyle işlemler yapabilmemiz için, “ESP8266Wifi” ise Wifi modülü ile işlem yapabilmek için kullanılacak.
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <ESP8266WiFi.h>
// WiFi info
const char* ssid = "your WIFI_SSID";
const char* password = "your WIFI_PASSWORD";
// GPS pins
const int GPS_RX_PIN = 2;
const int GPS_TX_PIN = 3;
// GPS object
TinyGPSPlus gps;
// WiFi object
WiFiClient client;
// IotMilivolt.News addrs.and port number (80, for http)
const char* server = "iot.milivolt.news";
const int port = 80;
void setup() {
// Serial baud speed
Serial.begin(9600);
// WiFi connect
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("WiFi waiting...");
}
Serial.println("WiFi connected!");
}
void loop() {
// read data from GPS
while (Serial.available() > 0) {
if (gps.encode(Serial.read())) {
if (gps.location.isValid()) {
// GPS coord.
float latitude = gps.location.lat();
float longitude = gps.location.lng();
// send GPS data to server (iot.milivolt.news)
sendGPSData(latitude, longitude);
// 2 seconds wait
delay(2000);
}
}
}
}
void sendGPSData(float latitude, float longitude) {
// connect to server
if (client.connect(server, port)) {
// GPS datas
String gpsData = "latitude=" + String(latitude, 6) + "&longitude=" + String(longitude, 6);
// HTTP POST request
String postRequest = "POST /save_gps_data.php HTTP/1.1\r\n";
postRequest += "Host: " + String(server) + "\r\n";
postRequest += "Content-Type: application/x-www-form-urlencoded\r\n";
postRequest += "Content-Length: " + String(gpsData.length()) + "\r\n";
postRequest += "Connection: close\r\n\r\n";
postRequest += gpsData;
// POST to server
client.print(postRequest);
// Get response from server
while (client.connected()) {
if (client.available()) {
String response = client.readStringUntil('\r');
Serial.println(response);
}
}
// close port
client.stop();
} else {
Serial.println("Could not connect to server!");
}
}
sendGPSData(float latitude, float longitude)
satırıyla GPS dataları alındıktan sonra sunucuya gönderilir. Sunucu tarafında bu dataları alan bir “php” uzantılı dosya olmalı. Bu dosyanın adı, “save_gps_data.php”. Web server tarafındaki bu kodlar ise aşağıda:
Web sunucu tarafında, daha önceden bir veri tabanı oluşturulmuş olmalı. Veri tabanı, kullanıcı adı ve şifresi belirlenmiş veri tabanına kayıt kodları ile iki adet GPS verisini tablomuza kayıt ediyoruz.
<?php
// Enter the required information for the database connection
$servername = "localhost";
$username = "mysql_user";
$password = "mysql_password";
$dbname = "database_name";
// receive POST Datas
$latitude = $_POST['latitude'];
$longitude = $_POST['longitude'];
// Connect to Database
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Database connection failed: " . $conn->connect_error);
}
// record to GPS datas
$sql = "INSERT INTO gps_data (latitude, longitude) VALUES ('$latitude', '$longitude')";
if ($conn->query($sql) === TRUE) {
echo " GPS data saved successfully.";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
// Close the database connection
$conn->close();
?>
Arduino kodları içerisinde yazdığımız delay(2000)
satırından dolayı, bu php uzantılı kodlar 2 saniyede bir çalışacak. Süre ayarlaması istenirse değiştirilebilir.
Şimdi, sıra geldi bu GPS verilerinin bir harita üzerinde gösterimine. Bunun için “html” uzantılı bir dosyaya ihtiyaç var. Aşağıdaki html dosyasında, veri tabanına kayıt edilen GPS verilerini belirli süre aralıklarında çeken JavaScript kodları var. Bu dosyanın adı index.html olsun.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<title>GPS Datas</title>
<style>
#map {
height: 400px;
width: 100%;
}
</style>
</head>
<body>
<h1>GPS Datas</h1>
<div id="map"></div>
<script>
function initMap() {
// Create a map
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 15,
center: {lat: 0, lng: 0}
});
// get GPS data and marker
setInterval(function() {
fetchGPSData(map);
}, 2000);
}
function fetchGPSData(map) {
// get GPS data
fetch('http://iot.milivolt.news/get_gps_data.php')
.then(response => response.json())
.then(data => {
// Mark the GPS data on the map----------------------------
var latitude = parseFloat(data.latitude);
var longitude = parseFloat(data.longitude);
var marker = new google.maps.Marker({
position: {lat: latitude, lng: longitude},
map: map
});
// Updates maps center
map.setCenter({lat: latitude, lng: longitude});
})
.catch(error => {
console.log('Hata:', error);
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
</body>
</html>
Bu kodlar içerisinde, geri planda veri tabanından kodları çeken bir “get_gps_data.php” var. Bu kodlar ise aşağıda:
<?php
// Enter the required information for the database connection
$servername = "localhost";
$username = "mysql_user";
$password = "mysql_password";
$dbname = "databese name";
// Connect to database
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Database connection failed: " . $conn->connect_error);
}
// Get latest GPS data from database
$sql = "SELECT latitude, longitude FROM gps_data ORDER BY id DESC LIMIT 1";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// Get the latest recorded GPS data
$row = $result->fetch_assoc();
$latitude = $row["latitude"];
$longitude = $row["longitude"];
// Generate the JSON data
$data = array(
'latitude' => $latitude,
'longitude' => $longitude
);
// Send JSON data as output
header('Content-Type: application/json');
echo json_encode($data);
} else {
echo " GPS data not found.";
}
// Close connect
$conn->close();
?>
Proje tasarımı ile ilgili bir değerlendirme yapalım:
Mikrodenetleyici yazılımı, GPS modülü üzerinden koordinat verilerini alır ve WiFi modül üzerinden iot.milivolt.news sunucusuna gönderir. Sunucuya gelen veriler “save_gps_data.php” aracılığıyla veri tabanına kayıt edilir.
iot.milivolt.news sitesinde anasayfa olarak bulunan index.html dosyası ise, içerisindeki javascript kodları yardımıyla GPS verilerini görselleştirir.
Projemizin genel yapısı ve çalışması bu şekilde olacak. Bu proje deneysel amaçlı olarak tasarlandı. Projeye pek çok özellik eklenebilir. Örneğin, pek çok kullanıcının kendi takip verilerini kayıt edebilmesi ve izleyebilmesi için üyelik sistemi eklenebilir.
Birden çok IoT (MCU+Wifi+GPS) sisteme eklenebilmesi için, her bir IoT nesnesine ayrı bir kimlik bilgisi de verilmesi gerekir.
Bu takip sistemi, takip edilen şeylerin türüne göre farklı amaçlar için kullanılabilir. Motorlu araçları takip ediyorsak, kayıt edilen takip verilerini kullanarak yakıt tüketimi ve yakıt giderleri de izlenebilir.