Salinity temp compensation?

Expansion modules and attachments
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Salinity temp compensation?

Post by dazza1304 »

From the reading I have been doing and testing myself, I have seen and found that over a relatively small range of temperatures, the temp effect on salinity is very linear and typically in the range of 2-2.4% per deg Celsius change.

Why not have automatic temp compensation provided in the libraries to enable more accurate salinity readings?

I am sure most people with reef angel will control their temps within very tight limits, and this would improve the accuracy of salinity readings.

For example, with salinity of 35ppt, for each 0.1 deg variation, you will typically get a variation in salinity of 0.077ppt, (so almost 0.1ppt for each 0.1 deg C) which is significant.

I have for some time been using ATO based off salinity, but it is not controlled as tight as is possible (or I would like) with the reef angel for the above reason.

I found this code, and as an interim would like to use it, just not sure where to put it so to speak, also I run my tank at 25.5 deg, so would I need to change the values to 255 instead of 250 - but ultimately, could this not be incorporated as standard into reef angel code which will make the reef angel even more awesome! In fact I think that other product to do with neptune has this feature!?

Posted: 22 Mar 2012 19:27
Ok, I changed it to this:
CODE: SELECT ALL
double SalCompensation;
if (TempSensor.unit)
SalCompensation=Params.Salinity/(1+((Params.Temp[T1_PROBE]-250)*0.0024));
else
SalCompensation=Params.Salinity/(1+((Params.Temp[T1_PROBE]-770)*0.001333));
Params.Salinity=round(SalCompensation);
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

Actually, in order for this to work, you must save the temperature in which the calibration occurred in internal memory.
Then, you can calibrate at any temperature and also compensate it to adjust to any temperature variance along the way.
The formula you posted was contributed by a user and did not work quite well for me.
I was never able to make it work.
I did however come up with another formula that I have tested for a +/- 10F degree variance and it performed quite well.
This is what I used:

Code: Select all

      double SalCompensation;
      if (ReefAngel.TempSensor.unit)
        SalCompensation=ReefAngel.Params.Salinity/(1+((t-InternalMemory.SalTempComp_read())*0.00344123));
      else
        SalCompensation=ReefAngel.Params.Salinity/(1+((t-InternalMemory.SalTempComp_read())*0.001925));//001333
      ReefAngel.Params.Salinity=round(SalCompensation);
But in order for this formula to work, the temperature in which the salilnity calibration occured must be save in internal memory (SalTempComp location).
If you want to test and confirm it is working, it would be awesome.
Post your code and I can change it to apply the compensation.
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

rimai wrote:Actually, in order for this to work, you must save the temperature in which the calibration occurred in internal memory.
Then, you can calibrate at any temperature and also compensate it to adjust to any temperature variance along the way.
The formula you posted was contributed by a user and did not work quite well for me.
I was never able to make it work.
I did however come up with another formula that I have tested for a +/- 10F degree variance and it performed quite well.
This is what I used:

Code: Select all

      double SalCompensation;
      if (ReefAngel.TempSensor.unit)
        SalCompensation=ReefAngel.Params.Salinity/(1+((t-InternalMemory.SalTempComp_read())*0.00344123));
      else
        SalCompensation=ReefAngel.Params.Salinity/(1+((t-InternalMemory.SalTempComp_read())*0.001925));//001333
      ReefAngel.Params.Salinity=round(SalCompensation);
But in order for this formula to work, the temperature in which the salilnity calibration occured must be save in internal memory (SalTempComp location).
If you want to test and confirm it is working, it would be awesome.
Post your code and I can change it to apply the compensation.
more than happy to give it a try!!! Just let me know where I need to enter my cal temp etc!! Also, ultimately as said before, it would be great to have incorporated in the embedded code - for salinity cal I could see a simple change where you enter your tank temp probe, then set your compensation factor, then salinity cal.

Anyway, below is my code -

PS - what is it with all these idiots lately posting rubbish?
#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 <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

////// Place global variable code below here
unsigned long lastLowSal=now();//salinity >35.1 timer
boolean SALduration=true;//salinity >35.1 for 2 minutes flag
boolean ATOEnabled=false;//enable ATO function for 5 seconds
boolean ATOPumping=true;//disable ATO function for 5 minutes
unsigned long ATOStart=now();//ATO 5 sec run timer

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


void setup()
{
    // This must be the first line
    ReefAngel.Init(); //Initialize controller
    ReefAngel.SetTemperatureUnit( Celsius ); // set to Celsius Temperature

    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.FeedingModePortsE[0] = 0;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port2Bit;
    ReefAngel.WaterChangePortsE[0] = 0;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    ReefAngel.LightsOnPortsE[0] = 0;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port6Bit;
    ReefAngel.OverheatShutoffPortsE[0] = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 260 );


    // Ports that are always on
    ReefAngel.Relay.On( Port4 );
    ReefAngel.Relay.On( Port5 );
    ReefAngel.Relay.On( Port8 );
    ReefAngel.Relay.On( Box1_Port1 );
    ReefAngel.Relay.On( Box1_Port2 );
    ReefAngel.Relay.On( Box1_Port4 );
    ReefAngel.Relay.On( Box1_Port6 );
    ReefAngel.Relay.On( Box1_Port7 );
    ReefAngel.Relay.On( Box1_Port8 );
    
    ////// Place additional initialization code below here
    
    ReefAngel.Timer[1].SetInterval(1800); // 30 mins before reactivation of ATO
    
    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.MHLights( Port3,0,30,23,30,5 );//skimmer off and on for dosing reef energy
    ReefAngel.StandardHeater( Port6,254,255 );
    ReefAngel.StandardFan( Port7,255,256 );
    ReefAngel.MHLights( Box1_Port5,23,30,23,31,0 );//air pump for mix reef energy prior to dosing
    ////// Place your custom code below here
    ReefAngel.WaterLevelATO(Port2,180,38,40);// Salinty top up to keep water level correct
    
    ///// If salinity >35.1 for 120 sec set SALduration flag
    if (ReefAngel.Params.Salinity<351) lastLowSal=now();
    
    if (now()-lastLowSal>120) SALduration=false;
  
    if (SALduration && ATOPumping)//if salinity>35.1 for 2 minutes enable ATO
  
    {ATOStart=now();
  }
  else
  {
    ATOEnabled=true;
    ATOPumping=false;
  }

  if (now()-ATOStart<5)//ATO pump on time 5 seconds
  {
    if (ATOEnabled) ReefAngel.Relay.On(Port1);
    ReefAngel.Timer[1].Start();//start 5 minute disable of ATO
  }
  else
  {
    ReefAngel.Relay.Off(Port1);
    ATOEnabled=false;
  }
  if (ReefAngel.Timer[1].IsTriggered())//after 30 minute disable, enable ATO
  {
    ATOPumping=true;
    ATOStart=now();
    SALduration=true;
  }


    ///// if skimmer cup full, turn off skimmer
    if (ReefAngel.HighATO.IsActive()) {
    bitClear(ReefAngel.Relay.RelayMaskOff,2);
    }
    else {
    bitSet(ReefAngel.Relay.RelayMaskOff,2);
    }
    
    ////// Place your custom code above here

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

void DrawCustomMain()
{
    int x,y;
    char text[10];
    // Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params,
    ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
    pingSerial();

    // Salinity
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,46, "SAL:" );
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,46, ReefAngel.Params.Salinity );
    pingSerial();

    // ORP
    ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,75,46, "ORP:" );
    ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,99,46, ReefAngel.Params.ORP );
    pingSerial();

    // Water Level
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,75,63, "WL:" );
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,99,63, ReefAngel.WaterLevel.GetLevel() );
    pingSerial();

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

    // Relay Expansion
    TempRelay = ReefAngel.Relay.RelayDataE[0];
    TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
    TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
    ReefAngel.LCD.DrawOutletBox( 12, 98, TempRelay );
    pingSerial();

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

void DrawCustomGraph()
{
}
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

Try this:

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

////// Place global variable code below here
unsigned long lastLowSal=now();//salinity >35.1 timer
boolean SALduration=true;//salinity >35.1 for 2 minutes flag
boolean ATOEnabled=false;//enable ATO function for 5 seconds
boolean ATOPumping=true;//disable ATO function for 5 minutes
unsigned long ATOStart=now();//ATO 5 sec run timer

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


void setup()
{
  // This must be the first line
  ReefAngel.Init(); //Initialize controller
  ReefAngel.SetTemperatureUnit( Celsius ); // set to Celsius Temperature

  // Ports toggled in Feeding Mode
  ReefAngel.FeedingModePorts = 0;
  ReefAngel.FeedingModePortsE[0] = 0;
  // Ports toggled in Water Change Mode
  ReefAngel.WaterChangePorts = Port1Bit | Port2Bit;
  ReefAngel.WaterChangePortsE[0] = 0;
  // Ports toggled when Lights On / Off menu entry selected
  ReefAngel.LightsOnPorts = 0;
  ReefAngel.LightsOnPortsE[0] = 0;
  // Ports turned off when Overheat temperature exceeded
  ReefAngel.OverheatShutoffPorts = Port6Bit;
  ReefAngel.OverheatShutoffPortsE[0] = 0;
  // Use T1 probe as temperature and overheat functions
  ReefAngel.TempProbe = T1_PROBE;
  ReefAngel.OverheatProbe = T1_PROBE;
  // Set the Overheat temperature setting
  InternalMemory.OverheatTemp_write( 260 );
  InternalMemory.SalTempComp_write( 780); // Change this to compensation temperature



  // Ports that are always on
  ReefAngel.Relay.On( Port4 );
  ReefAngel.Relay.On( Port5 );
  ReefAngel.Relay.On( Port8 );
  ReefAngel.Relay.On( Box1_Port1 );
  ReefAngel.Relay.On( Box1_Port2 );
  ReefAngel.Relay.On( Box1_Port4 );
  ReefAngel.Relay.On( Box1_Port6 );
  ReefAngel.Relay.On( Box1_Port7 );
  ReefAngel.Relay.On( Box1_Port8 );

  ////// Place additional initialization code below here

  ReefAngel.Timer[1].SetInterval(1800); // 30 mins before reactivation of ATO

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

void loop()
{
  ReefAngel.MHLights( Port3,0,30,23,30,5 );//skimmer off and on for dosing reef energy
  ReefAngel.StandardHeater( Port6,254,255 );
  ReefAngel.StandardFan( Port7,255,256 );
  ReefAngel.MHLights( Box1_Port5,23,30,23,31,0 );//air pump for mix reef energy prior to dosing
  ////// Place your custom code below here
  ReefAngel.WaterLevelATO(Port2,180,38,40);// Salinty top up to keep water level correct

  // Apply Salinity Compensation
  double SalCompensation;
  if (ReefAngel.TempSensor.unit)
    SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.00344123));
  else
    SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001925));//001333
  ReefAngel.Params.Salinity=round(SalCompensation);
  ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading


  ///// If salinity >35.1 for 120 sec set SALduration flag
  if (ReefAngel.Params.Salinity<351) lastLowSal=now();

  if (now()-lastLowSal>120) SALduration=false;

  if (SALduration && ATOPumping)//if salinity>35.1 for 2 minutes enable ATO

  {
    ATOStart=now();
  }
  else
  {
    ATOEnabled=true;
    ATOPumping=false;
  }

  if (now()-ATOStart<5)//ATO pump on time 5 seconds
  {
    if (ATOEnabled) ReefAngel.Relay.On(Port1);
    ReefAngel.Timer[1].Start();//start 5 minute disable of ATO
  }
  else
  {
    ReefAngel.Relay.Off(Port1);
    ATOEnabled=false;
  }
  if (ReefAngel.Timer[1].IsTriggered())//after 30 minute disable, enable ATO
  {
    ATOPumping=true;
    ATOStart=now();
    SALduration=true;
  }


  ///// if skimmer cup full, turn off skimmer
  if (ReefAngel.HighATO.IsActive()) {
    bitClear(ReefAngel.Relay.RelayMaskOff,2);
  }
  else {
    bitSet(ReefAngel.Relay.RelayMaskOff,2);
  }

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

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

void DrawCustomMain()
{
  int x,y;
  char text[10];
  // Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
  ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params,
  ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
  ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
  pingSerial();

  // Salinity
  ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,46, "SAL:" );
  ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,46, ReefAngel.Params.Salinity );
  pingSerial();

  // ORP
  ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,75,46, "ORP:" );
  ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,99,46, ReefAngel.Params.ORP );
  pingSerial();

  // Water Level
  ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,75,63, "WL:" );
  ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,99,63, ReefAngel.WaterLevel.GetLevel() );
  pingSerial();

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

  // Relay Expansion
  TempRelay = ReefAngel.Relay.RelayDataE[0];
  TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
  TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
  ReefAngel.LCD.DrawOutletBox( 12, 98, TempRelay );
  pingSerial();

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

void DrawCustomGraph()
{
}
To be honest, I never tested it in Celsius though. Sorry... :(
So, I would suggest starting your tests with Fahrenheit first.
Make sure you change the value in this line:

Code: Select all

  InternalMemory.SalTempComp_write( 780); // Change this to compensation temperature
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Hi Roberto,

Happy to try in celcius - just wanted to check with the code below:

// Apply Salinity Compensation
double SalCompensation;
if (ReefAngel.TempSensor.unit)
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.00344123));
else
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001925));//001333
ReefAngel.Params.Salinity=round(SalCompensation);
ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading

As I always have set to Celcius, couldnt I simplify a little as below?

// Apply Salinity Compensation
double SalCompensation;
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.022));

ReefAngel.Params.Salinity=round(SalCompensation);
ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

That's what I said. Please test it in F before you move to C.
Don't change any code at this time.
I think I made the constants correct. Well, I'm sure it it for F degrees.
The problem of this compensation is to adjust the constant.
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Hi Roberto,

Tried this code below and I am sure it is something simple, but when I run, the salinity display on the head unit is jumping all over the place - like it is been re written many times with differing values - any ideas?

I also tried the code exactly as you pasted above and changed temp unit to deg F, and still the same.
#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 <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

////// Place global variable code below here
unsigned long lastLowSal=now();//salinity >35.1 timer
boolean SALduration=true;//salinity >35.1 for 2 minutes flag
boolean ATOEnabled=false;//enable ATO function for 5 seconds
boolean ATOPumping=true;//disable ATO function for 5 minutes
unsigned long ATOStart=now();//ATO 5 sec run timer

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


void setup()
{
    // This must be the first line
    ReefAngel.Init(); //Initialize controller
    ReefAngel.SetTemperatureUnit( Celsius ); // set to Celsius Temperature

    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.FeedingModePortsE[0] = 0;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port2Bit;
    ReefAngel.WaterChangePortsE[0] = 0;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    ReefAngel.LightsOnPortsE[0] = 0;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port6Bit;
    ReefAngel.OverheatShutoffPortsE[0] = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 260 );
    InternalMemory.SalTempComp_write( 255); // Change this to compensation temperature


    // Ports that are always on
    ReefAngel.Relay.On( Port4 );
    ReefAngel.Relay.On( Port5 );
    ReefAngel.Relay.On( Port8 );
    ReefAngel.Relay.On( Box1_Port1 );
    ReefAngel.Relay.On( Box1_Port2 );
    ReefAngel.Relay.On( Box1_Port4 );
    ReefAngel.Relay.On( Box1_Port6 );
    ReefAngel.Relay.On( Box1_Port7 );
    ReefAngel.Relay.On( Box1_Port8 );
    
    ////// Place additional initialization code below here
    
    ReefAngel.Timer[1].SetInterval(1800); // 30 mins before reactivation of ATO
    
    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.MHLights( Port3,0,30,23,30,5 );//skimmer off and on for dosing reef energy
    ReefAngel.StandardHeater( Port6,252,255 );
    ReefAngel.StandardFan( Port7,255,258 );
    ReefAngel.MHLights( Box1_Port5,23,30,23,31,0 );//air pump for mix reef energy prior to dosing
    ////// Place your custom code below here
    ReefAngel.WaterLevelATO(Port2,180,38,40);// Salinty top up to keep water level correct
    
   // Apply Salinity Compensation
  double SalCompensation;
  if (ReefAngel.TempSensor.unit)
    SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
  else
    SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001925));
  ReefAngel.Params.Salinity=round(SalCompensation);
  ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading

    ///// If salinity >35.1 for 120 sec set SALduration flag
    if (ReefAngel.Params.Salinity<351) lastLowSal=now();
    
    if (now()-lastLowSal>120) SALduration=false;
  
    if (SALduration && ATOPumping)//if salinity>35.1 for 2 minutes enable ATO
  
    {ATOStart=now();
  }
  else
  {
    ATOEnabled=true;
    ATOPumping=false;
  }

  if (now()-ATOStart<5)//ATO pump on time 5 seconds
  {
    if (ATOEnabled) ReefAngel.Relay.On(Port1);
    ReefAngel.Timer[1].Start();//start 5 minute disable of ATO
  }
  else
  {
    ReefAngel.Relay.Off(Port1);
    ATOEnabled=false;
  }
  if (ReefAngel.Timer[1].IsTriggered())//after 30 minute disable, enable ATO
  {
    ATOPumping=true;
    ATOStart=now();
    SALduration=true;
  }


    ///// if skimmer cup full, turn off skimmer
    if (ReefAngel.HighATO.IsActive()) {
    bitClear(ReefAngel.Relay.RelayMaskOff,2);
    }
    else {
    bitSet(ReefAngel.Relay.RelayMaskOff,2);
    }
    
    ////// Place your custom code above here

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

void DrawCustomMain()
{
    int x,y;
    char text[10];
    // Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params,
    ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
    pingSerial();

    // Salinity
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,46, "SAL:" );
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,46, ReefAngel.Params.Salinity );
    pingSerial();

    // ORP
    ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,75,46, "ORP:" );
    ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,99,46, ReefAngel.Params.ORP );
    pingSerial();

    // Water Level
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,75,63, "WL:" );
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,99,63, ReefAngel.WaterLevel.GetLevel() );
    pingSerial();

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

    // Relay Expansion
    TempRelay = ReefAngel.Relay.RelayDataE[0];
    TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
    TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
    ReefAngel.LCD.DrawOutletBox( 12, 98, TempRelay );
    pingSerial();

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

void DrawCustomGraph()
{
}

dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Can anybody help please??
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

I'll try to look into this over the weekend.
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Thanks ronerto
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Thanks Roberto!
Piper
Posts: 296
Joined: Fri Jul 20, 2012 7:13 am
Location: Oakley, CA

Re: Salinity temp compensation?

Post by Piper »

You probably need to put a clear in right before you draw the salinity. Try this:

Code: Select all

    // Salinity
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,46, "SAL:" );
    ReefAngel.LCD.Clear(DefaultBGColor, 39, 46, 69, 54); // You will probably need to adjust the x,y on this a little
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,46, ReefAngel.Params.Salinity );
    pingSerial();
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Thanks, but that doesnt fix the problem.

I have played around a bit more and I think it has something to do with the map function - with this in, the reading really jumps all over the place.

With it removed, it seems to work a bit more stable, but still the salinity value jumps around a lot - it seems that the salinity value is way too sensitive to the temp, if that makes sense?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

Yeah, I don't think it will work as it is.
We'll need to come up with a different plot.
This constant was calculated and tested for another meter I have, but the resolution is different between the two.
If you want to contribute with the plot, it would be awesome!!
Here is your code with the raw adc readings in it.

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

////// Place global variable code below here
unsigned long lastLowSal=now();//salinity >35.1 timer
boolean SALduration=true;//salinity >35.1 for 2 minutes flag
boolean ATOEnabled=false;//enable ATO function for 5 seconds
boolean ATOPumping=true;//disable ATO function for 5 minutes
unsigned long ATOStart=now();//ATO 5 sec run timer

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


void setup()
{
    // This must be the first line
    ReefAngel.Init(); //Initialize controller
    ReefAngel.SetTemperatureUnit( Celsius ); // set to Celsius Temperature

    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.FeedingModePortsE[0] = 0;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port2Bit;
    ReefAngel.WaterChangePortsE[0] = 0;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    ReefAngel.LightsOnPortsE[0] = 0;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port6Bit;
    ReefAngel.OverheatShutoffPortsE[0] = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 260 );


    // Ports that are always on
    ReefAngel.Relay.On( Port4 );
    ReefAngel.Relay.On( Port5 );
    ReefAngel.Relay.On( Port8 );
    ReefAngel.Relay.On( Box1_Port1 );
    ReefAngel.Relay.On( Box1_Port2 );
    ReefAngel.Relay.On( Box1_Port4 );
    ReefAngel.Relay.On( Box1_Port6 );
    ReefAngel.Relay.On( Box1_Port7 );
    ReefAngel.Relay.On( Box1_Port8 );
    
    ////// Place additional initialization code below here
    
    ReefAngel.Timer[1].SetInterval(1800); // 30 mins before reactivation of ATO
    
    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.MHLights( Port3,0,30,23,30,5 );//skimmer off and on for dosing reef energy
    ReefAngel.StandardHeater( Port6,254,255 );
    ReefAngel.StandardFan( Port7,255,256 );
    ReefAngel.MHLights( Box1_Port5,23,30,23,31,0 );//air pump for mix reef energy prior to dosing
    ////// Place your custom code below here
    ReefAngel.WaterLevelATO(Port2,180,38,40);// Salinty top up to keep water level correct
    
    ///// If salinity >35.1 for 120 sec set SALduration flag
    if (ReefAngel.Params.Salinity<351) lastLowSal=now();
    
    if (now()-lastLowSal>120) SALduration=false;
  
    if (SALduration && ATOPumping)//if salinity>35.1 for 2 minutes enable ATO
  
    {ATOStart=now();
  }
  else
  {
    ATOEnabled=true;
    ATOPumping=false;
  }

  if (now()-ATOStart<5)//ATO pump on time 5 seconds
  {
    if (ATOEnabled) ReefAngel.Relay.On(Port1);
    ReefAngel.Timer[1].Start();//start 5 minute disable of ATO
  }
  else
  {
    ReefAngel.Relay.Off(Port1);
    ATOEnabled=false;
  }
  if (ReefAngel.Timer[1].IsTriggered())//after 30 minute disable, enable ATO
  {
    ATOPumping=true;
    ATOStart=now();
    SALduration=true;
  }


    ///// if skimmer cup full, turn off skimmer
    if (ReefAngel.HighATO.IsActive()) {
    bitClear(ReefAngel.Relay.RelayMaskOff,2);
    }
    else {
    bitSet(ReefAngel.Relay.RelayMaskOff,2);
    }
    
    ////// Place your custom code above here

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

void DrawCustomMain()
{
    int x,y;
    char text[10];
    // Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params,
    ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
    pingSerial();

    // Salinity
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,46, "SAL:" );
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,46, ReefAngel.Params.Salinity );
    pingSerial();
    
    // ADC
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,63, "ADC:" );
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,63, ReefAngel.Salinity.Read() );
    pingSerial();    

    // ORP
    ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,75,46, "ORP:" );
    ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,99,46, ReefAngel.Params.ORP );
    pingSerial();

    // Water Level
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,75,63, "WL:" );
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,99,63, ReefAngel.WaterLevel.GetLevel() );
    pingSerial();

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

    // Relay Expansion
    TempRelay = ReefAngel.Relay.RelayDataE[0];
    TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
    TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
    ReefAngel.LCD.DrawOutletBox( 12, 98, TempRelay );
    pingSerial();

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

void DrawCustomGraph()
{
}
What we need is to collect the adc reading at several different temperatures.
Preferably for every 1/2 C degree within the +/-5 degree range of your tank temperature where the salinity was calibrated.
So, fill up a cup of tank water and heat it up to +5C degrees and place the temp probe and salinity probe in it.
Start logging the data all the way until the temperature of the water is -5C degrees.
I'll try to plot the same for F degrees.
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Will do Roberto,
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Hi Roberto,

Here is the results of that - results pretty linear.

Temp Sal ADC
31.0 396 3343
30.5 393 3307
30.0 389 3271
29.5 385 3231
29.0 381 3195
28.5 377 3151
28.0 373 3111
27.5 369 3075
27.0 365 3035
26.5 362 3007
26.0 359 2975
25.5 356 2943
25.0 353 2915
24.5 350 2879
24.0 346 2843
23.5 342 2803
23.0 338 2759
22.5 333 2719
22.0 329 2675
21.5 325 2635
21.0 321 2595
20.5 316 2547
20.0 311 2499

here are the charts, if I can get them to load!!
temp vs  Sal ADC.tiff
temp vs Sal ADC.tiff (194.46 KiB) Viewed 5530 times
temp vs salinity.tiff
temp vs salinity.tiff (204.4 KiB) Viewed 5530 times
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

Awesome!!
Yes, it is supposed to be linear.
At what temperature did you calibrate?
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

rimai wrote:Awesome!!
Yes, it is supposed to be linear.
At what temperature did you calibrate?
Hi Roberto, yes I know it is supposed to be linear, I was just stating that my data points seem to be valid!!

Calibration temp was 25.5 deg C.

I have done the maths on this for you, and using the formula:

Actual salinity = Measured salinity/(1+((temp sal measured at - calibration temp)* factor)))

For the Salinity reading I come out with a factor of 0.0214

For the ADC values, I come out with a factor 0.0248

I have attached the data, and also a plot of the compensated salinity and ADC using the above formula.

So, I think this brings us back to square one, in terms of getting the temp compensation working??
data.tiff
data.tiff (68.03 KiB) Viewed 5515 times
comp salinity 1.jpg
comp salinity 1.jpg (36.54 KiB) Viewed 5515 times
comp ADC 1.tiff
comp ADC 1.tiff (538.59 KiB) Viewed 5515 times
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

Awesome!!!
Did you try it in your code?
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

no - not yet - will do that tomorrow.

Just been playing around with the constants to get a better fit and now have a really good fit for Celcius and Fahrenheit.

Basically, Celcius constant = 0.00211 Fahrenheit constant = 0.001175 - graphs below with these contants used so you can see the correction.
comp salinity 1.tiff
comp salinity 1.tiff (548.35 KiB) Viewed 5502 times
salinity vs F2.jpg
salinity vs F2.jpg (37.62 KiB) Viewed 5502 times
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

Awesome work, man!!! :)
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Hi Roberto,

I think there is still problems with the code and I think I know where.

// Apply Salinity Compensation
double SalCompensation;
if (ReefAngel.TempSensor.unit)
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
else
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001925));
ReefAngel.Params.Salinity=round(SalCompensation);
ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading

In the above code, the compensated salinity is been written to reef angel.params.salinity and each time it goes through the loop it will try to apply the compensation to the already compensated value etc.

So, if we changed the code to :

// Apply Salinity Compensation
double SalCompensation;
if (ReefAngel.TempSensor.unit)
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
else
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001925));
SalCompensation=round(SalCompensation);

Then we would just need to display the SalCompensation value instead (or even as well as) the salinity value.

So, how do I do that - something like this below, although somehow the SalCompensation needs to be defined and not sure how to do that?

// SalCompensated
ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,63, "SALC:" );
ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,63, SalCompensation.Read() );
pingSerial();
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

Code: Select all

ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,63, (int)SalCompensation );
SalCompensation is already a variable that you can display.
But, I think the best approach is to compensate the ADC value.
Try this:

Code: Select all

// Apply Salinity Compensation
 double SalCompensation;
 if (ReefAngel.TempSensor.unit)
 SalCompensation=ReefAngel.Salinity.Read()/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
 else
 SalCompensation=ReefAngel.Salinity.Read()//(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001925));
 ReefAngel.Params.Salinity=round(SalCompensation);
 ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

When compiling, the following line give an error - expected ";" before reef angel?
ReefAngel.Params.Salinity=round(SalCompensation);
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

Oh, I just copied what you had....
There was an extra slash in there, turning the rest of the code into comment.

Code: Select all

 double SalCompensation;
 if (ReefAngel.TempSensor.unit)
 SalCompensation=ReefAngel.Salinity.Read()/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
 else
 SalCompensation=ReefAngel.Salinity.Read()/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001925));
 ReefAngel.Params.Salinity=round(SalCompensation);
 ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Hi Roberto,

OK, what I would like to do, is run both uncompensated salinity and compensated, so I can check it works how I expect first, as use salinity for my ATO, and dont want to mess my tank up!!

I have the code as below, but when I compile it comes up with an error: SalCompensation was not declared in this scope
   ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,63, (int)SalCompensation );
#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 <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <ReefAngel.h>

////// Place global variable code below here
unsigned long lastLowSal=now();//salinity >35.1 timer
boolean SALduration=true;//salinity >35.1 for 2 minutes flag
boolean ATOEnabled=false;//enable ATO function for 5 seconds
boolean ATOPumping=true;//disable ATO function for 5 minutes
unsigned long ATOStart=now();//ATO 5 sec run timer

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


void setup()
{
    // This must be the first line
    ReefAngel.Init(); //Initialize controller
    ReefAngel.SetTemperatureUnit( Celsius ); // set to Celsius Temperature

    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = 0;
    ReefAngel.FeedingModePortsE[0] = 0;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port2Bit;
    ReefAngel.WaterChangePortsE[0] = 0;
    // Ports toggled when Lights On / Off menu entry selected
    ReefAngel.LightsOnPorts = 0;
    ReefAngel.LightsOnPortsE[0] = 0;
    // Ports turned off when Overheat temperature exceeded
    ReefAngel.OverheatShutoffPorts = Port6Bit;
    ReefAngel.OverheatShutoffPortsE[0] = 0;
    // Use T1 probe as temperature and overheat functions
    ReefAngel.TempProbe = T1_PROBE;
    ReefAngel.OverheatProbe = T1_PROBE;
    // Set the Overheat temperature setting
    InternalMemory.OverheatTemp_write( 260 );
    InternalMemory.SalTempComp_write( 255); // Change this to compensation temperature


    // Ports that are always on
    ReefAngel.Relay.On( Port4 );
    ReefAngel.Relay.On( Port5 );
    ReefAngel.Relay.On( Port8 );
    ReefAngel.Relay.On( Box1_Port1 );
    ReefAngel.Relay.On( Box1_Port2 );
    ReefAngel.Relay.On( Box1_Port4 );
    ReefAngel.Relay.On( Box1_Port6 );
    ReefAngel.Relay.On( Box1_Port7 );
    ReefAngel.Relay.On( Box1_Port8 );
    
    ////// Place additional initialization code below here
    
    ReefAngel.Timer[1].SetInterval(1800); // 30 mins before reactivation of ATO
    
    ////// Place additional initialization code above here
}

void loop()
{
    ReefAngel.MHLights( Port3,0,30,23,30,5 );//skimmer off and on for dosing reef energy
    ReefAngel.StandardHeater( Port6,252,255 );
    ReefAngel.StandardFan( Port7,255,258 );
    ReefAngel.MHLights( Box1_Port5,23,30,23,31,0 );//air pump for mix reef energy prior to dosing
    ////// Place your custom code below here
    ReefAngel.WaterLevelATO(Port2,180,38,40);// Salinty top up to keep water level correct
    
   // Apply Salinity Compensation
    double SalCompensation;
    if (ReefAngel.TempSensor.unit)
    SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.00215));
    else
    SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001925));
    SalCompensation=round(SalCompensation);
    
    
    ///// If salinity >35.1 for 120 sec set SALduration flag
    if (ReefAngel.Params.Salinity<351) lastLowSal=now();
    
    if (now()-lastLowSal>120) SALduration=false;
  
    if (SALduration && ATOPumping)//if salinity>35.1 for 2 minutes enable ATO
  
    {ATOStart=now();
  }
  else
  {
    ATOEnabled=true;
    ATOPumping=false;
  }

  if (now()-ATOStart<5)//ATO pump on time 5 seconds
  {
    if (ATOEnabled) ReefAngel.Relay.On(Port1);
    ReefAngel.Timer[1].Start();//start 5 minute disable of ATO
  }
  else
  {
    ReefAngel.Relay.Off(Port1);
    ATOEnabled=false;
  }
  if (ReefAngel.Timer[1].IsTriggered())//after 30 minute disable, enable ATO
  {
    ATOPumping=true;
    ATOStart=now();
    SALduration=true;
  }


    ///// if skimmer cup full, turn off skimmer
    if (ReefAngel.HighATO.IsActive()) {
    bitClear(ReefAngel.Relay.RelayMaskOff,2);
    }
    else {
    bitSet(ReefAngel.Relay.RelayMaskOff,2);
    }
    
    ////// Place your custom code above here

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

void DrawCustomMain()
{
    int x,y;
    char text[10];
    // Parameters
#if defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params,
    ReefAngel.PWM.GetDaylightValue(), ReefAngel.PWM.GetActinicValue() );
#else // defined DisplayLEDPWM && ! defined RemoveAllLights
    ReefAngel.LCD.DrawMonitor( 15, 10, ReefAngel.Params );
#endif // defined DisplayLEDPWM && ! defined RemoveAllLights
    pingSerial();

    // Salinity
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,46, "SAL:" );
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,46, ReefAngel.Params.Salinity );
    pingSerial();
    
   //comp salinity
   ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,63, (int)SalCompensation );


    // ORP
    ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,75,46, "ORP:" );
    ReefAngel.LCD.DrawText( COLOR_PALEVIOLETRED,DefaultBGColor,99,46, ReefAngel.Params.ORP );
    pingSerial();

    // Water Level
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,75,63, "WL:" );
    ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,99,63, ReefAngel.WaterLevel.GetLevel() );
    pingSerial();

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

    // Relay Expansion
    TempRelay = ReefAngel.Relay.RelayDataE[0];
    TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
    TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
    ReefAngel.LCD.DrawOutletBox( 12, 98, TempRelay );
    pingSerial();

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

void DrawCustomGraph()
{
}

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

Re: Salinity temp compensation?

Post by lnevo »

You have SalCompenstation being declared within the loop function. If you want to draw it in the DrawCustomMain() function, you'll have to declare it with your globals.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

lnevo wrote:You have SalCompenstation being declared within the loop function. If you want to draw it in the DrawCustomMain() function, you'll have to declare it with your globals.
As Roberto said, the SalCompensation is already defined in a library somewhere though? I think reefangel.cpp?

If it is defined there, I shouldn't have to define it again in a global should I?
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Salinity temp compensation?

Post by rimai »

No, it's declared in your loop()

Code: Select all

    double SalCompensation;
Just move it up top to globals.
Roberto.
dazza1304
Posts: 154
Joined: Sat Aug 04, 2012 4:22 am

Re: Salinity temp compensation?

Post by dazza1304 »

Sorry for being so thick- now works!! BTW, what does double do - as in double SalCompensation?

Will chart it tomorrow and see how it works!!!
Post Reply