tft每日頭條

 > 汽車

 > 車庫門自行打開咋弄

車庫門自行打開咋弄

汽車 更新时间:2024-06-16 09:28:57

本文以不用原配鑰匙無線電遙控打開車庫電動卷簾門為目标,深入研究了ASK/OOK的編/解碼,并用樹莓派 五元錢的發射模塊實現了打開車庫門的各種姿勢。本文适用于主流315/433MHz射頻遙控。

背景

車庫裝了電動卷簾門,為了了解其安全性,也是為了能自主控制,研究了下其遙控原理。其實在這個過程中,我測試了家裡幾乎所有的無電線遙控器,包括電動窗簾、投影幕布、電動衣架、車鑰匙。除了車鑰匙,其它都是類似的,即ASK/OOK編碼。

ASK,簡單的理解,就是調幅,用不同的幅度來代表不同的信息。OOK是ASK的特例,因為隻有0和1要表示,可以用有載波來代表1,無載波來代表0。但實際上并不是這麼直接,通常會加上脈寬調制(PWM)以提高抗幹擾能力。

用HackRF确定可行性

據說有的車庫門是滾動碼的(編碼是變化的),我們可以先用HackRF做個簡單的重放攻擊測試。

錄制2秒的信号并重放:

hackrf_transfer -f 433920000 -s 2000000 -a 1 -r capture.raw -n 4000000 -g 40 -l 16 hackrf_transfer -f 433920000 -s 2000000 -a 1 -t capture.raw -x 40

部分運行提示:

call hackrf_set_sample_rate(2000000 Hz/2.000 MHz) call hackrf_set_hw_sync_mode(0) call hackrf_set_freq(433920000 Hz/433.920 MHz) call hackrf_set_amp_enable(1) samples_to_xfer 4000000/4Mio Stop with Ctrl-C 3.9 MiB / 1.000 sec = 3.9 MiB/second 3.9 MiB / 1.000 sec = 3.9 MiB/second 0.3 MiB / 1.000 sec = 0.3 MiB/second Exiting... hackrf_is_streaming() result: streaming terminated (-1004)

實測用錄制的信号是可以控制的(如果不行,注意調整HackRF放大器的增益)。但這個沒多大技術含量,而且成本高,數據量也大。我們的目标是解碼後再重新編碼/重放。

用GNU Radio錄制信号

用GNU Radio搭一個簡單的接收框圖,一方面将接收信号保存到文件,另一方面将信号以瀑布圖顯示作為實時反饋。因為遙控信号是433.92MHz,中心頻率設在這個附近都可以;采樣率2M就夠了。

車庫門自行打開咋弄(我是怎麼打開車庫門的)1

下圖是運行時的瀑布圖,其中按了5次遙控器。

車庫門自行打開咋弄(我是怎麼打開車庫門的)2

用 Inspectrum 手動解碼

用apt-get安裝inspectrum,或下載最新的Inspectrum代碼,按照文檔自行編譯。試過Debian和Mac下都沒問題(Mac下用MacPorts要安裝一堆依賴)。編譯就不多說了,下面是解碼的主要步驟:

  1. 用Inspectrum打開前面錄制的文件,設置采樣率為錄制時的采樣率(2M);
  2. 水平拖動,找到有信号的區域;
  3. 在原始信号上右鍵,Add derived plot => Add sample plot;
  4. 此時原始信号上會出現兩條水平線,用鼠标拖動,調節中心頻率的位置和寬度;
  5. 在原始信号上右鍵,Add derived plot => Add amplitude plot;
  6. 在Amplitude plot上右鍵,Add derived plot => Add threshold plot;
  7. 勾選”Enable cursors”,此時會出現兩條豎線;
  8. Zoom放大信号圖,移動兩條豎線,使其寬度包含一個符号。注意跳過前導的高低電平(start1, start0)。數據通常是脈寬編碼的,一對高低電平的組合代表一個bit:高電平較寬的代表1,低電平較寬的代表0。從圖中應該能看出這個規律。
  9. 改變符号數,使其包含整個信号區域(圖中是65個符号,這相當于完整的key),并調節首尾對齊(結束時通常有較長的低電平),這時可以得到符号的速率,即波特率(對OOK,其實等同于比特率)。

車庫門自行打開咋弄(我是怎麼打開車庫門的)3

最後,在Amplitude plot或Threshold plot上分别點右鍵,Extract symbols (to stdout),可以得到解碼的數據。其中前者相當于模拟信号,簡單理解:正數代表1,負數代表0;後者才是我們想要的bit流。

車庫門自行打開咋弄(我是怎麼打開車庫門的)4

為确認解碼正确,可以再選一段信号區域,做同樣的操作,看結果是否一緻。畢竟ASK抗幹擾不強,有時候可能會差一兩個bit。通常,按一下遙控器,同樣的數據會重複發送幾次。

遙控信号編碼分析

根據前面的解碼,以及對更多遙控器的分析,可以歸納出一個模型。一個ASK信号包含如下部分(參數):

  • start1: 起始的高電平時間長度;
  • start0: 起始的低電平時間長度;
  • stop0: 結束的低電平時間長度;
  • period: 每個bit的周期,在PWM編碼中,每個bit都對應一對高/低電平,而且總是先高後低;
  • duty: 占空比,比如占空比是75%,則意味着一個周期内如果75%左右是高電平,則代表1; 而75%左右是低電平則代表0;
  • bits: 實際的bit流。

這裡的占空比肯定是大于50%的,通常在75%左右比較合适,這樣既能拉開(每個周期内)兩種電平的比例差,減少接收端的誤判;又能保證接收時能采樣到兩種電平,也是為了減少誤碼。試想對于99%的占空比,1%周期的電平很可能被接收端采樣不到,導緻采樣到199%(甚至更長)周期的同一種電平,這樣解碼時就會出錯。

發射模塊

最初,我是想用GNU Radio做ASK/OOK編碼并發射的。萬能的HackRF和SDR按說能搞定這個小Case。

研究了下,發現這并不是一件容易的事。需要使用很多的模塊。這也許是一個很好的GNU Radio的練習題。但我還是先看下有沒有更簡單的辦法。

然後口水了一下TI的EZ430-Chronos手表,找了下“廉價”的RFcat,發現并不容易買到。最後在萬能的假貨寶發現了真正廉價的東東:隻要5元!(你買不了吃虧,買不了上當。。)

這個模塊很簡單,就是把輸入的信号以433/315M的載波調制/發射出去。DATA為高電平,就按高電平調幅輸出(請注意,這裡調制的是電平,并不是數據。也就是說,數據”1″對應多長時間的高電平,多長時間的低電平,這個模塊都不管的——這些是編碼模塊要處理的事)。

車庫門自行打開咋弄(我是怎麼打開車庫門的)5

用Python編碼

為了代碼的模塊化,也是為了減少發射時的計算量,我們采取先編碼再發送的方案。根據前面建立的ASK信号的模型,将這個信号編碼為高低電平交替的波形,并用一個數組表示,數組中每個元素存儲高低電平切換時對應的時間戳。波形總是以高電平開始。

起始/結束電平的時長、占空比這些參數理論上并不需要嚴格準确,但這取決于接收端的寬容度,所以我們還是盡量忠實于原信号。

下面是核心的Python代碼片斷,其中ts是時間戳數組。

def encodePWM(self, ts): t = 0 ts.append(t) t = self.start1 ts.append(t) t = self.start0 ts.append(t) for i in range(0, self.bits.len): w = self.duty if self.bits[i] else 1 - self.duty ts.append(t self.period * w) t = self.period ts.append(t) ts[-1] = self.stop0

用樹莓派發送

發送工作就很簡單了:将發射模塊的DATA腳與樹莓派的某個GPIO相連,電源也直接用樹莓派的;

車庫門自行打開咋弄(我是怎麼打開車庫門的)6

然後根據時間戳交替翻轉對應的GPIO就行了。下面是Python的核心代碼。

def send(self, ts): b = 1 t1 = time.time() GPIO.output(self.pin_tx, b) t1 -= ts[0] for t in ts[1:-1]: b = 1 - b wait = t1 t - time.time() if wait > 0: time.sleep(wait) GPIO.output(self.pin_tx, b) wait = t1 ts[-1] - time.time() if wait > 0: time.sleep(wait)

用sleep控制時間盡管有一定誤差,腳本語言的運行也沒那麼快,但實測是夠用的。下圖是示波器上看到的DATA引腳的波形圖(兩個通道都連着DATA腳)。

車庫門自行打開咋弄(我是怎麼打開車庫門的)7

為便于觀察,我将編碼周期設置為1ms,和示波器界面的1ms/div對應。圖中測量的間距是2.78ms(預期是2.75ms),偏差是可接受的。

多種姿勢打開車庫門

把發射的裝置放在車庫内,并連上網絡,我們就可以無需鑰匙自主控制車庫門的開/關了。

手機開關門

不需要自己寫App,用ssh終端密鑰登錄并執行命令,就可以手機一鍵開/關門了,并且可以遠程控制。

車庫門自行打開咋弄(我是怎麼打開車庫門的)8

自動開關門

以指定手機作為鑰匙,當持手機靠近車庫時(其實是連上車庫WiFi後),就自動開門。大緻流程是:

  1. 遠程執行路由器的 iwinfo 命令(如下)檢測連接在上面的設備;
  2. 如果作為鑰匙的手機的MAC在列表裡,并且信号強度(SNR)超過設定值,就計為一個有效的連接。當連接數從0變為非0時,就自動開門。
  3. 如果鑰匙手機的有效連接數降到0, 就自動關門。

ssh root@192.168.12.34 'iwinfo ra0 assoclist && iwinfo rai0 assoclist'

自動關門的好處是可以防止人走了忘了關門(俺家真的發生過)。

芝麻開門

理論上可以做到,但需要可靠的聲紋識别。這個就算了。。

鎖死車庫門

把發射模塊對應的GPIO設為高電平,由于發射模塊信号強,距離近,接收端收到的總是1,導緻用真的鑰匙也開不了門。

結語

不用滾動碼編碼的車庫門其實是毫無安全性可言的。不管是簡單的原始信号重放、還是解碼後再編碼的重放都比較容易實現。但我們可以利用這種不安全為自己提供便利,更靈活地自主開/關門。另外,用發射模塊發射高電平可以幹擾鑰匙的信号達到鎖死車庫門的效果。

但如果不是通過監聽鑰匙的信号,用暴力破解Key也并不是那麼容易的。因為ASK編碼除了需要數據吻合,載波頻率相同,還需要數據編碼速率,甚至起止電平的時長都要一緻。

用廉價的硬件發射模塊配合樹莓派(或單片機)可以低成本地編碼/發射ASK/OOK信号,簡單易行。而HackRF加Inspectrum解碼僅适合實驗和調試用,實用價值不高。後續将會嘗試ASK/OOK的自動解碼(解碼可以用來做什麼,你懂的)。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关汽車资讯推荐

热门汽車资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved