Salinity temp compensation?
Re: Salinity temp compensation?
Size of the variable.
byte is 8 bit variable
int is 16 bit and goes all the way up to double, which is 64bit variable.
byte is 8 bit variable
int is 16 bit and goes all the way up to double, which is 64bit variable.
Roberto.
Re: Salinity temp compensation?
Ok, that makes sense. So why use double when the resolution even from the adc is only 12 bit, wouldn't integer be better to use?
Not picking just trying to understand the code better so I can be self sufficient - ish!
Not picking just trying to understand the code better so I can be self sufficient - ish!
Re: Salinity temp compensation?
Anything that is not a whole number needs to be either float or double.
0.001925 - this is definitely not a whole number.
That's why we use 751 for temperature instead of 75.1.
751 fits in an integer, but 75.1 requires float.
0.001925 - this is definitely not a whole number.
That's why we use 751 for temperature instead of 75.1.
751 fits in an integer, but 75.1 requires float.
Roberto.
Re: Salinity temp compensation?
Cool- thanks, makes sense now!
Re: Salinity temp compensation?
Well, it works fine!!
I have some slightly corrected values for the compensation constants -
Celcius = 0.0022
Fahrenheit = 0.001165
I have attached a chart below showing results from uncompensated salinity reading and compensated readings over about 10 deg C.
I have changed my salinity ATO to use temp compensated salinity and expect to it work fine!!
I have also attached my code if anyone is interested!!
I have some slightly corrected values for the compensation constants -
Celcius = 0.0022
Fahrenheit = 0.001165
I have attached a chart below showing results from uncompensated salinity reading and compensated readings over about 10 deg C.
I have changed my salinity ATO to use temp compensated salinity and expect to it work fine!!
I have also attached my code if anyone is interested!!
#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
double SalCompensation;
////// 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
if (ReefAngel.TempSensor.unit)
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
else
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.001165));
SalCompensation=round(SalCompensation);
///// If salinity >35.1 for 120 sec set SALduration flag
if (SalCompensation<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();
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()
{
}
Re: Salinity temp compensation?
Hi Roberto, I have a quick question for you.rimai wrote:SalCompensation is already a variable that you can display.Code: Select all
ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,63, (int)SalCompensation );
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
Currently I have coded my controller to do the temp compensation for salinity, and currently display uncompensated salinity, compensated as per the above code, and compensated with the above code without the mapping.
Basically, it appears the mapping function makes no difference to the end value - is this what you would expect, as I am not sure quite how the map function works?
cheers..
Re: Salinity temp compensation?
Is the SalCompensation already giving you ppt values?
If it is, there is something wrong with the calculation then.
SalCompensation was supposed to the compensated raw adc values, which would be converted to ppt with the map function. map function is simply a linear interpolation of raw adc values to ppt values.
If it is, there is something wrong with the calculation then.
SalCompensation was supposed to the compensated raw adc values, which would be converted to ppt with the map function. map function is simply a linear interpolation of raw adc values to ppt values.
Roberto.
Re: Salinity temp compensation?
No the salcompensation will display an ADC value as expected.
However, if I display salinity after this ReefAngel.Params.Salinity=round(SalCompensation);
and also after this ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350);
Then, basically the values are the same - i.e . the mapping function does not appear to add anything?
However, if I display salinity after this ReefAngel.Params.Salinity=round(SalCompensation);
and also after this ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350);
Then, basically the values are the same - i.e . the mapping function does not appear to add anything?
Re: Salinity temp compensation?
Oh, no.
You can't assign ReefAngel.Params.Salinity=something.
The next loop, the value is overwritten by the libraries own calculation and it is not compensated values.
However, you can display round(SalCompensation); and use this to convert the new compensated value:
SalCompensation=map(SalCompensation, 0, ReefAngel.SalMax, 60, 350);
This will convert it to ppt compensated values.
You can't assign ReefAngel.Params.Salinity=something.
The next loop, the value is overwritten by the libraries own calculation and it is not compensated values.
However, you can display round(SalCompensation); and use this to convert the new compensated value:
SalCompensation=map(SalCompensation, 0, ReefAngel.SalMax, 60, 350);
This will convert it to ppt compensated values.
Roberto.
Re: Salinity temp compensation?
Below is the code I am using. Basically displaying salcompensation and salinity test (which uses the map function) and the map function does not seem to add anything i.e produces the same result as the displaying 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
double SalCompensation;
double Salinitytest;
////// 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
//salinity temp compensation
if (ReefAngel.TempSensor.unit)
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
else
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.001165));
SalCompensation=round(SalCompensation);
// Apply Salinity Compensation 2
if (ReefAngel.TempSensor.unit)
Salinitytest=ReefAngel.Salinity.Read()/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
else
Salinitytest=ReefAngel.Salinity.Read()/(1+((ReefAngel.Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001925));
Salinitytest=round(Salinitytest);
Salinitytest=map(Salinitytest, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading
///// If salinity >35.1 for 120 sec set SALduration flag
if (SalCompensation<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();
//temp comp salinity
ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,63, "S/T:" );
ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,63, (int)SalCompensation );
//map of adc temp comp salinity
ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,15,54, "ADC:" );
ReefAngel.LCD.DrawText( COLOR_BLACK,DefaultBGColor,39,54, (int)Salinitytest );
// 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()
{
}
Re: Salinity temp compensation?
What are you seeing on SalCompensation and Salinitytest in the screen?
Roberto.
Re: Salinity temp compensation?
Temp Compensated salinity values, which are virtually identical.
Re: Salinity temp compensation?
That's not supposed to be ppt values....
It's supposed to be compensated adc values. Your formula may be converting it to ppt values and disregarding the calibration. The map function is what applies the calibration.
It's supposed to be compensated adc values. Your formula may be converting it to ppt values and disregarding the calibration. The map function is what applies the calibration.
Roberto.
Re: Salinity temp compensation?
Ok, think I figured this out - I am actually using the reefangel.params.salinity to compensate, so of course will be in ppt.
And if I changed to reefangel.salinty.read, it would of course be the ADC value, then i would need the map function to convert to ppt - is this correct?
I guess I am confused as to where the salinity calibration (not temp compensation) happens - if I read the ADC value using reefangel.salinity.read, then this returns a raw uncalibrated ADC value? If I then convert to ppt using the map function, how does the salinty calibration happen?
And if I changed to reefangel.salinty.read, it would of course be the ADC value, then i would need the map function to convert to ppt - is this correct?
I guess I am confused as to where the salinity calibration (not temp compensation) happens - if I read the ADC value using reefangel.salinity.read, then this returns a raw uncalibrated ADC value? If I then convert to ppt using the map function, how does the salinty calibration happen?
Re: Salinity temp compensation?
Correct. You should use the adc value to compensate.dazza1304 wrote:Ok, think I figured this out - I am actually using the reefangel.params.salinity to compensate, so of course will be in ppt.
Yes.dazza1304 wrote: And if I changed to reefangel.salinty.read, it would of course be the ADC value, then i would need the map function to convert to ppt - is this correct?
The calibration happens when you apply the map function. It does both at the same time. It will calibrate and convert to ppt.dazza1304 wrote: I guess I am confused as to where the salinity calibration (not temp compensation) happens - if I read the ADC value using reefangel.salinity.read, then this returns a raw uncalibrated ADC value? If I then convert to ppt using the map function, how does the salinty calibration happen?
Roberto.
Re: Salinity temp compensation?
OK, something is not happening as I would expect. When I use the code below, ReefAngel.Params.Salinty is definitely temperature compensated, but for some reason, it seems to knock my salinity ATO off. For example, my salinity is definitely over 351, but still the ATO wont trigger.
// Apply Salinity temp Compensation & salinity calibration
double SalCompensation;
if (ReefAngel.TempSensor.unit)
SalCompensation=ReefAngel.Salinity.Read()/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
else
SalCompensation=ReefAngel.Salinity.Read()/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.001165));
ReefAngel.Params.Salinity=round(SalCompensation);
ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading//salinity temp compensation
// For displaying salinity without temp compensation
Salinitytest=ReefAngel.Salinity.Read();
Salinitytest=round(Salinitytest);
Salinitytest=map(Salinitytest, 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;
However, if I change the code around a bit and use the value SalCompensation for triggering the ATO as below, it works fine.
// Apply Salinity temp Compensation & salinity calibration
double SalCompensation;
if (ReefAngel.TempSensor.unit)
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
else
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.001165));
SalCompensation=round(SalCompensation);
// For displaying salinity without temp compensation
Salinitytest=SalCompensation;
///// If salinity >35.1 for 120 sec set SALduration flag
if (SalCompensation<351) lastLowSal=now();
if (now()-lastLowSal>120) SALduration=false;
What I don't undertand, is why the top bit of code doesnt work? I think it may have something to do with the map function, which I think should run only once, rather than be in the loop?
Any help would be appreciated!!
I can make do with things as they are, but as the portal only charts the ReefAngel.Params.Salinity parameter, I cannot get a graph of what my temp compensated salinity is which is the one I really want!!
// Apply Salinity temp Compensation & salinity calibration
double SalCompensation;
if (ReefAngel.TempSensor.unit)
SalCompensation=ReefAngel.Salinity.Read()/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
else
SalCompensation=ReefAngel.Salinity.Read()/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.001165));
ReefAngel.Params.Salinity=round(SalCompensation);
ReefAngel.Params.Salinity=map(ReefAngel.Params.Salinity, 0, ReefAngel.SalMax, 60, 350); // apply the calibration to the sensor reading//salinity temp compensation
// For displaying salinity without temp compensation
Salinitytest=ReefAngel.Salinity.Read();
Salinitytest=round(Salinitytest);
Salinitytest=map(Salinitytest, 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;
However, if I change the code around a bit and use the value SalCompensation for triggering the ATO as below, it works fine.
// Apply Salinity temp Compensation & salinity calibration
double SalCompensation;
if (ReefAngel.TempSensor.unit)
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.0022));
else
SalCompensation=ReefAngel.Params.Salinity/(1+((ReefAngel.Params.Temp[T3_PROBE]-InternalMemory.SalTempComp_read())*0.001165));
SalCompensation=round(SalCompensation);
// For displaying salinity without temp compensation
Salinitytest=SalCompensation;
///// If salinity >35.1 for 120 sec set SALduration flag
if (SalCompensation<351) lastLowSal=now();
if (now()-lastLowSal>120) SALduration=false;
What I don't undertand, is why the top bit of code doesnt work? I think it may have something to do with the map function, which I think should run only once, rather than be in the loop?
Any help would be appreciated!!
I can make do with things as they are, but as the portal only charts the ReefAngel.Params.Salinity parameter, I cannot get a graph of what my temp compensated salinity is which is the one I really want!!
Re: Salinity temp compensation?
You won't. Not yet.
We need to merge this into the libraries.
The real ReefAngel.Params.Salinity is still uncompensated coming from the libraries.
We need to merge this into the libraries.
The real ReefAngel.Params.Salinity is still uncompensated coming from the libraries.
Roberto.
Re: Salinity temp compensation?
So is there 2 ReefAngel.Params.Salinty??
When I ran the first bit of code the salinity display was def temp compensated - I proved this by holding the T3 probe, which caused the salinity value to change as you would expect when the salinity probe was in a constant salinity solution.
When I ran the first bit of code the salinity display was def temp compensated - I proved this by holding the T3 probe, which caused the salinity value to change as you would expect when the salinity probe was in a constant salinity solution.
Re: Salinity temp compensation?
It's the sequence of events that is tripping you.
The salinity ReefAngel.Params.Salinity value changes when the ShowInterface() function is called.
When you change the value on the DrawCustomMain() function, it is only temporarily. It gets overwritten by the libraries in the next loop.
So, you can change and display it within the DrawCustomMain(), but won't affect the controller, because it reads a new value again and overwrites whatever you placed in the variable.
The salinity ReefAngel.Params.Salinity value changes when the ShowInterface() function is called.
When you change the value on the DrawCustomMain() function, it is only temporarily. It gets overwritten by the libraries in the next loop.
So, you can change and display it within the DrawCustomMain(), but won't affect the controller, because it reads a new value again and overwrites whatever you placed in the variable.
Roberto.
Re: Salinity temp compensation?
Got it - I think - so what library do I need to modify to get this to work and what do I need to do to it, as I would like to see what my salinity graph looks like with temp compensation!! I realise if i change the library, it will be overwritten next update!!
Re: Salinity temp compensation?
yes, it will get overwritten in the next update.
You need to change the ReefAngel.cpp in the mean time.
It starts on line 738:
https://github.com/reefangel/Libraries/ ... l.cpp#L738
Apply the compensation before the map() function is called.
Pretty sure you know what to do by looking at the code there.
You need to change the ReefAngel.cpp in the mean time.
It starts on line 738:
https://github.com/reefangel/Libraries/ ... l.cpp#L738
Apply the compensation before the map() function is called.
Pretty sure you know what to do by looking at the code there.
Roberto.
Re: Salinity temp compensation?
So the only difference between the old temperature compensation code and this one is that the compensation is applied to the ADC values instead of the ppt values?
Re: Salinity temp compensation?
Actually, there is a need to offset the temperature in which the calibration happened, or the compensated value would be wrong.
Roberto.
Re: Salinity temp compensation?
I think its also better to define the constant Alpha in memory to make it easier to tune using wifi if needed cause I think it might differ a bit from a person to the other depending on the probe, salinity and Temperature. So adding it to memory would make it a lot easier than having to change the code and load several times until we get it right
Re: Salinity temp compensation?
Good suggestion. I've added a ticket.
https://github.com/reefangel/Libraries/issues/79
https://github.com/reefangel/Libraries/issues/79
Roberto.
Re: Salinity temp compensation?
I added the salinity compensation constant to the code in library below but manually changing the value of the constant in memory does not change anything in the value of salinity displayed on the screen. I m using Celsius temperature and i have set the salinity constant Alpha= 220. I changed it to several other values but no change
I have also noticed something that i think is weird and I dont know if it is related, if I just write any junk in reefangel.cpp and save the file then try to verify my code the compiler does not find errors
Code: Select all
#if defined SALINITYEXPANSION
if (Salinity.TemperatureCompensation)
{
double SalCompensation;
if (TempSensor.unit)
SalCompensation=Salinity.Read()/(1+((Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*Alpha_read()/100000));
else
SalCompensation=Salinity.Read()/(1+((Params.Temp[T1_PROBE]-InternalMemory.SalTempComp_read())*0.001165));
Params.Salinity=round(SalCompensation);
Params.Salinity=map(Params.Salinity, 0, SalMax, 60, 390); // apply the calibration to the sensor reading//salinity temp compensation
}
Re: Salinity temp compensation?
Make sure you are changing it in the correct place.
There are two places.
The top one is deprecated and will be removed.
There are two places.
The top one is deprecated and will be removed.
Roberto.