數字負載秤是現代工程和設計的另一個奇跡。是的,我們談論的是我們在大多數雜貨店和其他地方經常看到的體重秤,但你有沒有想過體重秤是如何工作的?為了回答這個問題,在這個項目中,我們將看看稱重傳感器及其工作原理。最后,我們將使用 HX711 重量傳感器構建一個基于 Arduino 的便攜式負載秤,它可以測量高達 10 公斤的重量。
這臺稱重機非常適合本地商店,他們在那里批量包裝物品。與商業產品一樣,我們的體重秤將有一個歸零按鈕,可將秤清零。此外,它具有設置重量進行測量的選項,當測量重量達到設定重量時,蜂鳴器快速響起,當設定重量等于測量重量時停止。這樣,用戶只需聽到聲音就可以打包,而不必看顯示器。由于這是一個非常簡單的項目,我們將使用 Arduino 和應變計稱重傳感器等組件非常輕松地構建它。所以,事不宜遲,讓我們開始吧。
Arduino稱重機工作
該項目的主要部件是一個稱重傳感器和HX711 稱重傳感器放大器模塊。如您所見,一側標有十公斤。另外,您會注意到稱重傳感器上方有某種白色保護膠,并出現了四種不同顏色的電線,將在本文后面揭開白色保護膠下面的秘密以及這些四色電線的功能。
稱重傳感器是將力或壓力轉換為電輸出的傳感器。它有兩個側面,比如說右側和左側,它是由鋁塊制成的。正如你所看到的,材料的中間通過放一個大孔變薄了。這就是為什么當負載放置在安裝側時會發生變形的點。現在想象一下,右側傳感器安裝在底座上,左側是放置負載的位置,由于中間的巨大孔,這種配置會使應變儀稱重傳感器變形。
當負載放在稱重傳感器的負載側時,頂部會受到拉力,而底部會受到壓力。這就是鋁條在左側向下彎曲的原因。如果我們測量這種變形,我們可以測量施加在鋁塊上的力,這正是我們要做的。
現在,問題仍然是白色保護膠里面是什么?在這種保護膠里面,我們會發現一個非常薄的彈性元件,叫做應變儀。 應變計是用于測量應變的組件。如果我們仔細觀察這個組件,我們可以看到兩個連接焊盤,然后我們有一個重復偏轉的導線圖案。該導線具有確定的電阻。當我們彎曲它時,電阻值會改變嗎?因此,將應變片的一側安裝并固定在一個地方,如果我們在鋁棒的另一側放置一個重物,這將迫使應變片彎曲,從而導致電阻發生變化。這實際上是如何發生的?應變片的導電圖案是用銅做的,這根導線會有一定的面積??和長度,所以這兩個單元會給出導線的電阻。導線的電阻與電流的流動相反。現在很明顯 如果這條線的面積變小了 更少的電子可以通過意味著更低的電流。現在,如果我們增加面積,它將增加導體的電阻。如果對該線施加一些力,這將拉伸該區域,同時它會變小,電阻會增加。但是這種電阻變化非常小。如果我們拉伸應變片,電阻會增加,如果我們壓縮它,電阻會變小。為了測量力,我們需要測量阻力。直接測量電阻并不總是可行的,因為變化非常小。因此,我們可以輕松地測量電壓,而不是測量電阻。因此,在這種情況下,我們需要將儀表輸出從電阻值轉換為電壓值。如果對該線施加一些力,這將拉伸該區域,同時它會變小,電阻會增加。但是這種電阻變化非常小。如果我們拉伸應變片,電阻會增加,如果我們壓縮它,電阻會變小。為了測量力,我們需要測量阻力。直接測量電阻并不總是可行的,因為變化非常小。因此,我們可以輕松地測量電壓,而不是測量電阻。因此,在這種情況下,我們需要將儀表輸出從電阻值轉換為電壓值。如果對該線施加一些力,這將拉伸該區域,同時它會變小,電阻會增加。但是這種電阻變化非常小。如果我們拉伸應變片,電阻會增加,如果我們壓縮它,電阻會變小。為了測量力,我們需要測量阻力。直接測量電阻并不總是可行的,因為變化非常小。因此,我們可以輕松地測量電壓,而不是測量電阻。因此,在這種情況下,我們需要將儀表輸出從電阻值轉換為電壓值。阻力會越來越低。為了測量力,我們需要測量阻力。直接測量電阻并不總是可行的,因為變化非常小。因此,我們可以輕松地測量電壓,而不是測量電阻。因此,在這種情況下,我們需要將儀表輸出從電阻值轉換為電壓值。阻力會越來越低。為了測量力,我們需要測量阻力。直接測量電阻并不總是可行的,因為變化非常小。因此,我們可以輕松地測量電壓,而不是測量電阻。因此,在這種情況下,我們需要將儀表輸出從電阻值轉換為電壓值。
我們可以在惠斯通電橋的幫助下做到這一點。如果電橋是平衡的,我們將應變計放置在惠斯通電橋中,中間點的電壓應該為零(之前我們已經建立了一個項目,其中我們描述了惠斯通電橋的工作原理,如果你想你可以檢查一下了解有關該主題的更多信息)。當應變片改變其電阻時,會使電橋失衡,電壓也會發生變化。因此,這就是惠斯通電橋將電阻變化轉換為電壓值的方式。
但是這個電壓變化還是很小的,所以要增加它,我們需要使用HX711模塊。HX711 是一個 24 位差分 ADC,通過這種方式,我們可以測量非常小的電壓變化。它將給出從 0 到 2 的指數 24 的值。
基于 Arduino 的稱重機所需的組件
為了使這個項目盡可能簡單,我們使用了非常通用的組件,您可以在任何本地愛好商店中找到這些組件。下圖將讓您了解組件。此外,我們還有下面列出的物料清單 (BOM)。
稱重傳感器(我們使用的是 10 kg 稱重傳感器)
HX 711 功放模塊
Arduino納米
I2C LCD 16X2 – I2C 兼容
1k電阻-2個
LED -2Nos
蜂鳴器
普通PCB
7.4V電池(如果你想要它便攜)
LM7805穩壓器
基于 Arduino 的稱重機 - 電路圖
稱重傳感器有四根電線,分別是紅、黑、綠和白。此顏色可能因制造商而異,因此最好參考數據表。紅色接HX711板子的E+,黑色接E-,白色接A+,綠色接A-,Dout,板子時鐘分別接D4和D5。將按鈕的一端連接到 D3、D8、D9,另一端接地。我們有 I2C LCD,所以將 SDA 連接到 A4,將 SCL 連接到 A5。將 LCD、HX711 和 Arduino 的地連接到地,同時將 VCC 連接到Arduino的 5Vpin 。所有模塊都在 5V 下工作,因此我們添加了一個LM7805 穩壓器。如果您不希望它便攜,您可以使用 USB 電纜直接為 Arduino 供電。
在虛線穿孔板上制作電路
我們已將所有組件焊接在一個普通的點狀穿孔板上。我們使用母頭將 Arduino 和 ADC 與電路板焊接,我們還使用電線連接所有按鈕和 LED。完成所有焊接過程后,我們已確保從 LM7805 輸出正確的 5V。最后,我們設置了一個開關來打開/關閉電路。一旦我們都完成了,它看起來像下面的圖像。
為基于 Arduino 的稱重機構建外殼
如您所見,稱重傳感器有一些螺紋,因此我們可以將其安裝在底板上。我們將使用 PVC 板作為秤的底座,為此,我們首先從 PVC 板上切割出 20*20 厘米的正方形和四個 20*5 的矩形。然后使用硬膠,我們把每一塊都粘起來,做成一個小外殼。
請記住,我們沒有固定一側,因為我們需要在其上放置按鈕、LED 和 LCD。然后我們在秤的頂部使用了一塊塑料板。在永久設置此設置之前,我們需要確保從地面到稱重傳感器有足夠的空間,以便它能夠彎曲,所以我們在稱重傳感器和底座之間放置了螺釘和螺母,我們還添加了稱重傳感器和頂部之間的一些塑料墊片。我們使用圓形塑料板作為平衡的頂級智能。
然后我們將LCD、LED和按鈕放在前面板上,所有東西都用長絕緣線連接。完成布線后,我們將前面板傾斜地粘在主底座上,這樣我們就可以很容易地從 LCD 讀取值。最后,我們將主開關連接到天平的一側,就是這樣。這就是我們為體重秤制作身體的方式。
您可以根據自己的想法進行設計,但請記住將稱重傳感器放置在圖像中。
Arduino稱重機 - 代碼
由于我們現在完成了數字秤的構建過程,我們可以進入編程部分。為了方便編程,我們將使用 HX711 庫、EEPROM 庫和LiquidCrystal 庫。您可以從官方 GitHub 存儲庫下載HX711 庫,或者轉到工具》包含 庫》管理 庫,然后使用關鍵字HX711搜索庫,下載庫后,將其安裝到 Arduino ide 中。
首先,我們需要校準稱重傳感器并將該值存儲在 EEPROM 中,為此,轉到文件 》 示例 》 HX 711_ADC, 然后選擇校準代碼。在上傳代碼之前,將天平放在穩定的平面上。然后將代碼上傳到 Arduino 并打開串行監視器。然后將波特率更改為 572600。現在監視器要求稱重,為此我們需要按 t 并輸入。
現在,我們需要將已知重量放在天平上,在我的例子中,即 194gm。放置已知重量后,在串行監視器上輸入重量,然后按 Enter。
現在,串行監視器詢問您是否要將值保存在 EEPROM 中,因此請鍵入 Y 選擇是。現在我們可以在串行監視器上看到重量。
該項目的主要代碼,我們從 HX711 庫的示例草圖開發。您可以從下面下載該項目的代碼。
在編碼部分,首先,我們添加了所有三個庫。HX711 庫用于獲取稱重傳感器值。EEPROM是Arduino ide的內置庫,用于將值存儲在EEPROM中,LiquidCrystal庫用于l2C LCD模塊。
?
#include#include #include
?
然后為不同的引腳定義整數并分配值。HX711_ADC 稱重傳感器功能用于設置 Dout 和時鐘引腳。
?
常量 int HX711_dout = 4; 常量 int HX711_sck = 5; 詮釋 tpin = 3; HX711_ADC LoadCell(HX711_dout, HX711_sck); 常量 int calVal_eepromAdress = 0; 長 t; 常量 int Up_buttonPin = 9; 常量 int Down_buttonPin = 8; 浮動按鈕PushCounter = 0; 浮動 up_buttonState = 0; 浮動 up_lastButtonState = 0; 浮動 down_buttonState = 0; 浮動 down_lastButtonState = 0;
?
在設置部分,我們首先啟動了串口監視器,這只是為了調試。然后我們定義了引腳模式,所有按鈕都定義為輸入。在 Arduino PULL UP 功能的幫助下,我們通常將引腳設置為邏輯高電平。因此,我們不想為此使用任何外部電阻器。
?
pinMode(tpin,INPUT_PULLUP); pinMode(6,輸出); pinMode(12,輸出); pinMode(Up_buttonPin,INPUT_PULLUP); pinMode( Down_buttonPin , INPUT_PULLUP);
?
以下代碼行用于設置 I2C LCD。首先,我們使用LCD.print()函數顯示歡迎文本,兩秒鐘后,我們使用lcd.clear?()清除顯示。也就是說,一開始,顯示器顯示ARDUINO BALANCE作為歡迎文字,兩秒鐘后,它會清除并顯示測量重量。
?
液晶顯示器(); 液晶背光(); lcd.setCursor(0, 0); lcd.print("ARDUINO 平衡"); lcd.setCursor(0, 1); lcd.print("讓我們測量一下"); 延遲(2000); lcd.clear();
?
然后開始使用loadCell.begin()函數從稱重傳感器讀取值,之后,我們讀取校準值的 EEPROM,我們使用EEPROM.get()函數來完成。也就是說,我們已經使用校準草圖將值存儲在?EEPROM地址中,我們只需重新獲取該值。
?
LoadCell.begin(); EEPROM.get(calVal_eepromAdress,calibrationValue);
?
在循環部分,首先,我們使用LoadCell.update(?)檢查來自稱重傳感器的任何數據是否可用,如果可用,我們讀取并存儲該數據,為此,我們使用LoadCell.getData()。接下來,我們需要在 LCD 中顯示存儲的值。為此,我們使用了LCD.print()函數。另外,我們打印設定的重量。設置重量是在按鈕計數器的幫助下設置的。這在上一節中解釋了。
?
if (LoadCell.update()) newDataReady = true; if (newDataReady) { if (millis() > t + serialPrintInterval) { float i = LoadCell.getData(); lcd.setCursor(0, 0); lcd.print("設置 wei:"); lcd.setCursor(9, 0); lcd.print(buttonPushCounter); lcd.setCursor(14, 0); lcd.print("GM"); lcd.setCursor(0, 1); lcd.print("重量:"); lcd.setCursor(9, 1); lcd.print(i); lcd.setCursor(14, 1); lcd.print("GM");
?
接下來,我們設置皮重值,為此,首先,我們使用?digitalRead()函數讀取皮重按鈕的狀態,如果狀態低,我們將該重量去皮為零。該體重秤的去皮功能是將讀數歸零。例如,如果我們有一個裝有東西的碗,那么凈重將是碗的重量 + 東西的重量。如果我們在裝東西之前用稱重傳感器上的碗按下去皮按鈕,籃子的重量將被抵消,我們可以單獨測量東西的重量。
?
if (digitalRead(tpin) == LOW) { LoadCell.tareNoDelay();
?
現在,我們需要設置不同指示的條件,例如設置蜂鳴器的延遲和 LED 狀態。我們使用if?條件來做到這一點,我們總共有三個條件。首先,我們計算設定重量和測量重量之間的差值,然后將該值存儲在變量 k 中。
?
浮動 k = buttonPushCounter-i ;
?
1.如果設定重量和測量重量的差值大于等于50gms,蜂鳴器會延遲200毫秒(慢)發出蜂鳴聲。
?
if ( k >= 50 ) { digitalWrite (6, HIGH); 延遲(200); 數字寫入(6,低); 延遲(200); }
?
2.如果設定重量與測量重量的差值小于 50 克且大于 1 克,蜂鳴器會延遲 50 毫秒(更快)發出蜂鳴聲。
?
if ( k < 50 && k > 1 ) { digitalWrite (6, HIGH); 延遲(50); 數字寫入(6,低); 延遲(50); }
?
3、當計量重量等于或大于設定值時,綠燈亮,蜂鳴器和紅燈滅。
?
if(i>=buttonPushCounter) { digitalWrite (6, LOW); 數字寫入(12,高); }
?
我們還有兩個 void 函數 () 用于設置設定重量(用于計算按鈕按下)。
每按一次設定值增加10gms的功能。這是通過使用 Arduino 的digitalRead功能來完成的,如果引腳為低電平,這意味著按鈕被按下,并且該值將增加 10gms。
?
up_buttonState = digitalRead(Up_buttonPin); if (up_buttonState != up_lastButtonState) { if (up_buttonState == LOW) { bPress = true; buttonPushCounter = buttonPushCounter + 10; }
?
相似地,
?checkdown 用于每按一次將設定值減少 10gms。
?
down_buttonState = digitalRead(Down_buttonPin); if (down_buttonState != down_lastButtonState) { if (down_buttonState == LOW) { bPress = true; buttonPushCounter = buttonPushCounter - 10; }
?
這標志著編程部分的結束。
這種基于 Arduino 的電子秤非常適合測量高達 10 公斤的重量(我們可以通過使用更高額定的稱重傳感器來增加這個限制)。這與原始測量結果的準確度為 99%。
#include
#include
#include
LiquidCrystal_I2C lcd(0x27, 2, 16);
HX711_ADC LoadCell(HX711_dout, HX711_sck);
常量 int HX711_dout = 4; //mcu > HX711 輸出引腳
常量 int HX711_sck = 5; //mcu > HX711 sck管腳
詮釋 tpin = 3;
常量 int calVal_eepromAdress = 0;
長 t;
常量 int Up_buttonPin = 9; // 按鈕所連接的引腳
常量 int Down_buttonPin = 8;
浮動按鈕PushCounter = 0; // 按鈕按下次數的計數器
浮動 up_buttonState = 0; // 向上按鈕的當前狀態
浮動 up_lastButtonState = 0; //向上按鈕的前一個狀態
浮動 down_buttonState = 0; // 向上按鈕的當前狀態
浮動 down_lastButtonState = 0; //向上按鈕的前一個狀態
布爾 bPress = 假;
無效設置(){
序列號.開始(57600);
延遲(10);
序列號.println();
Serial.println("開始...");
pinMode(tpin,INPUT_PULLUP);
pinMode(6,輸出);
pinMode(12,輸出);
pinMode(Up_buttonPin,INPUT_PULLUP);
pinMode( Down_buttonPin , INPUT_PULLUP);
液晶顯示器();
液晶背光();
lcd.setCursor(0, 0);
lcd.print("ARDUINO 平衡");
lcd.setCursor(0, 1);
lcd.print("讓我們測量一下");
延遲(2000);
lcd.clear();
LoadCell.begin();
浮動校準值;// 校準值(參見示例文件“Calibration.ino”)
校準值 = 696.0;// 如果要在草圖中設置校準值,請取消注釋
#如果定義(ESP8266)|| 定義(ESP32)
//EEPROM.begin(512); // 如果您使用 ESP8266/ESP32 并想從 eeprom 獲取校準值,請取消注釋
#萬一
EEPROM.get(calVal_eepromAdress,calibrationValue); // 如果要從 eeprom 獲取校準值,請取消注釋
穩定時間長 = 2000;// 加電后的精度可以通過增加幾秒鐘的穩定時間來提高
布爾_皮重=真;//如果您不希望在下一步中執行去皮,請將其設置為 false
LoadCell.start(穩定時間,_皮重);
if (LoadCell.getTareTimeoutFlag())
{
Serial.println("超時,檢查 MCU>HX711 接線和引腳名稱");
而(1);
}
別的
{
LoadCell.setCalFactor(校準值);//設置校準值(浮點數)
Serial.println("啟動完成");
}
}
無效循環(){
靜態布爾 newDataReady = 0;
常量 int serialPrintInterval = 0; //增加值以減慢串行打印活動
// 檢查新數據/開始下一次轉換:
if (LoadCell.update()) newDataReady = true;
// 從數據集中獲取平滑值:
如果(新數據就緒)
{
if (millis() > t + serialPrintInterval) {
浮動 i = LoadCell.getData();
Serial.print("Load_cell 輸出值:");
序列號.println(i);
新數據就緒 = 0;
t = 毫秒();
lcd.setCursor(0, 0);
lcd.print("設置 wei:");
lcd.setCursor(9, 0);
lcd.print(buttonPushCounter);
lcd.setCursor(14, 0);
lcd.print("GM");
lcd.setCursor(0, 1);
lcd.print("重量:");
lcd.setCursor(9, 1);
lcd.print(i);
lcd.setCursor(14, 1);
lcd.print("GM");
}
}
清理(??);
checkDown();
如果(數字讀取(tpin)==低){
LoadCell.tareNoDelay();
}
// 檢查最后一次去皮操作是否完成:
if (LoadCell.getTareStatus() == true) {
lcd.clear();
lcd.print("去皮完成");
延遲(1000);
lcd.clear();
}
浮動 i = LoadCell.getData();
浮動 k = buttonPushCounter - i;
如果 ( k < 50 && k > 1 )
{
數字寫入(6,高);
延遲(50);
數字寫入(6,低);
延遲(50);
}
如果 ( k >= 50 )
{
數字寫入(6,高);
延遲(200);
數字寫入(6,低);
延遲(200);
}
if (i >= buttonPushCounter)
{
數字寫入(6,低);
數字寫入(12,高);
}
別的
{
數字寫入(12,低);
}
}
無效檢查()
{
up_buttonState = digitalRead(Up_buttonPin);
// 比較 buttonState 和之前的狀態
if (up_buttonState != up_lastButtonState)
{
// 如果狀態已經改變,增加計數器
如果(up_buttonState == LOW)
{
bPress =真;
// 如果當前狀態為 HIGH,則按鈕從關閉變為打開:
buttonPushCounter = buttonPushCounter + 10;
}
}
// 將當前狀態保存為上一個狀態,以備下次循環使用
up_lastButtonState = up_buttonState;
}
無效 checkDown()
{
down_buttonState = digitalRead(Down_buttonPin);
// 比較 buttonState 和之前的狀態
if (down_buttonState != down_lastButtonState)
{
// 如果狀態已經改變,增加計數器
如果(down_buttonState == LOW)
{
bPress =真;
buttonPushCounter = buttonPushCounter - 10;
}
}
// 將當前狀態保存為上一個狀態,以備下次循環使用
down_lastButtonState = down_buttonState;
}
評論
查看更多