Custom Variables

Do you have a question on how to do something.
Ask in here.
Post Reply
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Custom Variables

Post by ecam »

Code: Select all

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

      for (int i=0;i< numDPumps;i++) {
        if (ReefAngel.Relay.Status(pumpRelays[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)CalVol[i]/CalTime[i];

            // Report How much volume has been dosed per day.
            // Could make this in minutes... excercise for the reader..
            ReefAngel.CustomVar[2]=pumpTimer[0]*rate;
            ReefAngel.CustomVar[3]=pumpTimer[1]*rate; 
          }
        }
     
        // Clear timer at end of day
        if (now()%SECS_PER_DAY==SECS_PER_DAY-1) pumpTimer[i]=0;
      } 
    }
Using this code I've been watching my Custom variables on the portal. Field 1 and 3 havent changed from 1. So is this code working for the dosers? Is this a count that will tell me how many times the relay has triggered or how many MLs of buffers has been dosed. Just trying to understand what im looking for..

Thank you
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

This code if i recall correctly logs the volume in ml. And then backs up that value from the previous day to the second set of variables.
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Custom Variables

Post by ecam »

Current code

Code: Select all

    #include <RA_ATO.h>
    #include <RF.h>
    #include <ReefAngel_Features.h>
    #include <Globals.h>
    #include <RA_Wifi.h>
    #include <Wire.h>
    #include <OneWire.h>
    #include <Time.h>
    #include <DS1307RTC.h>fafa
    #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 <InternalEEPROM.h>
    #include <RA_Colors.h>
    #include <RA_CustomColors.h>
    #include <Salinity.h>
    #include <RF.h>fa
    #include <IO.h>
    #include <ORP.h>
    #include <PH.h>
    #include <WaterLevel.h>
    #include <ReefAngel.h>

    ////// Place global variable code below here
      byte myRFMode=0;
        byte myRFDuration=0;
        byte myRFSpeed=0;


    ////// Place global variable code above here


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller
        // Ports toggled in Feeding Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port8Bit; // Turn off Ports 5 and 6 when Feeding Mode is activated
      ReefAngel.FeedingModePorts = Port1Bit | Port6Bit | Port8Bit; // Turn off Ports 1, 6, 7 and 8 when Water Change Mode is activated
      ReefAngel.LightsOnPorts = Port2Bit | Port3Bit | Port4Bit| Port5Bit;
      ReefAngel.OverheatShutoffPorts = Port2Bit |Port3Bit | Port4Bit | Port5Bit | Port7Bit; // Turn off Ports 3,
        ReefAngel.TempProbe = T3_PROBE;
        ReefAngel.OverheatProbe = T3_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 825 );




        // Ports that are always on
        ReefAngel.Relay.On( Port1 );
        ReefAngel.Relay.On( Box1_Port2 );  // Razor Led
        ReefAngel.Relay.On( Box1_Port4 ); // Sump Equipment - UV, Pump
        ReefAngel.Relay.On( Box1_Port5 ); // MP40s   
        ReefAngel.Relay.On( Box1_Port6 ); // JBJ
        ////// Place additional initialization code below here
       

        ////// Place additional initialization code above here
    }

    void loop()
    {
      //  Port1 Return pump...  on all the time!!!
          ReefAngel.Relay.Set( Port2, !ReefAngel.Relay.Status( Port4 ) ); //Refuge
      //  Port3 ...  not used
          ReefAngel.StandardLights( Port4,10,0,20,0 ); //ATI Actinic
          ReefAngel.StandardLights( Port5,11,0,19,0 );  //ATI Daylight
          ReefAngel.StandardLights( Port6,10,0,20,0 );  //ATI Fan
          ReefAngel.StandardHeater( Port7,778,790 ); //Heater
          ReefAngel.Relay.DelayedOn( Port8,2 ); //Skimmer
         
          //box 2
          ReefAngel.Relay.Off( Box1_Port1); // Lunar Hub Not used   Port #9
    //   Box1_Port2 Razor_LED (Sump)...  on all the time!!!      Port #10
          ReefAngel.Relay.Off( Box1_Port3); // Start with the relay off       Port #11
                  if (hour()>=5 && hour()<10) ReefAngel.Relay.On(Box1_Port3); // Moonlight Between 5-10am turn the relay on
                  if (hour()>=20 && hour()<=23) ReefAngel.Relay.On(Box1_Port3); // From 8pm-Midnight turn the relay on

    //   Box1_Port4 Ecotech MP_40 Pumps  on all the time!!!      Port #12
    //   Box1_Port5 Razor_LED (Sump)...  on all the time!!!      Port #13
    //   Box1_Port6 JBJ ATO ...          on all the time!!!      Port #14
         ReefAngel.Relay.Off( Box1_Port7);  // ALK Doser ...      Port #15
         ReefAngel.Relay.Off( Box1_Port8);  // Calc Doser ...     Port #16


    ReefAngel.PWM.SetDaylight( MoonPhase() );

    // ReefAngel.PWM.SetDaylight(PWMParabola(20,0,23,0,0, MoonPhase(),0 ));



        ////// Place your custom code below here
       
       
          ReefAngel.RF.UseMemory = false;
          if (hour()>=6 && hour()<11)
            myRFSetMode(ReefCrest,85,10);
          else if (hour()>=11 && hour()<13)
            myRFSetMode(ReefCrest,85,10);
          else if (hour()>=13 && hour()<16)
            myRFSetMode(Smart_NTM,85,15);
          else if (hour()>=16 && hour()<19)
            myRFSetMode(ReefCrest,65,10);
          else
            myRFSetMode(Lagoon,40,10);
             
         
           
        // Hardcode PH calibrations
         //ReefAngel.PHMin=544; // PH7.0
         //ReefAngel.PHMax=830; // PH10.0

         RunDosingPumps();
         LogDosingPumps();
        ////// Place your custom code above here

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

    void DrawCustomMain()
    {

        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 48, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 48, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 94, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    /////////////////////////////////////////
    // Define Your dosing pumps
    /////////////////////////////////////////
    #define numDPumps 2
    byte pumpRelays[numDPumps]={ Box1_Port7, Box1_Port8 };
    int DPVolume[numDPumps]={ 3, 3 } ; // 1ml for each alk and calcium
    int DPRepeat[numDPumps]={ 240, 240 } ; // Repeat every 4 hrs 5x a day
    /////////////////////////////////////////
    // Define Calibration here
    /////////////////////////////////////////
    int CalTime[numDPumps]={ 600, 600 }; // 10 minutes / 10 minutes
    int CalVol[numDPumps]={ 350, 300 }; // 350ml / 300ml... .58 / .5

    /////////////////////////////////////////
    // Function: RunDosingPumps()
    /////////////////////////////////////////
    void RunDosingPumps() {
      float rate;
      int calcTime[numDPumps];

      for (int i=0;i < numDPumps; i++) {
        rate=(float)CalVol[i]/CalTime[i];
        calcTime[i]=DPVolume[i]/rate/(1440/DPRepeat[i]);

        // Run the pumps
        ReefAngel.DosingPumpRepeat(pumpRelays[i], i*20, DPRepeat[i], calcTime[i]); // Offset between each pump is 20 minutes
      }

      // Display Time calculated in portal
      ReefAngel.CustomVar[0]=calcTime[0];
      ReefAngel.CustomVar[1]=calcTime[1];
    }

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

      for (int i=0;i< numDPumps;i++) {
        if (ReefAngel.Relay.Status(pumpRelays[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)CalVol[i]/CalTime[i];

            // Report How much volume has been dosed per day.
            // Could make this in minutes... excercise for the reader..
            ReefAngel.CustomVar[2]=pumpTimer[0]*rate;
            ReefAngel.CustomVar[3]=pumpTimer[1]*rate; 
          }
        }
     
        // Clear timer at end of day
        if (now()%SECS_PER_DAY==SECS_PER_DAY-1) pumpTimer[i]=0;
      } 
    }


        void DrawCustomGraph()
        {
        }

        void myRFSetMode(byte m, byte s, byte d)
        {
          if (m!=myRFMode || s!=myRFSpeed || d!=myRFDuration || millis()<5000)
          {
            myRFMode=m;
            myRFSpeed=s;
            myRFDuration=d;
            ReefAngel.RF.SetMode(m,s,d);
          }
        }

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

Re: Custom Variables

Post by lnevo »

Question for you. Can you confirm the date/time on your RA. Second, were you having rebooting (time travel) issues that you're working on with Roberto on? Some of the data in your custom variables seems a little eratic, and just trying to see if we're overlapping with the other issues. Sorry if I'm mixing up your case with another. Also if you could let me know any intentional reboots over the past two days will help me troubleshoot...
egadgetjnr
Posts: 54
Joined: Wed Jul 18, 2012 1:32 pm

Post by egadgetjnr »

lnevo wrote:Question for you. Can you confirm the date/time on your RA. Second, were you having rebooting (time travel) issues that you're working on with Roberto on? Some of the data in your custom variables seems a little eratic, and just trying to see if we're overlapping with the other issues. Sorry if I'm mixing up your case with another. Also if you could let me know any intentional reboots over the past two days will help me troubleshoot...
Hey Lee, that's me who has the time travelling RA. :p it appears to be the dimming module that caused it.

Edit: it appears that more then just me might be having the time travel issue? I just saw a post then someone mentioned it. Lol
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

Ok here's what's happening...based on the code above you are only set to dose 3ml every 4 hours (that's 6x per day...you commented it was 5x) this equates to .5 ml per dosage....

Now the calibration settings you have calculate one pump at .58 ml/sec and the other at .5ml/sec... We'll come back to that...

The code above puts the calculated time in C0 and C1 and then C2 and C3 are the amount of ml dosed. Now looking at your parameters, C0 is not coming up....meaning it's getting 0's and C1 is sticking at 1.

C1 is sticking at 1 because it is set to dose .5ml per dosage and it takes 1 second to do that.

3 ml / .5ml/sec / 6 doses = 1

C0 is sticking at 0 because when you divide 3ml by .58ml/sec divided by 6 doses you get less than 1 (.86 seconds) which rounds to 0. Now we could go into millisecond dosing...but who wants to do that really...

The bouncing of C2 and C3 I believe are due to reboots...

I would one confirm your dosing pump flow rate 30ml and 35ml per minute are pretty fast for dosing pumps...but not unheard of.. Second I would raise the 3ml to something more measurable. Then examine C0 and C1 again to see if they meet your requirements.
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Custom Variables

Post by ecam »

Okay so just tested my calibration and .58 and .5 are correct for the dosing. on one pump o got 350 mls in 600 seconds (10 mins) and 309 mls in 600 mls in the other.

CO C1 didnt change while i ran the pump. however, c2 and c3 did change to reflect the volume dosed but its showing45 and 48 respectively. this should be showing 356 and 305.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

As i said c0 and c1 are the time per dose based on your calibration. Of you change 3ml to 30ml you will see c0 and c1 change.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

Why should they be showing the numbers you said? They will show ml not seconds. Those variables are bytes (0-255) if thy are displaying seconds they will roll over...they should show based on how many seconds they are run for times the rate they were calculated at. 45 and 48 sound right if you ran them for close to 10 minutes...
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

Also keep in mind due to rounding (.86 was showing 0...) the number will be less...

A .5ml/sec pump running 10 minutes would be 50ml so round down and be off by a second or two and you've got 48...

The .58ml/sec pump running for 10 minutes should have pumped 58ml so unless you were timing that they filled 10ml then it would be under 10 minutes...and again some rounding. Could explain the difference...

I used to have a routine that calibrated each pump for exactly 10 minutes then you could measure the exact volume (with an accurate device or scale 1ml = 1g). I'll try and dig it up.

But i think you are on track and working properly.

If you change the 3ml or have the volume pull from memory you can adjust the volume on the fly..
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Custom Variables

Post by ecam »

Lee the pumps running for 600 seconds at an average of .54 ml/s would result in the 350 and 300 respectively. so the numbers still dont add up

lnevo wrote:Also keep in mind due to rounding (.86 was showing 0...) the number will be less...

A .5ml/sec pump running 10 minutes would be 50ml so round down and be off by a second or two and you've got 48...

The .58ml/sec pump running for 10 minutes should have pumped 58ml so unless you were timing that they filled 10ml then it would be under 10 minutes...and again some rounding. Could explain the difference...

I used to have a routine that calibrated each pump for exactly 10 minutes then you could measure the exact volume (with an accurate device or scale 1ml = 1g). I'll try and dig it up.

But i think you are on track and working properly.

If you change the 3ml or have the volume pull from memory you can adjust the volume on the fly..
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

If you are dosing that many ml than you are surpassing the variable and rolling over the 255
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Custom Variables

Post by ecam »

Any solutions? This is RA doser I'm using I can't be the only one with this problem. Can I extend the count beyond 255?
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

Yes we just have to come up with one..

But how much are you plan ing to dose. Set your ra to 15ml and watch the charts..it should be very reliable..
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Custom Variables

Post by ecam »

lnevo wrote:Yes we just have to come up with one..

But how much are you plan ing to dose. Set your ra to 15ml and watch the charts..it should be very reliable..

im trying to calibrate my system now. that is why im startin low. I guess i should just have it does the 15 mls once a day for now till i need to increase. is that what you are suggesting/
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

What I'm saying is that 3 is too low and the time that you calibrate is running over our counter. In order to get the details of what is curerntly logged to C0-C3 we need numbers that work. Currently one pump is not dosing anything. If you probably increase to 4ml it would show something in C0.... then at each dose you should see it increment 1ml in C2/C3. Because of the speed of pump1 is why you getting a value of 0 and therefore not dosing one of your 2 part additives.

If you're nervous, I would suggest manually dosing for now and using Ro/Di to confirm that your dosing is doing what you want. Then you can put the numbers to whatever you need to confirm them.
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Custom Variables

Post by ecam »

Lee, so I changed the code to test. I have it set to dose 4mls every minute w\ a 1 minute offset. Its not running at all. been waiting for 30 mins. any ideas

Code: Select all

#include <Relay.h>

    #include <RA_ATO.h>
    #include <RF.h>
    #include <ReefAngel_Features.h>
    #include <Globals.h>
    #include <RA_Wifi.h>
    #include <Wire.h>
    #include <OneWire.h>
    #include <Time.h>
    #include <DS1307RTC.h>fafa
    #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 <InternalEEPROM.h>
    #include <RA_Colors.h>
    #include <RA_CustomColors.h>
    #include <Salinity.h>
    #include <RF.h>fa
    #include <IO.h>
    #include <ORP.h>
    #include <PH.h>
    #include <WaterLevel.h>
    #include <ReefAngel.h>

    ////// Place global variable code below here
      byte myRFMode=0;
        byte myRFDuration=0;
        byte myRFSpeed=0;


    ////// Place global variable code above here


    void setup()
    {
        // This must be the first line
        ReefAngel.Init();  //Initialize controller
        // Ports toggled in Feeding Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port8Bit; // Turn off Ports 5 and 6 when Feeding Mode is activated
      ReefAngel.FeedingModePorts = Port1Bit | Port6Bit | Port8Bit; // Turn off Ports 1, 6, 7 and 8 when Water Change Mode is activated
      ReefAngel.LightsOnPorts = Port2Bit | Port3Bit | Port4Bit| Port5Bit;
      ReefAngel.OverheatShutoffPorts = Port2Bit |Port3Bit | Port4Bit | Port5Bit | Port7Bit; // Turn off Ports 3,
        ReefAngel.TempProbe = T3_PROBE;
        ReefAngel.OverheatProbe = T3_PROBE;
        // Set the Overheat temperature setting
        InternalMemory.OverheatTemp_write( 825 );




        // Ports that are always on
        ReefAngel.Relay.On( Port1 );
        ReefAngel.Relay.On( Box1_Port2 );  // Razor Led
        ReefAngel.Relay.On( Box1_Port4 ); // Sump Equipment - UV, Pump
        ReefAngel.Relay.On( Box1_Port5 ); // MP40s   
        ReefAngel.Relay.On( Box1_Port6 ); // JBJ
        ////// Place additional initialization code below here
       

        ////// Place additional initialization code above here
    }

    void loop()
    {
      //  Port1 Return pump...  on all the time!!!
          ReefAngel.Relay.Set( Port2, !ReefAngel.Relay.Status( Port4 ) ); //Refuge
      //  Port3 ...  not used
          ReefAngel.StandardLights( Port4,10,0,20,0 ); //ATI Actinic
          ReefAngel.StandardLights( Port5,11,0,19,0 );  //ATI Daylight
          ReefAngel.StandardLights( Port6,10,0,20,0 );  //ATI Fan
          ReefAngel.StandardHeater( Port7,778,790 ); //Heater
          ReefAngel.Relay.DelayedOn( Port8,2 ); //Skimmer
         
          //box 2
          ReefAngel.Relay.Off( Box1_Port1); // Lunar Hub Not used   Port #9
    //   Box1_Port2 Razor_LED (Sump)...  on all the time!!!      Port #10
          ReefAngel.Relay.Off( Box1_Port3); // Start with the relay off       Port #11
                  if (hour()>=5 && hour()<10) ReefAngel.Relay.On(Box1_Port3); // Moonlight Between 5-10am turn the relay on
                  if (hour()>=20 && hour()<=23) ReefAngel.Relay.On(Box1_Port3); // From 8pm-Midnight turn the relay on

    //   Box1_Port4 Ecotech MP_40 Pumps  on all the time!!!      Port #12
    //   Box1_Port5 Razor_LED (Sump)...  on all the time!!!      Port #13
    //   Box1_Port6 JBJ ATO ...          on all the time!!!      Port #14
         ReefAngel.Relay.Off( Box1_Port7);  // ALK Doser ...      Port #15
         ReefAngel.Relay.Off( Box1_Port8);  // Calc Doser ...     Port #16


    ReefAngel.PWM.SetDaylight( MoonPhase() );

    // ReefAngel.PWM.SetDaylight(PWMParabola(20,0,23,0,0, MoonPhase(),0 ));



        ////// Place your custom code below here
       
       
          ReefAngel.RF.UseMemory = false;
          if (hour()>=6 && hour()<11)
            myRFSetMode(ReefCrest,85,10);
          else if (hour()>=11 && hour()<13)
            myRFSetMode(ReefCrest,85,10);
          else if (hour()>=13 && hour()<16)
            myRFSetMode(Smart_NTM,85,15);
          else if (hour()>=16 && hour()<19)
            myRFSetMode(ReefCrest,65,10);
          else
            myRFSetMode(Lagoon,40,10);
             
         
           
        // Hardcode PH calibrations
         //ReefAngel.PHMin=544; // PH7.0
         //ReefAngel.PHMax=830; // PH10.0

         RunDosingPumps();
         LogDosingPumps();
        ////// Place your custom code above here

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

    void DrawCustomMain()
    {

        pingSerial();

        // Parameters
    #if defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 48, ReefAngel.Params,
        ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
    #else // defined DisplayLEDPWM && ! defined RemoveAllLights
        ReefAngel.LCD.DrawMonitor( 15, 48, ReefAngel.Params );
    #endif // defined DisplayLEDPWM && ! defined RemoveAllLights
        pingSerial();

        // Main Relay Box
        byte TempRelay = ReefAngel.Relay.RelayData;
        TempRelay &= ReefAngel.Relay.RelayMaskOff;
        TempRelay |= ReefAngel.Relay.RelayMaskOn;
        ReefAngel.LCD.DrawOutletBox( 12, 94, TempRelay );
        pingSerial();

        // Date and Time
        ReefAngel.LCD.DrawDate( 6, 122 );
        pingSerial();
    }

    /////////////////////////////////////////
    // Define Your dosing pumps
    /////////////////////////////////////////
    #define numDPumps 2
    byte pumpRelays[numDPumps]={ Box1_Port7, Box1_Port8 };
    int DPVolume[numDPumps]={ 4, 4 } ; // 1ml for each alk and calcium
    int DPRepeat[numDPumps]={ 1, 1 } ; // Repeat every 4 hrs 6x a day ----in mins
    /////////////////////////////////////////
    // Define Calibration here
    /////////////////////////////////////////
    int CalTime[numDPumps]={ 600, 600 }; // 10 minutes / 10 minutes
    int CalVol[numDPumps]={ 350, 300 }; // 350ml / 300ml... .58 / .5

    /////////////////////////////////////////
    // Function: RunDosingPumps()
    /////////////////////////////////////////
    void RunDosingPumps() {
      float rate;
      int calcTime[numDPumps];

      for (int i=0;i < numDPumps; i++) {
        rate=(float)CalVol[i]/CalTime[i];
        calcTime[i]=DPVolume[i]/rate/(1440/DPRepeat[i]);

        // Run the pumps
        ReefAngel.DosingPumpRepeat(pumpRelays[i], i*1, DPRepeat[i], calcTime[i]); // Offset between each pump is 20 minutes
      }

      // Display Time calculated in portal
      ReefAngel.CustomVar[0]=calcTime[0];
      ReefAngel.CustomVar[1]=calcTime[1];
    }

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

      for (int i=0;i< numDPumps;i++) {
        if (ReefAngel.Relay.Status(pumpRelays[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)CalVol[i]/CalTime[i];

            // Report How much volume has been dosed per day.
            // Could make this in minutes... excercise for the reader..
            ReefAngel.CustomVar[2]=pumpTimer[0]*rate;
            ReefAngel.CustomVar[3]=pumpTimer[1]*rate; 
          }
        }
     
        // Clear timer at end of day
        if (now()%SECS_PER_DAY==SECS_PER_DAY-1) pumpTimer[i]=0;
      } 
    }


        void DrawCustomGraph()
        {
        }

        void myRFSetMode(byte m, byte s, byte d)
        {
          if (m!=myRFMode || s!=myRFSpeed || d!=myRFDuration || millis()<5000)
          {
            myRFMode=m;
            myRFSpeed=s;
            myRFDuration=d;
            ReefAngel.RF.SetMode(m,s,d);
          }
        }
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

Lol no you dont...

You have it set to dose 4ml over the course of 24 hours in 1 second intervals...

That will be 0 again...

Its volume / rate / number of doses

At 1 sec you have 1440 doses per day!!!
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Custom Variables

Post by ecam »

Lee, thanks for all the help. Its working great so far. Not time for the next project. Going to memory
rossbryant1956
Posts: 471
Joined: Sat Jan 14, 2012 2:08 pm
Location: Montgomery Village, MD

Re: Custom Variables

Post by rossbryant1956 »

Hey Lee

Studying your dosing code. What are doing here?

#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

Are these virtual outlets? Is there a post where you've discussed this? Thx
Roscoe's Reefs - Starting Over Again:

Building new 29g Nano after landlord went berserk over my 4 75 gallon tanks, Multiple RA's, Water mixing stations, etc. Your help welcomed in remembering all I've forgotten.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

Yes the VO represents Virtual Outlet in my naming convention. They are outlets that don't exist physically that I use to trigger activity in some of my functions. Mainly I use the RefillATO and EnableATO. The RefillATO fills my ato reservoir until it hits 100% and the EnableATO function is part of my water change that turns my auxilliary pump in my new SW into an ATO as I drain the tank with my reactor pump :)

Vacation and AutoFeed are tied to the memory location as well but an easy way to see/change the status of those modes.

Calibrate is the import one when it comes to dosing. It's used in conjunction with the LockPorts relay. Basically my dosing pumps can not be masked on / off in the portal or on the phone apps. If a mask is detected its removed immediately before the relay gets a chance to actually turn on. This prevents the dreaded oops my alk was on all day... Now my calibration on the other hand requires that you can turn on and off the ports. So first I unlock the ports by turning off the lock port relay. Then I turn on the calibration switch. Now I can manually turn on/off the dosing pumps and fill a container to whatever volume I want. Then if I want to save the changes, I turn off the calibration and then lock the ports. If I want to scrap the calibration, I turn off the lock ports and the timers are scrapped.

Now the nice thing about the calibration is it reuses some of the code in the LogDosing function to keep track of how long the relay was on. So at the end of the routine when I measure let's say 10ml of fluid, however long the pump was on while calibration relay was on is what is stored in memory for the calibration time. The time and volume determine the rate and my DosingPumps function uses the volume you specifcy to calculate how long to dose based on the calibration values.

Sorry if that was long and involved. But overall the virtual outlets are great. They are a fantastic method to trigger a function you want to happen in the RA without having to fiddle with memory to trigger it.
rossbryant1956
Posts: 471
Joined: Sat Jan 14, 2012 2:08 pm
Location: Montgomery Village, MD

Re: Custom Variables

Post by rossbryant1956 »

Dude, you are really scary... Thx. :?
Roscoe's Reefs - Starting Over Again:

Building new 29g Nano after landlord went berserk over my 4 75 gallon tanks, Multiple RA's, Water mixing stations, etc. Your help welcomed in remembering all I've forgotten.
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Custom Variables

Post by lnevo »

Uhm...thanks? :)
Post Reply