新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 樹莓派RP2350-桌面動(dòng)態(tài)溫濕度計(jì)

樹莓派RP2350-桌面動(dòng)態(tài)溫濕度計(jì)

作者:無垠的廣袤 時(shí)間:2025-06-28 來源:EEPW 收藏


本文引用地址:http://www.2s4d.com/article/202506/471813.htm

1   RP2350-桌面動(dòng)態(tài)

本文介紹了DFRobot Beetle RP2350開發(fā)板結(jié)合DHT11模塊、鋰電池模塊、隨機(jī)眨眼動(dòng)畫,實(shí)現(xiàn)OLED 顯示的桌面動(dòng)態(tài)的項(xiàng)目設(shè)計(jì)。

2   項(xiàng)目介紹

本項(xiàng)目包括如下。

工作原理:ADC電壓采集與電量轉(zhuǎn)換

工程調(diào)試:電量獲取、電量圖標(biāo)顯示、DHT11溫濕度顯示、OLED眨眼動(dòng)畫

工程代碼:合并調(diào)試代碼,實(shí)現(xiàn)完整的項(xiàng)目設(shè)計(jì)功能

效果演示:幀動(dòng)畫顯示、動(dòng)態(tài)展示

最終實(shí)現(xiàn)桌面動(dòng)態(tài)的制作。

3 工作原理

根據(jù)開發(fā)板原理圖可知,電池VBAT的分壓電路與主控的GPIO29模擬接口相連,因此通過該引腳可實(shí)時(shí)采集監(jiān)測(cè)電池電壓信息,進(jìn)而實(shí)現(xiàn)電量顯示。

1751097964544899.png

4   硬件連接

GP0->DATA(DHT11)

GP4->SDA(OLED)

GP5->SCL(OLED)

BAT->Battery Positive

GND->Battery Negative

5   示意圖

1751098020985209.png

6   工程調(diào)試

包括ADC電量采集、電量的OLED顯示、DHT11溫濕度數(shù)據(jù)和電量圖標(biāo)的顯示、眨眼動(dòng)畫等調(diào)試項(xiàng)目。

7   電量獲取

通過ADC 讀取GPIO29 電壓值并終端打印

8  代碼

view plaincopy to clipboardprint?

1.from machine import Pin, ADC

2.import utime

3.

4.#initialize ADC pin

5.adc = ADC(Pin(29))

6.

7.#parameters for voltage divide resistor

8.R1, R2=1000000, 1000000

9.DIV_RATIO=(R1 + R2)/R1

10.

11.def get_battery_level():

12.adc_value = adc.read_u16()

13.voltage = (adc_value / 65535) * 3.3

14.actual_voltage = voltage * DIV_RATIO # voltage division compensation

15.percent=min(max((actual_voltage - 3.3) / (4.2-3.3) *100, 0), 100)

16.return percent, actual_voltage

17.

18.while True:

19.    percent, voltage = get_battery_level()

20.    print(‘Battery Voltage: {:.2f} V, Battery Level: {:.1f}%’.format(voltage,percent))

21.    utime.sleep(1)

保存代碼,連接開發(fā)板,配置解釋器并運(yùn)行。

9 效果

終端打印ADC 采集的電池電壓值以及電量百分比

image.png

10   電量顯示

OLED顯示ADC采集的電量百分比。

11   代碼

view plaincopy to clipboardprint?

1.from machine import Pin, ADC, I2C

2.import ssd1306

3.import utime

4.

5.#initialize ADC pin

6.adc=ADC(Pin(29))

7.

8.#initialize OLED

9.i2c=I2C(0, scl=Pin(5), sda=Pin(4))

10.oled=ssd1306.SSD1306_I2C(128, 64, i2c)

11.

12.#parameters of voltage divide resistor

13.R1, R2=1000000, 1000000 # 1M

14. Vref_BAT=3.9#battery voltage in full charged state

15.

16.def get_battery_level():

17.    adc_value = adc.read_u16()

18.    voltage = (adc_value / 65535) * 3.3

19.    DIV_RATIO = (R1 + R2) / R1

20.    actual_voltage = voltage * DIV_RATIO # voltage division compensation

21.    percent=min(max((actual_voltage - 3.3) /(Vref_BAT - 3.3) * 100, 0), 100)

22.    return percent, actual_voltage

23.

24.def draw_battery(percent):

25.    oled.fill(0)

26.    oled.text(‘{:.0f}%’.format(percent), 0, 17)

27.    # draw battery cartoon icon

28.    oled.rect(0, 0, 30, 15, 1)  # frame (x,y,width,height)

29.    oled.rect(30, 5, 3, 5, 1)    # anode

30.    oled.fill_rect(2, 2, int(26 * percent / 100), 11, 1) # electric percent column

31.    oled.rotate(0)

32.    oled.show()

33.

34.def BAT_display(percent,x,y): # battery percent,icon position (x,y)

35.    oled.fill(0)

36.    oled.text(‘{:.0f}%’.format(percent), 0+x, 17+y)

37.    # draw battery cartoon icon

38.    oled.rect(0+x, 0+y, 30, 15, 1)    # frame (x,y,width,height)

39.    oled.rect(30+x, 5+y, 3, 5, 1)       # anode

40.    oled.fill_rect(2+x, 2+y, int(26 * percent / 100),11, 1)    # electric percent column

41.    oled.rotate(0)

42.    oled.show()

43.

44.def draw_vertical_battery(percent,x,y):   # battery percent, icon position (x,y)

45.    oled.fill(0)

46.    oled.text(‘{:.0f}’.format(percent), 0+x, 33+y)

47.    # draw battery cartoon icon

48.    oled.rect(0+x, 2+y, 15, 30, 1)    # frame (x,y,width,height)

49.    oled.rect(5+x, 0+y, 5, 3, 1)         # anode

50.    fill_h = int(27 * percent / 100)

51.    oled.fill_rect(2+x, 2 + (28 - fill_h) + y, 11, fill_h, 1)   # percent column

52.    oled.rotate(0)

53.    oled.show()

54.

55.while True:

56.    percent, voltage = get_battery_level()

57.    #draw_battery(percent)

58.    BAT_display(percent,90,2)

59.    #draw_vertical_battery(percent,90,9)

60.    print(‘Battery Voltage: {:.2f} V, Battery Level:{:.1f}%’.format(voltage,percent))

61.    utime.sleep(2)

保存代碼,連接開發(fā)板,配置解釋器并運(yùn)行。

12   效果

電量圖標(biāo)的水平顯示

1751098336641707.png

量圖標(biāo)的豎直顯示

1751098374755203.png

13   DHT11溫濕度計(jì)

帶電量顯示的DHT11溫濕度計(jì)

14   代碼

view plaincopy to clipboardprint?

1.from machine import Pin, ADC, I2C

2.from PicoDHT22 import PicoDHT22

3.import ssd1306

4.import utime

5.

6.#initialize ADC pin

7.adc = ADC(Pin(29))

8.

9.#initialize OLED

10.i2c=I2C(0, scl=Pin(5), sda=Pin(4))

11.oled=ssd1306.SSD1306_I2C(128, 64, i2c)

12.

13.#parameters of voltage divide resistor

14.R1, R2 = 1000000, 1000000

15.Vref_BAT = 3.81    # battery voltage in full charged state

16.

17.def get_battery_level():

18.     adc_value = adc.read_u16()

19.     voltage = (adc_value / 65535) * 3.3

20.    DIV_RATIO = (R1 + R2) / R1

21.    actual_voltage = voltage * DIV_RATIO    # voltage division compensation

22.    percent = min(max((actual_voltage - 3.3) /(Vref_BAT - 3.3) * 100, 0), 100)

23.    return percent, actual_voltage

24.

25.def draw_battery(percent):

26.    oled.fill(0)

27.    oled.text(‘{:.0f}%’.format(percent), 90, 27)

28.    # draw battery cartoon icon

29.    oled.rect(90, 10, 30, 15, 1) # frame

30.    oled.rect(120, 15, 3, 5, 1) # anode

31.    oled.fill_rect(92, 12, int(26 * percent / 100),11, 1)   # electric percent column

32.    oled.show()

33.

34.def BAT_display(percent):

35.    oled.fill(0)

36.    oled.text(‘{:.0f}%’.format(percent), 90, 27)

37.    # draw battery cartoon icon

38.    oled.rect(90, 10, 30, 15, 1) # frame

39.    oled.rect(120, 15, 3, 5, 1) # anode

40.    oled.fill_rect(92, 12, int(26 * percent / 100), 11, 1)

41.    oled.show()

42.

43.def draw_vertical_battery(percent,x,y):

44.    #局部清屏并顯示電量百分比

45.    oled.fill_rect(x,y,15+8,30+16,0)

46.    oled.text(‘{:.0f}’.format(percent), 0+x, 33+y)

47.    #豎版電池繪制

48.    oled.rect(0+x, 2+y, 15, 30, 1)    # frame (x,y,width,height)

49.    oled.rect(5+x, 0+y, 5, 3, 1)         # anode

50.    fill_h = int(26 * percent / 100)

51.    oled.fill_rect(2+x, 2 + (28 - fill_h) + y, 11, fill_h, 1) # percent column

52.    oled.rotate(0)

53.     oled.show()

54.

55. def display_TH(temp,humi):

56.    oled.fill_rect(20,15,6*8,64-15,0)   #局部清屏

57.    oled.text(“Temperature:”, 0, 0)

58.    oled.text(“{:.1f} C”.format(temp), 20, 15)

59.    oled.text(“Humidity:”, 0, 35)

60.    oled.text(“{:.1f} %”.format(humi), 20, 50)

61.    oled.rotate(0) # rotate the screen display for a more comfortable position

62.    oled.show()

63.

64.dht_sensor=PicoDHT22(Pin(0,Pin.IN,Pin.PULL_UP),dht11=True)

65.while True:

66.    temp,humi = dht_sensor.read()

67.    percent, voltage = get_battery_level()

68.    #draw_battery(percent)

69.    #BAT_display(percent)

70.    draw_vertical_battery(percent,90,16)

71.    display_TH(temp,humi)

72.    print(‘Battery Voltage: {:.2f} V, Battery Level:{:.1f}%’.format(voltage,percent))

73.    utime.sleep(2)

15 效果

電量和溫濕度顯示,數(shù)據(jù)刷新的時(shí)間間隔為2秒

1751098544917116.png

16   眨眼動(dòng)畫

OLED顯示矩形填充狀眼睛,改變形狀并利用人眼的視覺暫留效應(yīng)實(shí)現(xiàn)眨眼效果。

17   代碼

view plaincopy to clipboardprint?

1.from machine import Pin, I2C

2.import ssd1306

3.import utime

4.import urandom

5.

6.i2c = I2C(0, scl=Pin(5), sda=Pin(4))

7.oled_width = 128

8.oled_height = 64

9.oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

10.

11.def draw_eyes(state,xshift,yshift):

12.   “””state: 0=完全睜開, 1=半閉, 2=完全閉上”””

13.    width,height = (int)(oled_width/5),(int)(oled_height/3)

14.    cx,cy=(int)((oled_width-2.5*width)/2),(int)((oled_height-height)/2)   # eyes at scrren center 定位點(diǎn)為矩形左上角

15.    x=cx+xshift

16.    y=cy+yshift

17.    oled.fill_rect(x, y, int(2.5*width), height, 0)

18.    #draw left eye

19.    if state == 0:     # 完全睜開

20.    oled.fill_rect(x, y, width, height, 1)

21.    elif state == 1:     # 半閉

22.        oled.fill_rect(x, y+(int)(height/4), width,(int)(height/2), 1)

23.    else:    # 完全閉上

24.        oled.hline(x, y+(int)(height/2), width, 1)

25.    # draw right eye

26.    if state == 0:    # 完全睜開

27.        oled.fill_rect(x+width+(int)(width/2), y, width, height, 1)

28.    elif state == 1:    # 半閉

29.        oled.fill_rect(x+width+(int)(width/2), y+(int)(height/4), width, (int)(height/2), 1)

30.    else:     # 完全閉上

31.        oled.hline(x+width+(int)(width/2), y+(int)(height/2), width, 1)

32.    oled.show()

33.

34.def blink_eyes(xshift,yshift):

35.    #睜眼狀態(tài)保持

36.    draw_eyes(0,xshift,yshift)

37.    utime.sleep(1)

38.    #眨眼動(dòng)畫序列

39.    draw_eyes(1,xshift,yshift)    # 半閉

40.    utime.sleep(0.1)

41.    draw_eyes(2,xshift,yshift)    # 全閉

42.    utime.sleep(0.1)

43.    draw_eyes(1,xshift,yshift)    # 半閉

44.    utime.sleep(0.1)

45.    draw_eyes(0,xshift,yshift)    # 全開

46.

47.def random_eyes():

48.    xshift = urandom.randint(-(int)(oled_width/4),(int)(oled_width/4))

49.    yshift = urandom.randint(-(int)(oled_height/3),(int)(oled_height/3))

50.    oled.fill(0)

51.    blink_eyes(xshift,yshift)

52.    #print(xshift,yshift)

53.

54.while True:

55.    random_eyes()

56.    #blink_eyes(0,0)

保存代碼,連接開發(fā)板,配置解釋器并運(yùn)行。

18   效果

眨眼效果(眼睛位置在屏幕內(nèi)隨機(jī)移動(dòng))

image.png

19   工程代碼

將工程調(diào)試的代碼合并,實(shí)現(xiàn)溫濕度數(shù)據(jù)(包括電池電量)與息屏隨機(jī)眨眼動(dòng)畫的切換顯示。

view plaincopy to clipboardprint?

1.from machine import Pin, ADC, I2C

2.from PicoDHT22 import PicoDHT22

3.import ssd1306

4.import utime

5.import urandom

6.

7.#initialize ADC pin

8.adc=ADC(Pin(29))

9.

10.#initialize OLED

11.i2c=I2C(0, scl=Pin(5), sda=Pin(4))

12.oled_width=128

13.oled_height=64

14.oled=ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

15.

16.#parameters of voltage divide resistor

17.R1, R2=1000000, 1000000

18.Vref_BAT=3.81 # battery voltage in full charged state

19.

20.def get_battery_level():

21.    adc_value=adc.read_u16()

22.    voltage=(adc_value / 65535) * 3.3

23.    DIV_RATIO=(R1+R2)/R1

24.    actual_voltage=voltage*DIV_RATIO#voltage division compensation

25.    percent=min(max((actual_voltage-3.3) /(Vref_BAT-3.3) *100, 0),100)

26.    return percent, actual_voltage

27.

28.def draw_vertical_battery(percent,x,y):

29.    # 局部清屏并顯示電量百分比

30.    oled.fill_rect(x,y,15+8,30+16,0)

31.    oled.text(‘{:.0f}’.format(percent), 0+x, 33+y)

32.    # 豎版電池繪制

33.    oled.rect(0+x, 2+y, 15, 30, 1)   # frame (x,y,width,height)

34.    oled.rect(5+x, 0+y, 5, 3, 1)    # anode

35.    fill_h=int(26 * percent / 100)

36.    oled.fill_rect(2+x, 2 + (28 - fill_h) + y, 11, fill_h, 1)    # percent column

37.    oled.rotate(0)

38.    oled.show()

39.

40.def display_TH(temp,humi):

41.    oled.fill_rect(20,15,6*8,64-15,0) # part clear

42.    oled.text(“Temperature:”, 0, 0)

43.    oled.text(“{:.1f} C”.format(temp), 20, 15)

44.    oled.text(“Humidity:”, 0, 35)

45.    oled.text(“{:.1f} %”.format(humi), 20, 50)

46.    oled.rotate(0) # rotate the screen display for a more comfortable position

47.    oled.show()

48.

49.def draw_eyes(state,xshift,yshift):

50.   “””state: 0=full open, 1=half open, 2=close”””

51.    width,height = (int)(oled_width/5),(int)(oled_height/3)

52.    cx,cy = (int)((oled_width-2.5*width)/2),(int)((oled_height-height)/2)    # eyes at scrren center

53.    x=cx+xshift

54.    y=cy+yshift

55.    oled.fill_rect(x, y, int(2.5*width), height, 0)

56.    #draw left eye

57.    if state==0: # full open

58.        oled.fill_rect(x, y, width, height, 1)

59.    elif state == 1: # half open

60.        oled.fill_rect(x, y+(int)(height/4), width,(int)(height/2), 1)

61.    else:    # close

62.        oled.hline(x, y+(int)(height/2), width, 1)

63.    #draw right eye

64.    if state==0: # full open

65.        oled.fill_rect(x+width+(int)(width/2), y, width, height, 1)

66.    elif state == 1: # half open

67.        oled.fill_rect(x+width+(int)(width/2), y+(int)(height/4), width, (int)(height/2), 1)

68.     else: # close

69.        oled.hline(x+width+(int)(width/2), y+(int)(height/2), width, 1)

70.    oled.show()

71.

72.def blink_eyes(xshift,yshift):

73.    #keep opening

74.    draw_eyes(0,xshift,yshift)

75.    utime.sleep(0.5)

76.    # blink eyes order

77.    draw_eyes(1,xshift,yshift)    # half open

78.    utime.sleep(0.1)

79.    draw_eyes(2,xshift,yshift)    # close

80.    utime.sleep(0.1)

81.    draw_eyes(1,xshift,yshift)    # half open

82.    utime.sleep(0.1)

83.    draw_eyes(0,xshift,yshift)    # full open

84.    utime.sleep(0.5)

85.

86.def random_eyes():

87.    xshift = urandom.randint(-(int)(oled_width/4),(int)(oled_width/4))

88.    yshift = urandom.randint(-(int)(oled_height/3),(int)(oled_height/3))

89.    oled.fill(0)

90.    blink_eyes(xshift,yshift)

91.    #print(xshift,yshift)

92.

93.dht_sensor = PicoDHT22(Pin(0,Pin.IN,Pin.PULL_UP),dht11=True)

94.def TH_BAT():

95.   ‘’’ temperature and humidity and battery ‘’’

96.    temp,humi = dht_sensor.read()

97.    percent, voltage = get_battery_level()

98.    oled.fill(0)

99.    display_TH(temp,humi)

100.    draw_vertical_battery(percent,90,16)

101.    print(‘Temperature: {:.2f} C, Humidity: {:.2f} RH, Battery Voltage: {:.2f} V, Battery Level:{:.1f}%’.format(temp,humi,voltage,percent))

102.    utime.sleep(2)

103.

104.while True:

105.    TH_BAT()

106.    random_eyes()

連接開發(fā)板,配置解釋器,將代碼保存至根目錄,取下數(shù)據(jù)線,連接電池,實(shí)現(xiàn)顯示效果。

20   效果

幀動(dòng)畫分別如下

1751099071588259.png

1751099124761880.png

21   總結(jié)

本文介紹了RP2350開發(fā)板結(jié)合DHT11模塊、鋰電池模塊、隨機(jī)眨眼動(dòng)畫,實(shí)現(xiàn)OLED顯示的桌面動(dòng)態(tài)溫濕度計(jì)的項(xiàng)目設(shè)計(jì)。通過多任務(wù)結(jié)合,為更多DIY設(shè)計(jì)提供了可能,如添加按鍵掃描或語音控制模塊,實(shí)現(xiàn)指定的功能切換與人機(jī)交互,拓展和豐富了該開發(fā)板在物聯(lián)網(wǎng)領(lǐng)域的創(chuàng)新與應(yīng)用,為RP2350 的開發(fā)設(shè)計(jì)和產(chǎn)品應(yīng)用提供了參考。

(本文來源于《EEPW》



關(guān)鍵詞: 202506 樹莓派 溫濕度計(jì)

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉