在開始之前,首先需要搞明白以下幾個概念,RS485, Modbus協(xié)議和DTU。
RS485,基礎概念自行度娘,這里如果簡單理解的話就是一種串行通信標準。非硬件工程師其實記住RS485有4條線,A,B,VIM和GND。 可簡單理解為A,B作為數(shù)據(jù)傳輸,VIM和GND作為電源的正負。在設備接入上一般是A口對A口, B口對B口。
Modbus協(xié)議, 一種通信協(xié)議,而且是現(xiàn)在很多工業(yè)的電氣設備上都會用到的。稍后我們會在例子中講到。
DTU, 數(shù)據(jù)傳輸單元,通過DTU,可以將RS485設備的數(shù)據(jù)傳輸?shù)組QTT或者其他地方。
簡單理解上面的概念后,我們開始進行數(shù)據(jù)的接入。
1. 首先進行硬件之間的對接,將RS485的A口接入DTU的A口, B口接入B口。在這里要值得注意得是,因為RS485設備是屬于被動設備,需要由上位機發(fā)起詢問后才會返回傳感器上的數(shù)據(jù)。具體的數(shù)據(jù)格式需要根據(jù)自己手上的設備來確定。
以老司機手里的這款溫濕度傳感器為例,在產(chǎn)品說明書的章節(jié)里面,描述了這款傳感器的問詢參數(shù):
地址碼 | 功能碼 | 起始地址 | 數(shù)據(jù)長度 | 校驗碼低位 | 校驗碼高位 |
0x01 | 0x03 | 0x00,0x00 | 0x00,0x02 | 0xC4 | 0x0B |
這說明了,如果我們需要讓傳感器返回傳感器的數(shù)據(jù),我們需要對傳感器下發(fā)如下的命令:
010300000002C40B?
為了便于大家理解, 我們這樣來看這串命令
01【我們要查詢地址為01的設備,默認的地址為01】
03【使用功能03】
0000【從這里開始查詢】
0002【數(shù)據(jù)長度】
C40B【驗證碼】
如果指令下發(fā)正常,將會返回下面的數(shù)據(jù):
地址碼 | 功能碼 | 字節(jié)數(shù) | 數(shù)據(jù)值(濕度、溫度) | 校驗碼低位 | 校驗碼高位 |
0x01 | 0x03 | 0x04 | 0x02 0x3F 0x01 0x06 | 0x4A | 0x15 |
我們還是把數(shù)據(jù)拆分起來看一下,如果返回正常,我們將會得到下面的數(shù)據(jù)。
010304023F01064A15
其中023F0106就是我們期望得到的數(shù)據(jù),因為返回的值是16進制的,我們根據(jù)產(chǎn)品手冊的描述,得知023F和0106分別表示在十六進制下的溫度和濕度,我們再進行轉換后就可以得到實際10進制下的溫度和濕度了。
2. 在我們理解了如何下發(fā)數(shù)據(jù)到設備,以及讀取設備返回的值后。我們開始在阿里云物聯(lián)網(wǎng)平臺進行操作。
2.1 首先創(chuàng)建產(chǎn)品,這里要注意的是,因為我們的設備是一個4G的DTU,所以聯(lián)網(wǎng)方式選擇蜂窩,數(shù)據(jù)格式選擇透傳(因為我們從DTU拿到的數(shù)據(jù)并不是JSON格式的)
當我們產(chǎn)品創(chuàng)建好了后,我們可以看到我們的物模型的透傳傷上行和下行的TOPIC。
2.2? 【重點來了】因為我們透傳過來的數(shù)據(jù)并不是能直接被云平臺可以解析的,所以阿里云物聯(lián)網(wǎng)平臺提供了【消息解析】這么一個功能。
為了方便理解,我們可以看一下一次設備上報將會經(jīng)過哪些步驟。
通過圖,我們可以看到,設備通過DTU把設備上傳后,首先云平臺通過MQTT的TOPIC接手到消息后,會調用RawDataToProtocol講數(shù)據(jù)從?原始數(shù)據(jù)解析道協(xié)議數(shù)據(jù),接著云端進行一個響應up_raw.
我們從DTU上行收到的數(shù)據(jù)如下:
最終通過轉換之后得到的數(shù)據(jù)如下:
{"Params":"01030402e40080ba1c","ResultData":{"method":"thing.event.property.post","fHead":1,"id":"50594532","addr":"1","params":{"Humidity":74,"temperature":12.8},"version":"1.0","fun":"3"},"RequestId":"null","Content":"null","Reason":"success","clientId":"null"}
?在這里我們可以看到我們已經(jīng)拿到了設備上行的數(shù)據(jù),即{"Humidity":74,"temperature":12.8}
這里之所以能進行轉換,就是我們剛提到的消息解析所進行的。消息解析只是JS,PYTHON,PHP進行編寫。
老司機使用的是PYHON,我們來看一下代碼
ALINK_PROP_REPORT_METHOD = 'thing.event.property.post' # 物聯(lián)網(wǎng)平臺Topic,設備上傳屬性數(shù)據(jù)到云端。
def raw_data_to_protocol(bytes):
uint8Array = []
for byteValue in bytes:
uint8Array.append(byteValue & 0xff)
fHead = uint8Array[0]
jsonMap = {}
jsonMap['fHead'] = fHead
jsonMap['method'] = ALINK_PROP_REPORT_METHOD
jsonMap['version'] = '1.0'
jsonMap['id'] = str(bytes_to_int(uint8Array[1:5]))
jsonMap['addr'] = str(bytes_to_int(uint8Array[0:1]))
jsonMap['fun'] = str(bytes_to_int(uint8Array[1:2]))
params = {}
params['Humidity'] = float(bytes_to_int(uint8Array[3:5]))/10
params['temperature'] = float(bytes_to_int(uint8Array[5:7]))/10
jsonMap['params'] = params
return jsonMap
# byte轉成int。
def bytes_to_int(bytes):
data = ['%02X' % i for i in bytes]
return int(''.join(data), 16)
?在上面的代碼上,我們可以看到消息解析 講收到的消息進行了幾次轉換,得到了相對應的數(shù)據(jù)。
我們這里著重描述一下如何獲取到溫度和濕度
params['Humidity'] = float(bytes_to_int(uint8Array[3:5]))/10
params['temperature'] = float(bytes_to_int(uint8Array[5:7]))/10
我們回顧一下,上述代碼其實是對010304023F01064A15進行了解析。而根據(jù)傳感器的約定,數(shù)據(jù)的第四,第五位表示的是濕度,第六,第七表示的是溫度。
01 03 04?02 3F 01 06?4A 15
所以uint8Array[3:5] 我們拿到的是 02 3F,并將bytes轉換成int后,再除以10,則得到了我們的濕度。
uint8Array[5:7] => 01 06 進行轉換,再除以10,得到溫度。
以上就是通過消息解析,將透傳的數(shù)據(jù)在阿里云平臺上進行轉換的方式了。文章來源:http://www.zghlxwxcb.cn/news/detail-468684.html
值得注意的是,由于RS485設備屬于被動設備,有的DTU可以自動輪訊,有的DTU是需要上位機下發(fā)指令后才能對RS485設備發(fā)送指令。文章來源地址http://www.zghlxwxcb.cn/news/detail-468684.html
到了這里,關于RS485設備通過DTU上傳數(shù)據(jù)到阿里云物聯(lián)網(wǎng)平臺的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!