基于RP2040及ESP32完成简易气象台的制作
本项目基于RP2040嵌入式系统以及ESP32WIFI模块,实现了简易气象台的制作,通过LCD屏幕及其按钮实现了切换不同城市的功能。
标签
嵌入式系统
RP2040
2022暑假在家练
Nacht
更新2022-09-02
集美大学诚毅学院
769

项目总结报告

一、项目介绍

本项目基于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板上的按键实现切换不同城市的效果,本次我选择的五个城市分别是:北京、厦门、成都、武汉、杭州。Fplh5Pn5MWvqkhyxLmQWqghd8g1zFkl4eE27gyrdlJpSHzSGxQ-xv7AyFkHU2sDi0xXDHJIrTTabFtco4Py_FkkJGUvGp9yCE2hHdiPVL4w-5agoFsKq2kxxgkjxPQwZAJmdYqJEJusxFkay0eO2AHo3H574XiuK4f433vbg

二、项目设计思路

1、通过编写代码控制LCD屏幕显示某个城市的天气情况,运用getweather函数进行城市天气温度的循环获取。

2、使用循环函数判断是否按下A按钮切换城市,不按按钮则不进行切换。

FppzrXk8q7WIR6z5ZLCGkPTVrInH

三、硬件介绍

此项目使用基于树莓派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等,终于成功运行了。

六、未来的计划与建议

通过这一次参加硬禾学堂电子森林的活动,深深的体会到了在放假期间如何增强自己的技能,学会更多的东西,也认识到了自身还有许多不足的地方,在以后的放假期间,我会尽力再去做一些与专业有关的知识的积累或者是实践,为以后的学习增添更多内容。

 

附件下载
简易气象站.zip
团队介绍
本人是来自集美大学诚毅学院智能制造工程20级学生
团队成员
Nacht
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号