Подключение Ардуино к тензодатчику, при помощи модуля HX711

Тензодатчик - устройство позволяющее фиксировать изменения приложенной к нему силы. На него подается питающее напряжение, которое изменяется на выходе, пропорционально приложенной нагрузке. Благодаря взаимосвязи между силой и выходным напряжением тензодатчики получили широкое распространение во всех областях где требуется решать задачи измерения веса.

Из-за хорошей линейности характеристик, невысокой стоимости и простоты работы с ними, на текущий момент, тензодатчики практически вытеснили все механические весы. В этой статье мы рассмотрим вопросы подключения тензодатчика к плате Ардуино при помощи модуля HX711, и постараемся определить для каких целей можно применять подобное решение, а для каких лучше использовать промышленные весовые контроллеры и преобразователи тензосигнала.

В качестве АЦП для преобразования сигнала с тензодатчика мы будем использовать 24-разрядный аналого-цифровой преобразователь, называемый HX711. С его помощью Ардуино будет получать информацию о текущей нагрузке на тензодатчик и выводить это значение на индикатор.

Для работы с модулем HX711 мы возьмем стандартную библиотеку, дабы не усложнять себе жизнь и проверить насколько точную весоизмерительную систему можно собрать из готовых компонент. Чтобы установить библиотеку, перейдите в диспетчер библиотек в среде IDE Arduino и введите HX711. Мы будем использовать библиотеку от Богдана Некула (Bogdan Necula), самая верхняя на приведенном ниже скриншоте.

Помимо модуля АЦП и платы Ардуино нам понадобятся:

  • 0.96 Oled дисплей, вариант I2C
  • 4 тактовые кнопки
  • 4 резистора 10кОм

После сборки платы необходимо загрузить в вашу ардуино исполняемый код, его можно создать из скетча приведенного в конце данной статьи. А результат его работы можно посмотреть на видео:

#include <Wire.h>
#include "HX711.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // ширина дисплея в пикселях 
#define SCREEN_HEIGHT 64 // высота дисплея в пикселях

// Создаем объект дисплея 
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int Button_1 = 22;  //Кнопка увеличения коэффициента калибровки
int Button_2 = 23;  //Кнопка уменьшения коэффициента калибровки
int Button_3 = 24;  //Кнопка применения коэффициента калибровки
int Button_4 = 25;  //Кнопка назначения нулевого веса

// Подключение модуля ацп
const int LOADCELL_DOUT_PIN = A0;
const int LOADCELL_SCK_PIN = A1;

// Создаем Объект модуля АЦП
HX711 scale;

float calibration_factor =3178.0  ; // коэффициент калибровки
float cal_y1 = 500.0; // calibrated mass to be added
long cal_x1 = 0L;
long cal_x0 = 0L;

float units;  //Код АЦП
float gramm;  // Вес в граммах
float gramm_max=0;  // определение разброса
float gramm_min=1000;  // определение разброса


void setup() {
  // Запускаем дисплей
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) // по адрессу 0x3С 
  { 
    Serial.println(F("SSD1306 allocation failed")); //выводим сообщение если не получилось
    for(;;);
  }

 
  // Очищаем дисплей
  display.clearDisplay();   
  display.setTextColor(WHITE); 
  display.setTextSize(1); 

  // Выводим информационый экран
  display.setTextSize(2); 
  display.setTextColor(WHITE); 
  display.setCursor(0,32); 
  display.println("TMM-002");
  display.setTextSize(1); 
  display.setCursor(0,48); 
  display.println("WWW.INTEREL.RU");
  display.display();

  //Запускаем АЦП
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.set_scale();
  
 //scale.set_scale(calibration_factor);       //Применяем калибровку
   pinMode(Button_1, INPUT);
   pinMode(Button_2, INPUT);
   pinMode(Button_3, INPUT);
   pinMode(Button_4, INPUT);

    delay(5000);
}

void loop() {


  
  Serial.print("Reading: ");
  
  //for(int i = 0;i < 10; i ++) units =+ scale.get_units(), 10;   // усредняем показания считав 10 раз 
  //units / 10;                                                   // делим на 10

units = scale.get_units(10);

  gramm = units;                                    // переводим унции в граммы              
  Serial.print(gramm);                                          // отправляем в монитор порта
  Serial.print(" grams");  
  Serial.println(); 
  display.clearDisplay();

  display.setTextSize(1); 
  display.setCursor(0,0);

if (gramm_min>gramm)gramm_min=gramm;
if (gramm_max<gramm)gramm_max=gramm;

 //Увеличиваем коэффициент калибровки
if(digitalRead(Button_1) == LOW) {
 display.print("1: On"); 
 gramm_max=0;
 gramm_min=1000;
 } else {
 display.print("1: Off");
 }

  display.setCursor(0,8);

 //Уменьшаем коэффициент калибровки
if(digitalRead(Button_2) == LOW) {
 display.print("2: On"); 
calibration_factor=gramm/500.0f;
 scale.set_scale(calibration_factor);       //Применяем калибровку
 
 } else {
 display.print("2: Off");
 }

  display.setCursor(64,0);

 //Применяем калибровочный коэффициент
if(digitalRead(Button_3) == LOW) {
 display.print("3: On"); 
 scale.set_scale(); // Сбрасываем калибровку
 gramm_max=0;
 gramm_min=1000; } else {
 display.print("3: Off");
 }
  display.setCursor(64,8);

 //Принимаем текущий вес за 0
if(digitalRead(Button_4) == LOW) {
 display.print("4: On"); 
   scale.tare();                              //Сбрасываем на 0
 //  scale.set_scale(calibration_factor);       //Применяем калибровку
 gramm_max=0;
 gramm_min=1000;
 } else {
 display.print("4: Off");
 }


  // Выводим на экран информацию о текущем весе
  display.setTextSize(2); 
  display.setCursor(0,16);
  display.print("BEC:");
  display.println(gramm);

  display.setTextSize(2); 
  display.setCursor(0,32);
  display.print("DIF:");
  display.println(gramm_max-gramm_min);

    display.setTextSize(2); 
  display.setCursor(0,48);
    display.print("K:");
  display.println(calibration_factor);


  display.display();
}