Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
CN0357 - Toxic gas measurement
CN0216 - Weight Scale