1
Dependencies: mbed
Revision 0:2a01c5a56ed1, committed 2018-07-09
- Comitter:
- meric
- Date:
- Mon Jul 09 09:12:38 2018 +0000
- Commit message:
- 1
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/alerts.h Mon Jul 09 09:12:38 2018 +0000
@@ -0,0 +1,23 @@
+#ifndef ALERTS_H
+#define ALERTS_H
+/*
+ ****************************************************************************
+ ****************************************************************************
+ ** DEVINT BİLİŞİM YAZILIM DONANIM TİC. LTD. ŞTİ. TARAFINDAN GELİŞTİRİLMİŞTİR
+ ** İzmir / TÜRKİYE
+ **
+ ** (C) 2015
+ ****************************************************************************
+ ****************************************************************************
+ *************************************************************** K A M B O **
+*/
+
+//
+void send_alarm(uint8_t _alarmID, uint16_t _filterID, uint8_t _slaveID)
+{
+ sprintf(fnode.alarmBuffer, "%s%d%s%d%s%d%s%d%s%d%s%.1f%s%.1f%s%.1f%s%llu%s%llu%s%.1f%c", "{ALR:\"FALR\",ALRCODE:", _alarmID, ",FID:", _filterID, ",Z:", fnode.currentFlushingFilter, ",FLID:", fnode.currentFlushPhase, ",SID:", _slaveID, ",PRIN:", fnode.inletPressure, ",PROUT:", fnode.outletPressure, ",DP:", fnode.dpPressure, ",WI:", fnode.WI, ",WIC:", fnode.WIC, ",QI:", fnode.QI, '}');
+ send_to_coordinator(fnode.alarmBuffer);
+ memset (fnode.alarmBuffer, 0, sizeof(fnode.alarmBuffer));
+ wait_ms(50);
+}
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/define.h Mon Jul 09 09:12:38 2018 +0000
@@ -0,0 +1,491 @@
+#ifndef _DEFINE_H_
+#define _DEFINE_H_
+/*
+ ****************************************************************************
+ ****************************************************************************
+ ** DEVINT BİLİŞİM YAZILIM DONANIM TİC. LTD. ŞTİ. TARAFINDAN GELİŞTİRİLMİŞTİR
+ ** İzmir / TÜRKİYE
+ **
+ ** (C) 2015
+ ****************************************************************************
+ ****************************************************************************
+ *************************************************************** K A M B O **
+*/
+
+/* FİLTRASYON MASTER PIN SET
+ RF Tx..................................................................PA_11
+ RF Rx..................................................................PA_12
+ RF Aktif...............................................................PB_10
+
+ EEPROM SDA..............................................................PB_9
+ EEPROM SCL..............................................................PB_8
+
+ DP Sensörü (0-3.3VDC)...................................................PC_2
+ Basınç Sensörü (4-20mA).................................................PA_0
+ Akış Sensörü............................................................PC_3
+ Sayaç...................................................................PC_4
+*/
+
+// MASTER ID
+#define MASTER_ID 0x00
+
+// EEPROM Ayarları
+#define EEPROM_TYPE 1 // 1: 1 bayt hafıza adreslemeli EEPROM, 2: 2 bayt hafıza adreslemeli EEPROM
+#define EEPROM_ADDRESS 0xA0 // EEPROM device address
+#define IO_EXPANDER_ADDRESS 0x40 // IO çoklayıcı adresi
+#define EEPROM_FREQUENCY 100000 // EEPROM frekansı 100 KHz
+
+// EEPROM Varsayılan Değerler
+#define SYSTEM_SETUP_DEFAULT 15 // Sistem el kitabına bakın
+#define AUTOSEND_STATUS_DEFAULT 1 // 0: Otomatik veri aktarımı kapalı, 1: Otomatik veri aktarımı açık
+#define IRRI_TRANSMIT_INTERVAL_DEFAULT 15 // Sulama sırasında veri gönderim sıklığı (Dakika)
+#define DRY_TRANSMIT_INTERVAL_DEFAULT 15 // Sulama dışında veri gönderim sıklığı, (Dakika)
+#define PMAX_DEFAULT 10 // Basınç sensörü max. basınç değeri (Bar)
+#define PRESSURE_SENSOR_DEFAULT 1 // Basınç sensörü tipi: 0: 0-3.3V (HONEYWELL), 1: 4-20mA
+#define WATERMETER_COEFF_DEFAULT 1000 // Sayaç katsayısı (litre/pals)
+#define DP_DEFAULT 10 // Ters yıkamanın başlayacağı fark basınç (DP) değeri, bar (10/10 = 1)
+#define PRESSURE_CONTROL_FREQUENCY_DEFAULT 30 // Basınç kontrol sıklığı (Saniye)
+#define FLUSH_DURATION_DEFAULT 45 // 1 filtre yıkama süresi (Saniye)
+#define FLUSH_INTERVAL_DEFAULT 30 // 2 filtre yıkaması arası bekleme süresi (Saniye)
+#define FLOW_CONTROL_LATENCY_DEFAULT 20 // Akış kontrolü gecikme süresi (Saniye)
+#define FLUSH_ENABLE_DEFAULT 1 // 0: Ters yıkama kapalı, 1: Ters yıkama açık
+#define PR_SENSOR_POSITION_DEFAULT 0 // 0: Basınç sensörü filtre girişinde, 1: Basınç sensörü filtre çıkışında
+#define BACKFLUSH_STOP_DEFAULT 0 // 0: Ters yıkama sırasındaki herhangi bir hatada ters yıkama devam eder, 1: Ters yıkama sırasındaki herhangi bir hatada ters yıkama durur
+#define INLET_PRS_LOW_TRS_DEFAULT 20 // Giriş basıncı alarmı alt eşik set değeri 1 bar (10/10 = 1)
+#define INLET_PRS_HIGH_TRS_DEFAULT 60 // Giriş basıncı alarmı üst eşik set değeri 7 bar (70/10 = 7)
+#define ALARMS_ENABLE_DEFAULT 1 // 0: Alarmlar kapalı, 1: Alarmlar açık
+#define DP_HIGH_TRS_DEFAULT 15 // DP üst sınır alarmı eşik değeri (Bar) (/10)
+#define INLET_PRS_SET_DEFAULT 10 // Sulamanın başladığının anlaşıldığı giriş basıncı değeri 0.2 bar (2/10 = 0.2)
+#define OUTLET_PRS_SET_FOR_DP_DEFAULT 20 // DP kontrolünün başlayacağı filtrasyon çıkış basıncı (Bar) (/10)
+#define PERIODIC_FLUSH_DEFAULT 10 // Periyodik yıkama aktif ve belirtilen dakikada devreye girer. Bu değer sıfır ise periyodik yıkama aktiflenmez. (saat)
+#define MIN_FLUSH_INTERVAL_DEFAULT 5 // DP'ye göre yıkamada iki yıkama arasındaki süre (DAKİKA). Bu değer sıfır ise DP'ye göre yıkama bittiğinde DP değeri düşmemişse hemen yeniden yıkama yapar.
+#define FILTER_NUMBER_DEFAULT 4 // Varsayılan filtre sayısı 4
+
+// EEPROM Adresleri
+#define DEFAULT_CONFIG_ADDR 0x00
+#define IRRI_STATUS_ADDR 0x01
+#define SYSTEM_SETUP_ADDR 0x02
+#define AUTOSEND_STATUS_ADDR 0x03
+#define IRRI_TRANSMIT_INTERVAL_ADDR 0x04
+#define DRY_TRANSMIT_INTERVAL_ADDR 0x05
+#define WATERMETER_COEFF_ADDR_1 0x06
+#define WATERMETER_COEFF_ADDR_2 0x07
+#define PMAX_ADDR 0x08
+#define PRESSURE_SENSOR_ADDR 0X09
+#define DP_ADDR 0x0A
+#define PRESSURE_CONTROL_FREQUENCY_ADDR 0x0B
+#define FLUSH_DURATION_ADDR 0x0C
+#define FLUSH_INTERVAL_ADDR 0x0D
+#define FLOW_CONTROL_LATENCY_ADDR 0x0E
+#define FLUSH_ENABLE_ADDR 0x0F
+#define PR_SENSOR_POSITION_ADDR 0x10
+#define BACKFLUSH_STOP_ADDR 0x11
+#define INLET_PRS_LOW_TRS_ADDR 0x12
+#define INLET_PRS_HIGH_TRS_ADDR 0x13
+#define ALARMS_ENABLE_ADDR 0x14
+#define DP_HIGH_TRS_ADDR 0x15
+#define INLET_PRS_SET_ADDR 0x16
+#define OUTLET_PRS_SET_FOR_DP_ADDR 0x17
+#define PERIODIC_FLUSH_ADDR 0x18
+#define MIN_FLUSH_INTERVAL_ADDR_1 0x19
+#define MIN_FLUSH_INTERVAL_ADDR_2 0x1A
+#define FILTER_NUMBER_ADDR 0x1B
+
+// RF Koordinatör Adresi
+#define COORD_ADDR_1 255 // WSN koordinatör adresi 1. baytı (0xFF)
+#define COORD_ADDR_2 255 // WSN koordinatör adresi 2. baytı (0xFF)
+
+// RF USART
+#define TX_RF PA_11 // RF Module Tx Pin (Serial6)
+#define RX_RF PA_12 // RF Module Rx Pin (Serial6)
+#define RF_ACTIVE PB_10 // RF Reset Pin (3.3v verilirse RF aktif kalır)
+#define BAUD_SERIAL_RF 38400 // RF USART Baudrate
+#define CR 13 // "\r" ASCII kodu
+#define EQUAL 61 // "=" ASCII kodu
+
+// MASTER USART
+#define TX_MASTER PB_6
+#define RX_MASTER PB_7
+#define BAUD_MASTER 38400
+#define CR 13 // "\r" ASCII kodu
+
+// GPIO
+#define WATERMETER_PIN PC_4 // IN1 - Sayaç
+#define FLOW_PIN PC_3 // IN2 - Akış sensörü
+#define DP_PIN PC_2 // IN3 - Fark basınç sensörü
+#define PRESSURE_PIN PA_0 // IN4 - Basınç sensörü
+
+// Diğer
+#define RMS_SAMPLING_NUMBER 100 // Analog kanal okumaları için RMS örnekleme sayısı
+#define RT_DATA_TRANSMIT_INTERVAL 30 // Gerçek zamanlı veri 30 sn aralıkla gönderiliyor
+
+// Alarmlar
+#define BACKFLUSH_DP_STARTED 255
+#define BAKCFLUSH_ENDED 254
+
+#define DP_CONTROL_STARTED 253
+
+#define IRRIGATION_STARTED 252
+#define IRRIGATION_ENDED 251
+
+#define INLET_LOW_PRESSURE 250
+#define INLET_NORMAL_PRESSURE 249
+#define INLET_HIGH_PRESSURE 248
+
+#define FILTER_FLUSH_STARTED 1
+#define FILTER_FLUSH_ENDED 2
+
+#define NO_FLOW_DURING_FLUSH 3
+#define FLOW_DURING_FLUSH 4
+
+#define BACKFLUSH_MANUAL_STARTED 247
+#define ALREADY_FLUSHING 246
+#define NO_IRRIGATION_FOR_FLUSHING 245
+#define FLUSH_DISABLED 244
+#define BACKFLUSH_PERIODIC_STARTED 243
+
+enum node_commands {
+
+ FENABLE = 1,
+ FDISABLE,
+ FSETSYS,
+ FSETDEF,
+ FGETCFG,
+ FREAD,
+ FSTART,
+ FSTOP,
+ FTEST,
+ FRESET,
+ FCLEAR,
+ FFIX,
+ FGETSTATUS,
+ FGETFSTATUS,
+ FLUSHNOW,
+ SELTESTON,
+ SELTESTOFF,
+ FFGETSTAT
+};
+
+enum solenoid_commands {
+
+ CLOSE_SOLENOID = 0x00,
+ OPEN_SOLENOID = 0x01,
+ TEST_OPEN_SOLENOID = 0x02,
+ TEST_CLOSE_SOLENOID = 0x03
+
+};
+
+enum success_state {
+
+ _ERROR_ = 0x00,
+ _OK_ = 0x01
+
+};
+
+enum filter_solenoid_id {
+
+ FILTER_MAIN_SOLENOID = 0x00,
+ FILTER_1_SOLENOID = 0x01,
+ FILTER_2_SOLENOID = 0x02,
+ FILTER_3_SOLENOID = 0x03,
+ FILTER_4_SOLENOID = 0x04
+
+};
+
+struct RTU {
+ float dpPressure;
+ float pressure;
+ float inletPressure;
+ float outletPressure;
+ float flowrate;
+ float flowrateTransmission;
+
+ char temporaryBuffer[256];
+ char dataBuffer[256];
+ char rfBuffer[256];
+ char str[24];
+ char alarmBuffer[256];
+ char edata;
+ char edata2[2];
+ char edata3[3];
+ char value;
+ char iodata[2];
+
+ uint8_t systemSetup;
+ uint8_t filterNumber;
+ uint8_t dpSet;
+ uint8_t flushDuration;
+ uint8_t flushInterval;
+ uint8_t pressureControlFrequency;
+ uint8_t pMax;
+ uint8_t pressureSensorType;
+ uint8_t autosendStatus;
+ uint8_t irriTransmitInterval;
+ uint8_t dryTransmitInterval;
+ uint8_t enableFlush;
+ uint8_t filterByte_1;
+ uint8_t filterByte_2;
+ uint8_t flowControlLatency;
+ uint8_t pressureSensorPosition;
+ uint8_t pressureLowThreshold;
+ uint8_t pressureHighThreshold;
+ uint8_t dpThreshold;
+ uint8_t inletPressureSet;
+ uint8_t outletPressureSet;
+ uint8_t alarm;
+ uint8_t flushEnabled;
+ uint8_t onErrorStop;
+ uint8_t alarmsEnabled;
+
+ uint16_t watermeterCoefficient;
+
+ uint64_t WI;
+ uint64_t WIC;
+ float QI;
+
+ uint64_t WD;
+ uint64_t WDC;
+ float QD;
+
+ uint64_t rWI;
+ uint64_t rWIC;
+ float rQI;
+
+ uint64_t rWD;
+ uint64_t rWDC;
+ float rQD;
+
+ volatile uint64_t pulse;
+ volatile uint64_t pulseTransmit;
+ volatile uint64_t pulsePressureCheck;
+
+ volatile bool transmitData;
+ volatile bool rfInterruptComplete;
+ bool flushStarted;
+ volatile bool checkPressure;
+
+ volatile uint8_t rfBufferCounter;
+ volatile uint8_t flushPhase;
+
+ volatile char rfBufferChar;
+
+ bool irrigation;
+ bool autosend;
+ bool flushing;
+ bool flowControl;
+ bool errorOccured;
+ bool pressureLowError;
+ bool pressureNormalError;
+ bool pressureHighError;
+ bool dpControlStarted;
+ bool checkDp;
+
+ bool periodicFlushEnabled;
+ uint8_t periodicFlushInterval;
+ volatile uint16_t periodicFlushCounter;
+
+ uint16_t minFlushInterval;
+ volatile uint16_t minFlushCounter;
+ bool isMinTimePassed;
+ bool minFlushEnabled;
+
+ volatile bool transmit_rtData;
+ volatile uint8_t rtCounter;
+
+ volatile uint64_t rtPulseFirst;
+ bool rtActive;
+
+ uint8_t testFilterNo;
+
+ uint16_t lastFlushPhase;
+
+ volatile char masterBufferChar;
+ char masterRxBuffer[2];
+ char masterTxBuffer[5];
+ volatile uint8_t masterBufferCounter;
+ volatile bool masterInterruptComplete;
+
+ uint16_t globalFlushPhase;
+ uint8_t currentFlushPhase;
+ uint8_t currentFlushingFilter;
+ uint8_t currentWorkingSlave;
+ uint16_t globalFlushingFilter;
+
+ uint8_t testid;
+
+ volatile bool flush_isr;
+
+ uint8_t periodicFirstStartCounter;
+
+ uint8_t totalSlaveNumber;
+
+
+ RTU() {
+
+ pulse = 0;
+ pulseTransmit = 0;
+ pulsePressureCheck = 0;
+
+ rfBufferCounter = 0;
+ alarm = 0;
+ flushPhase = 0;
+ pressureSensorPosition = 0;
+ onErrorStop = 0;
+
+ filterByte_1 = 255;
+ filterByte_2 = 255;
+ alarmsEnabled = 1;
+
+ transmitData = false;
+ rfInterruptComplete = false;
+ irrigation = false;
+ autosend = false;
+ flushStarted = false;
+ checkPressure = false;
+ flushing = false;
+ flowControl = false;
+ errorOccured = false;
+ pressureLowError = false;
+ pressureNormalError = false;
+ pressureHighError = false;
+ dpControlStarted = false;
+ checkDp = true;
+
+ WI = 0;
+ WIC = 0;
+ QI = 0.0;
+
+ WD = 0;
+ WDC = 0;
+ QD = 0.0;
+
+ rWI = 0;
+ rWIC = 0;
+ rQI = 0.0;
+
+ rWD = 0;
+ rWDC = 0;
+ rQD = 0.0;
+
+ periodicFlushEnabled = false;
+ periodicFlushInterval = 0;
+ periodicFlushCounter = 0;
+
+ minFlushInterval = 0;
+ minFlushCounter = 0;
+ isMinTimePassed = true;
+ minFlushEnabled = false;
+
+ transmit_rtData = false;
+ rtCounter = 0;
+
+ rtPulseFirst = 0;
+ rtActive = false;
+
+ masterBufferCounter = 0;
+ masterInterruptComplete = false;
+
+ flush_isr = false;
+
+ periodicFirstStartCounter = 0;
+ }
+} fnode;
+
+// Global değişkenler
+uint8_t c1 = 0;
+uint8_t c2 = 0;
+uint8_t c3 = 0;
+uint8_t c4 = 0;
+uint8_t c5_a = 0;
+uint8_t c5_b = 0;
+uint16_t c5 = 0;
+uint8_t c6 = 0;
+uint8_t c7 = 0;
+uint8_t c8 = 0;
+uint8_t c9 = 0;
+uint8_t c10 = 0;
+uint8_t c11 = 0;
+uint8_t c12 = 0;
+uint8_t c13 = 0;
+uint8_t c14 = 0;
+uint8_t c15 = 0;
+uint8_t c16 = 0;
+uint8_t c17 = 0;
+uint8_t c18 = 0;
+uint8_t c19 = 0;
+uint8_t c20 = 0;
+uint8_t c21 = 0;
+uint8_t c22 = 0;
+uint8_t c23_a = 0;
+uint8_t c23_b = 0;
+uint16_t c23 = 0;
+uint8_t c24 = 0;
+uint8_t irriTrsIntOld = 0;
+uint8_t dryTrsIntOld = 0;
+
+float rmsStore[RMS_SAMPLING_NUMBER];
+float totalSampling = 0.0;
+float tempValue = 0.0;
+float tp = 0.0;
+float tdp = 0.0;
+float tdpResult = 0.0;
+
+// JSON
+const char* jsonHeader[9] = {"PRIN:", "PROUT:", "DP:", "WI:", "WIC:", "QI:", "WD:", "WDC:", "QD:"};
+const char* json[2] = {"{F:{", "}}"};
+const char* jsonAlarm[15] = {"{ALR:\"FALR\"", "ALRCODE:", "APRSIN:", "ADP:", "AIRR:", "AFLUSH:", "AF11:", "AF12:", "AF21:", "AF22:", "AF31:", "AF32:", "AF41:", "AF42:", "}"};
+
+// Komutlar
+const char* fenable_command = "FENABLE";
+const char* fdisable_command = "FDISABLE";
+const char* fsetsys_command = "FSETSYS";
+const char* fgetcfg_command = "FGETCFG";
+const char* fread_command = "FREAD";
+const char* fstart_command = "FSTART";
+const char* fstop_command = "FSTOP";
+const char* ftest_command = "FTEST";
+const char* freset_command = "FRESET";
+const char* fclear_command = "FCLEAR";
+const char* ffix_command = "FFIX";
+const char* fgetstatus_command = "FGETSTATUS";
+const char* fgetfstatus_command = "FGETFSTATUS";
+const char* fflushnow_command = "FLUSHNOW";
+const char* frton_command = "FRTON";
+const char* frtoff_command = "FRTOFF";
+const char* getfrtstatus_command = "GETFRTSTATUS";
+const char* selteston_command = "SELTESTON";
+const char* seltestoff_command = "SELTESTOFF";
+const char* ffgetstat_command = "FFGETSTAT";
+
+// EEPROM I2C
+I2C i2c(I2C_SDA, I2C_SCL);
+
+// DP Sensörü
+AnalogIn dpSensor = DP_PIN;
+
+// Basınç sensörü
+AnalogIn pressureSensor = PRESSURE_PIN;
+
+// Akış sensörü
+DigitalIn flowSensor(FLOW_PIN, PullDown);
+
+// RF Reset Pin
+DigitalOut rfPower(RF_ACTIVE, 0);
+
+// Sayaç & Sayaç ISR
+DigitalIn watermeterPin(WATERMETER_PIN, PullDown);
+InterruptIn watermeterInterrupt(WATERMETER_PIN);
+
+// RF USART
+RawSerial rf(TX_RF, RX_RF);
+RawSerial master(TX_MASTER, RX_MASTER);
+
+// Zamanlayıcılar
+Timeout flushTimer;
+Timer timer;
+Ticker pressureCheckTicker;
+Ticker dataTransmitTicker;
+Ticker periodicFlushTicker;
+Ticker minFlushTicker;
+Ticker rtDataTransmitTicker;
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/function.h Mon Jul 09 09:12:38 2018 +0000
@@ -0,0 +1,1977 @@
+#ifndef FUNCTION_H
+#define FUNCTION_H
+
+/*
+ ****************************************************************************
+ ****************************************************************************
+ ** DEVINT BİLİŞİM YAZILIM DONANIM TİC. LTD. ŞTİ. TARAFINDAN GELİŞTİRİLMİŞTİR
+ ** İzmir / TÜRKİYE
+ **
+ ** Copyright (C) 2015
+ ****************************************************************************
+ ****************************************************************************
+ *************************************************************** K A M B O **
+*/
+
+// FONKSIYON PROTOTİPLERİ
+void configure_eeprom_default_values(void);
+//******************************************************************************
+
+void init_node(void);
+//******************************************************************************
+
+float read_pressure_dp(void);
+//******************************************************************************
+
+float read_pressure(void);
+//******************************************************************************
+
+void prepare_data(void);
+//******************************************************************************
+
+void prepare_data_fread(void);
+//******************************************************************************
+
+void send_to_coordinator(char* char_array);
+//******************************************************************************
+
+void process_command(uint8_t cmmnd);
+//******************************************************************************
+
+void data_transmit_isr(void);
+//******************************************************************************
+
+void rf_rx_isr(void);
+//******************************************************************************
+
+void master_rx_isr(void);
+//******************************************************************************
+
+bool open_solenoid(uint8_t filter_no);
+//******************************************************************************
+
+bool close_solenoid(uint8_t filter_no);
+//******************************************************************************
+
+float map(float x, float in_min, float in_max, float out_min, float out_max);
+//******************************************************************************
+
+void watermeter_isr(void);
+//******************************************************************************
+
+void flowrate_isr(void);
+//******************************************************************************
+
+void flush_phase_isr(void);
+//******************************************************************************
+
+void pressure_check_isr(void);
+//******************************************************************************
+
+bool check_and_close_valves(void);
+//******************************************************************************
+
+void periodic_flush_isr(void);
+//******************************************************************************
+
+void min_flush_interval_isr(void);
+//******************************************************************************
+
+void rt_data_transmit_isr(void);
+//******************************************************************************
+
+void send_alarm(uint8_t _alarmID, uint16_t _filterID, uint8_t _slaveID);
+//******************************************************************************
+
+bool send_command(uint8_t _slaveid, uint8_t _command, uint8_t _filterid);
+//******************************************************************************
+
+// FONKSIYONLAR
+float map(float x, float in_min, float in_max, float out_min, float out_max)
+{
+ return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
+}
+
+//
+bool check_and_close_valves()
+{
+ bool check = false;
+
+ for (uint8_t _slaveID = 0; _slaveID <= fnode.totalSlaveNumber - 1; _slaveID++) {
+
+ for (uint8_t _filterNo = 0; _filterNo < 5; _filterNo ++) {
+
+ if (send_command(_slaveID, CLOSE_SOLENOID, _filterNo)) {
+
+ check = true;
+ wait_ms(500);
+
+ } else {
+
+ check = false;
+
+ }
+
+ if (check == false) {
+ break;
+ }
+ }
+
+ if (check == false) {
+ break;
+ }
+ }
+
+ return check;
+}
+
+bool open_solenoid(uint8_t _filter_no)
+{
+ bool _success = false;
+
+ switch (_filter_no) {
+
+ case FILTER_1_SOLENOID: { // OUT1
+
+ // İleri
+ fnode.filterByte_2 &= ~(1 << 6); // Bit 6 = 0
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_2 &= ~(1 << 5); // Bit 5 = 0
+ fnode.filterByte_2 &= ~(1 << 4); // Bit 4 = 0
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_2 |= 1 << 4; // Bit 4 = 1
+ fnode.filterByte_2 |= 1 << 5; // Bit 5 = 1
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+
+ case FILTER_2_SOLENOID: { // OUT2
+
+ // İleri
+ fnode.filterByte_2 &= ~(1 << 3); // Bit 3 = 0
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_2 &= ~(1 << 2); // Bit 2 = 0
+ fnode.filterByte_2 &= ~(1 << 1); // Bit 1 = 0
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_2 |= 1 << 1; // Bit 1 is 1
+ fnode.filterByte_2 |= 1 << 2; // Bit 2 is 1
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+
+ case FILTER_3_SOLENOID: { // OUT3
+
+ // İleri
+ fnode.filterByte_2 &= ~(1 << 0); // Bit 0 = 0
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_1 &= ~(1 << 7); // Bit 7 = 0
+ fnode.filterByte_1 &= ~(1 << 6); // Bit 6 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_1 |= 1 << 6; // Bit 6 = 1
+ fnode.filterByte_1 |= 1 << 7; // Bit 7 = 1
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+
+ case FILTER_4_SOLENOID: { // OUT4
+
+ // İleri
+ fnode.filterByte_1 &= ~(1 << 5); // Bit 5 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_1 &= ~(1 << 4); // Bit 4 = 0
+ fnode.filterByte_1 &= ~(1 << 3); // Bit 3 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_1 |= 1 << 3; // Bit 3 = 1
+ fnode.filterByte_1 |= 1 << 4; // Bit 4 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+
+ case FILTER_MAIN_SOLENOID: { // OUT5
+
+ // İleri
+ fnode.filterByte_1 &= ~(1 << 2); // Bit 2 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_1 &= ~(1 << 1); // Bit 1 = 0
+ fnode.filterByte_1 &= ~(1 << 0); // Bit 0 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_1 |= 1 << 0; // Bit 0 = 1
+ fnode.filterByte_1 |= 1 << 1; // Bit 1 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+ }
+
+ return _success;
+}
+
+//
+bool close_solenoid(uint8_t _filter_no)
+{
+ bool _success = false;
+
+ switch (_filter_no) {
+
+ case FILTER_1_SOLENOID: { // OUT1
+
+ // Geri
+ fnode.filterByte_2 |= 1 << 6; // Bit 6 = 1
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_2 &= ~(1 << 5); // Bit 5 = 0
+ fnode.filterByte_2 &= ~(1 << 4); // Bit 4 = 0
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_2 |= 1 << 4; // Bit 4 = 1
+ fnode.filterByte_2 |= 1 << 5; // Bit 5 = 1
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+
+ case FILTER_2_SOLENOID: { // OUT2
+
+ // Geri
+ fnode.filterByte_2 |= 1 << 3; // Bit 3 = 1
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_2 &= ~(1 << 2); // Bit 2 = 0
+ fnode.filterByte_2 &= ~(1 << 1); // Bit 1 = 0
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_2 |= 1 << 1; // Bit 1 = 1
+ fnode.filterByte_2 |= 1 << 2; // Bit 2 = 1
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+
+ case FILTER_3_SOLENOID: { // OUT3
+
+ // Geri
+ fnode.filterByte_2 |= 1 << 0; // Bit 0 = 1
+ fnode.filterByte_1 = fnode.filterByte_1;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_1 &= ~(1 << 7); // Bit 7 = 0
+ fnode.filterByte_1 &= ~(1 << 6); // Bit 6 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_1 |= 1 << 6; // Bit 6 = 1
+ fnode.filterByte_1 |= 1 << 7; // Bit 7 = 1
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+
+ case FILTER_4_SOLENOID: { // OUT4
+
+ // Geri
+ fnode.filterByte_1 |= 1 << 5; // Bit 5 = 1
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_1 &= ~(1 << 4); // Bit 4 = 0
+ fnode.filterByte_1 &= ~(1 << 3); // Bit 3 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_1 |= 1 << 3; // Bit 3 = 1
+ fnode.filterByte_1 |= 1 << 4; // Bit 4 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+
+ case FILTER_MAIN_SOLENOID: { // OUT5
+
+ // Geri
+ fnode.filterByte_1 |= 1 << 2; // Bit 2 = 1
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ // H-köprüsünü aç ve uyandır
+ fnode.filterByte_1 &= ~(1 << 1); // Bit 1 = 0
+ fnode.filterByte_1 &= ~(1 << 0); // Bit 0 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ wait_ms(250);
+
+ _success = true;
+
+ // Uyut ve H-köprüsünü kapat
+ fnode.filterByte_1 |= 1 << 0; // Bit 0 = 1
+ fnode.filterByte_1 |= 1 << 1; // Bit 1 = 0
+ fnode.filterByte_2 = fnode.filterByte_2;
+
+ if (io_send(fnode.filterByte_1, fnode.filterByte_2) == true) {
+
+ _success = true;
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+
+ } else {
+
+ _success = false;
+
+ }
+ }
+ break;
+ }
+
+ return _success;
+}
+
+//
+void configure_eeprom_default_values()
+{
+ if (eeprom_read(EEPROM_TYPE, DEFAULT_CONFIG_ADDR) != 35) {
+
+ for (uint8_t i = 0; i < 99; i++) {
+
+ eeprom_write(EEPROM_TYPE, i, 0xFF);
+
+ }
+
+ eeprom_write(EEPROM_TYPE, DEFAULT_CONFIG_ADDR, 35);
+
+ eeprom_write(EEPROM_TYPE, SYSTEM_SETUP_ADDR, SYSTEM_SETUP_DEFAULT);
+ eeprom_write(EEPROM_TYPE, AUTOSEND_STATUS_ADDR, AUTOSEND_STATUS_DEFAULT);
+ eeprom_write(EEPROM_TYPE, IRRI_TRANSMIT_INTERVAL_ADDR, IRRI_TRANSMIT_INTERVAL_DEFAULT);
+ eeprom_write(EEPROM_TYPE, DRY_TRANSMIT_INTERVAL_ADDR, DRY_TRANSMIT_INTERVAL_DEFAULT);
+ eeprom_write(EEPROM_TYPE, WATERMETER_COEFF_ADDR_1, WATERMETER_COEFF_DEFAULT >> 8);
+ eeprom_write(EEPROM_TYPE, WATERMETER_COEFF_ADDR_2, WATERMETER_COEFF_DEFAULT & 0xFF);
+ eeprom_write(EEPROM_TYPE, PMAX_ADDR, PMAX_DEFAULT);
+ eeprom_write(EEPROM_TYPE, PRESSURE_SENSOR_ADDR, PRESSURE_SENSOR_DEFAULT);
+ eeprom_write(EEPROM_TYPE, DP_ADDR, DP_DEFAULT);
+ eeprom_write(EEPROM_TYPE, PRESSURE_CONTROL_FREQUENCY_ADDR, PRESSURE_CONTROL_FREQUENCY_DEFAULT);
+ eeprom_write(EEPROM_TYPE, FLUSH_DURATION_ADDR, FLUSH_DURATION_DEFAULT);
+ eeprom_write(EEPROM_TYPE, FLUSH_INTERVAL_ADDR, FLUSH_INTERVAL_DEFAULT);
+ eeprom_write(EEPROM_TYPE, FLOW_CONTROL_LATENCY_ADDR, FLOW_CONTROL_LATENCY_DEFAULT);
+ eeprom_write(EEPROM_TYPE, FLUSH_ENABLE_ADDR, FLUSH_ENABLE_DEFAULT);
+ eeprom_write(EEPROM_TYPE, PR_SENSOR_POSITION_ADDR, PR_SENSOR_POSITION_DEFAULT);
+ eeprom_write(EEPROM_TYPE, BACKFLUSH_STOP_ADDR, BACKFLUSH_STOP_DEFAULT);
+ eeprom_write(EEPROM_TYPE, INLET_PRS_LOW_TRS_ADDR, INLET_PRS_LOW_TRS_DEFAULT);
+ eeprom_write(EEPROM_TYPE, INLET_PRS_HIGH_TRS_ADDR, INLET_PRS_HIGH_TRS_DEFAULT);
+ eeprom_write(EEPROM_TYPE, ALARMS_ENABLE_ADDR, ALARMS_ENABLE_DEFAULT);
+ eeprom_write(EEPROM_TYPE, DP_HIGH_TRS_ADDR, DP_HIGH_TRS_DEFAULT);
+ eeprom_write(EEPROM_TYPE, INLET_PRS_SET_ADDR, INLET_PRS_SET_DEFAULT);
+ eeprom_write(EEPROM_TYPE, OUTLET_PRS_SET_FOR_DP_ADDR, OUTLET_PRS_SET_FOR_DP_DEFAULT);
+ eeprom_write(EEPROM_TYPE, PERIODIC_FLUSH_ADDR, PERIODIC_FLUSH_DEFAULT);
+ eeprom_write(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_1, MIN_FLUSH_INTERVAL_DEFAULT >> 8);
+ eeprom_write(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_2, MIN_FLUSH_INTERVAL_DEFAULT & 0xFF);
+ eeprom_write(EEPROM_TYPE, FILTER_NUMBER_ADDR, FILTER_NUMBER_DEFAULT);
+ }
+}
+
+//
+void init_node()
+{
+ // EEPROM'dan sistem ayarlarını oku
+ fnode.systemSetup = eeprom_read(EEPROM_TYPE, SYSTEM_SETUP_ADDR);
+
+ // Filtre sayısını hesapla
+ fnode.filterNumber = eeprom_read(EEPROM_TYPE, FILTER_NUMBER_ADDR);
+ fnode.lastFlushPhase = ((uint16_t)fnode.filterNumber * 4) + 1;
+
+ // Sayaç mevcuts ISR'yi aktifle
+ if ((fnode.systemSetup >> 3) & 1 == 1) {
+
+ watermeterInterrupt.rise(&watermeter_isr);
+
+ }
+
+ // EEPROM'dan sulama sırasında veri gönderim sıklığını oku
+ fnode.irriTransmitInterval = eeprom_read(EEPROM_TYPE, IRRI_TRANSMIT_INTERVAL_ADDR);
+
+ // EEPROM'dan sulama dışında veri gönderim sıklığını oku
+ fnode.dryTransmitInterval = eeprom_read(EEPROM_TYPE, DRY_TRANSMIT_INTERVAL_ADDR);
+
+ // EEPROM'dan otomatik veri gönderimini oku
+ if (eeprom_read(EEPROM_TYPE, AUTOSEND_STATUS_ADDR) == 1) {
+
+ fnode.autosend = true;
+
+ } else {
+
+ fnode.autosend = false;
+
+ }
+
+ if (eeprom_read(EEPROM_TYPE, IRRI_STATUS_ADDR) == 1) {
+
+ fnode.irrigation = true;
+
+ dataTransmitTicker.attach(&data_transmit_isr, fnode.irriTransmitInterval * 60);
+
+ timer.reset();
+ timer.start();
+
+ } else {
+
+ fnode.irrigation = false;
+
+ dataTransmitTicker.attach(&data_transmit_isr, fnode.dryTransmitInterval * 60);
+
+ timer.reset();
+ timer.start();
+
+ }
+
+ // EEPROM'dan sayaç katsayısını oku
+ fnode.watermeterCoefficient = (eeprom_read(EEPROM_TYPE, WATERMETER_COEFF_ADDR_1) << 8) + eeprom_read(EEPROM_TYPE, WATERMETER_COEFF_ADDR_2);
+
+ // EEPROM'dan basınç sensörünün okuyabileceği maksimum basıncı oku
+ fnode.pMax = eeprom_read(EEPROM_TYPE, PMAX_ADDR);
+
+ // EEPROM'dan basınç sensörü tipini oku (4-20 mA veya 0-3.3v)
+ fnode.pressureSensorType = eeprom_read(EEPROM_TYPE, PRESSURE_SENSOR_ADDR);
+
+ // EEPROM'dan DP set değerini oku
+ fnode.dpSet = eeprom_read(EEPROM_TYPE, DP_ADDR);
+
+ // EEPROM'dan basınç kontrol sıklığını oku
+ fnode.pressureControlFrequency = eeprom_read(EEPROM_TYPE, PRESSURE_CONTROL_FREQUENCY_ADDR);
+
+ // EEPROM'dan 1 filtre yıkama süresini oku
+ fnode.flushDuration = eeprom_read(EEPROM_TYPE, FLUSH_DURATION_ADDR);
+
+ // EEPROM'dan 2 filtre yıkaması arasındaki bekleme süresini oku
+ fnode.flushInterval = eeprom_read(EEPROM_TYPE, FLUSH_INTERVAL_ADDR);
+
+ // EEPROM'dan akış kontrolü gecikme süresini oku (Akış kontrolü filtre yıkaması başladıktan ya da bittikten kaç saniye sonra yapılacak?)
+ fnode.flowControlLatency = eeprom_read(EEPROM_TYPE, FLOW_CONTROL_LATENCY_ADDR);
+
+ // EEPROM'dan ters yıkama kontrolü aktif ya da pasif durumunu oku
+ if (eeprom_read(EEPROM_TYPE, FLUSH_ENABLE_ADDR) == 1) {
+
+ fnode.flushEnabled = 1;
+
+ } else {
+
+ fnode.flushEnabled = 0;
+
+ }
+
+ // EEPROM'dan basınç sensörünün yerleştirme noktasını oku (Filtre öncesi ya da sonrası)
+ fnode.pressureSensorPosition = eeprom_read(EEPROM_TYPE, PR_SENSOR_POSITION_ADDR);
+
+ // EEPROM'dan hata durumunda ters yıkamanın durdurulup durdurulmayacağını oku
+ if (eeprom_read(EEPROM_TYPE, BACKFLUSH_STOP_ADDR) == 0) {
+
+ fnode.onErrorStop = 0;
+
+ } else {
+
+ fnode.onErrorStop = 1;
+
+ }
+
+ fnode.pressureLowThreshold = eeprom_read(EEPROM_TYPE, INLET_PRS_LOW_TRS_ADDR);
+ fnode.pressureHighThreshold = eeprom_read(EEPROM_TYPE, INLET_PRS_HIGH_TRS_ADDR);
+
+ // Timer ve tickerları başlat
+ // Basınç sürekli kontrol edilecek
+ pressureCheckTicker.attach(&pressure_check_isr, fnode.pressureControlFrequency);
+
+ // EEPROM'dan alarmların açık/kapalı durumunu oku
+ if (eeprom_read(EEPROM_TYPE, ALARMS_ENABLE_ADDR) == 0) {
+
+ fnode.alarmsEnabled = 0;
+
+ } else {
+
+ fnode.alarmsEnabled = 1;
+
+ }
+
+ // EEPROM'dan DP alarmı eşik değerini oku
+ // Yıkama sırasında DP bu değerin üstüne çıkarsa alarm gönderilir
+ // Bazı durumlarda DP düşmeyebilir !!!
+ fnode.dpThreshold = eeprom_read(EEPROM_TYPE, DP_HIGH_TRS_ADDR);
+
+ // EEPROM'dan sulamanın başladığının anlaşılacağı giriş basıncı set değerini oku
+ fnode.inletPressureSet = eeprom_read(EEPROM_TYPE, INLET_PRS_SET_ADDR);
+
+ // EEPROM'dan DP kontrolünün başlayacağı filtrasyon çıkış basıncı set değerini oku
+ fnode.outletPressureSet = eeprom_read(EEPROM_TYPE, OUTLET_PRS_SET_FOR_DP_ADDR);
+
+ // periodicFlushInterval değeri 0 ise periyodik yıkama yapılmaz
+ fnode.periodicFlushInterval = eeprom_read(EEPROM_TYPE, PERIODIC_FLUSH_ADDR);
+
+ if (fnode.periodicFlushInterval == 0) {
+
+ fnode.periodicFlushEnabled = false;
+ periodicFlushTicker.detach();
+ fnode.periodicFlushCounter = 0;
+
+ } else {
+
+ fnode.periodicFlushEnabled = true;
+ fnode.periodicFlushCounter = 0;
+
+ // Periodic flush isr works every 1 second to increase periodicCounter by 1
+ // If periodicCounter value >= peridicFlushInterval * 3600
+ // Example:
+ // Periodic flush interval is 6 hours
+ // Periodic counter counts every 1 seconds by ISR
+ // In 1 hour there is 3600 seconds..... In 6 hours 6 * 3600 = 21600 seconds
+
+ if (fnode.irrigation == true) {
+
+ periodicFlushTicker.attach(&periodic_flush_isr, 1); // ISR set every 1 second
+
+ } else {
+
+ periodicFlushTicker.detach();
+
+ }
+ }
+
+ // minFlushInterval değeri 0'dan farklı ise DP yıkamaları min süre beklenerek yapılır
+ c23_a = eeprom_read(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_1);
+ c23_b = eeprom_read(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_2);
+ fnode.minFlushInterval = (c23_a << 8) + c23_b;
+
+ if (fnode.minFlushInterval == 0) {
+
+ fnode.minFlushEnabled = false;
+
+ } else {
+
+ fnode.minFlushEnabled = true;
+ }
+
+ if (fnode.filterNumber % 4 == 0) {
+
+ fnode.totalSlaveNumber = fnode.filterNumber / 4;
+
+ } else {
+
+ fnode.totalSlaveNumber = (fnode.filterNumber / 4) + 1;
+ }
+}
+
+//
+float read_pressure_dp()
+{
+ // Analog kanal okumasının RMS (Root Mean Square) hesaplaması
+ memset(rmsStore, 0, sizeof(rmsStore));
+ totalSampling = 0.0;
+ tempValue = 0.0;
+ tdp = 0.0;
+
+ for (uint8_t b = 0; b < RMS_SAMPLING_NUMBER; b++) {
+
+ tempValue = dpSensor.read();
+ rmsStore[b] = tempValue * tempValue;
+ totalSampling = totalSampling + rmsStore[b];
+
+ }
+
+ tdp = (sqrt ((float)((totalSampling / RMS_SAMPLING_NUMBER)))) * 4096.0f;
+ //
+
+ // Fark basınç hesaplaması, BAR, -4 ile +4 bar arası
+ // DP + 4 = ((Sensor okuması - 409.6) / 409.6) ==> Honeywell sensor katalog sadeleştirilmiş denklem
+ tdpResult = ((tdp-409.6f)/409.6f) - 4.0f;
+
+ if (tdpResult < 0) {
+
+ tdpResult = 0;
+
+ }
+
+ tdpResult = floor(tdpResult * 10) / 10;
+
+ return tdpResult;
+}
+
+//
+float read_pressure()
+{
+ // Analog kanal okumasının RMS (Root Mean Square) hesaplaması
+ memset(rmsStore, 0, sizeof(rmsStore));
+ totalSampling = 0;
+ tempValue = 0;
+ tp = 0;
+
+ for (uint8_t b = 0; b < RMS_SAMPLING_NUMBER; b++) {
+
+ tempValue = pressureSensor.read();
+ rmsStore[b] = tempValue * tempValue;
+ totalSampling = totalSampling + rmsStore[b];
+
+ }
+
+ tp = (sqrt ((float)((totalSampling / RMS_SAMPLING_NUMBER)))) * 4096.0f;
+ //
+
+ if (fnode.pressureSensorType == 0) {
+
+ // Ham analog verisinden basınç hesaplaması, BAR
+ // Honeywell Truw Stability sensörlerine özel, PSI, 3.3v, map'lenmemiş
+ tp = ((tp - 409.6f) / (3276.8f / (float)fnode.pMax)) * 0.0689476f; // 0.0689 is for psi to bar conversion;
+
+ } else {
+
+ // Ham analog verisinden basınç hesaplaması, BAR
+ // 4-20 mA sensöre özel, BAR
+ // 4 mA = 480 mV = 595.8 RAW
+ // 20 mA = 2400 mV = 2978.9 RAW
+ tp = map (tp, 595.8f, 2978.9f, 0.0f, (float)fnode.pMax);
+
+ }
+
+ if (tp < 0) {
+
+ tp = 0;
+
+ }
+
+ tp = floor(tp * 10) / 10;
+
+ return tp;
+}
+
+void prepare_data_fread()
+{
+ memset(fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Filtrasyon JSON headırını yaz
+ sprintf(fnode.temporaryBuffer, "%s", json[0]);
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Eğer basınç sensörü varsa
+ if (fnode.systemSetup & (1 << 1)) {
+
+ // Basınç sensörü varken DP sensörü de mevcutsa hem giriş hem çıkış basıncını yaz
+ if (fnode.systemSetup & (1 << 1)) {
+
+ sprintf(fnode.temporaryBuffer, "%s%.1f%c%s%.1f%c", jsonHeader[0], fnode.inletPressure, ',', jsonHeader[1], fnode.outletPressure, ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Basınç sensörü varken DP sensörü yoksa basınç sensörünün pozisyonuna göre giriş veya çıkış basıncını yaz
+ } else {
+
+ // Basınç sensörü girişte ise giriş basıncını yaz, çıkış basıncı NULL olsun
+ if (fnode.systemSetup & (1 << 1) && fnode.pressureSensorPosition == 0) {
+
+ sprintf(fnode.temporaryBuffer, "%s%.1f%c%s%s%c", jsonHeader[0], fnode.inletPressure, ',', jsonHeader[1], "null", ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Basınç sensörü çıkışta ise çıkış basıncını yaz, giriş basıncı NULL olsun
+ } else if (fnode.systemSetup & (1 << 1) && fnode.pressureSensorPosition == 1) {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c%s%.1f%c", jsonHeader[0], "null", ',', jsonHeader[1], fnode.outletPressure, ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+ }
+
+ // Basınç sensörü yoksa giriş ve çıkış basınç değerleri NULL olsun
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c%s%s%c", jsonHeader[0], "null", ',', jsonHeader[1], "null", ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+ }
+
+ // Eğer DP sensörü varsa DP verisini ekle
+ if (fnode.systemSetup & (1 << 1)) {
+
+ sprintf(fnode.temporaryBuffer, "%s%.1f%c", jsonHeader[2], fnode.dpPressure, ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // DP sensörü yoksa DP verisi NULL olsun
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c", jsonHeader[2], "null", ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ // Eğer sayaç mevcutsa su hacmi ve debi verilerini ekle
+ // İki veri gönderimi arasındaki su hacmi ve debi verisini burada hesapla
+ if (fnode.systemSetup & (1 << 3)) {
+
+ sprintf(fnode.temporaryBuffer, "%s%llu%c%s%llu%c%s%.1f%c%s%llu%c%s%llu%c%s%.1f", jsonHeader[3], fnode.rWI, ',', jsonHeader[4], fnode.rWIC, ',', jsonHeader[5], fnode.rQI, ',', jsonHeader[6], fnode.rWD, ',', jsonHeader[7], fnode.rWDC, ',', jsonHeader[8], fnode.rQD);
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c%s%s%c%s%s%c%s%s%c%s%s%c%s%s", jsonHeader[3], "null", ',', jsonHeader[4], "null", ',', jsonHeader[5], "null", ',', jsonHeader[6], "null", ',', jsonHeader[7], "null", ',', jsonHeader[8], "null");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ // Sulama durumu
+ if (fnode.irrigation == true) {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",STAT:\"IRR\"");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",STAT:\"DRY\"");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ // Yıkama durumu
+ if (fnode.flushing == true) {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",FSTAT:1");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",FSTAT:0");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ sprintf(fnode.temporaryBuffer, "%s", "},RT:1}");
+
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+}
+
+
+//
+void prepare_data()
+{
+ memset(fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Filtrasyon JSON headırını yaz
+ sprintf(fnode.temporaryBuffer, "%s", json[0]);
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Eğer basınç sensörü varsa
+ if (fnode.systemSetup & (1 << 1)) {
+
+ // Basınç sensörü varken DP sensörü de mevcutsa hem giriş hem çıkış basıncını yaz
+ if (fnode.systemSetup & (1 << 0)) {
+
+ sprintf(fnode.temporaryBuffer, "%s%.1f%c%s%.1f%c", jsonHeader[0], fnode.inletPressure, ',', jsonHeader[1], fnode.outletPressure, ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Basınç sensörü varken DP sensörü yoksa basınç sensörünün pozisyonuna göre giriş veya çıkış basıncını yaz
+ } else {
+
+ // Basınç sensörü girişte ise giriş basıncını yaz, çıkış basıncı NULL olsun
+ if (fnode.systemSetup & (1 << 1) && fnode.pressureSensorPosition == 0) {
+
+ sprintf(fnode.temporaryBuffer, "%s%.1f%c%s%s%c", jsonHeader[0], fnode.inletPressure, ',', jsonHeader[1], "null", ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Basınç sensörü çıkışta ise çıkış basıncını yaz, giriş basıncı NULL olsun
+ } else if (fnode.systemSetup & (1 << 1) && fnode.pressureSensorPosition == 1) {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c%s%.1f%c", jsonHeader[0], "null", ',', jsonHeader[1], fnode.outletPressure, ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+ }
+
+ // Basınç sensörü yoksa giriş ve çıkış basınç değerleri NULL olsun
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c%s%s%c", jsonHeader[0], "null", ',', jsonHeader[1], "null", ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+ }
+
+ // Eğer DP sensörü varsa DP verisini ekle
+ if (fnode.systemSetup & (1 << 0)) {
+
+ sprintf(fnode.temporaryBuffer, "%s%.1f%c", jsonHeader[2], fnode.dpPressure, ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // DP sensörü yoksa DP verisi NULL olsun
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c", jsonHeader[2], "null", ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ // Eğer sayaç mevcutsa su hacmi ve debi verilerini ekle
+ // İki veri gönderimi arasındaki su hacmi ve debi verisini burada hesapla
+ if (fnode.systemSetup & (1 << 3)) {
+
+ sprintf(fnode.temporaryBuffer, "%s%llu%c%s%llu%c%s%.1f%c%s%llu%c%s%llu%c%s%.1f", jsonHeader[3], fnode.WI, ',', jsonHeader[4], fnode.WIC, ',', jsonHeader[5], fnode.QI, ',', jsonHeader[6], fnode.WD, ',', jsonHeader[7], fnode.WDC, ',', jsonHeader[8], fnode.QD);
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c%s%s%c%s%s%c%s%s%c%s%s%c%s%s", jsonHeader[3], "null", ',', jsonHeader[4], "null", ',', jsonHeader[5], "null", ',', jsonHeader[6], "null", ',', jsonHeader[7], "null", ',', jsonHeader[8], "null");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ // Sulama durumu
+ if (fnode.irrigation == true) {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",STAT:\"IRR\"");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",STAT:\"DRY\"");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ // Yıkama durumu
+ if (fnode.flushing == true) {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",FSTAT:1");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",FSTAT:0");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ sprintf(fnode.temporaryBuffer, "%s", "}}");
+
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+}
+
+//
+void send_to_coordinator(char* char_array)
+{
+ rf.putc(COORD_ADDR_1);
+ rf.putc(COORD_ADDR_2);
+ rf.putc(EQUAL);
+ rf.puts(char_array);
+ rf.putc(CR);
+ wait_ms(50);
+}
+
+//
+void process_command(uint8_t cmnd)
+{
+ switch(cmnd) {
+
+ case FENABLE: {
+
+ // Eğer ters yıkama zaten akitflenmişse hata mesajı gönder
+ if (eeprom_read(EEPROM_TYPE, FLUSH_ENABLE_ADDR) == 1) {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FENABLEERR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ // Ters yıkamayı devre dışı bırak
+ } else {
+
+ // Yıkamanın devreye alındığını EEPROM'a yaz
+ eeprom_write(EEPROM_TYPE, FLUSH_ENABLE_ADDR, 1);
+
+ fnode.flushEnabled = 1;
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FENABLEOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+ }
+ break;
+
+ case FDISABLE: {
+
+ // Eğer ters yıkama zaten akitflenmişse hata mesajı gönder
+ if (eeprom_read(EEPROM_TYPE, FLUSH_ENABLE_ADDR) == 0) {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FDISABLEERR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ // Ters yıkamayı devre dışı bırak
+ } else {
+
+ // Yıkamanın devre dışı kaldığını EEPROM'a yaz
+ eeprom_write(EEPROM_TYPE, FLUSH_ENABLE_ADDR, 0);
+
+ fnode.flushEnabled = 0;
+
+ /*
+ // Yıkama zamanlayıcısını kapat
+ flushTimer.detach();
+
+ // Yıkama fazını sıfırla
+ fnode.flushPhase = 0;
+
+ // Solenoid vanaları kontrol et ve kapat
+ check_and_close_valves();
+ */
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FDISABLEOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+ }
+ break;
+
+ case FSETSYS: {
+
+ // Sistem ayarları
+ eeprom_write(EEPROM_TYPE, SYSTEM_SETUP_ADDR, fnode.systemSetup);
+
+ // Otomatik veri aktarımı
+ eeprom_write(EEPROM_TYPE, AUTOSEND_STATUS_ADDR, fnode.autosendStatus);
+
+ // Yeni set edilecek veri aktarım aralıkları eskisinden farklıysa zamanlayıcıları yeni ayarla başlat
+ // Eski ile yeni aktarım aralıkları aynı ise değişiklik yapma (Alt satırlarda)
+ irriTrsIntOld = eeprom_read(EEPROM_TYPE, IRRI_TRANSMIT_INTERVAL_ADDR);
+ eeprom_write(EEPROM_TYPE, IRRI_TRANSMIT_INTERVAL_ADDR, fnode.irriTransmitInterval);
+
+ dryTrsIntOld = eeprom_read(EEPROM_TYPE, DRY_TRANSMIT_INTERVAL_ADDR);
+ eeprom_write(EEPROM_TYPE, DRY_TRANSMIT_INTERVAL_ADDR, fnode.dryTransmitInterval);
+
+ // Sayaç katsayısı
+ eeprom_write(EEPROM_TYPE, WATERMETER_COEFF_ADDR_1, fnode.watermeterCoefficient >> 8);
+ eeprom_write(EEPROM_TYPE, WATERMETER_COEFF_ADDR_2, fnode.watermeterCoefficient & 0xFF);
+
+ // Basınç sensörü maksimum basıncı
+ eeprom_write(EEPROM_TYPE, PMAX_ADDR, fnode.pMax);
+
+ // Basınç sensörü tipi
+ eeprom_write(EEPROM_TYPE, PRESSURE_SENSOR_ADDR, fnode.pressureSensorType);
+
+ // DP set
+ eeprom_write(EEPROM_TYPE, DP_ADDR, fnode.dpSet);
+
+ // Basınç kontrol sıklığı
+ eeprom_write(EEPROM_TYPE, PRESSURE_CONTROL_FREQUENCY_ADDR, fnode.pressureControlFrequency);
+
+ // 1 filtre yıkama süresi
+ eeprom_write(EEPROM_TYPE, FLUSH_DURATION_ADDR, fnode.flushDuration);
+
+ // Yıkama aralığı
+ eeprom_write(EEPROM_TYPE, FLUSH_INTERVAL_ADDR, fnode.flushInterval);
+
+ // Akış kontrol gecikmesi
+ eeprom_write(EEPROM_TYPE, FLOW_CONTROL_LATENCY_ADDR, fnode.flowControlLatency);
+
+ // Ters yıkama devrede/devrede değil
+ eeprom_write(EEPROM_TYPE, FLUSH_ENABLE_ADDR, fnode.flushEnabled);
+
+ // Basınç sensörü pozisyonu
+ eeprom_write(EEPROM_TYPE, PR_SENSOR_POSITION_ADDR, fnode.pressureSensorPosition);
+
+ // Hata durumunda ters yıkamayı durdur/durdurma
+ eeprom_write(EEPROM_TYPE, BACKFLUSH_STOP_ADDR, fnode.onErrorStop);
+
+ // Giriş basıncı alarm alt sınır eşik
+ eeprom_write(EEPROM_TYPE, INLET_PRS_LOW_TRS_ADDR, fnode.pressureLowThreshold);
+
+ // Giriş basıncı alarm üst sınır eşik
+ eeprom_write(EEPROM_TYPE, INLET_PRS_HIGH_TRS_ADDR, fnode.pressureHighThreshold);
+
+ // Alarmlar devrede
+ eeprom_write(EEPROM_TYPE, ALARMS_ENABLE_ADDR, fnode.alarmsEnabled);
+
+ // DP alarm eşik değeri
+ eeprom_write(EEPROM_TYPE, DP_HIGH_TRS_ADDR, fnode.dpThreshold);
+
+ eeprom_write(EEPROM_TYPE, INLET_PRS_SET_ADDR, fnode.inletPressureSet);
+
+ eeprom_write(EEPROM_TYPE, OUTLET_PRS_SET_FOR_DP_ADDR, fnode.outletPressureSet);
+
+ eeprom_write(EEPROM_TYPE, PERIODIC_FLUSH_ADDR, fnode.periodicFlushInterval);
+
+ eeprom_write(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_1, fnode.minFlushInterval >> 8);
+ eeprom_write(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_2, fnode.minFlushInterval & 0xFF);
+
+ eeprom_write(EEPROM_TYPE, FILTER_NUMBER_ADDR, fnode.filterNumber);
+
+
+ // Check written SSETSYS values on EEPROM
+ c1 = eeprom_read(EEPROM_TYPE, SYSTEM_SETUP_ADDR);
+ c2 = eeprom_read(EEPROM_TYPE, AUTOSEND_STATUS_ADDR);
+ c3 = eeprom_read(EEPROM_TYPE, IRRI_TRANSMIT_INTERVAL_ADDR);
+ c4 = eeprom_read(EEPROM_TYPE, DRY_TRANSMIT_INTERVAL_ADDR);
+ c5_a = eeprom_read(EEPROM_TYPE, WATERMETER_COEFF_ADDR_1);
+ c5_b = eeprom_read(EEPROM_TYPE, WATERMETER_COEFF_ADDR_2);
+ c5 = (c5_a << 8) + c5_b;
+ c6 = eeprom_read(EEPROM_TYPE, PMAX_ADDR);
+ c7 = eeprom_read(EEPROM_TYPE, PRESSURE_SENSOR_ADDR);
+ c8 = eeprom_read(EEPROM_TYPE, DP_ADDR);
+ c9 = eeprom_read(EEPROM_TYPE, PRESSURE_CONTROL_FREQUENCY_ADDR);
+ c10 = eeprom_read(EEPROM_TYPE, FLUSH_DURATION_ADDR);
+ c11 = eeprom_read(EEPROM_TYPE, FLUSH_INTERVAL_ADDR);
+ c12 = eeprom_read(EEPROM_TYPE, FLOW_CONTROL_LATENCY_ADDR);
+ c13 = eeprom_read(EEPROM_TYPE, FLUSH_ENABLE_ADDR);
+ c14 = eeprom_read(EEPROM_TYPE, PR_SENSOR_POSITION_ADDR);
+ c15 = eeprom_read(EEPROM_TYPE, BACKFLUSH_STOP_ADDR);
+ c16 = eeprom_read(EEPROM_TYPE, INLET_PRS_LOW_TRS_ADDR);
+ c17 = eeprom_read(EEPROM_TYPE, INLET_PRS_HIGH_TRS_ADDR);
+ c18 = eeprom_read(EEPROM_TYPE, ALARMS_ENABLE_ADDR);
+ c19 = eeprom_read(EEPROM_TYPE, DP_HIGH_TRS_ADDR);
+ c20 = eeprom_read(EEPROM_TYPE, INLET_PRS_SET_ADDR);
+ c21 = eeprom_read(EEPROM_TYPE, OUTLET_PRS_SET_FOR_DP_ADDR);
+ c22 = eeprom_read(EEPROM_TYPE, PERIODIC_FLUSH_ADDR);
+ c23_a = eeprom_read(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_1);
+ c23_b = eeprom_read(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_2);
+ c23 = (c23_a << 8) + c23_b;
+ c24 = eeprom_read(EEPROM_TYPE, FILTER_NUMBER_ADDR);
+
+ // Kaydedilen değerler ile gönderilen değerleri karşılaştır
+ // Aynı ise sunucuya mesaj gönder
+ if (c1 == fnode.systemSetup && c2 == fnode.autosendStatus && c3 == fnode.irriTransmitInterval && c4 == fnode.dryTransmitInterval && c5 == fnode.watermeterCoefficient && c6 == fnode.pMax && c7 == fnode.pressureSensorType && c8 == fnode.dpSet && c9 == fnode.pressureControlFrequency && c10 == fnode.flushDuration && c11 == fnode.flushInterval && c12 == fnode.flowControlLatency && c13 == fnode.flushEnabled && c14 == fnode.pressureSensorPosition && c15 == fnode.onErrorStop && c16 == fnode.pressureLowThreshold && c17 == fnode.pressureHighThreshold && c18 == fnode.alarmsEnabled && c19 == fnode.dpThreshold && c20 == fnode.inletPressureSet && c21 == fnode.outletPressureSet && c22 == fnode.periodicFlushInterval && c23 == fnode.minFlushInterval && c24 == fnode.filterNumber) {
+
+ sprintf(fnode.dataBuffer, "%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%c", "{CMD:\"FSETSYSOK\",C1:", c1, ",C2:", c2, ",C3:", c3, ",C4:", c4, ",C5:", c5, ",C6:", c6, ",C7:", c7, ",C8:", c8, ",C9:", c9, ",C10:", c10, ",C11:", c11, ",C12:", c12, ",C13:", c13, ",C14:", c14, ",C15:", c15, ",C16:", c16, ",C17:", c17, ",C18:", c18, ",C19:", c19, ",C20:", c20, ",C21:", c21, ",C22:", c22, ",C23:", c23, ",C24:", c24, '}');
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ // YENİ SET Değerlerine göre ayarlar
+ // Filtre sayısı
+ fnode.filterNumber = c24;
+ fnode.lastFlushPhase = ((uint16_t)fnode.filterNumber * 4) + 1;
+
+ // Sayaç mevcutsa ISR'yi aktifle
+ if (fnode.systemSetup & (1 << 3)) {
+
+ watermeterInterrupt.rise(NULL);
+ watermeterInterrupt.rise(&watermeter_isr);
+
+ } else {
+
+ watermeterInterrupt.rise(NULL);
+ }
+
+ if (fnode.autosendStatus == 0) {
+
+ fnode.autosend = false;
+
+ } else {
+
+ fnode.autosend = true;
+ }
+
+ // If irrigation phase and autosend is active and new data transmission interval is different than old one attach data transmission ISR again
+ if (fnode.irrigation == true && fnode.autosend == true && irriTrsIntOld != fnode.irriTransmitInterval) {
+
+ dataTransmitTicker.detach();
+ dataTransmitTicker.attach(&data_transmit_isr, fnode.irriTransmitInterval * 60);
+
+ // If not irrigation phase and autosend is active and new data transmission interval is different than old one attach data transmission ISR again
+ } else if (fnode.irrigation == false && fnode.autosend == true && dryTrsIntOld != fnode.dryTransmitInterval) {
+
+ dataTransmitTicker.detach();
+ dataTransmitTicker.attach(&data_transmit_isr, fnode.dryTransmitInterval * 60);
+
+ // If autosend is not active detach data transmission ISR
+ } else if (fnode.autosend == false) {
+
+ dataTransmitTicker.detach();
+
+ }
+
+ // periodicFlushInterval değeri 0 ise periyodik yıkama yapılmaz
+ if (fnode.periodicFlushInterval == 0) {
+
+ fnode.periodicFlushEnabled = false;
+ periodicFlushTicker.detach();
+ fnode.periodicFlushCounter = 0;
+
+ } else {
+
+ fnode.periodicFlushEnabled = true;
+ fnode.periodicFlushCounter = 0;
+
+ // Periodic flush isr works every 1 second to increase periodicCounter by 1
+ // If periodicCounter value >= peridicFlushInterval * 3600
+ // Example:
+ // Periodic flush interval is 6 hours
+ // Periodic counter counts every 1 seconds by ISR
+ // In 1 hour there is 3600 seconds..... In 6 hours 6 * 3600 = 21600 seconds
+
+ if (fnode.irrigation == true) {
+
+ periodicFlushTicker.attach(&periodic_flush_isr, 1); // ISR set every 1 second
+
+ } else {
+
+ periodicFlushTicker.detach();
+
+ }
+ }
+
+ // minFlushInterval değeri 0'dan farklı ise DP yıkamaları min süre beklenerek yapılır
+ if (fnode.minFlushInterval == 0) {
+
+ fnode.minFlushEnabled = false;
+
+ } else {
+
+ fnode.minFlushEnabled = true;
+ }
+
+ } else {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FSETSYSERR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+ }
+ break;
+
+ case FGETCFG: {
+
+ // Get configuration from EEPROM
+ c1 = eeprom_read(EEPROM_TYPE, SYSTEM_SETUP_ADDR);
+ c2 = eeprom_read(EEPROM_TYPE, AUTOSEND_STATUS_ADDR);
+ c3 = eeprom_read(EEPROM_TYPE, IRRI_TRANSMIT_INTERVAL_ADDR);
+ c4 = eeprom_read(EEPROM_TYPE, DRY_TRANSMIT_INTERVAL_ADDR);
+ c5_a = eeprom_read(EEPROM_TYPE, WATERMETER_COEFF_ADDR_1);
+ c5_b = eeprom_read(EEPROM_TYPE, WATERMETER_COEFF_ADDR_2);
+ c5 = (c5_a << 8) + c5_b;
+ c6 = eeprom_read(EEPROM_TYPE, PMAX_ADDR);
+ c7 = eeprom_read(EEPROM_TYPE, PRESSURE_SENSOR_ADDR);
+ c8 = eeprom_read(EEPROM_TYPE, DP_ADDR);
+ c9 = eeprom_read(EEPROM_TYPE, PRESSURE_CONTROL_FREQUENCY_ADDR);
+ c10 = eeprom_read(EEPROM_TYPE, FLUSH_DURATION_ADDR);
+ c11 = eeprom_read(EEPROM_TYPE, FLUSH_INTERVAL_ADDR);
+ c12 = eeprom_read(EEPROM_TYPE, FLOW_CONTROL_LATENCY_ADDR);
+ c13 = eeprom_read(EEPROM_TYPE, FLUSH_ENABLE_ADDR);
+ c14 = eeprom_read(EEPROM_TYPE, PR_SENSOR_POSITION_ADDR);
+ c15 = eeprom_read(EEPROM_TYPE, BACKFLUSH_STOP_ADDR);
+ c16 = eeprom_read(EEPROM_TYPE, INLET_PRS_LOW_TRS_ADDR);
+ c17 = eeprom_read(EEPROM_TYPE, INLET_PRS_HIGH_TRS_ADDR);
+ c18 = eeprom_read(EEPROM_TYPE, ALARMS_ENABLE_ADDR);
+ c19 = eeprom_read(EEPROM_TYPE, DP_HIGH_TRS_ADDR);
+ c20 = eeprom_read(EEPROM_TYPE, INLET_PRS_SET_ADDR);
+ c21 = eeprom_read(EEPROM_TYPE, OUTLET_PRS_SET_FOR_DP_ADDR);
+ c22 = eeprom_read(EEPROM_TYPE, PERIODIC_FLUSH_ADDR);
+ c23_a = eeprom_read(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_1);
+ c23_b = eeprom_read(EEPROM_TYPE, MIN_FLUSH_INTERVAL_ADDR_2);
+ c23 = (c23_a << 8) + c23_b;
+ c24 = eeprom_read(EEPROM_TYPE, FILTER_NUMBER_ADDR);
+
+ sprintf(fnode.dataBuffer, "%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%s%d%c", "{CMD:\"FGETCFGOK\",C1:", c1, ",C2:", c2, ",C3:", c3, ",C4:", c4, ",C5:", c5, ",C6:", c6, ",C7:", c7, ",C8:", c8, ",C9:", c9, ",C10:", c10, ",C11:", c11, ",C12:", c12, ",C13:", c13, ",C14:", c14, ",C15:", c15, ",C16:", c16, ",C17:", c17, ",C18:", c18, ",C19:", c19, ",C20:", c20, ",C21:", c21, ",C22:", c22, ",C23:", c23, ",C24:", c24, '}');
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+ break;
+
+ case FSTART: {
+
+ if (fnode.autosend == false) {
+
+ fnode.autosend = true;
+
+ if (fnode.irrigation) {
+
+ dataTransmitTicker.detach();
+ dataTransmitTicker.attach(&data_transmit_isr, fnode.irriTransmitInterval * 60);
+
+ } else {
+
+ dataTransmitTicker.detach();
+ dataTransmitTicker.attach(&data_transmit_isr, fnode.dryTransmitInterval * 60);
+
+ }
+
+ // Save autosend enable status to EEPROM
+ eeprom_write(EEPROM_TYPE, AUTOSEND_STATUS_ADDR, 1);
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FSTARTOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ } else {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FSTARTERR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+
+ }
+ break;
+
+
+ case FSTOP: {
+
+ if (fnode.autosend == true) {
+
+ fnode.autosend = false;
+
+ dataTransmitTicker.detach();
+
+ // Save autosend disable status to EEPROM
+ eeprom_write(EEPROM_TYPE, AUTOSEND_STATUS_ADDR, 0);
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FSTOPOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ } else {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FSTOPERR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+ }
+ break;
+
+ case FFIX: {
+
+ if (fnode.errorOccured == true) {
+
+ fnode.errorOccured = false;
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FFIXOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ } else {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FFIXERR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+ }
+ break;
+
+ case FGETSTATUS: {
+
+ //STAT:"IRR"
+ if (fnode.irrigation == true) {
+
+ sprintf(fnode.dataBuffer, "%s", "{STAT:\"IRR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ //STAT:"DRY"
+ } else {
+
+ sprintf(fnode.dataBuffer, "%s", "{STAT:\"DRY\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+
+ }
+ break;
+
+ case FGETFSTATUS: {
+
+ // Flushing Now
+ if(fnode.flushing) {
+ sprintf(fnode.dataBuffer, "%s", "{STAT:\"FLUSHING\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ } else {
+
+ sprintf(fnode.dataBuffer, "%s", "{STAT:\"NOTFLUSHING\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+ }
+ break;
+
+ case FFGETSTAT: {
+
+ memset(fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Filtrasyon JSON headırını yaz
+ //sprintf(fnode.temporaryBuffer, "%s", json[0]);
+ sprintf(fnode.temporaryBuffer, "%s", "{STAT:{");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ fnode.pressure = read_pressure();
+ fnode.dpPressure = read_pressure_dp();
+
+ // Eğer basınç sensörü filtre girişinde ise basınç ve DP değerine göre giriş ve çıkış basıncını hesapla
+ // Giriş basıncı = Okunan basınç
+ // Çıkış basıncı = Okunan basınç - Fark basınç
+ if (fnode.pressureSensorPosition == 0) {
+
+ fnode.inletPressure = fnode.pressure;
+ fnode.outletPressure = fnode.pressure - fnode.dpPressure;
+
+ if (fnode.outletPressure < 0) {
+
+ fnode.outletPressure = 0;
+
+ }
+
+ // Eğer basınç sensörü filtre çıkışında ise basınç ve DP değerine göre giriş ve çıkış basıncını hesapla
+ // Giriş basıncı = Okunan basınç + Fark basınç
+ // Çıkış basıncı = Okunan basınç
+ } else {
+
+ fnode.inletPressure = fnode.pressure + fnode.dpPressure;
+ fnode.outletPressure = fnode.pressure;
+
+ }
+
+ // Eğer basınç sensörü varsa
+ if (fnode.systemSetup & (1 << 1)) {
+
+ // Basınç sensörü varken DP sensörü de mevcutsa hem giriş hem çıkış basıncını yaz
+ if (fnode.systemSetup & (1 << 1)) {
+
+ sprintf(fnode.temporaryBuffer, "%s%.1f%c%s%.1f%c", jsonHeader[0], fnode.inletPressure, ',', jsonHeader[1], fnode.outletPressure, ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Basınç sensörü varken DP sensörü yoksa basınç sensörünün pozisyonuna göre giriş veya çıkış basıncını yaz
+ } else {
+
+ // Basınç sensörü girişte ise giriş basıncını yaz, çıkış basıncı NULL olsun
+ if (fnode.systemSetup & (1 << 1) && fnode.pressureSensorPosition == 0) {
+
+ sprintf(fnode.temporaryBuffer, "%s%.1f%c%s%s%c", jsonHeader[0], fnode.inletPressure, ',', jsonHeader[1], "null", ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // Basınç sensörü çıkışta ise çıkış basıncını yaz, giriş basıncı NULL olsun
+ } else if (fnode.systemSetup & (1 << 1) && fnode.pressureSensorPosition == 1) {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c%s%.1f%c", jsonHeader[0], "null", ',', jsonHeader[1], fnode.outletPressure, ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+ }
+
+ // Basınç sensörü yoksa giriş ve çıkış basınç değerleri NULL olsun
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s%s%c%s%s%c", jsonHeader[0], "null", ',', jsonHeader[1], "null", ',');
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+ }
+
+ // Eğer DP sensörü varsa DP verisini ekle
+ if (fnode.systemSetup & (1 << 1)) {
+
+ sprintf(fnode.temporaryBuffer, "%s%.1f", jsonHeader[2], fnode.dpPressure);
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ // DP sensörü yoksa DP verisi NULL olsun
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s%s", jsonHeader[2], "null");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+
+ // Sulama durumu
+ if (fnode.irrigation == true) {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",STAT:\"IRR\"");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",STAT:\"DRY\"");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ // Yıkama durumu
+ if (fnode.flushing == true) {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",FSTAT:1");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ } else {
+
+ sprintf(fnode.temporaryBuffer, "%s", ",FSTAT:0");
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ }
+
+ sprintf(fnode.temporaryBuffer, "%s", "},RT:1}");
+
+ strcat(fnode.dataBuffer, fnode.temporaryBuffer);
+ memset (fnode.temporaryBuffer, 0, sizeof(fnode.temporaryBuffer));
+
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ }
+ break;
+
+ // Elle yıkamayı başlat
+ case FLUSHNOW: {
+
+ // Eğer zaten yıkama varsa
+ if(fnode.flushing == true) {
+
+ send_alarm(ALREADY_FLUSHING, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ // Yıkama yoksa başla
+ } else if (fnode.flushEnabled == 1 && fnode.errorOccured == false) {
+
+ periodicFlushTicker.detach();
+ fnode.periodicFlushCounter = 0;
+
+ fnode.flushing = true;
+ fnode.flushStarted = true;
+ fnode.checkDp = false;
+
+ minFlushTicker.detach();
+ fnode.minFlushCounter = 0;
+ fnode.isMinTimePassed = false;
+
+ fnode.globalFlushPhase = 1;
+ fnode.currentFlushPhase = 1;
+ fnode.globalFlushingFilter = 1;
+ fnode.currentFlushingFilter = 1;
+ fnode.currentWorkingSlave = 0;
+
+ send_alarm(BACKFLUSH_MANUAL_STARTED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ } else if (fnode.flushEnabled == 0 && fnode.errorOccured == false) {
+
+ send_alarm(FLUSH_DISABLED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ }
+ }
+ break;
+ }
+}
+
+bool send_command(uint8_t _slaveid, uint8_t _command, uint8_t _filterid)
+{
+ bool _ackinit = false;
+
+ if (_slaveid == MASTER_ID) {
+
+ if (_command == OPEN_SOLENOID || _command == TEST_OPEN_SOLENOID) {
+
+ if (open_solenoid(_filterid) == true) {
+
+ _ackinit = true;
+
+ }
+
+ } else if (_command == CLOSE_SOLENOID || _command == TEST_CLOSE_SOLENOID) {
+
+ if (close_solenoid(_filterid)) {
+
+ _ackinit = true;
+
+ }
+ }
+
+ } else {
+
+ fnode.masterTxBuffer[0] = MASTER_ID;
+ fnode.masterTxBuffer[1] = _slaveid;
+ fnode.masterTxBuffer[2] = _command;
+ fnode.masterTxBuffer[3] = _filterid;
+ fnode.masterTxBuffer[4] = 0x0D;
+
+ for (uint8_t i = 0; i < sizeof(fnode.masterTxBuffer); i++) {
+
+ for (uint8_t j = 0; j < 3; j++) {
+
+ if (master.putc(fnode.masterTxBuffer[i]) == fnode.masterTxBuffer[i]) {
+
+ _ackinit = true;
+
+ } else {
+
+ _ackinit = false;
+
+ }
+
+ if (_ackinit == true) {
+
+ break;
+
+ }
+ }
+
+ if (_ackinit == false) {
+
+ break;
+
+ }
+ }
+
+ // Slave'den cevap tamamlanıncaya/gelinceye kadar bekle (ISR ile tamamlanır)
+ while (fnode.masterInterruptComplete != true) {}
+
+ if (fnode.masterInterruptComplete == true) {
+
+ if (fnode.masterRxBuffer[0] == _OK_) {
+
+ _ackinit = true;
+
+ } else {
+
+ _ackinit = false;
+
+ }
+ }
+
+
+ memset (fnode.masterRxBuffer, 0, sizeof(fnode.masterRxBuffer));
+ master.attach(&master_rx_isr, Serial::RxIrq);
+
+ fnode.masterInterruptComplete = false;
+ }
+
+ return _ackinit;
+}
+
+// Data aktarım ISR
+void data_transmit_isr()
+{
+ fnode.transmitData = true;
+}
+
+// RF Rx ISR
+void rf_rx_isr()
+{
+ fnode.rfBufferChar = rf.getc();
+
+ if (fnode.rfBufferChar != '\r') {
+
+ fnode.rfBuffer[fnode.rfBufferCounter] = fnode.rfBufferChar;
+ fnode.rfBufferCounter++;
+
+ } else if (fnode.rfBufferChar == '\r') {
+
+ rf.attach(NULL, Serial::RxIrq);
+ fnode.rfBufferCounter = 0;
+ fnode.rfInterruptComplete = true;
+ }
+}
+
+void master_rx_isr()
+{
+ fnode.masterBufferChar = master.getc();
+
+ if (fnode.masterBufferChar != '\r') {
+
+ fnode.masterRxBuffer[fnode.masterBufferCounter] = fnode.masterBufferChar;
+ fnode.masterBufferCounter++;
+
+ } else if (fnode.masterBufferChar == '\r') {
+
+ master.attach(NULL, Serial::RxIrq);
+ fnode.masterBufferCounter = 0;
+ fnode.masterInterruptComplete = true;
+ }
+}
+
+// Sayaç pals ISR
+void watermeter_isr()
+{
+ fnode.pulse ++;
+ fnode.pulseTransmit ++;
+ fnode.pulsePressureCheck ++;
+}
+
+// Yıkama fazı değişim ISR
+void flush_phase_isr()
+{
+ fnode.flush_isr = true;
+}
+
+// Basınç kontrol ISR
+void pressure_check_isr()
+{
+ fnode.checkPressure = true;
+}
+
+void periodic_flush_isr()
+{
+ fnode.periodicFlushCounter ++;
+}
+
+void min_flush_interval_isr()
+{
+ fnode.minFlushCounter ++;
+}
+
+void rt_data_transmit_isr()
+{
+ fnode.transmit_rtData = true;
+ fnode.rtCounter ++;
+}
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/i2c.h Mon Jul 09 09:12:38 2018 +0000
@@ -0,0 +1,96 @@
+#ifndef _I2C_H_
+#define _I2C_H_
+/*
+ ****************************************************************************
+ ****************************************************************************
+ ** DEVINT BİLİŞİM YAZILIM DONANIM TİC. LTD. ŞTİ. TARAFINDAN GELİŞTİRİLMİŞTİR
+ ** İzmir / TÜRKİYE
+ **
+ ** (C) 2015
+ ****************************************************************************
+ ****************************************************************************
+ *************************************************************** K A M B O **
+*/
+
+// FONKSIYON PROTOTİPLERİ
+void eeprom_write(uint8_t eepromtype, uint16_t memory_address, uint8_t value);
+//******************************************************************************
+
+uint8_t eeprom_read(uint8_t eepromtype, uint16_t memory_address);
+//******************************************************************************
+
+bool io_send(uint8_t first_byte, uint8_t second_byte);
+//******************************************************************************
+
+//
+void eeprom_write(uint8_t eepromtype, uint16_t memory_address, uint8_t val)
+{
+ if (eepromtype == 1) { // 1 bayt adresleme
+
+ fnode.edata2[0] = memory_address;
+ fnode.edata2[1] = val;
+ i2c.write(EEPROM_ADDRESS, fnode.edata2, 2, false);
+ wait_ms(10);
+
+ } else { // 2 bayt adresleme
+
+ fnode.edata3[0] = memory_address >> 8;
+ fnode.edata3[1] = memory_address & 0xFF;
+ fnode.edata3[2] = val;
+ i2c.write(EEPROM_ADDRESS, fnode.edata3, 3, false);
+ wait_ms(10);
+
+ }
+}
+
+//
+uint8_t eeprom_read(uint8_t eepromtype, uint16_t memory_address)
+{
+ if (eepromtype == 1) { // 1 bayt adresleme
+
+ fnode.edata = memory_address;
+ i2c.write(EEPROM_ADDRESS, &fnode.edata, 1, true);
+ wait_ms(5);
+ i2c.read(EEPROM_ADDRESS, &fnode.value, 1, false);
+ wait_ms(10);
+
+ return (uint8_t)fnode.value;
+
+ } else { // 2 bayt adresleme
+
+ fnode.edata2[0] = memory_address >> 8;
+ fnode.edata2[1] = memory_address & 0xFF;
+ i2c.write(EEPROM_ADDRESS, fnode.edata2, 2, true);
+ wait_ms(5);
+ i2c.read(EEPROM_ADDRESS, &fnode.value, 1, false);
+ wait_ms(10);
+
+ return (uint8_t)fnode.value;
+
+ }
+}
+
+//
+//
+bool io_send(uint8_t first_byte, uint8_t second_byte)
+{
+ bool _success = false;
+
+ fnode.iodata[0] = first_byte;
+ fnode.iodata[1] = second_byte;
+
+ // Try max. 3 times
+ for (uint8_t i = 0; i < 3; i++) {
+
+ if (i2c.write(IO_EXPANDER_ADDRESS, fnode.iodata, 2) == 0) {
+ _success = true;
+ }
+
+ if (_success == true) {
+ break;
+ }
+ }
+
+ return _success;
+}
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main_filtration.cpp Mon Jul 09 09:12:38 2018 +0000
@@ -0,0 +1,1008 @@
+/*
+ ****************************************************************************
+ ****************************************************************************
+ ** DEVINT BİLİŞİM YAZILIM DONANIM TİC. LTD. ŞTİ. TARAFINDAN GELİŞTİRİLMİŞTİR
+ ** İzmir / TÜRKİYE
+ **
+ ** Copyright (C) 2015
+ ****************************************************************************
+ ****************************************************************************
+*/
+
+#include "mbed.h"
+#include "define.h"
+#include "i2c.h"
+#include "function.h"
+#include "alerts.h"
+
+int main ()
+{
+// RF Modül açık
+ rfPower = 1;
+ wait_ms(50);
+
+// RF UART: 38400 Kbit, 8 Data Bits, No Parity, 1 Stop Bit
+ rf.baud(BAUD_SERIAL_RF);
+ rf.format(8, SerialBase::None, 1);
+
+// MASTER UART: 115200 Kbit, 8 Data Bits, No Parity, 1 Stop Bit
+ master.baud(BAUD_MASTER);
+ master.format(8, SerialBase::None, 1);
+
+// UART Rx ISR
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+// MASTER Rx ISR
+ master.attach(&master_rx_isr, Serial::RxIrq);
+
+// EEPROM frekansı 100 KHz
+ i2c.frequency(EEPROM_FREQUENCY);
+ wait_ms(1500);
+
+// EEPROM'a ilk çalışma için varsayılan konfigürasyonları yaz
+ configure_eeprom_default_values();
+
+// EEPROM'dan konfigürasyonu oku
+ init_node();
+
+// PCF pinleri LOW
+ io_send(fnode.filterByte_1, fnode.filterByte_2);
+ wait_ms(1500);
+
+ check_and_close_valves();
+
+ while(1) {
+
+
+ if (fnode.flush_isr == true) {
+
+ fnode.flush_isr = false;
+
+ if (fnode.globalFlushPhase != fnode.lastFlushPhase) {
+
+ fnode.globalFlushPhase ++;
+ fnode.currentFlushPhase ++;
+
+ if (fnode.currentFlushPhase > 4) {
+
+ fnode.globalFlushingFilter ++;
+ fnode.currentFlushingFilter ++;
+
+ fnode.currentFlushPhase = 1;
+ }
+
+ if (fnode.currentFlushingFilter > 4) {
+
+ fnode.currentWorkingSlave ++;
+ fnode.currentFlushingFilter = 1;
+
+ }
+ }
+
+ fnode.flushStarted = true;
+ }
+
+ // 30 sn aralıkla 10 kez veri gönderim koşulu oluşmuşsa
+ if (fnode.transmit_rtData == true) {
+
+ if (fnode.irrigation == true) {
+
+ fnode.rWIC = 0;
+ fnode.rWI = (fnode.rtPulseFirst - fnode.pulse) * fnode.watermeterCoefficient;
+ fnode.rQI = (float)fnode.rWI / (float)RT_DATA_TRANSMIT_INTERVAL;
+ fnode.rtPulseFirst = fnode.pulse;
+
+ } else {
+
+ fnode.rWDC = 0;
+ fnode.rWD = (fnode.rtPulseFirst - fnode.pulse) * fnode.watermeterCoefficient;
+ fnode.rQD = (float)fnode.rWD / (float)RT_DATA_TRANSMIT_INTERVAL;
+ fnode.rtPulseFirst = fnode.pulse;
+
+ }
+
+ fnode.transmit_rtData = false;
+
+ prepare_data_fread();
+
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ if (fnode.rtCounter >= 10) {
+ rtDataTransmitTicker.detach();
+ fnode.rtCounter = 0;
+ fnode.rtActive = false;
+ fnode.rtPulseFirst = 0;
+
+ send_to_coordinator("{CMD:\"FRTOFFOK\"}");
+ memset(fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+ wait_ms(50);
+ }
+ }
+
+ // Otomatik veri aktarım koşulu oluşmuşsa
+ if (fnode.transmitData == true) {
+
+ fnode.transmitData = false;
+
+ if (fnode.irrigation == true) {
+
+ fnode.WIC = fnode.pulse * fnode.watermeterCoefficient;
+ fnode.WI = fnode.pulseTransmit * fnode.watermeterCoefficient;
+ fnode.QI = (float)fnode.WI / timer.read();
+
+ } else {
+
+ fnode.WDC = fnode.pulse * fnode.watermeterCoefficient;
+ fnode.WD = fnode.pulseTransmit * fnode.watermeterCoefficient;
+ fnode.QD = (float)fnode.WD / timer.read();
+
+ }
+
+ fnode.pulseTransmit = 0;
+
+ timer.reset();
+
+ prepare_data();
+
+ // Otomatik veri aktarımı açıksa veriyi gönder
+ if (fnode.autosend == true) {
+ send_to_coordinator(fnode.dataBuffer);
+ }
+
+ memset(fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+ }
+
+ // İki DP yıkaması arasında min bekleme süresinin hesaplanması
+ if (fnode.minFlushEnabled == true && (fnode.minFlushCounter >= fnode.minFlushInterval * 60)) {
+
+ minFlushTicker.detach();
+ fnode.isMinTimePassed = true;
+ fnode.minFlushCounter = 0;
+ }
+
+ // PERIYODIK YIKAMA
+ // Filtrasyon nodunda ters yıkamalara izin verilmişse && şu an ters yıkama yoksa (manual ya da DP ile aktiflenmiş) && sulama varsa && önceden hata oluşmamışsa && periyodik yıkamanın kullanımı aktif edilmişse
+ //if (fnode.flushEnabled == 1 && fnode.flushing == false && fnode.irrigation == true && fnode.errorOccured == false && fnode.periodicFlushEnabled == true) {
+ if (fnode.flushEnabled == 1 && fnode.flushing == false && fnode.errorOccured == false && fnode.periodicFlushEnabled == true) {
+
+ // Periyodik sayaç periyot değerine ulaşmışsa yıkamayı başlat
+ if (fnode.periodicFlushCounter >= fnode.periodicFlushInterval * 60 * 60) {
+
+ // Periyot zamanlayıcısını iptal et ve periyot sayaç değerini sıfırla
+ periodicFlushTicker.detach();
+ fnode.periodicFlushCounter = 0;
+
+ // Yıkama zamanlayıcısını iptal et ve minimum zaman sayacını sıfırla
+ minFlushTicker.detach();
+ //fnode.isMinTimePassed = true;
+ fnode.minFlushCounter = 0;
+
+ // Şu an periyodik yıkama yapılıyor koşuluna geç
+ fnode.flushing = true;
+
+ fnode.checkDp = false;
+ fnode.flushStarted = true;
+
+ // Yıkama fazı 1
+ fnode.globalFlushPhase = 1;
+ fnode.currentFlushPhase = 1;
+ fnode.globalFlushingFilter = 1;
+ fnode.currentFlushingFilter = 1;
+ fnode.currentWorkingSlave = 0;
+
+ send_alarm(BACKFLUSH_PERIODIC_STARTED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+ }
+ }
+
+ if (fnode.checkPressure == true) {
+
+ fnode.checkPressure = false;
+
+ fnode.pressure = read_pressure();
+ fnode.dpPressure = read_pressure_dp();
+
+ // Eğer basınç sensörü filtre girişinde ise basınç ve DP değerine göre giriş ve çıkış basıncını hesapla
+ // Giriş basıncı = Okunan basınç
+ // Çıkış basıncı = Okunan basınç - Fark basınç
+ if (fnode.pressureSensorPosition == 0) {
+
+ fnode.inletPressure = fnode.pressure;
+ fnode.outletPressure = fnode.pressure - fnode.dpPressure;
+
+ if (fnode.outletPressure < 0) {
+
+ fnode.outletPressure = 0;
+
+ }
+
+ // Eğer basınç sensörü filtre çıkışında ise basınç ve DP değerine göre giriş ve çıkış basıncını hesapla
+ // Giriş basıncı = Okunan basınç + Fark basınç
+ // Çıkış basıncı = Okunan basınç
+ } else {
+
+ fnode.inletPressure = fnode.pressure + fnode.dpPressure;
+ fnode.outletPressure = fnode.pressure;
+
+ }
+
+ // Eğer alarmlar aktifse ve giriş basıncı set edilen alt alarm eşik değerinin altında ise ve alarm daha önce gönderilmemişse alarm gönder
+ // Alarm gönderme işlemi alarm bölgesi değiştiğinde tekrar devreye girer
+ if (fnode.alarmsEnabled == 1) {
+
+ if (fnode.inletPressure < (float)fnode.pressureLowThreshold / 10.0f && fnode.pressureLowError == false) {
+
+ fnode.pressureLowError = true;
+ fnode.pressureNormalError = false;
+ fnode.pressureHighError = false;
+
+ // Düşük
+ send_alarm(INLET_LOW_PRESSURE, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ // Eğer giriş basıncı set edilen güvenli bölge içinde ise alarm gönder
+ } else if (fnode.inletPressure >= (float)fnode.pressureLowThreshold / 10.0f && fnode.inletPressure <= (float)fnode.pressureHighThreshold / 10.0f && fnode.pressureNormalError == false) {
+
+ fnode.pressureLowError = false;
+ fnode.pressureNormalError = true;
+ fnode.pressureHighError = false;
+
+ // Normal
+ send_alarm(INLET_NORMAL_PRESSURE, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ // Eğer giriş basıncı set edilen üst alarm eşik değerinin üstünde ise alarm gönder
+ } else if (fnode.inletPressure > (float)fnode.pressureHighThreshold / 10.0f && fnode.pressureHighError == false) {
+
+ fnode.pressureLowError = false;
+ fnode.pressureNormalError = false;
+ fnode.pressureHighError = true;
+
+ // Yüksek
+ send_alarm(INLET_HIGH_PRESSURE, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ }
+ }
+
+ // Giriş basıncı set edilen değerin altında ise sulamanın bittiği kabul edilir
+ // SULAMA DIŞI
+ if (fnode.inletPressure < (float)fnode.inletPressureSet / 10.0f) {
+
+ // Giriş basıncı set edilen değerden düşükse önce son kez data gönderilir, sonrasında sulama bitti (filtrasyondan su geçişi durdu) alarmı gönderilir
+ if (fnode.irrigation == true) {
+
+ fnode.irrigation = false;
+
+ dataTransmitTicker.detach();
+
+ // Sulama bitince periyodik sayıcıyı durdur ancak counterı sıfırlama (Pause)
+ // Sulama başlayınca saymaya devam edecek
+ periodicFlushTicker.detach();
+
+ // Min yıkama aralığını durdur
+ minFlushTicker.detach();
+ fnode.minFlushCounter = 0;
+
+ // Sulama bitince sulama sırasında geçen su miktarlarını ve debiyi hesapla
+ fnode.WI = fnode.pulseTransmit * fnode.watermeterCoefficient;
+ fnode.WIC = fnode.pulse * fnode.watermeterCoefficient;
+ fnode.QI = (float)fnode.WI / timer.read();
+
+ // Sulama dışı değişkenleri sıfırla
+ fnode.WD = 0;
+ fnode.WDC = 0;
+ fnode.QD = 0;
+
+ // Basınç alarmlarını sıfırla
+ fnode.pressureLowError = false;
+ fnode.pressureNormalError = false;
+ fnode.pressureHighError = false;
+
+ // Timerı resetle
+ timer.reset();
+
+ // Pals sayaç ISR değişkenlerini sıfırla
+ fnode.pulse = 0;
+ fnode.pulseTransmit = 0;
+ fnode.pulsePressureCheck = 0;
+
+ // SULAMA BİTTİĞİNDE SON KEZ DATA GÖNDER !!!
+ prepare_data();
+ if (fnode.autosend == true) {
+ send_to_coordinator(fnode.dataBuffer);
+ }
+ memset(fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ // SULAMANIN BİTTİĞİNİ BELİRTEN ALARMI GÖNDER !!!
+ send_alarm(IRRIGATION_ENDED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ // Sulama sırasında geçen su miktarını sıfırla
+ fnode.WIC = 0;
+ fnode.WI = 0;
+ fnode.QI = 0;
+
+ // Veri aktarım aralığını sulama dışı sıklığa ayarla
+ dataTransmitTicker.attach(&data_transmit_isr, fnode.dryTransmitInterval * 60);
+
+ // Sulamanın bittiğini EEPROM'a yaz
+ eeprom_write(EEPROM_TYPE, IRRI_STATUS_ADDR, 0);
+
+ }
+
+ // Giriş basıncı set değerinin üzerine çıktığında filtrasyon aktive olur. (Kendi başına çalışma koşulu)
+ // Bu durumda çıkış basıncının set edilen değere ulaşıp ulaşmadığına bakılır
+ //(SULAMA)
+ } else if (fnode.inletPressure >= (float)fnode.inletPressureSet / 10.0f) {
+
+ // Giriş basıncı set edilen değerden yüksekse sulama başladı (filtrasyondan su geçişi var) alarmı gönderilir
+ if (fnode.irrigation == false) {
+
+ fnode.irrigation = true;
+
+ dataTransmitTicker.detach();
+
+ fnode.WDC = fnode.pulse * fnode.watermeterCoefficient;
+ fnode.WD = fnode.pulseTransmit * fnode.watermeterCoefficient;
+ fnode.QD = (float)fnode.WD / timer.read();
+
+ timer.reset();
+
+ fnode.pulse = 0;
+ fnode.pulseTransmit = 0;
+ fnode.pulsePressureCheck = 0;
+
+ fnode.WI = 0;
+ fnode.WIC = 0;
+ fnode.QI = 0;
+
+ // Basınç alarmlarını sıfırla
+ fnode.pressureLowError = false;
+ fnode.pressureNormalError = false;
+ fnode.pressureHighError = false;
+
+ // Veri aktarım aralığını sulama sıklığına ayarla
+ dataTransmitTicker.attach(&data_transmit_isr, fnode.irriTransmitInterval * 60);
+
+ //Sulama başlayınca ilk sulama verisini gönder
+ prepare_data();
+ if (fnode.autosend == true) {
+ send_to_coordinator(fnode.dataBuffer);
+ }
+ memset(fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ // Sulama başlayınca sulama başladı alarmını gönder
+ send_alarm(IRRIGATION_STARTED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ fnode.WD = 0;
+ fnode.WDC = 0;
+ fnode.QD = 0;
+
+ // Periyodik yıkama süresini yeniden başlat
+ fnode.periodicFirstStartCounter ++;
+
+ if (fnode.periodicFirstStartCounter == 1) {
+
+ periodicFlushTicker.attach(&periodic_flush_isr, 1);
+ fnode.periodicFlushCounter = 0;
+
+ } else if (fnode.periodicFirstStartCounter > 1) {
+
+ fnode.periodicFirstStartCounter = 2;
+
+ if (fnode.periodicFlushCounter >= fnode.periodicFlushInterval * 60 * 60) {
+
+ fnode.periodicFlushCounter = 0;
+ periodicFlushTicker.attach(&periodic_flush_isr, 1);
+
+ } else {
+
+ periodicFlushTicker.attach(&periodic_flush_isr, 1);
+
+ }
+ }
+
+ // Min yıkama aralığını yeniden başlat
+ fnode.minFlushCounter = 0;
+
+ // Sulamanın başladığını EEPROM'a yaz
+ eeprom_write(EEPROM_TYPE, IRRI_STATUS_ADDR, 1);
+
+ }
+
+ // Sulama yapılıyorsa ve sayaç mevcutsa geçen su miktarlarını sulama süresince her basınç kontrolü yapıldığında hesapla
+ if ((fnode.systemSetup >> 3) & 1) {
+
+ fnode.WIC = fnode.pulse * fnode.watermeterCoefficient;
+ fnode.WI = fnode.pulsePressureCheck * fnode.watermeterCoefficient;
+ fnode.QI = (float)fnode.WI / (float)fnode.pressureControlFrequency;
+
+ fnode.pulsePressureCheck = 0;
+
+ }
+
+ // Eğer çıkış basıncı set edilen değere ulaşmışsa DP de kontrol edilir (Çıkış basıncı stabil durumda, DP kontrolü başlayacak). Ancak o an periyodik yıkama veya elle yıkama olmamaması ve ters yıkamanın kapatılmamaış olması ve iki yıkama arasındaki min sürenin geçmiş olması gerekir.
+ if ((fnode.outletPressure >= (float)fnode.outletPressureSet / 10.0f) && fnode.flushing == false && fnode.flushEnabled == 1 && fnode.isMinTimePassed == true) {
+
+ if (fnode.dpControlStarted == false) {
+
+ fnode.dpControlStarted = true;
+
+ fnode.globalFlushPhase = 1;
+ fnode.currentFlushPhase = 1;
+ fnode.globalFlushingFilter = 1;
+ fnode.currentFlushingFilter = 1;
+ fnode.currentWorkingSlave = 0;
+
+ send_alarm(DP_CONTROL_STARTED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ }
+
+ // DP set edilen değerden yüksekse ve hata durumu yoksa ve ters yıkama aktiflenmişse ve o an yıkama yapılmıyorsa ve min bekleme zamanı geçmişse ters yıkamayı başlat
+ if (fnode.dpPressure >= (float)(fnode.dpSet / 10.0f) && fnode.checkDp == true && fnode.errorOccured == false && fnode.flushEnabled == 1 && fnode.flushing == false && fnode.isMinTimePassed == true) {
+
+ // Periyodik yıkama ISR'sini durdur ve sayacı sıfırla
+ periodicFlushTicker.detach();
+ fnode.periodicFlushCounter = 0;
+
+ fnode.isMinTimePassed = false;
+ fnode.minFlushCounter = 0;
+
+ fnode.checkDp = false;
+
+ fnode.flushing = true;
+ fnode.flushStarted = true;
+
+ // Yıkama fazı 1
+ fnode.globalFlushPhase = 1;
+ fnode.currentFlushPhase = 1;
+ fnode.globalFlushingFilter = 1;
+ fnode.currentFlushingFilter = 1;
+ fnode.currentWorkingSlave = 0;
+
+ send_alarm(BACKFLUSH_DP_STARTED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ }
+ }
+ }
+ }
+
+// YIKAMA FAZLARI
+ if (fnode.currentFlushPhase == 1 && fnode.flushStarted == true) {
+
+ // Ters yıkama bitirme fazı
+ if (fnode.globalFlushPhase == fnode.lastFlushPhase) {
+
+ fnode.flushStarted = false;
+
+ send_alarm(BAKCFLUSH_ENDED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ // DP kontrolünü yeniden başlat
+ fnode.checkDp = true;
+ fnode.flushing = false;
+ fnode.dpControlStarted = false;
+
+ // Yıkama bitti
+ // Sulama varsa periyodik sayaç resetlenir ve devam eder
+ // Sulama yoksa periyodik sayaç pause moduna alınır
+
+ if (fnode.irrigation == true) {
+
+ fnode.periodicFlushCounter = 0;
+ periodicFlushTicker.attach(&periodic_flush_isr, 1);
+
+ } else {
+
+ periodicFlushTicker.detach();
+
+ }
+
+ // Yıkama bittiği için min yıkama süresi sayacını etkinleştir
+ fnode.minFlushCounter = 0;
+ fnode.isMinTimePassed = false;
+
+ if (fnode.irrigation == true) {
+
+ minFlushTicker.attach(&min_flush_interval_isr, 1);
+
+ } else {
+
+ minFlushTicker.detach();
+
+ }
+
+ } else {
+
+ fnode.flushStarted = false;
+ fnode.flowControl = false;
+
+ // SOLENOIDLER ACIK
+ if (open_solenoid(FILTER_MAIN_SOLENOID) == false) {
+
+ // ALARM
+ }
+
+ if (send_command(fnode.currentWorkingSlave, OPEN_SOLENOID, fnode.currentFlushingFilter) == false) {
+
+ // SEND ERROR ALARM
+
+ } else {
+
+ send_alarm(FILTER_FLUSH_STARTED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ }
+
+ // Faz 2'yi zamanla
+ flushTimer.attach(&flush_phase_isr, (float)fnode.flowControlLatency);
+ }
+
+
+ } else if (fnode.currentFlushPhase == 2 && fnode.flushStarted == true) {
+
+ fnode.flushStarted = false;
+ fnode.flowControl = true;
+
+ // Faz 3'ü zamanla
+ flushTimer.attach(&flush_phase_isr, (float)(fnode.flushDuration - fnode.flowControlLatency));
+
+ } else if (fnode.currentFlushPhase == 3 && fnode.flushStarted == true) {
+
+ fnode.flushStarted = false;
+ fnode.flowControl = false;
+
+ // SOLENOIDLER KAPALI
+ if (close_solenoid(FILTER_MAIN_SOLENOID) == false) {
+
+ // ALARM
+ }
+
+ if (send_command(fnode.currentWorkingSlave, CLOSE_SOLENOID, fnode.currentFlushingFilter) == false) {
+
+ // SEND ERROR ALARM
+
+ } else {
+
+ send_alarm(FILTER_FLUSH_ENDED, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ }
+
+ // Faz 4'ü zamanla
+ flushTimer.attach(&flush_phase_isr, (float)fnode.flowControlLatency);
+
+ } else if (fnode.currentFlushPhase == 4 && fnode.flushStarted == true) {
+
+ fnode.flushStarted = false;
+ fnode.flowControl = true;
+
+ // Sonraki ya da son fazı zamanla
+ flushTimer.attach(&flush_phase_isr, (float)(fnode.flushInterval - fnode.flowControlLatency));
+ }
+
+
+
+// AKIŞ SENSÖRÜ KONTROLÜ
+// YIKAMA SIRASINDA
+// Filtre yıkanırken AKIŞ YOK hatası:
+ if (fnode.currentFlushPhase == 2 && flowSensor.read() == 0 && fnode.flowControl == true) {
+
+ // Eğer hata olduğunda ters yıkama duracaksa
+ if (fnode.onErrorStop == 1) {
+
+ fnode.flowControl = false;
+
+ // Faz zamanlayıcısını kapat
+ flushTimer.detach();
+
+ fnode.errorOccured = true;
+ fnode.flushing = false;
+
+ // SOLENOIDLER KAPALI
+ if (close_solenoid(FILTER_MAIN_SOLENOID) == false) {
+
+ // ALARM
+ }
+
+
+ if (send_command(fnode.currentWorkingSlave, CLOSE_SOLENOID, fnode.currentFlushingFilter) == false) {
+
+
+ } else {
+
+ send_alarm(NO_FLOW_DURING_FLUSH, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ }
+
+ fnode.globalFlushPhase = 0;
+ fnode.currentFlushPhase = 0;
+ fnode.globalFlushingFilter = 0;
+ fnode.currentFlushingFilter = 0;
+ fnode.currentWorkingSlave = 0;
+
+ // Yıkama bittiği için periyodik yıkama sayacını aktifleştir.
+ fnode.periodicFlushCounter = 0;
+ periodicFlushTicker.attach(&periodic_flush_isr, 1);
+
+ } else {
+
+ fnode.flowControl = false;
+
+ // Filtre yıkaması sırasında akış yok hatası
+ send_alarm(NO_FLOW_DURING_FLUSH, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ }
+
+
+//----------------------------------------------------------------------------//
+ // YIKAMA SONRASINDA
+ // Filtre yıkaması arasında AKIŞ VAR hatası:
+ } else if (fnode.currentFlushPhase == 4 && flowSensor.read() == 1 && fnode.flowControl == true) {
+
+ // Eğer hata olduğunda ters yıkama duracaksa
+ if (fnode.onErrorStop == 1) {
+
+ fnode.flowControl = false;
+
+ // Faz zamanlayıcısını kapat
+ flushTimer.detach();
+
+ fnode.errorOccured = true;
+ fnode.flushing = false;
+
+ // 1. ve ana solenoid Faz 4'de kapatıldığı için kapatmaya gerek yok.
+
+ send_alarm(FLOW_DURING_FLUSH, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ fnode.globalFlushPhase = 0;
+ fnode.currentFlushPhase = 0;
+ fnode.globalFlushingFilter = 0;
+ fnode.currentFlushingFilter = 0;
+ fnode.currentWorkingSlave = 0;
+
+ // Yıkama bittiği için periyodik yıkama sayacını aktifleştir.
+ fnode.periodicFlushCounter = 0;
+ periodicFlushTicker.attach(&periodic_flush_isr, 1);
+
+ } else {
+
+ fnode.flowControl = false;
+
+ // Filtre yıkaması arasında akış var hatası
+ send_alarm(FLOW_DURING_FLUSH, fnode.globalFlushingFilter, fnode.currentWorkingSlave);
+
+ }
+ }
+
+
+ // WSN Komutlarının İşlenmesi
+ if (fnode.rfInterruptComplete == true) {
+
+ // FENABLE
+ if (strncmp (fnode.rfBuffer, fenable_command, 7) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FENABLE);
+
+ // FDISABLE
+ } else if (strncmp (fnode.rfBuffer, fdisable_command, 8) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FDISABLE);
+
+ // FSETSYS
+ } else if (strncmp (fnode.rfBuffer, fsetsys_command, 7) == 0) {
+
+ sscanf (fnode.rfBuffer,"%s%hhd%hhd%hhd%hhd%hd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hhd%hd%hhd", fnode.str, &fnode.systemSetup, &fnode.autosendStatus, &fnode.irriTransmitInterval, &fnode.dryTransmitInterval, &fnode.watermeterCoefficient, &fnode.pMax, &fnode.pressureSensorType, &fnode.dpSet, &fnode.pressureControlFrequency, &fnode.flushDuration, &fnode.flushInterval, &fnode.flowControlLatency, &fnode.flushEnabled, &fnode.pressureSensorPosition, &fnode.onErrorStop, &fnode.pressureLowThreshold, &fnode.pressureHighThreshold, &fnode.alarmsEnabled, &fnode.dpThreshold, &fnode.inletPressureSet, &fnode.outletPressureSet, &fnode.periodicFlushInterval, &fnode.minFlushInterval, &fnode.filterNumber);
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+ memset (fnode.str, 0, sizeof(fnode.str));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FSETSYS);
+
+ // FGETCFG
+ } else if (strncmp(fnode.rfBuffer, fgetcfg_command, 7) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FGETCFG);
+
+ // FREAD
+ } else if (strncmp(fnode.rfBuffer, fread_command, 5) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FREAD);
+
+ // FFIX
+ } else if (strncmp(fnode.rfBuffer, ffix_command, 4) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FFIX);
+
+ // FTEST
+ } else if (strncmp(fnode.rfBuffer, ftest_command, 5) == 0) {
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FTESTOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ // FRESET komutu
+ } else if (strncmp(fnode.rfBuffer, freset_command, 6) == 0) {
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ if (fnode.irrigation == true) {
+
+ eeprom_write(EEPROM_TYPE, IRRI_STATUS_ADDR, 1);
+
+ } else {
+
+ eeprom_write(EEPROM_TYPE, IRRI_STATUS_ADDR, 0);
+
+ }
+
+ if (fnode.autosend == true) {
+
+ eeprom_write(EEPROM_TYPE, AUTOSEND_STATUS_ADDR, 1);
+
+ } else {
+
+ eeprom_write(EEPROM_TYPE, AUTOSEND_STATUS_ADDR, 0);
+
+ }
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FRESETOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ wait(1);
+ NVIC_SystemReset();
+
+ // FCLEAR
+ } else if (strncmp(fnode.rfBuffer, fclear_command, 6) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ bool eepromOk = true;
+
+ for (uint16_t i = 0; i < 60; i++) {
+
+ eeprom_write(EEPROM_TYPE, i, 0xFF);
+
+ }
+
+ for (uint16_t i = 0; i < 60; i++) {
+
+ if (eeprom_read(EEPROM_TYPE, i) != 0xFF) {
+
+ eepromOk = false;
+
+ }
+ }
+
+ if (eepromOk == true) {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FCLEAROK\"}");
+
+ } else {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FCLEARERR\"}");
+
+ }
+
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ // FGETSTATUS
+ } else if (strncmp(fnode.rfBuffer, fgetstatus_command, 10) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FGETSTATUS);
+
+ // FFGETSTAT
+ } else if (strncmp(fnode.rfBuffer, ffgetstat_command, 9) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FFGETSTAT);
+
+ // FGETFSTATUS
+ } else if (strncmp(fnode.rfBuffer, fgetfstatus_command, 11) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FGETFSTATUS);
+
+ // FLUSHNOW
+ } else if (strncmp(fnode.rfBuffer, fflushnow_command, 9) == 0) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ process_command(FLUSHNOW);
+
+ // FRTON
+ } else if (strncmp(fnode.rfBuffer, frton_command, 5) == 0) {
+
+ if(fnode.rtActive == false) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FRTONOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ fnode.rtCounter = 0;
+ fnode.rtActive = true;
+
+ fnode.rtPulseFirst = fnode.pulse;
+
+ rtDataTransmitTicker.attach(&rt_data_transmit_isr, RT_DATA_TRANSMIT_INTERVAL);
+
+ } else {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FRTONERROR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ }
+
+ // FRTOFF
+ } else if (strncmp(fnode.rfBuffer, frtoff_command, 6) == 0) {
+
+ if (fnode.rtActive == true) {
+
+ rtDataTransmitTicker.detach();
+
+ fnode.rtCounter = 0;
+ fnode.rtActive = false;
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FRTOFFOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ } else {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"FRTOFFERROR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ }
+
+ // GETFRTSTATUS
+ } else if (strncmp(fnode.rfBuffer, getfrtstatus_command, 12) == 0) {
+
+ if (fnode.rtActive == true) {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"GETFRTSTATUS\",STAT:\"ACTIVE\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ } else {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"GETFRTSTATUS\",STAT:\"PASSIVE\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ }
+
+ // SELTESTON
+ } else if (strncmp(fnode.rfBuffer, selteston_command, 9) == 0) {
+
+ sscanf (fnode.rfBuffer,"%s%hhd%hhd", fnode.str, &fnode.testid, &fnode.testFilterNo);
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+ memset (fnode.str, 0, sizeof(fnode.str));
+
+ if (send_command(fnode.testid, TEST_OPEN_SOLENOID, fnode.testFilterNo) == true) {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"SELTESTONOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ } else {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"SELTESTONERROR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+ }
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ // SELTESTOFF
+ } else if (strncmp(fnode.rfBuffer, seltestoff_command, 10) == 0) {
+
+ sscanf (fnode.rfBuffer,"%s%hhd%hhd", fnode.str, &fnode.testid, &fnode.testFilterNo);
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+ memset (fnode.str, 0, sizeof(fnode.str));
+
+ if (send_command(fnode.testid, TEST_CLOSE_SOLENOID, fnode.testFilterNo) == true) {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"SELTESTOFFOK\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ } else {
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"SELTESTOFFERROR\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+ }
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+
+ // TANIMSIZ KOMUT
+ } else {
+
+ memset (fnode.rfBuffer, 0, sizeof(fnode.rfBuffer));
+
+ sprintf(fnode.dataBuffer, "%s", "{CMD:\"UNKNOWN COMMAND\"}");
+ send_to_coordinator(fnode.dataBuffer);
+ memset (fnode.dataBuffer, 0, sizeof(fnode.dataBuffer));
+
+ fnode.rfInterruptComplete = false;
+ rf.attach(&rf_rx_isr, Serial::RxIrq);
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Jul 09 09:12:38 2018 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/a7c7b631e539 \ No newline at end of file