3rd dosometric pump

Related to the development libraries, released by Curt Binder
Post Reply
pasqualevg
Posts: 13
Joined: Fri May 13, 2011 12:27 pm
Location: Italy

3rd dosometric pump

Post by pasqualevg »

Hi,
i'm planning a new pde to set my RA and i'm thinking if is possible to set a 3rd dosometric pump (to make the balling method)...
This should be a nice idea...
is it possible?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 3rd dosometric pump

Post by rimai »

Sure it is.
I actually don't even use timer for dosing on my tank.
I simply choose to dose every hour to be easier and I use this:

Code: Select all

  if (ReefAngel.DisplayedMenu==255 && minute()==0 && second()<4)  //Alk Doser - Only works if Main screen is showing
    ReefAngel.Relay.On(AlkDoser);  //Turn Alk Doser on
  else
    ReefAngel.Relay.Off(AlkDoser);  //Turn Alk Doser off
  if (ReefAngel.DisplayedMenu==255 && minute()==5 && second()<4)  //CA Doser - Only works if Main screen is showing
    ReefAngel.Relay.On(CaDoser);  //Turn CA Doser on
  else
    ReefAngel.Relay.Off(CaDoser);  //Turn CA Doser off
The code actually does Alk dosing on every full hour and CA dosing 5 minutes after.
You can simply add as many other ones you like and change the minute to spread them apart so they don't dose at the same time.
Roberto.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 3rd dosometric pump

Post by rimai »

Just anoter note, I choose to check to see if the main screen is showing just because I don't want the dosers to kick in when I'm doing water change or maintenance and my sump has no circulation, but if you are dosing in a place where there is always circulation, you can choose not to do the same check I do.
Roberto.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: 3rd dosometric pump

Post by binder »

Nice. I like the idea and concept of it. Clean and simple.

curt
pasqualevg
Posts: 13
Joined: Fri May 13, 2011 12:27 pm
Location: Italy

Re: 3rd dosometric pump

Post by pasqualevg »

yes... good idea but with this solution i can not change the dose simply changing a value on the memory...
There isn't a solution using the memory?
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: 3rd dosometric pump

Post by binder »

pasqualevg wrote:yes... good idea but with this solution i can not change the dose simply changing a value on the memory...
There isn't a solution using the memory?
There can be a solution using the memory. Were you wanting one like Roberto showed? If so, that can be simple to create. Or are you wanting something to be exactly like the existing dosing pump functions?

curt
pasqualevg
Posts: 13
Joined: Fri May 13, 2011 12:27 pm
Location: Italy

Re: 3rd dosometric pump

Post by pasqualevg »

For me is perfect like roberto say... the only think is:
if i want to increase the dosing of 3 seconds (for example)... i have to connect the RA with PC and re-charge the pde... and not simply change (througth wifi) a value on the memory...
And using the balling method probably i have to change many times the dosage to to reach the stability...

For me should be more intresting something like:

if (ReefAngel.DisplayedMenu==255 && hour()==15 && minute()==0 && second()<*value in the memory changeable via wifi*) //Doser - Only works if Main screen is showing
ReefAngel.Relay.On(1); //Turn relay1 on
else
ReefAngel.Relay.Off(1); //Turn relay1 off

Is it possible? I think many people want to use complete balling method (3 solutions to dose)...
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: 3rd dosometric pump

Post by binder »

Yeah, that's super easy to do. First thing we must do is pick a couple memory locations to use. Since the memory stuff will most likely be expanding in the future, we will pick some locations that I will not be touching (for this type of purpose).

We will use locations 100 (For the hour), 101 (For the minute), 102 (for the duration in seconds).

Code: Select all

// memory locations for the 3rd dosing pump
#define DP3_HOUR	100
#define DP3_MINUTE	101
#define DP3_SECONDS	102

void setup()
{
	// setup code here
}

void loop()
{
	// ...  OTHER CODE HERE, other functions, etc

	// Only turn on the pump if we are on the main menu
	if (ReefAngel.DisplayedMenu==DEFAULT_MENU && 
		hour()==InternalMemory.read(DP3_HOUR) &&
		minute()==InternalMemory.read(DP3_MINUTE) &&
		second()<InternalMemory.read(DP3_SECONDS)
		)
		ReefAngel.Relay.On(1); //Turn relay1 on
	else
		ReefAngel.Relay.Off(1); //Turn relay1 off

	// ... ADDITIONAL CODE HERE, if needed
}
To explain the code, here's what we are doing.
  • I created some define statements to tell where the memory locations are at that we are reading. I only did this to make things much more readable in the code and to have a single location to look for the values. So if you used them elsewhere in the code or need to find out what they are, it's easy to locate.
  • I put the check in for the displayed menu to be the default menu (home screen). I made it use the define that the libraries use, so if something ever changed in the future (highly doubtful this would change but still), it would be consistent and continue to work (plus it makes it more readable too).
  • I made the IF statement occupy multiple lines (which doesn't affect anything, just makes it easier to read) and put in the ability to read the values from the InternalMemory. So you can change the start time (hour & minute) and the run time (seconds) by using the wifi interface.
The values are all bytes. To update them, you have 2 choices: 1) Use my status application 2) Use a web browser.
Here's the commands to read/write them via the web browser (if you wanted to use this route):

Code: Select all

// Read the values, Hour, Minute, Seconds in that order
http://CONTROLLER_IP/mb100
http://CONTROLLER_IP/mb101
http://CONTROLLER_IP/mb102

// write the values, Hour, Minute, Seconds in that order
http://CONTROLLER_IP/mb100,VALUE
http://CONTROLLER_IP/mb101,VALUE
http://CONTROLLER_IP/mb102,VALUE
You would just have to copy & paste the URL into your web browser to update the values one at a time. Or you can just use the status app and update the values 1 at a time by using locations 100, 101, & 102.

curt
pasqualevg
Posts: 13
Joined: Fri May 13, 2011 12:27 pm
Location: Italy

Re: 3rd dosometric pump

Post by pasqualevg »

Great... i'm already using status application because the client cannot read/write °C in the memory screen...
Using this code should be very user-friendly

Thanks
ahmedess
Posts: 174
Joined: Sun May 22, 2011 2:29 pm

Re: 3rd dosometric pump

Post by ahmedess »

How can I offset doser2 from doser1 by x minutes if i m using the standard repeat dosing setup in my code?
I'd like to be able to set the interval and the duration and also the offset between them. The function Roberto posted it doses every hour with an offset of 5 mins what about if i want to be able to change the interval and the duration from the memory and have a time offset between each doser?
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: 3rd dosometric pump

Post by Deckoz2302 »

Create another memory value for offset and duration1 duration2 so you can have a different duration for each pump if you want, then instead of using just hour min seconds duration on the second pump you would use hour min+offset. Seconds duration
ahmedess
Posts: 174
Joined: Sun May 22, 2011 2:29 pm

Re: 3rd dosometric pump

Post by ahmedess »

I was thinking about using this function which is available in the dev. libraries file reefangel.cpp, because it already has everything setup for it in memory except the offset so all i need to figure out is how i could modify this function to add an offset for doser2

Code: Select all

void ReefAngelClass::DosingPumpRepeat(byte DPRelay, byte DPTimer, int RepeatMinute, byte RunTime)
{
	/*
	This function runs the specified relay for the RunTime seconds every RepeatMinute minutes.
	So you can run the relay for 10 seconds every 60 minutes (1 hour)

	This function bases the RepeatMinute off of Midnight (00:00) of the current day.  It uses midnight to
	compute when the pump will run.

	DPRelay - Relay that contains the dosing pump
	Timer - number of the timer in the timer array to use
	RepeatMinute - number of minutes to wait before running the pump again
	RunTime - duration (in seconds) to run the pump
	*/

	// if the current minutes since midnight are divisible by the repeat interval and the current seconds
	// are zero (top of the minute), then we can run the pump
	time_t t = now();
	uint8_t h = hour(t);
	if ( (h == 0) && (minute(t) == 0) )
	{
		// if we are at midnight, change hours to 24 so we can get the correct minutes for computation
		h = 24;
	}
	int current_min = NumMins(h, minute(t));
	int r = current_min % RepeatMinute;
	if ( (r == 0) && (second(t) == 0) )
	{
		Relay.On(DPRelay);
		Timer[DPTimer].SetInterval(RunTime);
		Timer[DPTimer].Start();
	}

	// Should change the timer to be a Dosing Pump Timer
	// is the timer expired?
	if ( Timer[DPTimer].IsTriggered() )
	{
		Relay.Off(DPRelay);
	}
}
ahmedess
Posts: 174
Joined: Sun May 22, 2011 2:29 pm

Re: 3rd dosometric pump

Post by ahmedess »

Deckoz2302 wrote:Create another memory value for offset and duration1 duration2 so you can have a different duration for each pump if you want, then instead of using just hour min seconds duration on the second pump you would use hour min+offset. Seconds duration

what about if i wanna change the interval?
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: 3rd dosometric pump

Post by Deckoz2302 »

What interval where you looking to do? Odd numbers, even numbers. Interval how rimai posted was when minutes from time equal 0 and seconds are under 4. You could do something like.

if (ReefAngel.DisplayedMenu==255 && hour() % memvar# == 0 && minute()==0 && second()<4)
Relay on
Else
Off

Its not true code just an idea. For even numbers - set memvar# as 2, for odd numbers flip the on off. Ie if statement would be off else would be on. Or you could do every 3 hours setting memvar. As 3, or every 8 setting it as 8. So you don't. Have to plug into the reef angel to switch between odd & even you could creat another memvar with if statment, set it as 0 for even, 1 for odd and write a statement in loop

If (memvar# ==0) even();
Else (memvar#==1) odd();

Then create a function for each odd and even, or you could skip writing a function and do a boolean statement. Sorry I'm on my phone ill type something out when I get home hope it makes sense
ahmedess
Posts: 174
Joined: Sun May 22, 2011 2:29 pm

Re: 3rd dosometric pump

Post by ahmedess »

actually i was thinkin of shortening the interval period cause my dosers are 1ml/min so they are very slow thats why I might wanna dose every 30 minutes for example. so i want to be able to set the interval in minutes so that if i want to set it less than an hour i could and if i wanna set it more than an hour I d still be able to. At the same time I still want to offset the dosers from each other.

what about if i do this:

if (ReefAngel.DisplayedMenu==255 && minute() % memvar# == 0 && second()<InternalMemory.DP1Timer_read())

then if i set memvar to 30 I d be dosing every 30 minutes, correct? how could i offset now?
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: 3rd dosometric pump

Post by Deckoz2302 »

I think you could do == 0 + 5
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 3rd dosometric pump

Post by rimai »

Well, it would work... But, here is my point of view.
If you for example change the memvar to let's say 25, the doser will be activated at xx:00, XX:25 and XX:50. It would not be an even 25 minutes throughout the day.
If you want an even distribuition throughout the day, you will need to compare it to number of minutes from midnight.
So, the function would be something like this:

Code: Select all

if (ReefAngel.DisplayedMenu==255 && NumMinutes(hour(),minute()) % InternalMemory.DP1OnMinute_read() == 0 && second()<InternalMemory.DP1Timer_read())
You can use a defined memory location DP1OnMinute to store your minutes interval. Just keep in mind not to use any of the DosingPump or DosingPumpInterval functions.
The offset can be done by just changing the 0 on the comparison.
The below would have a 5 minute offset from the first.

Code: Select all

if (ReefAngel.DisplayedMenu==255 && NumMinutes(hour(),minute()) % InternalMemory.DP1OnMinute_read() == 5 && second()<InternalMemory.DP1Timer_read())
Give it a shot and see if it works.
Roberto.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 3rd dosometric pump

Post by rimai »

Deckoz2302 wrote:I think you could do == 0 + 5
Dead center :ugeek:
Roberto.
Deckoz2302
Posts: 149
Joined: Tue Nov 01, 2011 11:05 am

Re: 3rd dosometric pump

Post by Deckoz2302 »

Lol I try :)
ahmedess
Posts: 174
Joined: Sun May 22, 2011 2:29 pm

Re: 3rd dosometric pump

Post by ahmedess »

rimai wrote:Well, it would work... But, here is my point of view.
If you for example change the memvar to let's say 25, the doser will be activated at xx:00, XX:25 and XX:50. It would not be an even 25 minutes throughout the day.
If you want an even distribuition throughout the day, you will need to compare it to number of minutes from midnight.
So, the function would be something like this:

Code: Select all

if (ReefAngel.DisplayedMenu==255 && NumMinutes(hour(),minute()) % InternalMemory.DP1OnMinute_read() == 0 && second()<InternalMemory.DP1Timer_read())
You can use a defined memory location DP1OnMinute to store your minutes interval. Just keep in mind not to use any of the DosingPump or DosingPumpInterval functions.
The offset can be done by just changing the 0 on the comparison.
The below would have a 5 minute offset from the first.

Code: Select all

if (ReefAngel.DisplayedMenu==255 && NumMinutes(hour(),minute()) % InternalMemory.DP1OnMinute_read() == 5 && second()<InternalMemory.DP1Timer_read())
Give it a shot and see if it works.
tested the functions above, the offset works fine but the duration does not because as soon as the current time jumps to the next minute the condition no longer becomes true because of this part "NumMinutes(hour(),minute()) % InternalMemory.DP1OnMinute_read() == 0"

so the doser gets turned off as soon as 1 minute passes
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 3rd dosometric pump

Post by rimai »

How long would you like to dose?
More than 60 seconds?
Roberto.
ahmedess
Posts: 174
Joined: Sun May 22, 2011 2:29 pm

Re: 3rd dosometric pump

Post by ahmedess »

yes 200 secs
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 3rd dosometric pump

Post by rimai »

Yeah, this code won't work then.
Turns out you will indeed have to use something similar to the DosingPumpRepeat()

Code: Select all

  if (ReefAngel.DisplayedMenu==255 && (NumMins(hour(),minute()) % InternalMemory.DP1OnMinute_read()) == 0 && second() == 0)
  {
    ReefAngel.Timer[1].SetInterval(InternalMemory.DP1Timer_read()); // Read DP1Timer
    ReefAngel.Timer[1].Start();
    ReefAngel.Relay.On(Port1);
  }
  if (ReefAngel.Timer[1].IsTriggered())
  {
    ReefAngel.Relay.Off(Port1);
  }

  if (ReefAngel.DisplayedMenu==255 && (NumMins(hour(),minute()) % InternalMemory.DP1OnMinute_read()) == 5 && second() == 0)
  {
    ReefAngel.Timer[2].SetInterval(InternalMemory.DP2Timer_read()); // Read DP2Timer
    ReefAngel.Timer[2].Start();
    ReefAngel.Relay.On(Port2);
  }
  if (ReefAngel.Timer[2].IsTriggered())
  {
    ReefAngel.Relay.Off(Port2);
  }
In the code above, we are using just DP1OnMinute for both doser to make sure they are in sync and only 5 minutes apart.
DP1Timer and DP2Timer can be different, so you can have different dosages for pump1 and pump2.
Let me know if it works this way.
Roberto.
ahmedess
Posts: 174
Joined: Sun May 22, 2011 2:29 pm

Re: 3rd dosometric pump

Post by ahmedess »

Its workin fine now, thanks
ahmedess
Posts: 174
Joined: Sun May 22, 2011 2:29 pm

Re: 3rd dosometric pump

Post by ahmedess »

rimai wrote:Yeah, this code won't work then.
Turns out you will indeed have to use something similar to the DosingPumpRepeat()

Code: Select all

  if (ReefAngel.DisplayedMenu==255 && (NumMins(hour(),minute()) % InternalMemory.DP1OnMinute_read()) == 0 && second() == 0)
  {
    ReefAngel.Timer[1].SetInterval(InternalMemory.DP1Timer_read()); // Read DP1Timer
    ReefAngel.Timer[1].Start();
    ReefAngel.Relay.On(Port1);
  }
  if (ReefAngel.Timer[1].IsTriggered())
  {
    ReefAngel.Relay.Off(Port1);
  }

  if (ReefAngel.DisplayedMenu==255 && (NumMins(hour(),minute()) % InternalMemory.DP1OnMinute_read()) == 5 && second() == 0)
  {
    ReefAngel.Timer[2].SetInterval(InternalMemory.DP2Timer_read()); // Read DP2Timer
    ReefAngel.Timer[2].Start();
    ReefAngel.Relay.On(Port2);
  }
  if (ReefAngel.Timer[2].IsTriggered())
  {
    ReefAngel.Relay.Off(Port2);
  }
In the code above, we are using just DP1OnMinute for both doser to make sure they are in sync and only 5 minutes apart.
DP1Timer and DP2Timer can be different, so you can have different dosages for pump1 and pump2.
Let me know if it works this way.

if i want to be able to change the dosing interval using the memory location "InternalMemory.DP1RepeatInterval" lets say change it from repeating the dose every hour to repeating the dose every 30 minutes, how do i code that?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: 3rd dosometric pump

Post by rimai »

Code: Select all

ReefAngel.DosingPump1(Port1);
Roberto.
Post Reply