Add ProgramArduino/coding.ino
This commit is contained in:
parent
00746421eb
commit
8fb6d5fbc8
|
@ -0,0 +1,249 @@
|
|||
#include <SPI.h>
|
||||
#include <MFRC522.h>
|
||||
#include <TinyGPS++.h>
|
||||
#include <TinyGsmClient.h>
|
||||
#include <ArduinoHttpClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <math.h>
|
||||
|
||||
const char FIREBASE_HOST[] = "sistem-keamanan-c9565-default-rtdb.firebaseio.com";
|
||||
const String FIREBASE_AUTH = "m34dRlGN86G2xllAm197fVt8VhPj4dfQxKGejjnz";
|
||||
const int SSL_PORT = 443;
|
||||
const String GPS_PATH = "/gps";
|
||||
const String RELAY_PATH = "/relay";
|
||||
|
||||
char apn[] = "internet";
|
||||
char user[] = "";
|
||||
char pass[] = "";
|
||||
|
||||
#define rxPin 4
|
||||
#define txPin 2
|
||||
HardwareSerial sim800(1);
|
||||
TinyGsm modem(sim800);
|
||||
|
||||
#define RXD2 16
|
||||
#define TXD2 17
|
||||
HardwareSerial neogps(2);
|
||||
TinyGPSPlus gps;
|
||||
|
||||
TinyGsmClientSecure gsm_client_secure_modem(modem, 0);
|
||||
HttpClient http_client = HttpClient(gsm_client_secure_modem, FIREBASE_HOST, SSL_PORT);
|
||||
|
||||
unsigned long previousMillis = 0;
|
||||
const long interval = 10000; // Interval hanya untuk relay
|
||||
|
||||
#define RELAY_PIN 5
|
||||
#define RST_PIN 22
|
||||
#define SS_PIN 21
|
||||
MFRC522 rfid(SS_PIN, RST_PIN);
|
||||
|
||||
#define BUZZER_PIN 15
|
||||
|
||||
bool relayState = false;
|
||||
|
||||
String registeredRFID[] = {"BEC1596E", "23C13394", "73BE3A1C"};
|
||||
|
||||
double prevLatitude = 0.0;
|
||||
double prevLongitude = 0.0;
|
||||
const double DISTANCE_THRESHOLD = 10.0; // 10 meter
|
||||
#define EARTH_RADIUS 6371e3
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
SPI.begin();
|
||||
rfid.PCD_Init();
|
||||
|
||||
sim800.begin(9600, SERIAL_8N1, rxPin, txPin);
|
||||
|
||||
neogps.begin(9600, SERIAL_8N1, RXD2, TXD2);
|
||||
delay(3000);
|
||||
|
||||
pinMode(RELAY_PIN, OUTPUT);
|
||||
digitalWrite(RELAY_PIN, HIGH); // Memastikan relay dalam keadaan Normally Closed (NC)
|
||||
|
||||
pinMode(BUZZER_PIN, OUTPUT);
|
||||
digitalWrite(BUZZER_PIN, LOW); // Memastikan buzzer mati
|
||||
|
||||
modem.restart();
|
||||
String modemInfo = modem.getModemInfo();
|
||||
|
||||
connectToInternet();
|
||||
|
||||
http_client.setHttpResponseTimeout(90 * 1000); // Timeout 90 detik
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!modem.isNetworkConnected()) {
|
||||
connectToInternet();
|
||||
}
|
||||
|
||||
// Tangani permintaan HTTP untuk relay secara berkala
|
||||
unsigned long currentMillis = millis();
|
||||
if (currentMillis - previousMillis >= interval) {
|
||||
previousMillis = currentMillis;
|
||||
|
||||
bool newRelayState = relayState;
|
||||
if (GetRelayStateFromFirebase(&http_client, newRelayState) && newRelayState != relayState) {
|
||||
updateRelayState(newRelayState);
|
||||
}
|
||||
}
|
||||
gps_loop();
|
||||
|
||||
// Selalu cek kartu RFID
|
||||
rfid_loop();
|
||||
}
|
||||
|
||||
void connectToInternet() {
|
||||
int retry_count = 0;
|
||||
const int max_retries = 5;
|
||||
|
||||
while (retry_count < max_retries) {
|
||||
if (modem.gprsConnect(apn, user, pass)) {
|
||||
return;
|
||||
} else {
|
||||
retry_count++;
|
||||
delay(2000); // Tunggu sebelum mencoba lagi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PostToFirebase(const char* method, const String & path, const String & data, HttpClient* http) {
|
||||
String response;
|
||||
int statusCode = 0;
|
||||
http->connectionKeepAlive(); // Saat ini diperlukan untuk HTTPS
|
||||
|
||||
String url;
|
||||
if (path[0] != '/') {
|
||||
url = "/";
|
||||
}
|
||||
url += path + ".json";
|
||||
url += "?auth=" + FIREBASE_AUTH;
|
||||
|
||||
String contentType = "application/json";
|
||||
http->put(url, contentType, data);
|
||||
|
||||
statusCode = http->responseStatusCode();
|
||||
response = http->responseBody();
|
||||
|
||||
if (!http->connected()) {
|
||||
http->stop(); // Matikan
|
||||
if (!modem.isNetworkConnected()) {
|
||||
connectToInternet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GetRelayStateFromFirebase(HttpClient* http, bool &relayState) {
|
||||
String url = String(RELAY_PATH) + ".json?auth=" + FIREBASE_AUTH;
|
||||
|
||||
http->get(url);
|
||||
int statusCode = http->responseStatusCode();
|
||||
String response = http->responseBody();
|
||||
|
||||
if (statusCode == 200) {
|
||||
DynamicJsonDocument doc(1024);
|
||||
deserializeJson(doc, response);
|
||||
relayState = doc["relayState"];
|
||||
return true;
|
||||
} else {
|
||||
if (!http->connected()) {
|
||||
connectToInternet();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void gps_loop() {
|
||||
boolean newData = false;
|
||||
for (unsigned long start = millis(); millis() - start < 2000; ) {
|
||||
while (neogps.available()) {
|
||||
if (gps.encode(neogps.read())) {
|
||||
newData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newData) {
|
||||
double currentLat = gps.location.lat();
|
||||
double currentLng = gps.location.lng();
|
||||
|
||||
double distance = haversineDistance(prevLatitude, prevLongitude, currentLat, currentLng);
|
||||
|
||||
if (distance >= DISTANCE_THRESHOLD) {
|
||||
String latitude = String(currentLat, 6);
|
||||
String longitude = String(currentLng, 6);
|
||||
|
||||
String gpsData = "{";
|
||||
gpsData += "\"lat\":" + latitude + ",";
|
||||
gpsData += "\"lng\":" + longitude + "";
|
||||
gpsData += "}";
|
||||
|
||||
PostToFirebase("PATCH", GPS_PATH, gpsData, &http_client);
|
||||
|
||||
prevLatitude = currentLat;
|
||||
prevLongitude = currentLng;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rfid_loop() {
|
||||
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String rfidTag = "";
|
||||
for (byte i = 0; i < rfid.uid.size; i++) {
|
||||
rfidTag += String(rfid.uid.uidByte[i], HEX);
|
||||
}
|
||||
rfidTag.toUpperCase();
|
||||
|
||||
for (String id : registeredRFID) {
|
||||
if (rfidTag == id) {
|
||||
bool newRelayState = !relayState;
|
||||
updateRelayState(newRelayState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateRelayState(bool newRelayState) {
|
||||
relayState = newRelayState;
|
||||
|
||||
if (relayState) {
|
||||
buzz(2, 200);
|
||||
} else {
|
||||
buzz(1, 200);
|
||||
}
|
||||
|
||||
digitalWrite(RELAY_PIN, relayState ? LOW : HIGH);
|
||||
|
||||
String relayData = "{";
|
||||
relayData += "\"relayState\":" + String(relayState ? "true" : "false");
|
||||
relayData += "}";
|
||||
|
||||
PostToFirebase("PATCH", RELAY_PATH, relayData, &http_client);
|
||||
}
|
||||
|
||||
void buzz(int count, int delayTime) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
digitalWrite(BUZZER_PIN, HIGH);
|
||||
delay(delayTime);
|
||||
digitalWrite(BUZZER_PIN, LOW);
|
||||
delay(delayTime);
|
||||
}
|
||||
}
|
||||
|
||||
double haversineDistance(double lat1, double lon1, double lat2, double lon2) {
|
||||
double lat1Rad = radians(lat1);
|
||||
double lat2Rad = radians(lat2);
|
||||
double deltaLat = radians(lat2 - lat1);
|
||||
double deltaLon = radians(lon2 - lon1);
|
||||
|
||||
double a = sin(deltaLat / 2) * sin(deltaLat / 2) +
|
||||
cos(lat1Rad) * cos(lat2Rad) * sin(deltaLon / 2) * sin(deltaLon / 2);
|
||||
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
|
||||
|
||||
return EARTH_RADIUS * c;
|
||||
}
|
Loading…
Reference in New Issue