在前面的文章中我們學會了如何在Pico/Pico W中利用SSD1306這個微型顯示器來輸出文字,也利用pixel函式繪製了一個SIN函數圖形,那麼,我們在資料收集的過程中,如果想要把這些資料的內容以折線圖的方式呈現出來,該如何編寫程式呢?我們這篇文章就來教同學們如何在SSD1306繪製資料折線圖。
想要在SSD1306繪製折線圖有兩個重要的地方,第一個是瞭解如何在SSD1306繪製直線。參考前面的文章說明,在建立了SSD1306的物件disp之後,使用disp.text(str, x, y)可以輸出文字,disp.pixel(x, y, 1)可以在指定座標繪製一個像素,而disp.line(x1, y1, x2, y2, 1)則可以在(x1, y1)-(x2, y2)之間繪製一條直線,我們要使用的就是這個功能。
第二個要知道的是,要繪製折線圖使用的資料點。由於SSD1306的解析度在x軸為128點,也就是0~127,可以得知這樣以螢幕的寬度最多可以繪製128個資料點。此外,在y軸的部份,由於解析度只有64,而上方我們還想要顯示一些文字,所以可以使用的範圍以不超過螢幕的一半為原則,也就是說,資料能夠顯示的範圍需控制在0~32之間。
在這個例子中,我們打算把感測到亮度的光敏電阻所取得的數值換算成百分比,然後把這個比例除以 2.5,讓它可以呈現的範圍約略在30之內(如果更暗一點可能會超出範圍,但是很暗的時候通常我們不會觀察這個螢幕,所以就以正常的環境亮度範圍來看,換算後大約是30%~90%之間)。從感測器中取得的數值都放在data這個串列中,但是當串列中的資料項目數量超過128時,就把第0個項目拋棄,再增加新的項目,讓串列的個數維持在128個以內。
每次取得資料之後,就把所有目前取得的數值資料從第0個開始繪製,用line把每一個點連接起來,就可以得到動態的折線圖了,如下圖所示:
程式碼如下所示:
from machine import ADC, Pin, I2C
import time
import ssd1306
i2c = I2C(0, sda=Pin(16), scl=Pin(17))
disp = ssd1306.SSD1306_I2C(128, 64, i2c)
temp_sensor = ADC(1)
light_sensor = ADC(0)
data = list()
while True:
val = temp_sensor.read_u16()
light = light_sensor.read_u16()
temp = round((val/65536) * 3.3 * 100, 2)
light = 100-round(light/65536*100,2)
if len(data)<=128:
data.append(light/2.5)
else:
del data[0]
data.append(light/2.5)
disp.fill(0)
disp.text('NKUST CCET', 0, 0)
disp.text('Min-Huang Ho', 0, 8)
disp.text("{}C, {}%".format(temp, light), 0, 16)
x, y, py = 0, 70, 70-int(data[0])
for i, t in enumerate(data):
y = 70-int(t)
disp.line(x, py, x, y, 1)
x += 1
py = y
disp.show()
以下是動態的執行效果展示: