Add ProgramArduino/coding.ino

This commit is contained in:
nanda_fathurahma 2024-07-22 13:21:41 +07:00
parent 00746421eb
commit 8fb6d5fbc8
1 changed files with 249 additions and 0 deletions

249
ProgramArduino/coding.ino Normal file
View File

@ -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;
}