I/O Expansion and ATO 1, 2, 3, 4....

Expansion modules and attachments
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

Hi everyone :), I am new here... based in East London, Eastern Cape, South Africa.

I hope you are all well!! I am needing some help with adding more ATO pumps to my Reef Angel (RA) system I currently have ATO1 (StandardAto) operating fine on relay box port 1 with float switches connected to the high and low ATO float switches input ports on the RA controller.

I am needing to sort out ATO2 which I want on relay box port 2 with float switches connected to channnel 0 and channel 1 on the i/o expansion module.

I may also add more ATO's in the future so can anyone please assist with the code.

@rimai

Code is as follows:

#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 <ReefAngel.h>
#include <Salinity.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>


byte x,y;
byte bkcolor;

void DrawCustomMain()
{
// the graph is drawn/updated when we exit the main menu &
// when the parameters are saved
ReefAngel.LCD.DrawDate(6, 112);
pingSerial();
#if defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params,
ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue());
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params);
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
pingSerial();
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
y=10;
x=15;
for (int a=0;a<6;a++)
{
if(ReefAngel._IO.GetChannel(a)) bkcolor=COLOR_RED;
else bkcolor=COLOR_GREEN;
if (a>2) x=75;
if (a==3) y=10;
ReefAngel.LCD.Clear(bkcolor, x, y-3, x+40,y-1);
ReefAngel.LCD.Clear(bkcolor, x, y+8, x+40,y+10);
ReefAngel.LCD.Clear(bkcolor, x, y, x+3,y+8);
ReefAngel.LCD.Clear(bkcolor, x+37, y, x+40,y+8);
ReefAngel.LCD.DrawText(COLOR_WHITE, bkcolor, x+3, y, "Input");
ReefAngel.LCD.DrawText(COLOR_WHITE, bkcolor, x+32, y, a);
y+=15;
}
}

void DrawCustomGraph()
{
}

/*

For more information about custom main screen (RA forum URL removed)
*/

// Define Relay Ports By Name
#define ATO1 1
#define ATO2 2 *This is the one i must sort out.
#define Skimmer 3
#define Daylights 4
#define Flowpumps1 5
#define Flowpumps2 6
#define Heaters 7
#define Return 8

void setup()
{
ReefAngel.Init(); // Initialize Controller
ReefAngel.AddDateTimeMenu();
ReefAngel.AddStandardMenu();
ReefAngel.SetTemperatureUnit(Celsius); // set Temperature to Celsius
ReefAngel.FeedingModePorts = Port5Bit | Port6Bit; // Turn off Ports 5 and 6 when Feeding Mode is activated
ReefAngel.WaterChangePorts = Port1Bit | Port2Bit | Port3Bit | Port5Bit | Port6Bit | Port7Bit | Port8Bit; // Turn off Ports 1, 2, 3, 5, 6, 7 and 8 when Water Change Mode is activated
ReefAngel.OverheatShutoffPorts = Port4Bit | Port7Bit; // Turn off Ports 4 and 7 when Overheat Occurs
ReefAngel.LightsOnPorts = Port4Bit; // Turn on/off Ports 4 when Turn Lights On/Off is activated
ReefAngel.OverheatProbe = T1_PROBE | T2_PROBE | T3_PROBE; // Use Temperature probe 1, 2 and 3 to check for overheat
ReefAngel.TempProbe = T1_PROBE | T2_PROBE | T3_PROBE; // Use Temperature probe 1, 2 and 3 to check temperature

// Always on
ReefAngel.Relay.On(Return);
ReefAngel.Relay.On(Skimmer);
ReefAngel.Relay.On(Flowpumps1);
ReefAngel.Relay.On(Flowpumps2);
}

void loop()
{
ReefAngel.StandardATO(ATO1); // Standard ATO
ReefAngel.StandardLights(Daylights); // Daylight Lights
ReefAngel.StandardHeater(Heaters); // Heater
ReefAngel.PWM.StandardDaylight(); // Dimming for Daylight Channel
ReefAngel.PWM.StandardActinic(30); // Dimming for Actinic Channel
ReefAngel.ShowInterface(); // Display everything on the LCD screen
}

If i can see the ReefAngel.StandardATO code as it is written in the RA memory then i may be able to use that as the only difference will be that the input ports for the float switches will be on the i/o expansion module and not the RA controller as with ATO1.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

I/O Expansion and ATO 1, 2, 3, 4....

Post by binder »

the libraries code is inside the Arduino/libraries folder. inside there, look for the ReefAngel folder. inside there, the StandardATO function is located in the ReefAngel.cpp file.

you can then simply copy the function and paste it into your INO file with some modifications to use the other I/O pins.

Sent from my iPad using Tapatalk
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

Thanks @binder i first had to figure out where exactly i find this library folder so i researched a bit and came across some useful information at www.arduino/en/hacking/libraries which directed me to it's location on Windows: My Documents\Arduino\libraries\. When I went there I ended up at C:\Users\User\Documents\Arduino\libraries\ReefAngel as i was searching for the Reef Angel folder and Cpp file and i found it!

I removed the StandardAto part and it is as follows:
void ReefAngelClass::StandardATO(byte ATORelay, int ATOTimeout)
{
// Input: Relay port and timeout value (max number of seconds that ATO pump is allowed to run)
unsigned long TempTimeout = ATOTimeout;
TempTimeout *= 1000;

/*
Is the low switch active (meaning we need to top off) and are we not currently topping off
Then we set the timer to be now and start the topping pump
*/
if ( LowATO.IsActive() && ( !LowATO.IsTopping()) )
{
LowATO.Timer = millis();
LowATO.StartTopping();
Relay.On(ATORelay);
}

// If the high switch is activated, this is a safeguard to prevent over running of the top off pump
if ( HighATO.IsActive() )
{
LowATO.StopTopping(); // stop the low ato timer
Relay.Off(ATORelay);
}

/*
If the current time minus the start time of the ATO pump is greater than the specified timeout value
AND the ATO pump is currently running:
We turn on the status LED and shut off the ATO pump
This prevents the ATO pump from contniously running.
*/
if ( (millis()-LowATO.Timer > TempTimeout) && LowATO.IsTopping() )
{
LED.On();
bitSet(AlertFlags,ATOTimeOutFlag);
#ifdef ENABLE_EXCEED_FLAGS
if (InternalMemory.read(ATO_Exceed_Flag)==0)
InternalMemory.write(ATO_Exceed_Flag, 1);
#endif // ENABLE_EXCEED_FLAGS
Relay.Off(ATORelay);
#ifdef ENABLE_ATO_LOGGING
// bump the counter if a timeout occurs
AtoEventCount++;
if ( AtoEventCount >= MAX_ATO_LOG_EVENTS ) { AtoEventCount = 0; }
#endif // ENABLE_ATO_LOGGING
}
}

I now just need to figure out where to insert i/o channel 0 (Low) and i/o channel 1 (High). If i don't revert back soon with info that i came right will you mind just showing me where this changes must be please? Another thing i am wondering about is will this code effect my current timeout setting of 150 seconds and if so must i put this value in somewhere.

Thanks,
Juan
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

JclaasSA wrote:void ReefAngelClass::StandardATO(byte ATORelay, int ATOTimeout)
Just to answer my own question it looks like the 150 seconds time out must be put in lace of ATOTimeout.
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

If I insert a value here then how will i be able to change this via the App or Portal?
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

I haven't managed to come right yet so i tried a more basic approach.. still without any luck!

//RA Standard ATO code for ATO2 on IO exansion
void StandardATO()
{
// If the low switch is active, turn ATO2 pump on
if (ReefAngel.IO.GetChannel(0))
{
ReefAngel.Relay.On(ATO2);
}
// If the high switch is activated, turn ATO2 pump off
if ( ReefAngel.IO.GetChannel(1))
{
ReefAngel.Relay.Off(ATO2);
}

If this code can be corrected to work please assist and then i want the timeout to also be included as it appears in the RA cpp file.

@binder
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by binder »

I will look at it more later (in several hours) when I am done at work and can spend a little time on it to give you an answer.

Sent from my XT1585 using Tapatalk
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

OK thanks a lot I'm looking forward to your positive response.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by binder »

On a side note, you have a problem with the TempProbe and OverheatProbe lines.
You have these 2 lines:

Code: Select all

ReefAngel.OverheatProbe = T1_PROBE | T2_PROBE | T3_PROBE; // Use Temperature probe 1, 2 and 3 to check for overheat
ReefAngel.TempProbe = T1_PROBE | T2_PROBE | T3_PROBE; // Use Temperature probe 1, 2 and 3 to check temperature
This will not work properly. In fact, this code just tells the controller to use the T3_PROBE to monitor the Overheat and Temp probes. Unfortunately, you cannot use the built-in Overheat check to monitor all 3 probes and you cannot use the Temp probe to be all three probes either. The built-in functions only operate when you have 1 of those 3 probes selected. If you want all three probes to be used, then you must have a custom function written.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by binder »

Ok. I took the time to write out some code for you. I wrote it so it could be incorporated into your INO file.

I have created your entire code and you should just be able to copy and paste the entire code block and run it. I have not tried to compile it or run it, but it should work. I have it set to where you could easily add in an ATO 3 or 4 just by adding a few more lines.

I assume that you are controlling port2 (ATO2) for the relay and that IO port 0 is the low switch and IO port 1 is the high switch. The switches should be mounted exactly like the standard switches are. I have hard coded the 150s timeout value as well. This can be changed in the future but that's a minor change. I wanted to get the code working first.

The function you call in your loop() is ATOoverIO(ato2). The variable ato2 is different from your port ATO2. ato2 is a special variable that i created just for the function. You will see how it is created when you look through the code.

Anyways, give this code a try and see how it works.

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 <ReefAngel.h>
#include <Salinity.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>


byte x,y;
byte bkcolor;

void DrawCustomMain()
{
// the graph is drawn/updated when we exit the main menu &
// when the parameters are saved
ReefAngel.LCD.DrawDate(6, 112);
pingSerial();
#if defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params,
ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue());
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params);
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
pingSerial();
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
y=10;
x=15;
for (int a=0;a<6;a++)
{
if(ReefAngel._IO.GetChannel(a)) bkcolor=COLOR_RED;
else bkcolor=COLOR_GREEN;
if (a>2) x=75;
if (a==3) y=10;
ReefAngel.LCD.Clear(bkcolor, x, y-3, x+40,y-1);
ReefAngel.LCD.Clear(bkcolor, x, y+8, x+40,y+10);
ReefAngel.LCD.Clear(bkcolor, x, y, x+3,y+8);
ReefAngel.LCD.Clear(bkcolor, x+37, y, x+40,y+8);
ReefAngel.LCD.DrawText(COLOR_WHITE, bkcolor, x+3, y, "Input");
ReefAngel.LCD.DrawText(COLOR_WHITE, bkcolor, x+32, y, a);
y+=15;
}
}

void DrawCustomGraph()
{
}

/*

For more information about custom main screen (RA forum URL removed)
*/

// Define Relay Ports By Name
#define ATO1 1
#define ATO2 2 *This is the one i must sort out.
#define Skimmer 3
#define Daylights 4
#define Flowpumps1 5
#define Flowpumps2 6
#define Heaters 7
#define Return 8

// Custom ATO Functions
typedef struct _ATOIO {
  byte relay;  // port to control
  int timeout;  // max number of seconds that the ATO pump is allowed to run
  byte low_ioport; // IO port the low switch is connected
  byte high_ioport; // IO port the high switch is connected
  unsigned long timer;
  boolean topping; // are we currently topping off / running
} ATOIO;

void ATOoverIO(ATOIO &ato)
{
	unsigned long TempTimeout = ato.timeout;
	TempTimeout *= 1000;

	/*
	Is the low switch active (meaning we need to top off) and are we not currently topping off
	Then we set the timer to be now and start the topping pump
	 */
  if ( ReefAngel.IO.GetChannel(ato.low_ioport) && (!ato.topping)) {
    ato.timer = millis();
    ato.topping = true;
    ReefAngel.Relay.On(ato.relay);
  }

	// If the high switch is activated, this is a safeguard to prevent over running of the top off pump
  if ( ReefAngel.IO.GetChanngel(ato.high_ioport) ) {
    ato.topping = false;
    ReefAngel.Relay.Off(ato.relay);
  }

	/*
    If the current time minus the start time of the ATO pump is greater than the specified timeout value
    AND the ATO pump is currently running:
    We turn on the status LED and shut off the ATO pump
    This prevents the ATO pump from continuously running.
	 */
  if ( (millis() - ato.timer > TempTimeout) && ato.topping ) {
    ReefAngel.LED.On();
    // Verify the bitset function works properly
    bitSet(ReefAngel.AlertFlags, ReefAngel.ATOTimeOutFlag);
    ReefAngel.Relay.Off(ato.relay);
  }
}
// End Custom ATO Functions

// Create additional ATO's
ATOIO ato2;
ato2.relay = ATO2;  // Relay to use
ato2.timeout = 150;  // 150s timeout
ato2.low_ioport = 0;  // IO Port 0
ato2.high_ioport = 1;  // IO Port 1
ato2.timer = 0;  // always initialize to 0
ato2.topping = false;  // always initialize to false


void setup()
{
ReefAngel.Init(); // Initialize Controller
ReefAngel.AddDateTimeMenu();
ReefAngel.AddStandardMenu();
ReefAngel.SetTemperatureUnit(Celsius); // set Temperature to Celsius
ReefAngel.FeedingModePorts = Port5Bit | Port6Bit; // Turn off Ports 5 and 6 when Feeding Mode is activated
ReefAngel.WaterChangePorts = Port1Bit | Port2Bit | Port3Bit | Port5Bit | Port6Bit | Port7Bit | Port8Bit; // Turn off Ports 1, 2, 3, 5, 6, 7 and 8 when Water Change Mode is activated
ReefAngel.OverheatShutoffPorts = Port4Bit | Port7Bit; // Turn off Ports 4 and 7 when Overheat Occurs
ReefAngel.LightsOnPorts = Port4Bit; // Turn on/off Ports 4 when Turn Lights On/Off is activated
ReefAngel.OverheatProbe = T1_PROBE; // Use Temperature probe 1
ReefAngel.TempProbe = T1_PROBE; // Use Temperature probe 1

// Always on
ReefAngel.Relay.On(Return);
ReefAngel.Relay.On(Skimmer);
ReefAngel.Relay.On(Flowpumps1);
ReefAngel.Relay.On(Flowpumps2);
}

void loop()
{
ReefAngel.StandardATO(ATO1); // Standard ATO
ATOoverIO(ato2); // Alternate ATO2
ReefAngel.StandardLights(Daylights); // Daylight Lights
ReefAngel.StandardHeater(Heaters); // Heater
ReefAngel.PWM.StandardDaylight(); // Dimming for Daylight Channel
ReefAngel.PWM.StandardActinic(30); // Dimming for Actinic Channel
ReefAngel.ShowInterface(); // Display everything on the LCD screen
}
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

Thank you for your time with this.. I just tried to compile and received the following:

variable or field 'ATOoverIO' declared void

sketch_aug23a:26: error: variable or field 'ATOoverIO' declared void
sketch_aug23a:26: error: 'ATOIO' was not declared in this scope
sketch_aug23a:26: error: 'ato' was not declared in this scope
sketch_aug23a.cpp: In function 'void DrawCustomMain()':
sketch_aug23a:53: error: 'class ReefAngelClass' has no member named '_IO'
sketch_aug23a.cpp: At global scope:
sketch_aug23a:96: error: expected ',' or '...' before '&&' token
sketch_aug23a.cpp: In function 'void ATOoverIO(ATOIO)':
sketch_aug23a:98: error: 'ato' was not declared in this scope
sketch_aug23a:112: error: 'class IOClass' has no member named 'GetChanngel'
sketch_aug23a:126: error: expected unqualified-id before numeric constant
sketch_aug23a:126: error: expected `)' before numeric constant
sketch_aug23a:126: error: expected `)' before ';' token
sketch_aug23a:126: error: expected `)' before ';' token
sketch_aug23a.cpp: At global scope:
sketch_aug23a:134: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:135: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:136: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:137: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:138: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:139: error: expected constructor, destructor, or type conversion before '.' token
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

Fixed some of the obvious things, here is an update on the compilation fault-

variable or field 'ATOoverIO' declared void


sketch_aug23a:26: error: variable or field 'ATOoverIO' declared void
sketch_aug23a:26: error: 'ATOIO' was not declared in this scope
sketch_aug23a:26: error: 'ato' was not declared in this scope
sketch_aug23a.cpp: In function 'void ATOoverIO(ATOIO&)':
sketch_aug23a:126: error: expected unqualified-id before numeric constant
sketch_aug23a:126: error: expected `)' before numeric constant
sketch_aug23a:126: error: expected `)' before ';' token
sketch_aug23a:126: error: expected `)' before ';' token
sketch_aug23a.cpp: At global scope:
sketch_aug23a:134: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:135: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:136: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:137: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:138: error: expected constructor, destructor, or type conversion before '.' token
sketch_aug23a:139: error: expected constructor, destructor, or type conversion before '.' token
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

Updated code with compilation fault variable or field 'ATOoverIO' declared void

RA_Ino_ino_ATO2:27: error: variable or field 'ATOoverIO' declared void
RA_Ino_ino_ATO2:27: error: 'ATOIO' was not declared in this scope
RA_Ino_ino_ATO2:27: error: 'ato' was not declared in this scope
RA_Ino_ino_ATO2.cpp: In function 'void ATOoverIO(ATOIO&)':
RA_Ino_ino_ATO2:129: error: expected unqualified-id before numeric constant
RA_Ino_ino_ATO2:129: error: expected `)' before numeric constant
RA_Ino_ino_ATO2:129: error: expected `)' before ';' token
RA_Ino_ino_ATO2:129: error: expected `)' before ';' token
RA_Ino_ino_ATO2.cpp: At global scope:
RA_Ino_ino_ATO2:137: error: expected constructor, destructor, or type conversion before '.' token
RA_Ino_ino_ATO2:138: error: expected constructor, destructor, or type conversion before '.' token
RA_Ino_ino_ATO2:139: error: expected constructor, destructor, or type conversion before '.' token
RA_Ino_ino_ATO2:140: error: expected constructor, destructor, or type conversion before '.' token
RA_Ino_ino_ATO2:141: error: expected constructor, destructor, or type conversion before '.' token
RA_Ino_ino_ATO2:142: error: expected constructor, destructor, or type conversion before '.' token

Code: Select all

#include <Salinity.h>
#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 <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

// CustomMainscreen_IOExpansion
byte x,y;
byte bkcolor;


void DrawCustomMain()
{
  // the graph is drawn/updated when we exit the main menu &
  // when the parameters are saved
  ReefAngel.LCD.DrawDate(6, 112);
  pingSerial();
#if defined DisplayLEDPWM && ! defined RemoveAllLights
  ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params,
  ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue());
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
  ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params);
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
  pingSerial();
  byte TempRelay = ReefAngel.Relay.RelayData;
  TempRelay &= ReefAngel.Relay.RelayMaskOff;
  TempRelay |= ReefAngel.Relay.RelayMaskOn;
  ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
  y=10;
  x=15;
  for (int a=0;a<6;a++)
  {
    if(ReefAngel.IO.GetChannel(a)) bkcolor=COLOR_RED; 
    else bkcolor=COLOR_GREEN; 
    if (a>2) x=75;
    if (a==3) y=10;
    ReefAngel.LCD.Clear(bkcolor, x, y-3, x+40,y-1);
    ReefAngel.LCD.Clear(bkcolor, x, y+8, x+40,y+10);
    ReefAngel.LCD.Clear(bkcolor, x, y, x+3,y+8);
    ReefAngel.LCD.Clear(bkcolor, x+37, y, x+40,y+8);
    ReefAngel.LCD.DrawText(COLOR_WHITE, bkcolor, x+3, y, "Input");
    ReefAngel.LCD.DrawText(COLOR_WHITE, bkcolor, x+32, y, a);
    y+=15;
  }
}

void DrawCustomGraph()
{
}

/*
  
 For more information about custom main screen: http://forum.reefangel.com/viewtopic.php?f=14&t=109
 
 */

// Define Relay Ports By Name
#define ATO1               1
#define ATO2               2
#define Skimmer            3
#define Daylights          4
#define Flowpumps1         5
#define Flowpumps2         6
#define Heaters            7
#define Return             8

// Custom ATO Functions
typedef struct _ATOIO {
  byte relay;  // port to control
  int timeout;  // max number of seconds that the ATO pump is allowed to run
  byte low_ioport; // IO port the low switch is connected
  byte high_ioport; // IO port the high switch is connected
  unsigned long timer;
  boolean topping; // are we currently topping off / running
} ATOIO;

void ATOoverIO(ATOIO &ato)
{
   unsigned long TempTimeout = ato.timeout;
   TempTimeout *= 1000;

   /*
   Is the low switch active (meaning we need to top off) and are we not currently topping off
   Then we set the timer to be now and start the topping pump
    */
  if ( ReefAngel.IO.GetChannel(ato.low_ioport) && (!ato.topping)) {
    ato.timer = millis();
    ato.topping = true;
    ReefAngel.Relay.On(ato.relay);
  }

   // If the high switch is activated, this is a safeguard to prevent over running of the top off pump
  if ( ReefAngel.IO.GetChannel(ato.high_ioport) ) {
    ato.topping = false;
    ReefAngel.Relay.Off(ato.relay);
  }

   /*
    If the current time minus the start time of the ATO pump is greater than the specified timeout value
    AND the ATO pump is currently running:
    We turn on the status LED and shut off the ATO pump
    This prevents the ATO pump from continuously running.
    */
  if ( (millis() - ato.timer > TempTimeout) && ato.topping ) {
    ReefAngel.LED.On();
    // Verify the bitset function works properly
    bitSet(ReefAngel.AlertFlags, ReefAngel.ATOTimeOutFlag);
    ReefAngel.Relay.Off(ato.relay);
  }
}
// End Custom ATO Functions

// Create additional ATO's
ATOIO ato2;
ato2.relay = ATO2;  // Relay to use
ato2.timeout = 150;  // 150s timeout
ato2.low_ioport = 0;  // IO Port 0
ato2.high_ioport = 1;  // IO Port 1
ato2.timer = 0;  // always initialize to 0
ato2.topping = false;  // always initialize to false

void setup()
{
  ReefAngel.Init(); // Initialize Controller
  ReefAngel.AddDateTimeMenu(); 
  ReefAngel.AddStandardMenu();
  ReefAngel.SetTemperatureUnit(Celsius);  // set Temperature to Celsius
  ReefAngel.FeedingModePorts = Port5Bit | Port6Bit; // Turn off Ports 5 and 6 when Feeding Mode is activated
  ReefAngel.WaterChangePorts = Port1Bit | Port2Bit | Port3Bit | Port5Bit | Port6Bit | Port7Bit | Port8Bit; // Turn off Ports 1, 2, 3, 5, 6, 7 and 8 when Water Change Mode is activated
  ReefAngel.OverheatShutoffPorts = Port4Bit | Port7Bit; // Turn off Ports 4 and 7 when Overheat Occurs
  ReefAngel.LightsOnPorts = Port4Bit; // Turn on/off Ports 4 when Turn Lights On/Off is activated
  ReefAngel.OverheatProbe = T1_PROBE; // Use Temperature probe 1, 2 and 3 to check for overheat
  ReefAngel.TempProbe = T1_PROBE; // Use Temperature probe 1, 2 and 3 to check temperature
  
  // Always on
  ReefAngel.Relay.On(Return);
  ReefAngel.Relay.On(Skimmer);
  ReefAngel.Relay.On(Flowpumps1);
  ReefAngel.Relay.On(Flowpumps2);
}

void loop()
{
  ReefAngel.StandardATO(ATO1); // Standard ATO
  ATOoverIO(ato2); // Alternate ATO2
  ReefAngel.StandardLights(Daylights); // Daylight Lights
  ReefAngel.StandardHeater(Heaters); // Heater
  ReefAngel.PWM.StandardDaylight(); // Dimming for Daylight Channel
  ReefAngel.PWM.StandardActinic(30); // Dimming for Actinic Channel
  ReefAngel.ShowInterface(); // Display everything on the LCD screen
}




binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by binder »

ok. that's what I get for not testing it. I'll look more and get it figured out.

Sent from my XT1585 using Tapatalk
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

OK thank you sir! Do you have a separate system for testing or do you just upset yours? I'm thinking of keeping one just for testing as I have another one..
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

Any luck with us putting this one to bed...
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by binder »

JclaasSA wrote:OK thank you sir! Do you have a separate system for testing or do you just upset yours? I'm thinking of keeping one just for testing as I have another one..
I have several. I have 1 specifically for testing. with what I am doing for you doesn't require anything other than compiling the code.
JclaasSA wrote:Any luck with us putting this one to bed...
not tonight. I had a big issue to deal with today that kept me from getting to it. I'm sure I made a simple error.

Sent from my XT1585 using Tapatalk
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

binder wrote:
JclaasSA wrote:OK thank you sir! Do you have a separate system for testing or do you just upset yours? I'm thinking of keeping one just for testing as I have another one..
I have several. I have 1 specifically for testing. with what I am doing for you doesn't require anything other than compiling the code.
JclaasSA wrote:Any luck with us putting this one to bed...
not tonight. I had a big issue to deal with today that kept me from getting to it. I'm sure I made a simple error.

Sent from my XT1585 using Tapatalk
I actually that that you would have one for testing, thats great! I will do the same with the extra unit i have, but i am under the impression that i may need to get a new board for it as the screen goes funny (Flickers) after a while and then goes off.

I hope you got your stuff sorted.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by binder »

JclaasSA wrote: I hope you got your stuff sorted.
I did, thanks. I completely re-plumbed my entire fish tank/sump and had some major problems. Fortunately I was able to fix the problems but took me a lot longer than expected. Then I had to deal with a small leak, that is hopefully fixed.

I did start to look at the code last night and was checking on some of the things I did and was making sure I was using the code properly. I will hopefully have something for you tonight.


Sent from my iPad using Tapatalk
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

Hectic! I know what that's like.. it's at least an evening or two's work and having stuff like leaks doesn't help reduce the time. I once converted a boyu tank for someone to include an overflow and a sump.. it was a 1m tank with the cuboard being two separate compartments at the bottom so I had to build to sumps (one for the skimmer and the othe for the return which I obviously had to join. Anyway it leaked in between them.. I almost thought I wasnt going to win! So that's probably my worse leak other than an anemone blocking the overflow at 5am haha

Thanks man I appreciate it.
binder
Posts: 2871
Joined: Fri Mar 18, 2011 6:20 pm
Location: Illinois
Contact:

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by binder »

I had to scrap what I did partially due to a nuance with Arduino and sketches. Anyways, this function works but it's currently hard coded to ATO2. We can change it for future improvements if it works properly for you.

Code: Select all

#include <Salinity.h>
#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 <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

// CustomMainscreen_IOExpansion
byte x,y;
byte bkcolor;


void DrawCustomMain()
{
  // the graph is drawn/updated when we exit the main menu &
  // when the parameters are saved
  ReefAngel.LCD.DrawDate(6, 112);
  pingSerial();
#if defined DisplayLEDPWM && ! defined RemoveAllLights
  ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params,
  ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue());
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
  ReefAngel.LCD.DrawMonitor(15, 60, ReefAngel.Params);
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
  pingSerial();
  byte TempRelay = ReefAngel.Relay.RelayData;
  TempRelay &= ReefAngel.Relay.RelayMaskOff;
  TempRelay |= ReefAngel.Relay.RelayMaskOn;
  ReefAngel.LCD.DrawOutletBox(12, 93, TempRelay);
  y=10;
  x=15;
  for (int a=0;a<6;a++)
  {
    if(ReefAngel.IO.GetChannel(a)) bkcolor=COLOR_RED;
    else bkcolor=COLOR_GREEN;
    if (a>2) x=75;
    if (a==3) y=10;
    ReefAngel.LCD.Clear(bkcolor, x, y-3, x+40,y-1);
    ReefAngel.LCD.Clear(bkcolor, x, y+8, x+40,y+10);
    ReefAngel.LCD.Clear(bkcolor, x, y, x+3,y+8);
    ReefAngel.LCD.Clear(bkcolor, x+37, y, x+40,y+8);
    ReefAngel.LCD.DrawText(COLOR_WHITE, bkcolor, x+3, y, "Input");
    ReefAngel.LCD.DrawText(COLOR_WHITE, bkcolor, x+32, y, a);
    y+=15;
  }
}

void DrawCustomGraph()
{
}

/*

 For more information about custom main screen: http://forum.reefangel.com/viewtopic.php?f=14&t=109

 */

// Define Relay Ports By Name
#define ATO1               1
#define ATO2               2
#define Skimmer            3
#define Daylights          4
#define Flowpumps1         5
#define Flowpumps2         6
#define Heaters            7
#define Return             8

// Custom ATO Functions
unsigned long ATO2_timer = 0;
boolean ATO2_topping = false;
void ATOoverIO(byte relay, int timeout, byte low_ioport, byte high_ioport){
   unsigned long TempTimeout = timeout;
   TempTimeout *= 1000;

   //Is the low switch active (meaning we need to top off) and are we not currently topping off
   //Then we set the timer to be now and start the topping pump

  if ( ReefAngel.IO.GetChannel(low_ioport) && (!ATO2_topping)) {
    ATO2_timer = millis();
    ATO2_topping = true;
    ReefAngel.Relay.On(relay);
  }

   // If the high switch is activated, this is a safeguard to prevent over running of the top off pump
  if ( ReefAngel.IO.GetChannel(high_ioport) ) {
    ATO2_topping = false;
    ReefAngel.Relay.Off(relay);
  }

    // If the current time minus the start time of the ATO pump is greater than the specified timeout value
    // AND the ATO pump is currently running:
    // We turn on the status LED and shut off the ATO pump
    // This prevents the ATO pump from continuously running.

  if ( (millis() - ATO2_timer > TempTimeout) && ATO2_topping ) {
    ReefAngel.LED.On();
    // Verify the bitset function works properly
    //bitSet(ReefAngel.AlertFlags, ReefAngel.ATOTimeOutFlag);
    ReefAngel.Relay.Off(relay);
  }
}

void setup()
{
  ReefAngel.Init(); // Initialize Controller
  ReefAngel.AddDateTimeMenu();
  ReefAngel.AddStandardMenu();
  ReefAngel.SetTemperatureUnit(Celsius);  // set Temperature to Celsius
  ReefAngel.FeedingModePorts = Port5Bit | Port6Bit; // Turn off Ports 5 and 6 when Feeding Mode is activated
  ReefAngel.WaterChangePorts = Port1Bit | Port2Bit | Port3Bit | Port5Bit | Port6Bit | Port7Bit | Port8Bit; // Turn off Ports 1, 2, 3, 5, 6, 7 and 8 when Water Change Mode is activated
  ReefAngel.OverheatShutoffPorts = Port4Bit | Port7Bit; // Turn off Ports 4 and 7 when Overheat Occurs
  ReefAngel.LightsOnPorts = Port4Bit; // Turn on/off Ports 4 when Turn Lights On/Off is activated
  ReefAngel.OverheatProbe = T1_PROBE; // Use Temperature probe 1, 2 and 3 to check for overheat
  ReefAngel.TempProbe = T1_PROBE; // Use Temperature probe 1, 2 and 3 to check temperature

  // Always on
  ReefAngel.Relay.On(Return);
  ReefAngel.Relay.On(Skimmer);
  ReefAngel.Relay.On(Flowpumps1);
  ReefAngel.Relay.On(Flowpumps2);

  // Initialize ATO2 values
  ATO2_timer = 0;  // always initialize to 0
  ATO2_topping = false;  // always initialize to false
}

void loop()
{
  ReefAngel.StandardATO(ATO1); // Standard ATO
  // ATOoverIO(Relay, Timeout, low io port, high io port)
  ATOoverIO(ATO2, 150, 0, 1); // Alternate ATO2
  ReefAngel.StandardLights(Daylights); // Daylight Lights
  ReefAngel.StandardHeater(Heaters); // Heater
  ReefAngel.PWM.StandardDaylight(); // Dimming for Daylight Channel
  ReefAngel.PWM.StandardActinic(30); // Dimming for Actinic Channel
  ReefAngel.ShowInterface(); // Display everything on the LCD screen
}

It compiles and will need tested. So give it a test and see how it does for you.
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

OK cool thanks will do so now as soon as possible should be this morning! Let you know...
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

Now this code compiles, that's great !

BUT am I too much of a perfectionist here or what buddy?? We are trying to have the standard ato funtion but just on the i/o expansion. I tested it using the same orientation of the floats as required in standard ato.

Standard ATO
Here is the way the Stand ardATO function works:
High switch mounted with wires at the bottom
Low switch mounted with the wires at the top
When water level lowers all the way to cause the low switch to be active (float is touching the end opposite from 2
wires coming out of it), the ATO pump/specified relay is turned on.
The ATO pump runs until the water level raises the low switch up from making contact, continues to raise the water
level until the high switch is active (float is touching the end opposite of the 2 wires coming out of it). The ATO pump
shuts off when the high switch is active OR if the ATO Timeout value is exceeded. The timeout prevents the pump
from running too long in case the reservoir runs dry or something else happens.
Water then evaporates out of the tank and lowers until the low switch is active.
Repeat process

The closest I get is with channel 0 float with wires at the bottom and channel 1 float with wires at the top but it turns the relay on and off without influence from float on channel 0.

Can you have a look at this again please with floats in standard ato orientation and revert back if i am talking nonsense!

Thanks.
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

You have already been a big help @binder - it's much appreciated! !

I look forward to your answer.
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

@rimai
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

@binder
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by rimai »

Probably you have the channels in the wrong position.
Try switching 0 on top and 1 at the bottom
Roberto.
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

rimai wrote:Probably you have the channels in the wrong position.
Try switching 0 on top and 1 at the bottom
Please upload this on your side and just test it for me. It appears to be code issue.
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

rimai wrote:Probably you have the channels in the wrong position.
Try switching 0 on top and 1 at the bottom
I did this.
JclaasSA
Posts: 25
Joined: Fri Aug 18, 2017 10:11 am

Re: I/O Expansion and ATO 1, 2, 3, 4....

Post by JclaasSA »

@rimai please reply to my posts.
Post Reply