#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>
SoftwareSerial gsm(10, 11); //RX,TX
LiquidCrystal_I2C lcd(0x27, 20, 4); // I2C adresi 0x27 olan 20x4 LCD ekran
const int MAX_PHONE_NUMBERS = 3;
const int PHONE_NUMBER_LENGTH = 11;
const int PHONE_NUMBER_START_ADDRESS = 200;
const int PRESSURE_THRESHOLD_ADDRESS = PHONE_NUMBER_START_ADDRESS + (MAX_PHONE_NUMBERS * PHONE_NUMBER_LENGTH);
const int butony = 4; // Yukarı Buton
const int butona = 5; // Aşağı Buton
const int motorStartPin = 8; // Motor start pinini belirleyin
const int motorStopPin = 7; // Motor stop pinini belirleyin
bool motordurum = false;
bool previousMotorState = false;
const int sensorPin = A0; // A4 pinini kullanacağız
const float sensorMaxPsi = 150.0; // Sensörün maksimum ölçüm aralığı (psi)
const int sensorMaxADC = 1023; // Arduino'nun analog okuma maksimum değeri (0-1023)
const float sensorVoltage = 5.0; // Besleme voltajı
const float psiToBar = 0.0689476; // 1 psi = 0.0689476 bar
// Kalibrasyon için sıfır noktasında okunan değeri tanımlayın
int sensorZeroOffset = 99; // Bu değeri sıfır basınç altında iken okuyun
const int thermPin = 9; // Motor termiği pin
const int phaseProtPin = 6; // Faz koruma rölesi pin
const float maxPressure = 10.0; // Maksimum basınç (bar)
const float minPressure = 0.0; // Minimum basınç (bar)
float pressureThreshold = 3.50; // Başlangıç Basınç eşiği (bar)
unsigned long previousMillis = 3000; // Son ekran güncellemesinin zamanı
const long interval = 3000; // Ekranı güncelleme aralığı (milisaniye cinsinden)
const int numReadings = 10; // Basınç sensörü için ortalama alınacak okuma sayısı
int lastSignalStrength = -1;
bool lastThermStatus = false;
bool lastPhaseProtStatus = false;
float lastPressure = -1.0;
float lastPressureThreshold = -1.0;
bool pressureLowAlertSent = false; // Basınç düşük olduğunda SMS gönderilip gönderilmediğini takip eder
void setup() {
pinMode(motorStartPin, OUTPUT);
pinMode(motorStopPin, OUTPUT);
digitalWrite(motorStartPin, HIGH);
digitalWrite(motorStopPin, HIGH);
pinMode(thermPin, INPUT);
pinMode(phaseProtPin, INPUT);
pinMode(butony, INPUT_PULLUP); // Yukarı buton
pinMode(butona, INPUT_PULLUP); // Aşağı buton
gsm.begin(9600);
Serial.begin(9600);
// EEPROM'dan basınç eşiği değerini oku
EEPROM.get(PRESSURE_THRESHOLD_ADDRESS, pressureThreshold);
if (isnan(pressureThreshold) || pressureThreshold < minPressure || pressureThreshold > maxPressure) {
pressureThreshold = 3.50; // Varsayılan değer
EEPROM.put(PRESSURE_THRESHOLD_ADDRESS, pressureThreshold);
}
// LCD ekranı başlat
lcd.init();
lcd.backlight();
lcd.clear();
// SIM800 modülünü başlatma
gsm.println("AT"); // Modülün cevap verip vermediğini kontrol etmek için AT komutu gönder
delay(1000);
gsm.println("AT+CMGF=1"); // SMS modunu text moduna geçirme
delay(1000);
gsm.println("AT+CNMI=1,2,0,0,0"); // Yeni SMS geldiğinde direkt seri porta iletilmesini sağlama
delay(1000);
gsm.println("ATS0=1"); // otomatik cevapla
delay(1000);
gsm.println("AT+DDET=1"); // DTMF aktif
delay(1000);
Serial.println("SIM800 Modülü Hazır.");
// Başlangıç ekranını göster
lcd.setCursor(2, 0);
lcd.print("SiSTEM BASLATILDI");
lcd.setCursor(0, 2);
lcd.print(" OZTURK YAZILIM");
lcd.setCursor(0, 3);
lcd.print(" 0507 537 0001");
delay(3000);
lcd.clear();
// Sabit metinleri bir kez yazdır
lcd.setCursor(0, 0);
lcd.print("SEBEKE: ");
lcd.setCursor(0, 1);
lcd.print("TRMK: ");
lcd.setCursor(8, 1);
lcd.print("FAZ.K: ");
lcd.setCursor(0, 2);
lcd.print("Basinc : ");
lcd.setCursor(0, 3);
lcd.print("Basnc SET: ");
}
void loop() {
if (motordurum) {
monitorMotorConditions();
}
delay(15);
// Basınç eşiğini butonlarla ayarla
if (digitalRead(butony) == LOW) {
pressureThreshold += 0.10;
if (pressureThreshold > maxPressure) {
pressureThreshold = maxPressure;
}
EEPROM.put(PRESSURE_THRESHOLD_ADDRESS, pressureThreshold);
delay(15); // Buton debounce
}
if (digitalRead(butona) == LOW) {
pressureThreshold -= 0.10;
if (pressureThreshold < minPressure) {
pressureThreshold = minPressure;
}
EEPROM.put(PRESSURE_THRESHOLD_ADDRESS, pressureThreshold);
delay(15); // Buton debounce
}
// SMS ve DTMF kontrolü
if (gsm.available()) {
String message = gsm.readString();
Serial.println("Gelen Mesaj: " + message);
// DTMF Kontrolü
int dtmfIndex = message.indexOf("+DTMF:");
if (dtmfIndex != -1) {
char dtmfTonu = message.charAt(dtmfIndex + 7);
Serial.println("DTMF Tonu: " + String(dtmfTonu));
if (dtmfTonu == '1') {
if (checkConditions()) {
startMotor();
motordurum = true;
Serial.println("MOTOR ÇALIŞTIRILDI (DTMF)");
sendSMS("MOTOR CALISTIRILDI (DTMF)");
deleteAllSMS();
}
} else if (dtmfTonu == '0') {
stopMotor();
motordurum = false;
Serial.println("MOTOR DURDURULDU (DTMF)");
sendSMS("MOTOR DURDURULDU (DTMF)");
deleteAllSMS();
}
}
// SMS ile kontrol
else if (message.indexOf("MOTOR ON") != -1) {
if (checkConditions()) {
startMotor();
motordurum = true;
Serial.println("MOTOR ÇALIŞTIRILDI");
sendSMS("MOTOR CALISTIRILDI");
deleteAllSMS();
}
} else if (message.indexOf("MOTOR OFF") != -1) {
stopMotor();
motordurum = false;
Serial.println("MOTOR DURDURULDU");
sendSMS("MOTOR DURDURULDU");
deleteAllSMS();
} else if (message.indexOf("bilgiler") != -1) {
String info = getDeviceStatus();
sendSMS(info);
deleteAllSMS();
} else if (message.indexOf("ekle") != -1) {
String phoneNumber = message.substring(message.indexOf("ekle") + 5);
phoneNumber.trim();
if (addPhoneNumber(phoneNumber)) {
sendSMS(phoneNumber + " eklendi");
} else {
sendSMS("Numara eklenemedi. Hafiza dolu veya numara zaten kayitli.");
}
} else if (message.indexOf("sil") != -1) {
String phoneNumber = message.substring(message.indexOf("sil") + 4);
phoneNumber.trim();
if (removePhoneNumber(phoneNumber)) {
sendSMS(phoneNumber + " silindi");
} else {
sendSMS("Numara bulunamadi veya silinemedi.");
}
} else if (message.indexOf("set") != -1) {
float newThreshold = message.substring(message.indexOf("set") + 4).toFloat();
if (newThreshold >= minPressure && newThreshold <= maxPressure) {
pressureThreshold = newThreshold;
EEPROM.put(PRESSURE_THRESHOLD_ADDRESS, pressureThreshold);
sendSMS("Basinc esigi " + String(pressureThreshold, 2) + " bar olarak ayarlandi");
} else {
sendSMS("Gecersiz basinc esigi degeri");
}
}
}
// Periyodik güncelleme ve LCD ekran yenileme
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
updateLCD();
}
}
void sendSMS(String message) {
for (int i = 0; i < MAX_PHONE_NUMBERS; i++) {
int address = PHONE_NUMBER_START_ADDRESS + (i * PHONE_NUMBER_LENGTH);
char phoneNumber[PHONE_NUMBER_LENGTH + 1];
EEPROM.get(address, phoneNumber);
if (strlen(phoneNumber) > 0) {
gsm.println("AT+CMGF=1");
delay(1000);
gsm.print("AT+CMGS=\"+");
gsm.print(phoneNumber);
gsm.println("\"");
delay(1000);
gsm.print(message);
delay(1000);
gsm.write(26);
delay(1000);
}
}
Serial.println("Gönderilen SMS: " + message);
}
String getDeviceStatus() {
// Basınç değerini oku
float pressureBar = readPressure();
// Termik durumunu oku
bool thermStatus = digitalRead(thermPin);
String thermStatusStr = thermStatus ? "Acik" : "Kapali";
// Faz koruma durumunu oku
bool phaseProtStatus = digitalRead(phaseProtPin);
String phaseProtStatusStr = phaseProtStatus ? "Acik" : "Kapali";
// Motor durumunu oku
String motorStatusStr = motordurum ? "Calisiyor" : "Durmus";
// Durum bilgilerini birleştir ve döndür
String status = "Cihaz bilgileri:\n";
status += "Basinc: " + String(pressureBar, 2) + " bar\n";
status += "Termik: " + thermStatusStr + "\n";
status += "Faz Koruma: " + phaseProtStatusStr + "\n";
status += "Motor: " + motorStatusStr;
return status;
}
void deleteAllSMS() {
gsm.println("AT+CMGDA=\"DEL ALL\"");
delay(1000);
Serial.println("Tüm SMS'ler silindi");
}
float readPressure() {
int sensorValue = analogRead(sensorPin); // Sensör değerini oku
int correctedSensorValue = sensorValue - sensorZeroOffset; // Sıfır noktasını düzelt
// Negatif değerleri 0 olarak ayarlayın
if (correctedSensorValue < 0) {
correctedSensorValue = 0;
}
float voltage = (correctedSensorValue * sensorVoltage) / sensorMaxADC; // Okunan değeri voltaja dönüştür
float pressurePsi = (voltage / sensorVoltage) * sensorMaxPsi; // Voltajı psi cinsine çevir
float pressureBar = pressurePsi * psiToBar; // Psi cinsinden basıncı bar cinsine çevir
return pressureBar;
}
bool checkConditions() {
bool thermStatus = digitalRead(thermPin);
bool phaseProtStatus = digitalRead(phaseProtPin);
if (!thermStatus) {
sendSMS("Motor termigi devrede degil, motor acilmadi.");
deleteAllSMS();
return false;
}
if (!phaseProtStatus) {
sendSMS("Faz koruma rolesi devrede degil, motor acilmadi.");
deleteAllSMS();
return false;
}
return true;
}
void monitorMotorConditions() {
bool thermStatus = digitalRead(thermPin);
bool phaseProtStatus = digitalRead(phaseProtPin);
float pressureBar = readPressure();
if (!thermStatus) {
stopMotor(); // Motoru kapat
sendSMS("Motor termigi devre degil, motor kapatildi.");
deleteAllSMS();
} else if (!phaseProtStatus) {
stopMotor(); // Motoru kapat
sendSMS("Faz koruma rolesi devrede degil, motor kapatildi.");
deleteAllSMS();
} else if (pressureBar < pressureThreshold) {
if (!pressureLowAlertSent) {
sendSMS("Basinc " + String(pressureThreshold, 2) + " barn altinda.");
pressureLowAlertSent = true;
}
} else {
pressureLowAlertSent = false; // Basınç normale döndüğünde SMS gönderim bayrağını sıfırla
}
}
// LCD ekranını güncelleyen fonksiyon
void updateLCD() {
int signalStrength = getSignalStrength();
bool thermStatus = digitalRead(thermPin);
bool phaseProtStatus = digitalRead(phaseProtPin);
float pressure = readPressure();
lcd.setCursor(8, 0);
lcd.print(signalStrength);
lcd.print(" ");
lcd.setCursor(5, 1);
lcd.print(thermStatus ? "OK " : "FAIL");
lcd.setCursor(15, 1);
lcd.print(phaseProtStatus ? "OK " : "FAIL");
lcd.setCursor(10, 2);
lcd.print(pressure, 2);
lcd.print(" bar ");
lcd.setCursor(10, 3);
lcd.print(pressureThreshold, 2);
lcd.print(" bar ");
}
// Yeni fonksiyonlar
bool addPhoneNumber(String phoneNumber) {
for (int i = 0; i < MAX_PHONE_NUMBERS; i++) {
int address = PHONE_NUMBER_START_ADDRESS + (i * PHONE_NUMBER_LENGTH);
char storedNumber[PHONE_NUMBER_LENGTH + 1];
EEPROM.get(address, storedNumber);
if (String(storedNumber) == phoneNumber) {
return false; // Numara zaten kayıtlı
}
if (strlen(storedNumber) == 0) {
EEPROM.put(address, phoneNumber.c_str());
return true;
}
}
return false; // Boş yer yok
}
bool removePhoneNumber(String phoneNumber) {
for (int i = 0; i < MAX_PHONE_NUMBERS; i++) {
int address = PHONE_NUMBER_START_ADDRESS + (i * PHONE_NUMBER_LENGTH);
char storedNumber[PHONE_NUMBER_LENGTH + 1];
EEPROM.get(address, storedNumber);
if (String(storedNumber) == phoneNumber) {
for (int j = 0; j < PHONE_NUMBER_LENGTH; j++) {
EEPROM.update(address + j, 0);
}
return true;
}
}
return false;
}
// Sinyal gücünü döndüren fonksiyon
int getSignalStrength() {
gsm.println("AT+CSQ");
delay(500);
if (gsm.available()) {
String response = gsm.readString();
int index = response.indexOf("+CSQ: ");
if (index != -1) {
int commaIndex = response.indexOf(",");
return response.substring(index + 6, commaIndex).toInt();
}
}
return 0;
}
void startMotor() {
digitalWrite(motorStartPin, LOW);
delay(500);
digitalWrite(motorStartPin, HIGH);
}
void stopMotor() {
digitalWrite(motorStopPin, LOW);
delay(500);
digitalWrite(motorStopPin, HIGH);
}