CN0397 (Smart Visible Light Detection)

Dependencies:   AD7798

Dependents:   cn0397-helloworld

For additional information check out the mbed page of the Analog Devices wiki: https://wiki.analog.com/resources/tools-software/mbed-drivers-all

Committer:
adisuciu
Date:
Mon Nov 07 15:57:44 2016 +0000
Revision:
0:61b289f9bab0
Child:
1:77eb0888c15a
Initial revision

Who changed what in which revision?

UserRevisionLine numberNew contents of line
adisuciu 0:61b289f9bab0 1 /**
adisuciu 0:61b289f9bab0 2 * @file CN0397.cpp
adisuciu 0:61b289f9bab0 3 * @brief Source file for the CN0397
adisuciu 0:61b289f9bab0 4 * @author Analog Devices Inc.
adisuciu 0:61b289f9bab0 5 *
adisuciu 0:61b289f9bab0 6 * For support please go to:
adisuciu 0:61b289f9bab0 7 * Github: https://github.com/analogdevicesinc/mbed-adi
adisuciu 0:61b289f9bab0 8 * Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers
adisuciu 0:61b289f9bab0 9 * Product: www.analog.com/EVAL-CN0397-ARDZ
adisuciu 0:61b289f9bab0 10 * More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all
adisuciu 0:61b289f9bab0 11
adisuciu 0:61b289f9bab0 12 ********************************************************************************
adisuciu 0:61b289f9bab0 13 * Copyright 2016(c) Analog Devices, Inc.
adisuciu 0:61b289f9bab0 14 *
adisuciu 0:61b289f9bab0 15 * All rights reserved.
adisuciu 0:61b289f9bab0 16 *
adisuciu 0:61b289f9bab0 17 * Redistribution and use in source and binary forms, with or without
adisuciu 0:61b289f9bab0 18 * modification, are permitted provided that the following conditions are met:
adisuciu 0:61b289f9bab0 19 * - Redistributions of source code must retain the above copyright
adisuciu 0:61b289f9bab0 20 * notice, this list of conditions and the following disclaimer.
adisuciu 0:61b289f9bab0 21 * - Redistributions in binary form must reproduce the above copyright
adisuciu 0:61b289f9bab0 22 * notice, this list of conditions and the following disclaimer in
adisuciu 0:61b289f9bab0 23 * the documentation and/or other materials provided with the
adisuciu 0:61b289f9bab0 24 * distribution.
adisuciu 0:61b289f9bab0 25 * - Neither the name of Analog Devices, Inc. nor the names of its
adisuciu 0:61b289f9bab0 26 * contributors may be used to endorse or promote products derived
adisuciu 0:61b289f9bab0 27 * from this software without specific prior written permission.
adisuciu 0:61b289f9bab0 28 * - The use of this software may or may not infringe the patent rights
adisuciu 0:61b289f9bab0 29 * of one or more patent holders. This license does not release you
adisuciu 0:61b289f9bab0 30 * from the requirement that you obtain separate licenses from these
adisuciu 0:61b289f9bab0 31 * patent holders to use this software.
adisuciu 0:61b289f9bab0 32 * - Use of the software either in source or binary form, must be run
adisuciu 0:61b289f9bab0 33 * on or directly connected to an Analog Devices Inc. component.
adisuciu 0:61b289f9bab0 34 *
adisuciu 0:61b289f9bab0 35 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
adisuciu 0:61b289f9bab0 36 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
adisuciu 0:61b289f9bab0 37 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
adisuciu 0:61b289f9bab0 38 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
adisuciu 0:61b289f9bab0 39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
adisuciu 0:61b289f9bab0 40 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
adisuciu 0:61b289f9bab0 41 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
adisuciu 0:61b289f9bab0 42 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
adisuciu 0:61b289f9bab0 43 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
adisuciu 0:61b289f9bab0 44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
adisuciu 0:61b289f9bab0 45 *
adisuciu 0:61b289f9bab0 46 ********************************************************************************/
adisuciu 0:61b289f9bab0 47
adisuciu 0:61b289f9bab0 48 #include "CN0397.h"
adisuciu 0:61b289f9bab0 49 #include "AD7798.h"
adisuciu 0:61b289f9bab0 50 #include "Timer.h"
adisuciu 0:61b289f9bab0 51 #include <stdio.h>
adisuciu 0:61b289f9bab0 52 #include <math.h>
adisuciu 0:61b289f9bab0 53 #include <mbed.h>
adisuciu 0:61b289f9bab0 54
adisuciu 0:61b289f9bab0 55 extern Serial pc;
adisuciu 0:61b289f9bab0 56
adisuciu 0:61b289f9bab0 57
adisuciu 0:61b289f9bab0 58 void flush_serial()
adisuciu 0:61b289f9bab0 59 {
adisuciu 0:61b289f9bab0 60 wait_ms(10); // wait for all data to come through
adisuciu 0:61b289f9bab0 61 while (pc.readable()) pc.getc();
adisuciu 0:61b289f9bab0 62 }
adisuciu 0:61b289f9bab0 63
adisuciu 0:61b289f9bab0 64
adisuciu 0:61b289f9bab0 65 CN0397::CN0397(PinName cs) : ad7798(cs)
adisuciu 0:61b289f9bab0 66 {
adisuciu 0:61b289f9bab0 67
adisuciu 0:61b289f9bab0 68 }
adisuciu 0:61b289f9bab0 69 void CN0397::display_data(void)
adisuciu 0:61b289f9bab0 70 {
adisuciu 0:61b289f9bab0 71
adisuciu 0:61b289f9bab0 72 uint8_t channel = 0, i;
adisuciu 0:61b289f9bab0 73
adisuciu 0:61b289f9bab0 74 /* for(channel = 0; channel < CHANNELS; channel++){
adisuciu 0:61b289f9bab0 75
adisuciu 0:61b289f9bab0 76 pc.printf("%s (channel %d):\n", colour[channel], (channel + 1));
adisuciu 0:61b289f9bab0 77 pc.printf("\tADC output = %u (%#06x)\n", adcValue[channel], adcValue[channel]);
adisuciu 0:61b289f9bab0 78 pc.printf("\tVoltage = %f mV\n", voltageValue[channel]);
adisuciu 0:61b289f9bab0 79 pc.printf("\tLight Intensity = %.2f lux\n", intensityValue[channel]);
adisuciu 0:61b289f9bab0 80 pc.printf("\tLight Concentration = %.2f%c\n", lightConcentration[channel], 37);
adisuciu 0:61b289f9bab0 81
adisuciu 0:61b289f9bab0 82 }*/
adisuciu 0:61b289f9bab0 83
adisuciu 0:61b289f9bab0 84
adisuciu 0:61b289f9bab0 85 for(channel = 0; channel < CHANNELS; channel++) {
adisuciu 0:61b289f9bab0 86
adisuciu 0:61b289f9bab0 87 pc.printf("\t\t\033[2;%dm%s\033[0m channel:\t\t", ColorPrint[channel], colour[channel]);
adisuciu 0:61b289f9bab0 88 }
adisuciu 0:61b289f9bab0 89
adisuciu 0:61b289f9bab0 90 pc.printf("\n");
adisuciu 0:61b289f9bab0 91 pc.printf("\t");
adisuciu 0:61b289f9bab0 92
adisuciu 0:61b289f9bab0 93 /*
adisuciu 0:61b289f9bab0 94 for(channel = 0; channel < CHANNELS; channel++) {
adisuciu 0:61b289f9bab0 95
adisuciu 0:61b289f9bab0 96 pc.printf("\t\t\tADC output = %u (%#06x)", adcValue[channel], adcValue[channel]);
adisuciu 0:61b289f9bab0 97 }
adisuciu 0:61b289f9bab0 98
adisuciu 0:61b289f9bab0 99 pc.printf("\n");
adisuciu 0:61b289f9bab0 100 pc.printf("\t");
adisuciu 0:61b289f9bab0 101
adisuciu 0:61b289f9bab0 102 */
adisuciu 0:61b289f9bab0 103 for(channel = 0; channel < CHANNELS; channel++) {
adisuciu 0:61b289f9bab0 104
adisuciu 0:61b289f9bab0 105 pc.printf("\t\tLight Intensity = %.2f lux", intensityValue[channel]);
adisuciu 0:61b289f9bab0 106 }
adisuciu 0:61b289f9bab0 107
adisuciu 0:61b289f9bab0 108 pc.printf("\n");
adisuciu 0:61b289f9bab0 109 pc.printf("\t");
adisuciu 0:61b289f9bab0 110
adisuciu 0:61b289f9bab0 111
adisuciu 0:61b289f9bab0 112 for(channel = 0; channel < CHANNELS; channel++) {
adisuciu 0:61b289f9bab0 113
adisuciu 0:61b289f9bab0 114 pc.printf("\t\tLight Concentration = %.2f%c", lightConcentration[channel], 37);
adisuciu 0:61b289f9bab0 115 }
adisuciu 0:61b289f9bab0 116
adisuciu 0:61b289f9bab0 117 pc.printf("\n");/*pc.printf("\t");
adisuciu 0:61b289f9bab0 118
adisuciu 0:61b289f9bab0 119 for(channel = 0; channel < CHANNELS; channel++) {
adisuciu 0:61b289f9bab0 120
adisuciu 0:61b289f9bab0 121 pc.printf("\t\t\tLight Concentration = %.2f%c", lightConcentration[channel], 37);
adisuciu 0:61b289f9bab0 122 }
adisuciu 0:61b289f9bab0 123
adisuciu 0:61b289f9bab0 124 pc.printf("\n");pc.printf("\t");
adisuciu 0:61b289f9bab0 125
adisuciu 0:61b289f9bab0 126 /* for(channel = 0; channel < CHANNELS; channel++){
adisuciu 0:61b289f9bab0 127
adisuciu 0:61b289f9bab0 128 pc.printf("\t\t\t\033[2;%dm|\033[0m\t", ColorPrint[channel]);
adisuciu 0:61b289f9bab0 129
adisuciu 0:61b289f9bab0 130 }*/
adisuciu 0:61b289f9bab0 131
adisuciu 0:61b289f9bab0 132 for(channel = 0; channel < 5; channel++) {
adisuciu 0:61b289f9bab0 133 pc.printf("\n");
adisuciu 0:61b289f9bab0 134 }
adisuciu 0:61b289f9bab0 135
adisuciu 0:61b289f9bab0 136 // pc.printf("\n");
adisuciu 0:61b289f9bab0 137 // pc.printf("\n");
adisuciu 0:61b289f9bab0 138 pc.printf("\n");
adisuciu 0:61b289f9bab0 139 }
adisuciu 0:61b289f9bab0 140
adisuciu 0:61b289f9bab0 141
adisuciu 0:61b289f9bab0 142 void CN0397::data_to_voltage(uint16_t adcValue, float *voltage)
adisuciu 0:61b289f9bab0 143 {
adisuciu 0:61b289f9bab0 144
adisuciu 0:61b289f9bab0 145 *voltage = (float)(adcValue * V_REF) / (float)(_2_16 * gainAdc);
adisuciu 0:61b289f9bab0 146
adisuciu 0:61b289f9bab0 147 }
adisuciu 0:61b289f9bab0 148
adisuciu 0:61b289f9bab0 149 void CN0397::init(void)
adisuciu 0:61b289f9bab0 150 {
adisuciu 0:61b289f9bab0 151 ad7798.reset();
adisuciu 0:61b289f9bab0 152 uint8_t channel;
adisuciu 0:61b289f9bab0 153
adisuciu 0:61b289f9bab0 154 if(ad7798.init()) {
adisuciu 0:61b289f9bab0 155
adisuciu 0:61b289f9bab0 156 ad7798.set_coding_mode(AD7798_UNIPOLAR);
adisuciu 0:61b289f9bab0 157 ad7798.set_mode(AD7798_MODE_SINGLE);
adisuciu 0:61b289f9bab0 158 ad7798.set_gain(ADC_GAIN);
adisuciu 0:61b289f9bab0 159 ad7798.set_filter(ADC_SPS);
adisuciu 0:61b289f9bab0 160 ad7798.set_reference(AD7798_REFDET_ENA);
adisuciu 0:61b289f9bab0 161
adisuciu 0:61b289f9bab0 162 }
adisuciu 0:61b289f9bab0 163
adisuciu 0:61b289f9bab0 164 gainAdc = Gain[ADC_GAIN];
adisuciu 0:61b289f9bab0 165 #ifdef USE_CALIBRATION
adisuciu 0:61b289f9bab0 166 pc.printf("Calibrate the system:\n");
adisuciu 0:61b289f9bab0 167 pc.printf("\n");
adisuciu 0:61b289f9bab0 168
adisuciu 0:61b289f9bab0 169 for(channel = 0; channel < CHANNELS; channel++) {
adisuciu 0:61b289f9bab0 170
adisuciu 0:61b289f9bab0 171 pc.printf("\tCalibrate channel %d: be sure that %s photodiode is cover and press <ENTER>.\n", (Channels[channel] + 1), colour[channel]);
adisuciu 0:61b289f9bab0 172 pc.getc();
adisuciu 0:61b289f9bab0 173 flush_serial();
adisuciu 0:61b289f9bab0 174 calibration(Channels[channel]);
adisuciu 0:61b289f9bab0 175 pc.printf("\t\tChannel %d is calibrated!\n", (Channels[channel] + 1));
adisuciu 0:61b289f9bab0 176 pc.printf("\n");
adisuciu 0:61b289f9bab0 177
adisuciu 0:61b289f9bab0 178 }
adisuciu 0:61b289f9bab0 179
adisuciu 0:61b289f9bab0 180 printf("System calibration complete!\n");
adisuciu 0:61b289f9bab0 181 printf("\n");
adisuciu 0:61b289f9bab0 182 printf("\n");
adisuciu 0:61b289f9bab0 183
adisuciu 0:61b289f9bab0 184 #endif
adisuciu 0:61b289f9bab0 185 }
adisuciu 0:61b289f9bab0 186
adisuciu 0:61b289f9bab0 187 void CN0397::calc_light_intensity(uint8_t channel, uint16_t adcValue, float *intensity)
adisuciu 0:61b289f9bab0 188 {
adisuciu 0:61b289f9bab0 189
adisuciu 0:61b289f9bab0 190 *intensity = adcValue * Lux_LSB[channel];
adisuciu 0:61b289f9bab0 191
adisuciu 0:61b289f9bab0 192 }
adisuciu 0:61b289f9bab0 193
adisuciu 0:61b289f9bab0 194 void CN0397::calc_light_concentration(uint8_t channel, float intensity, float *conc)
adisuciu 0:61b289f9bab0 195 {
adisuciu 0:61b289f9bab0 196
adisuciu 0:61b289f9bab0 197 *conc = (intensity * 100) / Optimal_Levels[channel];
adisuciu 0:61b289f9bab0 198
adisuciu 0:61b289f9bab0 199 }
adisuciu 0:61b289f9bab0 200
adisuciu 0:61b289f9bab0 201 void CN0397::set_app_data(void)
adisuciu 0:61b289f9bab0 202 {
adisuciu 0:61b289f9bab0 203 uint8_t channel, rgbChannel;
adisuciu 0:61b289f9bab0 204 uint16_t *adcData = &adcValue[0];
adisuciu 0:61b289f9bab0 205 float *voltageData = &voltageValue[0], *intensityData = &intensityValue[0];
adisuciu 0:61b289f9bab0 206 float *concData = &lightConcentration[0];
adisuciu 0:61b289f9bab0 207
adisuciu 0:61b289f9bab0 208 for(channel = 0; channel < CHANNELS; channel++) {
adisuciu 0:61b289f9bab0 209
adisuciu 0:61b289f9bab0 210 rgbChannel = Channels[channel];
adisuciu 0:61b289f9bab0 211
adisuciu 0:61b289f9bab0 212 ad7798.set_channel(channel);
adisuciu 0:61b289f9bab0 213
adisuciu 0:61b289f9bab0 214 adcData = &adcValue[rgbChannel];
adisuciu 0:61b289f9bab0 215 voltageData = &voltageValue[rgbChannel];
adisuciu 0:61b289f9bab0 216 intensityData = &intensityValue[rgbChannel];
adisuciu 0:61b289f9bab0 217 concData = &lightConcentration[rgbChannel];
adisuciu 0:61b289f9bab0 218 ad7798.read_data(channel, adcData);
adisuciu 0:61b289f9bab0 219 data_to_voltage(*adcData, voltageData);
adisuciu 0:61b289f9bab0 220 calc_light_intensity(rgbChannel, *adcData, intensityData);
adisuciu 0:61b289f9bab0 221 calc_light_concentration(rgbChannel, *intensityData, concData);
adisuciu 0:61b289f9bab0 222
adisuciu 0:61b289f9bab0 223 /* adcData++;
adisuciu 0:61b289f9bab0 224 voltageData++;
adisuciu 0:61b289f9bab0 225 intensityData++;
adisuciu 0:61b289f9bab0 226 concData++;*/
adisuciu 0:61b289f9bab0 227
adisuciu 0:61b289f9bab0 228 }
adisuciu 0:61b289f9bab0 229 }
adisuciu 0:61b289f9bab0 230
adisuciu 0:61b289f9bab0 231 void CN0397::calibration(uint8_t channel)
adisuciu 0:61b289f9bab0 232 {
adisuciu 0:61b289f9bab0 233
adisuciu 0:61b289f9bab0 234 uint16_t setValue;
adisuciu 0:61b289f9bab0 235
adisuciu 0:61b289f9bab0 236 ad7798.set_channel(channel); //select channel to calibrate
adisuciu 0:61b289f9bab0 237
adisuciu 0:61b289f9bab0 238 // Perform system zero-scale calibration
adisuciu 0:61b289f9bab0 239 setValue = ad7798.get_register_value(AD7798_REG_MODE, 2);
adisuciu 0:61b289f9bab0 240 setValue &= ~(AD7798_MODE_SEL(0x07));
adisuciu 0:61b289f9bab0 241 setValue |= AD7798_MODE_SEL(AD7798_MODE_CAL_SYS_ZERO);
adisuciu 0:61b289f9bab0 242 ad7798.set_register_value(AD7798_REG_MODE, setValue, 2);
adisuciu 0:61b289f9bab0 243
adisuciu 0:61b289f9bab0 244 while((ad7798.get_register_value( AD7798_REG_STAT, 1) & channel) != channel); // wait for RDY bit to go low
adisuciu 0:61b289f9bab0 245
adisuciu 0:61b289f9bab0 246 while(ad7798.get_register_value(AD7798_REG_MODE, 2) != 0x4005); // wait for ADC to go in idle mode
adisuciu 0:61b289f9bab0 247
adisuciu 0:61b289f9bab0 248
adisuciu 0:61b289f9bab0 249 }
adisuciu 0:61b289f9bab0 250
adisuciu 0:61b289f9bab0 251
adisuciu 0:61b289f9bab0 252
adisuciu 0:61b289f9bab0 253