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

Revision:
0:61b289f9bab0
Child:
1:77eb0888c15a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CN0397.cpp	Mon Nov 07 15:57:44 2016 +0000
@@ -0,0 +1,253 @@
+/**
+*   @file     CN0397.cpp
+*   @brief    Source file for the CN0397
+*   @author   Analog Devices Inc.
+*
+* For support please go to:
+* Github: https://github.com/analogdevicesinc/mbed-adi
+* Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers
+* Product: www.analog.com/EVAL-CN0397-ARDZ
+* More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all
+
+********************************************************************************
+* Copyright 2016(c) Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*  - Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*  - Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in
+*    the documentation and/or other materials provided with the
+*    distribution.
+*  - Neither the name of Analog Devices, Inc. nor the names of its
+*    contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*  - The use of this software may or may not infringe the patent rights
+*    of one or more patent holders.  This license does not release you
+*    from the requirement that you obtain separate licenses from these
+*    patent holders to use this software.
+*  - Use of the software either in source or binary form, must be run
+*    on or directly connected to an Analog Devices Inc. component.
+*
+* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+********************************************************************************/
+
+#include "CN0397.h"
+#include "AD7798.h"
+#include "Timer.h"
+#include <stdio.h>
+#include <math.h>
+#include <mbed.h>
+
+extern Serial pc;
+
+
+void flush_serial()
+{
+    wait_ms(10); // wait for all data to come through
+    while (pc.readable())  pc.getc();
+}
+
+
+CN0397::CN0397(PinName cs) : ad7798(cs)
+{
+
+}
+void CN0397::display_data(void)
+{
+
+    uint8_t channel = 0, i;
+
+    /* for(channel = 0; channel < CHANNELS; channel++){
+
+        pc.printf("%s (channel %d):\n", colour[channel], (channel + 1));
+        pc.printf("\tADC output = %u (%#06x)\n", adcValue[channel], adcValue[channel]);
+        pc.printf("\tVoltage = %f mV\n", voltageValue[channel]);
+        pc.printf("\tLight Intensity = %.2f lux\n", intensityValue[channel]);
+        pc.printf("\tLight Concentration = %.2f%c\n", lightConcentration[channel], 37);
+
+     }*/
+
+
+    for(channel = 0; channel < CHANNELS; channel++) {
+
+        pc.printf("\t\t\033[2;%dm%s\033[0m channel:\t\t", ColorPrint[channel], colour[channel]);
+    }
+
+    pc.printf("\n");
+    pc.printf("\t");
+
+    /*
+    	for(channel = 0; channel < CHANNELS; channel++) {
+
+    		pc.printf("\t\t\tADC output = %u (%#06x)", adcValue[channel], adcValue[channel]);
+    	}
+
+    	pc.printf("\n");
+    	pc.printf("\t");
+
+    */
+    for(channel = 0; channel < CHANNELS; channel++) {
+
+        pc.printf("\t\tLight Intensity = %.2f lux", intensityValue[channel]);
+    }
+
+    pc.printf("\n");
+    pc.printf("\t");
+
+
+    for(channel = 0; channel < CHANNELS; channel++) {
+
+        pc.printf("\t\tLight Concentration = %.2f%c", lightConcentration[channel], 37);
+    }
+
+    pc.printf("\n");/*pc.printf("\t");
+
+	for(channel = 0; channel < CHANNELS; channel++) {
+
+		pc.printf("\t\t\tLight Concentration = %.2f%c", lightConcentration[channel], 37);
+	}
+
+	pc.printf("\n");pc.printf("\t");
+
+	/* for(channel = 0; channel < CHANNELS; channel++){
+
+             pc.printf("\t\t\t\033[2;%dm|\033[0m\t", ColorPrint[channel]);
+
+     }*/
+
+    for(channel = 0; channel < 5; channel++) {
+        pc.printf("\n");
+    }
+
+    //  pc.printf("\n");
+    //  pc.printf("\n");
+    pc.printf("\n");
+}
+
+
+void CN0397::data_to_voltage(uint16_t adcValue, float *voltage)
+{
+
+    *voltage = (float)(adcValue * V_REF) / (float)(_2_16 * gainAdc);
+
+}
+
+void CN0397::init(void)
+{
+    ad7798.reset();
+    uint8_t channel;
+
+    if(ad7798.init()) {
+
+        ad7798.set_coding_mode(AD7798_UNIPOLAR);
+        ad7798.set_mode(AD7798_MODE_SINGLE);
+        ad7798.set_gain(ADC_GAIN);
+        ad7798.set_filter(ADC_SPS);
+        ad7798.set_reference(AD7798_REFDET_ENA);
+
+    }
+
+    gainAdc = Gain[ADC_GAIN];
+#ifdef USE_CALIBRATION
+    pc.printf("Calibrate the system:\n");
+    pc.printf("\n");
+
+    for(channel = 0; channel < CHANNELS; channel++) {
+
+        pc.printf("\tCalibrate channel %d: be sure that %s photodiode is cover and press <ENTER>.\n", (Channels[channel] + 1), colour[channel]);
+        pc.getc();
+        flush_serial();
+        calibration(Channels[channel]);
+        pc.printf("\t\tChannel %d is calibrated!\n", (Channels[channel] + 1));
+        pc.printf("\n");
+
+    }
+
+    printf("System calibration complete!\n");
+    printf("\n");
+    printf("\n");
+
+#endif
+}
+
+void CN0397::calc_light_intensity(uint8_t channel, uint16_t adcValue, float *intensity)
+{
+
+    *intensity = adcValue * Lux_LSB[channel];
+
+}
+
+void CN0397::calc_light_concentration(uint8_t channel, float intensity, float *conc)
+{
+
+    *conc = (intensity * 100) / Optimal_Levels[channel];
+
+}
+
+void CN0397::set_app_data(void)
+{
+    uint8_t channel, rgbChannel;
+    uint16_t *adcData = &adcValue[0];
+    float *voltageData = &voltageValue[0], *intensityData = &intensityValue[0];
+    float *concData = &lightConcentration[0];
+
+    for(channel = 0; channel < CHANNELS; channel++) {
+
+        rgbChannel = Channels[channel];
+
+        ad7798.set_channel(channel);
+
+        adcData = &adcValue[rgbChannel];
+        voltageData = &voltageValue[rgbChannel];
+        intensityData = &intensityValue[rgbChannel];
+        concData = &lightConcentration[rgbChannel];
+        ad7798.read_data(channel, adcData);
+        data_to_voltage(*adcData, voltageData);
+        calc_light_intensity(rgbChannel, *adcData, intensityData);
+        calc_light_concentration(rgbChannel, *intensityData, concData);
+
+        /*    adcData++;
+            voltageData++;
+            intensityData++;
+            concData++;*/
+
+    }
+}
+
+void CN0397::calibration(uint8_t channel)
+{
+
+    uint16_t setValue;
+
+    ad7798.set_channel(channel);  //select channel to calibrate
+
+    // Perform system zero-scale calibration
+    setValue = ad7798.get_register_value(AD7798_REG_MODE, 2);
+    setValue &= ~(AD7798_MODE_SEL(0x07));
+    setValue |= AD7798_MODE_SEL(AD7798_MODE_CAL_SYS_ZERO);
+    ad7798.set_register_value(AD7798_REG_MODE, setValue, 2);
+
+    while((ad7798.get_register_value( AD7798_REG_STAT, 1) & channel) != channel); // wait for RDY bit to go low
+
+    while(ad7798.get_register_value(AD7798_REG_MODE, 2) != 0x4005);    // wait for ADC to go in idle mode
+
+
+}
+
+
+
+