项目总结报告
一、项目介绍
本项目基于RP2040嵌入式系统及ESP32WiFi模块,实现了简易气象台的制作。
项目要求:
1、RP2040 Game Kit板通过提供的ESP32-S2的WiFi模块连接网络。
2、在RP2040 Game Kit上显示某一个城市的气象信息 。
3、通过RP2040 Game Kit上的按键能够切换显示不同城市的信息。
实现功能:
1、通过RP2040 Game Kit板的LCD屏幕显示某个城市的气温与天气情况。
2、通过RP2040 Game Kit板上的按键实现切换不同城市的效果,本次我选择的五个城市分别是:北京、厦门、成都、武汉、杭州。
二、项目设计思路
1、通过编写代码控制LCD屏幕显示某个城市的天气情况,运用getweather函数进行城市天气温度的循环获取。
2、使用循环函数判断是否按下A按钮切换城市,不按按钮则不进行切换。
三、硬件介绍
此项目使用基于树莓派RP2040的嵌入式系统学习平台,使用到板载的RP2040 MCU,其具有双核Arm Cortex M0+内核和264KB内存,支持MicroPython、C/C++编程,外接ESP32-S2WiFi模块,其具有ESP32-S2芯片,Xtensa单核32位LX7微处理器,内置芯片叠封4MB flash,可叠封2MB PSRAM,37个GPIO,具有丰富的外设,板载PCB天线,其具有两排10pin的排针将重要IO引出。以及使用到了RP2040自带的240*240分辨率的彩色IPS LCD屏幕,其接口为SPI,控制器为ST7789;除此之外,还使用到了按键A,USB Type-C连接器来进行板子与电脑的连接与信号的传输。
四、主要代码片段及说明
首先导入使用的模块。
import os
import time,utime
import ujson
import machine
import _thread
import lcd_gui
import network
import st7789 as st7789
from machine import UART,Pin, ADC,RTC,SPI
调用天气的图标。
image_sunny = "logo/0sunny.ebm"#48x48
image_cloudy = "logo/7cloudy.ebm"#58x41
image_overcast = "logo/9overcast.ebm"#58x38
image_rain = "logo/13rain.ebm"#58x57
image_snow = "logo/23snow.ebm"#58x55
使用st7789驱动屏幕,进行屏幕的初始化。
st7789_res = 0
st7789_dc = 1
#buttonB = 5
disp_width = 240
disp_height = 240
CENTER_Y = int(disp_width/2)
CENTER_X = int(disp_height/2)
spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi0=machine.SPI(0,baudrate=4000000, phase=1, polarity=1, sck=spi_sck, mosi=spi_tx)
display = st7789.ST7789(spi0, disp_width, disp_width,
reset=machine.Pin(st7789_res, machine.Pin.OUT),
dc=machine.Pin(st7789_dc, machine.Pin.OUT),
xstart=0, ystart=0, rotation=0)
对按键A进行初始化配置。
buttonA = Pin(6,Pin.IN, Pin.PULL_UP)
初始化串行端口和网络。
city=['beijing','xiamen','chengdu','wuhan','hangzhou']
num=0
用weatherinit函数初始化界面,用了一个天气图标和文字指示按下A按钮进入天气的显示播报,以及运用while的循环来进行城市之间的切换。
def weatherinit():
display_info.lcd_display_image(image_overcast,38,58)
display_info.lcd_display_text16x32("PRESS A",100,100)
display_info.lcd_display_text16x32("Weather Report",10,170)
global i
while True:
if buttonA.value()==0:
display.fill(st7789.BLACK)
while True:
getweather()
time.sleep(8)
#在页面更新前按下A可以改变城市
if(buttonA.value()==0):
i=i+1
break
进入循环,循环里的getweather函数进行城市的天气的循环播报,其中填入WiFi的用户名和密码来进行WiFi的配置使用,以及天气数据获取的接口。
def getweather():
global num
network_AT = network.Network(uart = UART(0, baudrate=115200, tx=Pin(12), rx=Pin(13)),
recvInfo = "",# receive buffer global variable
cmd_retore = 'AT+RESTORE',
cmd_mode = 'AT+CWMODE=1',#config as station
cmd_inquiry = 'AT+CIPSTA?',#inquiry the IP addr
cmd_connectRouter = 'AT+CWJAP="WiFi","PASSWORD"',#connect to Router
cmd_httpget = 'AT+HTTPCLIENT=2,0,"https://api.seniverse.com/v3/weather/now.json?key=SmiBGll6Bs6dy0A-7&location='+city[num%5]+'&language=en&unit=c",,,2',
cmd_ack = 'OK'
)
将城市存入列表中,采用取余数的方式依次选择城市进行循环。
city=['beijing','xiamen','chengdu','wuhan','hangzhou']
num=0
使用HTTP GET协议,从心知天气网上获取当地的天气时间,显示在RP2040板的LCD屏幕上。
#network_AT.sendATCMD(network_AT.cmd_retore,network_AT.cmd_ack,5000)
time.sleep(3)
if(network_AT.connectNetwork() == True):
#STATUS
#0:config network error
#1:config network ok
#2:http get error
#3:http get ok
network_status = 1
print ('Done!')
else:
network_status = 0
print ('NetWork Config Error!')
time.sleep(3)
display.fill(st7789.BLACK)
while True:
if(network_status == 0):
if(network_AT.connectNetwork() == True):
print ('config network Done!')
network_status = 1
else:
network_status = 0
print ('NetWork Config Error!')
elif(network_status == 1):
if(network_AT.httpGet() == True):
time.sleep(3)
network_status = 3
print ('HttpGet Done!')
else:
network_status = 2
elif(network_status == 2):
network_status = 1
time.sleep(1)
print ('HttpGet try again!')
elif(network_status == 3):
#parse json info
print(network_AT.recvInfo)
str_start = network_AT.recvInfo.find('{')
print(str_start)
str_end = network_AT.recvInfo.find(']}')
print(str_end)
weatherInfo_str = network_AT.recvInfo[str_start:str_end+2]
print(weatherInfo_str)
weather_json = ujson.loads(weatherInfo_str)
weather_location = weather_json['results'][0]['location']['name']
print(weather_location,end=' ')
weather_now = weather_json['results'][0]['now']['code']
print(weather_now,end=' ')
weather_temp = weather_json['results'][0]['now']['temperature']
print(weather_temp,end='℃ ')
weather_time = weather_json['results'][0]['last_update']
print(weather_time)
# code
# 1-3 sunny -- 1
# 4-8 cloudy -- 2
# 9- overcast -- 3
# 10-18 rain -- 4
# 19-25 snow -- 5
weather_now = int(weather_now)
if(0 < weather_now <= 3 ):
weather_now_code = 1 #sunnny
display_info.lcd_display_image(image_sunny,48,48)
display_info.lcd_display_text16x32("Sunny",130,30)
elif(weather_now <= 8):
weather_now_code = 2 #cloudy
display_info.lcd_display_image(image_cloudy,41,58)
display_info.lcd_display_text16x32("Cloudy",130,30)
elif(weather_now == 9):
weather_now_code = 3 #overcast
display_info.lcd_display_image(image_overcast,38,58)
display_info.lcd_display_text16x32("Overcast",110,30)
elif(weather_now <= 18):
weather_now_code = 4 #rain
display_info.lcd_display_image(image_rain,57,58)
display_info.lcd_display_text16x32("Rain",130,30)
elif(weather_now <= 25):
weather_now_code = 5 #snow
display_info.lcd_display_image(image_snow,55,58)
display_info.lcd_display_text16x32("Snow",130,30)
else:
weather_now_code = 0
print(weather_now_code)
display_info.lcd_display_text16x32(weather_location,20,140)
display_info.lcd_display_text16x32(weather_temp+" C",130,100)
display_info.lcd_display_text8x8("o",170,95)
display_info.lcd_display_text8x8(weather_time[0:10],80,210)
#time.sleep(60)
network_status = 1
break
五、遇到的主要难题及解决方法
1、一开始因为学的是C语言但是此次活动的项目大多数都是使用micro python进行编程,所以在做本项目的过程中,在一些语法的不同情况下会有一些难题解决不了,后来特地去学习了一些python的内容,然后解决了一些程序编写上面的问题。
2、第一次接触RP2040,虽然它的按钮布局较为简单,但是对其按钮的控制是我一开始做这个项目的最大难题,后来看了一些之前的项目案例,知道了应该如何对按钮进行控制。
3、ESP32WiFi模块一开始比较不稳定,运行程序总是报错,后来尝试了很多方法,换了WiFi,重新启动程序,关闭软件,重置RP2040等,终于成功运行了。
六、未来的计划与建议
通过这一次参加硬禾学堂电子森林的活动,深深的体会到了在放假期间如何增强自己的技能,学会更多的东西,也认识到了自身还有许多不足的地方,在以后的放假期间,我会尽力再去做一些与专业有关的知识的积累或者是实践,为以后的学习增添更多内容。