ArduinoGeneral

Dissolved Oxygen Probe DFRobot Code

userHead Account cancelled 2018-01-25 08:53:18 3905 Views0 Replies
Hello, I am currently working on a project that requires me to measure the dissolved oxygen concentration in water. I was using the code supplied on the DFRobot page however I am having difficulty figuring out how to determine the SaturationDOVoltage. The code supplied on the website gives a default voltage but I am unsure as to how that was obtained. I am not using EEPROM. This is the code I am referring to on the website. Any help would be appreciated!

/***************************************************
DFRobot Gravity: Analog Dissolved Oxygen Sensor / Meter Kit for Arduino
<https://www.dfrobot.com/wiki/index.php/ ... KU:SEN0237>

***************************************************
This example reads the concentration of dissolved oxygen in water.
The saturated oxygen calibration is available by UART commends with NL & CR:
calibration ---- enter the calibration mode
satcal ---- calibrate the parameters with saturated oxygen value
exit ---- exit the calibration mode

Created 2017-5-22
By Jason <[email protected]@dfrobot.com>

GNU Lesser General Public License.
See <http://www.gnu.org/licenses/> for details.
All above must be included in any redistribution
****************************************************/

/***********Notice and Trouble shooting***************
1. This code is tested on Arduino Uno and Leonardo with Arduino IDE 1.0.5 r2 and 1.8.2.
2. More details, please click this link: <https://www.dfrobot.com/wiki/index.php/ ... KU:SEN0237>
****************************************************/

#include <avr/pgmspace.h>
#include <EEPROM.h>

#define DoSensorPin A1 //dissolved oxygen sensor analog output pin to arduino mainboard
#define VREF 5000 //for arduino uno, the ADC reference is the AVCC, that is 5000mV(TYP)
float doValue; //current dissolved oxygen value, unit; mg/L
float temperature = 25; //default temperature is 25^C, you can use a temperature sensor to read it

#define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp);}
#define EEPROM_read(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp=EEPROM.read(address+i);}

#define ReceivedBufferLength 20
char receivedBuffer[ReceivedBufferLength+1]; // store the serial command
byte receivedBufferIndex = 0;

#define SCOUNT 30 // sum of sample point
int analogBuffer[SCOUNT]; //store the analog value in the array, readed from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex = 0,copyIndex = 0;

#define SaturationDoVoltageAddress 12 //the address of the Saturation Oxygen voltage stored in the EEPROM
#define SaturationDoTemperatureAddress 16 //the address of the Saturation Oxygen temperature stored in the EEPROM
float SaturationDoVoltage,SaturationDoTemperature;
float averageVoltage;

const float SaturationValueTab[41] PROGMEM = { //saturation dissolved oxygen concentrations at various temperatures
14.46, 14.22, 13.82, 13.44, 13.09,
12.74, 12.42, 12.11, 11.81, 11.53,
11.26, 11.01, 10.77, 10.53, 10.30,
10.08, 9.86, 9.66, 9.46, 9.27,
9.08, 8.90, 8.73, 8.57, 8.41,
8.25, 8.11, 7.96, 7.82, 7.69,
7.56, 7.43, 7.30, 7.18, 7.07,
6.95, 6.84, 6.73, 6.63, 6.53,
6.41,
};

void setup()
{
Serial.begin(115200);
pinMode(DoSensorPin,INPUT);
readDoCharacteristicValues(); //read Characteristic Values calibrated from the EEPROM
}

void loop()
{
static unsigned long analogSampleTimepoint = millis();
if(millis()-analogSampleTimepoint > 30U) //every 30 milliseconds,read the analog value from the ADC
{
analogSampleTimepoint = millis();
analogBuffer[analogBufferIndex] = analogRead(DoSensorPin); //read the analog value and store into the buffer
analogBufferIndex++;
if(analogBufferIndex == SCOUNT)
analogBufferIndex = 0;
}

static unsigned long tempSampleTimepoint = millis();
if(millis()-tempSampleTimepoint > 500U) // every 500 milliseconds, read the temperature
{
tempSampleTimepoint = millis();
//temperature = readTemperature(); // add your temperature codes here to read the temperature, unit:^C
}

static unsigned long printTimepoint = millis();
if(millis()-printTimepoint > 1000U)
{
printTimepoint = millis();
for(copyIndex=0;copyIndex<SCOUNT;copyIndex++)
{
analogBufferTemp[copyIndex]= analogBuffer[copyIndex];
}
averageVoltage = getMedianNum(analogBufferTemp,SCOUNT) * (float)VREF / 1024.0; // read the value more stable by the median filtering algorithm
Serial.print(F("Temperature:"));
Serial.print(temperature,1);
Serial.print(F("^C"));
doValue = pgm_read_float_near( &SaturationValueTab[0] + (int)(SaturationDoTemperature+0.5) ) * averageVoltage / SaturationDoVoltage; //calculate the do value, doValue = Voltage / SaturationDoVoltage * SaturationDoValue(with temperature compensation)
Serial.print(F(", DO Value:"));
Serial.print(doValue,2);
Serial.println(F("mg/L"));
}

if(serialDataAvailable() > 0)
{
byte modeIndex = uartParse(); //parse the uart command received
doCalibration(modeIndex); // If the correct calibration command is received, the calibration function should be called.
}

}

boolean serialDataAvailable(void)
{
char receivedChar;
static unsigned long receivedTimeOut = millis();
while ( Serial.available() > 0 )
{
if (millis() - receivedTimeOut > 500U)
{
receivedBufferIndex = 0;
memset(receivedBuffer,0,(ReceivedBufferLength+1));
}
receivedTimeOut = millis();
receivedChar = Serial.read();
if (receivedChar == '\n' || receivedBufferIndex == ReceivedBufferLength)
{
receivedBufferIndex = 0;
strupr(receivedBuffer);
return true;
}else{
receivedBuffer[receivedBufferIndex] = receivedChar;
receivedBufferIndex++;
}
}
return false;
}

byte uartParse()
{
byte modeIndex = 0;
if(strstr(receivedBuffer, "CALIBRATION") != NULL)
modeIndex = 1;
else if(strstr(receivedBuffer, "EXIT") != NULL)
modeIndex = 3;
else if(strstr(receivedBuffer, "SATCAL") != NULL)
modeIndex = 2;
return modeIndex;
}

void doCalibration(byte mode)
{
char *receivedBufferPtr;
static boolean doCalibrationFinishFlag = 0,enterCalibrationFlag = 0;
float voltageValueStore;
switch(mode)
{
case 0:
if(enterCalibrationFlag)
Serial.println(F("Command Error"));
break;

case 1:
enterCalibrationFlag = 1;
doCalibrationFinishFlag = 0;
Serial.println();
Serial.println(F(">>>Enter Calibration Mode<<<"));
Serial.println(F(">>>Please put the probe into the saturation oxygen water! <<<"));
Serial.println();
break;

case 2:
if(enterCalibrationFlag)
{
Serial.println();
Serial.println(F(">>>Saturation Calibration Finish!<<<"));
Serial.println();
EEPROM_write(SaturationDoVoltageAddress, averageVoltage);
EEPROM_write(SaturationDoTemperatureAddress, temperature);
SaturationDoVoltage = averageVoltage;
SaturationDoTemperature = temperature;
doCalibrationFinishFlag = 1;
}
break;

case 3:
if(enterCalibrationFlag)
{
Serial.println();
if(doCalibrationFinishFlag)
Serial.print(F(">>>Calibration Successful"));
else
Serial.print(F(">>>Calibration Failed"));
Serial.println(F(",Exit Calibration Mode<<<"));
Serial.println();
doCalibrationFinishFlag = 0;
enterCalibrationFlag = 0;
}
break;
}
}

int getMedianNum(int bArray[], int iFilterLen)
{
int bTab[iFilterLen];
for (byte i = 0; i<iFilterLen; i++)
{
bTab = bArray;
}
int i, j, bTemp;
for (j = 0; j < iFilterLen - 1; j++)
{
for (i = 0; i < iFilterLen - j - 1; i++)
{
if (bTab > bTab[i + 1])
{
bTemp = bTab;
bTab = bTab[i + 1];
bTab[i + 1] = bTemp;
}
}
}
if ((iFilterLen & 1) > 0)
bTemp = bTab[(iFilterLen - 1) / 2];
else
bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
return bTemp;
}

void readDoCharacteristicValues(void)
{
EEPROM_read(SaturationDoVoltageAddress, SaturationDoVoltage);
EEPROM_read(SaturationDoTemperatureAddress, SaturationDoTemperature);
if(EEPROM.read(SaturationDoVoltageAddress)==0xFF && EEPROM.read(SaturationDoVoltageAddress+1)==0xFF && EEPROM.read(SaturationDoVoltageAddress+2)==0xFF && EEPROM.read(SaturationDoVoltageAddress+3)==0xFF)
{
SaturationDoVoltage = 1127.6; //default voltage:1127.6mv
EEPROM_write(SaturationDoVoltageAddress, SaturationDoVoltage);
}
if(EEPROM.read(SaturationDoTemperatureAddress)==0xFF && EEPROM.read(SaturationDoTemperatureAddress+1)==0xFF && EEPROM.read(SaturationDoTemperatureAddress+2)==0xFF && EEPROM.read(SaturationDoTemperatureAddress+3)==0xFF)
{
SaturationDoTemperature = 25.0; //default temperature is 25^C
EEPROM_write(SaturationDoTemperatureAddress, SaturationDoTemperature);
}
}