1.项目需求
RP2040 Game Kit板通过提供的ESP32-S2的WiFi模块连接网络获取网上信息并在RP2040 Game Kit上显示某一个城市的气象信息 - 时间、温度、湿度、气压....并通过RP2040 Game Kit上的按键能够切换显示不同城市的信息 。
本项目中,使用ESP-32来进行联网,使用RP2040 Game Kit处理网上下载的数据包,再将取得的数据显示在240 X 240的LCD屏上,通过RP2040 Game Kit上的按键A来完成城市的切换
2.设计思路
整体的设计思路如图所示:
3.硬件介绍
本项目中使用了RP2040 Game Kit,这是基于树莓派RP2040的嵌入式系统学习平台,可以通过C/C++以及MicroPython编程来学习嵌入式系统的工作原理和应用。作为一个嵌入式系统的学习平台,首先要基于核心芯片的核心板的特点以及嵌入式系统的关键知识点来定义这款学习平台:采用树莓派Pico核心芯片RP2040:双核Arm Cortex M0+内核,可以运行到133MHz,264KB内存性能强大、高度灵活的可编程IO可用于高速数字接口,片内温度传感器、并支持外部4路模拟信号输入,内部ADC采样率高达500Ksps、12位精度,支持MicroPython、C、C++编程。
联网的部分则使用了ESP32-S2,ESP32-S2 系列模组是通用的 Wi-Fi MCU 模组,功能强大,具有丰富的外设接口,是物联网、可穿戴电子设备和智能家居等应用场景的理想选择。内置 ESP32-S2FH4 或 ESP32-S2FN4R2 芯片,Xtensa® 单核 32 位 LX7 微处理器,支持高达240 MHz 的时钟频率。
4.实现的功能及图片展示
成功运行程序后,屏幕会显示“Press A start”的字样
当按下RP2040 Game Kit上的按键A时,屏幕上显示“Getting information”
此时RP2040 Game Kit通过esp 32连接网络,并从心知天气上获取免费的天气信息,通过解码下载的json文件,显示在屏幕上
再次按下A键后,它会重新从网络上下载另一个城市的信息并解码显示出来
5.主要代码及说明
首先对屏幕进行设置
st7789_res = 0
st7789_dc = 1
disp_width = 240
disp_height= 240
CENTER_X = int(disp_height/2)
CENTER_Y = int(disp_width/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
city=['quanzhou','xiamen','beijing','shanghai','tianjin'] #设置城市集
i=0
buttonA = Pin(6,Pin.IN,Pin.PULL_UP) #设置按键A
buttonB = Pin(5,Pin.IN,Pin.PULL_UP) #设置按键B
使用函数将主要代码封装起来,该函数负责按键A和按键B对城市集的切换
def aaa():
global i #声明在函数内部使用的是在函数外部定义的全局变量i
display.text(font2,"Press A",10,60)
display.text(font2,"start",30,120)
while True:
if buttonA.value()==0: #检测到按键A按下
i=i+1
ccc()
if buttonB.value()==0: #检测到按键B按下
i=i-1
ccc()
此时RP2040 Game Kit通过esp 32连接网络,并从心知天气上获取免费的天气信息,通过解码下载的json文件,显示在屏幕上
def bbb():
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',
cmd_inquiry = 'AT+CIPSTA?',
cmd_connectRouter = 'AT+CWJAP="wifi","Wifi password"',
cmd_httpget = 'AT+HTTPCLIENT=2,0,"https://api.seniverse.com/v3/weather/now.json?key=youkey&location='+city[i%5]+'&language=en&unit=c",,,2',
cmd_ack = 'OK'
) #设置联网的信息,其中需要填入wifi名称和密码,以及心知天气上的私匙
if(network_AT.connectNetwork() == True):
network_status = 1
print ('Done!')
else:
network_status = 0
print ('NetWork Config Error!')
time.sleep(3)
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):
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)
weather_pressure = weather_json['results'][0]['now']['pressure']
weather_humidity = weather_json['results'][0]['now']['humidity']
display.fill(st7789.BLACK)
weather_now = int(weather_now)
if(0<weather_now<=3):
weather_now_code=1
display.text(font2,"sunny",10,60)
elif(weather_now<=8):
weather_now_code=2
display.text(font2,"cloud",10,60)
elif(weather_now==9):
weather_now_code=3
display.text(font2,"overcast",10,60)
elif(weather_now<=18):
weather_now_code=4
display.text(font2,"rain",10,60)
elif(weather_now<=25):
weather_now_code=5
display.text(font2,"snow",10,60)
print(weather_now_code)
image=str(weather_now_code)+".bin"
f_image=open(image,'rb')
buf=f_image.read(6000)
display.blit_buffer(buf,160,0,51,50)
display.text(font2,weather_location,10,20)
display.text(font2,weather_temp+" C",150,60)
display.text(font1,"o",190,55)
display.text(font2,"pressure:"+weather_pressure,10,90)
display.text(font2,"humidity:"+weather_humidity+"%",10,120)
display.text(font1,weather_time[0:10],80,210)
display.text(font1,"Press A to query the next city",0,230)
display.text(font1,"Press B to query the previous city",0,220)
network_status=1
break
该函数是将上述两个函数链接起来
def ccc():
display.fill(st7789.BLACK)
display.text(font2,"Getting",10,60)
display.text(font2,"information",30,120)
bbb()
time.sleep(1)
5.遇到的主要难题
1.因为是第一次接触python,在尝试编写代码时,总是遇到各种报错,大多数的报错都是语法上及变量设置上的错误,在网上系统地学习了python之后,知道了报错出现的原因以及该如何解决报错
2.代码中的“network.py”有些不稳定,在刚开始运行的时候总是会出现报错,后面发现只要再重新开始运行,就不会再出现报错信息(个人猜测可能因为是刚开始运行程序时esp-32的wifi模块没激活?)
3.在使用while循环的时候,发现在查询完天气信息后,总会自动执行连接网络,重新下载当前城市的天气信息,而按下按键A也没有反应,重新排查了一遍流程后发现,因为使用的是while True循环,所以会一直循环当前的流程,再结尾加上break后解决