Dosing Question - Lee

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

Dosing Question - Lee

Post by ecam »

Code: Select all

/////////////////////////////////////////
// Define Your dosing pumps
/////////////////////////////////////////
#define numDPumps 2
byte pumpRelays[numDPumps]={ Port4, Port6 };
int DPVolume[numDPumps]={ 30, 30 } ; // 30ml for each alk and calcium
int DPRepeat[numDPumps]={ 60, 60 } ; // Repeat every 60 miniutes
/////////////////////////////////////////
// Define Calibration here
/////////////////////////////////////////
int CalTime[numDPumps]={ 600, 600 }; // 10 minutes / 10 minutes
int CalVol[numDPumps]={ 300, 178 }; // 300ml / 178ml

/////////////////////////////////////////
// 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*5, DPRepeat[i], calcTime[i]); // Offset between each pump is 5 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; 
  }  
}
Since the reef angel logs the volume being dosed daily. Will I be able to see a chart of this with my reef angel website? if not... is their anyway i can make it do so... The reason i want this is because i figured if I fill up a gallon bucket and can go back and check how long did it does over the month. I can notice when I may need to adjust my calibration due to the pump changing its pump rate

// Clear timer at end of day
if (now()%SECS_PER_DAY==SECS_PER_DAY-1) pumpTimer=0;
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Dosing Question - Lee

Post by lnevo »

Yes my code is logging through the ReefAngel.CustomVar[] and you can get the graph from the portal. However the portal only stores 7 days so you wont be able to see the full month, unless you log it yourself or use reeftronics.net :)

The only issue I've had with the logging I have is that I get a bit under what I put in which may just be rounding errors..
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Dosing Question - Lee

Post by ecam »

Is there anything special i need to do to feed data to reeftronics.
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Dosing Question - Lee

Post by ecam »

Also, i was looking through your custom pde and I want to "borrow" so much of it. Especailly the reminders. However, how do i get around your use of "memory" to use code like i like to use. Or to get to your code, do i have to go to the dark side of the force ("memory") :twisted: :lol:
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Dosing Question - Lee

Post by lnevo »

The dark side of the force is not that dark...all you need is the #define lines I use. But yes the reminders rely on memory otherwise if you load code or your controller resets then you would lose everything you saved.

You could just use variables though if you really wanted to avoid it...
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Dosing Question - Lee

Post by ecam »

Code: Select all

/////////////////////////////////////////
// Define Your dosing pumps
/////////////////////////////////////////
#define numDPumps 2
byte pumpRelays[numDPumps]={ Box1_Port7, Box1_Port8 };
int DPVolume[numDPumps]={ 30, 30 } ; // 30ml for each alk and calcium
int DPRepeat[numDPumps]={ 60, 60 } ; // Repeat every 60 miniutes
/////////////////////////////////////////
// Define Calibration here
/////////////////////////////////////////
int CalTime[numDPumps]={ 600, 600 }; // 10 minutes / 10 minutes
int CalVol[numDPumps]={ 350, 300 }; // 350ml / 300ml

/////////////////////////////////////////
// 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; 
  }  
}
lee, im gettigng a variable not expected before'{' token... any idea how to fix it
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Re: Dosing Question - Lee

Post by lnevo »

It's somewhere else in your code. I took that section and added the #include files and a blank setup() and loop() function and it compiles fine.

Can you post the full code please?
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Dosing Question - Lee

Post by ecam »

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 <AI.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 );

    // Setup ATO Port for AI communication
//    ReefAngel.AI.SetPort( lowATOPin );



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

 
//    ReefAngel.AI.SetChannel( White, PWMParabola(11,0,17,0,0,75,0) );
//    ReefAngel.AI.SetChannel( Blue, PWMParabola(9,0,20,0,15,100,0) );
//    ReefAngel.AI.SetChannel( RoyalBlue, PWMParabola(9,0,20,0,15,100,(MoonPhase()/5)<3 ? 3:MoonPhase()/5) );
    ReefAngel.RF.UseMemory = false;
    ReefAngel.RF.SetMode( ReefCrest,85,10 );

  //  ReefAngel.RF.SetChannel( Radion_White, PWMParabola(9,0,20,0,0,60,0) );
  //  ReefAngel.RF.SetChannel( Radion_RoyalBlue, MoonPhase() );
  //  ReefAngel.RF.SetChannel( Radion_Red, PWMParabola(9,0,20,0,15,65,15) );
  //  ReefAngel.RF.SetChannel( Radion_Green, PWMParabola(9,0,20,0,15,50,15) );
  //  ReefAngel.RF.SetChannel( Radion_Blue, MoonPhase() );
 //   ReefAngel.RF.SetChannel( Radion_Intensity, PWMParabola(9,0,20,0,15,94,15) );
  //  if ( second()==0 ) ReefAngel.RF.RadionWrite();



/////////////////////////////////////////
// Define Your dosing pumps
/////////////////////////////////////////
#define numDPumps 2
byte pumpRelays[numDPumps]={ Box1_Port7, Box1_Port8 };
int DPVolume[numDPumps]={ 30, 30 } ; // 30ml for each alk and calcium
int DPRepeat[numDPumps]={ 60, 60 } ; // Repeat every 60 miniutes
/////////////////////////////////////////
// Define Calibration here
/////////////////////////////////////////
int CalTime[numDPumps]={ 600, 600 }; // 10 minutes / 10 minutes
int CalVol[numDPumps]={ 350, 300 }; // 350ml / 300ml

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






    ////// 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

    ////// Place your custom code above here

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

void DrawCustomMain()
{
    int x,y;
    char text[10];
    // Aqua Illumination
    x = 10;
    y = 20;
    ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x,y,"WH:" );
    ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x+38,y,"BL:" );
    ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x+76,y,"RB:" );
    for ( int a=0;a<3;a++ )
    {
      ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x+18,y,ReefAngel.AI.GetChannel(a) );
      x += 38;
    }
    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();
}

    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: Dosing Question - Lee

Post by lnevo »

That section that you originally posted does not go inside the loop() function. It's 2 functions and some global variables. It all goes at the bottom. And add only the function calls to the loop()

Code: Select all

     RunDosingPumps();
     LogDosingPumps();
Try this:

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 <AI.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 );

    // Setup ATO Port for AI communication
//    ReefAngel.AI.SetPort( lowATOPin );



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


//    ReefAngel.AI.SetChannel( White, PWMParabola(11,0,17,0,0,75,0) );
//    ReefAngel.AI.SetChannel( Blue, PWMParabola(9,0,20,0,15,100,0) );
//    ReefAngel.AI.SetChannel( RoyalBlue, PWMParabola(9,0,20,0,15,100,(MoonPhase()/5)<3 ? 3:MoonPhase()/5) );
    ReefAngel.RF.UseMemory = false;
    ReefAngel.RF.SetMode( ReefCrest,85,10 );

  //  ReefAngel.RF.SetChannel( Radion_White, PWMParabola(9,0,20,0,0,60,0) );
  //  ReefAngel.RF.SetChannel( Radion_RoyalBlue, MoonPhase() );
  //  ReefAngel.RF.SetChannel( Radion_Red, PWMParabola(9,0,20,0,15,65,15) );
  //  ReefAngel.RF.SetChannel( Radion_Green, PWMParabola(9,0,20,0,15,50,15) );
  //  ReefAngel.RF.SetChannel( Radion_Blue, MoonPhase() );
//   ReefAngel.RF.SetChannel( Radion_Intensity, PWMParabola(9,0,20,0,15,94,15) );
  //  if ( second()==0 ) ReefAngel.RF.RadionWrite();







    ////// 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()
{
    int x,y;
    char text[10];
    // Aqua Illumination
    x = 10;
    y = 20;
    ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x,y,"WH:" );
    ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x+38,y,"BL:" );
    ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x+76,y,"RB:" );
    for ( int a=0;a<3;a++ )
    {
      ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x+18,y,ReefAngel.AI.GetChannel(a) );
      x += 38;
    }
    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]={ 30, 30 } ; // 30ml for each alk and calcium
int DPRepeat[numDPumps]={ 60, 60 } ; // Repeat every 60 miniutes
/////////////////////////////////////////
// Define Calibration here
/////////////////////////////////////////
int CalTime[numDPumps]={ 600, 600 }; // 10 minutes / 10 minutes
int CalVol[numDPumps]={ 350, 300 }; // 350ml / 300ml

/////////////////////////////////////////
// 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);
      }
    }
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Dosing Question - Lee

Post by ecam »

Okay so i loaded this code. where do i go to see the log update. do i go to the portal the head unit or ipad app. how can i get it to show up on the portal



lnevo wrote:That section that you originally posted does not go inside the loop() function. It's 2 functions and some global variables. It all goes at the bottom. And add only the function calls to the loop()

Code: Select all

     RunDosingPumps();
     LogDosingPumps();
Try this:

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 <AI.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 );

    // Setup ATO Port for AI communication
//    ReefAngel.AI.SetPort( lowATOPin );



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


//    ReefAngel.AI.SetChannel( White, PWMParabola(11,0,17,0,0,75,0) );
//    ReefAngel.AI.SetChannel( Blue, PWMParabola(9,0,20,0,15,100,0) );
//    ReefAngel.AI.SetChannel( RoyalBlue, PWMParabola(9,0,20,0,15,100,(MoonPhase()/5)<3 ? 3:MoonPhase()/5) );
    ReefAngel.RF.UseMemory = false;
    ReefAngel.RF.SetMode( ReefCrest,85,10 );

  //  ReefAngel.RF.SetChannel( Radion_White, PWMParabola(9,0,20,0,0,60,0) );
  //  ReefAngel.RF.SetChannel( Radion_RoyalBlue, MoonPhase() );
  //  ReefAngel.RF.SetChannel( Radion_Red, PWMParabola(9,0,20,0,15,65,15) );
  //  ReefAngel.RF.SetChannel( Radion_Green, PWMParabola(9,0,20,0,15,50,15) );
  //  ReefAngel.RF.SetChannel( Radion_Blue, MoonPhase() );
//   ReefAngel.RF.SetChannel( Radion_Intensity, PWMParabola(9,0,20,0,15,94,15) );
  //  if ( second()==0 ) ReefAngel.RF.RadionWrite();







    ////// 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()
{
    int x,y;
    char text[10];
    // Aqua Illumination
    x = 10;
    y = 20;
    ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x,y,"WH:" );
    ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x+38,y,"BL:" );
    ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x+76,y,"RB:" );
    for ( int a=0;a<3;a++ )
    {
      ReefAngel.LCD.DrawText( COLOR_DODGERBLUE,DefaultBGColor,x+18,y,ReefAngel.AI.GetChannel(a) );
      x += 38;
    }
    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]={ 30, 30 } ; // 30ml for each alk and calcium
int DPRepeat[numDPumps]={ 60, 60 } ; // Repeat every 60 miniutes
/////////////////////////////////////////
// Define Calibration here
/////////////////////////////////////////
int CalTime[numDPumps]={ 600, 600 }; // 10 minutes / 10 minutes
int CalVol[numDPumps]={ 350, 300 }; // 350ml / 300ml

/////////////////////////////////////////
// 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: Dosing Question - Lee

Post by lnevo »

You should see it in the portal under the custom variables. If you want to see over time go to http://forum.reefangel.com/status/chart ... &filter=C2

Change C2 to C3 to see the other pump.
ecam
Posts: 229
Joined: Thu Nov 15, 2012 11:27 am

Re: Dosing Question - Lee

Post by ecam »

I dont see anything that would include custom variables anywhere. in the portal, it isnt dependant on memory is it?
Post Reply