pH calibration for freshwater aquariums?

Related to the development libraries, released by Curt Binder

Posts: 21
Joined: Tue Apr 17, 2012 2:47 pm
Location: Colorado
PostPosted: Sun May 13, 2012 7:59 am
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...

Posts: 12275
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Sun May 13, 2012 8:22 am
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:
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];
   }
}

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:
Code: Select all
    unsigned int iCal[2] = {4,7};

This is just label for the calibration screen. The original was:
Code: Select all
    unsigned int iCal[2] = {7,10};

Then, on line 661 of ReefAngel.cpp, change this:
Code: Select all
   Params.PH=map(Params.PH, PHMin, PHMax, 700, 1000); // apply the calibration to the sensor reading

To this:
Code: Select all
   Params.PH=map(Params.PH, PHMin, PHMax, 400, 700); // apply the calibration to the sensor reading

Try that and let me know how it goes.
Roberto.

Posts: 21
Joined: Tue Apr 17, 2012 2:47 pm
Location: Colorado
PostPosted: Sun May 13, 2012 8:36 am
Awesome, thanks Roberto! I'll go pick up a pH-4 standard this afternoon and let you know how it goes.

Posts: 80
Joined: Thu Mar 08, 2012 5:11 pm
Location: Oakland, California
PostPosted: Tue Oct 01, 2013 8:39 pm
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.
Gabe's Grad Reef
Image
User avatar
Posts: 19
Joined: Wed Mar 05, 2014 10:53 pm
Location: Greece
PostPosted: Sat Mar 08, 2014 11:39 am
Hi Guys,

Can someone help. How can i edit SetupCalibratePH() function library to change PH calibration?
Greenaquarium
Image

Posts: 12275
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Sat Mar 08, 2014 11:55 am
You don't need to modify it.
Add this to your setup() section
Code: Select all
ReefAngel.UseFlexiblePhCalibration();

Then you can go into calibration and change which values you would like to use.
Roberto.
User avatar
Posts: 19
Joined: Wed Mar 05, 2014 10:53 pm
Location: Greece
PostPosted: Sat Mar 08, 2014 1:19 pm
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)
Greenaquarium
Image
User avatar
Posts: 19
Joined: Wed Mar 05, 2014 10:53 pm
Location: Greece
PostPosted: Sat Mar 08, 2014 1:38 pm
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();
}
Greenaquarium
Image

Posts: 12275
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Sat Mar 08, 2014 2:24 pm
If it is too big, you may want to think about upgrading to RA+
Roberto.
User avatar
Posts: 19
Joined: Wed Mar 05, 2014 10:53 pm
Location: Greece
PostPosted: Sat Mar 08, 2014 2:36 pm
This i will do, RA+, till then, can i get out: #include <Humidity.h> I do not use it.
Greenaquarium
Image

Return to Development Libraries

Who is online

Users browsing this forum: No registered users and 2 guests

cron