9017| 12
|
[项目] 分光光度计实验-光谱传感器 |
本帖最后由 柳春晓 于 2020-11-3 17:01 编辑 这篇文章中我将带大家使用光谱传感器来做一个简易的分光光度计,通过数据采集、拟合曲线等操作,最终实现能将水中的溶解物质的浓度显示出来。 一、背景介绍首先来给大家介绍一下分光光度计和光谱传感器是什么。 1.分光光度计分光光度计:又称光谱仪,主要由光源、单色器、样品室、检测器、信号处理器和显示与存储系统组成。当我们用他来测量一个液体中含有某物质的浓度时,由于很多物质是有吸光性的,而且不同物质吸收的光谱(颜色)是不同的,利用这些特性就可以鉴别出液体中含有某种物质的浓度。 光源和单色器:真实的光度计光源使用的是钨光灯,然后用棱镜作为单色器将钨光灯的光折射,得到由红、橙、黄、绿、蓝、靛、紫组成的连续色谱。我们为了实验的简单性,直接使用一个普通的红色LED灯来模拟光源。 剩下的,样品室我们使用的是比色皿,某宝3RMB/个;检测器就是我们的光谱传感器;信号处理单元使用UNO控制器 2.光谱传感器AS7341可见光传感器,采用业内知名的ams公司推出的新一代AS7341光谱传感IC。该传感器有8个可见光通道、1个闪烁通道、1个NIR通道和1个未加滤光片的通道。该传感器拥有6个独立的16位ADC通道,可以并行的处理数据。可检测F1(405-425nm)、F2(435-455nm)、F3(470-490nm)、F4(505-525nm)、F5(545-565nm)、F6(580-600nm)、F7(620-640nm)、F8(670-690nm)八个波段的波长强度。 3.设备安装需要准备: Arduino UNO - 1 Arduino扩展板 - 1 光谱传感器 - 1 红色LED灯 - 1 比色皿 - 1 显示器 - 1 3D打印外壳 - 1 烧杯 - 6(或其他容器) 染料(或其他溶于水的物质) 由于组装比较简单,这里就不一步步展示安装过程了,组装完成后: 二、调试光谱传感器将LED灯的正负极对应接到板子的正负极上点亮小灯,光谱传感器按照上图连接,然后烧录代码: [mw_shl_code=cpp,false]/*! * @file getData.ino * @brief 读取光谱传感器10个光通道的数值,光源的某波长的光越多,对应通道的数值越大 * * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com) * @licence The MIT License (MIT) * @author [fengli](li.feng@dfrobot.com) * @version V1.0 * @date 2020-07-16 * @get from https://www.dfrobot.com * @url https://github.com/DFRobot/DFRobot_AS7341 */ #include "DFRobot_AS7341.h" /*! * @brief Construct the function * @param pWire IC bus pointer object and construction device, can both pass or not pass parameters, Wire in default. */ DFRobot_AS7341 as7341; void setup(void) { Serial.begin(115200); //检测IIC是否能正常通信 while (as7341.begin() != 0) { Serial.println("IIC初始化失败,请检测连线是否正确"); delay(1000); } // //Integration time = (ATIME + 1) x (ASTEP + 1) x 2.78µs // //设置寄存器ATIME的值,通过该值可计算Integration time的值,该值表示读取数据过程中必须要消耗的时间 // as7341.setAtime(29); // //设置ASTEP寄存器的值,通过该值可计算Integration time的值,该值表示读取数据过程中必须要消耗的时间 // as7341.setAstep(599); // //设置增益(0~10对应 X0.5,X1,X2,X4,X8,X16,X32,X64,X128,X256,X512) // as7341.setAGAIN(7); // //使能LED // //as7341.enableLed(true); // //设置引脚电流控制亮度(1~20对应电流 4mA,6mA,8mA,10mA,12mA,......,42mA) // //as7341.controlLed(10); } void loop(void) { DFRobot_AS7341::sModeOneData_t data1; DFRobot_AS7341::sModeTwoData_t data2; //开始光谱的测量. //通道映射的模式 :1.eF1F4ClearNIR,2.eF5F8ClearNIR as7341.startMeasure(as7341.eF1F4ClearNIR); //读取传感器数据通道0~5的值,eF1F4ClearNIR模式下. data1 = as7341.readSpectralDataOne(); Serial.print("F1(405-425nm):"); Serial.println(data1.ADF1); Serial.print("F2(435-455nm):"); Serial.println(data1.ADF2); Serial.print("F3(470-490nm):"); Serial.println(data1.ADF3); Serial.print("F4(505-525nm):"); Serial.println(data1.ADF4); //Serial.print("Clear:"); //Serial.println(data1.ADCLEAR); //Serial.print("NIR:"); //Serial.println(data1.ADNIR); as7341.startMeasure(as7341.eF5F8ClearNIR); //读取传感器数据通道0~5的值,eF5F8ClearNIR模式下. data2 = as7341.readSpectralDataTwo(); Serial.print("F5(545-565nm):"); Serial.println(data2.ADF5); Serial.print("F6(580-600nm):"); Serial.println(data2.ADF6); Serial.print("F7(620-640nm):"); Serial.println(data2.ADF7); Serial.print("F8(670-690nm):"); Serial.println(data2.ADF8); Serial.print("Clear:"); Serial.println(data2.ADCLEAR); Serial.print("NIR:"); Serial.println(data2.ADNIR); delay(1000); }[/mw_shl_code] 在比色皿中什么都没加入的情况下,打开串口监视器后,可以观察到数据中,F7波段的光强度最高,因此我们将采用F7波段光的强度作为参考,记录F7的数据。 三、实验接下来我们通过一个实验来记录几组数据。需要准备6个烧杯(或其他容器),一些染料。 1.将6个烧杯中都倒入100ml的清水准备好 2.将染料按照一定比例加入6个清水的烧杯中,第一杯不加,第二杯加入1滴,第三杯加入2滴,第四杯加入3滴,第五杯加入4滴,第六杯加入5滴。 3.将6个烧杯中的溶液搅拌好,分别倒入到比色皿中进行数据测量,为保证数据准确性,每一次更换溶液时要将比色皿清洗干净,并将测量出的数据记录到excel表格中。 四、分析数据通过观察数据,我们可以看到随着染料浓度越来越高,F7的强度就变得越来越低,我们假设每滴入一滴染料会使浓度增加15%,所以我们的六次数据可以拟合成一条浓度0%-75%的曲线。接下来我们就在Excel中将这条曲线拟合出来。 1.首先选中浓度一行的数据,然后选中F7一行的数据,最后点击创建散点图。 2.在出现的散点图中任选一点右键,选择添加趋势线,趋势线选项选择一个最贴合数据点的曲线,最后显示公式,这样就可以得到最终拟合出的公式了。我获得的公式是:y = 2E-06x2 - 0.0257x + 70.525。 五、屏幕直接显示未知的浓度将上一步的公式直接带入到代码中,在代码中添加代码:*outdata=(0.000002data2.ADF7data2.ADF7-0.0257data2.ADF7+70.525);** 然后加入对应的显示屏的库文件,以及修改显示部分的代码,教程最后的附件中会给出最终的代码和需要的库。 [mw_shl_code=cpp,false]#include "DFRobot_AS7341.h" #include <DFRobot_SSD1306_I2C.h> const chCode chBuf[] = { {0x6d53,0xe6b593,0xC5A8,{0x00,0x40,0x20,0x40,0x10,0x40,0x17,0xfc,0x84,0x84,0x48,0x88,0x41,0x40,0x11,0x44,0x13,0x48,0x25,0x30,0xe9,0x20,0x21,0x10,0x21,0x08,0x21,0x44,0x21,0x82,0x01,0x00}}, {0x5ea6,0xe5baa6,0xB6C8,{0x01,0x00,0x00,0x80,0x3f,0xfe,0x22,0x20,0x22,0x20,0x3f,0xfc,0x22,0x20,0x22,0x20,0x23,0xe0,0x20,0x00,0x2f,0xf0,0x24,0x10,0x42,0x20,0x41,0xc0,0x86,0x30,0x38,0x0e}} }; DFRobot_AS7341 as7341; DFRobot_SSD1306_I2C oled12864; double outdata; void setup(void) { Serial.begin(115200); oled12864.begin(0x3c); //检测IIC是否能正常通信 while (as7341.begin() != 0) { Serial.println("IIC初始化失败,请检测连线是否正确"); delay(1000); } } void loop(void) { DFRobot_AS7341::sModeOneData_t data1; DFRobot_AS7341::sModeTwoData_t data2; //开始光谱的测量. //通道映射的模式 :1.eF1F4ClearNIR,2.eF5F8ClearNIR as7341.startMeasure(as7341.eF1F4ClearNIR); //读取传感器数据通道0~5的值,eF1F4ClearNIR模式下. data1 = as7341.readSpectralDataOne(); Serial.print("F1(405-425nm):"); Serial.println(data1.ADF1); Serial.print("F2(435-455nm):"); Serial.println(data1.ADF2); Serial.print("F3(470-490nm):"); Serial.println(data1.ADF3); Serial.print("F4(505-525nm):"); Serial.println(data1.ADF4); //Serial.print("Clear:"); //Serial.println(data1.ADCLEAR); //Serial.print("NIR:"); //Serial.println(data1.ADNIR); as7341.startMeasure(as7341.eF5F8ClearNIR); //读取传感器数据通道0~5的值,eF5F8ClearNIR模式下. data2 = as7341.readSpectralDataTwo(); Serial.print("F5(545-565nm):"); Serial.println(data2.ADF5); Serial.print("F6(580-600nm):"); Serial.println(data2.ADF6); Serial.print("F7(620-640nm):"); Serial.println(data2.ADF7); Serial.print("F8(670-690nm):"); Serial.println(data2.ADF8); Serial.print("Clear:"); Serial.println(data2.ADCLEAR); Serial.print("NIR:"); Serial.println(data2.ADNIR); delay(1000); outdata=(0.000002*data2.ADF7*data2.ADF7-0.0257*data2.ADF7+70.525); Serial.print("浓度:"); Serial.println(outdata); oled12864.setChCode(chBuf); oled12864.setCursor(1, 1); oled12864.print("浓度"); oled12864.setCursor(110, 1); oled12864.print("%"); oled12864.setCursor(40, 1); oled12864.print(outdata); }[/mw_shl_code] 最后我随意混合了一些溶液装入了比色皿中 将比色皿放入我们的仪器中,可以通过屏幕直接读取到溶液的浓度 |
wcm_e45 发表于 2020-10-13 15:39 这个需要做实验,不确定他们的光谱吸收特性。 不过这是一个非常好的想法,建议实际的测一下。 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed