牟曉東
眾所周知,高中物理本身就是一門實驗性極強的“燒腦”學科,但在實際的物理教學過程中仍存在很多使用傳統(tǒng)的手工測量方式來獲取實驗數據的現(xiàn)象,效率比較低,而且在增加更多的實驗誤差的同時還有可能會影響到最終物理實驗規(guī)律的歸納與總結。
如果根據不同的物理實驗特點引入開源硬件進行編程,可利用計算機的高速運算和傳感器的動態(tài)獲取實時實驗數據來降低操作難度和減小實驗誤差,而且也能夠極大地提高學生的學習興趣。以“勻加速直線運動”物理實驗為例,我們來嘗試使用樹莓派結合超聲波傳感器,通過Python編程和Plotly作“位移s-時間t”圖像,對勻加速直線運動進行探索研究。
實驗器材包括樹莓派3B+主板和古德微擴展板各一塊,HC-SR04超聲波傳感器一個,紅色LED燈一支,充電寶一個,實驗小車一個,1.2米滑軌一個,擋板一個,橡皮筋若干,墊腳物若干,橡皮一塊。
首先,將古德微擴展板正確安裝于樹莓派主板上;接著,將超聲波傳感器的四個引腳插入擴展板的20號和21號引腳,注意電源正極VCC端、接地GND端、Trig信號發(fā)射端及Echo信號接收端要一一對應;最后,將紅色LED燈按照“長腿正、短腿負”的原則插入12號引腳,并且借助于橡皮筋將樹莓派和充電寶捆綁于小車上,放置于滑軌起始端(前方用橡皮塞住車輪以防滑行);滑軌末端直立固定好擋板,作為超聲波傳感器的目標測試靶,滑軌起始端放置墊腳物,模擬不同坡度的光滑斜面(如圖1)。
“勻加速直線運動”實驗分若干次進行,每次不斷增加墊腳物來提高滑軌起始端的高度,相當于滑軌的光滑斜面傾角在不斷增加;每變化一次斜面的傾角,都控制小車從“坡頂”(滑軌起始端)由靜止開始下滑,作勻加速直線運動,直至運動到“坡底”(滑軌末端)。在整個運動過程中,樹莓派會控制超聲波傳感器不斷測試并記錄小車與擋板間的距離,同時也會標注每個位移數據所對應的時刻,并且將這些數據均寫入文件中進行保存;最后,編程讀取數據進行物理圖像的繪制,在分析物理實驗數據的過程中歸納和總結出勻加速直線運動的特點和規(guī)律。
使用數據線將樹莓派與充電寶連接,啟動其操作系統(tǒng)。運行Windows的“遠程桌面連接”程序,輸入樹莓派的IP地址(比如:192.168.1.113)進行連接,登錄成功后點擊“編程”-“ThonnyPythonIDE”菜單,開始Python代碼編程。
從gpiozero庫模塊中導入控制LED燈和超聲波傳感器的LED類和DistanceSensor類:“from gpiozero import LED,DistanceSensor”,導入time時間模塊用來控制循環(huán)的時間間隔:“import time”;導入csv模塊——“import csv”,作用是建立csv文件并向其中寫入實驗數據;再導入warnings模塊——“import warnings”,準備對程序運行時可能出現(xiàn)的“意外錯誤”提示代碼進行過濾屏蔽:“warnings.filterwarnings("ignore")”,即設置其為“忽略”狀態(tài),否則每次程序運行結束后都會出現(xiàn)“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”分別對應超聲波傳感器的信號回收端與發(fā)射端所插接的擴展板21號和20號引腳,“max_distance=4”是將超聲波傳感器的最大檢測距離設置為4米(不帶該參數的話,其測量的極限是1米的距離);建立變量X_Time,賦值為0:“X_Time = 0”,作用是設置實驗的第一個時刻點(即圖像的坐標原點);建立空列表Y_Dis:“Y_Dis = []”,準備用來存放實驗過程中與每一個時刻X_Time所對應的超聲波測距值,即“位移”。
在while循環(huán)中,每次都是先為變量dis進行賦值:“dis = round(sensor.distance,4)”,通過round()函數進行四舍五入處理,保留4位小數,單位是“米”,相當于精確到“毫米”;語句“Red_LED.off()”的作用是關閉紅色LED燈,結合下方if條件的選擇結構中的“Red_LED.on()”點亮LED燈,共同實現(xiàn)只有在有效測距時才會亮起紅色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)”的作用是控制每次循環(huán)測試的時間間隔均為0.05秒,同時再通過語句“X_Time += 0.05”將變量X_Time進行0.05的“自增”。
需要注意的是,在該“while…True…”循環(huán)中要建立與if條件判斷對應的else分支,其執(zhí)行語句只有“break”一行,作用是在dis變量處于“小于等于0.05米”的臨界盲區(qū)或“大于1.1米”的滑軌越界區(qū)時能夠“跳出”循環(huán)以中止無效實驗數據的采集,防止“死循環(huán)”的產生。
新建一個名為“data1.csv”的文件,并且準備以追加的方式進行數據的填充,同時加入參數“encoding='utf-8'”,防止在進行文件信息讀寫時出現(xiàn)漢字“亂碼”現(xiàn)象,參數“newline=''”的作用是防止在向csv文件寫數據時出現(xiàn)多余的空行問題:“with open('data1.csv','a',encoding='utf-8',newline='') as f:”。接著,通過csv模塊中的writer等函數進行數據寫入,其中的“writer.writerow(['Time','Distance'])”是寫入第一行的標題信息“Time”和“Distance”,對應的是時間和位移;再通過for循環(huán)開始將本次實驗的每組時間與位移的對應值寫到data1.csv文件中,循環(huán)的次數由range()函數來控制,其參數為“int(X_Time*20)”——因為每次循環(huán)的時間間隔是0.05秒;語句“writer.writerow([i/20,Y_Dis[i]])”的作用是將一個列表全部寫入csv文件的同一行,該列表包括時刻和對應的位移值;最后,通過“print("寫入csv文件結束!:)”打印輸出提示信息,并將程序代碼保存為“勻加速直線運動數據采集.py”(如圖2)。
先在滑軌起始端下方只放置一塊墊腳物,再點擊Run按鈕測試運行程序后再輕輕撤掉小車前方的阻塞橡皮,保證其由靜止狀態(tài)開始向滑軌末端作勻加速直線運動。當開始進行數據的記錄操作時,樹莓派上的紅色LED燈會發(fā)光提示,同時在程序下方也有“開始記錄數據:1.0113”等提示信息;直到小車運動至滑軌末端停止,紅色LED燈熄滅,程序提示:“開始寫入csv文件……”、“寫入csv文件結束!”。此時,在程序所在的文件夾中會新生成一個名為data1.csv的數據文件,調用Excel打開后就會看到有兩列數據,分別對應Time和Distance(如圖3)。
將Python程序代碼中的“with open”中的參數修改一下,比如先改為data2.csv;然后將滑軌起始端再增加一塊墊腳物,第二次測試運行該程序,會生成第二個csv實驗數據文件data2.csv;按照同樣的操作方式,持續(xù)進行六次實驗,最終得到從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的參數規(guī)則進行賦值:“l(fā)ine1 = 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()”進行圖像的繪制,點擊“運行”后就看到下方出現(xiàn)了位移-時間圖像(如圖4)。
與上述操作類似,新建文件“同時繪制data1-6實驗數據的多個圖像.ipynb”,同樣是導入相關的模塊并增加多個變量進行賦值,比如data2至data6、line2至line6,最后仍是通過語句“fig.show()”進行多個圖像的同時繪制,得到了六組實驗數據的對比顯示效果,均以不同顏色來區(qū)分(如圖5)。如果去除若干個無效實驗數據的話,這些圖像在一定程度上非常直觀地反映出了勻加速直線運動規(guī)律。
(1)嚴格而言,文中使用超聲波傳感器所測量并存儲的Dis變量值并非小車的直線運動位移數據,而是它與目標靶之間的直線距離值,也因此在最終畫出的位移-時間圖像中顯示的位移是隨時間增加而減小。如果將樹莓派連同超聲波傳感器在水平面上進行180°轉向,并且將擋板從滑軌末端移至起始端,這樣才會獲取到真正的小車勻加速直線運動的各個位移數據。
(2)為了減小實驗誤差,得到更為精準的數據與圖像,可考慮將滑軌的長度適當增加,比如延長至3米;同時再考慮對滑軌與水平面之間的夾角進行更為精確的控制,而不是僅僅通過粗略地增減墊腳物的數量來控制斜面的傾角,最終繪制出的位移-時間圖像就更具規(guī)律性。
(3)對于同樣的滑軌,其實還可以考慮在其上均勻鋪設光滑絲綢、長木塊條、粗糙毛巾等具有不同靜摩擦系數的各種物品,在固定或是改變斜面傾角的前提下進行若干次小車的勻加速直線運動對比實驗,從而繪制出各相關物理量的不同圖像。
(4)在“勻加速直線運動數據采集.py”程序的循環(huán)結構中,考慮到所使用的HC-SR04超聲波傳感器的測量頻率較低問題,同時又要兼顧數據采樣的“密度”,因此設置每個循環(huán)周期中的時間間隔值為50ms,設置太小的話就更容易導致HC-SR04超聲波傳感器“反應”不過來,從而產生更多的無效數據。如果條件允許,可嘗試使用US-100超聲波傳感器來取代HC-SR04超聲波傳感器,程序中的50ms便可以設置得更小些(比如25ms),同樣情況下數據的采樣率就會提高一倍,最終生成的圖像就顯得更“圓滑”、更漂亮。
(5)實驗數據的采集及圖像繪制的兩段Python代碼程序其實是可以進行“合并”的,最終實現(xiàn)實驗數據的獲取、存儲及作圖的“一條龍”式輸出,尤其是多種不同的實驗情況對應各自的數據存儲及圖像的動態(tài)生成。
(6)在實驗數據的采集時,Python程序是在循環(huán)結構中通過if語句判斷Dis的值是否在0.05米和1.1米之間((dis<=1.1000) and (dis>0.0500))來觸發(fā)數據的記錄的,如果在實驗器材中增加光電門、霍爾傳感器或是電磁開關,可以更加“硬性”地減少無效數據的記錄。
(7)在“勻加速直線運動”實驗器材的基礎上進行一定的改裝,可以非常快速地將其“變身”為打點計時器,通過超聲波傳感器與目標靶間的無接觸式極小空氣阻力運動方式,極大地減小傳統(tǒng)電磁打點計時器的探針與紙帶間的打點摩擦阻力因素,實驗數據自然會更加趨向于“理想狀態(tài)下”。
(8)如果增加第二個或更多個樹莓派進行物聯(lián)網編程式的實驗數據傳輸,實現(xiàn)不同實驗探究小組間或與教師間的信息共享,課堂教學的實驗操作效率會非常高,最終還可以在教師端根據各小組所傳輸的多組data.csv文件進行更多圖像的繪制對比與展示。
大家不妨一試。