2016年3月3日 星期四

用 HT1632 LED 矩陣和 HX711 讀取重量感測器

這次要玩的是重量感測器

從露天拍賣取得, 應該是由浙江三科所販賣的半橋式重量感測器
詳細資料從掏寶網擷取:電阻應變半橋傳感器
沒技術支持, 不懂不要買 ! 霸氣 ! XD


使用方法就是照上圖右那樣擺, 從中間半圓球突起處施加壓力
上圖左是背面圖, 施壓後紅框處會產生應變, 上面固定的特製電阻就會改變阻值
一共有兩顆電阻, 當往固定方向施壓時, 例如上圖右那樣放然後往下壓
其中一顆電阻阻抗會增加, 而另一顆電阻則是阻抗會減少
所以掏寶網的說明中兩顆電阻分別寫正應變和負應變
由於量測點是在上圖左紅框處, 施加壓力時要固定外框
紅框下方的鐵片不可接觸到物體, 應保持懸空, 這樣才能產生應變
如果施加過大壓力把懸空處拗到彎了, 那這東西就壞了

這是從感測器側面拍的

可以看到受力點刻意突起, 並沒有直接壓在電線上
由此可知感測器量測的不是壓力, 而是鐵片的應變

這裡有一些關於應變重量感測器的介紹:Getting Started with Load Cells
裡面其中一段:

這裡介紹了如何量測這種感測器, 電路是惠斯登電橋
不過玩法有點不同, 惠斯登電橋是用已知阻值電阻去計算未知電阻阻值
我們這感測器的阻值會隨著應變而改變, 沒有一個阻值是已知的
因此應用上我們只是借用惠斯登電橋的算法來評估量測結果
簡單的說, 就只是電阻分壓而已
如上圖, R1 和 R2 就代表一個重量感測器, R3 和 R4 則代表另一個重量感測器
接法在上圖下半部, 假設 R1, R2 組成的重量感測器為正應變負應變電阻
那麼 R3, R4 組成的重量感測器則為負應變正應變電阻
注意應變正負要相反, 理由是電阻分壓依據惠斯登電橋的公式
上圖那公式有點錯誤, 可參考惠斯登電橋中的公式, 套到上圖應該是:

Vout = [ ( R4 / (R3+R4) ) - ( R2 / (R1+R2) ) ] * Vin

如果 R1, R3 都是正應變, R2, R4 都是負應變
假設兩個感測器受力平均, 那麼受到壓力時
R1, R2 的中點電壓會和 R3, R4 的中點電壓相同, 同時上升或下降
量測它們倆中點電壓的電壓差將永遠是 0
就算不是 0, 這樣的設計意思是兩個變化量相減, 這值沒有意義
因此要將另一顆感測器的電阻反接, 這樣才會拉大電壓差
讓兩側的變化量相加, 這樣的量測結果才有意義, 總變化量才是我們要的


在我們開始玩弄這玩具之前, 我找來了另一個玩具:

LED 矩陣顯示器, 用它來顯示量測結果

背面的樣子

上面安裝了一顆 Atmega8 的 MCU, 以及一個 HT1632 矩陣 LED 控制器
這控制器可以調整輸出亮度:

上圖為最暗和最亮的差別
這板子原本是當電子時鐘賣的, 由於我有玩過幾顆 AVR 的 MCU, 就把它轉做其他用途
像這樣:

接上 USBASP 的 ISP 即可寫入

電路板上就有寫接腳定義, 稍微用電錶導通測試測一下就知道怎麼接
然後再用電錶導通測試測兩 IC 的接腳, 可以找到接線方式:
PB3 接到 CS, PB4 接到 WR, PB5 接到 DATA
PB5 是 AVR SPI 的 SCK 接腳, 應該接到 WR 當 CLK 才對
但線路卻沒這樣接, 後來研究 HT1632 發現這貨用奇怪的 bit 數來控制
前 3 bit 是 ID, 然後跟 9 bit 命令, 資料模式則是 3 bit ID, 7 bit 位址, 然後 8 bit 資料
並不像那些專門給有 DMA 功能的 SPI 裝置總是以 byte 為單位
既然沒法用硬體 SPI, 那就 GPIO 慢慢拉唄

另外, 這張板子規劃的圖像排列是 8-bit 由下往上, 然後再由左往右
和 LCD 常用的直立 8-bit 由左往右到底不同
由於多數 LCD 都是這樣, 所以我不想為了這貨改變我的字庫, 不划算
所以在我源碼 ht1632.c 的 ht1632c_update_all() 中用了麻煩的轉換輸出
也因為這種怪排法, 部份更新不太好做, 所以更新時就索性整個畫面重畫

這顆 IC 初始化流程在 ht1632.c 中:

SWSPI_CS_0;
swspi_xfer(3, 0x4); // cmd mode 100
swspi_xfer(9, 0x2); // system osc on
swspi_xfer(9, 0x6); // LED on
swspi_xfer(9, 0x140); // 1/16 duty
swspi_xfer(9, 0x15E); // 16/16 duty
SWSPI_CS_1;

把 CS 拉低, 然後送 3 個 bit 表示指令模式
swspi_xfer(3, 0x4);  ← 3 就是 bit 數, 0x4 就是 3-bit 內容
接著連續四個 9-bit, 其中最後兩個命令 1/16 是最暗, 16/16 是最亮
註解最後一個命令就會變最暗, 送完後 CS 拉高即可

接著回來看我們的重力感測器
一開始我本來想用 OP 放大器放大電壓差然後直接塞給 AVR 的 ADC
但是實際量測發現......這感測器的電阻值變化太小了, 導致電壓差變化都是 mV 為單位
這樣放大也不容易, 倍數要非常高, 所以只好找現成的專用模組來用:

HX711, 這是顆 24-bit ADC, 具有內建 128 倍放大器
它和上面的 HT1632 類似, 都是使用奇怪 bit 數的序列傳輸, 所以只能用 GPIO 做
可以注意到上圖黑白兩線接法, 表示兩個感測器接電源時相反

讀取 HX711 只要兩條線, 一條 DATA 和一條 CLK
讀取流程:

檢查 DATA 是否在高電位, 若是, 表示 ADC 轉換中, 此時要等待
等到 DATA 拉低時, CLK 低→高→低 可以得到 1 bit 資料
拉 24 個 CLK 就讀完一筆轉換結果, 此時 DATA 電位高
這時流程還沒結束
如果下一筆資料想要從 Channel A 讀取 128 倍放大, 就要多拉一個 CLK
如果下一筆資料想要從 Channel B 讀取 32 倍放大, 就要多拉兩個 CLK
如果下一筆資料想要從 Channel B 讀取 64 倍放大, 就要多拉三個 CLK
也就是說, 讀取這 IC 至少要送 25 個 CLK, 最多送 27 個 CLK
最後三個 CLK 決定下一筆資料從哪讀

由於每個感測器阻抗不同, 電壓差也會不同, 所以要校正
我是讀出 0 的時候的 ADC 結果, 顯示到 LED 上, 然後把值寫死到韌體
如果要當體重計使用, 就必須做校正功能, 把 0 時讀到的值存起來
然後每次都減去這定值

至於讀到的值每個 bit 代表幾公克, 這我沒法從規格書判斷, 看不太懂...
也有可能規格裡沒有寫, 我就拿已知重量的物體去算, 然後除一個定值, 看起來好像還行...

這裡放出源碼:led-weight-meter.zip


板上的 Atmega8 預設用內建 RC 運行於 1 MHz, 挺慢的, 建議改 FUSE 提高速度
makefile 中這個:

#AVRDUDE_WRITE_FLASH += -U lfuse:w:0xe4:m -U hfuse:w:0xd9:m

解除註解刷上後再把註解加回去, 只要寫一次即可
讓 AVR 用內部 RC 以 8 MHz 運行

整張板子連線:


拿一個鉛蓄電池用電子秤量得 1549 公克


丟到我的感測器上:

1.5 公斤, 大致吻合
後來有量測 20 公斤物體, 重量也正確, 應該還能用
它就只能用來量測粗略值, 到 0.1公斤還行, 再下去到 0.01 時漂移的蠻嚴重的
應該是和高倍數 ADC 放大有關, 而且這感測器會有疲勞的現象
如果壓著太久, 它會沒法回到 0, 而會在 0.1~0.3 公斤左右, 所以量測單位應該就 0.1 公斤了

19 則留言:

  1. 可以請教你 你的訊號經過hx711後 怎麼換算成重量嗎...謝謝你

    回覆刪除
    回覆
    1. hx711 的讀出值減去校正值後再除一個定值, 就這樣而已
      每個感測器會有誤差都不一樣, 因此須自行量測校正值
      而除的定值也和感測器與 hx711 設定的放大率有關
      如果把我程式裡的數字直接套上保證是不會動的, 這都需要自行量測!

      刪除
    2. 可以教一下怎麼測校正值嗎...謝謝你

      刪除
    3. 感測器空載不要放東西, 然後把 HX711 讀到的值丟出來即可
      如果板上有 UART 就從 UART 丟, 它會不斷的跳動, 等個幾秒取最大值即可

      刪除
    4. 放知道重量上去測他的值 再去算嗎?

      刪除
    5. 作者已經移除這則留言。

      刪除
    6. 是的, 一樣是一直把值丟出來, 減去校正值再除已知重量即可

      刪除
    7. 4個七段顯示器 顯示的出來校正值嗎

      刪除
    8. 這要看你選的放大率以及需要的精確度
      我的是取五位數, 取最高五位, 後面低位數的都丟掉
      不過以這顆抖動的情況取高四位數應該是夠的, 就都試看看吧

      刪除
    9. 能跟你要個FB或line 比較好能請教你嗎@@

      刪除
    10. 作者已經移除這則留言。

      刪除
    11. 我沒有 line 也沒 FB, 平常上班沒閒用
      上面那篇留 ID 的建議刪掉以防廣告
      如果是缺基礎技術建議去找 arduino, 到處都有教學
      可以從 UART 丟資料會比較簡單, 不用考慮刪除幾位的問題

      刪除
  2. 作者已經移除這則留言。

    回覆刪除
  3. 想請問這個模組能用來量微小的電壓嗎?大概mV左右

    回覆刪除
    回覆
    1. 它是設計來量測 mV 的微小電壓沒錯, 但是須注意參考點
      HX711 量的是兩組電阻的中點電壓差, 它有點像聲音訊號
      當我們在處理聲音訊號時和一般從接地量起的訊號作法是不同的
      這部份我沒有學的很多, 只能提醒有這點不同
      至於怎麼處理比較好我不清楚

      刪除
  4. 請問 可以問一下重量感測那邊的程式怎麼寫嗎 原碼那個我不知道怎麼用 下載了以後要怎麼做?

    回覆刪除
    回覆
    1. 這是 ubuntu 上用的, 安裝 avr-gcc 就可以用 make 編譯
      如果是 windows 系統就只能提供做參考, windows 要如何安裝我不清楚...
      印象中 avr-gcc 和 make 都有 windows 版

      刪除
    2. 我看了一下 makefile 裡的註解才想起來, 以前是用 WinAVR 做的
      只是換到 ubuntu 以後又有修改過, 之後都是以 ubuntu 開發為主
      可以 Google 搜尋 winavr教學 試試, 應該是能編過但沒測過不保證

      刪除

注意:只有此網誌的成員可以留言。