注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
cc1989summer的个人空间 https://home.eeworld.com.cn/space-uid-289541.html [收藏] [复制] [分享] [RSS]
日志

【得捷电子Follow me第1期】作品提交+ 在线新闻浏览器

已有 712 次阅读2023-6-29 23:22 |个人分类:树莓派

【得捷电子Follow me第1期】+ 在线新闻浏览器

 

 

2aaf57ea8f1a8ab31c50d3a74b0f25ab

 

 

  1. 项目描述
    这款《在线新闻浏览器》使用了Raspberry Pi Pico W开发板及OLED屏幕模块,充分利用了Raspberry Pi Pico W强大的WIFI联网能力及大内存(本项目需要显示中文,而所用的中文字库文件就达到了近500KB)。而且所用的MicroPython也支持高级编程语言,支持requests及Json解析,大大方便了信息流的获取及处理,想想如果这是传统单片机,实现同样的功能要多少代码量。
    首先,回顾下Raspberry Pi Pico W所搭载的资源,可以看到还是非常丰富的,为实现各类物联网项目打下了坚实基础。
    采用了 Raspberry Pi 官方自主设计的 RP2040 微控制器芯片
    • 搭载了双核 ARM Cortex M0 + 处理器,运行频率高达 133MHz 灵活时钟(可超频)
    • 内置了 264KB 的 SRAM 和 2MB 的片上 Flash
    • 板载2.4GHz无线接口芯片(802.11n或Wifi4)。
    • 支持蓝牙 5.2
    • 邮票孔设计,可直接焊接集成到用户自主设计的底板上
    • USB1.1 主机和设备支持
    • 支持低功耗睡眠和休眠模式
    • 可识别为 USB 大容量存储器进行拖放式程序更新
    • 多达 26 个多功能的 GPIO 引脚
    • 2 个 SPI,2 个 I2C,2 个 UART,3 个 12 位 ADC,16 个可控 PWM 通道
    • 精确的片上时钟和定时器
    • 温度传感器
    • 片上加速浮点库
    • 8 个可编程 I/O (PIO) 状态机,用于自定义外设支持
    在线新闻浏览器项目主要分3个模块。
    第一部分

    连接WIFI


    第二部分

    获取新闻


    第三部分

    在OLED屏幕上显示新闻

  2. 各功能对应的主要代码片段及说明
import time
import network
import urequests
import urequests as requests
import ujson
from machine import Pin, I2C, ADC, PWM
from time import sleep
import ufont
import ssd1306


ssid = 'ccqp'
password = ''

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)

# Wait for connect or fail
max_wait = 10
while max_wait > 0:
    if wlan.status() < 0 or wlan.status() >= 3:
        break
    max_wait -= 1
    print('waiting for connection...')
    time.sleep(1)

# Handle connection error
if wlan.status() != 3:
    raise RuntimeError('network connection failed')
else:
    print('connected')
    status = wlan.ifconfig()
    print( 'ip = ' + status[0] )
    
import ntptime
def sync_ntp():
     ntptime.NTP_DELTA = 3155644800#3155673600#3155644800   # 可选 UTC+8偏移时间(秒),不设置就是UTC0
     ntptime.host = 'ntp1.aliyun.com'  # 可选,ntp服务器,默认是"pool.ntp.org"
     ntptime.settime()   # 修改设备时间,到这就已经设置好了
    
sync_ntp()
# 已经设置好了,随便用
from machine import RTC
rtc = RTC()
print(rtc.datetime())


#可以通过字典对象上值的键来获取每个单独的JSON值
##可借助ujson库来解析内容



import urequests
Url = 'https://api.seniverse.com/v3/weather/now.json?key=SK6E_7MBhPJr0_Cs3&location=shenzhen&language=zh-Hans&unit=c'

r = urequests.get(Url)

r.json()

print (r.json()['results'][0]['location']['name'],r.json()['results'][0]['now']['temperature'],r.json()['results'][0]['now']['text'])



i2c = I2C(1, scl=Pin(7), sda=Pin(6), freq = 400000)
display = ssd1306.SSD1306_I2C(128, 64, i2c)
# 载入字体
# 使用字体制作工具:javascript:;
font = ufont.BMFont("unifont-14-12917-16.v3.bmf")

request_url = 'javascript:;'
resp = urequests.get(request_url)
#resp_json = ujson.loads(resp.text)

print (resp.json()['result']['data'][0]['title'])
print (resp.json()['result']['data'][1]['title'])
print (resp.json()['result']['data'][2]['title'])
print (resp.json()['result']['data'][3]['title'])

titile=resp.json()['result']['data'][1]['uniquekey']
print (titile)

request_url1 = 'https://v.juhe.cn/toutiao/content?key=5f78766a1e82f665528a474b411a59dc&uniquekey='+ titile
#resp1 = urequests.get(request_url1)
#print (resp1.json()['result']['content'])

font.text(display, resp.json()['result']['data'][0]['title'], 0, 0, font_size=16, show=True, clear=True)
font.text(display, resp.json()['result']['data'][1]['title'], 0, 16, font_size=16, show=True, clear=True)
font.text(display, resp.json()['result']['data'][2]['title'], 0, 32, font_size=16, show=True, clear=True)
font.text(display, resp.json()['result']['data'][3]['title'], 0, 48, font_size=16, show=True, clear=True)

 

 

第一部分,就不再赘述。

第二部分,也是最有难度的部分是获取新闻,如何连上新闻服务器,获取并返回我们要的新闻?

本文重点讲解此部分代码。

  • 本项目使用了“聚合数据”平台。

javascript:;

我们打开他的官网,找到API,再找到新闻头条。

可以看到普通会员(免费注册的)每天可以查询50次。

接下来我们看下接口文档及示例代码。

可以看到新闻列表的接口地址是javascript:;

新闻正文的接口地址是 http://v.juhe.cn/toutiao/content

主要的代码就是Python下的Request语句。这条语句的主要参数有三个参数,url、type和key。

第一个参数url也就是网址,上文提到了新闻列表和新闻正文各自对应的url。

第二个参数是type,也就是你要获取的新闻的类型:

top(推荐,默认)
guonei(国内)
guoji(国际)
yule(娱乐)
tiyu(体育)
junshi(军事)
keji(科技)
caijing(财经)
youxi(游戏)
qiche(汽车)
jiankang(健康)

第三个参数,就是在聚合数据免费注册的普通会员,每个应用对于的密钥。

比如,这是我免费申请的Key。

以上3个参数弄明白后,就可以着手准备咱们的micropython代码了。

在这里主要参考了一段天气预报的代码,如下:

import urequests

Url = 'https://api.seniverse.com/v3/weather/now.json?key=SK6E_7MBhPJr0_Cs3&location=shenzhen&language=zh-Hans&unit=c'

上面这句至关重要,可以看到几个重要参数,第一个就是网址url,第二个就是key也就是密码,第三个就是位置,这里设置为深圳。

r = urequests.get(Url)

urequests.get这句就是核心语句,从指定网址的指定接口抓取信息,抓到的信息存在对象r中。

r.json()

将数据以json的格式整理。

json的全称为:JavaScript Object Notation,是一种轻量级的数据交互格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。

简单来说:json就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互。

我们如果直接把带参数的url输入到浏览器,就会返回一长串看似杂乱的字符串,其实这就是Json格式的信息。

为了便于读懂这段Json格式的信息,我们可以使用“聚合数据”自带的JSON在线格式化工具,方便整理读懂信息。

https://tool.juhe.cn/

按上图的逻辑关系:

['results'][0]['location']['name']就对应“深圳”

['results'][0]['now']['temperature']就对应“29”

['results'][0]['now']['text']就对应“阴”

所以最后把你想要的信息打印出来。

print (r.json()['results'][0]['location']['name'],r.json()['results'][0]['now']['temperature'],r.json()['results'][0]['now']['text'])

运行结果如图红框内。

理解了天气预报的逻辑,获取新闻就简单了。

request_url = 'javascript:;'

resp = urequests.get(request_url)

print (resp.json()['result']['data'][0]['title'])

print (resp.json()['result']['data'][1]['title'])

print (resp.json()['result']['data'][2]['title'])

print (resp.json()['result']['data'][3]['title'])

我们将带参数的网址粘贴到浏览器。

javascript:;

因此,

['result']['data'][0]['title'] 就对应“小型飞机闯入禁区被法战机拦截:嫌犯高空抛下15个袋子 疑为毒品”

['result']['data'][1]['title'] 就对应“反复“退群”“返群”,美国把加入国际组织当作逛公园”

上面只是这条新闻的标题,那如果想要获取新闻的正文怎么办呢?

回到前面的介绍。

新闻正文的接口地址是 http://v.juhe.cn/toutiao/content

这里有两个关键参数,第一个仍然是密码,前文有说。

第二个参数就是uniquekey,这其实对应的是刚刚第一步获取新闻标题里JSON数据里的uniquekey。

我们直接把获取新闻正文的网址输入浏览器:

javascript:;

titile=resp.json()['result']['data'][1]['uniquekey']

此句获取新闻的'uniquekey'

print (titile)

打印出'uniquekey'

request_url1 = 'https://v.juhe.cn/toutiao/content?key=5f78766a1e82f665528a474b411a59dc&uniquekey='+ titile

抓取新闻正文的链接

resp1 = urequests.get(request_url1)

抓取新闻正文

print (resp1.json()['result']['content'])

第三部分 中文显示

这里用到了MicroPython-uFont

需要把上图3个文件下载到PICO W板卡上。

i2c = I2C(1, scl=Pin(7), sda=Pin(6), freq = 400000)

display = ssd1306.SSD1306_I2C(128, 64, i2c)

# 载入字体

# 使用字体制作工具:javascript:;

font = ufont.BMFont("unifont-14-12917-16.v3.bmf")

font.text(display, resp.json()['result']['data'][0]['title'], 0, 0, font_size=16, show=True, clear=True)

font.text(display, resp.json()['result']['data'][1]['title'], 0, 16, font_size=16, show=True, clear=True)

font.text(display, resp.json()['result']['data'][2]['title'], 0, 32, font_size=16, show=True, clear=True)

font.text(display, resp.json()['result']['data'][3]['title'], 0, 48, font_size=16, show=True, clear=True)

执行结果如下图

MMMMMM

 

 

2.    功能展示及说明

功能展示如图所示,列出了4条国际新闻标题,由于MicroPython-uFont 默认超出边界不换行,因此标题未显示完全。

另外,由于此屏幕比较小,128*64,只能显示4行中文,而且没有按钮等翻屏工具,因此目前没有再深入编写进一步的功能,也算给后续开发留点悬念吧。

其他的展示:

任务1:熟悉micropython基本语法

这里要特别指出,单击要上传的文件,右键有“上传到/”就可以很便捷地实现程序上传功能。

另外,为了便于学习python语言,推荐以下网址:

任务2:驱动外设

  • 点亮LED

  • 驱动蜂鸣器
    自己编写了一首《卡农》,代码见附件,效果见视频。
  • 驱动OLED屏幕

任务3:同步网络时间

任务4:实现定位功能

由于在室内,GPS信号不支持,放到室外就好很多。

  1. 对本活动的心得体会

本次活动是我第一次开发树莓派,也是第一次体验Micro-Python,以往的开发经历比如51单片机及MSP430单片机,都需要特别关注处理器的底层细节,比如时钟、寄存器,还需要专门的烧录工具,而且由于51单片机及MSP430单片机的资源比较有限,时钟频率也不高,可玩性就不那么丰富,这次Digi-Key联合EEWORLD发起的"Follow me活动”,给了我一个完整的开发体验,Digi-Key上有丰富的外设资源,完全能满足我的开发需求。

 

 

 

最后附上全部代码,包括原创的《卡农》。

 

 

本文来自论坛,点击查看完整帖子内容。

全部作者的其他最新日志
评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章