CN0397 (Smart Visible Light Detection)
Dependencies: AD7798
CN0397.cpp
00001 /** 00002 * @file CN0397.cpp 00003 * @brief Source file for the CN0397 00004 * @author Analog Devices Inc. 00005 * 00006 * For support please go to: 00007 * Github: https://github.com/analogdevicesinc/mbed-adi 00008 * Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers 00009 * Product: www.analog.com/EVAL-CN0397-ARDZ 00010 * More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all 00011 00012 ******************************************************************************** 00013 * Copyright 2016(c) Analog Devices, Inc. 00014 * 00015 * All rights reserved. 00016 * 00017 * Redistribution and use in source and binary forms, with or without 00018 * modification, are permitted provided that the following conditions are met: 00019 * - Redistributions of source code must retain the above copyright 00020 * notice, this list of conditions and the following disclaimer. 00021 * - Redistributions in binary form must reproduce the above copyright 00022 * notice, this list of conditions and the following disclaimer in 00023 * the documentation and/or other materials provided with the 00024 * distribution. 00025 * - Neither the name of Analog Devices, Inc. nor the names of its 00026 * contributors may be used to endorse or promote products derived 00027 * from this software without specific prior written permission. 00028 * - The use of this software may or may not infringe the patent rights 00029 * of one or more patent holders. This license does not release you 00030 * from the requirement that you obtain separate licenses from these 00031 * patent holders to use this software. 00032 * - Use of the software either in source or binary form, must be run 00033 * on or directly connected to an Analog Devices Inc. component. 00034 * 00035 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR 00036 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, 00037 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00038 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, 00039 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00040 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR 00041 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00042 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00043 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00044 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00045 * 00046 ********************************************************************************/ 00047 00048 #include "CN0397.h" 00049 #include "AD7798.h" 00050 #include "Timer.h" 00051 #include <stdio.h> 00052 #include <math.h> 00053 #include <mbed.h> 00054 00055 extern Serial pc; 00056 00057 00058 void flush_serial() 00059 { 00060 wait_ms(10); // wait for all data to come through 00061 while (pc.readable()) pc.getc(); 00062 } 00063 00064 const uint8_t CN0397::Channels[3] = { 1, 0, 2}; 00065 const char CN0397::colour[3][6] = { "RED", "GREEN", "BLUE" }; 00066 const uint8_t CN0397::ColorPrint[3] = { 31, 32, 34 }; 00067 const uint8_t CN0397::Gain[8] = { 1, 2, 4, 8, 16, 32, 64, 128}; 00068 const float CN0397::Lux_LSB[3] = {2.122, 2.124, 2.113}; 00069 const float CN0397::Optimal_Levels[3] = {26909.0, 8880.0, 26909.0}; 00070 00071 CN0397::CN0397(PinName cs) : ad7798(cs) 00072 { 00073 } 00074 void CN0397::display_data(void) 00075 { 00076 00077 uint8_t channel = 0, i; 00078 00079 /* for(channel = 0; channel < CHANNELS; channel++){ 00080 00081 pc.printf("%s (channel %d):\n", colour[channel], (channel + 1)); 00082 pc.printf("\tADC output = %u (%#06x)\n", adcValue[channel], adcValue[channel]); 00083 pc.printf("\tVoltage = %f mV\n", voltageValue[channel]); 00084 pc.printf("\tLight Intensity = %.2f lux\n", intensityValue[channel]); 00085 pc.printf("\tLight Concentration = %.2f%c\n", lightConcentration[channel], 37); 00086 00087 }*/ 00088 00089 00090 for(channel = 0; channel < CHANNELS; channel++) { 00091 00092 pc.printf("\t\t\033[2;%dm%s\033[0m channel:\t\t", ColorPrint[channel], colour[channel]); 00093 } 00094 00095 pc.printf("\n"); 00096 pc.printf("\t"); 00097 00098 /* 00099 for(channel = 0; channel < CHANNELS; channel++) { 00100 00101 pc.printf("\t\t\tADC output = %u (%#06x)", adcValue[channel], adcValue[channel]); 00102 } 00103 00104 pc.printf("\n"); 00105 pc.printf("\t"); 00106 00107 */ 00108 for(channel = 0; channel < CHANNELS; channel++) { 00109 00110 pc.printf("\t\tLight Intensity = %.2f lux", intensityValue[channel]); 00111 } 00112 00113 pc.printf("\n"); 00114 pc.printf("\t"); 00115 00116 00117 for(channel = 0; channel < CHANNELS; channel++) { 00118 00119 pc.printf("\t\tLight Concentration = %.2f%c", lightConcentration[channel], 37); 00120 } 00121 00122 pc.printf("\n");/*pc.printf("\t"); 00123 00124 for(channel = 0; channel < CHANNELS; channel++) { 00125 00126 pc.printf("\t\t\tLight Concentration = %.2f%c", lightConcentration[channel], 37); 00127 } 00128 00129 pc.printf("\n");pc.printf("\t"); 00130 00131 /* for(channel = 0; channel < CHANNELS; channel++){ 00132 00133 pc.printf("\t\t\t\033[2;%dm|\033[0m\t", ColorPrint[channel]); 00134 00135 }*/ 00136 00137 for(channel = 0; channel < 5; channel++) { 00138 pc.printf("\n"); 00139 } 00140 00141 // pc.printf("\n"); 00142 // pc.printf("\n"); 00143 pc.printf("\n"); 00144 } 00145 00146 00147 void CN0397::data_to_voltage(uint16_t adcValue, float *voltage) 00148 { 00149 00150 *voltage = (float)(adcValue * V_REF) / (float)(_2_16 * gainAdc); 00151 00152 } 00153 00154 void CN0397::init(void) 00155 { 00156 ad7798.reset(); 00157 uint8_t channel; 00158 00159 if(ad7798.init()) { 00160 00161 ad7798.set_coding_mode(AD7798_UNIPOLAR); 00162 ad7798.set_mode(AD7798_MODE_SINGLE); 00163 ad7798.set_gain(ADC_GAIN); 00164 ad7798.set_filter(ADC_SPS); 00165 ad7798.set_reference(AD7798_REFDET_ENA); 00166 00167 } 00168 00169 gainAdc = Gain[ADC_GAIN]; 00170 #ifdef USE_CALIBRATION 00171 pc.printf("Calibrate the system:\n"); 00172 pc.printf("\n"); 00173 00174 for(channel = 0; channel < CHANNELS; channel++) { 00175 00176 pc.printf("\tCalibrate channel %d: be sure that %s photodiode is cover and press <ENTER>.\n", (Channels[channel] + 1), colour[channel]); 00177 pc.getc(); 00178 flush_serial(); 00179 calibration(Channels[channel]); 00180 pc.printf("\t\tChannel %d is calibrated!\n", (Channels[channel] + 1)); 00181 pc.printf("\n"); 00182 00183 } 00184 00185 printf("System calibration complete!\n"); 00186 printf("\n"); 00187 printf("\n"); 00188 00189 #endif 00190 } 00191 00192 void CN0397::calc_light_intensity(uint8_t channel, uint16_t adcValue, float *intensity) 00193 { 00194 00195 *intensity = adcValue * Lux_LSB[channel]; 00196 00197 } 00198 00199 void CN0397::calc_light_concentration(uint8_t channel, float intensity, float *conc) 00200 { 00201 00202 *conc = (intensity * 100) / Optimal_Levels[channel]; 00203 00204 } 00205 00206 void CN0397::set_app_data(void) 00207 { 00208 uint8_t channel, rgbChannel; 00209 uint16_t *adcData = &adcValue[0]; 00210 float *voltageData = &voltageValue[0], *intensityData = &intensityValue[0]; 00211 float *concData = &lightConcentration[0]; 00212 00213 for(channel = 0; channel < CHANNELS; channel++) { 00214 00215 rgbChannel = Channels[channel]; 00216 00217 ad7798.set_channel(channel); 00218 00219 adcData = &adcValue[rgbChannel]; 00220 voltageData = &voltageValue[rgbChannel]; 00221 intensityData = &intensityValue[rgbChannel]; 00222 concData = &lightConcentration[rgbChannel]; 00223 ad7798.read_data(channel, adcData); 00224 data_to_voltage(*adcData, voltageData); 00225 calc_light_intensity(rgbChannel, *adcData, intensityData); 00226 calc_light_concentration(rgbChannel, *intensityData, concData); 00227 00228 /* adcData++; 00229 voltageData++; 00230 intensityData++; 00231 concData++;*/ 00232 00233 } 00234 } 00235 00236 void CN0397::calibration(uint8_t channel) 00237 { 00238 00239 uint16_t setValue; 00240 00241 ad7798.set_channel(channel); //select channel to calibrate 00242 00243 // Perform system zero-scale calibration 00244 setValue = ad7798.get_register_value(AD7798_REG_MODE, 2); 00245 setValue &= ~(AD7798_MODE_SEL(0x07)); 00246 setValue |= AD7798_MODE_SEL(AD7798_MODE_CAL_SYS_ZERO); 00247 ad7798.set_register_value(AD7798_REG_MODE, setValue, 2); 00248 00249 while((ad7798.get_register_value( AD7798_REG_STAT, 1) & channel) != channel); // wait for RDY bit to go low 00250 00251 while(ad7798.get_register_value(AD7798_REG_MODE, 2) != 0x4005); // wait for ADC to go in idle mode 00252 00253 00254 } 00255 00256 00257 00258
Generated on Mon Jul 18 2022 00:52:12 by 1.7.2