pH calibration for freshwater aquariums?
pH calibration for freshwater aquariums?
Hi-- I'm using a ReefAngel to control a planted freshwater aquarium, including using the RA pH probe to control my CO2 injection system. In contrast to most reef setups, with a freshwater aquarium you are typically shooting for water that is slightly acidic, say in the 6.5-7.0 range.
In the pH calibration process on the RA, the standards used are pH=7 and pH=10, appropriate for the alkaline pH values that I gather most saltwater setups are trying to target. I assume that the reef angel is doing some kind of functional (linear?) interpolation to calculate pH between these two values. However, for pH's below 7.0 the pH calculation must be an extrapolation of the functional fit between 7 and 10, rather than the interpolation that pH's between 7 and 10 would allow. Typically, extrapolations are more error-prone than interpolations. So a couple questions:
- How does reef angel calculate pH based on the calibration values? is it a simple linear relation? I'm having a hard time finding that part of the calculation in the libraries. If its linear and the relevant slope in the 7-10 range is about the same for pH<7, then there shouldn't be a problem using it for pH measurements in a freshwater aquarium.
- Otherwise, it might make sense for those of us trying to use the RA for freshwater setups to calibrate the probe for the acidic end of the pH spectrum, using say, pH=4 and pH=7 standards for the calibration. I've got only a vague sense of what needs to be done in the SetupCalibratePH functions in the libraries, and no idea what changes need to be made in the part of the code that does the actual pH calculation (nor where that part of the code even exists). Is it possible to easily modify the ReefAngel to use a 4-7calibration standard, rather than a 7-10 calibration?
I'm not much of a programmer, but would be happy to fiddle around with this problem if someone can point me at the relevant sections of code. Thanks much for any help or insight...
In the pH calibration process on the RA, the standards used are pH=7 and pH=10, appropriate for the alkaline pH values that I gather most saltwater setups are trying to target. I assume that the reef angel is doing some kind of functional (linear?) interpolation to calculate pH between these two values. However, for pH's below 7.0 the pH calculation must be an extrapolation of the functional fit between 7 and 10, rather than the interpolation that pH's between 7 and 10 would allow. Typically, extrapolations are more error-prone than interpolations. So a couple questions:
- How does reef angel calculate pH based on the calibration values? is it a simple linear relation? I'm having a hard time finding that part of the calculation in the libraries. If its linear and the relevant slope in the 7-10 range is about the same for pH<7, then there shouldn't be a problem using it for pH measurements in a freshwater aquarium.
- Otherwise, it might make sense for those of us trying to use the RA for freshwater setups to calibrate the probe for the acidic end of the pH spectrum, using say, pH=4 and pH=7 standards for the calibration. I've got only a vague sense of what needs to be done in the SetupCalibratePH functions in the libraries, and no idea what changes need to be made in the part of the code that does the actual pH calculation (nor where that part of the code even exists). Is it possible to easily modify the ReefAngel to use a 4-7calibration standard, rather than a 7-10 calibration?
I'm not much of a programmer, but would be happy to fiddle around with this problem if someone can point me at the relevant sections of code. Thanks much for any help or insight...
Re: pH calibration for freshwater aquariums?
Yes, it is just simple interpolation and a pH probe has a fairly linear response, so even though it is extrapolating, the error shouldn't be concerning.
But, if you are really trying to change the libraries, here is what needs to be done:
Change your SetupCalibratePH() function to:
The above SetupCalibratePH() function is the adapted version of new function that will be released on the next libraries update. I just changed a couple days ago to have better resolution and noise cancellation.
So, what I changed for your case was:
This is just label for the calibration screen. The original was:
Then, on line 661 of ReefAngel.cpp, change this:
To this:
Try that and let me know how it goes.
But, if you are really trying to change the libraries, here is what needs to be done:
Change your SetupCalibratePH() function to:
Code: Select all
void ReefAngelClass::SetupCalibratePH()
{
bool bOKSel = false;
bool bSave = false;
bool bDone = false;
bool bDrawButtons = true;
unsigned int iO[2] = {0,0};
unsigned int iCal[2] = {4,7};
byte offset = 65;
// draw labels
ClearScreen(DefaultBGColor);
for (int b=0;b<2;b++)
{
if (b==1 && !bSave) break;
bOKSel=false;
bSave=false;
bDone = false;
bDrawButtons = true;
LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, MENU_START_ROW, "Calibrate pH");
LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, MENU_START_ROW*5, "pH");
LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL + 18, MENU_START_ROW*5, (int)iCal[b]);
do
{
#if defined WDT || defined WDT_FORCE
wdt_reset();
#endif // defined WDT || defined WDT_FORCE
iO[b]=0;
for (int a=0;a<30;a++)
{
iO[b] += analogRead(PHPin);
}
iO[b]/=30;
LCD.DrawCalibrate(iO[b], MENU_START_COL + offset, MENU_START_ROW*5);
if ( bDrawButtons )
{
if ( bOKSel )
{
LCD.DrawOK(true);
LCD.DrawCancel(false);
}
else
{
LCD.DrawOK(false);
LCD.DrawCancel(true);
}
bDrawButtons = false;
}
if ( Joystick.IsUp() || Joystick.IsDown() || Joystick.IsRight() || Joystick.IsLeft() )
{
// toggle the selection
bOKSel = !bOKSel;
bDrawButtons = true;
}
if ( Joystick.IsButtonPressed() )
{
bDone = true;
if ( bOKSel )
{
bSave = true;
}
}
} while ( ! bDone );
}
ClearScreen(DefaultBGColor);
if ( bSave )
{
// save PHMin & PHMax to memory
InternalMemory.PHMin_write(iO[0]);
PHMin = iO[0];
InternalMemory.PHMax_write(iO[1]);
PHMax = iO[1];
}
}
So, what I changed for your case was:
Code: Select all
unsigned int iCal[2] = {4,7};
Code: Select all
unsigned int iCal[2] = {7,10};
Code: Select all
Params.PH=map(Params.PH, PHMin, PHMax, 700, 1000); // apply the calibration to the sensor reading
Code: Select all
Params.PH=map(Params.PH, PHMin, PHMax, 400, 700); // apply the calibration to the sensor reading
Roberto.
Re: pH calibration for freshwater aquariums?
Awesome, thanks Roberto! I'll go pick up a pH-4 standard this afternoon and let you know how it goes.
-
- Posts: 89
- Joined: Thu Mar 08, 2012 5:11 pm
- Location: Redwood City, California
Re: pH calibration for freshwater aquariums?
How did this work out? I am about to start dosing my freshwater planted tank with CO2 as well and wanted a more accurate pH reading. I will give this a try but I would like to know how it worked out for billybob.
Re: pH calibration for freshwater aquariums?
Hi Guys,
Can someone help. How can i edit SetupCalibratePH() function library to change PH calibration?
Can someone help. How can i edit SetupCalibratePH() function library to change PH calibration?
Greenaquarium
Re: pH calibration for freshwater aquariums?
You don't need to modify it.
Add this to your setup() section
Then you can go into calibration and change which values you would like to use.
Add this to your setup() section
Code: Select all
ReefAngel.UseFlexiblePhCalibration();
Roberto.
Re: pH calibration for freshwater aquariums?
Hi Roberto,
I add it but there is something wrong with code, I have only few futures and Binary sketch size is 33,912 bytes, what can I do to check if there is any problem?
see:
The following features were automatically added:
Watchdog Timer
Version Menu
The following features were detected:
Dimming Signal
Wifi Attachment
Calibrate pH Menu with Choices
Simple Menu
Binary sketch size: 33,912 bytes (of a 32,256 byte maximum)
processing.app.debug.RunnerException: Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.
at processing.app.Sketch.size(Sketch.java:1844)
at processing.app.Sketch.build(Sketch.java:1775)
at processing.app.Sketch.build(Sketch.java:1750)
at processing.app.Editor$DefaultRunHandler.run(Editor.java:1867)
at java.lang.Thread.run(Thread.java:619)
I add it but there is something wrong with code, I have only few futures and Binary sketch size is 33,912 bytes, what can I do to check if there is any problem?
see:
The following features were automatically added:
Watchdog Timer
Version Menu
The following features were detected:
Dimming Signal
Wifi Attachment
Calibrate pH Menu with Choices
Simple Menu
Binary sketch size: 33,912 bytes (of a 32,256 byte maximum)
processing.app.debug.RunnerException: Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.
at processing.app.Sketch.size(Sketch.java:1844)
at processing.app.Sketch.build(Sketch.java:1775)
at processing.app.Sketch.build(Sketch.java:1750)
at processing.app.Editor$DefaultRunHandler.run(Editor.java:1867)
at java.lang.Thread.run(Thread.java:619)
Greenaquarium
Re: pH calibration for freshwater aquariums?
Roberto,
Here is setup code, what can I get out?
Thank you
#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 <Humidity.h>
#include <DCPump.h>
#include <ReefAngel.h>
////// Place global variable code below here
////// Place global variable code above here
void setup()
{
InternalMemory.LCDID_write(0);
// 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;
// Ports toggled in Water Change Mode
ReefAngel.WaterChangePorts = 0;
// Ports toggled when Lights On / Off menu entry selected
ReefAngel.LightsOnPorts = 0;
// Ports turned off when Overheat temperature exceeded
ReefAngel.OverheatShutoffPorts = 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( 330 );
ReefAngel.UseFlexiblePhCalibration();
// Ports that are always on
ReefAngel.Relay.On( Port6 );
////// Place additional initialization code below here
////// Place additional initialization code above here
}
void loop()
{
ReefAngel.StandardLights( Port1,11,0,18,0 );
ReefAngel.StandardFan( Port2,290,300 );
ReefAngel.CO2Control( Port3,675,695 );
ReefAngel.StandardLights( Port4,20,0,9,0 );
ReefAngel.StandardLights( Port5,12,0,14,0 );
ReefAngel.PWM.SetActinic( PWMParabola(20,0,23,59,0,100,0) );
////// Place your custom code below here
////// Place your custom code above here
// This should always be the last line
ReefAngel.Portal( "semik" );
ReefAngel.ShowInterface();
}
Here is setup code, what can I get out?
Thank you
#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 <Humidity.h>
#include <DCPump.h>
#include <ReefAngel.h>
////// Place global variable code below here
////// Place global variable code above here
void setup()
{
InternalMemory.LCDID_write(0);
// 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;
// Ports toggled in Water Change Mode
ReefAngel.WaterChangePorts = 0;
// Ports toggled when Lights On / Off menu entry selected
ReefAngel.LightsOnPorts = 0;
// Ports turned off when Overheat temperature exceeded
ReefAngel.OverheatShutoffPorts = 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( 330 );
ReefAngel.UseFlexiblePhCalibration();
// Ports that are always on
ReefAngel.Relay.On( Port6 );
////// Place additional initialization code below here
////// Place additional initialization code above here
}
void loop()
{
ReefAngel.StandardLights( Port1,11,0,18,0 );
ReefAngel.StandardFan( Port2,290,300 );
ReefAngel.CO2Control( Port3,675,695 );
ReefAngel.StandardLights( Port4,20,0,9,0 );
ReefAngel.StandardLights( Port5,12,0,14,0 );
ReefAngel.PWM.SetActinic( PWMParabola(20,0,23,59,0,100,0) );
////// Place your custom code below here
////// Place your custom code above here
// This should always be the last line
ReefAngel.Portal( "semik" );
ReefAngel.ShowInterface();
}
Greenaquarium
Re: pH calibration for freshwater aquariums?
If it is too big, you may want to think about upgrading to RA+
Roberto.
Re: pH calibration for freshwater aquariums?
This i will do, RA+, till then, can i get out: #include <Humidity.h> I do not use it.
Greenaquarium