#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 = 12;
const int PHONE_NUMBER_START_ADDRESS = 0;
const int PRESSURE_THRESHOLD_ADDRESS = 50;
const int butony = 7; // Yukarı Buton
const int butona = 8; // Aşağı Buton
const int motorStartPin = 6; // Motor start pinini belirleyin
const int motorStopPin = 9; // 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 energyPin = 3;
const int thermPin = 2; // Motor termiği pin
const int phaseProtPin = 4; // 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(energyPin, 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("tellist") != -1) {
listRegisteredPhoneNumbers();
} 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");
}
}
}
// LCD ekranını belirli aralıklarla güncelle
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
updateLCD();
}
}
void sendSMS(String message) {
gsm.println("AT+CMGF=1"); // Text moduna geç
delay(100);
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]; // Null sonlandırıcı için yer ayırın
EEPROM.get(address, phoneNumber);
phoneNumber[PHONE_NUMBER_LENGTH] = '\0'; // Null sonlandırıcı ekleyin
if (strlen(phoneNumber) > 0) {
Serial.print("Numaraya SMS gönderiliyor: ");
Serial.println(phoneNumber);
gsm.print("AT+CMGS=\"");
gsm.print(phoneNumber);
gsm.println("\"");
delay(100);
gsm.print(message);
delay(100);
gsm.write(26); // CTRL+Z (SMS gönder)
delay(5000);
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 && lastThermStatus) { // Termik yeni devre dışı kaldıysa
stopMotor();
sendSMS("Motor termigi devre dışı, motor kapatıldı.");
deleteAllSMS();
}
lastThermStatus = thermStatus; // Güncel durumu kaydet
if (!phaseProtStatus && lastPhaseProtStatus) { // Faz koruma yeni devre dışı kaldıysa
stopMotor();
sendSMS("Faz koruma rolesi devre dışı, motor kapatıldı.");
deleteAllSMS();
}
lastPhaseProtStatus = phaseProtStatus; // Güncel durumu kaydet
if (pressureBar < pressureThreshold && !pressureLowAlertSent) { // Basınç düşükse ve daha önce uyarı gönderilmediyse
delay(72000);
sendSMS("Basınç " + String(pressureThreshold, 2) + " bar'ın altında.");
pressureLowAlertSent = true;
} else if (pressureBar >= pressureThreshold) { // Basınç normale döndüyse
pressureLowAlertSent = false;
}
}
// 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 " : "ERR");
lcd.setCursor(15, 1);
lcd.print(phaseProtStatus ? "OK " : "ERR");
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) {
if (phoneNumber.length() > PHONE_NUMBER_LENGTH) { // Telefon numarası uzunluk kontrolü
// Telefon numarası çok uzun, hata işleme (örneğin, seri porttan hata mesajı yazdırma)
return false;
}
char phoneNumberArray[PHONE_NUMBER_LENGTH];
phoneNumber.toCharArray(phoneNumberArray, PHONE_NUMBER_LENGTH);
for (int i = 0; i < MAX_PHONE_NUMBERS; i++) {
int address = PHONE_NUMBER_START_ADDRESS + (i * PHONE_NUMBER_LENGTH);
char storedNumber[PHONE_NUMBER_LENGTH];
EEPROM.get(address, storedNumber);
if (strcmp(storedNumber, phoneNumberArray) == 0) {
return false; // Numara zaten kayıtlı
}
if (strlen(storedNumber) == 0) {
// EEPROM'a yazmadan önce dizi taşması kontrolü yapılıyor
if (!EEPROM.put(address, phoneNumberArray)) { // EEPROM yazma işlemi
// EEPROM yazma hatası, hata işleme (örneğin, seri porttan hata mesajı yazdırma)
return false;
}
//EEPROM.commit(); // EEPROM'a yazmayı tamamla
return true;
}
}
return false; // Boş yer yok
}
bool removePhoneNumber(String phoneNumber) {
char phoneNumberArray[PHONE_NUMBER_LENGTH];
phoneNumber.toCharArray(phoneNumberArray, PHONE_NUMBER_LENGTH);
for (int i = 0; i < MAX_PHONE_NUMBERS; i++) {
int address = PHONE_NUMBER_START_ADDRESS + (i * PHONE_NUMBER_LENGTH);
char storedNumber[PHONE_NUMBER_LENGTH];
EEPROM.get(address, storedNumber);
if (strcmp(storedNumber, phoneNumberArray) == 0) { // strcmp() ile karşılaştır
for (int j = 0; j < PHONE_NUMBER_LENGTH; j++) {
EEPROM.update(address + j, 0); // Numarayı silmek için 0 yaz
}
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);
}
void listRegisteredPhoneNumbers() {
String numberList = "Kayitli Numaralar:\n";
for (int i = 0; i < MAX_PHONE_NUMBERS; i++) {
int address = PHONE_NUMBER_START_ADDRESS + (i * PHONE_NUMBER_LENGTH);
char storedNumber[PHONE_NUMBER_LENGTH];
EEPROM.get(address, storedNumber);
if (strlen(storedNumber) > 0) {
numberList += (i + 1); // Numarayı listeye ekle
numberList += ": ";
numberList += storedNumber;
numberList += "\n";
}
}
// Numaraları içeren SMS'i gönder
sendSMS(numberList);
}