first publish without code changes
Dependencies: AD7124
Revision 0:d6b384fb3c16, committed 2016-10-24
- Comitter:
- adisuciu
- Date:
- Mon Oct 24 15:27:31 2016 +0000
- Child:
- 1:712abd52fa0a
- Commit message:
- Initial revision
Changed in this revision
| CN0398.cpp | Show annotated file Show diff for this revision Revisions of this file |
| CN0398.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CN0398.cpp Mon Oct 24 15:27:31 2016 +0000
@@ -0,0 +1,379 @@
+#include "CN0398.h"
+#include "AD7124.h"
+#include <mbed.h>
+
+#define RREF (5000.0)
+#define TEMP_GAIN (16.0)
+#define PT100_RESISTANCE_TO_TEMP(x) ((x-100.0)/(0.385))
+#define _2_23 (1<<23)
+
+#define CALIBRATION_NR_OF_SAMPLES (5)
+
+extern Serial pc;
+
+#define ms_delay (1)
+
+CN0398::CN0398(PinName cs, PinName adp7118enable) : ad7124(cs), ADP7118Enable(adp7118enable), offset_voltage(default_offset_voltage)
+{
+ calibration_ph[0][0] = default_calibration_ph[0][0];
+ calibration_ph[0][1] = default_calibration_ph[0][1];
+ calibration_ph[1][0] = default_calibration_ph[1][0];
+ calibration_ph[1][1] = default_calibration_ph[1][1];
+ solution0 = 0;
+ solution1 = 0;
+}
+
+void CN0398::calibrate_ph_pt0(float temperature)
+{
+ float volt = 0;
+ for(int i = 0; i < CALIBRATION_NR_OF_SAMPLES; i++) {
+ set_digital_output(P2, true);
+ int32_t data = read_channel(0);
+ set_digital_output(P2, false);
+ volt += data_to_voltage_bipolar(data >> 8, 1, 3.3);
+ }
+ volt = volt / CALIBRATION_NR_OF_SAMPLES;
+ if(temperature < 0) {
+ calibration_ph[0][0] = ph_temp_lut[solution0][0];
+ } else {
+ for(uint8_t i = 1; i < NUMBER_OF_TEMPERATURE_ENTRIES; i++) {
+ if(temperature > ph_temperatures[i - 1] && temperature <= ph_temperatures[i]) {
+ calibration_ph[0][0] = ph_temp_lut[solution0][i];
+ break;
+ }
+ }
+ }
+ calibration_ph[0][1] = volt;
+ pc.printf("Calibration solution 1 ph: %f with sensor voltage of %f\r\n", calibration_ph[0][0], volt);
+}
+void CN0398::calibrate_ph_pt1(float temperature)
+{
+ float volt = 0;
+ for(int i = 0; i < CALIBRATION_NR_OF_SAMPLES; i++) {
+ set_digital_output(P2, true);
+ int32_t data = read_channel(0);
+ set_digital_output(P2, false);
+ volt += data_to_voltage_bipolar(data >> 8, 1, 3.3);
+ }
+
+ volt = volt / CALIBRATION_NR_OF_SAMPLES;
+ if(temperature < 0) {
+ calibration_ph[1][0] = ph_temp_lut[solution1][0];
+ } else {
+ for(uint8_t i = 1; i < NUMBER_OF_TEMPERATURE_ENTRIES; i++) {
+ if(temperature > ph_temperatures[i - 1] && temperature <= ph_temperatures[i]) {
+ calibration_ph[1][0] = ph_temp_lut[solution1][i];
+ break;
+ }
+ }
+ }
+ calibration_ph[1][1] = volt;
+ pc.printf("Calibration solution 2 ph: %f with sensor voltage of %f\r\n", calibration_ph[1][0], volt);
+}
+
+void CN0398::calibrate_ph_offset()
+{
+ float volt = 0;
+ for(int i = 0; i < CALIBRATION_NR_OF_SAMPLES; i++) {
+ set_digital_output(P2, true);
+ int32_t data = read_channel(0);
+ set_digital_output(P2, false);
+ volt += data_to_voltage_bipolar(data >> 8, 1, 3.3);
+ }
+ offset_voltage = volt / CALIBRATION_NR_OF_SAMPLES;
+ pc.printf("Offset voltage is: %f \r\n", volt);
+}
+
+
+float CN0398::read_rtd()
+{
+ float temperature = 25.0;
+#ifdef TEMPERATURE_SENSOR_PRESENT
+ int32_t data = read_channel(2);
+ data = (data >> 8) & 0x00ffffff;
+ float resistance = ((static_cast<float>(data) - _2_23) * RREF) / (TEMP_GAIN * _2_23);
+#ifdef USE_LINEAR_TEMP_EQ
+ temperature = PT100_RESISTANCE_TO_TEMP(resistance);
+#else
+
+#define A (3.9083*pow(10,-3))
+#define B (-5.775*pow(10,-7))
+ /*if(resistance < 100.0)
+ temperature = -242.02 + 2.228 * resistance + (2.5859 * pow(10, -3)) * pow(resistance, 2) - (48260 * pow(10, -6)) * pow(resistance, 3) - (2.8183 * pow(10, -3)) * pow(resistance, 4) + (1.5243 * pow(10, -10)) * pow(resistance, 5);
+ else*/
+ temperature = ((-A + sqrt(double(pow(A, 2) - 4 * B * (1 - resistance / 100.0))) ) / (2 * B));
+#endif
+#endif
+ return temperature;
+
+}
+
+int32_t CN0398::read_channel(uint8_t ch)
+{
+ int32_t data;
+ enable_channel(ch);
+ start_single_conversion();
+
+ if (ad7124.WaitForConvReady(10000) == -3) {
+ pc.printf("TIMEOUT");
+ return -1;
+ }
+ ad7124.ReadData(&data);
+ disable_channel(ch);
+ return data;
+
+}
+float CN0398::read_ph(float temperature)
+{
+ float ph = 0;
+#ifdef PH_SENSOR_PRESENT
+ set_digital_output(P2, true);
+ int32_t data = read_channel(0);
+ set_digital_output(P2, false);
+ float volt = data_to_voltage_bipolar(data >> 8, 1, 3.3);
+#ifdef DEBUG_MODE
+ pc.printf("pH sensor voltage - %f\n", volt);
+#endif
+
+ if(use_nernst) {
+ ph = -((volt - ZERO_POINT_TOLERANCE) / ((2.303 * AVOGADRO * (temperature + KELVIN_OFFSET)) / FARADAY_CONSTANT) ) + PH_ISO;
+ } else {
+ float m = (calibration_ph[1][0] - calibration_ph[0][0]) / (calibration_ph[1][1] - calibration_ph[0][1]);
+ ph = m * (volt - calibration_ph[1][1] + offset_voltage) + calibration_ph[1][0];
+ }
+#endif
+ return ph;
+}
+float CN0398::read_moist()
+{
+ float moisture = 0;
+#ifdef MOISTURE_SENSOR_PRESENT
+ ADP7118Enable = true;
+ set_digital_output(P3, true);
+ wait_ms(SENSOR_SETTLING_TIME);
+ int32_t data = read_channel(1);
+ ADP7118Enable = false;
+ set_digital_output(P3, false);
+
+ data = (data >> 8) & 0x00ffffff;
+ float volt = data_to_voltage(data, 1, 3.3);
+#ifdef USE_MANUFACTURER_MOISTURE_EQ
+ if(volt <= 1.1) {
+ moisture = 10 * volt - 1;
+ } else if(volt > 1.1 && volt <= 1.3) {
+ moisture = 25 * volt - 17.5;
+ } else if(volt > 1.3 && volt <= 1.82) {
+ moisture = 48.08 * volt - 47.5;
+ } else if(volt > 1.82) {
+ moisture = 26.32 * volt - 7.89;
+ }
+#else
+ moisture = -1.18467 + 21.5371 * volt - 110.996 * (pow(volt, 2)) + 397.025 * (pow(volt, 3)) - 666.986 * (pow(volt, 4)) + 569.236 * (pow(volt, 5)) - 246.005 * (pow(volt, 6)) + 49.4867 * (pow(volt, 7)) - 3.37077 * (pow(volt, 8));
+#endif
+ if(moisture > 100) moisture = 100;
+ if(moisture < 0 ) moisture = 0;
+#endif
+ return moisture;
+}
+
+float CN0398::data_to_voltage_bipolar(uint32_t data, uint8_t gain, float VREF)
+{
+ data = data & 0xFFFFFF;
+ return ((data / static_cast<float>(0xFFFFFF / 2)) - 1) * (VREF / gain);
+}
+
+float CN0398::data_to_voltage(uint32_t data, uint8_t gain, float VREF)
+{
+ data = data & 0xFFFFFF;
+ return (data / static_cast<float>(0xFFFFFF)) * (VREF / gain);
+}
+
+void CN0398::enable_channel(int channel)
+{
+ AD7124::ad7124_registers regNr = static_cast<AD7124::ad7124_registers> (AD7124::AD7124_Channel_0 + channel); //Select ADC_Control register
+ uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
+ setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+ wait_ms(ms_delay);
+}
+
+void CN0398::disable_channel(int channel)
+{
+ AD7124::ad7124_registers regNr = static_cast<AD7124::ad7124_registers> (AD7124::AD7124_Channel_0 + channel); //Select ADC_Control register
+ uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
+ setValue &= (~(uint32_t) AD7124_CH_MAP_REG_CH_ENABLE); //Enable channel0
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+ wait_ms(ms_delay);
+}
+
+/*
+void CN0398::enable_current_source0(int current_source_channel)
+{
+ AD7124::ad7124_registers regNr = AD7124::AD7124_IOCon1; //Select ADC_Control register
+ uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
+ setValue &= ~(AD7124_IO_CTRL1_REG_IOUT_CH0(0xF));
+ setValue |= AD7124_IO_CTRL1_REG_IOUT_CH0(current_source_channel);// set IOUT0 current to 500uA
+ setValue &= 0xFFFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+ wait_ms(ms_delay);
+}
+
+void CN0398::enable_current_source1(int current_source_channel)
+{
+ AD7124::ad7124_registers regNr = AD7124::AD7124_IOCon1; //Select ADC_Control register
+ uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
+ setValue &= ~(AD7124_IO_CTRL1_REG_IOUT_CH1(0xF));
+ setValue |= AD7124_IO_CTRL1_REG_IOUT_CH1(current_source_channel);// set IOUT0 current to 500uA
+ setValue &= 0xFFFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+ wait_ms(ms_delay);
+}*/
+
+void CN0398::set_digital_output(ad_digital_output_t p, bool state)
+{
+ AD7124::ad7124_registers regNr = AD7124::AD7124_IOCon1; //Select ADC_Control register
+ uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
+ if(state)
+ setValue |= ((AD7124_8_IO_CTRL1_REG_GPIO_DAT1) << p);
+ else
+ setValue &= (~((AD7124_8_IO_CTRL1_REG_GPIO_DAT1) << p));
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+ wait_ms(ms_delay);
+}
+
+
+void CN0398::start_single_conversion()
+{
+ AD7124::ad7124_registers regNr = AD7124::AD7124_ADC_Control; //Select ADC_Control register
+ uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
+ setValue &= 0xFFC3;
+ setValue |= 0x04; //single conversion;
+ setValue |= AD7124_ADC_CTRL_REG_DATA_STATUS;
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC*/
+ wait_ms(ms_delay * 10);
+}
+
+void CN0398::reset()
+{
+ ad7124.frequency(500000);
+ ad7124.Reset();
+ pc.printf("Reseted AD7124\r\n");
+ wait_ms(1000);
+}
+
+void CN0398::setup()
+{
+ ad7124.Setup();
+}
+
+void CN0398::init()
+{
+ uint32_t setValue;
+ enum AD7124::ad7124_registers regNr;
+
+ /* Set Config_0 0x19*/
+ regNr = AD7124::AD7124_Config_0; //Select Config_0 register - pH
+ setValue = 0;//ad7124.ReadDeviceRegister(regNr);
+ setValue |= AD7124_CFG_REG_BIPOLAR; //Select bipolar operation
+ setValue |= AD7124_CFG_REG_BURNOUT(0); //Burnout current source off
+ setValue |= AD7124_CFG_REG_REF_BUFP;
+ setValue |= AD7124_CFG_REG_REF_BUFM;
+ setValue |= AD7124_CFG_REG_AIN_BUFP; //Buffer AIN5
+ setValue |= AD7124_CFG_REG_AINN_BUFM; //Buffer AIN4
+ setValue |= AD7124_CFG_REG_REF_SEL(0); //REFIN1(+)/REFIN1(−).
+ setValue |= AD7124_CFG_REG_PGA(0);
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+
+ /* Set Config_0 0x1A*/
+ regNr = AD7124::AD7124_Config_1; //Select Config_1 register - Moisture
+ setValue = 0;//ad7124.ReadDeviceRegister(regNr);
+ setValue &= ~AD7124_CFG_REG_BIPOLAR; //Select bipolar operation
+ setValue |= AD7124_CFG_REG_BURNOUT(0); //Burnout current source off
+ setValue |= AD7124_CFG_REG_REF_BUFP;
+ setValue |= AD7124_CFG_REG_REF_BUFM;
+ setValue |= AD7124_CFG_REG_AIN_BUFP; //Buffer AIN5
+ setValue |= AD7124_CFG_REG_AINN_BUFM; //Buffer AIN4*/
+ setValue |= AD7124_CFG_REG_REF_SEL(0); // REFIN1(+)/REFIN1(−).
+ setValue |= AD7124_CFG_REG_PGA(0);
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+
+ /* Set Config_0 0x1B*/
+ regNr = AD7124::AD7124_Config_2; //Select Config_2 register - temp
+ setValue = 0;//ad7124.ReadDeviceRegister(regNr);
+ setValue |= AD7124_CFG_REG_BIPOLAR; //Select bipolar operation
+ setValue |= AD7124_CFG_REG_BURNOUT(0); //Burnout current source off
+ setValue |= AD7124_CFG_REG_REF_BUFP;
+ setValue |= AD7124_CFG_REG_REF_BUFM;
+ setValue |= AD7124_CFG_REG_AIN_BUFP; //Buffer AIN5
+ setValue |= AD7124_CFG_REG_AINN_BUFM; //Buffer AIN4
+ setValue |= AD7124_CFG_REG_REF_SEL(1); //REFIN2(+)/REFIN2(-).
+ setValue |= AD7124_CFG_REG_PGA(4); // gain 16
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+
+ /* Set Channel_0 register 0x09*/
+ regNr = AD7124::AD7124_Channel_0; // pH reading
+ setValue = 0;
+ setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0
+ setValue |= AD7124_CH_MAP_REG_AINP(6); // Set AIN4 as positive input
+ setValue |= AD7124_CH_MAP_REG_AINM(7); // Set AIN5 as negative input
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+
+ regNr = AD7124::AD7124_Channel_1; // Moisture
+ setValue = 0;
+ setValue |= AD7124_CH_MAP_REG_SETUP(1); // Select setup0
+ setValue |= AD7124_CH_MAP_REG_AINP(8); // Set AIN4 as positive input
+ setValue |= AD7124_CH_MAP_REG_AINM(19); // Set AIN5 as negative input
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+
+ regNr = AD7124::AD7124_Channel_2; // RTD - gain 16
+ setValue = 0;
+ setValue |= AD7124_CH_MAP_REG_SETUP(2); // Select setup0
+ setValue |= AD7124_CH_MAP_REG_AINP(9); // Set AIN4 as positive input
+ setValue |= AD7124_CH_MAP_REG_AINM(10); // Set AIN5 as negative input
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+
+ /* Set IO_Control_1 0x03 */
+ regNr = AD7124::AD7124_IOCon1; //Select IO_Control_1 register
+ //setValue = ad7124.ReadDeviceRegister(regNr);
+ setValue = 0;
+ setValue |= AD7124_8_IO_CTRL1_REG_GPIO_CTRL2; // enable AIN3 as digital output
+ setValue |= AD7124_8_IO_CTRL1_REG_GPIO_CTRL3; // enable AIN4 as digital output
+ setValue |= AD7124_IO_CTRL1_REG_IOUT_CH0(11); // source ain11
+ setValue |= AD7124_IO_CTRL1_REG_IOUT_CH1(12); // source ain12
+ setValue |= AD7124_IO_CTRL1_REG_IOUT0(0x4);// set IOUT0 current to 500uA
+ setValue |= AD7124_IO_CTRL1_REG_IOUT1(0x4);// set IOUT0 current to 500uA*/
+ setValue &= 0xFFFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue);// Write data to ADC
+
+ // Set IO_Control_2
+ regNr = AD7124::AD7124_IOCon2; //Select IO_Control_2 register
+ setValue = 0;
+ setValue |= AD7124_8_IO_CTRL2_REG_GPIO_VBIAS7; // enable AIN3 as digital output
+ setValue &= 0xFFFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue);// Write data to ADC
+
+
+ /* Set ADC_Control 0x01 */
+ regNr = AD7124::AD7124_ADC_Control; //Select ADC_Control register
+ setValue = ad7124.ReadDeviceRegister(regNr);
+ setValue |= AD7124_ADC_CTRL_REG_DATA_STATUS; // set data status bit in order to check on which channel the conversion is
+ setValue &= 0xFFC3; // remove prev mode bits
+ setValue |= AD7124_ADC_CTRL_REG_MODE(2);
+ setValue &= 0xFFFF;
+ ad7124.WriteDeviceRegister(regNr, setValue); // Write data to ADC
+ wait_ms(ms_delay);
+}
+
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CN0398.h Mon Oct 24 15:27:31 2016 +0000
@@ -0,0 +1,235 @@
+#ifndef _CN0398_H_
+#define _CN0398_H_
+#include "AD7124.h"
+
+/**
+ * @brief Calibration solutions enum
+ */
+enum {
+ ACETATE,
+ BORATE,
+ CAOH2,
+ CARBONATE,
+ CITRATE,
+ HCL,
+ OXALATE,
+ PHOSPHATE0,
+ PHOSPHATE1,
+ PHOSPHATE2,
+ PHTHALATE,
+ TARTRATE,
+ TRIS,
+ PH4,
+ PH10,
+ NUMBER_OF_SOLUTIONS
+};
+
+/**
+ * @brief Calibration solutions strings
+ */
+const char solutions[NUMBER_OF_SOLUTIONS][20] = {
+ "ACETATE",
+ "BORATE",
+ "CAOH2",
+ "CARBONATE",
+ "CITRATE",
+ "HCL",
+ "OXALATE",
+ "PHOSPHATE0",
+ "PHOSPHATE1",
+ "PHOSPHATE2",
+ "PHTHALATE",
+ "TARTRATE",
+ "TRIS",
+ "PH4",
+ "PH10"
+};
+#define NUMBER_OF_TEMPERATURE_ENTRIES 31
+
+// *INDENT-OFF*
+/**
+ * @brief Calibration temperatures
+ */
+const uint8_t ph_temperatures[NUMBER_OF_TEMPERATURE_ENTRIES] =
+{
+ 0 , 5 , 10, 15, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 35, 37, 40, 45, 50, 55, 60,
+ 65, 70, 75, 80, 85, 90, 95,
+};
+
+/**
+ * @brief Calibration solutions temperature to ph look-up tables
+ */
+const float ph_temp_lut[NUMBER_OF_SOLUTIONS][NUMBER_OF_TEMPERATURE_ENTRIES]
+{
+/* ACETATE */ {4.667, 4.66, 4.655, 4.652, 4.651, 4.651, 4.65, 4.65, 4.65, 4.65, 4.65, 4.65, 4.65, 4.651, 4.651, 4.651, 4.652, 4.655, 4.656, 4.659, 4.666, 4.673, 4.683, 4.694, 4.706, 4.72, 4.736, 4.753, 4.772, 4.793, 4.815},
+/* BORATE */ {9.464, 9.395, 9.332, 9.276, 9.245, 9.235, 9.225, 9.216, 9.207, 9.197, 9.189, 9.18, 9.171, 9.163, 9.155, 9.147, 9.139, 9.102, 9.088, 9.068, 9.038, 9.01, 8.985, 8.962, 8.941, 8.921, 8.902, 8.884, 8.867, 8.85, 8.833},
+/* CAOH2 */ {13.424, 13.207, 13.003, 12.81, 12.699, 12.663, 12.627, 12.592, 12.557, 12.522, 12.488, 12.454, 12.42, 12.387, 12.354, 12.322, 12.289, 12.133, 12.072, 11.984, 11.841, 11.705, 11.574, 11.449 },
+/* CARBONATE */ {10.317, 10.245, 10.179, 10.118, 10.084, 10.073, 10.062, 10.052, 10.042, 10.032, 10.022, 10.012, 10.002, 9.993, 9.984, 9.975, 9.966, 9.925, 9.91, 9.889, 9.857, 9.828},
+/* CITRATE */ {3.863, 3.84, 3.82, 3.803, 3.793, 3.791, 3.788, 3.785, 3.783, 3.78, 3.778, 3.776, 3.774, 3.772, 3.77, 3.768, 3.766, 3.759, 3.756, 3.754, 3.75, 3.749},
+/* HCL */ {1.082, 1.085, 1.087, 1.089, 1.09, 1.091, 1.091, 1.092, 1.092, 1.093, 1.093, 1.094, 1.094, 1.094, 1.095, 1.095, 1.096, 1.098, 1.099, 1.101, 1.103, 1.106, 1.108, 1.111, 1.113, 1.116, 1.119, 1.121, 1.124, 1.127, 1.13},
+/* OXALATE */ {1.666, 1.668, 1.67, 1.672, 1.674, 1.675, 1.675, 1.676, 1.677, 1.678, 1.678, 1.679, 1.68, 1.681, 1.681, 1.682, 1.683, 1.688, 1.69, 1.694, 1.7, 1.707, 1.715, 1.723, 1.732, 1.743, 1.754, 1.765, 1.778, 1.792, 1.806},
+/* PHOSPHATE0 */ {6.984, 6.951, 6.923, 6.9, 6.888, 6.884, 6.881, 6.877, 6.874, 6.871, 6.868, 6.865, 6.862, 6.86, 6.857, 6.855, 6.853, 6.844, 6.841, 6.838, 6.834, 6.833, 6.833, 6.836, 6.84, 6.845, 6.852, 6.859, 6.867, 6.876, 6.886},
+/* PHOSPHATE1 */ {7.118, 7.087, 7.059, 7.036, 7.024, 7.02, 7.016, 7.013, 7.009, 7.006, 7.003, 7, 6.997, 6.994, 6.992, 6.989, 6.987, 6.977, 6.974, 6.97, 6.965, 6.964, 6.965, 6.968, 6.974, 6.982, 6.992, 7.004, 7.018, 7.034, 7.052},
+/* PHOSPHATE2 */ {7.534, 7.5, 7.472, 7.448, 7.436, 7.432, 7.429, 7.425, 7.422, 7.419, 7.416, 7.413, 7.41, 7.407, 7.405, 7.402, 7.4, 7.389, 7.386, 7.38, 7.373, 7.367},
+/* PHTHALATE */ {4, 3.998, 3.997, 3.998, 3.999, 4, 4.001, 4.001, 4.002, 4.003, 4.004, 4.005, 4.006, 4.007, 4.008, 4.009, 4.011, 4.018, 4.022, 4.027, 4.038, 4.05, 4.064, 4.08, 4.097, 4.116, 4.137, 4.159, 4.183, 4.208, 4.235},
+/* TARTRATE */ {3.557, 3.557, 3.557, 3.557, 3.557, 3.557, 3.557, 3.557, 3.557, 3.557, 3.557, 3.557, 3.556, 3.555, 3.554, 3.553, 3.552, 3.549, 3.548, 3.547, 3.547, 3.549, 3.554, 3.56, 3.569, 3.58, 3.593, 3.61, 3.628, 3.65, 3.675},
+/* TRIS */ {8.471, 8.303, 8.142, 7.988, 7.899, 7.869, 7.84, 7.812, 7.783, 7.755, 7.727, 7.699, 7.671, 7.644, 7.617, 7.59, 7.563, 7.433, 7.382, 7.307, 7.186, 7.07},
+/* PH4 */ {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
+/* PH10 */ {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 },
+};
+// *INDENT-ON*
+
+#define TEMPERATURE_SENSOR_PRESENT
+#define MOISTURE_SENSOR_PRESENT
+#define PH_SENSOR_PRESENT
+
+//#define USE_LINEAR_TEMP_EQ
+//#define USE_MANUFACTURER_MOISTURE_EQ
+
+
+#define ZERO_POINT_TOLERANCE (0.003)
+#define PH_ISO (7)
+#define AVOGADRO (8.314)
+#define FARADAY_CONSTANT (96485.0)
+#define KELVIN_OFFSET (273.1)
+
+
+
+
+/**
+ * @brief the CN0398 shield class
+ */
+class CN0398
+{
+private:
+public:
+ /**
+ * @brief CN0398 constructor
+ * @param cs - CN0398 external ADC chip select pin
+ * @param swctrl0 - CN0398 ADP7118 enable pin
+ */
+ CN0398(PinName cs, PinName swctrl0);
+
+ /**
+ * @brief reads the temperature sensor
+ * @return temperature
+ */
+ float read_rtd();
+ /**
+ * @brief reads the pH sensor
+ * @param temperature(optional) - environment temperature
+ * @return reading of the pH sensor corrected with temperature(if provided)
+ */
+ float read_ph(float temperature = 25.0);
+
+ /**
+ * @brief reads the moisture sensor
+ * @return reading of the moisture sensor
+ */
+ float read_moist();
+
+ typedef enum {
+ P1 = 0,
+ P2 = 1,
+ P3 = 2,
+ P4 = 3
+ } ad_digital_output_t;
+
+ /**
+ * @brief reads the ADC channel
+ * @param ch channel to be read
+ * @return ADC reading in counts
+ */
+ int32_t read_channel(uint8_t ch);
+
+ /**
+ * @brief converts counts to voltage - unipolar conversion
+ * @param data in counts
+ * @param gain(optional) - default 1
+ * @param VREF(optional) - default 2.5 - reference voltage
+ * @return voltage
+ */
+ float data_to_voltage(uint32_t data, uint8_t gain = 1, float VREF = 2.5);
+
+ /**
+ * @brief converts counts to voltage - bipolar conversion
+ * @param data in counts
+ * @param gain(optional) - default 1
+ * @param VREF(optional) - default 2.5 - reference voltage
+ * @return voltage
+ */
+ float data_to_voltage_bipolar(uint32_t data, uint8_t gain = 1, float VREF = 2.5);
+
+ /**
+ * @brief enables an ADC channel
+ * @param channel - channel to be enabled
+ */
+ void enable_channel(int channel);
+ /**
+ * @brief disables an ADC channel
+ * @param channel - channel to be disabled
+ */
+ void disable_channel(int channel);
+
+ /**
+ * @brief performs pt 0 calibration. ph probe should be in calibration solution before calling this method
+ * @param temp - environment temperature
+ */
+ void calibrate_ph_pt0(float temperature = 25.0);
+
+ /**
+ * @brief performs pt 1 calibration. ph probe should be in calibration solution before calling this method
+ * @param temp - environment temperature
+ */
+ void calibrate_ph_pt1(float temperature = 25.0);
+
+ /**
+ * @brief performs offset calibration. pH probes should be shorted before calling this method
+ *
+ */
+ void calibrate_ph_offset();
+
+ /* void enable_current_source0(int current_source_channel);
+ void enable_current_source1(int current_source_channel);*/
+
+ /**
+ * @brief toggles the digital outputs on or off
+ * @param p - digital output
+ * @param state - state of the output
+ */
+ void set_digital_output(ad_digital_output_t p, bool state);
+
+ /**
+ * @brief triggers ADC start of single conversion
+ */
+ void start_single_conversion();
+
+ /**
+ * @brief resets the digital interface of the ADC
+ */
+ void reset();
+
+ /**
+ * @brief initializes the ADC
+ */
+ void setup();
+
+ /**
+ * @brief configures the ADC for the CN0398 application
+ */
+ void init();
+
+ AD7124 ad7124;
+ DigitalOut ADP7118Enable;
+
+ bool use_nernst = false;
+ const float default_offset_voltage = 0;
+ const uint16_t SENSOR_SETTLING_TIME = 400; /*in ms*/
+ float offset_voltage;
+ float default_calibration_ph[2][2] = {{4, 0.169534}, {10, -0.134135}};
+ float calibration_ph[2][2];
+ uint8_t solution0, solution1;
+
+};
+#endif

