树莓派物理实验

2022-07-05 23:54牟晓东
电脑报 2022年25期
关键词:树莓超声波小车

牟晓东

众所周知,高中物理本身就是一门实验性极强的“烧脑”学科,但在实际的物理教学过程中仍存在很多使用传统的手工测量方式来获取实验数据的现象,效率比较低,而且在增加更多的实验误差的同时还有可能会影响到最终物理实验规律的归纳与总结。

如果根据不同的物理实验特点引入开源硬件进行编程,可利用计算机的高速运算和传感器的动态获取实时实验数据来降低操作难度和减小实验误差,而且也能够极大地提高学生的学习兴趣。以“匀加速直线运动”物理实验为例,我们来尝试使用树莓派结合超声波传感器,通过Python编程和Plotly作“位移s-时间t”图像,对匀加速直线运动进行探索研究。

实验器材包括树莓派3B+主板和古德微扩展板各一块,HC-SR04超声波传感器一个,红色LED灯一支,充电宝一个,实验小车一个,1.2米滑轨一个,挡板一个,橡皮筋若干,垫脚物若干,橡皮一块。

首先,将古德微扩展板正确安装于树莓派主板上;接着,将超声波传感器的四个引脚插入扩展板的20号和21号引脚,注意电源正极VCC端、接地GND端、Trig信号发射端及Echo信号接收端要一一对应;最后,将红色LED灯按照“长腿正、短腿负”的原则插入12号引脚,并且借助于橡皮筋将树莓派和充电宝捆绑于小车上,放置于滑轨起始端(前方用橡皮塞住车轮以防滑行);滑轨末端直立固定好挡板,作为超声波传感器的目标测试靶,滑轨起始端放置垫脚物,模拟不同坡度的光滑斜面(如图1)。

“匀加速直线运动”实验分若干次进行,每次不断增加垫脚物来提高滑轨起始端的高度,相当于滑轨的光滑斜面倾角在不断增加;每变化一次斜面的倾角,都控制小车从“坡顶”(滑轨起始端)由静止开始下滑,作匀加速直线运动,直至运动到“坡底”(滑轨末端)。在整个运动过程中,树莓派会控制超声波传感器不断测试并记录小车与挡板间的距离,同时也会标注每个位移数据所对应的时刻,并且将这些数据均写入文件中进行保存;最后,编程读取数据进行物理图像的绘制,在分析物理实验数据的过程中归纳和总结出匀加速直线运动的特点和规律。

使用数据线将树莓派与充电宝连接,启动其操作系统。运行Windows的“远程桌面连接”程序,输入树莓派的IP地址(比如:192.168.1.113)进行连接,登录成功后点击“编程”-“ThonnyPythonIDE”菜单,开始Python代码编程。

从gpiozero库模块中导入控制LED灯和超声波传感器的LED类和DistanceSensor类:“from gpiozero import LED,DistanceSensor”,导入time时间模块用来控制循环的时间间隔:“import time”;导入csv模块——“import csv”,作用是建立csv文件并向其中写入实验数据;再导入warnings模块——“import warnings”,准备对程序运行时可能出现的“意外错误”提示代码进行过滤屏蔽:“warnings.filterwarnings("ignore")”,即設置其为“忽略”状态,否则每次程序运行结束后都会出现“warnings.warn(DistanceSensorNoEcho('no echo received'))”的红色代码错误提示,虽不影响程序运行但比较令人讨厌。

建立变量Red_LED,其值对应插入扩展板12号引脚的红色LED灯:“Red_LED = LED(12)”;建立变量sensor,通过语句“sensor = DistanceSensor(echo=21,trigger=20,max_distance=4)”对HC-SR04超声波传感器的类进行实例化,其中的“echo=21”和“trigger=20”分别对应超声波传感器的信号回收端与发射端所插接的扩展板21号和20号引脚,“max_distance=4”是将超声波传感器的最大检测距离设置为4米(不带该参数的话,其测量的极限是1米的距离);建立变量X_Time,赋值为0:“X_Time = 0”,作用是设置实验的第一个时刻点(即图像的坐标原点);建立空列表Y_Dis:“Y_Dis = []”,准备用来存放实验过程中与每一个时刻X_Time所对应的超声波测距值,即“位移”。

在while循环中,每次都是先为变量dis进行赋值:“dis = round(sensor.distance,4)”,通过round()函数进行四舍五入处理,保留4位小数,单位是“米”,相当于精确到“毫米”;语句“Red_LED.off()”的作用是关闭红色LED灯,结合下方if条件的选择结构中的“Red_LED.on()”点亮LED灯,共同实现只有在有效测距时才会亮起红色LED灯作为提示;根据实验器材的参数,将超声波传感器的“有效测距”限制为0.05-1.1米之间:“((dis<=1.1000)and (dis>0.0500))”,亮灯的同时还会在屏幕下方通过print语句来输出提示信息:“print("开始记录数据:",dis)”;语句“Y_Dis.append(dis)”的作用是将每次测试获取的dis位移值通过追加的方式保存至Y_Dis列表中,语句“time.sleep(0.05)”的作用是控制每次循环测试的时间间隔均为0.05秒,同时再通过语句“X_Time += 0.05”将变量X_Time进行0.05的“自增”。

需要注意的是,在该“while…True…”循环中要建立与if条件判断对应的else分支,其执行语句只有“break”一行,作用是在dis变量处于“小于等于0.05米”的临界盲区或“大于1.1米”的滑轨越界区时能够“跳出”循环以中止无效实验数据的采集,防止“死循环”的产生。

新建一个名为“data1.csv”的文件,并且准备以追加的方式进行数据的填充,同时加入参数“encoding='utf-8'”,防止在进行文件信息读写时出现汉字“乱码”现象,参数“newline=''”的作用是防止在向csv文件写数据时出现多余的空行问题:“with open('data1.csv','a',encoding='utf-8',newline='') as f:”。接着,通过csv模块中的writer等函数进行数据写入,其中的“writer.writerow(['Time','Distance'])”是写入第一行的标题信息“Time”和“Distance”,对应的是时间和位移;再通过for循环开始将本次实验的每组时间与位移的对应值写到data1.csv文件中,循环的次数由range()函数来控制,其参数为“int(X_Time*20)”——因为每次循环的时间间隔是0.05秒;语句“writer.writerow([i/20,Y_Dis[i]])”的作用是将一个列表全部写入csv文件的同一行,该列表包括时刻和对应的位移值;最后,通过“print("写入csv文件结束!:)”打印输出提示信息,并将程序代码保存为“匀加速直线运动数据采集.py”(如图2)。

先在滑轨起始端下方只放置一块垫脚物,再点击Run按钮测试运行程序后再轻轻撤掉小车前方的阻塞橡皮,保证其由静止状态开始向滑轨末端作匀加速直线运动。当开始进行数据的记录操作时,树莓派上的红色LED灯会发光提示,同时在程序下方也有“开始记录数据:1.0113”等提示信息;直到小车运动至滑轨末端停止,红色LED灯熄灭,程序提示:“开始写入csv文件……”、“写入csv文件结束!”。此时,在程序所在的文件夹中会新生成一个名为data1.csv的数据文件,调用Excel打开后就会看到有两列数据,分别对应Time和Distance(如图3)。

将Python程序代码中的“with open”中的参数修改一下,比如先改为data2.csv;然后将滑轨起始端再增加一块垫脚物,第二次测试运行该程序,会生成第二个csv实验数据文件data2.csv;按照同样的操作方式,持续进行六次实验,最终得到从data1.csv到data6.csv共六个实验数据文件。

将六个csv文件全部复制至data文件夹,运行Jupyter并新建文件“绘制data1实验数据的单个图像.ipynb”。首先,导入plotly和pandas模块:“import plotly”、“import pandas as pd”;点击“运行”按钮后再将data1.csv中的数据读取进来:“data1 = pd.read_csv('data/data1.csv')”,此时可通过“data1.head()”语句来查看该csv文件中的前五条数据内容(包括Time和Distance标题)。

接着,导入plotly模块中的graph_objects:“import plotly.graph_objects as go”,建立变量line1并按照pltly的参数规则进行赋值:“line1 = go.Scatter(x=data1['Time'],y=data1['Distance'],name='第一次实验')”;然后,建立变量fig并指定其画图对象为line1:“fig = go.Figure(line1)”,再进行画图布局的更新:“fig.update_layout(title = "位移-时间图像",xaxis_title = "时间:t(s)",yaxis_title = "位移:s(m)")”,包括图像的标题名称、X和Y两个坐标轴的显示名称等信息;最后,通过语句“fig.show()”进行图像的绘制,点击“运行”后就看到下方出现了位移-时间图像(如图4)。

与上述操作类似,新建文件“同时绘制data1-6实验数据的多个图像.ipynb”,同样是导入相关的模块并增加多个变量进行赋值,比如data2至data6、line2至line6,最后仍是通过语句“fig.show()”进行多个图像的同时绘制,得到了六组实验数据的对比显示效果,均以不同颜色来区分(如图5)。如果去除若干个无效实验数据的话,这些图像在一定程度上非常直观地反映出了匀加速直线运动规律。

(1)严格而言,文中使用超声波传感器所测量并存储的Dis变量值并非小车的直线运动位移数据,而是它与目标靶之间的直线距离值,也因此在最终画出的位移-时间图像中显示的位移是随时间增加而减小。如果将树莓派连同超声波传感器在水平面上进行180°转向,并且将挡板从滑轨末端移至起始端,这样才会获取到真正的小车匀加速直线运动的各个位移数据。

(2)为了减小实验误差,得到更为精准的数据与图像,可考虑将滑轨的长度适当增加,比如延长至3米;同时再考虑对滑轨与水平面之间的夹角进行更为精确的控制,而不是仅仅通过粗略地增减垫脚物的数量来控制斜面的倾角,最终绘制出的位移-时间图像就更具规律性。

(3)对于同样的滑轨,其实还可以考虑在其上均匀铺设光滑丝绸、长木块条、粗糙毛巾等具有不同静摩擦系数的各种物品,在固定或是改变斜面倾角的前提下进行若干次小车的匀加速直线运动对比实验,从而绘制出各相关物理量的不同图像。

(4)在“匀加速直線运动数据采集.py”程序的循环结构中,考虑到所使用的HC-SR04超声波传感器的测量频率较低问题,同时又要兼顾数据采样的“密度”,因此设置每个循环周期中的时间间隔值为50ms,设置太小的话就更容易导致HC-SR04超声波传感器“反应”不过来,从而产生更多的无效数据。如果条件允许,可尝试使用US-100超声波传感器来取代HC-SR04超声波传感器,程序中的50ms便可以设置得更小些(比如25ms),同样情况下数据的采样率就会提高一倍,最终生成的图像就显得更“圆滑”、更漂亮。

(5)实验数据的采集及图像绘制的两段Python代码程序其实是可以进行“合并”的,最终实现实验数据的获取、存储及作图的“一条龙”式输出,尤其是多种不同的实验情况对应各自的数据存储及图像的动态生成。

(6)在实验数据的采集时,Python程序是在循环结构中通过if语句判断Dis的值是否在0.05米和1.1米之间((dis<=1.1000) and (dis>0.0500))来触发数据的记录的,如果在实验器材中增加光电门、霍尔传感器或是电磁开关,可以更加“硬性”地减少无效数据的记录。

(7)在“匀加速直线运动”实验器材的基础上进行一定的改装,可以非常快速地将其“变身”为打点计时器,通过超声波传感器与目标靶间的无接触式极小空气阻力运动方式,极大地减小传统电磁打点计时器的探针与纸带间的打点摩擦阻力因素,实验数据自然会更加趋向于“理想状态下”。

(8)如果增加第二个或更多个树莓派进行物联网编程式的实验数据传输,实现不同实验探究小组间或与教师间的信息共享,课堂教学的实验操作效率会非常高,最终还可以在教师端根据各小组所传输的多组data.csv文件进行更多图像的绘制对比与展示。

大家不妨一试。

猜你喜欢
树莓超声波小车
超声波诊断甲状腺结节的临床应用观察
追车
积木小车
蝙蝠的超声波
去修理厂
黄金水果红树莓
树莓红了 游人醉了
蝙蝠的超声波
e络盟率先推出第三代树莓派
年度睡姿大盘点(下)