Contents

將 ADC 加入您的 Raspberry Pi:您需要了解什麼

要點

Raspberry Pi無法直接處理類比訊號;但是,它可以配備外部類比數位轉換器 (ADC),將實體電壓值轉換為適合資料儲存、操作和管理的數位格式。

流行的類比數位轉換器 (ADC) 選擇包括在速度和精度之間實現平衡的 MCP3004/MCP3008,以及以較低取樣頻率提供 16 位元解析度的 ADS111x。

Adafruit 提供的 ADS1115 是一款優雅的解決方案,具有可編程增益放大器 (PGA),能夠檢測微小的電壓差異,同時促進運行期間的動態增益調整。透過 I2C 與 Raspberry Pi 整合不會帶來任何挑戰。

Raspberry Pi 在提供類比輸入方面的最初缺陷使其與 Arduino 等面向微控制器的平台區分開來,與這些替代方案相比,這可能會限制其功能。

雖然這看起來令人畏懼,但還有多種替代方案可供探索。您可以先使用 Raspberry Pi 和外部類比數位轉換器 (ADC) 來實現無縫操作。

為什麼要新增輸入?

在自然界中,存在著許多可以透過利用電勢方便地封裝的事件。透過將這些勢轉換成它們的二元等價物,它們可以被存檔、操縱並用作調節其他因素和激活進一步機制的手段。

人們可能希望觀察地球的潮濕程度、溫室的溫暖程度或囓齒動物的重量。人們可能會尋求在 Raspberry Pi 上整合一個電平調節器,建立一整套滑塊,或從頭開始製作一個操縱桿。潛在的應用廣泛且多樣。

ADC 選項

那麼,哪個ADC最適合新手呢?

最受歡迎和最簡單的選項包括 MCP3004(和 MCP3008 ) Microchip 晶片。您將獲得四個(或八個)通道,每個通道 10 位,讀取速度高達 200 kSPS。另一方面,德州儀器 (TI) 的 ADS111x 裝置可以以 860 SPS 讀取 16 位元。因此,速度和精度(當然還有價格)之間需要權衡。

一些微控制器配備了整合式類比數位轉換器 (ADC)。例如,大多數 Arduino 中廣泛使用的 ATMega 提供多個 10 位元解析度通道以及其他功能。此功能使 Arduino 平台能夠支援超出 Raspberry Pi 功能限制的類比輸入訊號。如果現有的 Arduino 整合到專案中並且 10 位元解析度足以滿足所需的精度,則使用現成的 Arduino 解決方案可能被證明是最簡單的做法。

事實上,為了簡單起見,在本例中我們將使用 Adafruit 提供的 ADS1115。

/bc/images/ads1115_photo.png

什麼是可程式增益放大器?

此積體電路具有多種有趣的功能,特別是整合的可編程增益放大器(PGA),它可以對首選幅度頻譜進行數位設定。 PGA 允許將電壓範圍規範低至幾分之一伏,由於 16 位元解析度表示的大量值,因此能夠檢測小至幾微伏特的微小變化。

這種特殊晶片的優點之一是它允許在操作期間調整增益。相較之下,某些其他裝置(例如 MCP3004)採用替代策略,透過合併可施加參考電壓的附加引腳。

多路復用怎麼樣?

多工器(也稱為多工器)用作開關設備,可利用單獨的類比數位轉換器 (ADC) 對來自多個來源的資料進行取樣。在 ADC 積體電路擁有多個輸入端子的情況下,很明顯內部會發生多路復用的固有過程。例如,ADS1115 包含一個多工器元件,能夠容納多達四個不同的輸入訊號,可以透過操縱其固有的暫存器配置來選擇性地選擇這些訊號。

處理暫存器

ADS1115 提供了一系列功能,可以透過操縱多個控制設定輕鬆存取這些功能。其中包括管理多個

每個單獨功能的啟動機制都隱藏在產品包裝的範圍內,表現為稱為「暫存器」的微小資料儲存庫。為了啟用特定功能,只需將適當的暫存器從其預設狀態零更改為值一即可。

查看 ADS111x 資料表,您會發現這些型號帶有四個暫存器,包括管理裝置的配置暫存器€™ 的行為。

/bc/images/as1115_config_register.jpg

在本文中,位元14至12用於控制多工器的操作。透過使用這三個二進制數字,人們可以在八種不同的配置中進行選擇。值得注意的是,這種情況下理想的配置是“100”,因為它決定了輸入通道 0 和接地之間的差分訊號。相反,位 7 至 5 負責調節取樣頻率。為了實現每秒 860 個樣本的最高可能取樣率,將這些位元設為「111」將是理想的。

一旦您確定了要應用的適當設置,您將可以存取可傳輸到類比數位轉換器的總共兩個位元。如果您隨後想要修改各個位,則可以透過單獨使用位元運算來實現。

二進位系統中各個開關狀態的表示可能會造成一些混亂。雖然二進位代碼本身並不直接表示特定的數值,但它可以用來指示每個單獨開關的狀態。此資訊可以用多種格式表示,例如十進位或十六進位符號;然而,為了便於理解並防止潛在的複雜性,通常最好保持使用二進位格式。

連接起來

該設備可以方便地連接到麵包板。其正電壓輸入範圍為 2 至 5.5 伏特,確保與 Raspberry Pi 的 3.3 伏特電源相容。

為了開始操作,將 MCP3008 的 SDA 和 SCL 引腳連接到 Raspberry Pi 上的相應端口,同時連接接地和 3.3V 連接。此外,在接地線和電壓線之間串聯插入一個電位器,然後將電位器中間導體的一端連接到類比數位轉換器 (ADC) 的第一個輸入。完成這些步驟後,您的設定就可以使用了。

處理 I2C

各種類比數位轉換器 (ADC) 利用各種通訊協定進行操作。例如,在 ADS1115 的背景下,我們將採用稱為內部積體電路 (I2C) 的特定介面來進行通訊和資料傳輸。

為了利用 Python 與 Raspberry Pi 上的類比數位轉換器 (ADC) 連接,必須滿足某些先決條件。幸運的是,最近的 Raspberry Pi 作業系統 (OS) 迭代大大簡化了這個過程。若要啟動設定流程,請導覽至系統選單中的“首選項”,然後選擇“Raspberry Pi 設定”。從那裡,進入“介面”選項卡並啟動“I2C”選項。

/bc/images/i2c_enable.jpg

為了確保所有元件正常運行,請透過開啟終端機視窗並執行以下命令來啟動命令列介面:

 sudo i2cdetect -y 1 

所提供的文字描述了一個場景,其中執行特定命令將在網格上產生輸出,其中包含與類比數位轉換器 (ADC) 位址相關的資訊。作者強調,這個十六進位值必須在前面加上「0x」才能在後續程式碼中使用。在本例中,該值表示為 0x48。

/bc/images/20231108_18h24m38s_grim.jpg

利用所獲得的位址,可以利用 SMBus 庫透過利用兩個不同的流程來傳輸 I2C 命令。這些方法之一涉及 write\_word\_data() 函數的使用,該函數需要三個輸入,即裝置位址、要寫入的特定暫存器以及將記錄在所述位置中的所需資料值。

函數 read_word_data() 將裝置位址和暫存器作為輸入,並使類比數位轉換器 (ADC) 連續取樣並將電壓值儲存在指定的暫存器中。這允許隨後從暫存器中檢索儲存的資料。

人們可以選擇增強輸出的視覺呈現並隨後顯示它。在重新進入迭代循環之前,可以實施短暫的暫停或延遲。這種方法有助於防止資訊過載。

 from smbus import SMBus
import time
addr = 0x48
bus = SMBus(1)

# set the registers for reading
CONFIGREG = 1
CONVERSIONREG = 0

# set the address register to point to the config register
# write to the config registers
bus.write_word_data(addr, CONFIGREG, (0b00000100 << 8 | 0b10000010))

 # define the top of the range
TOP = 26300

while True:
    # read the register
    b = bus.read_word_data(addr, CONVERSIONREG)

    # swap the two bytes
    b = ((b & 0xFF) << 8) | ((b >> 8) & 0xFF)
    
    # subtract half the range to set ground to zero
    b -= 0x8000

    # divide the result by the range to give us a value between zero and one
    b /= TOP

    # cap at one
    b = min(b, 1)

    # bottom is zero
    b = max(b, 0)

    # two decimal places
    b = round(b, 2)
    print(b)
    time.sleep(.01)

將變數的資料類型轉換為符合首選格式後,必須將結果值對應到原始比例中對應的對應值。這允許在兩組值之間進行有意義的比較。之後,您可以透過設定適當的小數位數來選擇丟棄任何多餘的數字。若要僅顯示更新的結果,請修改列印功能以僅在新值與先前顯示的值不同時顯示新值。有關 max、min 和 round 的更多信息,請參閱我們對 20 個最重要的 Python 函數的彙編。

處理噪音

在環境缺乏高度組織性和有序性的情況下,所收集的資料中可能明顯存在某些不必要的元素。這種現象可歸因於以下事實:使用較小範圍的值(例如 16 位元解析度而不是 10 位元)會導致遇到這些幹擾或「雜訊」的可能性增加。

將輸入一接地並設定設備以比較輸入一和輸入二時,可以實現更高的讀數穩定性。此外,可以使用具有電容增強功能的較短跨接電纜來取代較長、雜訊較大的版本。此外,調整電位器的電阻水平也會影響性能。

或者,可以利用軟體解決方案來管理數據波動。一種可能的方法包括計算移動平均值或完全忽略微小的變化。然而,這種做法會增加計算負擔。當使用 Python 等高階程式語言並每秒處理大量樣本時,這些費用會加速累積。

進一步採取許多可能的後續步驟

利用 I2C 進行讀取是一個相對簡單的過程,與 SPI 等替代方法的情況類似。儘管各種 ADC 替代方案之間存在明顯差異,但現實情況是,一旦成功實施其中任何一種方案,所獲得的專業知識就可以輕鬆應用於其他方案。

為什麼不進一步拓展新建的電位器控制器的界線呢?透過串聯多個電位器或嘗試測量光、聲音或溫度等變量,人們可以探索與 Raspberry Pi 系統互動的新可能性。透過擴展目前專案的功能並透過實作實驗創造完全互動的體驗,踏上令人興奮的旅程。