综述


faust.cao–曹恒镇

由树莓派作为上位机,定时运行Python爬虫程序,将结果通过蓝牙发送给Arduino,Arduino接收到数据,将数据显示在1602LCD屏上,如果数据中显示会下雨,则亮起红色LED以提醒并(拓展:使用SIM900GSM模块,通过Arduino发信息给手机实时提醒。)

电子器件:

  1. raspberry pi 3B
  2. Arduino Uno
  3. HC-05蓝牙主从一体模块
  4. 1602LCD显示屏
  5. HC-SR04超声波测距模块
  6. 9V电池
  7. 1000Ω电阻
  8. 红色,绿色LED
  9. 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。更重要的一点是它支持 Python3

Beautiful 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

天气预报实时显示系统设计相关推荐

  1. 多路视频数据实时采集系统设计与实现

    多路视频数据实时采集系统设计与实现 常永亮   王霖萱  常馨蓉 摘要 面对越来越多的实时视频采集.播放的应用,如何能更加方便的操控视频采集,保证流畅的播放效果,成为近几年实时媒体流的一个重要研究方向 ...

  2. 一、FPGA Cyclone Ⅳ OV5640图像实时采集系统设计

    一.FPGA Cyclone Ⅳ OV5640图像实时采集系统设计 1.系统框架 2.摄像头配置模块 3.图像数据拼接模块 4.SDRAM操作模块 5.乒乓缓存模块 6.VGA驱动模块 7.顶层模块 ...

  3. 基于JS+HTML实现的纯前端天气预报实时查询系统

    目录 基于JS+HTML实现的纯前端天气预报实时查询系统 功能介绍 技术栈 运行环境 效果演示 项目结构 示例代码 最后 基于JS+HTML实现的纯前端天气预报实时查询系统 该系统为纯前端项目,通过X ...

  4. 小型无人机地面站导航显示系统设计

    小型无人机地面站导航显示系统设计 http://www.ic72.com 发布时间:2009-2-18 9:04:39 1 引 言 小型无人机(Mini-UAV)通常指最大起飞重量小于10 kg的飞行 ...

  5. FFmpeg在Windows上通过dshow编解码方式设置为mjpeg并实时显示测试代码

    Windows上默认的内置摄像头一般支持两种编解码格式:rawvideo和mjpeg.在调用FFmpeg接口时默认的采用rawvideo.这里通过DirectShow实现为mjpeg进行编解码. 通过 ...

  6. 基于Jquery插件Uploadify实现实时显示进度条上传图片

    网址:http://www.jb51.net/article/83811.htm 这篇文章主要介绍了基于Jquery插件Uploadify实现实时显示进度条上传图片的相关资料,感兴趣的小伙伴们可以参考 ...

  7. XAML实时显示更新插件LiveXAML

    2019独角兽企业重金招聘Python工程师标准>>>  XAML实时显示更新插件LiveXAML LiveXAML是Visual Studio的第三方扩展插件.该插件可以从Visu ...

  8. 【响应式Web前端设计】在html页面实时显示系统时间

    在html页面实时显示系统时间 桌面新建记事本,将下列代码复制粘贴,重命名后缀为.html,保存,用浏览器打开即可 <html> <head><meta http-equ ...

  9. HSmartWindowControl 之 摄像头实时显示( 使用 WPF )

    1.添加Halcon控件,创建WPF项目 在VS2013中创建一个WPF工程,然后添加halcon的控件和工具包,参见: HSmartWindowControl之安装篇 (Visual Studio ...

最新文章

  1. 2021年就业力排名TOP10的英国大学
  2. 用P3P header解决IE下iframe跨域访问时候session丢失的问题
  3. 一个网站的诞生- MagicDict开发总结3 [日语字典数据结构]
  4. 未解决:错误的结果 2 (从“D:\Program Files\Microsoft Visual Studio 8\VC\bin\cl.exe”返回)。...
  5. Trilogy公司的笔试题:根据指定规则用最少的步骤将数转为1
  6. 10_30_unittest
  7. 使用LayoutParams设置布局
  8. linux 线程 waitforsingleobject,用Sleep或WaitForSingleObject实现线程的休眠 | 求索阁
  9. asp php 对照表,asp 与php中常用函数对比
  10. Python简单的多线程demo:装逼写法
  11. iWebShop 二次开发之商城后台模板渲染流程
  12. mac idea修改内存
  13. 官方正式(简/繁/英/日/韩文) Windows XP sp3 下载
  14. 解决tuple index out of range
  15. 二八十六进制相互转化
  16. OLLYDBG使用笔记
  17. 关于mysql百万100W数据查询优化
  18. 前端追梦人Cytoscape.js教程
  19. acm水仙花数java,水仙花数之C语言经典案例分析
  20. 2023百度统计被人恶意刷广告解决办法

热门文章

  1. C语言 —— pta寻找孪生素数 (20 分)
  2. eclipse web项目启动后不自动打开浏览器,谷歌了一下终于找到设置了
  3. “笨鸟”荣耀的2021
  4. [OAuth2.0三方登录系列文章-1]OAuth2.0与三方登录的端到端方案
  5. Python初探:turtle(海龟)实现动画
  6. 中国无乳糖食物行业市场供需与战略研究报告
  7. CSS第二部分——网页布局三大核心
  8. laravel-excel使用2(老猫包子店的故事)
  9. 网页布局——盒子模型
  10. Excel2007版的常用功能(7):Excel公式与函数