将简单的Arduino Uno(以及一些Python代码)转换为粗略的示波器,以查看波形和电压电平。
示波器非常有用,但通常带有很大的价格标签。幸运的是,有一些专用示波器的替代方案,所以在这个项目中,我们将把一个简单的Arduino Uno(以及一些Python代码)转换成可以用来查看波形和电压电平的粗略示波器!
工作原理:Arduino
示波器的硬件/固件端非常简单,并利用内置的模块Arduino,ADC。 ADC代表模拟数字转换器,是一个可以采用模拟电压(0V和5V之间)并将其转换为二进制数的模块。 Arduino有一个10位ADC,这意味着最大电压5V表示为1023(1111111111),最小电压0V表示为0(0000000000)。但是,由于Arduino是一个8位机器,无符号字符的大小为8位(稍后你会看到原因),我们只使用ADC结果中的前8位。这意味着5V现在表示为255,0V表示为0V。由于有256个可能的值,每个位代表5/256伏或0.02V(大约)。因此,0x0F的值表示0.3V,0x80的值表示2.56V,值0x3E表示1.22V。
虽然Arduino默认启用ADC,因此不需要设置代码,但我们仍将模拟引脚配置为输入。我们将用于获取读数的引脚为A0,即引脚编号14.除引脚配置外,我们还将配置UART模块以实现PC通信的快速波特率(115200波特),并初始化一些变量。
主循环中的代码首先从ADC模块中读取100个读数。从ADC读取模拟数据非常简单,可以使用函数analogRead(引脚号)完成,该函数返回一个整数,其中10位ADC结果来自引脚号指定的引脚。在我们的例子中,input0指的是引脚14,它是A0。一旦读取完毕,下一段要执行的代码就是延迟。延迟的大小(以微秒为单位)由timeBase定义,默认为100。尽管是100us延迟,但读数之间的真实间距是延迟的大小加上ADC转换时间(100us),这给出了200us的读取间隔。为简单起见,这个项目将被忽略。
一旦完成所有100个读数,就可以将这些数据发送到PC用于绘图。为确保接收器能够正确区分数据事务,Arduino只会在Arduino发送请求“R?”后接收方发送字母“K”后发送数据。
一次Arduino和PC已经成功地相互交谈,所有的数据都流出来了。但是,UART工作在8位,并且尝试在UART上发送整数将需要复杂的转换,这将使事情变得相当困难。因此,我们只将模拟读数作为单个字节发送,我们使用函数highByte()来完成。 Arduino中的整数大小为16位,这意味着我们需要取10位结果并将它们向左移动,直到前8位包含我们的数据。为此,我们将数据向左移动六次,这意味着我们丢失了ADC读数的最低2位,但对于我们的基本示波器无关紧要。
使用8位结果发送,最后一项任务是等待计算机的响应通知Arduino结果已被正确读取。 Arduino只是停留在一个循环中,等待串口上的字符“K”。一旦读完,整个循环就会自行重复!
工作原理:Python代码
Python代码以及一些额外的库是什么一个简单的Arduino数据记录器到一个基本的示波器。但是,Python本身无法执行某些任务,如图形例程和串口通信,因此我们需要先获取几个库。幸运的是,如果安装了PIP,安装这些库是轻而易举的。如果你不这样做,请先在这里按照本教程获取点子。安装pip后,打开命令提示符并按顺序输入以下命令(一次一个):
pip install pyserial
pip install PyGame
一旦成功安装了这两个软件包,我们就可以直接进入我们的图形应用程序!虽然串行包很容易理解,但pygame包有点复杂,所以这里只介绍基础知识。我们Python程序的第一个任务是导入所需的库,它们是pygame(用于生成图形界面),serial(用于Arduino通信)和时间(用于时间延迟)。下一个代码块用于变量声明和初始化,其中包括pygame的布尔值,字符串和颜色。 pygame中使用的颜色是RGB类型,其中三个字节(0-255)表示红色,绿色和/或蓝色的数量。
完成变量定义后,下一个任务是初始化pygame,这是通过调用pygame.init()来完成的。由于我们计划将文本打印到我们的窗口应用程序,我们还需要初始化字体引擎,这是通过调用pygame.font.init()来完成的。除了初始化字体引擎之外,我们还将创建一个字体对象,我们将使用它作为渲染字体(将是等宽字体)。 pygame初始化代码的最后一位将是创建一个窗口(大小为700×500)并将窗口的标题设置为“PyScopeUno”。
下一个任务涉及配置串行端口以使用与Arduino相匹配的波特率(在本例中为115200)。还必须选择正确的端口(在我的情况下为“COM8”)并指定超时,以便程序在串行端口循环期间不会挂起。配置串口后,最后一步是打开端口!
完成所有初始化代码后,主程序循环执行,即以while循环的形式,等待直到布尔变量applicationClose等于true。在窗口上单击关闭按钮时,此值设置为true,单击后,串口正常关闭,pygame关闭。
显示我们记录的数据的第一项任务是从Arduino获取串行数据。为此,我们要等到串口中有数据存在。如果此数据等于“R?”,我们将Arduino发送给字符“K”,这导致Arduino将100个字节流式传输到PC。程序等待直到收到所有100个字节,一旦完成,将这些字节传送到数据缓冲区。下一行代码涉及一些有用的基本操作,包括计算平均值和查找最小/最大值。
最后代码块涉及绘制数据,绘制文本和绘制线条,但由于代码的不言自明的特性,不会对此进行深入讨论。我们的示波器程序中的数据不是绘制为单个点,而是作为两个数据点之间的插值线,因为快速变化的信号将显示为散点图,这很难可视化。为此,绘制一条线,其中第一个点是第一个电压电平,而终点是下一个数据值。由于我们获取了100个读数但我们的图形宽度为400像素,因此我们将x坐标乘以4以拉伸图形。这样可以更容易地查看单个读数。
完整的图形化程序如下所示。
在不到15分钟的时间内完成并运行这个项目应该很容易和可行。可能导致最头疼的步骤是安装和运行Python库,因为命令行安装方法有抛出错误,无法找到所需文件或缺少权限的习惯。一旦Arduino加载了代码,它就会自动开始。假设Python程序有效(确保COM端口正确),那么项目应该可以正常工作。
-
示波器
+关注
关注
113文章
6178浏览量
184410 -
Arduino
+关注
关注
187文章
6461浏览量
186569
发布评论请先 登录
相关推荐
评论