步骤1:技术注意事项
Arduino Uno和Nano的一个缺点是它没有数字信号 - 模拟(DAC)转换器,因此无法直接在引脚上输出模拟电压。一种解决方案是R2R梯形图:8个数字引脚连接到电阻网络,因此可以达到256级输出。通过直接端口访问,Arduino可以通过一个命令同时设置8个引脚。对于电阻网络,需要9个值为R的电阻,8个值为2R的电阻。我使用10kOhm作为R的值,它将引脚的电流保持在0.5mA或更低。我猜R = 1kOhm也可以工作,因为Arduino可以轻松地为每个引脚提供5mA电流,每端口40mA。重要的是R和2R电阻之间的比率确实为2.通过将2个R值的电阻串联起来,总共25个电阻最容易实现。
相位累加器
生成波形然后重复向Arduino引脚重复发送一系列8位数字。波形存储在256字节的数组中,并对该阵列进行采样并发送到引脚。输出信号的频率取决于通过阵列前进的速度。一个强大,精确和优雅的方法是使用相位累加器:32位数字以固定间隔递增,我们使用8个最高有效位作为数组的索引。
快速采样
中断允许在明确定义的时间采样,但中断的开销将采样频率限制在~100kHz。无限循环更新相位,采样波形并设置引脚需要42个时钟周期,从而实现16MHz/42 = 381kHz的采样率。旋转或推动旋转编码器会导致引脚更改和从环路中断的中断以更改设置(波形或频率)。在此阶段,重新计算阵列中的256个数字,以便不需要在主循环中执行波形的实际计算。可以产生的绝对最大频率是190kHz的一半,但是每个周期只有两个样本,因此对形状的控制不大。因此,接口不允许将频率设置在100kHz以上。在50kHz时,每个周期有7-8个采样,并且在1.5kHz和低于所有存储在阵列中的256个数据每个周期都被采样。对于信号平滑变化的波形,例如正弦波,跳过样本没有问题。但对于具有窄尖峰的波形,例如占空比较小的方波,存在这样的危险:对于高于1.5 kHz的频率,单个样本丢失会导致波形表现不尽如人意
频率的准确度
每个样本相位递增的次数与频率成正比。因此,频率可以设置为381kHz/2 ^ 32 = 0.089mHz的精度。实际上,几乎不需要这种精度,因此界面限制以1mHz的步长设定频率。频率的绝对精度由Arduino时钟频率的精度决定。这取决于Arduino类型,但大多数指定频率为16.000MHz,因此精度为~10 ^ -4。该代码允许修改频率和相位增量的比率,以校正16MHz假设的小偏差。
缓冲和放大
电阻网络具有高输出阻抗,因此如果负载是,则其输出电压会快速下降连接。这可以通过缓冲或放大输出来解决。这里,缓冲和放大是用运算放大器完成的。我使用的是LM358,因为我有一些。它是一个慢速运算放大器(压摆率为每微秒0.5V),因此在高频和高幅度时信号会失真。一个好处是它可以处理非常接近0V的电压。然而,输出电压限制在低于轨道约2V,因此使用+ 5V功率将输出电压限制为3V。升压模块结构紧凑,价格低廉,为运算放大器提供+ 20V电压,可产生电压高达18V的信号。 (注意,原理图说LTC3105,因为那是我在Fritzing中发现的唯一升级。实际上我使用的是MT3608模块,请参阅后续步骤中的图片)。我选择对R2R DAC的输出应用可变衰减,然后使用其中一个运算放大器缓冲信号而不放大,另一个放大5.7,这样信号可以达到约20V的最大输出。输出电流相当有限,约为10mA,因此如果信号要驱动大型扬声器或电磁铁,则可能需要更强的放大器。
步骤2:所需组件
核心波形发生器
Arduino Uno或Nano
16x2 LCD显示屏+ 20kOhm微调和100欧姆用于背光的串联电阻器
5针旋转编码器(带集成按钮)
25个10kOhm电阻
用于缓冲器/放大器
LM358或其他双运算放大器
升压模块基于MT3608
50kOhm可变电阻
10kOhm电阻
47kOhm电阻
1μF电容
步骤3:构造
我在7x9cm原型板上焊接了所有东西,如图所示。由于所有电线都有点乱,我试着给带正电压红色的引线和带黑色的引线涂上颜色。
我使用的编码器有5个引脚,一边是3个,2个是另一边。有3个引脚的一侧是实际的编码器,带有2个引脚的一侧是集成按钮。在3引脚侧,中央应接地,另外两个接到D10和D11。在2引脚侧,一个引脚应连接到地,另一个应连接到D12。
这是我做过的最丑陋的事情,但它有效。放入一个外壳会很好,但是现在额外的工作和成本并没有真正证明它的合理性。 Nano和显示器附有针头。如果我要建一个新的,我不会再那样做了。我没有在板上放置连接器来拾取信号。相反,我用突出的铜线上的鳄鱼引线拾取它们,标记如下:
R - 来自R2R DAC的原始信号
B - 缓冲信号
A - 放大信号
来自引脚9的T - 定时器信号
G - 接地
+ - 来自升压的正“高”电压模块
步骤4:代码
代码是一个Arduino草图,附上并应上传到Arduino。
已有20个波形预定义。添加任何其他wave应该是直截了当的。请注意,随机波填充具有随机值的256值数组,但每个周期都会重复相同的模式。真正的随机信号听起来像噪声,但这种波形听起来更像是哨声。
该代码在引脚D9上用TIMER1设置1kHz信号。这对于检查模拟信号的时序非常有用。这就是我如何计算时钟周期数为42:如果我假设41或43,并产生1kHz信号,它显然与引脚D9上的信号具有不同的频率。使用值42,它们完全匹配。
通常,Arduino每毫秒都会中断以使用millis()函数跟踪时间。这会干扰准确的信号生成,因此禁用特定的中断。
编译器说:“Sketch使用7254字节(23%)的程序存储空间。最大值为30720字节。全局变量使用483字节(23%)动态内存,为局部变量留下1565个字节。最大为2048个字节。“因此,有足够的空间可以使用更复杂的代码。
步骤5:用法
只需通过Arduino的mini-USB线缆即可为设备供电纳米。最好使用移动电源,这样它就不会与可能连接的设备发生意外的接地回路。
接通电源时会产生100Hz的正弦波。通过旋转旋钮,可以选择其他20种波形中的一种。通过按下旋转,可以将光标设置为频率的任何数字,然后可以将其更改为所需的值。
可以使用电位计调节振幅,也可以使用缓冲器或可以使用放大的信号。
使用示波器检查信号幅度非常有用,特别是当信号向另一个设备提供电流时。如果汲取的电流太大,信号将被削波并且信号严重失真
对于非常低的频率,输出可以通过LED与10kΩ电阻串联来显示。用扬声器可以听到音频。确保将信号设置为非常小~0.5V,否则电流过高,信号开始削波。
-
波形发生器
+关注
关注
3文章
290浏览量
31378 -
Arduino
+关注
关注
188文章
6468浏览量
186951
发布评论请先 登录
相关推荐
评论