99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

怎樣將樹莓派連接到Oregon Scientific BLE氣象站

454398 ? 來源:wv ? 2019-10-12 09:09 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

步驟1:俄勒岡科學氣象站BLE協(xié)議

探索氣象站公開的BLE服務的一種簡單方法是在智能手機或平板電腦上使用BLE掃描儀應用程序。在這里,我將使用Android上的Nordic Semiconductor的nRF Connect。

對于不熟悉BLE的人們,您可能想開始使用此低功耗藍牙入門指南。這將幫助您了解GATT,服務和特性之類的術語。

借助BLE掃描器應用程序,您將找到周圍的所有BLE設備。并且您會看到俄勒岡科學氣象站正在將其自己廣告為 IDTW211R 。

如果連接到氣象站,您將獲得設備公開的服務列表

通用訪問UUID:0x1800

通用屬性UUID:0x1801

專有服務UUID:74e7fe00-c6a4-11e2-b7a9-0002a5d5c51b

設備信息UUID:0x180A

電池服務UUID:0x180F

對我們而言重要的服務是專有服務(UUID:74e7fe00-c6a4- 11E2-b7a9-0002a5d5c51b)。因此,我們單擊該服務并獲得該服務公開的特征列表。

我們的應用程序的相關特征是UUID:74e78e10-c6a4-11e2-b7a9-0002a5d5c51b(INDOOR_AND_CH1_TO_3_TH_DATA)。

如屬性中所示,此特征不可讀,但提供指示服務。而且我們將必須通過相應的客戶端特征配置描述符(UUID:0x2902)啟用指示。

事實證明,必須為設備的所有特征啟用指示/通知,才能開始獲取任何指示。

步驟2:將Raspberry Pi3連接到BLE氣象站

現(xiàn)在,我們對如何通過BLE檢索溫度數據有了更好的了解,讓我們嘗試讓Raspberry Pi與氣象站進行通訊。

Raspberry Pi上的BLE

我將使用Raspberry Pi3(集成了WLAN/BT控制器)和具有像素2016-09-23的Raspbian Jessie。

bluez (5.23)的版本此Raspbian版本已經過時了,我們必須升級到 bluez 的更高版本才能使用Bluetooth Low Energy。

下載 bluez 5.43 》并安裝所需的依賴項:

sudo apt-ge t update

sudo apt-get install -y libglib2.0-dev libdbus-1-dev libudev-dev libical-dev libreadline-dev

wget http://www.kernel .org/pub/linux/bluetooth/bluez-5.43.tar.xz

tar xvf bluez-5.43.tar.xz

配置,構建和安裝 bluez

。/configure

make

sudo make install

最后重新啟動Raspberry Pi。

現(xiàn)在,讓我們使用cmd hciconfig dev

驗證藍牙堆棧是否已啟動并且正在運行,然后確認我們可以掃描BLE設備: sudo hcitool lescan

我們應該看到氣象站的廣告為 IDTW211R 。

下一步是連接到氣象站:

sudo gatttool -b -t random -I

您應該獲得一個新的命令提示符,其BLE地址位于方括號之間。

connect

您應該獲得“連接成功”的提示,并變?yōu)椴噬?/p>

連接后,我們可以運行一些命令以獲取有關設備的更多詳細信息。例如,主要命令將列出設備公開的服務。

從氣象站收集數據

如前所述,開始獲取有關在INDOOR_AND_CH1_TO_3_TH_DATA(UUID:74e78e10-c6a4-11e2-b7a9-0002a5d5c51b)中,我們必須啟用所有特征的指示/通知。

我們通過在客戶端特征配置描述符中寫入0x0002(用于通知的0x0001)來啟用指示。 (UUID:0x2902)每個特性。寫應該以小尾數形式放置,這樣: char-write-req 0200

作為回報,您應該開始獲得指示/通知。對我們而言,相關的是INDOOR_AND_CH1_TO_3_TH_DATA指示(因此句柄0x0017)。

指示句柄= 0x0017值:01 05 01 15 01 ff 7f ff 7f 7f 7f 7f 7f ff ff 7f 7f 7f 7f 7f 7f

指示句柄= 0x0017值:82 7f 7f 7f 21 01 f8 00 24 01 ba 00 ff 7f ff 7f ff 7f ff 7f

對于每一輪指示,我們得到兩個20的數據包每個字節(jié)。最高有效字節(jié)指示數據類型(類型0或類型1)。有關數據包的更多詳細信息,請參見上一張圖片。

步驟3:檢索氣象站數據的Python腳本

現(xiàn)在我們成功地從氣象站中獲取了數據,讓我們自動化了整個過程并理解了數據。

這是一個連接到氣象站,檢索數據并提取氣象站底座和隨附的無線傳感器的溫度。

此腳本利用bluepy庫提供了API,以允許從Python訪問Bluetooth Low Energy設備。因此,您必須在執(zhí)行腳本之前安裝此模塊:https://github.com/IanHarvey/bluepy#installation

用法

可以使用MAC地址執(zhí)行腳本

在后一種情況下,腳本將執(zhí)行掃描并查找廣告為 IDTW211R 的設備。它必須以root特權執(zhí)行,因為 bluez 需要 root 特權才能進行掃描操作。

python bleWeatherStation.py [mac-address]

sudo python bleWeatherStation.py

bleWeatherStation.py

#!/usr/bin/python

# -*- coding: utf-8 -*-

# Connect to Oregon Scientific BLE Weather Station

# Copyright (c) 2016 Arnaud Balmelle

#

# This script will connect to Oregon Scientific BLE Weather Station

# and retrieve the temperature of the base and sensors attached to it.

# If no mac-address is passed as argument, it will scan for an Oregon Scientific BLE Weather Station.

#

# Supported Oregon Scientific Weather Station: EMR211 and RAR218HG (and probably BAR218HG)

#

# Usage: python bleWeatherStation.py [mac-address]

#

# Dependencies:

# - Bluetooth 4.1 and bluez installed

# - bluepy library (https://github.com/IanHarvey/bluepy)

#

# License: Released under an MIT license: http://opensource.org/licenses/MIT

import sys

import logging

import time

import sqlite3

from bluepy.btle import *

# uncomment the following line to get debug information

logging.basicConfig(format=‘%(asctime)s: %(message)s’, level=logging.DEBUG)

WEATHERSTATION_NAME = “IDTW211R” # IDTW213R for RAR218HG

class WeatherStation:

def __init__(self, mac):

self._data = {}

try:

self.p = Peripheral(mac, ADDR_TYPE_RANDOM)

self.p.setDelegate(NotificationDelegate())

logging.debug(‘WeatherStation connected !’)

except BTLEException:

self.p = 0

logging.debug(‘Connection to WeatherStation failed !’)

raise

def _enableNotification(self):

try:

# Enable all notification or indication

self.p.writeCharacteristic(0x000c, “x02x00”)

self.p.writeCharacteristic(0x000f, “x02x00”)

self.p.writeCharacteristic(0x0012, “x02x00”)

self.p.writeCharacteristic(0x0015, “x01x00”)

self.p.writeCharacteristic(0x0018, “x02x00”)

self.p.writeCharacteristic(0x001b, “x02x00”)

self.p.writeCharacteristic(0x001e, “x02x00”)

self.p.writeCharacteristic(0x0021, “x02x00”)

self.p.writeCharacteristic(0x0032, “x01x00”)

logging.debug(‘Notifications enabled’)

except BTLEException as err:

print(err)

self.p.disconnect()

def monitorWeatherStation(self):

try:

# Enable notification

self._enableNotification()

# Wait for notifications

while self.p.waitForNotifications(1.0):

# handleNotification() was called

continue

logging.debug(‘Notification timeout’)

except:

return None

regs = self.p.delegate.getData()

if regs is not None:

# expand INDOOR_AND_CH1_TO_3_TH_DATA_TYPE0

self._data[‘index0_temperature’] = ‘’.join(regs[‘data_type0’][4:6] + regs[‘data_type0’][2:4])

self._data[‘index1_temperature’] = ‘’.join(regs[‘data_type0’][8:10] + regs[‘data_type0’][6:8])

self._data[‘index2_temperature’] = ‘’.join(regs[‘data_type0’][12:14] + regs[‘data_type0’][10:12])

self._data[‘index3_temperature’] = ‘’.join(regs[‘data_type0’][16:18] + regs[‘data_type0’][14:16])

self._data[‘index0_humidity’] = regs[‘data_type0’][18:20]

self._data[‘index1_humidity’] = regs[‘data_type0’][20:22]

self._data[‘index2_humidity’] = regs[‘data_type0’][22:24]

self._data[‘index3_humidity’] = regs[‘data_type0’][24:26]

self._data[‘temperature_trend’] = regs[‘data_type0’][26:28]

self._data[‘humidity_trend’] = regs[‘data_type0’][28:30]

self._data[‘index0_humidity_max’] = regs[‘data_type0’][30:32]

self._data[‘index0_humidity_min’] = regs[‘data_type0’][32:34]

self._data[‘index1_humidity_max’] = regs[‘data_type0’][34:36]

self._data[‘index1_humidity_min’] = regs[‘data_type0’][36:38]

self._data[‘index2_humidity_max’] = regs[‘data_type0’][38:40]

# expand INDOOR_AND_CH1_TO_3_TH_DATA_TYPE1

self._data[‘index2_humidity_min’] = regs[‘data_type1’][2:4]

self._data[‘index3_humidity_max’] = regs[‘data_type1’][4:6]

self._data[‘index3_humidity_min’] = regs[‘data_type1’][6:8]

self._data[‘index0_temperature_max’] = ‘’.join(regs[‘data_type1’][10:12] + regs[‘data_type1’][8:10])

self._data[‘index0_temperature_min’] = ‘’.join(regs[‘data_type1’][14:16] + regs[‘data_type1’][12:14])

self._data[‘index1_temperature_max’] = ‘’.join(regs[‘data_type1’][18:20] + regs[‘data_type1’][16:18])

self._data[‘index1_temperature_min’] = ‘’.join(regs[‘data_type1’][22:24] + regs[‘data_type1’][20:22])

self._data[‘index2_temperature_max’] = ‘’.join(regs[‘data_type1’][26:28] + regs[‘data_type1’][24:26])

self._data[‘index2_temperature_min’] = ‘’.join(regs[‘data_type1’][30:32] + regs[‘data_type1’][28:30])

self._data[‘index3_temperature_max’] = ‘’.join(regs[‘data_type1’][34:36] + regs[‘data_type1’][32:34])

self._data[‘index3_temperature_min’] = ‘’.join(regs[‘data_type1’][38:40] + regs[‘data_type1’][36:38])

return True

else:

return None

def getValue(self, indexstr):

val = int(self._data[indexstr], 16)

if val 》= 0x8000:

val = ((val + 0x8000) & 0xFFFF) - 0x8000

return val

def getIndoorTemp(self):

if ‘index0_temperature’ in self._data:

temp = self.getValue(‘index0_temperature’) / 10.0

max = self.getValue(‘index0_temperature_max’) / 10.0

min = self.getValue(‘index0_temperature_min’) / 10.0

logging.debug(‘Indoor temp : %.1f°C, max : %.1f°C, min : %.1f°C’, temp, max, min)

return temp

else:

return None

def getOutdoorTemp(self):

if ‘index1_temperature’ in self._data:

temp = self.getValue(‘index1_temperature’) / 10.0

max = self.getValue(‘index1_temperature_max’) / 10.0

min = self.getValue(‘index1_temperature_min’) / 10.0

logging.debug(‘Outdoor temp : %.1f°C, max : %.1f°C, min : %.1f°C’, temp, max, min)

return temp

else:

return None

def disconnect(self):

self.p.disconnect()

class NotificationDelegate(DefaultDelegate):

def __init__(self):

DefaultDelegate.__init__(self)

self._indoorAndOutdoorTemp_type0 = None

self._indoorAndOutdoorTemp_type1 = None

def handleNotification(self, cHandle, data):

formatedData = binascii.b2a_hex(data)

if cHandle == 0x0017:

# indoorAndOutdoorTemp indication received

if formatedData[0] == ‘8’:

# Type1 data packet received

self._indoorAndOutdoorTemp_type1 = formatedData

logging.debug(‘indoorAndOutdoorTemp_type1 = %s’, formatedData)

else:

# Type0 data packet received

self._indoorAndOutdoorTemp_type0 = formatedData

logging.debug(‘indoorAndOutdoorTemp_type0 = %s’, formatedData)

else:

# skip other indications/notifications

logging.debug(‘handle %x = %s’, cHandle, formatedData)

def getData(self):

if self._indoorAndOutdoorTemp_type0 is not None:

# return sensors data

return {‘data_type0’:self._indoorAndOutdoorTemp_type0, ‘data_type1’:self._indoorAndOutdoorTemp_type1}

else:

return None

class ScanDelegate(DefaultDelegate):

def __init__(self):

DefaultDelegate.__init__(self)

def handleDiscovery(self, dev, isNewDev, isNewData):

global weatherStationMacAddr

if dev.getValueText(9) == WEATHERSTATION_NAME:

# Weather Station in range, saving Mac address for future connection

logging.debug(‘WeatherStation found’)

weatherStationMacAddr = dev.addr

if __name__==“__main__”:

weatherStationMacAddr = None

if len(sys.argv) 《 2:

# No MAC address passed as argument

try:

# Scanning to see if Weather Station in range

scanner = Scanner().withDelegate(ScanDelegate())

devices = scanner.scan(2.0)

except BTLEException as err:

print(err)

print(‘Scanning required root privilege, so do not forget to run the script with sudo.’)

else:

# Weather Station MAC address passed as argument, will attempt to connect with this address

weatherStationMacAddr = sys.argv[1]

if weatherStationMacAddr is None:

logging.debug(‘No WeatherStation in range !’)

else:

try:

# Attempting to connect to device with MAC address “weatherStationMacAddr”

weatherStation = WeatherStation(weatherStationMacAddr)

if weatherStation.monitorWeatherStation() is not None:

# WeatherStation data received

indoor = weatherStation.getIndoorTemp()

outdoor = weatherStation.getOutdoorTemp()

else:

logging.debug(‘No data received from WeatherStation’)

weatherStation.disconnect()

except KeyboardInterrupt:

logging.debug(‘Program stopped by user’)

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 氣象站
    +關注

    關注

    1

    文章

    776

    瀏覽量

    16228
  • 樹莓派
    +關注

    關注

    121

    文章

    2009

    瀏覽量

    107480
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    給孩子一堂自然課:氣象站如何讓科學觸手可及?

    氣象站
    奕帆科技
    發(fā)布于 :2025年05月06日 14:57:01

    解密交通氣象站:數據驅動的交通氣象服務革新

    在當今數字化時代,數據成為了推動各行業(yè)變革的核心動力,交通氣象領域也不例外。交通氣象站作為交通氣象服務的關鍵設施,正借助數據的力量實現(xiàn)著革新,為交通出行與順暢提供著更強大的支持。 交通氣象站
    的頭像 發(fā)表于 03-27 15:36 ?241次閱讀
    解密交通<b class='flag-5'>氣象站</b>:數據驅動的交通<b class='flag-5'>氣象</b>服務革新

    智慧校園:氣象站引領氣象知識科普

    在科技飛速發(fā)展的當下,智慧校園建設不斷深入,各類創(chuàng)新元素融入校園生活,為師生帶來全新體驗。其中,氣象站作為智慧校園的存在,正悄然引領著氣象科普的新風尚。 校園氣象站不再是傳統(tǒng)意義上簡單的氣象
    的頭像 發(fā)表于 02-08 15:29 ?317次閱讀

    自動氣象站的工作原理與應用

    自動氣象站是現(xiàn)代氣象觀測網絡的重要組成部分,它通過集成傳感器、數據采集與處理系統(tǒng)、通訊設備等技術手段,實現(xiàn)了對大氣環(huán)境參數的實時監(jiān)測和高效數據傳輸。以下是對自動氣象站的工作原理與應用的詳細探討
    的頭像 發(fā)表于 12-18 13:56 ?774次閱讀

    綠色校園,智慧氣象:走進我們的氣象站

    在蔚藍天空與蔥郁綠意的交相輝映下,我們的校園不僅是一片知識的沃土,更是綠色生.態(tài)與智慧科技融合的典范。在這片充滿活力的土地上,一座現(xiàn)代化的氣象站悄然矗立,它不僅是我們探索自然奧秘的窗口,更是綠色校園
    的頭像 發(fā)表于 12-10 11:58 ?419次閱讀

    自動超聲波氣象站:智慧氣象的重要組成部分

    自動超聲波氣象站是一款高度集成、低功耗、可快速安裝、便于野外監(jiān)測使用的高精度自動氣象觀測設備。以下是對自動超聲波氣象站的詳細介紹: 一、概述 超聲波氣象站(Ultrasonic wea
    的頭像 發(fā)表于 12-06 11:51 ?627次閱讀

    校園內環(huán)境監(jiān)測氣象站

    校園氣象站常用于校園氣象環(huán)境監(jiān)測及科普活動中,對校園開展的各項氣象科普活動給予支持,提高青少年科學思維能力,也可以通過校園氣象站監(jiān)測的信息和要素為學生的室外活動,穿衣等提供建議。此外,
    的頭像 發(fā)表于 11-13 16:55 ?426次閱讀

    交通氣象站:實時監(jiān)測道路氣象環(huán)境

    在現(xiàn)代交通體系中,安全與效率始終是人們關注的焦點。而交通氣象站,如同一位無聲的守護者,實時監(jiān)測著道路氣象環(huán)境,為交通的順暢運行和出行者的安全提供著至關重要的保障。 交通氣象站通常分布在高速公路、城市
    的頭像 發(fā)表于 10-23 18:28 ?591次閱讀

    負氧離子氣象站

    氣象站
    pingao141378
    發(fā)布于 :2024年10月19日 08:52:28

    車載小型氣象站:實時、準確地監(jiān)測氣象

    車載小型氣象站是一種高度集成化的氣象監(jiān)測設備,專為移動環(huán)境設計,如車輛、船只或移動觀測站等,能夠實時、準確地監(jiān)測多種關鍵氣象要素。 集成度高:車載小型氣象站通過緊湊的結構設計,集成了多
    的頭像 發(fā)表于 09-13 17:24 ?474次閱讀

    氣象站鋁鈦合金風桿的技術參數介紹

    氣象站鋁鈦合金風桿的技術參數
    發(fā)表于 09-09 10:39 ?0次下載

    自動氣象站組成和功能特點

    自動氣象站能夠長期、連續(xù)地收集氣象數據,為氣象科學研究提供了豐富的資料??茖W家們可以利用這些數據研究氣候變化、大氣環(huán)流、氣象災害等問題,推動氣象
    的頭像 發(fā)表于 08-21 16:48 ?814次閱讀
    自動<b class='flag-5'>氣象站</b>組成和功能特點

    區(qū)域生態(tài)自動氣象站:數據監(jiān)測與傳輸

    BK-CQX12,區(qū)域生態(tài)自動氣象站主要用于監(jiān)測和收集氣象數據,以便更好地了解和管理區(qū)域生態(tài)環(huán)境。這些氣象站通常配備各種傳感器和設備,用于實時監(jiān)測氣溫、濕度、降水量、風速、氣壓等氣象
    的頭像 發(fā)表于 08-09 16:30 ?629次閱讀
    區(qū)域生態(tài)自動<b class='flag-5'>氣象站</b>:數據監(jiān)測與傳輸

    校園氣象站高??破照撐?b class='flag-5'>氣象站多功能氣象站

    ,并通過無線通信模塊數據傳輸到云平臺,方便師生們通過手機APP或網頁端查看實時數據,了解天氣變化趨勢,提前做好應對準備。 校園氣象站高??破照撐?b class='flag-5'>氣象站多功能氣象站可在安卓/IOS手機
    的頭像 發(fā)表于 08-06 17:53 ?730次閱讀
    校園<b class='flag-5'>氣象站</b>高??破照撐?b class='flag-5'>氣象站</b>多功能<b class='flag-5'>氣象站</b>

    基于啟揚IMX8MPlus核心板的自動氣象站應用解決方案

    自動氣象站是一種能自動地觀測和存儲氣象觀測數據的設備,主要由傳感器、采集器、通訊接口、系統(tǒng)電源等組成。隨著人工智能、物聯(lián)網、大數據、云計算等先進技術的推動,自動氣象站也正朝著智能化、網絡化和數
    的頭像 發(fā)表于 08-02 08:00 ?872次閱讀
    基于啟揚IMX8MPlus核心板的自動<b class='flag-5'>氣象站</b>應用解決方案