构建一个开源动态光散射装置

描述

  让我们构建一个负担得起的开源动态光散射装置,用于纳米粒子尺寸测量!

  表征微米和纳米粒子的大小在许多应用中很重要,例如蛋白质聚集和复杂流体研究。对于大于约一微米的颗粒,光学显微镜可以与图像分析软件结合使用。然而,对于亚微米颗粒,必须采用更先进和更昂贵的技术,例如电子显微镜或光散射。特别是动态光散射(DLS) 广泛用于稀释颗粒悬浮液。在 DLS 中,当粒子在流体中经历布朗运动时,从激光束散射的光随时间演变的方式反向计算粒子大小。典型的商业 DLS 设备价格昂贵,因为使用了高质量的激光器和检测器,可以在广泛的颗粒尺寸和浓度范围内进行测量。最近的一些设备甚至可以确定非球形颗粒的形状。

  与昂贵的商业设备相比,该项目旨在通过低成本组件和开源设计探索 DLS 原则和边界。更广泛地说,我们希望这种方法也有助于未来涉及光散射或高频数据记录的项目。

  介绍

  动态光散射的工作原理如下(见下图):激光束照射到样品上并被粒子散射到各个方向(假设粒子尺寸小于激光波长)。散射光从光束以特定角度(此处为 90°)收集。来自不同粒子的光子会干扰检测器以产生特定的强度。由于溶液中的粒子经历布朗运动,因此收集的强度随时间变化,然后大小可以从强度时间序列中解卷积。

检测器

  从透明溶液中以大角度收集的光线非常暗淡,因此现代 DLS 设备使用昂贵的组件,例如高强度激光器和单光子探测器,以提高其信噪比并在几分钟内实现准确测量。这对于倾向于散射较少光的最小粒子(几纳米)至关重要。此外,小颗粒在溶液中移动得更快,需要高频信号采样(高达 100 kHz)。该项目的目的是探索具有可访问组件的 DLS 技术的技术边界,代价是更长的测量时间、有限的精度和减小的粒度范围。

  测量的内容

  首先将研究溶液中表征良好的高分子量蛋白质(光谱蛋白)和纤维(纤维素)。然后将研究其他类型的胶体系统,例如牛奶和牛奶替代品。

  硬件设计目标

  安全- 机箱完全封闭系统。如果外壳被意外打开,激光将关闭。

  可用性- 易于测量样品。

  成本- 经济实惠的组件和 3D 打印外壳。

  便携性 -该设备将围绕通过 USB 端口连接到 PC 的 Arduino 板构建,发送强度时间序列。该软件将用 Python 编写。

  项目实施

  外壳和组装

  下图显示了设备的部件。您可能需要根据您的硬件调整某些部件。

检测器

  顶板和底板是由不透明的片材激光切割而成。我们在比色杯室内使用白色 PMMA 并喷涂黑色亚光漆。直接从深色哑光材料上切割应该是更好的选择。其他部分是用黑色 PLA 3D 打印的。散热器用双面胶带固定。一个散热器用作光束停止器,处于倾斜位置以将未吸收的光束引导出比色皿腔室。另一个散热器放置在激光模块旁边,这里的效率相对较低。

  激光与安全

检测器

  注意:直接观察激光二极管发射可能会导致眼睛损伤。必须格外小心,以防止直接或通过反射观察光束。戴上适合波长的防护眼镜。如果同一个房间里有其他人,他们也应该穿戴防护用品。

  项目使用 Thorlabs 的 650nm 4.5mW 激光模块 CPS650F ,尽管可能有更便宜的替代品。但我使用它的主要原因是它的一个优点,带有一个集成的电流驱动器和一个聚焦光学器件。我们只需要提供 5V 电压,由于最大电流为 60mA,我们可以使用 Arduino 的 Vcc(或 5V)端口。

  在正常模式下,该设备应在完整的激光器外壳下运行(如 CD 播放器)。为了校准和聚焦激光,我们使用了 Thorlabs 的 LG4 眼镜和一张白纸。激光器与松动的激光器支架的螺钉对齐。后期底座上的孔足够大,可以提供一些灵活性。光束应聚焦在比色皿的中心。

检测器

  在下图中,光束在轻微浑浊的水中可见。

检测器

  光探测器

  这部分可能是该项目中最具挑战性的部分。

  选项 1 - 光敏电阻

检测器

  Biomaker 挑战包配有 Open-Smart 的分线板光传感器。我们对其进行了测试,尽管它的响应速度惊人(高达 20 kHz),但它的灵敏度却低了两个。

  选项 2 - Grove 数字光传感器

检测器

  另一个与 Arduino 兼容的光传感器。它带有一个集成的 ADC,但我们发现采样率在库代码中是有限的。目前尚不清楚为什么,我们决定选择下一个选项:

  选项 3 - 带有定制电路的光电二极管

检测器

  光电二极管在接收光时会产生小电流。以下跨阻抗电路用于将该电流转换为 Arduino 可读的(大部分)放大电压信号:

检测器

  在光伏模式下(左),二极管没有施加偏置电压。偏置用于减小二极管的电容,从而增加带宽(右)。增益由反馈电阻控制Rf。较大的 Rf 意味着较大的增益,但非常大的电阻器往往具有不可忽略的固有电容。电容器Cf用于稳定运算放大器,但会降低带宽。

  组成:

  光电二极管:BPW24R;

  运算放大器:TLC082IP

  在光伏模式下,Rf = 1 至 10 MOhm,Cf = 无。我们无法使光电二极管在偏置模式下工作。

  为了测试探测器,我们在其前面放置了一个 LED(此阶段无需使用激光),并带有一个扩散器以避免光电二极管饱和。函数发生器以指定频率的方波信号驱动 LED,检测器的输出电压由 Arduino 采样。

检测器

  我们采用 15 微秒的时间步长(67 kHz 采样)。理论上,我们可以采样 33 kHz 的信号,但是对于 5 kHz 的信号,我们每个周期会获得更多的点。第一个发现是 5 MOhm Rf 电阻的电容太大,我们可以看到:

检测器

  使用 1 MOhm Rf 电阻,我们得到一个较弱但尖锐的方波:

检测器

  所以我们选择 Rf = 1 MOhm,并且由于我们的运算放大器有两个通道,我们使用第二个通道进一步放大。第二个通道前面有一个高通滤波器,以消除与第一个通道的偏移。更好的系统将使用具有零偏移功能的运算放大器,对数电位器用于调整第二级的增益。然后使用低通滤波器来抑制 ADC 无法处理的高频。

检测器

  Rf1 = 1 MOhm, CHP = 220 nF, RHP = 47 kOms, Rf2 = 0-50 kOhm, R0 = 10 Ohm, RLP = 100 Ohm, CLP=47nF,

  如果我们在 LED 前面放置一个更强的扩散器,我们不会从第一个通道得到任何东西,但我们会从第二个通道得到一个有点失真的信号:

检测器

  能够调整增益也很重要,因为各种解决方案样本会以不同的幅度散射光。

  缺少的最后一部分是探测器的光学器件。目前它从一个相当宽的角度(12°)收集光,但目前尚不清楚它是否对系统有显着影响。

  从检测器采样数据

  我们将尝试仅使用 Arduino 功能对大约 67 kHz 的光电二极管信号进行采样。默认情况下,Arduino Uno 可以在 10kHz 左右进行采样,而无需考虑串行通信引起的开销。所以需要一些工作来加快速度。幸运的是,网上有很多例子。Willem Maes 的这份详尽文档可以提供帮助:magelhaes.hzs.be/willem/Arduino/speeding.pdf 。我们可以在三个层面采取行动:

  首先,ADC(模数转换器)时钟默认设置为比 ATmega 低得多的速度。我们可以在代码中更改时钟速度。

  其次,ADC 可以在自由运行模式下使用,在这种模式下,ADC 会不断地转换输入,从而节省函数调用开销。

  第三,在调用串行通信发送器之前,将值存储在缓冲区中(此处为 16 位的 800 个值)。缓冲区的大小受芯片上可用内存的限制。这里 800 个值可以在 67kHz 采样 12ms。

  目前第一点和第三点已经落实。下图显示了由函数发生器产生的 20 kHz 方波,并由 Arduino 通过引脚 A0 进行采样,并analogRead以 8.5 微秒 (117 kHz) 的时间步长运行。

检测器

  const unsigned int numReadings = 800;

unsigned int analogVals[numReadings];
long t, t0;

然后我们改变 ADC 的时钟速度。我们还设置了串口:

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
  
void setup() {
 Serial.begin(115200);
 // set prescale to 16
 sbi(ADCSRA, ADPS2) ; // cbi means clear bit
 cbi(ADCSRA, ADPS1) ; // sbi means set bit
 cbi(ADCSRA, ADPS0) ;
}

主循环从收集 800 个点开始,然后将表格发送analogVals到计算机,以时间序列的总持续时间 ( t) 结束。

void loop() {
 t0 = micros();
 for (int i=0; i < numReadings ; i++)
 {
   analogVals[i] = analogRead(A0);
 }
 t = micros()-t0;  // calculate elapsed time
 // Send to computer
 for (int i=0; i < numReadings ; i++)
 {
   Serial.print(analogVals[i]);
   Serial.print(',');
 }
 Serial.println(t);
 delay(10);

分析数据
我们使用安装了一些库(serial、numpy、matplotlib 和 scipy)的 Python。要使用该脚本,请使用文本编辑器打开它并检查变量的定义(特别是 Arduino 地址和与您的实验条件相关的所有内容)。

address='/dev/ttyUSB0'  # Arduino address
baud=115200             # baud for serial communication
lambd = 650e-9          # [m] Laser wavelength
n_s = 1.33              # Solvent refractive index at wavelength
k = 1.380649e-23        # [j/k] Boltzmann constant
T = 293                 # [K] Temperature
eta_s = 0.001           # [Pa.s] Solvent viscosity measurement at T
theta = np.pi/2         # Scattering angle 

  然后在终端中启动,后跟要从设备获取的时间序列数(默认为一个):

  python2 OpenDLS.py 1

  让我们看看我们的第一个信号。使用增益后,我们得到一条嘈杂的曲线,但低频变化很大:

检测器

  在这个阶段,尚不清楚峰值是否是由于灰尘颗粒反射光束造成的。此外,自相关函数有一个有趣的尾巴:这是因为时间序列不够长,无法对长弛豫时间进行重要统计。

  为了改善这一点,我们平均进行了 1000 多次测量;

  python2 OpenDLS.py 1000

检测器

  现在尾巴是固定的,虽然它仍然很吵。我们准备好分析数据了!

  对于单分散球体,自相关函数应该是一个递减指数,因此我们拟合 a,b和c:

  g(tau) = a + b*exp(-c*tau)

  c理论上是 2* q ** 2* D 。q是散射矢量:

  q = 4*pi* n_s *sin( theta /2)/ lambda ,n_s是溶剂的折射率,theta是散射角,lambda是激光的波长。

  D是来自斯托克斯-爱因斯坦关系的粒子的扩散系数:

  D = k*T /(6*pi* Rh * eta_s ),其中k是玻尔兹曼常数,T是温度,Rh是粒子的流体动力学半径,eta_s是溶剂的粘度。

  以 200nm 聚苯乙烯分散体为例

  我们有一个标准的 188 (+/-4) nm 聚苯乙烯珠,2.2% 在水中的质量 (Sigma-Aldrich 95581),它像牛奶一样白色和不透明。当稀释至 0.01% 质量分散度时,我们会得到一种透明但略微混浊的液体,它将足够的光散射到检测器。下图是 1000 个时间序列的平均值:

检测器

  我们拟合了 167 nm 的粒径,噪声包含在 +/-20% 的窗口中(在曲线的斜率处)。

  对颗粒大小和强噪声的系统性低估可能来自光束在到达检测器之前的多次散射。这可以通过稀释样品来改善,但是检测会更难,因为我们在这里玩的是我们系统的限制。

  对更多时间序列进行平均无助于减少噪声,正如我们从这 10,000 个平均值中看到的那样,需要 45 分钟才能完成:

检测器

  理想情况下,我们需要用其他粒度重复这个实验,看看我们观察到的相关性是否真的来自液体,而不是来自硬件。

  结论

  这种开源 DLS 设备对于将足够的光散射到廉价检测器的分散体来说似乎非常有前途,尽管准确度仍然很低。我们希望一些构建块和代码对其他项目有用。

  关于 DLS,未来可能的拓展:

  盖子打开时自动关闭激光。

  用于透明解决方案的更好检测器(具有零偏移功能的运算放大器、雪崩模式或盖革模式的光电二极管、用于选择精确散射角的孔径针孔系统)。

  温度探头,用于调节配合中的温度和粘度。

  使用电流检测器,研究来自混浊液体的反向散射光。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分