【K230 实战项目】气象时钟

【CanMV K230 AI视觉】 气象时钟

  • 功能描述:
  • 说明
    • HMDI资源
    • 3.5寸屏幕
  • 使用方法

为了方便小伙伴们理解,请查看视频
B站连接

在这里插入图片描述


功能描述:

  1. 天气信息获取:通过连接到互联网,实时获取天气数据,包括温度、湿度、天气状况、风向
  2. 实时时间显示:气象时钟能够显示当前的时间。
  3. 可视化天气:包括城市, 温度,相对湿度,实时风向,空气质量

说明

HMDI资源

HDMI屏幕的小伙伴下载链接:K230 气象时钟文件,包含图片,字体,代码

在这里插入图片描述
我在此基础上做了一个HDMI的气象时钟。(为了让小伙伴多给上面的大佬点赞,我这边的资源是VIP资源。)小伙伴可以去大佬那里点赞领取代码文件。3.5屏幕的小伙伴直接使用。HDMI的,可以使用我下面的代码。(资源里都带)

3.5寸屏幕

由大佬Dai0707分享,下载链接原作者博客.https://forum.01studio.cc/t/topic/70/2

在这里插入图片描述
在这里插入图片描述

文件说明
ui图片
urllib代码
main.py3.5寸屏代码
main咸鱼浆.pyHDMI代码
Source…字体
'''
实验名称:天气时钟
实验平台:01Studio CanMV K230
镜像版本:V1.0
日期:2024-8-27验证发布
教程:wiki.01studio.cc
作者:半只半解
版本:v1.0
修改:咸鱼浆
HDMI显示,更改UI坐标等等
'''import os, time, gc, sys, network, json, re
from clock.urllib import urequest ,ntptime
from media.display import *
from media.media import *
from machine import Pin# 初始化 Wi-Fi 指示灯
WIFI_LED_PIN = 52
LED = Pin(WIFI_LED_PIN, Pin.OUT)
bg=image.Image(f"/sdcard/clock/ui/1.jpeg").to_rgb565()
# 选择显示方式
#Display.init(Display.ST7701)    # 使用 LCD 屏幕显示
Display.init(Display.LT9611) #通过HDMI显示图像
# 初始化媒体管理器
MediaManager.init()# 创建图像对象用于绘制
canvas = image.Image(1920, 1080, image.RGB565)
canvas.clear()  # 清空图像# WiFi账号密码
SSID ='123456'
CODE ='123456'time.sleep(5) #等待WiFi模块初始化def WIFI_Connect(max_retries=5):"""连接到指定的 Wi-Fi 网络,并在屏幕上显示连接状态。"""# 初始化 Wi-Fi 接口wlan = network.WLAN(network.STA_IF)wlan.active(True)start_time = time.time()  # 记录时间做超时判断retries = max_retries  # 重试次数if not wlan.isconnected():print('连接到网络...')canvas.clear()  # 清除屏幕并显示 "正在连接到 WiFi..." 的信息canvas.draw_string_advanced(600, 500, 80, "正在连接到 WiFi...", color=(255, 255, 255))Display.show_image(canvas)wlan.connect(SSID, CODE)  # WiFi连接while not wlan.isconnected():  # 添加重试逻辑LED.value(1)time.sleep_ms(300)LED.value(0)time.sleep_ms(300)if time.time() - start_time > 15:  # 超时判断,15秒没连接成功判定为超时print('WIFI 连接超时 !')wlan.active(False)return Falseif wlan.isconnected():LED.value(1)  # LED点亮canvas.clear()# 清除上次残留# 显示连接成功的信息canvas.draw_string_advanced(600, 200, 80, "WiFi 连接成功", color=(255, 255, 255))canvas.draw_string_advanced(600, 400, 80, "WiFi IP: " + wlan.ifconfig()[0], color=(255, 255, 255))canvas.draw_string_advanced(600, 600, 80, "咸鱼浆", color=(255, 137, 54))Display.show_image(canvas)print('网络信息:', wlan.ifconfig()) # 打印网络信息# 立即获取天气信息和同步时间weather_get()sync_ntp()return Trueelse:canvas.clear() # 清除上次残留canvas.draw_string_advanced(600, 500, 80, "连接失败!", color=(255, 255, 255))Display.show_image(canvas)for _ in range(3):  # LED 闪烁三次提示连接失败LED.value(1)time.sleep_ms(300)LED.value(0)time.sleep_ms(300)print('连接失败!!!', wlan.ifconfig()) # 打印错误信信息并把LED重置为熄灭状态# LED 重置为熄灭状态LED.value(0)return False""""同步NTP服务器时间"""
def sync_ntp():ntp_servers = ['202.120.2.101', 'ntp.ntsc.ac.cn']  # 第二个NTP服务器作为备选for server in ntp_servers:ntptime.host = servertry:ntptime.settime()print(f"成功从 {server} 同步时间")breakexcept Exception as e:print(f"从 {server} 同步ntp时间错误: {repr(e)}")continueelse:print("所有NTP服务器均无法同步时间,请检查网络连接或NTP服务器地址。")""""处理日期和时间"""def zero_str(str_num):num = int(str_num)return "0" + str(num) if num > 0 and num < 10 else str(num)"""天气爬取"""# 定义一个长度为5的字符列表
weather = ['']*5
is_first_run = True  # 添加一个标志来标记是否为首次运行def weather_get(max_retries=5):print("尝试获取天气数据...")global weatherretries = max_retries# 保存当前的天气信息previous_weather = weather.copy()while retries > 0:try:myURL = urequest.urlopen("http://www.weather.com.cn/weather1d/101070101.shtml")text = myURL.read(40000).decode('utf-8')  # 获取前38000个数据以节省内存#text = myURL.read(40000)  # 获取前38000个数据以节省内存  V1.1版本用这个# 在网页内容中找出 var observe24h_data 相关内容match = re.search('var observe24h_data = ' + '(.*?)' + ';', text)if match:text2 = json.loads(match.group(1))# 获取城市、温度、湿度、风向、风力级数weather[0] = text2['od']['od1']          # 城市weather[1] = text2['od']['od2'][0]['od22']  # 温度weather[2] = text2['od']['od2'][0]['od27']  # 相对湿度weather[3] = text2['od']['od2'][0]['od24']  # 实时风向weather[4] = text2['od']['od2'][0]['od28']  # 空气质量return  # 成功获取数据后退出函数except Exception as e:print(f"Error fetching weather data: {e}")retries -= 1  # 减少重试次数if retries > 0:print(f"尝试重新获取天气数据,剩余{retries}次...")time.sleep(5)  # 等待一段时间再重试# 如果获取失败,恢复之前的天气信息weather = previous_weather.copy()print("获取天气数据失败!")""""开始连接wifi"""try:wifi_connected = WIFI_Connect()
except Exception as e:print(f"连接WIFI失败: {e}")wifi_connected = False# 如果连接失败,显示连接失败的信息
if not wifi_connected:print('WiFi连接失败.')canvas.clear()  # 清屏,黑色canvas.draw_string_advanced(600, 500, 80, "连接失败,复位重新连接!", color=(255, 255, 255))Display.show_image(canvas)  # 显示while True:pass  # 阻塞在此,不再继续执行
else:# 创建一个包含所有图片路径的列表#kof_paths = [f"/sdcard/clock/ui/kof/{i}.png" for i in range(1, 18)]  # 从1到17#star_paths = [f"/sdcard/clock/ui/star/{i}.png" for i in range(1, 25)]  # 从1到24#logo_paths = [f"/sdcard/clock/ui/logo/{i}.png" for i in range(1, 31)]  # 从1到31# 预处理所有图像并转换为RGB565格式#star_rgb565 = [image.Image(path).to_rgb565() for path in star_paths]#kof_rgb565 = [image.Image(path).to_rgb565() for path in kof_paths]#logo_rgb565 = [image.Image(path).to_rgb565() for path in logo_paths]# 用于显示图片#star_index = 0#kof_index = 0#logo_index = 0# 获取空气质量字符串aqi_str = weather[4]# 初始绘制,首次绘制.if is_first_run:# 清除上次残留canvas.draw_rectangle(0, 0, 1920, 1080, color = (0, 0, 0), thickness = 2, fill = True)canvas.draw_image(bg, 0, 0, alpha=256, scale=1.0)canvas.draw_string_advanced(140, 20, 120, f" {weather[0]} ", color = (255, 165, 0))# 绘制温度湿度信息canvas.draw_string_advanced(150, 190, 120, f"温度: {weather[1]}℃", color=(255,160,122))canvas.draw_string_advanced(900, 190, 120, f"湿度: {weather[2]}%", color=(32,178,170))# 清楚上次残留,并绘制风向信息canvas.draw_rectangle(140, 900, 840, 140, color = (199, 212, 195), thickness = 2, fill = True)canvas.draw_string_advanced(140, 900, 120, f"实时风向: {weather[3]}", color=(255, 255, 0))# 空气质量try:aqi = int(aqi_str)except ValueError:aqi = 0  # 设置默认值if 0 <= aqi < 50:  # 优canvas.draw_rectangle(900, 30, 120, 100, color=(0, 255, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 优!", color=(0, 0, 0))elif 50 <= aqi < 100:  # 良canvas.draw_rectangle(900, 30, 120, 100, color=(249, 218, 101), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 良", color=(0, 0, 0))elif 100 <= aqi < 150:  # 轻度canvas.draw_rectangle(900, 30, 120, 100, color=(255, 165, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 轻度", color=(0, 0, 0))elif 150 <= aqi < 200:  # 中度canvas.draw_rectangle(900, 30, 120, 100, color=(212, 106, 106), thickness=2, fill=True)canvas.draw_string_advanced(900, 20, 80, f" 中度", color=(0, 0, 0))elif 200 <= aqi < 300:  # 重度canvas.draw_rectangle(900, 30, 120, 100, color=(220, 20, 60), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 重度", color=(0, 0, 0))elif 300 <= aqi < 500:  # 严重canvas.draw_rectangle(900, 30, 120, 100, color=(139, 0, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 严重", color=(0, 0, 0))is_first_run = False  # 设置标志为False,下次循环不绘制这些信息# 主循环last_weather_update = time.time()  # 记录最后一次更新天气的时间try:while True:os.exitpoint() #检测IDE中断current_time = time.time()  # 当前时间localtime_now = time.localtime()  # 每次循环开始时定义 localtime_nowif current_time - last_weather_update > 1000:  # 每隔1000秒更新一次天气信息last_weather_update = current_timeweather_get()  # 获取天气sync_ntp()  # 同步时间aqi_str = weather[4]  # 更新空气质量字符串# 在同步时间之后获取本地时间并格式化time_str = '%s-%s-%s %s:%s:%s' % (localtime_now[0],   # 年zero_str(localtime_now[1]), # 月zero_str(localtime_now[2]), # 日zero_str(localtime_now[3]), # 小时zero_str(localtime_now[4]), # 分钟zero_str(localtime_now[5])  # 秒)print("当前日期和时间:",time_str)# 清除上次残留, # 日期:年月日canvas.draw_rectangle(140, 400, 950, 200, color = (214, 202, 56), thickness = 2, fill = True)canvas.draw_string_advanced(120, 390, 180, f" {localtime_now[0]}-{zero_str(localtime_now[1])}-{zero_str(localtime_now[2])}", color=(144,238,144))# 清除上次残留, # 城市信息canvas.draw_rectangle(150, 20, 140, 140, color = (0, 0, 0), thickness = 2, fill = True)canvas.draw_string_advanced(140, 20, 120, f" {weather[0]} ", color = (255, 165, 0))# 绘制温度湿度信息canvas.draw_string_advanced(150, 190, 120, f"温度: {weather[1]}℃", color=(255,160,122))canvas.draw_string_advanced(900, 190, 120, f"湿度: {weather[2]}%", color=(32,178,170))# 清楚上次残留,并绘制风向信息canvas.draw_rectangle(140, 900, 840, 140, color = (199, 212, 195), thickness = 2, fill = True)canvas.draw_string_advanced(140, 900, 120, f"实时风向: {weather[3]}", color=(255, 255, 0))# 空气质量try:aqi = int(aqi_str)except ValueError:aqi = 0  # 设置默认值if 0 <= aqi < 50:  # 优canvas.draw_rectangle(900, 30, 120, 100, color=(0, 255, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 优!", color=(0, 0, 0))elif 50 <= aqi < 100:  # 良canvas.draw_rectangle(900, 30, 120, 100, color=(249, 218, 101), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 良", color=(0, 0, 0))elif 100 <= aqi < 150:  # 轻度canvas.draw_rectangle(900, 30, 120, 100, color=(255, 165, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 轻度", color=(0, 0, 0))elif 150 <= aqi < 200:  # 中度canvas.draw_rectangle(900, 30, 120, 100, color=(212, 106, 106), thickness=2, fill=True)canvas.draw_string_advanced(900, 20, 80, f" 中度", color=(0, 0, 0))elif 200 <= aqi < 300:  # 重度canvas.draw_rectangle(900, 30, 120, 100, color=(220, 20, 60), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 重度", color=(0, 0, 0))elif 300 <= aqi < 500:  # 严重canvas.draw_rectangle(900, 30, 120, 100, color=(139, 0, 0), thickness=2, fill=True)canvas.draw_string_advanced(900, 30, 80, f" 严重", color=(0, 0, 0))############主循环绘制############# 清除上次残留, # 日期:年月日canvas.draw_rectangle(140, 400, 950, 200, color = (214, 202, 56), thickness = 2, fill = True)canvas.draw_string_advanced(120, 390, 180, f" {localtime_now[0]}-{zero_str(localtime_now[1])}-{zero_str(localtime_now[2])}", color=(144,238,144))# 清除上次残留,# 时间 :小时分钟秒canvas.draw_rectangle(140, 620, 700, 170, color = (102, 218, 119), thickness = 2, fill = True)canvas.draw_string_advanced(120, 610, 150, f" {zero_str(localtime_now[3])}:{zero_str(localtime_now[4])}:{zero_str(localtime_now[5])}", color=(199, 237, 204))# 图片绘制## canvas.draw_image(star_rgb565[star_index], 480, 0, alpha=256, scale=1.0)# canvas.draw_image(kof_rgb565[kof_index], 700,700, alpha=256, scale=1.0)Display.show_image(canvas)  # 显示图片time.sleep_ms(20)   # 消除图片过快鬼畜# 查询内存,可有可无K230随便造这些小功能DRAM = gc.mem_free()if DRAM < 1000000:  # 内存不足gc.collect()  # 回收内存# 更新索引,使用模运算实现循环# star_index = (star_index + 1) % len(star_rgb565)# kof_index = (kof_index + 1) % len(kof_rgb565)# logo_index = (logo_index + 1) % len(logo_rgb565)#  bg = (bg) % len(bg_rgb565)except KeyboardInterrupt:print("用户停止程序")except Exception as e:print(f"发生异常: {e}")finally:# 释放显示资源Display.deinit()MediaManager.deinit()os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)

使用方法

大致使用方法:

1,首先连接WIFI
在这里插入图片描述
输入WIFI账号密码

2,默认获取的是深圳市的气象数据
在这里插入图片描述
修改城市的方法也很简单,找到这段代码
在这里插入图片描述
把HTTP复制 在浏览器上粘贴
在这里插入图片描述
改一下自己想看的地方,然后吧链接替换就行
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/142099.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

您的计算机已被.lcrypt勒索病毒感染?恢复您的数据的方法在这里!

导言 在网络安全领域&#xff0c;勒索病毒已经成为一种威胁极大的恶意软件&#xff0c;其中.lcrypt勒索病毒&#xff08;.lcrypt ransomware&#xff09;是最近出现的一种新的变种。它以加密用户数据并要求赎金为手段&#xff0c;严重影响个人和组织的日常运营。本文91数据恢复…

力扣题解1184

大家好&#xff0c;欢迎来到无限大的频道。 今日继续给大家带来力扣题解。 题目描述&#xff08;简单&#xff09;&#xff1a; 公交站间的距离 环形公交路线上有 n 个站&#xff0c;按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离&#xff0c;distanc…

【Motion Forecasting】【摘要阅读】BANet: Motion Forecasting with Boundary Aware Network

BANet: Motion Forecasting with Boundary Aware Network 这项工作发布于2022年&#xff0c;作者团队来自于OPPO。这项工作一直被放在arxiv上&#xff0c;并没有被正式发表&#xff0c;所提出的方法BANet在2022年达到了Argoverse 2 test dataset上的SOTA水准。 Method BANet…

计算机三级网络技术总结(一)

RPR环中每一个节点都执行SRP公平算法IEEE 802.11a和g将传输速率提高到54Mbps一个BGP发言人与其他自治系统中的BGP发言人要交换路由信息就要先建立TCP连接在一个区域内的路由器数一般不超过200个进入接口配置模式&#xff1a;Router(config)#interface <接口名> 封装ppp协…

QT 事件 Event 应用

文章目录 一、事件处理过程1. QT 事件应用介绍2. 事件分发过程 二、重写事件案例1. 鼠标事件2. 自定义按钮事件 一、事件处理过程 1. QT 事件应用介绍 众所周知Qt是一个基于C的框架&#xff0c;主要用来开发带窗口的应用程序&#xff08;不带窗口的也行&#xff0c;但不是主流…

数据结构和算法之线性结构

原文出处:数据结构和算法之线性结构 关注码农爱刷题&#xff0c;看更多技术文章&#xff01;&#xff01;&#xff01; 线性结构是一种逻辑结构&#xff0c;是我们编程开发工作应用最广泛的数据结构之一。线性结构是包含n个相同性质数据元素的有限序列。它的基本特征是&…

QT--connect的使用

在qt里面我们可以用connect将信号与槽函数连接器起来&#xff0c;而connect是一个常用的函数&#xff0c;用法也非常简单。 来看一个非常简单的栗子 Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);qpbnew QPushButton(this)…

速通汇编(五)认识段地址与偏移地址,CS、IP寄存器和jmp指令,DS寄存器

一&#xff0c;地址的概念 通常所说的地址指的是某内存单元在整个机器内存中的物理地址&#xff0c;把整个机器内存比作一个酒店&#xff0c;内存单元就是这个酒店的各个房间&#xff0c;给这些房间编的门牌号&#xff0c;类比回来就是内存单元的物理地址 在第一篇介绍debug的…

242. 有效的字母异位词(排序后用Map或者滑动窗口用Map)

文章目录 242. 有效的字母异位词49. 字母异位词分组438. 找到字符串中所有字母异位词 242. 有效的字母异位词 242. 有效的字母异位词 给定两个字符串 s 和t&#xff0c;编写一个函数来判断t是否是s的 字母异位词(字母异位词是通过重新排列不同单词或短语的字母而形成的单词或…

VMware ESXi 7.0U3q macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Server 2025

VMware ESXi 7.0U3q macOS Unlocker 集成驱动版更新 OEM BIOS 2.7 支持 Windows Server 2025 VMware ESXi 7.0U3q macOS Unlocker & OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版) ESXi 7.0U3 标准版集成 Intel 网卡、Realtek USB 网卡 和 NVMe 驱动 请访问原文链…

【Linux进程控制】进程创建|终止

目录 一、进程创建 fork函数 写时拷贝 二、进程终止 想明白&#xff1a;终止是在做什么&#xff1f; 进程退出场景 常见信号码及其含义 进程退出的常见方法 正常终止与异常终止 exit与_exit的区别 一、进程创建 fork函数 在Linux中fork函数是非常重要的函数&#x…

【Python电商项目汇报总结】**采集10万+淘宝商品详情数据注意事项总结汇报**

大家好&#xff0c;今天我想和大家聊聊我们在采集10万淘宝商品详情数据时需要注意的一些关键问题。这不仅仅是一个技术活&#xff0c;更是一场细心与合规的较量。下面&#xff0c;我就用咱们都听得懂的话&#xff0c;一一给大家说道说道。 **一、明确目标&#xff0c;有的放矢…

Autosar BswM配置-手动建立Swc Port实现自定义模式切换

文章目录 前言Mode配置Interface配置Data type mappingBswM配置BswMModeRequestPort配置BswMModeCondition配置BswMLogicalExpression配置BswMDataTypeMappingSetsSWC接口配置RTE接口map代码实现总结前言 客户需求中需要在指定电压范围内允许通信,而目前项目中通信主要由PNC控…

C++从入门到起飞之——继承下篇(万字详解) 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1、派⽣类的默认成员函数 1.1 四个常⻅默认成员函数 1.2 实现⼀个不能被继承的类 ​编辑 2. 继承与友…

SpringBoot 消息队列RabbitMQ 交换机模式 Fanout广播 Direct定向 Topic话题

介绍 作用是接收生产者发送的消息&#xff0c;并根据某种规则将这些消息路由到一个或多个队列。交换机根据绑定规则和路由键来决定如何将消息分发到队列。简而言之&#xff0c;交换机是消息路由的核心组件&#xff0c;它负责将消息从生产者引导到适当的队列&#xff0c;以便消…

防火墙--NAT技术,基于源NAT,NAT服务器,双向NAT

文章目录 防火墙--NAT技术一、基于源NAT**方式**&#xff1a;NAT No-PATNAPT出接口地址方式Smart NAT三元组 NAT 二、基于服务器的NAT多出口场景下的NAT Server 三、双向NAT 防火墙–NAT技术 基于源NAT&#xff1a;用于将内部网络的私有IP地址转换为公共IP地址&#xff0c;以便…

[Meachines] [Easy] Sauna DC域+AS-REP+TGT票证窃取+AutoLogon凭据+DCSync攻击

信息收集 IP AddressOpening Ports10.10.10.175TCP:53,80,88,135,139,389,445,464,593,3268,3269,5985 $ nmap -p- 10.10.10.175 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 53/tcp open domain? | fingerprint-strings: | DNSVersionBindReqTCP…

如何处理模型API速率限制

引言 当我们访问大模型相关的API服务时&#xff0c;通常会遇到速率限制(即限流)&#xff0c;它用于防止用户向某个API发送大量请求&#xff0c;防止请求过载&#xff0c;确保每个人都能公平地访问API。 速率限制的方式 速率限制通常有以下几种形式&#xff1a; RPM(request…

详解HTTP/HTTPS协议

HTTP HTTP协议全名为超文本传输协议。HTTP协议是应用层协议&#xff0c;其传输层协议采用TCP协议。 请求—响应模型 HTTP协议采用请求-响应模型&#xff0c;通常由客户端发起请求由服务端完成响应。资源存储在服务端&#xff0c;客户端通过请求服务端获取资源。 认识URL 当…

Linux 系统盘空间不足,想要将 Docker 镜像和容器数据迁移到数据盘

摘要&#xff1a;大家在Linux上用Docker部署项目的时候&#xff0c;有时候会部署多个项目&#xff0c;系统盘空间不足&#xff0c;数据盘又挂载有很多空间&#xff0c;这时候就会想要将 Docker 镜像和容器数据迁移到数据盘&#xff0c;本文主要讲解迁移步骤和迁移过程中遇到的一…