天气预报实时显示系统设计
综述
faust.cao–曹恒镇
由树莓派作为上位机,定时运行Python爬虫程序,将结果通过蓝牙发送给Arduino,Arduino接收到数据,将数据显示在1602LCD屏上,如果数据中显示会下雨,则亮起红色LED以提醒并(拓展:使用SIM900GSM模块,通过Arduino发信息给手机实时提醒。)
电子器件:
- raspberry pi 3B
- Arduino Uno
- HC-05蓝牙主从一体模块
- 1602LCD显示屏
- HC-SR04超声波测距模块
- 9V电池
- 1000Ω电阻
- 红色,绿色LED
- SIM900 GSM模块(拓展)
树莓派上位机:
一:蓝牙配置
目前知道有2种方法:
A:完全通过Linux命令行完成
在python环境下使用“import bluetooth”如果报出错误信息“ImportError: No module named bluetooth”则说明没有安装相应的包,执行一下命令安装。
$sudo apt-get update
$sudo apt-get install bluetooth bluez python-bluez
- 1
- 2
- 1
- 2
进入蓝牙连接工具
$ bluetoothctl
[NEW] Controller B8:27:EB:D3:61:B0 raspberrypi [default]
[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
开始扫描周围蓝牙设备
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:D3:61:B0 Discovering: yes
[NEW] Device 98:14:01:10:C5:32 HC-05
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
连接蓝牙设备
[bluetooth]# pair 98:14:01:10:C5:32
Attempting to pair with 98:14:01:10:C5:32
[CHG] Device 98:14:01:10:C5:32 Connected: yes
Connected: yes
Request PIN code
[agent] Enter PIN code: 1234
[CHG] Device 98:14:01:10:C5:32 UUIDs:00001101-0000-1000-8000-00805f9b34fb
[CHG] Device 98:14:01:10:C5:32 Paired: yes
Pairing successful
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
生成rfcomm0 文件(要用)
$ sudo rfcomm bind 0 98:14:01:10:C5:32
- 1
- 2
- 1
- 2
连接蓝牙设备后,会在树莓派的【/dev】目录中创建一个蓝牙设备的虚拟文件 /dev/rfcomm0
如果大家觉得这方法繁琐且难以记住,还有一种相对简答方法:
B:先通过桌面,再通过命令行
较新的树莓派桌面支持显示蓝牙设备,我们可以通过桌面操作连接蓝牙
升级安装蓝牙相关软件包
关键第三步用来更新桌面环境,我的桌面版本老,故要执行
$sudo apt-get update
$sudo apt-get upgrade -y
$sudo apt-get dist-upgrade -y
$sudo apt-get install pi-bluetooth bluez bluez-firmware blueman
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
找到桌面蓝牙图标
之后的操作和命令行一样:
先进入bluetoothctl
$ bluetoothctl
- 1
- 2
- 1
- 2
找到对应的蓝牙地址(这是会自动显示再桌面下已连接的蓝牙设备)
再退出
exit
- 1
- 1
最后生成rfcomm0 文件(要用)
$ sudo rfcomm bind 0 98:14:01:10:C5:32
- 1
- 2
- 1
- 2
二: python网络爬虫获取天气预报
首先导入python相应模块
INDEX:
Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。Requests 的哲学是以 PEP 20 的习语为中心开发的,所以它比 urllib 更加 Pythoner。更重要的一点是它支持 Python3Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。
Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。
Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。serial 用于读串口的数据,使用非常的方便
time 处理与时间有关的操作,包括程序中断等
import requests
from bs4 import BeautifulSoup
import serial
from time import sleep#程序中断执行函数
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
如果导入出现困难,用linux命令行进行下载更新
法1:
$sudo apt-get install python-requests
- 1
- 1
法2:(前提是已经下载python pip 模块)
$sudo pip install python-requests
- 1
- 1
获得各城市天气预报网站函数
def get_url(city_name):#输入参数为城市名url = 'http://www.weather.com.cn/weather/'#打开存储对应城市对应网址地址的txt文档with open('city.txt', 'r', encoding='UTF-8') as fs:lines = fs.readlines()#对文件读取遍历for line in lines:if(city_name in line):#发现城市名code = line.split('=')[0].strip()#取得相应数字return url + code + '.shtml'#加到网址地址后raise ValueError('invalid city name')#未找到该城市
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
同路径下有个存储对应城市具体地址的txt文档
格式:
101010100=北京
101010200=海淀
网络爬虫获取地址中的内容
用简单的 requests 配合 BeautifulSoup 获取预报信息并保存。
下面两步根据链接地址把网页内容抓下来,然后进行解析,得到要保存的数据,返回的 content 是一个列表,每个元素是要保存的一行内容。
def get_content(url, data=None):rep = requests.get(url)rep.encoding = 'utf-8'return rep.textdef get_data(htmltext, city):content = []bs = BeautifulSoup(htmltext, "html.parser")body = bs.bodydata = body.find('div', {'id': '7d'})ul = data.find('ul')li = ul.find_all('li')for day in li:line = [city]date = day.find('h1').stringline.append(date)text = day.find_all('p')line.append(text[0].string)if text[1].find('span') is None:temperature_H = Noneelse:temperature_H = text[1].find('span').string.replace('℃', '')temperature_L = text[1].find('i').string.replace('℃', '')line.append(temperature_H)line.append(temperature_L)content.append(line)return content
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
对所获得信息进行处理
def finds(strings):#中文字符串
#找相应中文a=strings.find("雨",0)b=strings.find("云",0)c=strings.find("晴",0)if a!=-1:return 'r'#有雨发送‘r’if b!=-1:return 'c'#有云发送‘c’if c!=-1:return 's'#有阳发送‘s’#对没有天气情况的返回为‘N’,result列表储存今明2天天气情况
if result[0][3]==None:result[0][3]='N'
if result[0][4]==None:result[0][4]='N'
if result[1][3]==None:result[1][3]= 'N'
if result[1][4]==None:result[1][3]='N'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
三: 与Arduino下位机通信
#蓝牙串口虚拟文件port='/dev/rfcomm0'serial=serial.Serial(port,9600)#设置蓝牙波特率for i in range(1,10):#多次发送保证发送成功#调用serial.write()其在python3中只能一位一位发送,故将数据转为按位发送serial.write(bytes(finds(result[0][2]),'UTF-8'))#发送空格,分开各数据serial.write(bytes(' ','UTF-8'))serial.write(bytes(result[0][3],'UTF-8'))serial.write(bytes(' ','UTF-8'))serial.write(bytes(result[0][4],'UTF-8'))serial.write(bytes(' ','UTF-8'))serial.write(bytes(finds(result[1][2]),'UTF-8'))serial.write(bytes(' ','UTF-8'))serial.write(bytes(result[1][3],'UTF-8'))serial.write(bytes(' ','UTF-8'))serial.write(bytes(result[1][4],'UTF-8'))serial.write(bytes(' ','UTF-8'))serial.flushInput()#清除串口缓冲区sleep(.8)#程序终止运行0.8s,太快CPU费劲,程序也容易卡,LCD也会有反应不过来,更新过快
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
Arduino 下位机:
一: 获得树莓派数据
在arduino中蓝牙与串口使用方法相同
void got ()//收到蓝牙信号
{if (Serial.available())//不停读取发送的一个个位,最多会有16位数据{for (int i=0;i<16;i++){a=Serial.read();//将数据给数组b[i]=a;if (b[i]=='s')
//如果接收到要下雨信息,pin8至高电平,点亮红色LED提醒{digitalWrite(9,HIGH);}if (b[i]=='r')//如果接收到要天晴信息,pin9至高电平,点亮绿色LED{digitalWrite(8,HIGH);}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
二:在LCD上显示
要导入”LiquidCrystal”库
这样2行便解决
# include <LiquidCrystal.h>//设置光标位置
lcd.setCursor(i,2);//写入字符串
lcd.print(b[i]);
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
三:数据更新
有2种不同的选择:
A:通过超声波传感器接收距离信息,如果距离小于某值,则说明有人来了,向树莓派发送信息,树莓派进行数据更新
获得距离
//超声波传感器输出端
# define 6 trig//超声波传感器输入端
# define 6 trigfloat cm;//存储探测距离
float temp;//存储高脉冲信号长度void distance ()
{digitalWrite(trig,LOW);delayMicroseconds(2);digitalWrite(trig,HIGH);//给一个10us秒的高脉冲,激发传感器delayMicroseconds(10);digitalWrite(trig,LOW);temp=float(pulseIn(echo,HIGH));//检测计算传感器发出后接受到的高脉冲时长,其正比于距离cm=temp*17/1000;//公式换算}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
循环loop函数中进行检测更新发数据给树莓派
void loop()
{ distance();//获得距离if(cm<50){Serial.write(int(cm));//发送信息给树莓派for (int i=0;i<11;i++){got();//多次获得数据,保证数据正确完整lcd.setCursor(1,0);lcd.print("today tomorrow");//写明今明两天delay(800);}}//延时与树莓派相匹配
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
B:使用程序中断定时进行:
这也有2种方法:
a:使用python time 模块的sleep函数,执行中断一段时间,之后继续执行
例如我们让每3小时更新一下,只要加上”sleep(60*60*3)”并稍微改动即可
b:使用linux下的crontab工具,设置程序定时执行
打开在pi用户下的crontab
$sudo crontab -u pi -e
- 1
- 1
写下
7 0 * * * python weather2.py
11 0 * * * python weather2.py
16 0 * * * python weather2.py20 0 * * * python weather2.py
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
其格式是:
hour minute day month year command
退出vim编辑器后,很重要的一点是一定要执行如下命令,否则无法执行
$sudo /etc/init.d/cron restart
- 1
- 1
则python程序将在7,11,16,20点执行
四:电路连接
不想用Fritzing画图了,直接写了
1.LCD-Arduino
将电位器换成1000Ω电阻,另一端接地
2.HC-SR04
trig-6
echo-7
3.HC-05
TX-RX
RX-TX
4.LED
红+-pin8
绿+-pin9
5.电源
考虑到盒子小体积,我使用了较小的9V电池,分别直接接IO口的VIN与GND,没有接电源接口,主要是缩小体积。
五:拓展短信通知(没钱买模块啊!树莓派一买就要吃土了!!还有关键Uno上只有一个RX,TX,得换arduino mega)
加个函数再调用就行
void sendSms(String phonecode ,String content) {//电话号码 ,短信内容 Serial3.println("AT+CMGS=\""+phonecode+"\"");delay(500);//必须延时,不加延时可以自己看结果Serial3.print(content);//短内容为content;//不知为什么加这个?Serial3.write(0x1A)}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
总体包装:
先是用杜邦线连接调试,然后花了一个下午多把电路焊在洞洞板上(布线自己还算满意,学长或许就不这么认为了…),然后偶然看到实验室的一个盒子大小刚好适合,便顺便把盒子改造了下,把他塞进去了,还不错。时间比较紧,焊接制作各过程都没拍照,关键是近期手机坏了,不能拍照!
最后给一张我用老手机拍的模糊的最终成品照:
总结:
大一下学期学的较乱,黑白道(软硬件)通吃,却都很不精,感觉有点不踏实,不过想想以后又不是靠这些吃饭(至少不大可能),觉得现在多了解些挺好,打好通识工科,为以后打基础吧,这学期从最初的stm32,到python与OpenCV图形处理,再到树莓派与linux,计划之后再学学电路基础,偏点硬件。
PS:
该项目是实验室二轮考核的题目,在匆忙之中将其完成,应该包含了大部分我学习的内容,还是比较综合的吧,可能偏简答了,但觉得实验室应该没人做过这个,应该算是较新的领域了,
相对比较实用(这也是我选择项目的主要考虑因素)。也是完成了,感觉满满的成就感 ,别人是难以体会的,一种自我价值实现与创造,按柏格森说法,就是”生命创造论”,—个人创造冲动与工具理性的结合而产生,或者说是二者之间的一种相互妥协,这或许是2者最好的归宿。。。
(function () {(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(′\n′).length;var(this).text().split('\n').length;var numbering = $('').addClass('pre-numbering').hide(); (this).addClass(′has−numbering′).parent().append((this).addClass('has-numbering').parent().append(numbering); for (i = 1; i
天气预报实时显示系统设计相关推荐
- 多路视频数据实时采集系统设计与实现
多路视频数据实时采集系统设计与实现 常永亮 王霖萱 常馨蓉 摘要 面对越来越多的实时视频采集.播放的应用,如何能更加方便的操控视频采集,保证流畅的播放效果,成为近几年实时媒体流的一个重要研究方向 ...
- 一、FPGA Cyclone Ⅳ OV5640图像实时采集系统设计
一.FPGA Cyclone Ⅳ OV5640图像实时采集系统设计 1.系统框架 2.摄像头配置模块 3.图像数据拼接模块 4.SDRAM操作模块 5.乒乓缓存模块 6.VGA驱动模块 7.顶层模块 ...
- 基于JS+HTML实现的纯前端天气预报实时查询系统
目录 基于JS+HTML实现的纯前端天气预报实时查询系统 功能介绍 技术栈 运行环境 效果演示 项目结构 示例代码 最后 基于JS+HTML实现的纯前端天气预报实时查询系统 该系统为纯前端项目,通过X ...
- 小型无人机地面站导航显示系统设计
小型无人机地面站导航显示系统设计 http://www.ic72.com 发布时间:2009-2-18 9:04:39 1 引 言 小型无人机(Mini-UAV)通常指最大起飞重量小于10 kg的飞行 ...
- FFmpeg在Windows上通过dshow编解码方式设置为mjpeg并实时显示测试代码
Windows上默认的内置摄像头一般支持两种编解码格式:rawvideo和mjpeg.在调用FFmpeg接口时默认的采用rawvideo.这里通过DirectShow实现为mjpeg进行编解码. 通过 ...
- 基于Jquery插件Uploadify实现实时显示进度条上传图片
网址:http://www.jb51.net/article/83811.htm 这篇文章主要介绍了基于Jquery插件Uploadify实现实时显示进度条上传图片的相关资料,感兴趣的小伙伴们可以参考 ...
- XAML实时显示更新插件LiveXAML
2019独角兽企业重金招聘Python工程师标准>>> XAML实时显示更新插件LiveXAML LiveXAML是Visual Studio的第三方扩展插件.该插件可以从Visu ...
- 【响应式Web前端设计】在html页面实时显示系统时间
在html页面实时显示系统时间 桌面新建记事本,将下列代码复制粘贴,重命名后缀为.html,保存,用浏览器打开即可 <html> <head><meta http-equ ...
- HSmartWindowControl 之 摄像头实时显示( 使用 WPF )
1.添加Halcon控件,创建WPF项目 在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见: HSmartWindowControl之安装篇 (Visual Studio ...
最新文章
- 2021年就业力排名TOP10的英国大学
- 用P3P header解决IE下iframe跨域访问时候session丢失的问题
- 一个网站的诞生- MagicDict开发总结3 [日语字典数据结构]
- 未解决:错误的结果 2 (从“D:\Program Files\Microsoft Visual Studio 8\VC\bin\cl.exe”返回)。...
- Trilogy公司的笔试题:根据指定规则用最少的步骤将数转为1
- 10_30_unittest
- 使用LayoutParams设置布局
- linux 线程 waitforsingleobject,用Sleep或WaitForSingleObject实现线程的休眠 | 求索阁
- asp php 对照表,asp 与php中常用函数对比
- Python简单的多线程demo:装逼写法
- iWebShop 二次开发之商城后台模板渲染流程
- mac idea修改内存
- 官方正式(简/繁/英/日/韩文) Windows XP sp3 下载
- 解决tuple index out of range
- 二八十六进制相互转化
- OLLYDBG使用笔记
- 关于mysql百万100W数据查询优化
- 前端追梦人Cytoscape.js教程
- acm水仙花数java,水仙花数之C语言经典案例分析
- 2023百度统计被人恶意刷广告解决办法