CN0397 (Smart Visible Light Detection)

Dependencies:   AD7798

Dependents:   cn0397-helloworld

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CN0397.cpp Source File

CN0397.cpp

Go to the documentation of this file.
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