1.项目要求
1.RP2040 Game Kit板通过提供的ESP32-S2的WiFi模块连接网络
2.在RP2040 Game Kit上显示某一个城市的气象信息
3.通过RP2040 Game Kit上的按键能够切换显示不同城市的信息
2.具体完成的功能和图片展示
2.1 显示城市的气象信息
在程序运行后会先开始联网,联网成功后会显示“perperation completed”表示准备工作完成。
此时按A键即可显示出气象信息。
2.2切换功能
在一个城市的信息显示完后,再次按A键会切换到下一个城市。因为获取信息需要时间,按一下A键后不需要一直按,但是需要经过一段时间才会刷新出下一个城市的气象信息。简易气象站可以体现5个城市的天气信息,全程用A键控制切换,第五个城市之后会切换到第一个城市。
2.3单独城市刷新气象信息
在某一个城市的气象信息显示完成之后,按一下B键可以刷新实时的信息。动态功能的演示会放在视频里。
3.设计思路和框图
通过ESP-AT指令连接网络,然后获取按键的信息,根据按键信息改变目的城市,通过httpget来获取数据。最终分析获取的数据显示在屏幕上。
具体流程框图:
4.硬件介绍
这个项目主要用到了RP2040游戏机和ESP32-S2wifi模块。
基于树莓派RP2040的嵌入式系统学习平台,通过USB Type-C连接器供电,采用RP2040作为主控,具有双核Arm Cortex M0+内核和264KB内存,可通过MicroPython或C/C++编程,性能强大。板上四向摇杆 + 2个轻触按键 + 一个三轴姿态传感器MMA7660用做输入控制,并有240*240分辨率的彩色LCD屏显示,片内温度传感器、并支持外部4路模拟信号输入,内部ADC采样率高达500Ksps。可玩性极高。在这个项目中只涉及到了A键和B键的使用。
该模块是物联网、可穿戴电子设备和智能家居等应用场景的理想选择,板载了ESP32-S2-MINI-1模组,一款2.4 GHz WiFi 模组内置 ESP32S2 系列芯片,Xtensa® 单核 32 位 LX7 微处理器内置芯片叠封 4 MB flash,可叠封 2 MB PSRAM37 个 GPIO,具有丰富的外设板载 PCB 天线。配套的ESP32 S2 开发板除了ESP32wifi模组之外还集成了USB TYPE -C接口,两个按键,一个电源指示灯,一个用户LED灯,2排10pin的排针,将重要IO引出。使用USB供电或通过排针3.3V供电。ESP32-S2 是一款高度集成、高性价比、低功耗、主打安全的单核 Wi-Fi SoC,具备强大的功能和丰富的 IO 接口。使用乐鑫ESP-IF开发环境,这次项目中我选择烧录AT固件,作为WiFi透传模块与RP2040游戏机套件结合使用。
两个模块之间的连接比较简单,即为ESP32-S2使用3.3V供电,连接电源和GND之后,将两个模块的TX和RX交叉连接,即可实现信息的传递。
5.主要代码片段及说明
5.1按键控制
变量i是一个数字,用于控制获取哪个城市的气象信息。由A键和B键共同控制,其中A键负责切换,在5个城市之间循环;B键负责刷新本次城市的信息,以便于获取最新的实时消息。代码如下:
def button():
while True:
valueA = buttonA.value()
valueB = buttonB.value()
while(valueA ==0 or valueB ==0):
global i
if(valueA ==0 and i <= 3):
i = i+1
time.sleep(1)
valueA = buttonA.value()
valueB = buttonB.value()
return i
elif(valueA ==0 and i == 4):
i = 0
time.sleep(1)
valueA = buttonA.value()
valueB = buttonB.value()
return i
elif(valueB == 0):
i = i+0
time.sleep(1)
valueA = buttonA.value()
valueB = buttonB.value()
return i
5.2变量选择访问的城市
这部分代码比较简单,只是关于用i变量来代表不同的指令
def city(a):
print ('Start Get Weather info from seniverse')
if(a == 0):
uart.write('AT+HTTPCLIENT=2,0,"https://api.seniverse.com/v3/weather/now.json?key=SVJPGF0_tuHpWrjct&location=beijing&language=en&unit=c",,,2\r\n')
return True
elif(a == 1):
uart.write('AT+HTTPCLIENT=2,0,"https://api.seniverse.com/v3/weather/now.json?key=SVJPGF0_tuHpWrjct&location=guangzhou&language=en&unit=c",,,2\r\n')
return True
elif(a == 2):
uart.write('AT+HTTPCLIENT=2,0,"https://api.seniverse.com/v3/weather/now.json?key=SVJPGF0_tuHpWrjct&location=shanghai&language=en&unit=c",,,2\r\n')
return True
elif(a == 3):
uart.write('AT+HTTPCLIENT=2,0,"https://api.seniverse.com/v3/weather/now.json?key=SVJPGF0_tuHpWrjct&location=tianjin&language=en&unit=c",,,2\r\n')
return True
elif(a == 4):
uart.write('AT+HTTPCLIENT=2,0,"https://api.seniverse.com/v3/weather/now.json?key=SVJPGF0_tuHpWrjct&location=chongqing&language=en&unit=c",,,2\r\n')
return True
else:
return False
5.3 lcd的显示
在读取数据之后,处理所得数据并在屏幕上将需要的数据显示出来
def dis():
recvInfo = ''
check = 0
while (check == 0):
t = utime.ticks_ms()
while (utime.ticks_ms()-t) < 5000:
recv_str = uart.read()
if(recv_str != None):
recv = str(recv_str.decode())
recvInfo = recvInfo + recv
if(recvInfo.find('OK') >=0 ):
check = 1
print('DATA GETTED!')
str_start = recvInfo.find('{')
str_end = recvInfo.find(']}')
weatherInfo_str = recvInfo[str_start+12:str_end]
print(weatherInfo_str)
weather_json = ujson.loads(weatherInfo_str)
weather_json_location = weather_json['location']['name']
weather_json_tem = weather_json['now']['temperature']
weather_json_weather = weather_json['now']['text']
weather_json_humidity = weather_json['now']['humidity']
weather_json_pressure = weather_json['now']['pressure']
weather_json_last_update = weather_json['last_update']
weather_json_day = weather_json_last_update[0:10]
weather_json_time = weather_json_last_update[11:19]
display.fill(st7789.BLACK)
display.text(font2, weather_json_location, 10, 10)
display.text(font2, weather_json_weather, 10, 40)
display.text(font2, 'temp:'+weather_json_tem+' C', 10, 70)
display.text(font1, 'o', 130, 70)
display.text(font2, 'pressure:', 10, 110)
display.text(font2, weather_json_pressure+'mb', 50, 140)
display.text(font2, 'humidity:'+weather_json_humidity, 10, 180)
display.text(font1, weather_json_day+' '+weather_json_time, 10, 220)
return True
else:
check = 0
5.4连接网络
主要通过定义的network和ESP32-S2AT指令集来完成等一系列内容,包括恢复出厂设置,设置 Wi-Fi 模式为 station,连接路由器等等。主要使用的联网过程中的AT指令如下:
network_AT = network.Network(uart = UART(0,baudrate=115200,tx=Pin(12),rx=Pin(13)),
recvInfo = "",
cmd_retore = 'AT+RESTORE',
cmd_mode = 'AT+CWMODE=1',
cmd_inquiry = 'AT+CIPSTA?',
cmd_connectRouter = 'AT+CWJAP="nova","12345678"',
cmd_ack = 'OK'
)
以上便是在这个项目中使用的主要的代码块。
6.在项目过程中遇到的问题
这是我第一次接触到micro python和RP2040嵌入式系统,所以在刚开始主要借鉴了老师的示范中连接网络的部分代码。在其中我遇到了很多新手遇到的问题,比如格式错误,语法错误等等。在解决这些问题之后,我对micro python也有了一定了解。
整个项目的难点在于用按键控制文件的传输。首先我按照老师的示例中httpget请求的部分成功获得了气象信息,但是实例中的获得气象信息部分是和联网代码是一个整体。如果用按键操控就会导致每按一次按键都会重复联网和获取信息的整个过程,耗费大量时间。所以最后代码借鉴了老师的示例中连接网络的部分,将按键,httpget指令,lcd显示图像等部分定义为函数,最后成功运行。
获得气象信息时由于字符串过长容易中断,后来通过添加循环解决了问题。成功获得气象信息之后,json格式的结果在转化成python字典的时候一直出错,最后发现是截取的字符串格式出错,改变字符串截取的部分就可以成功运行。
7.未来的计划或建议
由于处理速度和网络等原因,从运行程序开始到联网以及从按下按键到气象信息刷新有很长的延时,但是不知道该用什么办法优化。或许可以选择加一小段加载画面,但是由于时间问题和不明白如何插入加载动画,最后没有完成。
通过这一段时间的学习,我初步了解了嵌入式系统和python,有很大收获,感谢硬禾学堂提供的机会和平台,之后要继续努力。