日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于Arduino的HX711称重实验

發布時間:2023/12/29 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于Arduino的HX711称重实验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

HX711模組稱重實驗

  • 實驗原理
    • 應變片橋式電路原理
    • HX711原理
    • 實驗接線圖
  • 實驗代碼(Arduino)
  • 數據處理
  • 實驗代碼中Arduino對應的庫文件

實驗原理

用應變片搭建橋式電路,通過壓力使應變片發生改變,應變片電阻發生變化,即兩端電壓發生變化,橋路輸出電壓發生變化輸出正是傳感器測量的輸出。通過HX711芯片將稱重片上的壓力變化導致的電壓值變化的模擬量轉化為數字量。即可根據輸入數值與輸出數值通過EXCELL擬合出二者的關系

應變片橋式電路原理

稱重器內部應變片電橋原理圖如下:

HX711原理

簡介:

HX711是一款專為高精度稱重傳感器而設計的24位A/D轉換器芯片。與同類型其它芯片相比,該芯片集成了包括穩壓電源、片內時鐘振蕩器等其它同類型芯片所需要的外圍電路,具有集成度高、響應速度快、抗干擾性強等優點。降低了電子秤的整機成本,提高了整機的性能和可靠性。該芯片與后端MCU芯片的接口和編程非常簡單,所有控制信號由管腳驅動,無需對芯片內部的寄存器編程。輸入選擇開關可任意選取通道A或通道B,與其內部的低噪聲可編程放大器相連。通道A的可編程增益為128或64,對應的滿額度差分輸入信號幅值分別為±20mV或±40mV。通道B則為固定的32增益,用于系統參數檢測。芯片內提供的穩壓電源可以直接向外部傳感器和芯片內的A/D轉換器提供電源,系統板上無需另外的模擬電源。芯片內的時鐘振蕩器不需要任何外接器件。上電自動復位功能簡化了開機的初始化過程。

特點:

兩路可選擇差分輸入

片內低噪聲可編程放大器,可選增益為64 和128

片內穩壓電路可直接向外部傳感器和芯片內A/D 轉換器提供電源

片內時鐘振蕩器無需任何外接器件,必要時也可使用外接晶振或時鐘

上電自動復位電路

簡單的數字控制和串口通訊:所有控制由管腳輸入,芯片內寄存器無需編程

可選擇10Hz 或80Hz 的輸出數據速率

同步抑制50Hz 和60Hz 的電源干擾

耗電量(含穩壓電源電路):典型工作電流:<1.7mA, 斷電電流:<1μA

工作電壓范圍:2.6 ~ 5.5V

工作溫度范圍:-20 ~ +85℃

16 管腳的SOP-16 封裝

模擬輸入

通道A模擬差分輸入可直接與橋式傳感器的差分輸出相接。由于橋式傳感器輸出的信號較小,為了充分利用A/D轉換器的輸入動態范圍,該通道的可編程增益較大,為128或64。這些增益所對應的滿量程差分輸入電壓分別±20mV或±40mV。通道B為固定的32增益,所對應的滿量程差分輸入電壓為±80mV。通道B應用于包括電池在內的系統參數檢測。

供電電源

數字電源(DVDD)應使用與MCU芯片相同的的數字供電電源。HX711芯片內的穩壓電路可同時向A/D轉換器和外部傳感器提供模擬電源。穩壓電源的供電電壓(VSUP)可與數字電源(DVDD)相同。穩壓電源的輸出電壓值(VAVDD)由外部分壓電阻R1、R2 和芯片的輸出參考電壓VBG決定(圖1),VAVDD=VBG(R1+R2)/R2。應選擇該輸出電壓比穩壓電源的輸入電壓(VSUP)低至少100mV。如果不使用芯片內的穩壓電路,管腳VSUP和管腳AVDD應相連,并接到電壓為2.6~5.5V的低噪聲模擬電源。管腳VBG上不需要外接電容,管腳VFB應接地,管腳BASE 為無連接。

時鐘選擇

如果將管腳XI接地,HX711將自動選擇使用內部時鐘振蕩器,并自動關閉外部時鐘輸入和晶振的相關電路。這種情況下,典型輸出數據速率為10Hz或80Hz。如果需要準確的輸出數據速率,可將外部輸入時鐘通過一個20pF的隔直電容連接到XI管腳上,或將晶振連接到XI和XO管腳上。這種情況下,芯片內的時鐘振蕩器電路會自動關閉,晶振時鐘或外部輸入時鐘電路被采用。此時,若晶振頻率為11.0592MHz,輸出數據速率為準確的10Hz或80Hz。輸出數據速率與晶振頻率以上述關系按比例增加或減少。使用外部輸入時鐘時,外部時鐘信號不一定需要為方波??蓪CU芯片的晶振輸出管腳上的時鐘信號通過20pF的隔直電容連接到XI管腳上,作為外部時鐘輸入。外部時鐘輸入信號的幅值可低至150mV。

串口通訊

串口通訊線由管腳PD_SCK和DOUT組成,用來輸出數據,選擇輸入通道和增益。當數據輸出管腳DOUT為高電平時,表明A/D轉換器還未準備好輸出數據,此時串口時鐘輸入信號PD_SCK應為低電平。當DOUT從高電平變低電平后,PD_SCK應輸入25至27個不等的時鐘脈沖(圖二)。其中第一個時鐘脈沖的上升沿將讀出輸出24位數據的最高位(MSB),直至第24個時鐘脈沖完成,24位輸出數據從最高位至最低位逐位輸出完成。第25至27個時鐘脈沖用來選擇下一次A/D轉換的輸入通道和增益,參見下圖。


PD_SCK的輸入時鐘脈沖數不應少于25或多于27,否則會造成串口通訊錯誤。當A/D轉換器的輸入通道或增益改變時,A/D轉換器需要4個數據輸出周期才能穩定。DOUT在4個數據輸出周期后才會從高電平變低電平,輸出有效數據。
根據以上讀數據原理官方編寫HX711芯片的驅動程序庫(采用c++編寫,主要要看begin()方法和read()方法)如下:

/**** HX711 library for Arduino* https://github.com/bogde/HX711** MIT License* (c) 2018 Bogdan Necula* **/ #include <Arduino.h> #include "HX711.h"// TEENSYDUINO has a port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3. #define HAS_ATOMIC_BLOCK (defined(ARDUINO_ARCH_AVR) || defined(TEENSYDUINO))// Whether we are running on either the ESP8266 or the ESP32. #define ARCH_ESPRESSIF (defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32))// Whether we are actually running on FreeRTOS. #define IS_FREE_RTOS defined(ARDUINO_ARCH_ESP32)// Define macro designating whether we're running on a reasonable // fast CPU and so should slow down sampling from GPIO. #define FAST_CPU \( \ARCH_ESPRESSIF || \defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || \defined(ARDUINO_ARCH_STM32) || defined(TEENSYDUINO) \)#if HAS_ATOMIC_BLOCK // Acquire AVR-specific ATOMIC_BLOCK(ATOMIC_RESTORESTATE) macro. #include <util/atomic.h> #endif#if FAST_CPU // Make shiftIn() be aware of clockspeed for // faster CPUs like ESP32, Teensy 3.x and friends. // See also: // - https://github.com/bogde/HX711/issues/75 // - https://github.com/arduino/Arduino/issues/6561 // - https://community.hiveeyes.org/t/using-bogdans-canonical-hx711-library-on-the-esp32/539 uint8_t shiftInSlow(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {uint8_t value = 0;uint8_t i;for(i = 0; i < 8; ++i) {digitalWrite(clockPin, HIGH);delayMicroseconds(1);if(bitOrder == LSBFIRST)value |= digitalRead(dataPin) << i;elsevalue |= digitalRead(dataPin) << (7 - i);digitalWrite(clockPin, LOW);delayMicroseconds(1);}return value; } #define SHIFTIN_WITH_SPEED_SUPPORT(data,clock,order) shiftInSlow(data,clock,order) #else #define SHIFTIN_WITH_SPEED_SUPPORT(data,clock,order) shiftIn(data,clock,order) #endifHX711::HX711() { }HX711::~HX711() { }void HX711::begin(byte dout, byte pd_sck, byte gain) {PD_SCK = pd_sck;DOUT = dout;pinMode(PD_SCK, OUTPUT);pinMode(DOUT, INPUT_PULLUP);set_gain(gain); }bool HX711::is_ready() {return digitalRead(DOUT) == LOW; }void HX711::set_gain(byte gain) {switch (gain) {case 128: // channel A, gain factor 128GAIN = 1;break;case 64: // channel A, gain factor 64GAIN = 3;break;case 32: // channel B, gain factor 32GAIN = 2;break;}}long HX711::read() {// Wait for the chip to become ready.wait_ready();// Define structures for reading data into.unsigned long value = 0;uint8_t data[3] = { 0 };uint8_t filler = 0x00;// Protect the read sequence from system interrupts. If an interrupt occurs during// the time the PD_SCK signal is high it will stretch the length of the clock pulse.// If the total pulse time exceeds 60 uSec this will cause the HX711 to enter// power down mode during the middle of the read sequence. While the device will// wake up when PD_SCK goes low again, the reset starts a new conversion cycle which// forces DOUT high until that cycle is completed.//// The result is that all subsequent bits read by shiftIn() will read back as 1,// corrupting the value returned by read(). The ATOMIC_BLOCK macro disables// interrupts during the sequence and then restores the interrupt mask to its previous// state after the sequence completes, insuring that the entire read-and-gain-set// sequence is not interrupted. The macro has a few minor advantages over bracketing// the sequence between `noInterrupts()` and `interrupts()` calls.#if HAS_ATOMIC_BLOCKATOMIC_BLOCK(ATOMIC_RESTORESTATE) {#elif IS_FREE_RTOS// Begin of critical section.// Critical sections are used as a valid protection method// against simultaneous access in vanilla FreeRTOS.// Disable the scheduler and call portDISABLE_INTERRUPTS. This prevents// context switches and servicing of ISRs during a critical section.portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;portENTER_CRITICAL(&mux);#else// Disable interrupts.noInterrupts();#endif// Pulse the clock pin 24 times to read the data.data[2] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST);data[1] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST);data[0] = SHIFTIN_WITH_SPEED_SUPPORT(DOUT, PD_SCK, MSBFIRST);// Set the channel and the gain factor for the next reading using the clock pin.for (unsigned int i = 0; i < GAIN; i++) {digitalWrite(PD_SCK, HIGH);#if ARCH_ESPRESSIFdelayMicroseconds(1);#endifdigitalWrite(PD_SCK, LOW);#if ARCH_ESPRESSIFdelayMicroseconds(1);#endif}#if IS_FREE_RTOS// End of critical section.portEXIT_CRITICAL(&mux);#elif HAS_ATOMIC_BLOCK}#else// Enable interrupts again.interrupts();#endif// Replicate the most significant bit to pad out a 32-bit signed integerif (data[2] & 0x80) {filler = 0xFF;} else {filler = 0x00;}// Construct a 32-bit signed integervalue = ( static_cast<unsigned long>(filler) << 24| static_cast<unsigned long>(data[2]) << 16| static_cast<unsigned long>(data[1]) << 8| static_cast<unsigned long>(data[0]) );return static_cast<long>(value); }void HX711::wait_ready(unsigned long delay_ms) {// Wait for the chip to become ready.// This is a blocking implementation and will// halt the sketch until a load cell is connected.while (!is_ready()) {// Probably will do no harm on AVR but will feed the Watchdog Timer (WDT) on ESP.// https://github.com/bogde/HX711/issues/73delay(delay_ms);} }bool HX711::wait_ready_retry(int retries, unsigned long delay_ms) {// Wait for the chip to become ready by// retrying for a specified amount of attempts.// https://github.com/bogde/HX711/issues/76int count = 0;while (count < retries) {if (is_ready()) {return true;}delay(delay_ms);count++;}return false; }bool HX711::wait_ready_timeout(unsigned long timeout, unsigned long delay_ms) {// Wait for the chip to become ready until timeout.// https://github.com/bogde/HX711/pull/96unsigned long millisStarted = millis();while (millis() - millisStarted < timeout) {if (is_ready()) {return true;}delay(delay_ms);}return false; }long HX711::read_average(byte times) {long sum = 0;for (byte i = 0; i < times; i++) {sum += read();// Probably will do no harm on AVR but will feed the Watchdog Timer (WDT) on ESP.// https://github.com/bogde/HX711/issues/73delay(0);}return sum / times; }double HX711::get_value(byte times) {return read_average(times) - OFFSET; }float HX711::get_units(byte times) {return get_value(times) / SCALE; }void HX711::tare(byte times) {double sum = read_average(times);set_offset(sum); }void HX711::set_scale(float scale) {SCALE = scale; }float HX711::get_scale() {return SCALE; }void HX711::set_offset(long offset) {OFFSET = offset; }long HX711::get_offset() {return OFFSET; }void HX711::power_down() {digitalWrite(PD_SCK, LOW);digitalWrite(PD_SCK, HIGH); }void HX711::power_up() {digitalWrite(PD_SCK, LOW); }

復位和斷電
當芯片上電時,芯片內的上電自動復位電路會使芯片自動復位。管腳PD_SCK輸入用來控制HX711的斷電。當PD_SCK為低電平時,芯片處于正常工作狀態。

實驗接線圖

實驗代碼(Arduino)

#include "HX711.h" HX711 hx ;//誤差系數 void setup() { //hx.reset();hx.begin(D4, D5);Serial.begin(9600); } void loop() { double sum = 0; for (int i = 0; i < 10; i++) sum += hx.read(); Serial.println(sum/10); delay(3000);}

數據處理

使用arduino 的串口工具讀出電壓的離散值,作出對應關系表格,再將表格數據用excell擬合,即可得到對應關系,本次實驗擬合 的是線性關系,靈敏度即為擬合線趨勢線的斜率。下面展示我得到的實驗數據及結果

實驗代碼中Arduino對應的庫文件

鏈接:https://pan.baidu.com/s/1PloT7_o7hERhte_LXG1jsg
提取碼:h2kp
HX711學習參考博客:HX711

總結

以上是生活随笔為你收集整理的基于Arduino的HX711称重实验的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。