Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions ArduinoUnoDo/WaterMonitor/CalibrationService.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#include "CalibrationService.h"
#include <EEPROM.h>

CalibrationService::CalibrationService(GravitySensorHub* sensorHub, SdService* sdService) :
_sensorHub(sensorHub),
_sdService(sdService),
_isCalibrating(false),
_currentCalibrationType(CALIBRATION_PH_3POINT),
_calibrationStartTime(0) {
}

void CalibrationService::setup() {
loadCalibrationData();
applyCalibration();
}

void CalibrationService::loop() {
if (!_isCalibrating) return;

unsigned long currentTime = millis();
if (currentTime - _calibrationStartTime < 10000) return; // Wait 10 seconds for stability

switch (_currentCalibrationType) {
case CALIBRATION_PH_3POINT:
calibratePh3Point();
break;
case CALIBRATION_PH_2POINT:
calibratePh2Point();
break;
case CALIBRATION_EC_1POINT:
calibrateEc1Point();
break;
case CALIBRATION_DO_2POINT:
calibrateDo2Point();
break;
case CALIBRATION_ORP_1POINT:
calibrateOrp1Point();
break;
}

_isCalibrating = false;
saveCalibrationData();
Serial.println(F("Calibration completed!"));
}

void CalibrationService::startCalibration(CalibrationType type) {
_currentCalibrationType = type;
_isCalibrating = true;
_calibrationStartTime = millis();
printCalibrationInstructions();
}

void CalibrationService::stopCalibration() {
_isCalibrating = false;
}

bool CalibrationService::isCalibrating() {
return _isCalibrating;
}

void CalibrationService::setPhCalibration(float ph7, float ph4, float ph10) {
_calibrationData.ph7Calibration = ph7;
_calibrationData.ph4Calibration = ph4;
_calibrationData.ph10Calibration = ph10;
_calibrationData.isCalibrated[0] = true;
applyCalibration();
}

void CalibrationService::setEcCalibration(float ecValue) {
_calibrationData.ecCalibration = ecValue;
_calibrationData.isCalibrated[3] = true;
applyCalibration();
}

void CalibrationService::setDoCalibration(float zeroValue, float spanValue) {
_calibrationData.doZeroCalibration = zeroValue;
_calibrationData.doSpanCalibration = spanValue;
_calibrationData.isCalibrated[2] = true;
applyCalibration();
}

void CalibrationService::setOrpCalibration(float orpValue) {
_calibrationData.orpCalibration = orpValue;
_calibrationData.isCalibrated[4] = true;
applyCalibration();
}

CalibrationData CalibrationService::getCalibrationData() {
return _calibrationData;
}

void CalibrationService::saveCalibrationData() {
EEPROM.put(0, _calibrationData);
Serial.println(F("Calibration data saved to EEPROM"));
}

void CalibrationService::loadCalibrationData() {
EEPROM.get(0, _calibrationData);
Serial.println(F("Calibration data loaded from EEPROM"));
}

void CalibrationService::printCalibrationInstructions() {
switch (_currentCalibrationType) {
case CALIBRATION_PH_3POINT:
Serial.println(F("PH 3-Point Calibration:"));
Serial.println(F("1. Place probe in pH 7 buffer"));
Serial.println(F("2. Wait for stable reading (10s)"));
Serial.println(F("3. Repeat for pH 4 and pH 10 buffers"));
break;
case CALIBRATION_EC_1POINT:
Serial.println(F("EC 1-Point Calibration:"));
Serial.println(F("1. Place probe in 1413 uS/cm solution"));
Serial.println(F("2. Wait for stable reading (10s)"));
break;
case CALIBRATION_DO_2POINT:
Serial.println(F("DO 2-Point Calibration:"));
Serial.println(F("1. Place probe in zero oxygen solution"));
Serial.println(F("2. Wait for stable reading (10s)"));
Serial.println(F("3. Place probe in air-saturated water"));
Serial.println(F("4. Wait for stable reading (10s)"));
break;
case CALIBRATION_ORP_1POINT:
Serial.println(F("ORP 1-Point Calibration:"));
Serial.println(F("1. Place probe in 225 mV solution"));
Serial.println(F("2. Wait for stable reading (10s)"));
break;
}
}

void CalibrationService::calibratePh3Point() {
Serial.println(F("Performing pH 3-point calibration..."));
// Implementation depends on sensor library integration
float ph7Reading = _sensorHub->getValueBySensorNumber(0);
float offset = 7.0 - ph7Reading;
setPhCalibration(offset, offset, offset);
}

void CalibrationService::calibratePh2Point() {
Serial.println(F("Performing pH 2-point calibration..."));
// Similar to 3-point but with 2 buffers
}

void CalibrationService::calibrateEc1Point() {
Serial.println(F("Performing EC 1-point calibration..."));
float ecReading = _sensorHub->getValueBySensorNumber(3);
float factor = 1413.0 / ecReading;
setEcCalibration(factor);
}

void CalibrationService::calibrateDo2Point() {
Serial.println(F("Performing DO 2-point calibration..."));
float zeroReading = _sensorHub->getValueBySensorNumber(2);
float spanReading = _sensorHub->getValueBySensorNumber(2);
setDoCalibration(zeroReading, spanReading);
}

void CalibrationService::calibrateOrp1Point() {
Serial.println(F("Performing ORP 1-point calibration..."));
float orpReading = _sensorHub->getValueBySensorNumber(4);
float offset = 225.0 - orpReading;
setOrpCalibration(offset);
}

void CalibrationService::applyCalibration() {
Serial.println(F("Applying calibration data..."));
// Apply calibration factors to sensors
}

void CalibrationService::resetCalibration() {
for (int i = 0; i < 5; i++) {
_calibrationData.isCalibrated[i] = false;
}
saveCalibrationData();
Serial.println(F("Calibration data reset"));
}
63 changes: 63 additions & 0 deletions ArduinoUnoDo/WaterMonitor/CalibrationService.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#pragma once

#include "GravitySensorHub.h"
#include "SdService.h"

enum CalibrationType {
CALIBRATION_PH_3POINT,
CALIBRATION_PH_2POINT,
CALIBRATION_EC_1POINT,
CALIBRATION_DO_2POINT,
CALIBRATION_ORP_1POINT
};

struct CalibrationData {
float ph7Calibration = 0.0;
float ph4Calibration = 0.0;
float ph10Calibration = 0.0;
float ecCalibration = 0.0;
float doZeroCalibration = 0.0;
float doSpanCalibration = 0.0;
float orpCalibration = 0.0;
bool isCalibrated[5] = {false, false, false, false, false};
};

class CalibrationService {
public:
CalibrationService(GravitySensorHub* sensorHub, SdService* sdService);

void setup();
void loop();

void startCalibration(CalibrationType type);
void stopCalibration();
bool isCalibrating();

void setPhCalibration(float ph7, float ph4, float ph10);
void setEcCalibration(float ecValue);
void setDoCalibration(float zeroValue, float spanValue);
void setOrpCalibration(float orpValue);

CalibrationData getCalibrationData();
void saveCalibrationData();
void loadCalibrationData();

void printCalibrationInstructions();

private:
GravitySensorHub* _sensorHub;
SdService* _sdService;
CalibrationData _calibrationData;
bool _isCalibrating;
CalibrationType _currentCalibrationType;
unsigned long _calibrationStartTime;

void calibratePh3Point();
void calibratePh2Point();
void calibrateEc1Point();
void calibrateDo2Point();
void calibrateOrp1Point();

void applyCalibration();
void resetCalibration();
};
102 changes: 102 additions & 0 deletions ArduinoUnoDo/WaterMonitor/GravityDfr0553Adc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "GravityDfr0553Adc.h"

GravityDfr0553Adc::GravityDfr0553Adc() :
i2cAddress(0x48),
fullScaleMilliVolts(6144.0f),
available(false)
{
}

void GravityDfr0553Adc::setup(uint8_t address, float vccMillivolts)
{
i2cAddress = address;
fullScaleMilliVolts = vccMillivolts;

Wire.begin();
Wire.beginTransmission(i2cAddress);
available = (Wire.endTransmission() == 0);
}

bool GravityDfr0553Adc::isAvailable() const
{
return available;
}

float GravityDfr0553Adc::readMilliVolts(uint8_t channel, float fallbackMilliVolts)
{
int16_t rawValue = 0;
if (!readRawSingleEnded(channel, rawValue))
{
return fallbackMilliVolts;
}

if (rawValue < 0)
{
rawValue = 0;
}

return (rawValue * fullScaleMilliVolts) / 32768.0f;
}

bool GravityDfr0553Adc::readRawSingleEnded(uint8_t channel, int16_t &rawValue)
{
if (!available || channel > 3)
{
return false;
}

const uint16_t mux = 0x04 + channel;
const uint16_t config =
0x8000 | // Start single conversion.
(mux << 12) | // AIN0..AIN3 to GND.
0x0000 | // +/-6.144V full-scale range for 0..VCC sensors.
0x0100 | // Single-shot mode.
0x0080 | // 128 samples per second.
0x0003; // Disable comparator.

if (!writeRegister(ConfigRegister, config))
{
available = false;
return false;
}

delay(9);

uint16_t rawRegister = 0;
if (!readRegister(ConversionRegister, rawRegister))
{
available = false;
return false;
}

rawValue = static_cast<int16_t>(rawRegister);
return true;
}

bool GravityDfr0553Adc::writeRegister(uint8_t reg, uint16_t value)
{
Wire.beginTransmission(i2cAddress);
Wire.write(reg);
Wire.write(static_cast<uint8_t>(value >> 8));
Wire.write(static_cast<uint8_t>(value & 0xFF));
return Wire.endTransmission() == 0;
}

bool GravityDfr0553Adc::readRegister(uint8_t reg, uint16_t &value)
{
Wire.beginTransmission(i2cAddress);
Wire.write(reg);
if (Wire.endTransmission() != 0)
{
return false;
}

if (Wire.requestFrom(i2cAddress, static_cast<uint8_t>(2)) != 2)
{
return false;
}

value = static_cast<uint16_t>(Wire.read()) << 8;
value |= static_cast<uint16_t>(Wire.read());
return true;
}
26 changes: 26 additions & 0 deletions ArduinoUnoDo/WaterMonitor/GravityDfr0553Adc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <Arduino.h>
#include <Wire.h>

class GravityDfr0553Adc
{
public:
GravityDfr0553Adc();

void setup(uint8_t address, float vccMillivolts);
bool isAvailable() const;
float readMilliVolts(uint8_t channel, float fallbackMilliVolts);

private:
static const uint8_t ConversionRegister = 0x00;
static const uint8_t ConfigRegister = 0x01;

uint8_t i2cAddress;
float fullScaleMilliVolts;
bool available;

bool writeRegister(uint8_t reg, uint16_t value);
bool readRegister(uint8_t reg, uint16_t &value);
bool readRawSingleEnded(uint8_t channel, int16_t &rawValue);
};
Loading
Loading