牟曉東
眾所周知,函數是程序設計語言的“基石”,即“組織好的、可重復使用的、用來實現單一或相關功能的代碼段”。Python本身提供了功能豐富的“內置函數”,可以在命令行模式中輸入“dir (__builtins__)”命令進行查看,例如求絕對值函數、求最大值和最小值函數,還包括input輸入和print輸出函數等(如圖1)。

此時,可以直接在命令行交互模式下使用內置函數,比如輸入“abs(-7)”來求解-7的絕對值,回車后就會返回數值7;輸入“max(0,6,-99,28)”求解四個數中的最大值,就會返回數值28。另外,Python還支持用戶根據自己的不同需求進行自定義函數操作,比如編寫一個能夠同時求解二數之和、之差的函數sum_sub():
def sum_sub(a,b):
return(a+b,a-b)
輸入“sum_sub(8,5)”進行測試,回車后就會返回兩個結果:13和3(如圖2)。

在開源硬件編程中使用Python可以靈活地控制各種周邊硬件,從而實現更為豐富的功能。我們在樹莓派中使用Python進行函數的自定義編寫,控制燈帶模仿現實生活中十字路口的紅綠燈,分別是單函數“帶參”的紅綠燈帶和雙函數“無參”的紅綠燈帶。
1.準備工作
將可編程ws281x燈帶通過古德微擴展板的18號接口與樹莓派連接,注意燈帶的三根引線分別標注+5V、GND和Din,不要接反。
在樹莓派中通過Python編程控制燈帶需要安裝rpi_ws281x庫模塊,因此需要通過“Windows的遠程桌面”連接樹莓派。在控制終端命令行模式中輸入命令:“sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel”,回車后等待進度條到達100%后會有“Successfully installed”的提示(如圖3)。

2.Python單函數“帶參”控制紅綠燈帶
(1)首先,以“ws”為別名導入rpi_ws281x庫:“import rpi_ws281x as ws”,再導入time庫中的sleep函數:“from time import sleep”;接著,設置燈帶中激活的“燈珠”數量LED_COUNT值為60:“LED_COUNT = 60”,燈帶接入的端口號LED_PIN是18號:“LED_PIN = 18”,并且創建燈帶對象strip,實例化PixelStrip,參數為LED_COUNT和LED_PIN:“strip = ws.PixelStrip(LED_COUNT, LED_PIN)”,語句“strip.begin()”的作用是對燈帶進行初始化。
(2)接下來自定義“帶參”(參數為color)的lights()函數:“def lights(color):”,注意后面有英文冒號。
(3)建立四分支選擇結構,特別要注意Python的“四空格”縮進。
第一分支為“if color == 'red':”,即函數參數為“red”時,使用循環結構控制60個燈珠全部發紅光,RGB值為(100,0,0);不要忘記對燈帶進行刷新操作:“strip.show()”。
第二和第三分支分別為“elif color == 'green':”和“elif color == 'yellow':”,即函數參數為“green”和“yellow”時,使用循環結構控制60個燈珠全部發綠光、黃光,RGB值分別為(0,100,0) 和(100,100,0);也要對燈帶進行刷新操作:“strip.show()”。
第四分支為“else:”,即函數參數為空字符串,控制60個燈珠全部熄滅,RGB值為(0,0,0)。
(4)主程序是一個“while True:”循環結構,通過傳遞不同的參數對lights()函數進行調用。先傳遞“green”參數亮綠燈:“lights('green')”,持續4秒鐘:“sleep(4)”;再建立執行三次的循環結構:“for i in range(3):”,傳遞參數為空字符串,關閉燈帶:“lights(' ')”,0.1秒后再次亮起綠燈:“lights('green')”,持續0.1秒后傳遞“yellow”參數亮黃燈:“lights('yellow')”;持續2秒后傳遞“red”參數亮紅燈:“lights('red')”,再持續5秒后結束本次循環;進入下一次循環:亮綠燈……
(5)保存程序為test_lights11.py,在命令行窗口中輸入命令“sudo python3 test_lights11.py”運行測試,一個燈帶式的“紅綠燈”開始工作起來,這就是Python單函數“帶參”紅綠燈帶(如圖4)。

3.Python雙函數“無參”控制紅綠燈帶
(1)第一部分庫模塊的導入和對燈帶進行初始化的代碼與剛才一致,直接復制和粘貼。整條燈帶的60個燈珠編號為0-59,將其均分為四組:0-14、15-29、30-44和45-59,其中的0-14和30-44對應“十字路口”的X方向,而15-29和45-59則對應Y方向。
(2)定義X方向上的x_lights()函數:“def x_lights():”:
第一部分的“for i in range(15)”“亮綠燈”(0,100,0)代碼,包括0-14、30-44兩組燈珠,注意30-44的表示方法是“i+30”,也就是同時控制X方向馬路正面和對面;不要忘記添加燈帶刷新代碼“strip.show()”,綠燈保持亮5秒:“sleep(5)”,省略了綠燈閃爍過程(可自行添加內循環來實現);
第二部分“亮黃燈”(100,100,0)代碼,復制粘貼后,只須改RGB顏色值即可,黃燈保持亮2秒:“sleep(2)”;
第三部分“亮紅燈”代碼,也是粘貼操作,改RGB值為(100,0,0),注意最后不必使用sleep()控制紅燈持續亮的時間。
(3)定義Y方向上的y_lights()函數:“def y_lights():”:
復制x_lights()函數粘貼為y_lights()函數,只修改三個循環結構中range()的參數為“15,30”即可,因為Y方向控制的是15-29、45-59兩組燈珠,同樣也是使用“i+30”來表示45-59。
兩個函數代碼編寫完畢,最后寫主程序的“while True:”循環結構,直接調用x_lights()和y_lights()即可。
保存程序為test_lights12.py,在命令行窗口中輸入命令“sudo python3 test_lights12.py”運行測試,模擬十字路口的四個方向紅綠燈工作過程:紅燈停、綠燈行,黃燈亮了等一等……這就是Python雙函數“無參”紅綠燈帶(如圖5)。
