IO Expansion Module - Check Reservoirs

Do you have a question on how to do something.
Ask in here.
Post Reply
btorrenga
Posts: 100
Joined: Mon Apr 16, 2012 10:22 pm

IO Expansion Module - Check Reservoirs

Post by btorrenga »

Curt helped me write a custom ATO function that will mimic the standard ATO but on three ports - there are three reservoirs, each with its own topoff pump in it:

Code: Select all

void MyCustomATO(int ATOTimeout)
{
   unsigned long TempTimeout = ATOTimeout;
   TempTimeout *= 1000;

    if ( ReefAngel.LowATO.IsActive() && ( !ReefAngel.LowATO.IsTopping()) )
    {
        ReefAngel.LowATO.Timer = millis();
        ReefAngel.LowATO.StartTopping();
        ReefAngel.Relay.On(Port5);
      ReefAngel.Relay.On(Port6);
      ReefAngel.Relay.On(Box1_Port5);
    }
   
    if ( ReefAngel.HighATO.IsActive() )
    {
      ReefAngel.LowATO.StopTopping();  // stop the low ato timer
        ReefAngel.Relay.Off(Port5);
      ReefAngel.Relay.Off(Port6);
      ReefAngel.Relay.Off(Box1_Port5);
    }

   if ( (millis()-ReefAngel.LowATO.Timer > TempTimeout) && ReefAngel.LowATO.IsTopping() )
   {
      ReefAngel.LED.On();
#ifdef ENABLE_EXCEED_FLAGS
      InternalMemory.write(ATO_Exceed_Flag, 1);
#endif  // ENABLE_EXCEED_FLAGS
        ReefAngel.Relay.Off(Port5);
      ReefAngel.Relay.Off(Port6);
      ReefAngel.Relay.Off(Box1_Port5);
#ifdef ENABLE_ATO_LOGGING
      // bump the counter if a timeout occurs
      AtoEventCount++;
      if ( AtoEventCount >= MAX_ATO_LOG_EVENTS ) { AtoEventCount = 0; }
#endif  // ENABLE_ATO_LOGGING
   }
}
The above works great. But, the kicker is that I want to have my IO expansion module not allow a topoff pump to run if there is no water in that pump's reservoir. I have been unable to find any code examples that do anything similar to what I want to achieve. Can anyone point me in the right direction? The tutorial for the IO Expansion is pretty sparse. (Extra credit points to anyone who can also suggest a method of firing off an email when a reservoir runs dry.)
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: IO Expansion Module - Check Reservoirs

Post by rimai »

Try this:

Code: Select all

  if ( ReefAngel.IO.GetChannel(0) ) 
  {
    ReefAngel.Relay.Off(Port5);
    ReefAngel.Relay.Off(Port6);
    ReefAngel.Relay.Off(Box1_Port5);
    ReefAngel.CustomVar[0]=1;
  }
  else
  {
    MyCustomATO(6);
    ReefAngel.CustomVar[0]=0;
  }
You will need to enable Custom Variables feature on RAGen.
Then, use the Portal to send you an email if C0>0
Roberto.
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: IO Expansion Module - Check Reservoirs

Post by binder »

Sounds like you would use the ReefAngel.IO.GetChannel() for each of the three reservoirs.
Roberto's example incorporates all three into one.
Here's an example that checks all 3 reservoirs inside the MyCustomATO and only activates the ATO's that the pumps are not dry and alerts for the 3.
I got a little carried away with this function. I added a CheckReservoirStatus function that monitors the IO port for the level of the reservoir. I used this function to check whether we can start the port while topping. Now, if the timeout exceeds, this function will continue to try to turn on the pumps because the IsTopping is still enabled/set (same logic).
You will have to test this out to see if it works for you. You may need to remove the block that I marked "might need to remove this check here". I added that section in as another safeguard to prevent the pump from running if the reservoir goes empty while topping.

Code: Select all

void CheckReservoirStatus(byte channel, byte pump)
{
    if ( ReefAngel.IO.GetChannel(channel) )
    {
        // If empty, shutoff the port, trigger alert
        ReefAngel.CustomVar[0] = 1;
        ReefAngel.Relay.Off(Port5);
    }
    else
    {
        // If not empty, turn on the port, clear alert
        ReefAngel.CustomVar[0] = 0;
        ReefAngel.Relay.On(Port5);
    }
}

void MyCustomATO(int ATOTimeout)
{
    /*
    This function works as follows:

    When it's time to topoff the system, we check the levels of each
    of the three reservoirs.  If a reservoir is empty, we set a custom
    flag to indicate it's empty on the portal and we do not start that
    pump.  Otherwise, we clear the custom flag for the reservoir and
    start the pump.
    The function monitors the switch levels like normal.
    Monitor the status of the reservoirs while topping off.
    When the high switch is triggered (aka, finished topping off), 
    ALL ports are turned off regardless of status (doesn't hurt to do this).
    If the timeout occurs, the LED light comes on and all ports are 
    turned off just like when we finish topping off.
    
    */
    unsigned long TempTimeout = ATOTimeout;
    TempTimeout *= 1000;

    if ( ReefAngel.LowATO.IsActive() && ( !ReefAngel.LowATO.IsTopping()) )
    {
        ReefAngel.LowATO.Timer = millis();
        ReefAngel.LowATO.StartTopping();

        // Check the level of each reservoir
        // If empty, set the alert and don't start topping off
        // otherwise if not empty, clear the alert and start topping
        CheckReservoirStatus(0, Port5);
        CheckReservoirStatus(1, Port6);
        CheckReservoirStatus(2, Box1_Port5);
    }

    // Monitor levels while topping off, to prevent a reservoir from running dry
    // Might need to remove this check here
    if ( ReefAngel.LowATO.IsTopping() )
    {
        CheckReservoirStatus(0, Port5);
        CheckReservoirStatus(1, Port6);
        CheckReservoirStatus(2, Box1_Port5);
    }

    if ( ReefAngel.HighATO.IsActive() )
    {
        ReefAngel.LowATO.StopTopping();  // stop the low ato timer
        ReefAngel.Relay.Off(Port5);
        ReefAngel.Relay.Off(Port6);
        ReefAngel.Relay.Off(Box1_Port5);
    }

    if ( (millis()-ReefAngel.LowATO.Timer > TempTimeout) && ReefAngel.LowATO.IsTopping() )
    {
        ReefAngel.LED.On();
#ifdef ENABLE_EXCEED_FLAGS
        InternalMemory.write(ATO_Exceed_Flag, 1);
#endif  // ENABLE_EXCEED_FLAGS
        ReefAngel.Relay.Off(Port5);
        ReefAngel.Relay.Off(Port6);
        ReefAngel.Relay.Off(Box1_Port5);
#ifdef ENABLE_ATO_LOGGING
        // bump the counter if a timeout occurs
        AtoEventCount++;
        if ( AtoEventCount >= MAX_ATO_LOG_EVENTS ) { AtoEventCount = 0; }
#endif  // ENABLE_ATO_LOGGING
    }
}
Anyways, this should be another good example for you to work from.
btorrenga
Posts: 100
Joined: Mon Apr 16, 2012 10:22 pm

Re: IO Expansion Module - Check Reservoirs

Post by btorrenga »

Thanks Curt. I am pretty sure I understand your code, and it makes sense to me.

I think maybe in the CheckReservoirStatus you meant to do something like this:

Code: Select all

void CheckReservoirStatus(byte channel, byte pump)
{
    if ( ReefAngel.IO.GetChannel(channel) )
    {
        // If empty, shutoff the port, trigger alert
        ReefAngel.CustomVar[channel] = 1;
        ReefAngel.Relay.Off(pump);
    }
    else
    {
        // If not empty, turn on the port, clear alert
        ReefAngel.CustomVar[channel] = 0;
        ReefAngel.Relay.On(pump);
    }
}
The code appears to work PERFECTLY. This is really starting to turn into quite a perfect setup.

I still need to configure the notifications properly. I think maybe the portal data got screwed up, as the plot of my data has not updated in two days for some reason.
binder
Posts: 2865
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: IO Expansion Module - Check Reservoirs

Post by binder »

Good catch. You are right. That's what happens when I think too much. ;-)
Post Reply