A collection of Analog Devices drivers for the mbed platform
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 17:59:52 by 1.7.2