树莓派RP2350-桌面动态温湿度计

  作者:无垠的广袤 时间:2025-06-28来源:EEPW


1   树莓派RP2350-桌面动态温湿度计

本文介绍了DFRobot Beetle RP2350开发板结合DHT11模块、锂电池模块、随机眨眼动画,实现OLED 显示的桌面动态温湿度计的项目设计。

2   项目介绍

本项目包括如下。

工作原理:ADC电压采集与电量转换

工程调试:电量获取、电量图标显示、DHT11温湿度显示、OLED眨眼动画

工程代码:合并调试代码,实现完整的项目设计功能

效果演示:帧动画显示、动态展示

最终实现桌面动态温湿度计的制作。

3 工作原理

根据开发板原理图可知,电池VBAT的分压电路与主控的GPIO29模拟接口相连,因此通过该引脚可实时采集监测电池电压信息,进而实现电量显示。

1751097964544899.png

4   硬件连接

GP0->DATA(DHT11)

GP4->SDA(OLED)

GP5->SCL(OLED)

BAT->Battery Positive

GND->Battery Negative

5   示意图

1751098020985209.png

6   工程调试

包括ADC电量采集、电量的OLED显示、DHT11温湿度数据和电量图标的显示、眨眼动画等调试项目。

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)

保存代码,连接开发板,配置解释器并运行。

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)

保存代码,连接开发板,配置解释器并运行。

12   效果

电量图标的水平显示

1751098336641707.png

量图标的竖直显示

1751098374755203.png

13   DHT11温湿度计

带电量显示的DHT11温湿度计

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 效果

电量和温湿度显示,数据刷新的时间间隔为2秒

1751098544917116.png

16   眨眼动画

OLED显示矩形填充状眼睛,改变形状并利用人眼的视觉暂留效应实现眨眼效果。

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 定位点为矩形左上角

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.    #睁眼状态保持

36.    draw_eyes(0,xshift,yshift)

37.    utime.sleep(1)

38.    #眨眼动画序列

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)

保存代码,连接开发板,配置解释器并运行。

18   效果

眨眼效果(眼睛位置在屏幕内随机移动)

image.png

19   工程代码

将工程调试的代码合并,实现温湿度数据(包括电池电量)与息屏随机眨眼动画的切换显示。

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()

连接开发板,配置解释器,将代码保存至根目录,取下数据线,连接电池,实现显示效果。

20   效果

帧动画分别如下

1751099071588259.png

1751099124761880.png

21   总结

本文介绍了树莓派RP2350开发板结合DHT11模块、锂电池模块、随机眨眼动画,实现OLED显示的桌面动态温湿度计的项目设计。通过多任务结合,为更多DIY设计提供了可能,如添加按键扫描或语音控制模块,实现指定的功能切换与人机交互,拓展和丰富了该开发板在物联网领域的创新与应用,为RP2350 的开发设计和产品应用提供了参考。

(本文来源于《EEPW》202506)

关键词: 202506 树莓派 温湿度计

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版