A collection of Analog Devices drivers for the mbed platform

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CN0398.cpp Source File

CN0398.cpp

00001 #include "CN0398.h"
00002 #include "AD7124.h"
00003 #include <mbed.h>
00004 
00005 #define RREF (5000.0)
00006 #define TEMP_GAIN (16.0)
00007 #define PT100_RESISTANCE_TO_TEMP(x) ((x-100.0)/(0.385))
00008 #define _2_23 (1<<23)
00009 
00010 #define CALIBRATION_NR_OF_SAMPLES (5)
00011 
00012 extern Serial pc;
00013 
00014 #define ms_delay (1)
00015 
00016 CN0398::CN0398(PinName cs, PinName adp7118enable) : ad7124(cs), ADP7118Enable(adp7118enable), offset_voltage(default_offset_voltage)
00017 {
00018     calibration_ph[0][0] = default_calibration_ph[0][0];
00019     calibration_ph[0][1] = default_calibration_ph[0][1];
00020     calibration_ph[1][0] = default_calibration_ph[1][0];
00021     calibration_ph[1][1] = default_calibration_ph[1][1];
00022     solution0 = 0;
00023     solution1 = 0;
00024 }
00025 
00026 void CN0398::calibrate_ph_pt0(float temperature)
00027 {
00028     float volt = 0;
00029     for(int i = 0; i < CALIBRATION_NR_OF_SAMPLES; i++) {
00030         set_digital_output(P2, true);
00031         int32_t data = read_channel(0);
00032         set_digital_output(P2, false);
00033         volt += data_to_voltage_bipolar(data >> 8, 1, 3.3);
00034     }
00035     volt = volt / CALIBRATION_NR_OF_SAMPLES;
00036     if(temperature < 0) {
00037         calibration_ph[0][0] = ph_temp_lut[solution0][0];
00038     } else {
00039         for(uint8_t i = 1; i < NUMBER_OF_TEMPERATURE_ENTRIES; i++) {
00040             if(temperature > ph_temperatures[i - 1] && temperature <= ph_temperatures[i]) {
00041                 calibration_ph[0][0] = ph_temp_lut[solution0][i];
00042                 break;
00043             }
00044         }
00045     }
00046     calibration_ph[0][1] = volt;
00047     pc.printf("Calibration solution 1 ph: %f with sensor voltage of %f\r\n", calibration_ph[0][0], volt);
00048 }
00049 void CN0398::calibrate_ph_pt1(float temperature)
00050 {
00051     float volt = 0;
00052     for(int i = 0; i < CALIBRATION_NR_OF_SAMPLES; i++) {
00053         set_digital_output(P2, true);
00054         int32_t data = read_channel(0);
00055         set_digital_output(P2, false);
00056         volt += data_to_voltage_bipolar(data >> 8, 1, 3.3);
00057     }
00058 
00059     volt = volt / CALIBRATION_NR_OF_SAMPLES;
00060     if(temperature < 0) {
00061         calibration_ph[1][0] = ph_temp_lut[solution1][0];
00062     } else {
00063         for(uint8_t i = 1; i < NUMBER_OF_TEMPERATURE_ENTRIES; i++) {
00064             if(temperature > ph_temperatures[i - 1] && temperature <= ph_temperatures[i]) {
00065                 calibration_ph[1][0] = ph_temp_lut[solution1][i];
00066                 break;
00067             }
00068         }
00069     }
00070     calibration_ph[1][1] = volt;
00071     pc.printf("Calibration solution 2 ph: %f with sensor voltage of %f\r\n", calibration_ph[1][0], volt);
00072 }
00073 
00074 void CN0398::calibrate_ph_offset()
00075 {
00076     float volt = 0;
00077     for(int i = 0; i < CALIBRATION_NR_OF_SAMPLES; i++) {
00078         set_digital_output(P2, true);
00079         int32_t data = read_channel(0);
00080         set_digital_output(P2, false);
00081         volt += data_to_voltage_bipolar(data >> 8, 1, 3.3);
00082     }
00083     offset_voltage = volt / CALIBRATION_NR_OF_SAMPLES;
00084     pc.printf("Offset voltage is: %f \r\n", volt);
00085 }
00086 
00087 
00088 float CN0398::read_rtd()
00089 {
00090     float temperature = 25.0;
00091 #ifdef TEMPERATURE_SENSOR_PRESENT
00092     int32_t data = read_channel(2);
00093     data = (data >> 8) & 0x00ffffff;
00094     float resistance = ((static_cast<float>(data) - _2_23) * RREF) / (TEMP_GAIN * _2_23);
00095 #ifdef USE_LINEAR_TEMP_EQ
00096     temperature = PT100_RESISTANCE_TO_TEMP(resistance);
00097 #else
00098 
00099 #define A (3.9083*pow(10,-3))
00100 #define B (-5.775*pow(10,-7))
00101     /*if(resistance < 100.0)
00102         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);
00103     else*/
00104     temperature = ((-A + sqrt(double(pow(A, 2) - 4 * B * (1 - resistance / 100.0))) ) / (2 * B));
00105 #endif
00106 #endif
00107     return temperature;
00108 
00109 }
00110 
00111 int32_t CN0398::read_channel(uint8_t ch)
00112 {
00113     int32_t data;
00114     enable_channel(ch);
00115     start_single_conversion();
00116 
00117     if (ad7124.WaitForConvReady (10000) == -3) {
00118         pc.printf("TIMEOUT");
00119         return -1;
00120     }
00121     ad7124.ReadData (&data);
00122     disable_channel(ch);
00123     return data;
00124 
00125 }
00126 float CN0398::read_ph(float temperature)
00127 {
00128     float ph = 0;
00129 #ifdef PH_SENSOR_PRESENT
00130     set_digital_output(P2, true);
00131     int32_t data = read_channel(0);
00132     set_digital_output(P2, false);
00133     float volt = data_to_voltage_bipolar(data >> 8, 1, 3.3);
00134 #ifdef DEBUG_MODE
00135     pc.printf("pH sensor voltage - %f\n", volt);
00136 #endif
00137 
00138     if(use_nernst) {
00139         ph  = -((volt - ZERO_POINT_TOLERANCE) / ((2.303 * AVOGADRO * (temperature + KELVIN_OFFSET)) / FARADAY_CONSTANT) ) + PH_ISO;
00140     } else {
00141         float m =  (calibration_ph[1][0] - calibration_ph[0][0]) / (calibration_ph[1][1] - calibration_ph[0][1]);
00142         ph = m * (volt - calibration_ph[1][1] + offset_voltage) + calibration_ph[1][0];
00143     }
00144 #endif
00145     return ph;
00146 }
00147 float CN0398::read_moist()
00148 {
00149     float moisture = 0;
00150 #ifdef MOISTURE_SENSOR_PRESENT
00151     ADP7118Enable = true;
00152     set_digital_output(P3, true);
00153     wait_ms(SENSOR_SETTLING_TIME);
00154     int32_t data = read_channel(1);
00155     ADP7118Enable = false;
00156     set_digital_output(P3, false);
00157 
00158     data = (data >> 8) & 0x00ffffff;
00159     float volt = data_to_voltage(data, 1, 3.3);
00160 #ifdef USE_MANUFACTURER_MOISTURE_EQ
00161     if(volt <= 1.1) {
00162         moisture = 10 * volt - 1;
00163     } else if(volt > 1.1 && volt <= 1.3) {
00164         moisture = 25 * volt - 17.5;
00165     } else if(volt > 1.3 && volt <= 1.82) {
00166         moisture = 48.08 * volt - 47.5;
00167     } else if(volt > 1.82) {
00168         moisture = 26.32 * volt - 7.89;
00169     }
00170 #else
00171     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));
00172 #endif
00173     if(moisture > 100) moisture = 100;
00174     if(moisture < 0 ) moisture = 0;
00175 #endif
00176     return moisture;
00177 }
00178 
00179 float CN0398::data_to_voltage_bipolar(uint32_t data, uint8_t gain, float VREF)
00180 {
00181     data = data & 0xFFFFFF;
00182     return ((data / static_cast<float>(0xFFFFFF / 2)) - 1) * (VREF / gain);
00183 }
00184 
00185 float CN0398::data_to_voltage(uint32_t data, uint8_t gain, float VREF)
00186 {
00187     data = data & 0xFFFFFF;
00188     return (data / static_cast<float>(0xFFFFFF)) * (VREF / gain);
00189 }
00190 
00191 void CN0398::enable_channel(int channel)
00192 {
00193     AD7124::ad7124_registers regNr = static_cast<AD7124::ad7124_registers> (AD7124::AD7124_Channel_0 + channel); //Select ADC_Control register
00194     uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
00195     setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE;  //Enable channel0
00196     setValue &= 0xFFFF;
00197     ad7124.WriteDeviceRegister(regNr, setValue);    // Write data to ADC
00198     wait_ms(ms_delay);
00199 }
00200 
00201 void CN0398::disable_channel(int channel)
00202 {
00203     AD7124::ad7124_registers regNr = static_cast<AD7124::ad7124_registers> (AD7124::AD7124_Channel_0 + channel); //Select ADC_Control register
00204     uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
00205     setValue &= (~(uint32_t) AD7124_CH_MAP_REG_CH_ENABLE);  //Enable channel0
00206     setValue &= 0xFFFF;
00207     ad7124.WriteDeviceRegister(regNr, setValue);    // Write data to ADC
00208     wait_ms(ms_delay);
00209 }
00210 
00211 /*
00212 void CN0398::enable_current_source0(int current_source_channel)
00213 {
00214     AD7124::ad7124_registers regNr = AD7124::AD7124_IOCon1; //Select ADC_Control register
00215     uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
00216     setValue &= ~(AD7124_IO_CTRL1_REG_IOUT_CH0(0xF));
00217     setValue |= AD7124_IO_CTRL1_REG_IOUT_CH0(current_source_channel);// set IOUT0 current to 500uA
00218     setValue &= 0xFFFFFF;
00219     ad7124.WriteDeviceRegister(regNr, setValue);    // Write data to ADC
00220     wait_ms(ms_delay);
00221 }
00222 
00223 void CN0398::enable_current_source1(int current_source_channel)
00224 {
00225     AD7124::ad7124_registers regNr = AD7124::AD7124_IOCon1; //Select ADC_Control register
00226     uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
00227     setValue &= ~(AD7124_IO_CTRL1_REG_IOUT_CH1(0xF));
00228     setValue |= AD7124_IO_CTRL1_REG_IOUT_CH1(current_source_channel);// set IOUT0 current to 500uA
00229     setValue &= 0xFFFFFF;
00230     ad7124.WriteDeviceRegister(regNr, setValue);    // Write data to ADC
00231     wait_ms(ms_delay);
00232 }*/
00233 
00234 void CN0398::set_digital_output(ad_digital_output_t p, bool state)
00235 {
00236     AD7124::ad7124_registers regNr = AD7124::AD7124_IOCon1; //Select ADC_Control register
00237     uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
00238     if(state)
00239         setValue |= ((AD7124_8_IO_CTRL1_REG_GPIO_DAT1) << p);
00240     else
00241         setValue &= (~((AD7124_8_IO_CTRL1_REG_GPIO_DAT1) << p));
00242     ad7124.WriteDeviceRegister(regNr, setValue);    // Write data to ADC
00243     wait_ms(ms_delay);
00244 }
00245 
00246 
00247 void CN0398::start_single_conversion()
00248 {
00249     AD7124::ad7124_registers regNr = AD7124::AD7124_ADC_Control; //Select ADC_Control register
00250     uint32_t setValue = ad7124.ReadDeviceRegister(regNr);
00251     setValue &= 0xFFC3;
00252     setValue |= 0x04;               //single conversion;
00253     setValue |= AD7124_ADC_CTRL_REG_DATA_STATUS;
00254     setValue &= 0xFFFF;
00255     ad7124.WriteDeviceRegister(regNr, setValue);    // Write data to ADC*/
00256     wait_ms(ms_delay * 10);
00257 }
00258 
00259 void CN0398::reset()
00260 {
00261     ad7124.frequency(500000);
00262     ad7124.Reset();
00263     pc.printf("Reseted AD7124\r\n");
00264     wait_ms(1000);
00265 }
00266 
00267 void CN0398::setup()
00268 {
00269     ad7124.Setup ();
00270 }
00271 
00272 void CN0398::init()
00273 {
00274     uint32_t setValue;
00275     enum AD7124::ad7124_registers regNr;
00276 
00277     /* Set Config_0 0x19*/
00278     regNr = AD7124::AD7124_Config_0;               //Select Config_0 register - pH
00279     setValue = 0;//ad7124.ReadDeviceRegister(regNr);
00280     setValue |= AD7124_CFG_REG_BIPOLAR;     //Select bipolar operation
00281     setValue |= AD7124_CFG_REG_BURNOUT(0);  //Burnout current source off
00282     setValue |= AD7124_CFG_REG_REF_BUFP;
00283     setValue |= AD7124_CFG_REG_REF_BUFM;
00284     setValue |= AD7124_CFG_REG_AIN_BUFP;    //Buffer AIN5
00285     setValue |= AD7124_CFG_REG_AINN_BUFM;   //Buffer AIN4
00286     setValue |= AD7124_CFG_REG_REF_SEL(0); //REFIN1(+)/REFIN1(−).
00287     setValue |= AD7124_CFG_REG_PGA(0);
00288     setValue &= 0xFFFF;
00289     ad7124.WriteDeviceRegister(regNr, setValue);   // Write data to ADC
00290 
00291     /* Set Config_0 0x1A*/
00292     regNr = AD7124::AD7124_Config_1;               //Select Config_1 register - Moisture
00293     setValue = 0;//ad7124.ReadDeviceRegister(regNr);
00294     setValue &= ~AD7124_CFG_REG_BIPOLAR;     //Select bipolar operation
00295     setValue |= AD7124_CFG_REG_BURNOUT(0);  //Burnout current source off
00296     setValue |= AD7124_CFG_REG_REF_BUFP;
00297     setValue |= AD7124_CFG_REG_REF_BUFM;
00298     setValue |= AD7124_CFG_REG_AIN_BUFP;    //Buffer AIN5
00299     setValue |= AD7124_CFG_REG_AINN_BUFM;   //Buffer AIN4*/
00300     setValue |= AD7124_CFG_REG_REF_SEL(0); // REFIN1(+)/REFIN1(−).
00301     setValue |= AD7124_CFG_REG_PGA(0);
00302     setValue &= 0xFFFF;
00303     ad7124.WriteDeviceRegister(regNr, setValue);   // Write data to ADC
00304 
00305     /* Set Config_0 0x1B*/
00306     regNr = AD7124::AD7124_Config_2;               //Select Config_2 register - temp
00307     setValue = 0;//ad7124.ReadDeviceRegister(regNr);
00308     setValue |= AD7124_CFG_REG_BIPOLAR;     //Select bipolar operation
00309     setValue |= AD7124_CFG_REG_BURNOUT(0);  //Burnout current source off
00310     setValue |= AD7124_CFG_REG_REF_BUFP;
00311     setValue |= AD7124_CFG_REG_REF_BUFM;
00312     setValue |= AD7124_CFG_REG_AIN_BUFP;    //Buffer AIN5
00313     setValue |= AD7124_CFG_REG_AINN_BUFM;   //Buffer AIN4
00314     setValue |= AD7124_CFG_REG_REF_SEL(1); //REFIN2(+)/REFIN2(-).
00315     setValue |= AD7124_CFG_REG_PGA(4); // gain 16
00316     setValue &= 0xFFFF;
00317     ad7124.WriteDeviceRegister(regNr, setValue);   // Write data to ADC
00318 
00319     /* Set Channel_0 register 0x09*/
00320     regNr = AD7124::AD7124_Channel_0;  // pH reading
00321     setValue = 0;
00322     setValue |= AD7124_CH_MAP_REG_SETUP(0);             // Select setup0
00323     setValue |= AD7124_CH_MAP_REG_AINP(6);         // Set AIN4 as positive input
00324     setValue |= AD7124_CH_MAP_REG_AINM(7);         // Set AIN5 as negative input
00325     setValue &= 0xFFFF;
00326     ad7124.WriteDeviceRegister(regNr, setValue);   // Write data to ADC
00327 
00328     regNr = AD7124::AD7124_Channel_1; // Moisture
00329     setValue = 0;
00330     setValue |= AD7124_CH_MAP_REG_SETUP(1);             // Select setup0
00331     setValue |= AD7124_CH_MAP_REG_AINP(8);         // Set AIN4 as positive input
00332     setValue |= AD7124_CH_MAP_REG_AINM(19);         // Set AIN5 as negative input
00333     setValue &= 0xFFFF;
00334     ad7124.WriteDeviceRegister(regNr, setValue);   // Write data to ADC
00335 
00336     regNr = AD7124::AD7124_Channel_2; // RTD - gain 16
00337     setValue = 0;
00338     setValue |= AD7124_CH_MAP_REG_SETUP(2);             // Select setup0
00339     setValue |= AD7124_CH_MAP_REG_AINP(9);         // Set AIN4 as positive input
00340     setValue |= AD7124_CH_MAP_REG_AINM(10);         // Set AIN5 as negative input
00341     setValue &= 0xFFFF;
00342     ad7124.WriteDeviceRegister(regNr, setValue);   // Write data to ADC
00343 
00344     /* Set IO_Control_1 0x03 */
00345     regNr = AD7124::AD7124_IOCon1;               //Select IO_Control_1 register
00346     //setValue = ad7124.ReadDeviceRegister(regNr);
00347     setValue = 0;
00348     setValue |= AD7124_8_IO_CTRL1_REG_GPIO_CTRL2; // enable AIN3 as digital output
00349     setValue |= AD7124_8_IO_CTRL1_REG_GPIO_CTRL3; // enable AIN4 as digital output
00350     setValue |= AD7124_IO_CTRL1_REG_IOUT_CH0(11); // source ain11
00351     setValue |= AD7124_IO_CTRL1_REG_IOUT_CH1(12); // source ain12
00352     setValue |= AD7124_IO_CTRL1_REG_IOUT0(0x4);// set IOUT0 current to 500uA
00353     setValue |= AD7124_IO_CTRL1_REG_IOUT1(0x4);// set IOUT0 current to 500uA*/
00354     setValue &= 0xFFFFFF;
00355     ad7124.WriteDeviceRegister(regNr, setValue);// Write data to ADC
00356 
00357     // Set IO_Control_2
00358     regNr = AD7124::AD7124_IOCon2;               //Select IO_Control_2 register
00359     setValue = 0;
00360     setValue |= AD7124_8_IO_CTRL2_REG_GPIO_VBIAS7; // enable AIN3 as digital output
00361     setValue &= 0xFFFFFF;
00362     ad7124.WriteDeviceRegister(regNr, setValue);// Write data to ADC
00363 
00364 
00365     /* Set ADC_Control 0x01 */
00366     regNr = AD7124::AD7124_ADC_Control;            //Select ADC_Control register
00367     setValue = ad7124.ReadDeviceRegister(regNr);
00368     setValue |= AD7124_ADC_CTRL_REG_DATA_STATUS; // set data status bit in order to check on which channel the conversion is
00369     setValue &= 0xFFC3; // remove prev mode bits
00370     setValue |= AD7124_ADC_CTRL_REG_MODE(2);
00371     setValue &= 0xFFFF;
00372     ad7124.WriteDeviceRegister(regNr, setValue);    // Write data to ADC
00373     wait_ms(ms_delay);
00374 }
00375 
00376 
00377 
00378 
00379