1

Dependencies:   mbed

main_filtration.cpp

Committer:
meric
Date:
2018-07-09
Revision:
0:2a01c5a56ed1

File content as of revision 0:2a01c5a56ed1:

/*
    ****************************************************************************
    ****************************************************************************
    ** 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);
            }
        }
    }
}