Why does my RA go into feeding mode randomly

Basic / Standard Reef Angel hardware
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Why does my RA go into feeding mode randomly

Post by lnevo »

You have to open the Arduino app by right clicking and do Show package contents..i can check the path for you later tonight.
javisaman
Posts: 63
Joined: Thu Jun 30, 2011 7:27 am

Re: Why does my RA go into feeding mode randomly

Post by javisaman »

Okay I found the path. Thanks! Plugged in the RF module again to (without updating the source) to see what happens. I moved the usb cable as well to another one on the hub. Before it was right next to the one that was connected to the relay expansion. I'll see if I have anymore random feeding modes, if I do, I'll try the replacement code.
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

I'm having the exact same issue, random feeding mode, as the others have reported. I replaced my twi.c file as well and will report back if the issue remains so that we can gather more data. Thanks guys.
Image
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

My RA just went into feeding mode again on its own. This was after replacing the twi.c file and re-uploading my ino.

Here's a pic of my relay activity in case it helps. You can see the history of the random feeding mode by looking at my Return pump behavior (orange). It's tied to my skimmer (purple).

Image

and my code:

Code: Select all

    #include <ReefAngel_Features.h>
    #include <Globals.h>
    #include <RA_Wifi.h>
    #include <Wire.h>
    #include <OneWire.h>
    #include <Time.h>
    #include <DS1307RTC.h>
    #include <InternalEEPROM.h>
    #include <RA_NokiaLCD.h>
    #include <RA_ATO.h>
    #include <RA_Joystick.h>
    #include <LED.h>
    #include <RA_TempSensor.h>
    #include <Relay.h>
    #include <RA_PWM.h>
    #include <Timer.h>
    #include <Memory.h>
    #include <RA_Colors.h>
    #include <RA_CustomColors.h>
    #include <RF.h>
    #include <ReefAngel.h>
    #include <SunLocation.h>
    #include <WaterLevel.h>
    #include <Tide.h>
    #include <Moon.h>
    #include <WiFiAlert.h>
    #include <InternalEEPROM.h>
    #include <avr/wdt.h>

    // Custom menus
    #include <avr/pgmspace.h>
    prog_char menu1_label[] PROGMEM = "Refugium Light";
    prog_char menu2_label[] PROGMEM = "Feeding Mode";
    prog_char menu3_label[] PROGMEM = "Water Change";
    prog_char menu4_label[] PROGMEM = "Vortech Mode";
    prog_char menu5_label[] PROGMEM = "ATO Clear";
    prog_char menu6_label[] PROGMEM = "Overheat Clear";
    prog_char menu7_label[] PROGMEM = "PH Calibration";
    prog_char menu8_label[] PROGMEM = "WLS Calibration";
    prog_char menu9_label[] PROGMEM = "Date / Time";

    // Group the menu entries together
    PROGMEM const char *menu_items[] = {
    menu1_label, menu2_label, menu3_label,
    menu4_label, menu5_label, menu6_label,
    menu7_label, menu8_label, menu9_label
    };

    // Define Custom Memory Locations
    #define Mem_B_MoonSlope       100
//    #define Mem_B_Vacation        101
//    #define Mem_B_AutoFeed        102
//    #define Mem_B_AutoFeedPress   103
//    #define Mem_B_AutoFeedRepeat  104
//    #define Mem_B_AutoFeedOffset  105
    #define Mem_I_WCFillTime      106
    #define Mem_I_Latitude        108
    #define Mem_I_Longitude       110
//    #define Mem_B_AcclRiseOffset  112
//    #define Mem_B_AcclSetOffset   113
//    #define Mem_B_AcclDay         114
//    #define Mem_B_SwabbieRepeat   115
//    #define Mem_B_SwabbieTime     116
    #define Mem_B_TideMin         117
    #define Mem_B_TideMax         118
    #define Mem_B_PumpOffset      119
    #define Mem_B_FeedingRF       120
    #define Mem_B_NightRF         121
    #define Mem_B_NightSpeed      122
    #define Mem_B_NightDuration   123
    #define Mem_B_NTMSpeed        124
    #define Mem_B_NTMDuration     125
    #define Mem_B_NTMDelay        126
    #define Mem_B_NTMTime         127
    #define Mem_I_CalDP1Vol       128
    #define Mem_I_CalDP1Time      130
    #define Mem_I_DP1Volume       132
    #define Mem_I_CalDP2Vol       134
    #define Mem_I_CalDP2Time      136
    #define Mem_I_DP2Volume       138
//    #define Mem_B_LogATO          140
//    #define Mem_B_LogPrevATO      141
//    #define Mem_B_RateAlarm       142
    #define Mem_B_TideMode        143
//    #define Mem_B_MaintGAC        144
//    #define Mem_B_MaintGFO        145
//    #define Mem_B_MaintCal        146
//    #define Mem_B_MaintAlk        147
//    #define Mem_B_MaintWC         148
//    #define Mem_B_MaintATO        149
//    #define Mem_B_MaintFeeding    150
//    #define Mem_B_MaintSkimmer    151
//    #define Mem_B_MaintSocks      152
//    #define Mem_B_MaintWCVol      153
    #define Mem_I_CalDP3Vol       154
    #define Mem_I_CalDP3Time      156
    #define Mem_I_DP3Volume       158

    #define Mem_B_PrintDebug      198
    #define Mem_B_ResetMemory     199

    void init_memory() {
      // Initialize Custom Memory Locations
      InternalMemory.write(Mem_B_MoonSlope,60);
      //InternalMemory.write(Mem_B_Vacation,false);
      //InternalMemory.write(Mem_B_AutoFeed,true);
      //InternalMemory.write(Mem_B_AutoFeedPress,2);
      //InternalMemory.write(Mem_B_AutoFeedRepeat,4);
      //InternalMemory.write(Mem_B_AutoFeedOffset,3);
      InternalMemory.write_int(Mem_I_WCFillTime,240);
      InternalMemory.write_int(Mem_I_Latitude,31);
      InternalMemory.write_int(Mem_I_Longitude,-118);
      //InternalMemory.write(Mem_B_AcclRiseOffset,4);
      //InternalMemory.write(Mem_B_AcclSetOffset,2);
      //InternalMemory.write(Mem_B_AcclDay,0);
      //InternalMemory.write(Mem_B_SwabbieRepeat,6); 
      //InternalMemory.write(Mem_B_SwabbieTime,1); 
      InternalMemory.write(Mem_B_TideMin,10);
      InternalMemory.write(Mem_B_TideMax,30);
      //InternalMemory.write(Mem_B_PumpOffset,70);
      InternalMemory.write(Mem_B_FeedingRF,true);
      InternalMemory.write(Mem_B_NightRF,false);
      InternalMemory.write(Mem_B_NightSpeed,30);
      InternalMemory.write(Mem_B_NightDuration,10);
      InternalMemory.write(Mem_B_NTMSpeed,65);
      InternalMemory.write(Mem_B_NTMDuration,5);
      InternalMemory.write(Mem_B_NTMDelay,15);
      InternalMemory.write(Mem_B_NTMTime,150);
      InternalMemory.write_int(Mem_I_CalDP1Vol,11); 
      InternalMemory.write_int(Mem_I_CalDP1Time,600); 
      InternalMemory.write_int(Mem_I_DP1Volume,30); 
      InternalMemory.write_int(Mem_I_CalDP2Vol,11); 
      InternalMemory.write_int(Mem_I_CalDP2Time,600);   
      InternalMemory.write_int(Mem_I_DP2Volume,30);   
      InternalMemory.write_int(Mem_I_CalDP3Vol,3); 
      InternalMemory.write_int(Mem_I_CalDP3Time,270);   
      InternalMemory.write_int(Mem_I_DP3Volume,0);     
      //InternalMemory.write(Mem_B_RateAlarm,15);
      InternalMemory.write(Mem_B_TideMode,0);

      //InternalMemory.write(Mem_B_LogATO,0);
      //InternalMemory.write(Mem_B_LogPrevATO,0);
    //  InternalMemory.write(Mem_B_MaintGAC,0);
    //  InternalMemory.write(Mem_B_MaintGFO,0);
    //  InternalMemory.write(Mem_B_MaintCal,0);
    //  InternalMemory.write(Mem_B_MaintAlk,0);
      //InternalMemory.write(Mem_B_MaintWC,0);
      //InternalMemory.write(Mem_B_MaintATO,0);
      //InternalMemory.write(Mem_B_MaintFeeding,0);
      //InternalMemory.write(Mem_B_MaintSkimmer,0);
      //InternalMemory.write(Mem_B_MaintSocks,0);

      InternalMemory.write(Mem_B_ResetMemory,false);
    }

    #define NUMBERS_8x16

    // Define Portal Variables
    #define Var_Feedings     0
    #define Var_DPump1       1
    #define Var_DPump2       2
    #define Var_AcclDay      3
    #define Var_Tide         4
    #define Var_TideMode     5
    #define Var_LogATO       6
    #define Var_WCVol        7

    // Define Relay Ports by Name
    #define RightLED           1   
    #define ATOSump            2
    #define MidLED             3
    #define Heater             4   
    #define Skimmer            5
    #define SumpCirc           6
    #define Return             7
    #define WaveRight          8
    //#define WhiteLEDs          3
    //#define BlueLEDs           4
    //#define Extension          5
    //#define Refugium           7
    //#define Reactor            8

    #define LeftLED            Box1_Port1
    #define Vortech1           Box1_Port2
    #define Reflights          Box1_Port3
    #define Dosing             Box1_Port4
    #define TBD2               Box1_Port5
    #define WaveLeft           Box1_Port6
    #define Feeder             Box1_Port7
    #define ATOres             Box1_Port8

    //#define Swabbie            Box1_Port1
    //#define Feeder             Box1_Port2

    //#define Vortech2           Box1_Port4
    //#define VortechUPS         Box1_Port5
    //#define Unused             Box1_Port6
    //#define DPump1             Box1_Port7
    //#define DPump2             Box1_Port8

    #define VO_RefillATO       Box2_Port1
    #define VO_EnableATO       Box2_Port2
    #define VO_StartFill       Box2_Port3
    #define VO_Vacation        Box2_Port4
    #define VO_AutoFeed        Box2_Port5
    #define VO_Unused          Box2_Port6
    #define VO_Calibrate       Box2_Port7
    #define VO_LockPorts       Box2_Port8

    ////// Place global variable code below here

    boolean dosing=false;
    byte vtechmode;
    //boolean bFeeding=false;

    // Custom classes
    SunLocation sun;
    Tide tide;

    // Vortech Variables
    byte vtMode, vtSpeed, vtDuration;

    // Needs to be global for DrawCustomGraph()
    int ScreenID=1;
    ////// Place global variable code above here

    // Setup on controller startup/reset
    void setup()
    {
      // This must be the first line
      //wdt_enable(WDTO_1S);
      ReefAngel.Init();  //Initialize controller
      ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items)); // Initialize Menu
      ReefAngel.AddWaterLevelExpansion();  // Water Level Expansion Module       
      // Ports toggled in Feeding Mode
      ReefAngel.FeedingModePorts = Port7Bit | Port5Bit ;
      ReefAngel.FeedingModePortsE[0] = 0;
      // Ports toggled in Water Change Mode
      ReefAngel.WaterChangePorts = Port4Bit | Port5Bit | Port6Bit | Port7Bit | Port8Bit;
      ReefAngel.WaterChangePortsE[0] = Port2Bit;
      // Ports toggled when Lights On / Off menu entry selected
      ReefAngel.LightsOnPorts = Box1_Port3;
      // Ports turned off when Overheat temperature exceeded
      ReefAngel.OverheatShutoffPorts = Port4Bit ;
      ReefAngel.OverheatShutoffPortsE[0] = 0;
      // Use T1 probe as temperature and overheat functions
      ReefAngel.TempProbe = T1_PROBE;
      ReefAngel.OverheatProbe = T1_PROBE;
       
      // Ports that default on
      ReefAngel.Relay.On(Return);
      ReefAngel.Relay.On(ATOSump);
      ReefAngel.Relay.On(Vortech1);
      ReefAngel.Relay.On(SumpCirc);
      //ReefAngel.Relay.On(VortechUPS);
      //ReefAngel.Relay.On(VO_LockPorts);     
     
      // Ports that default off
      //ReefAngel.Relay.Off(Extension);
      //ReefAngel.Relay.Off(Swabbie);
      //ReefAngel.Relay.Off(Feeder);
      //ReefAngel.Relay.Off(Unused);
       
      ////// Place additional initialization code below here
      ReefAngel.RF.UseMemory=false;
      randomSeed(now()/SECS_PER_DAY);
       
      if (InternalMemory.read(Mem_B_ResetMemory))
        init_memory();
      ////// Place additional initialization code above here
    }

    void loop()
    {
      //ReefAngel.MoonLights(Refugium);
      //ReefAngel.ActinicLights(BlueLEDs);
      //ReefAngel.StandardLights(WhiteLEDs);
      ReefAngel.StandardHeater( (Heater),751,780 );
      //ReefAngel.StandardLights( (Skimmer),0,0,20,0 );
      ReefAngel.StandardLights( (WaveRight),6,0,11,30 );
      ReefAngel.DosingPumpRepeat( (Dosing),0,60,10 );
      ReefAngel.StandardLights( (WaveLeft),11,30,17,30 );


      ////// Place your custom code below here
//      CheckPower();           // Monitor for power outages
//      CheckSwitches();        // Monitor for float switches
//      SetSun();               // Setup Sun rise/set lighting
      SetMoon();              // Setup Moon rise/set lighting
      SetTide();              // Set High/Low tide properties
      SetRF();                // Set Vortech modes
//      CheckATO();             // Calculate ATO reservoir evaporation
//      RefillATO();            // Automatic ATO reservoir refill
//      Vacation();             // Automation while on Vacation
//      LogFeedings();          // Track a relay
//      RunFeeder();            // Automatic Fish feeder
//      RunSwabbie();           // Skimmer neck cleaner
//      RunDosingPumps();       // Dose by volume or time
//      LogDosingPumps();       // Keep track of dosing
//      CalibrateDPumps();      // Calibrate Dosing pumps
//      AutoWaterChange();      // Automated water change
//      Reminders();            // Increment maintenance counters
//      LockPorts();            // Clear overrides for critical ports
     
      DelayedOnModes(Skimmer); // DelayedOn after mode change only
      
    //Dosing
    if (ReefAngel.Params.PH<800 && !dosing)
    {
      ReefAngel.Timer[1].Start();
      ReefAngel.Timer[2].Start();
      ReefAngel.Relay.On((Dosing));
      dosing=true;
    }
 
    if (ReefAngel.Timer[1].IsTriggered())
    {
      ReefAngel.Relay.Off((Dosing));
    }
 
    if (ReefAngel.Timer[2].IsTriggered())
    {
      dosing=false;
    }
    
    if (ReefAngel.Params.PH>855 && dosing)
    {
      ReefAngel.Relay.Off((Dosing));
    }

      //ATO Res.
      ReefAngel.WaterLevelATO( Box1_Port8,600,10,80 );
      
      //Skimmer failsafe
    if (ReefAngel.Relay.Status((Return)) != 1)
    {
    ReefAngel.Relay.Off((Skimmer));
    }
      
      ////// Place your custom code above here


      // This should always be the last line
      ReefAngel.Portal( "aranax" , "");
      ReefAngel.ShowInterface();
    }

/*    void CheckPower() {
      static boolean powerOutage=false;
      static WiFiAlert powerAlert;

      // Power Outage - turn off everything
      if (!ReefAngel.Relay.IsRelayPresent(EXP1_RELAY)) // Expansion Relay NOT present
      {
        powerOutage=true;
        ReefAngel.Relay.Off(Skimmer);
        //ReefAngel.Relay.Off(WhiteLEDs);
        //ReefAngel.Relay.Off(BlueLEDs);
        //ReefAngel.Relay.Off(Extension);
        ReefAngel.Relay.Off(Heater);
        //ReefAngel.Relay.Off(Refugium);
        //ReefAngel.Relay.Off(Reactor);
        ReefAngel.Relay.Off(Vortech1);
        //ReefAngel.Relay.Off(Vortech2);
        //ReefAngel.Relay.Off(VortechUPS);
        powerAlert.Send("Power+outage!");
      }

      // Power Restored - Turn things back on
      if (powerOutage && ReefAngel.Relay.IsRelayPresent(EXP1_RELAY))
      {
        LastStart=now();
        powerOutage=false;
        //ReefAngel.Relay.On(Reactor);
        ReefAngel.Relay.On(Vortech1);
        //ReefAngel.Relay.On(Vortech2);
        //ReefAngel.Relay.On(VortechUPS);
        powerAlert.Send("Power+restored.",true);
      }
    }

    void CheckSwitches() {
      static boolean returnOverride=true;
      static WiFiAlert switchAlert, skimmerAlert, atoAlert;
      skimmerAlert.SetDelay(3600);
      atoAlert.SetDelay(3600);
     
      if (ReefAngel.DisplayedMenu==FEEDING_MODE || ReefAngel.DisplayedMenu==WATERCHANGE_MODE)
       returnOverride=true;
     
      // Turn off return if sump overflowing or out of water in return
      ReefAngel.ReverseATOHigh(); // swap switch behavior so we can reuse as ATO
      if (!ReefAngel.HighATO.IsActive()) { // switch on by default
        if (!returnOverride) {
          switchAlert.Send("Sump+level+alarm!+Return+pump+disabled.");
          ReefAngel.Relay.Override(Return,0);
          returnOverride=true;
        }
      } else {
        returnOverride=false;
      }

      // Turn off Skimmer if waste collector is full.
      if (!ReefAngel.LowATO.IsActive()) { // switch is on by default
        skimmerAlert.Send("Skimmate+container+full!+Skimmer+disabled.");
        ReefAngel.Relay.Override(Skimmer,0);
        if (InternalMemory.read(Mem_B_MaintSkimmer) > 0) // Reset last Skimmer counter
          InternalMemory.write(Mem_B_MaintSkimmer,0);
      }
     
      // Turn off Skimmer if Return pump has been shutoff.   
      if (!ReefAngel.Relay.Status(Return)) {
        ReefAngel.Relay.Override(Skimmer,0);
      }
     
      // Alert if ATO timeput flag
      if (bitRead(ReefAngel.AlertFlags,ATOTimeOutFlag))
        atoAlert.Send("ATO+timeout!+ATO+disabled.");
    }

    void SetSun() {
      // Start acclimation routine
      int acclRiseOffset=InternalMemory.read(Mem_B_AcclRiseOffset)*60;
      int acclSetOffset=InternalMemory.read(Mem_B_AcclSetOffset)*60;
      byte acclDay=InternalMemory.read(Mem_B_AcclDay);
      ReefAngel.CustomVar[Var_AcclDay]=acclDay;

      // See if we are acclimating corals and decrease the countdown each day
      static boolean acclCounterReady=false;
      if (now()%SECS_PER_DAY!=0) acclCounterReady=true;
      if (now()%SECS_PER_DAY==0 && acclCounterReady && acclDay>0) {
        acclDay--;
        acclCounterReady=false;
        InternalMemory.write(Mem_B_AcclDay,acclDay);
     } 
      // End acclimation
      
      sun.Init(InternalMemory.read_int(Mem_I_Latitude), InternalMemory.read_int(Mem_I_Longitude));
      sun.SetOffset(-1,(acclDay*acclRiseOffset),-1,(-acclDay*acclSetOffset)); // Bahamas
      sun.CheckAndUpdate(); // Calculate today's Sunrise / Sunset
    } */
    
    void SetMoon() {
    // rfi
      byte offset=InternalMemory.read(Mem_B_MoonSlope);
     
      byte startD=InternalMemory.read(Mem_B_PWMSlopeStartD);
      byte endD=InternalMemory.read(Mem_B_PWMSlopeEndD);
      byte timeD=InternalMemory.read(Mem_B_PWMSlopeDurationD);

      byte startA=InternalMemory.read(Mem_B_PWMSlopeStartA);
      byte endA=InternalMemory.read(Mem_B_PWMSlopeEndA);
      byte timeA=InternalMemory.read(Mem_B_PWMSlopeDurationA);

      static byte mp=MoonPhase();
     
      if (mp!=MoonPhase()) {
        InternalMemory.write(Mem_B_PWMSlopeEndD,mp);
        InternalMemory.write(Mem_B_PWMSlopeEndA,mp);
        mp=MoonPhase();
      }
     
      moon_init(InternalMemory.read_int(Mem_I_Latitude), InternalMemory.read_int(Mem_I_Longitude));
     
      ReefAngel.PWM.SetDaylight(PWMSlope(Moon.riseH,Moon.riseM,Moon.setH,Moon.setM, startD,endD,timeD,0));
      ReefAngel.PWM.SetActinic(PWMSlope(Moon.riseH,Moon.riseM,Moon.setH,Moon.setM, startA,endA,timeA,0));
    }

    void SetTide() {
    // rfi
      byte nightSpeed=InternalMemory.read(Mem_B_NightSpeed);
      byte tideMin=InternalMemory.read(Mem_B_TideMin);
      byte tideMax=InternalMemory.read(Mem_B_TideMax);

      // Set tide offsets
      tide.SetOffset(tideMin, tideMax);     
      // Set tide speed. Slope in/out of Night Mode
      tide.SetSpeed(PWMSlope(sun.GetRiseHour()-1,sun.GetRiseMinute(),
        sun.GetSetHour(),sun.GetSetMinute(),nightSpeed+tideMin,vtSpeed,120,nightSpeed+tideMin));

      // Show tide info on portal
      ReefAngel.CustomVar[Var_Tide]=tide.CalcTide();
    }

    void SetRF() {
      int ntmDelay=InternalMemory.read(Mem_B_NTMDelay)*60;
      int ntmTime=InternalMemory.read(Mem_B_NTMTime)*60;
      boolean nightRF=InternalMemory.read(Mem_B_NightRF);
      boolean feedingRF=InternalMemory.read(Mem_B_FeedingRF);
      static time_t t;

      vtMode=InternalMemory.RFMode_read();
      vtSpeed=InternalMemory.RFSpeed_read();
      vtDuration=InternalMemory.RFDuration_read();

      if ((now()-t > ntmDelay && now()-t < ntmTime+ntmDelay) && feedingRF) {
        // Post feeding mode
        vtMode=Smart_NTM;
        vtSpeed=InternalMemory.read(Mem_B_NTMSpeed);
        vtDuration=InternalMemory.read(Mem_B_NTMDuration);
      } else if (!sun.IsDaytime() && nightRF) {
        vtMode=Night;
        vtSpeed=InternalMemory.read(Mem_B_NightSpeed);
        vtDuration=InternalMemory.read(Mem_B_NightDuration);
      } else {
        if (vtMode!=Night && ReefAngel.RF.Mode==Night)
          ReefAngel.RF.SetMode(Night_Stop,0,0);
      }

      if (ReefAngel.DisplayedMenu==FEEDING_MODE) {
        t=now(); // Run post feeding mode when this counter stops
      } else if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE) {
        ReefAngel.RF.SetMode(Constant,25,0);
      } else {
        if ((vtMode==Smart_NTM) || (vtMode==ShortPulse)) vtDuration=InternalMemory.read(Mem_B_NTMDuration);
        (vtMode==Custom) ? RFCustom() : ReefAngel.RF.SetMode(vtMode,vtSpeed,vtDuration);
      }
    }

    void RFCustom() {
      static boolean changeMode;
      byte rcSpeed, rcSpeedAS;

      // Define new modes
      const int BHazard=15;
      const int Else=16;
      const int Sine=17;
     
      byte tideSpeed=tide.CalcTide();
      byte tideMin=InternalMemory.read(Mem_B_TideMin);
      byte tideMax=InternalMemory.read(Mem_B_TideMax);
      byte tideMode=InternalMemory.read(Mem_B_TideMode);
      float pumpOffset=(float) InternalMemory.read(Mem_B_PumpOffset)/100;

      byte RandomModes[]={ ReefCrest, TidalSwell, Smart_NTM, Lagoon, ShortPulse, LongPulse, BHazard, Else, Sine };

      if (now()%SECS_PER_DAY!=0) changeMode=true;
      if ((now()%SECS_PER_DAY==0 && changeMode)) {
        tideMode=random(100)%sizeof(RandomModes);
        InternalMemory.write(Mem_B_TideMode,tideMode);
        changeMode=false;
      }
     
      ReefAngel.CustomVar[Var_TideMode]=tideMode+1;

      switch (RandomModes[tideMode]) {
        case ReefCrest: {
          rcSpeed=ReefCrestMode(tideSpeed,vtDuration*2,true);
          rcSpeedAS=ReefCrestMode(tideSpeed,vtDuration*2,false);
          break;
        }
        case Lagoon: {
          rcSpeed=ReefCrestMode(tideSpeed,vtDuration,true);
          rcSpeedAS=ReefCrestMode(tideSpeed,vtDuration,false);
          break;
        }
        case TidalSwell: {
          rcSpeed=TidalSwellMode(tideSpeed,true);
          rcSpeedAS=TidalSwellMode(tideSpeed,false);
          break;
        }
        case Smart_NTM: {
          rcSpeed=NutrientTransportMode(0,tideSpeed,vtDuration*50,true);
          rcSpeedAS=NutrientTransportMode(0,tideSpeed,vtDuration*50,false);
          break;
        }
        case ShortPulse: {
          rcSpeed=ShortPulseMode(0,tideSpeed,vtDuration*50,true);
          rcSpeedAS=ShortPulseMode(0,tideSpeed,vtDuration*50,false);
          break;
        }
        case LongPulse: {
          rcSpeed=LongPulseMode(0,tideSpeed,vtDuration,true);
          rcSpeedAS=LongPulseMode(0,tideSpeed,vtDuration,false);
          break;
        }
        case BHazard: {
          rcSpeed=millis()%1200>800?tideSpeed:0;
          rcSpeedAS=millis()%1200<400?0:tideSpeed;
          break;
        }   
        case Else: {
          rcSpeed=ElseMode(tideSpeed,vtDuration*2,true);
          rcSpeedAS=ElseMode(tideSpeed,vtDuration*2,false);
          break;
        }   
        case Sine: {
          rcSpeed=SineMode(tideSpeed-tideMin,tideSpeed+tideMin,vtDuration*100,true);
          rcSpeedAS=SineMode(tideSpeed-tideMin,tideSpeed+tideMin,vtDuration*100,false);
          break;
        }
        default: {
          rcSpeed=tideSpeed;
          rcSpeedAS=tideSpeed; 
        }
      }

      ReefAngel.RF.SetMode(Custom,rcSpeedAS*pumpOffset,tide.isOutgoing());
      ReefAngel.RF.SetMode(Custom,rcSpeed,tide.isIncoming());
    }

    // Monitor ATO reservoir
/*     void CheckATO() {
      static time_t t;
      static WiFiAlert atoLogAlert;   
      static boolean atoSaved;
      byte prevLevelOld, prevLevel, currLevel;
      byte numHours, rate, rateAlarm;
      char msg[32];
     
      atoLogAlert.SetDelay(SECS_PER_HOUR*6);
      currLevel=ReefAngel.WaterLevel.GetLevel();
      prevLevel=InternalMemory.read(Mem_B_LogATO);
      prevLevelOld=InternalMemory.read(Mem_B_LogPrevATO);
      numHours=(now()%(SECS_PER_HOUR*6))/SECS_PER_HOUR;
      rate=(prevLevelOld-currLevel)*(24/(6+numHours));
      rateAlarm=InternalMemory.read(Mem_B_RateAlarm);
      ReefAngel.CustomVar[Var_LogATO]=rate; 
     
      if ((rate<rateAlarm && rateAlarm!=0) && !ReefAngel.Relay.Status(VO_Vacation)) {
        if (!ReefAngel.Relay.Status(VO_RefillATO)) {
          sprintf(msg,"ATO+rate+(%d)+is+too+low!",rate);
          atoLogAlert.Send(msg);
        }
      }
     
      if (now()%(SECS_PER_HOUR*6)==0) { // Save level and alert every 6 hours
        if (!atoSaved) {
          atoSaved=true;
          InternalMemory.write(Mem_B_LogATO,currLevel);
          InternalMemory.write(Mem_B_LogPrevATO,prevLevel);
        }
      } else {
        atoSaved=false;
      }
     
    }

    // ATO Refill mode. Top off ATO reservoir until it's at 100%   
   void RefillATO() {
      static boolean refillActive=false;
      static WiFiAlert refillAlert;
      byte level, prevRate;

      if (ReefAngel.Relay.Status(VO_EnableATO) || ReefAngel.Relay.Status(VO_Vacation)) {
        ReefAngel.Relay.Override(VO_RefillATO,2);
      }

      level=ReefAngel.WaterLevel.GetLevel();
     
      if (ReefAngel.Relay.Status(VO_RefillATO)) {
        if (level<100) {
          ReefAngel.Relay.On(ATOres);
          refillActive=true;
        } else {
          ReefAngel.Relay.Override(VO_RefillATO,2);
          refillAlert.Send("ATO+Reservoir+is+full.");
          if (InternalMemory.read(Mem_B_MaintATO) > 0) // Reset last ATO counter
            InternalMemory.write(Mem_B_MaintATO,0);
        }
      } else {
        if (refillActive) {
          prevRate=InternalMemory.read(Mem_B_LogPrevATO)-InternalMemory.read(Mem_B_LogATO);
          InternalMemory.write(Mem_B_LogPrevATO, level+prevRate);
          InternalMemory.write(Mem_B_LogATO, level+1);

          ReefAngel.Relay.Off(ATORes);
          refillActive=false;
        }
      }
   }

    void Vacation() {
      static boolean onVacation=InternalMemory.read(Mem_B_Vacation);

      ReefAngel.Relay.Set(VO_Vacation, onVacation); // Sets RelayData only
      if (ReefAngel.Relay.Status(VO_Vacation)) { // Looks at actual status
        onVacation=ReefAngel.Relay.Status(VO_Vacation);
        InternalMemory.write(Mem_B_Vacation, onVacation);
        ReefAngel.Relay.Override(VO_Vacation,2); // Back to auto mode
      }
     
      if (onVacation) {
        ReefAngel.WaterLevelATO(ATORes);   

        if (now()%SECS_PER_DAY==19*SECS_PER_HOUR) {
          ReefAngel.FeedingModeStart();
        }
      }
    }

    void LogFeedings() {
      static byte feedings;
      static boolean feedStatus;

      if (ReefAngel.Relay.Status(Feeder)) {
        feedStatus=true;
      } else {
        if (feedStatus) {
          feedStatus=false;
          feedings++;
        }
      }

      if (ReefAngel.DisplayedMenu==FEEDING_MODE) {
       if (InternalMemory.read(Mem_B_MaintFeeding) > 0) // Reset last time in Feeding Mode
         InternalMemory.write(Mem_B_MaintFeeding,0);
      }

      ReefAngel.CustomVar[Var_Feedings]=feedings;
      if (now()%SECS_PER_DAY==SECS_PER_DAY-1) feedings=0; // Clear feedings at end of day 
    }

    void RunFeeder() {
      int press=InternalMemory.read(Mem_B_AutoFeedPress);
      int repeat=InternalMemory.read(Mem_B_AutoFeedRepeat)*SECS_PER_HOUR;
      int offset=InternalMemory.read(Mem_B_AutoFeedOffset)*SECS_PER_HOUR;
      boolean autoFeed=InternalMemory.read(Mem_B_AutoFeed);
      static time_t t;
     
      ReefAngel.Relay.Set(VO_AutoFeed, autoFeed);
      if (ReefAngel.Relay.Status(VO_AutoFeed)!=autoFeed) {
        autoFeed=ReefAngel.Relay.Status(VO_AutoFeed);
        InternalMemory.write(Mem_B_AutoFeed, autoFeed);
        ReefAngel.Relay.Override(VO_AutoFeed,2);
      }
     
      if (autoFeed) {
        if (sun.IsDaytime() && (now()+offset)%repeat==0) {
          t=now();
        }
      }
     
      if (ReefAngel.Relay.isMaskOn(Feeder)) {
        ReefAngel.Relay.Override(Feeder,2);
        t=now()-now()%20; // One feeding has already happened.
      }
         
      // Press the button once every 20 seconds
      if (now()-t < press*20) {
        ReefAngel.Relay.Set(Feeder,now()%20==0);
      } else {
        ReefAngel.Relay.Off(Feeder);
      }
    }

/*    void RunSwabbie() {
      int repeat=InternalMemory.read(Mem_B_SwabbieRepeat)*60;
      int runtime=InternalMemory.read(Mem_B_SwabbieTime)*60;
      static time_t t;
     
      // Manual mode
      if (ReefAngel.Relay.isMaskOn(Swabbie)) {
        ReefAngel.Relay.Override(Swabbie,2);
        t=now();
      } 

      if (now()-t < runtime) {
        ReefAngel.Relay.On(Swabbie);
      } else {
        ReefAngel.DosingPumpRepeat(Swabbie,0,repeat,runtime);   
      } 
    }

    // Definitions for dosing pumps
    #define numDPumps 3
    byte pump[numDPumps]={ DPump1, DPump2, Extension}; // Pump 3 is just for logging/calibration routine
    byte varReport[numDPumps]={ Var_DPump1, Var_DPump2, Var_WCVol};
    byte memDPTime[numDPumps]={ Mem_B_DP1Timer, Mem_B_DP2Timer, Mem_B_DP3Timer};
    int memDPVolume[numDPumps]={ Mem_I_DP1Volume, Mem_I_DP2Volume, Mem_I_DP3Volume };
    int memDPRepeat[numDPumps]={ Mem_I_DP1RepeatInterval, Mem_I_DP2RepeatInterval, Mem_I_DP3RepeatInterval };
    int memCalTime[numDPumps]={ Mem_I_CalDP1Time, Mem_I_CalDP2Time, Mem_I_CalDP3Time };
    int memCalVol[numDPumps]={ Mem_I_CalDP1Vol, Mem_I_CalDP2Vol, Mem_I_CalDP3Vol };

    void RunDosingPumps() {
      float rate;
      byte dpTime;
      int dpRepeat, calcTime, totalVolume;
      const int numPumps = numDPumps-1; // -1 = Remove "Extension" from the equation.
     
      static byte doseTime[numPumps]={
        InternalMemory.read(memDPTime[0]),
        InternalMemory.read(memDPTime[1])
      };
     
      for (int i=0;i < numPumps; i++) {
        dpTime=InternalMemory.read(memDPTime[i]);
        dpRepeat=InternalMemory.read_int(memDPRepeat[i]);
        rate=(float)InternalMemory.read_int(memCalVol[i])/InternalMemory.read_int(memCalTime[i]);
        calcTime=(InternalMemory.read_int(memDPVolume[i])/rate)/(1440/dpRepeat);
        totalVolume=rate*(dpTime*(1440/dpRepeat));

        if (dpTime!=doseTime[i]) { // Memory has changed.
            InternalMemory.write_int(memDPVolume[i], totalVolume); // Update volume
            doseTime[i]=dpTime;
        } else if (dpTime!=calcTime) { // Calculated time has changed.
            InternalMemory.write(memDPTime[i], calcTime); // Update time
            doseTime[i]=calcTime;
        }

        // Make sure we're not calibrating
        if (!ReefAngel.Relay.Status(VO_Calibrate))
          ReefAngel.DosingPumpRepeat(pump[i], i*5, dpRepeat, doseTime[i]);
      }
    }

    void LogDosingPumps() {
      static time_t pumpTimer[numDPumps];
      static boolean pumpStatus[numDPumps];
      float rate;

      for (int i=0;i< numDPumps;i++) {
        if (ReefAngel.Relay.Status(pump[i])) {
          if (!pumpStatus[i]) {
            pumpTimer[i]=now()-pumpTimer[i]; // Pump was off, timer is now a time
            pumpStatus[i]=true;
          }
        } else {
          if (pumpStatus[i]) {
            pumpTimer[i]=now()-pumpTimer[i]; // Pump was on, timer is now a timer
            pumpStatus[i]=false;
       
            rate=(float)InternalMemory.read_int(memCalVol[i])/InternalMemory.read_int(memCalTime[i]);
            ReefAngel.CustomVar[varReport[i]]=pumpTimer[i]*rate;
          }
        }

        if (now()%SECS_PER_DAY==SECS_PER_DAY-1 && i!=2) { // Don't overwrite WC log
          pumpTimer[i]=0; // Clear timer at end of day
          ReefAngel.CustomVar[varReport[i]]=0; // Clear portal variable
        }
      } 
     
      // Reset logging for WC fill pump at start of WC
      static boolean wcStart;
      if (ReefAngel.DisplayedMenu!=WATERCHANGE_MODE) wcStart=false;
      if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE && !wcStart) {
        ReefAngel.CustomVar[varReport[2]]=0;
        pumpTimer[2]=0;
        wcStart=true;
      }
    }

    void CalibrateDPumps() {
      static time_t pumpTimer[numDPumps];
      static boolean pumpStatus[numDPumps];
      static boolean running=false;
         
      if (ReefAngel.Relay.Status(VO_Calibrate)) {
        running=true;
       
        for (int i=0;i < numDPumps;i++) {
          if (ReefAngel.Relay.Status(pump[i])) {
            if (!pumpStatus[i]) {
              pumpTimer[i]=now()-pumpTimer[i]; // Pump was off, timer is now a time
              pumpStatus[i]=true;
            }
          } else {
            if (pumpStatus[i]) {
              pumpTimer[i]=now()-pumpTimer[i]; // Pump was on, timer is now a timer
              pumpStatus[i]=false;
            }
          }
        }     
      } else {
        if (running) {
          running=false;
         
          for (int i=0;i < numDPumps;i++) {
            if (pumpTimer[i]>0 && !ReefAngel.Relay.Status(VO_LockPorts)) {
              InternalMemory.write_int(memCalTime[i], pumpTimer[i]);
            }
            ReefAngel.Relay.Override(pump[i],2); // Go back to auto mode
            pumpStatus[i]=false;
            pumpTimer[i]=0;
          }
        }
      }   
    }

   void AutoWaterChange() {
      int runtime=InternalMemory.read_int(Mem_I_WCFillTime);
      static WiFiAlert wcAlert;
      static boolean started;
      static time_t t;

      if (ReefAngel.DisplayedMenu==WATERCHANGE_MODE) {
        ReefAngel.Relay.On(Refugium);

        if (ReefAngel.Relay.Status(VO_EnableATO)) {
         
          ReefAngel.SingleATOHigh(Extension); // Refill fresh SW as needed

          if (InternalMemory.read(Mem_B_MaintWC) > 0) // Reset last WC counter
            InternalMemory.write(Mem_B_MaintWC,0);
         
          if (ReefAngel.Relay.Status(VO_StartFill) && !started) {
            ReefAngel.Relay.Override(Reactor,1); // Start draining
            started=true;
            t=now();
          }
         
          if ( (now()-t > runtime && started) || bitRead(ReefAngel.AlertFlags,ATOTimeOutFlag) ) {
            ReefAngel.Relay.Override(Reactor,0); // Stop draining
            ReefAngel.Relay.Override(VO_StartFill,2); // Reset Start switch
            if (started) wcAlert.Send("Reactor+disabled.", true);
            started=false;
          }
         
        } else {
          // Done with ATO
          ReefAngel.Relay.Off(Extension);
          // Backup WC Vol
          if (InternalMemory.read(Mem_B_MaintWCVol) != ReefAngel.CustomVar[Var_WCVol])
            InternalMemory.write(Mem_B_MaintWCVol, ReefAngel.CustomVar[Var_WCVol]);
          // Clear stale timeout
          ReefAngel.ATOClear();
        }
      } else {
        ReefAngel.Relay.Override(VO_EnableATO,2);
        ReefAngel.Relay.Override(VO_StartFill,2);   
      }
    }

    // Disable masks for things that should not be turned on by mistake
    void LockPorts() {
      ReefAngel.AddPortOverrides();

      if (ReefAngel.Relay.Status(VO_LockPorts)) {
        ReefAngel.OverridePortsE[0] = Port7Bit | Port8Bit;
        ReefAngel.OverridePortsE[1] = Port4Bit | Port5Bit | Port7Bit;   
      } else {
        ReefAngel.OverridePortsE[0] = 0;
        ReefAngel.OverridePortsE[1] = 0;   
      }
    }
/*
    void Reminders() {
      static boolean counterReady;
      byte counter[]= { Mem_B_MaintGAC, Mem_B_MaintGFO, Mem_B_MaintCal, Mem_B_MaintAlk,
        Mem_B_MaintWC, Mem_B_MaintATO, Mem_B_MaintFeeding, Mem_B_MaintSkimmer, Mem_B_MaintSocks };
     
      if (now()%SECS_PER_DAY!=0) counterReady=true;
      if (now()%SECS_PER_DAY==0 && counterReady) {
        for (int i=0;i<sizeof(counter);i++) {
          InternalMemory.write(counter[i],InternalMemory.read(counter[i])+1);
        }
        counterReady=false; 
      }
    } */

    void NextRFMode() {
      vtMode++;
     
      if (vtMode > 12) {
        vtMode=0;
        vtSpeed=50; // Constant
      } else if (vtMode == 1) {
        vtSpeed=40; // Lagoon
      } else if (vtMode == 2) {
        vtSpeed=45; // Reef Crest
      } else if (vtMode == 3) { 
        vtSpeed=55; vtDuration=10; // Short Pulse
      } else if (vtMode == 4) {
        vtSpeed=55; vtDuration=20; // Long Pulse
      } else if (vtMode == 5) {
        vtSpeed=InternalMemory.read(Mem_B_NTMSpeed);
        vtDuration=InternalMemory.read(Mem_B_NTMDuration); // Smart_NTM
      } else if (vtMode == 6) {
        vtSpeed=50; vtDuration=10; // Smart_TSM
      } else if (vtMode == 7) {
        vtSpeed=InternalMemory.read(Mem_B_NightSpeed);
        vtDuration=InternalMemory.read(Mem_B_NightDuration);
        vtMode=9; // Night
      } else if (vtMode == 10) {
        vtSpeed=65; vtDuration=5; // Storm
      } else if (vtMode == 11) {
        vtSpeed=45; vtDuration=10; // Custom
      } 

      if (vtMode!=InternalMemory.RFMode_read())
        InternalMemory.RFMode_write(vtMode);
      if (vtSpeed!=InternalMemory.RFSpeed_read())
        InternalMemory.RFSpeed_write(vtSpeed);
      if (vtDuration!=InternalMemory.RFDuration_read())
        InternalMemory.RFDuration_write(vtDuration);
    }

    // Menu Code
    void MenuEntry1() {
      // Toggle refugium light between on/auto.
 //     ReefAngel.Relay.Override(Refugium, ReefAngel.Relay.Status(Refugium)+1);
      ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
    }
    void MenuEntry2() {
      ReefAngel.FeedingModeStart();
    }
    void MenuEntry3() {
      ReefAngel.WaterChangeModeStart();
    }
    void MenuEntry4() {
      NextRFMode(); 
      ReefAngel.DisplayedMenu = RETURN_MAIN_MODE;
    }
    void MenuEntry5() {
      ReefAngel.ATOClear();
      ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
    }
    void MenuEntry6() {
      ReefAngel.OverheatClear();
      ReefAngel.DisplayMenuEntry("Clear Overheat");
    }
    void MenuEntry7() {
      ReefAngel.SetupCalibratePH();
      ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
    }
    void MenuEntry8() {
      ReefAngel.SetupCalibrateWaterLevel();
      ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
    }
    void MenuEntry9() {
      ReefAngel.SetupDateTime();
      ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
    }

    // Custom Main Screen
    void DrawCustomMain() {
      const int NumScreens=3;
      static boolean drawGraph=true;
     
      // Main Header
      // ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, 35, 2,"Lee's Reef");
      ReefAngel.LCD.DrawDate(5,2);
      ReefAngel.LCD.Clear(COLOR_BLACK, 1, 11, 128, 11);

      // Param Header
      DrawParams(5,14);
     
      switch (ScreenID) {
        case 0:
        {
          if (drawGraph) { ReefAngel.LCD.DrawGraph(5,40); drawGraph=false; }
          break;
        }
        case 1: { DrawStatus(5,40); break; }
        case 2: { DrawSunMoon(5,40); break; }
      }
     
      // Draw Relays
      DrawRelays(12,94);
     
      // Date+Time
      // ReefAngel.LCD.DrawDate(5,122);
     
      if (ReefAngel.Joystick.IsLeft()) {
        ReefAngel.ClearScreen(DefaultBGColor);
        ScreenID--; drawGraph=true;
      }
      if (ReefAngel.Joystick.IsRight()) {
        ReefAngel.ClearScreen(DefaultBGColor);
        ScreenID++; drawGraph=true;
      }
      if (ScreenID<0) ScreenID=NumScreens-1;
      if (ScreenID>=NumScreens) ScreenID=0;
     
    }

    void DrawCustomGraph() {
      if (ScreenID==0)
        ReefAngel.LCD.DrawGraph(5, 40);
    }

    void DrawParams(int x, int y) {
      char buf[16];

      ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor,x+5,y,"Temp:");
      ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor,x+80, y, "PH:");
      // Temp and PH
      y+=2;
      ConvertNumToString(buf, ReefAngel.Params.Temp[T2_PROBE], 10);
      ReefAngel.LCD.DrawText(T2TempColor, DefaultBGColor, x+45, y, buf);
      y+=6;
      ConvertNumToString(buf, ReefAngel.Params.Temp[T1_PROBE], 10);
      ReefAngel.LCD.DrawLargeText(T1TempColor, DefaultBGColor, x+5, y, buf, Num8x16);
      ConvertNumToString(buf, ReefAngel.Params.PH, 100);
      ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, x+80, y, buf, Num8x16);
      y+=5;
      ConvertNumToString(buf, ReefAngel.Params.Temp[T3_PROBE], 10);
      ReefAngel.LCD.DrawText(T3TempColor, DefaultBGColor, x+45, y, buf);
    }

    void DrawStatus(int x, int y) {
      int t=x;
     
      ReefAngel.LCD.DrawLargeText(COLOR_INDIGO,DefaultBGColor,15,y,"High",Font8x16);
      ReefAngel.LCD.DrawLargeText(COLOR_INDIGO,DefaultBGColor,85,y,"Low",Font8x16);
     
      if (ReefAngel.HighATO.IsActive()) {
        ReefAngel.LCD.FillCircle(55,y+3,5,COLOR_GREEN);
      } else {
        ReefAngel.LCD.FillCircle(55,y+3,5,COLOR_RED);
      }
     
      if (ReefAngel.LowATO.IsActive()) {
        ReefAngel.LCD.FillCircle(70,y+3,5,COLOR_GREEN);
      } else {
        ReefAngel.LCD.FillCircle(70,y+3,5,COLOR_RED);
      }
      y+=12;
     
      // Display Water level
      ReefAngel.LCD.DrawText(DefaultFGColor,DefaultBGColor,x,y,"AT0 Level:"); x+=65;
      ReefAngel.LCD.DrawSingleMonitor(ReefAngel.WaterLevel.GetLevel(),DPColor,x,y,1);
      x+=5*(intlength(ReefAngel.WaterLevel.GetLevel())+1);
      ReefAngel.LCD.DrawText(DPColor, DefaultBGColor, x, y, "%");
      y+=12; x=t;
     
      // Vortech Mode
      ReefAngel.LCD.DrawText(0,255,x,y,"RF:"); x+=20;
      ReefAngel.LCD.Clear(DefaultBGColor,x,y,t+(128-t),y+8);
      if (vtMode == 0) ReefAngel.LCD.DrawLargeText(COLOR_GREEN,255,x,y,"Constant");
      else if (vtMode == 1) ReefAngel.LCD.DrawLargeText(COLOR_GOLD,255,x,y,"Lagoon");
      else if (vtMode == 2) ReefAngel.LCD.DrawLargeText(COLOR_GOLD,255,x,y,"Reef Crest");
      else if (vtMode == 3) ReefAngel.LCD.DrawLargeText(COLOR_RED,255,x,y,"Short Pulse");
      else if (vtMode == 4) ReefAngel.LCD.DrawLargeText(COLOR_RED,255,x,y,"Long Pulse");
      else if (vtMode == 5) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,x,y,"Smart NTM");
      else if (vtMode == 6) ReefAngel.LCD.DrawLargeText(COLOR_MAGENTA,255,x,y,"Tidal Swell");
      else if (vtMode == 9) ReefAngel.LCD.DrawLargeText(COLOR_WHITE,0,x,y,"Night");
      else if (vtMode == 10) ReefAngel.LCD.DrawLargeText(COLOR_BLUE,0,x,y,"Storm");
      else if (vtMode == 11) ReefAngel.LCD.DrawLargeText(COLOR_BLUE,255,x,y,"Custom");
      y+=10; x=t;
     
      ReefAngel.LCD.DrawText(0,255,x,y,"RF Speed:"); x+=60;
      ReefAngel.LCD.Clear(DefaultBGColor,x,y,128,y+8);
      ReefAngel.LCD.DrawText(COLOR_BLUE, DefaultBGColor,x,y,vtSpeed); x+=15;
      ReefAngel.LCD.DrawText(COLOR_BLUE, DefaultBGColor,x,y,"/"); x+=10;
      ReefAngel.LCD.DrawText(COLOR_BLUE, DefaultBGColor,x,y,vtDuration);
      y+=10; x=t;
     
      // Display Acclimation timer
      if (ReefAngel.CustomVar[Var_AcclDay] > 0) {
        ReefAngel.LCD.DrawText(DefaultFGColor,DefaultBGColor,x,y,"Acclimation Day:"); x+=100;
        ReefAngel.LCD.DrawSingleMonitor(ReefAngel.CustomVar[Var_AcclDay],DefaultFGColor,x,y,1);
      } else {
        ReefAngel.LCD.Clear(DefaultBGColor,x,y,128,y+8);
      }
    }

    void DrawSunMoon(int x, int y) {
      char buf[16];
      int t=x;

      y+=2;
      /// Display Sunrise / Sunset
      sprintf(buf, "%02d:%02d", sun.GetRiseHour(), sun.GetRiseMinute());
      ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor,x,y,"Rise:"); x+=31;
      ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor,x,y,buf);
      sprintf(buf, "%02d:%02d", sun.GetSetHour(), sun.GetSetMinute()); x+=36;
      ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor,x,y,"Set:"); x+=25;
      ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor,x,y,buf);
      y+=15; x=t;
     
      /// Display Moonrise / Moonset
      sprintf(buf, "%02d:%02d", Moon.riseH, Moon.riseM);
      ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor,x,y,"MR:"); x+=21;
      ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor,x,y,buf);
      sprintf(buf, "%02d:%02d", Moon.setH, Moon.setM); x+=36;
      ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor,x,y,"MS:"); x+=21;
      ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor,x,y,buf); x+=36;
      if (Moon.isUp) ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor,x,y,"@");
        else ReefAngel.LCD.DrawText(COLOR_RED,DefaultBGColor,x,y,"_");
      y+=10; x=t;
     
      // MoonPhase
      ReefAngel.LCD.DrawText(0,255,x,y,"Moon:");
      ReefAngel.LCD.Clear(DefaultBGColor,x+32,y,128,y+8);
      ReefAngel.LCD.DrawText(COLOR_MAGENTA,255,x+32,y,MoonPhaseLabel());
      y+=10; x=t;
     
      // MoonLight %
      ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor,x,y,"MoonLights:"); x+=68;
      ReefAngel.LCD.DrawSingleMonitor(ReefAngel.PWM.GetDaylightValue(),DPColor,x,y,1);
      x+=5*(intlength(ReefAngel.PWM.GetDaylightValue())+1);
      ReefAngel.LCD.DrawText(DPColor, DefaultBGColor, x, y, "%");
    }

    void DrawRelays(int x, int y) {
      // Draw Relays
      byte TempRelay = ReefAngel.Relay.RelayData;
      TempRelay &= ReefAngel.Relay.RelayMaskOff;
      TempRelay |= ReefAngel.Relay.RelayMaskOn;
      ReefAngel.LCD.DrawOutletBox(x, y, TempRelay);

      y+=12;
      TempRelay = ReefAngel.Relay.RelayDataE[0];
      TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
      TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
      ReefAngel.LCD.DrawOutletBox(x, y, TempRelay);
     
      y+=12;
      TempRelay = ReefAngel.Relay.RelayDataE[1];
      TempRelay &= ReefAngel.Relay.RelayMaskOffE[1];
      TempRelay |= ReefAngel.Relay.RelayMaskOnE[1];
      ReefAngel.LCD.DrawOutletBox(x, y, TempRelay); 
    }

    byte ElseMode( byte MidPoint, byte Offset, boolean WaveSync )
    {
      // Static's only initialize the first time they are called
      static unsigned long LastChange=millis();        // Set the inital time that the last change occurred
      static int Delay = random( 500, 3000);           // Set the initial delay
      static int NewSpeed = MidPoint;                  // Set the initial speed
      static int AntiSpeed = MidPoint;                 // Set the initial anti sync speed
      if ((millis()-LastChange) > Delay)               // Check if the delay has elapsed
      {
        Delay=random(500,5000);                        // If so, come up with a new delay
        int ChangeUp = random(Offset);                 // Amount to go up or down
        if (random(100)<50)                            // 50/50 chance of speed going up or going down
        {
          NewSpeed = MidPoint - ChangeUp;
          AntiSpeed = MidPoint + ChangeUp;
        }
        else
        {
          NewSpeed = MidPoint + ChangeUp;
          AntiSpeed = MidPoint - ChangeUp;
        }
        LastChange=millis();                           // Reset the time of the last change
      }
      if (WaveSync)
      {
        return NewSpeed;
      }
      else
      {
        return AntiSpeed;
      }
    }

    void DelayedOnModes(byte relay) {
      static unsigned long startTime=now();

      if (startTime==LastStart && ReefAngel.HighATO.IsActive()) {
        ReefAngel.Relay.On(relay);
      } else {
        ReefAngel.Relay.DelayedOn(relay);
      }
    }
Image
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

Not sure if this is related but...

1) I set my Return, Wavemaker Right and Wavemaker Left to Always On via the portal.
2) at 8:00 pm the RA unit seemed to reset/restart and all relays went back to their default "auto" state

The RA unit is plugged into a surge protector but there was no spike that occurred that would have reset the unit. Seems like the unit just reset itself on its own. Again, not sure if its related but I just noticed this happen. Please let me know if there is anything that you can uncover to help me/us troubleshoot this issue. Thanks.

Jeremiah
Image
javisaman
Posts: 63
Joined: Thu Jun 30, 2011 7:27 am

Re: Why does my RA go into feeding mode randomly

Post by javisaman »

Do you have the RF module to connect wirelessly to vortechs?
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

Yes. I had the same issue (random feeding mode and resets) when the RF module was connected or disconnected.
Image
javisaman
Posts: 63
Joined: Thu Jun 30, 2011 7:27 am

Re: Why does my RA go into feeding mode randomly

Post by javisaman »

Hmm mine doesn't have any issues when the RF module is disconnected (so far). I wonder if you are suffering from the exactly same issue as us. When it goes into these random feeding modes for you, is the head unit really in feeding mode or are the relays just turning off?
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

really in feeding ie. the display says feeding mode. If I exit out of feeding mode, the pump turns back on.

Just curious, are you calling the pump by port number in code ie. "port4" or "box1_port4" or "Port4Bit"? Or are you calling via defined named ie. "(Pump)" or "(ReturnPump)"?
Image
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

UPDATE

All,
I got annoyed that this issue was still happening so I did the following:

1) Backed my "lee's revised" ino
2) Used my current laptop and restored the code on the RA to default via TOOLS-->Restore Preloaded Code
3) Verified that the RA was reset to default code.
4) Used a BRAND NEW computer from my work and installed ReefAngelInstaller_1.1.0
5) Followed all the setup instructions
5) Re-downloaded the 4 folders that need to be copied to library from Lee's thread
6) Uploaded my backed-up code (I emailed it to myself)
7) Within 15 minutes my unit went into Feeding Mode without input from me.

Basically, reverting to original code, and restoring from a new computer did nothing. Just like before, I have no idea why my RA goes into Feeding Mode randomly. Please help. Thanks.

Jeremiah
Image
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

Hey guys,
Is there any other testing or data that you need to help us solve this? I'm at a loss at this point. I'd really like to get my tank running optimally again so any help you can provide would be appreciated. thanks.

Jeremiah
Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Why does my RA go into feeding mode randomly

Post by lnevo »

Has anyone tried downgrading the libraries. If its SW related it would help to know exactly which version introduced the issue.
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

Going from 110 to 109 didn't compile for me. I was getting this compile error:

Code: Select all

The following features were automatically added:
Watchdog Timer
Version Menu

The following features were detected:
Dimming Signal
RF Expansion Module
Wifi Attachment
Custom Main Screen
Custom Variable
Extra Font - Medium Size (8x8 pixels)
Extra Font - Numbers Only - Large Font (8x16 pixels)
Date/Time Setup Menu
Relay Expansion Module
Custom Menu
Water Level Expansion Module
Moon Phase Label
Number of Relay Expansion Modules: 2
Number of Menu Options: 9
Lees_alteredv3_cleaned.cpp: In function 'void setup()':
Lees_alteredv3_cleaned:171: error: 'class ReefAngelClass' has no member named 'AddWaterLevelExpansion'
Then I copied ReefAngel.cpp and ReefAngel.h from 110 to 109 and I got this error:

Code: Select all

The following features were automatically added:
Watchdog Timer
Version Menu

The following features were detected:
Dimming Signal
RF Expansion Module
Wifi Attachment
Custom Main Screen
Custom Variable
Extra Font - Medium Size (8x8 pixels)
Extra Font - Numbers Only - Large Font (8x16 pixels)
Date/Time Setup Menu
Relay Expansion Module
Custom Menu
Water Level Expansion Module
Moon Phase Label
Number of Relay Expansion Modules: 2
Number of Menu Options: 9
In file included from Lees_alteredv3_cleaned.cpp:21:
C:\Users\jmaza\Documents\Arduino\libraries\ReefAngel/ReefAngel.h:108: error: 'RA_Wifi' does not name a type
Lees_alteredv3_cleaned.cpp: In function 'void setup()':
Lees_alteredv3_cleaned:170: error: 'class ReefAngelClass' has no member named 'InitMenu'
Lees_alteredv3_cleaned.cpp: In function 'void loop()':
Lees_alteredv3_cleaned:255: error: 'class ReefAngelClass' has no member named 'ShowInterface'
Lees_alteredv3_cleaned.cpp: In function 'void MenuEntry5()':
Lees_alteredv3_cleaned:471: error: 'class ReefAngelClass' has no member named 'DisplayMenuEntry'
Lees_alteredv3_cleaned.cpp: In function 'void MenuEntry6()':
Lees_alteredv3_cleaned:475: error: 'class ReefAngelClass' has no member named 'DisplayMenuEntry'
Lees_alteredv3_cleaned.cpp: In function 'void MenuEntry8()':
Lees_alteredv3_cleaned:482: error: 'class ReefAngelClass' has no member named 'SetupCalibrateWaterLevel'
Lees_alteredv3_cleaned.cpp: In function 'void MenuEntry9()':
Lees_alteredv3_cleaned:486: error: 'class ReefAngelClass' has no member named 'SetupDateTime'
Lees_alteredv3_cleaned.cpp: In function 'void DrawCustomMain()':
Lees_alteredv3_cleaned:497: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:498: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:506: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:519: error: 'class ReefAngelClass' has no member named 'Joystick'
Lees_alteredv3_cleaned:523: error: 'class ReefAngelClass' has no member named 'Joystick'
Lees_alteredv3_cleaned.cpp: In function 'void DrawCustomGraph()':
Lees_alteredv3_cleaned:534: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned.cpp: In function 'void DrawParams(int, int)':
Lees_alteredv3_cleaned:540: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:541: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:545: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:548: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:550: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:553: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned.cpp: In function 'void DrawStatus(int, int)':
Lees_alteredv3_cleaned:559: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:560: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:563: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:565: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:569: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:571: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:576: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:577: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:579: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:583: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:584: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:585: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:586: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:587: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:588: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:589: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:590: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:591: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:592: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:593: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:594: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:597: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:598: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:599: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:600: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:601: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:606: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:607: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:609: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned.cpp: In function 'void DrawSunMoon(int, int)':
Lees_alteredv3_cleaned:620: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:621: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:623: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:624: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:629: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:630: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:632: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:633: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:634: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:635: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:639: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:640: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:641: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:645: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:646: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:648: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned.cpp: In function 'void DrawRelays(int, int)':
Lees_alteredv3_cleaned:656: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:662: error: 'class ReefAngelClass' has no member named 'LCD'
Lees_alteredv3_cleaned:668: error: 'class ReefAngelClass' has no member named 'LCD'
Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Why does my RA go into feeding mode randomly

Post by lnevo »

Think you need to try a clean install...
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

How do I do a clean install of libs 109? This install was semi-clean in that it was a new computer that I installed using libs 110 (most recent). I copied the appropriate files (moon, wifialert, etc.) and compiled successfully. I then downloaded libs 109 from a link in another post, unzipped files to my Arduino folder, renamed Library to Library_bak then renamed Library-109 (the name of unzipped libs) to Library. I relaunched Arduino, check libs version to confrim it said 109 then compiled and got these errors.

As a test I renamed everything back to "normal", relaunched Arduino, checked libs to confirm it said 110 and recompiled successfully.
Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Why does my RA go into feeding mode randomly

Post by lnevo »

The wifialert package has been updated to be compatible with 1.1.0, i think using the current version with the old library screwed up the package. Can you try a hard coded wizard version with 1.0.9 and see if you still have an issue. If it's good i'd recommend using the same ino on 1.1.0 to reproduce...my code is a hog using lots of custom memory locations and also if your using my RF custom mode could be contributing... I also do some weird things that could contribute if memory is set wrong including triggering feed mode in the vacation() function...
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

Downgrading libs isn't going to be as turn key as I thought. What i did:

Fresh install
Renamed Library folder to Library_bak
Unzipped Libs 1.0.9 to Arduino folder and renamed to Library
Launched Arduino and confirmed the libs are 1.0.9
Ran Wizard and skipped to Generate Only (didn't upload)
Once code was on screen I hit Verify and got the compile error below:

Code: Select all


The following features were automatically added:
Watchdog Timer
Version Menu

The following features were detected:
RF Expansion Module
Wifi Attachment
Relay Expansion Module
2014 Main Screen
Extra Font - Medium Size (8x8 pixels)
Water Level Expansion Module
Number of Relay Expansion Modules: 1
Simple Menu
libsv9_test.cpp: In function 'void setup()':
libsv9_test:41: error: 'class ReefAngelClass' has no member named 'Use2014Screen'
libsv9_test:42: error: 'class ReefAngelClass' has no member named 'AddWaterLevelExpansion'
I'm assuming the install assumes libs 1.1.0 and thus adds certain lines to the generated code as needed.

I'm going to run a few tests; like reverting back to my original ino, using clean 1.1.0 Wizard generated code and reverting back to default code via Tools --> Restore Preloaded code. I just wanted to get this latest test out there. Thanks.

Jeremiah
Image
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Why does my RA go into feeding mode randomly

Post by lnevo »

Roberto,

Do you have an archive of the 1.0.9 install somewhere?

Jeremiah, was 1.0.9 definitely the version you had that was working?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Why does my RA go into feeding mode randomly

Post by rimai »

Roberto.
aranax
Posts: 120
Joined: Thu Jun 02, 2011 11:54 pm

Re: Why does my RA go into feeding mode randomly

Post by aranax »

Thanks Roberto.

To the guys that are having this issue: I confirmed that my issue is the same, in that, if I disconnect my RF unit the random feeding mode stops. That said, have you tried swapping/switching ports on the expansion hub? I was testing each port on my expansion unit and found that the issue has gone away (for now) if I plug my RF unit into one of the SIDE ports (the side with only 2 available ports). I only have 3 modules (RF, Relay and Single ATO) and I had all three plugged into the "bottom" (in my setup) ports, so I used 3 of the 4 on one side. I switched the RF to ports mentioned above and I have gone ~20 hours without issue (longest stretch w/o issue).

@ Robert et al - any thoughts as to why changing the expansion slot would fix the issue or is it likely just coincidence?

Jeremiah
Image
javisaman
Posts: 63
Joined: Thu Jun 30, 2011 7:27 am

Re: Why does my RA go into feeding mode randomly

Post by javisaman »

I tried switching the ports as well, though it was less frequent it still did happen. I remember a while back there being an issue with usb noise on the expansion hub causing the system to periodically shut down.
modulok
Posts: 166
Joined: Wed Oct 24, 2012 8:37 am

Re: Why does my RA go into feeding mode randomly

Post by modulok »

So for me all signs point to the RF module. Every time I unplug it I don't get any mysterious Feeding Modes. Can this be updated? Roberto I have the firmware that makes the RF module reset all the time. Probably flashed that around October.
Image
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Why does my RA go into feeding mode randomly

Post by rimai »

Can you try the original one?
Attachments
update.zip
(408.13 KiB) Downloaded 456 times
Roberto.
Paul_Velasco
Posts: 127
Joined: Thu Sep 19, 2013 7:46 am
Location: Saint Cloud, FL

Re: Why does my RA go into feeding mode randomly

Post by Paul_Velasco »

Any ideas?
I just installed my unit and getting random feed mode
Fresh install
Rf module

I took everything off feed mode
Could it be that I have my vortech WES's plugged into relay box? Should these be plugged into wall?
Image
Paul_Velasco
Posts: 127
Joined: Thu Sep 19, 2013 7:46 am
Location: Saint Cloud, FL

Re: Why does my RA go into feeding mode randomly

Post by Paul_Velasco »

Just to update:

I took the advice and plugged the USB side of the RF module into the side of the expansion module. Two days now and there is no random feed mode happening anymore. Both pumps are plugged into relay box and everything seems to be OK now? Solution who knows but it is working properly.
Image
modulok
Posts: 166
Joined: Wed Oct 24, 2012 8:37 am

Re: Why does my RA go into feeding mode randomly

Post by modulok »

Didn't update the RF unit yet, but tried other usb ports in the expansion hub. I even have the Vortech pumps turned off and I am still having the issue.
Image
javisaman
Posts: 63
Joined: Thu Jun 30, 2011 7:27 am

Re: Why does my RA go into feeding mode randomly

Post by javisaman »

Haven't looked at this thread in a while. I'm trying one of the usb ports on the side (2 usb ports) of the expansion module. One thing I noticed is wiggling the connector on the RF module causes all of the relays to go beserk, if I wiggle the other end of the usb port (on the expansion hub) nothing happens. There is something very fishy with this RF module. It maybe a bad cable and I can see what happens when I replace it. But it is definitely the RF module/usb that causing this issue.
Amos Poh
Posts: 107
Joined: Sun Jul 22, 2012 4:51 am
Location: Singapore

Re: Why does my RA go into feeding mode randomly

Post by Amos Poh »

i would agree that is has to be something to do with the RF module, every time when the controller goes berserk first thing i will check is the RF module connection.

Any idea how to solve this?
modulok
Posts: 166
Joined: Wed Oct 24, 2012 8:37 am

Re: Why does my RA go into feeding mode randomly

Post by modulok »

Has anyone ever figured this issue out? I still get random feeding modes happen throughout the day. I have just switched the feedmode ports to my unused ports, but it would be nice to work correctly.
Image
Post Reply