Общие сведения:
Тензодатчики (типа "мост" и типа "полу-мост") и микросхема HX711 — связка, которая позволит создавать устройства для измерения веса или давления, оказываемого на поверхность датчика, а затем передавать эти показания (с высокой точностью) на плату Arduino.
Видео:
Спецификация:
Спецификация HX711
- Разрядность АЦП: 24 бит;
- Коэффициент усиления:
- Вход А: 64 или 128;
- Вход В: 32;
- Частота измерений: 10/80 Гц;
- Напряжение питания: 5В;
- Потребляемый ток: до 10 мА;
- Размеры: 34мм х 21мм;
Спецификация тензодатчиков мостовых
- Максимальный вес: 1/5/10/20 кг;
- Отверстия под винты: M4/M5 (подходит под винт с потайной головкой);
- Размеры: 14мм х 14мм х 80.5мм;
Спецификация тензодатчика полумостового
- Максимальный вес: 50 кг;
- Размеры: 34мм х 34мм х 9мм;
Подробнее о плате HX711:
Микросхема HX711 позволяет с высокой точностью получать показания веса или давления, оказываемого на тензодатчик (он же - тензорезистор).
Микросхема имеет 2 канала считывания показания счётчика: А и В:
- Канал А имеет возможность выбора коэффициента усиления: 64 или 128.
- Канал В имеет фиксированный коэффициент усиления, равный 32.
Это позволяет подключать к микросхеме HX711 до 2 независимых тензодатчиков! Однако, следует помнить, что чем выше коэффициент усиления, тем выше точность измерения показаний.
Подробнее о датчиках:
Тензорезистивные датчики предназначены для создания на их основе весов, датчиков давления или концевых датчиков.
В основе своей конструкции имеют тонкоплёночные резисторы, которые изменяют своё сопротивление при деформации.
Существует 2 версии данных датчиков:
- 1 — те, в которых резисторы объединены в мост, подключённый непосредственно к АЦП, который фиксирует изменения значений резисторов. Датчики выполнены из алюминия, имеют форму бруска с 4 отверстиями на одной плоскости и особым сдвоенным отверстием на другой. При установке датчике в рабочее положение необходимо жёстко закрепить одну его сторону, а на вторую установить (при необходимости) платформу для завешивания грузов. Имеют на выходе из датчика 4 провода.
Схема устройства и подключения мостового датчика к микросхеме HX711:
- 2 — те, в которых резисторы объединены в полумост, подключаются между собой, чтобы образовать полный мост и, затем, подключаются к АЦП, который фиксирует изменения значений резисторов. Имеют на выходе из датчика 3 провода. Схема их устройства и подключения следующая:
Схема устройства и подключения полу-мостового датчика к микросхеме HX711:
Для 1 тензодатчика:
Для 4 тензодатчиков:
Обратите внимание на то, что если полученные значения имеют отрицательный знак, то вам следует поменять местами датчики, подключенные к выводам А+ и А -
Следует также отметить, что показания тензодатчиков зависят от температуры окружающей среды — при разных температурах показания могут отличаться. Помните это и используйте "тарирование" (обнуление значений датчика) каждый раз при резких перепадах температуры. Если же работа датчика предполагается в условиях перепада температур в известном диапазоне, то вы можете воспользоваться одним из датчиков температуры и создать таблицу зависимости калибровочного коэффициента (calibration_factor
) от температуры.
Подключение:
Микросхема HX711
На плате есть два разъёма – P1 и P2, на которых имеются следующие обозначения:
Разъём P1
- GND - земля;
- VCC - питание 5В;
- DT, SCK – информационные выводы;
Разъём P2
- E– , E+ - питание тензорного моста;
- A– , A+ - подключение канала А;
- В– , В+ - подключение канала В;
Тензодатчик (мостовой)
У данного тензодатчика 4 выходных провода:
Провода тензодатчика | Выводы микросхемы HX711 |
Красный провод | E+ |
Чёрный провод | E- |
Зелёный провод | A- |
Белый провод | A+ |
Тензодатчик (полумостовой)
У данного тензодатчика 3 выходных провода:
Провода тензодатчика | Выводы микросхемы HX711 |
Красный провод | E+ |
Чёрный провод | E- |
Белый провод | A+ |
Провода тензодатчика | Выводы микросхемы HX711 |
---|---|
Зелёный провод | A- |
HX711
Данная плата подключается к Arduino по 4 проводам:
Выводы микросхемы HX711 | Выводы Arduino |
GND | GND |
VCC | 5V |
DT | любой цифровой вывод (указывается в скетче) |
SCK | любой цифровой вывод (указывается в скетче) |
Подключение HX711 к Arduino можно осуществить одним из 2 способов:
- Напрямую к плате Arduino/Piranha UNO:
- К одному из шилдов для подключения:
Питание:
Входное напряжение 5В, подаётся на выводы Vcc (V) и GND (G).
Примеры:
Калибровочный скетч для мостового датчика
#include "HX711.h" // подключаем библиотеку для работы с АЦП и тензодатчиками HX711 scale; // создаём объект scale для работы с тензодатчиком uint8_t DOUT_PIN = 7; // указываем вывод DOUT, к которому подключен HX711 uint8_t SCK_PIN = 6; // указываем вывод SCK , к которому подключен HX711 float weight_of_standard = 167.8; // указываем эталонный вес float conversion_rate = 0.035274; // указываем коэффициент для перевода из унций в граммы const int z = 10; // указываем количество измерений, по которым будет найдено среднее значение float calibration_value[z]; // создаём массив для хранения считанных значений float calibration_factor = 0; // создаём переменную для значения калибровочного коэффициента void setup() { Serial.begin(57600); // инициируем работу с последовательным портом на скорости 57600 бод scale.begin(DOUT_PIN, SCK_PIN); // инициируем работу с платой HX711, указав номера выводов Arduino, к которым подключена плата scale.set_scale(); // не калибруем полученные значения scale.tare(); // обнуляем вес на весах (тарируем) Serial.println("You have 10 seconds to set your known load"); // выводим в монитор порта текст о том, что у вас есть 10 секунд для установки эталонного веса на весы delay(10000); // ждём 10 секунд Serial.print("calibration factor: "); // выводим текст в монитор поседовательного порта for (int i = 0; i < z; i++) { // запускаем цикл, в котором calibration_value[i] = scale.get_units(1) / (weight_of_standard / conversion_rate); // считываем значение с тензодатчика и переводим его в граммы calibration_factor += calibration_value[i]; // суммируем все значения } calibration_factor = calibration_factor / z; // делим сумму на количество измерений Serial.println(calibration_factor); // выводим в монитор порта значение корректирующего коэффициента } void loop() {}
Вывод значений веса с 1 мостового тензодатчика в монитор последовательного порта (после калибровки)
#include "HX711.h" // подключаем библиотеку для работы с тензодатчиком #define DT A0 // Указываем номер вывода, к которому подключен вывод DT датчика #define SCK A1 // Указываем номер вывода, к которому подключен вывод SCK датчика HX711 scale; // создаём объект scale float calibration_factor = -14.15; // вводим калибровочный коэффициент float units; // задаём переменную для измерений в граммах float ounces; // задаём переменную для измерений в унциях void setup() { Serial.begin(9600); // инициируем работу последовательного порта на скорости 9600 бод scale.begin(DT, SCK); // инициируем работу с датчиком scale.set_scale(); // выполняем измерение значения без калибровочного коэффициента scale.tare(); // сбрасываем значения веса на датчике в 0 scale.set_scale(calibration_factor); // устанавливаем калибровочный коэффициент } void loop() { Serial.print("Reading: "); // выводим текст в монитор последовательного порта for (int i = 0; i < 10; i ++) { // усредняем показания, считав значения датчика 10 раз units = + scale.get_units(), 10; // суммируем показания 10 замеров } units = units / 10; // усредняем показания, разделив сумму значений на 10 ounces = units * 0.035274; // переводим вес из унций в граммы Serial.print(ounces); // выводим в монитор последовательного порта вес в граммах Serial.println(" grams"); // выводим текст в монитор последовательного порта }
Вывод значений веса с 4 мостовых тензодатчиков в монитор последовательного порта (после калибровки)
#include "HX711.h" // подключаем библиотеку для работы с платой HX711 HX711 load_cells[4]; // создаём 4 объекта для работы с тензодатчиками const uint8_t CLK[4] = { 2, 4, 6, 8}; // создаём массив с номерами выводов Arduino, к которым подключен вывод SCK const uint8_t DOUT[4] = { 3, 5, 7, 9}; // создаём массив с номерами выводов Arduino, к которым подключен вывод DOUT const float GAIN[4] = { -14.16, -14.14, -8.58, -13.45}; // создаём массив с корректирующими коэффициентами для каждого датчика float loads[4] = { 0.0, 0.0, 0.0, 0.0}; // создаём массив для хранения значений с каждого датчика float total_load = 0.0; // создаём переменную для хранения конечного значения веса uint8_t BUTTON_PIN = A0; // указываем вывод, к которому подключена кнопка тары float conversion_rate = 0.035274; // указываем коэффициент для перевода из унций в граммы void setup() { Serial.begin(57600); // инициируем работу с последовательным портом на скорости 57600 бод pinMode(BUTTON_PIN, INPUT_PULLUP); // настраиваем вывод для работы с кнопкой в режим ВХОДА for (int i = 0; i < 4; i++) { // выполняем цикл, в котором load_cells[i].begin(DOUT[i], CLK[i]); // выполняем инициализацию 4 тензодатчиков load_cells[i].set_scale(GAIN[i]); // устанавливаем корректирующие коэффициенты для каждого тензодатчика load_cells[i].tare(); // обнуляем значение на каждом датчике (тарируем) } } void loop() { if (digitalRead(BUTTON_PIN)) { // если кнопка была нажата, то Serial.println("Button push!"); // выводим текст в монитор последовательного порта о том, что кнопка была нажата for (int i = 0; i < 4; i++) { // выполняем цикл, в котором load_cells[i].tare(); // обнуляем значения веса на каждом тензодатчике } } total_load = 0.0; // обнуляем значение измеренного веса for (int i = 0; i < 4; i++) { // выполняем цикл, в котором loads[i] = load_cells[i].get_units(1) * conversion_rate; // считываем значение веса на каждом тензодатчике и преобразуем их из унций в граммы total_load += loads[i]; // суммируем все значения } Serial.println(total_load); // выводим в монитор последовательного порта значение веса delay(700); // ждём 700 мс }
Калибровочный скетч для полумостового датчика
#include "HX711.h" // подключаем библиотеку для работы с АЦП и тензодатчиками HX711 scale; // создаём объект scale для работы с тензодатчиком uint8_t DOUT_PIN = 3; // указываем вывод DOUT, к которому подключен HX711 uint8_t SCK_PIN = 2; // указываем вывод SCK , к которому подключен HX711 float weight_of_standard = 637; // указываем эталонный вес float conversion_rate = 0.035274; // указываем коэффициент для перевода из унций в граммы float calibration_factor = 0; // создаём переменную для значения калибровочного коэффициента void setup() { Serial.begin(57600); // инициируем работу с последовательным портом на скорости 57600 бод scale.begin(DOUT_PIN, SCK_PIN); // инициируем работу с платой HX711, указав номера выводов Arduino, к которым подключена плата scale.set_scale(); // не калибруем полученные значения scale.tare(); // обнуляем вес на весах (тарируем) Serial.println("You have 10 seconds to set your known load"); // выводим в монитор порта текст о том, что у вас есть 10 секунд для установки эталонного веса на весы delay(10000); // ждём 10 секунд Serial.print("calibration factor: "); // выводим текст в монитор поседовательного порта calibration_factor = scale.get_units(10) / (weight_of_standard / conversion_rate); // считываем значение с тензодатчика Serial.println(calibration_factor); // выводим в монитор порта значение корректирующего коэффициента } void loop() {}
Вывод значений веса с 1 полумостового тензодатчика в монитор последовательного порта (после калибровки)
#include "HX711.h" // подключаем библиотеку для работы с тензодатчиком uint8_t DOUT_PIN = 3; // указываем вывод DOUT, к которому подключен HX711 uint8_t SCK_PIN = 2; // указываем вывод SCK , к которому подключен HX711 HX711 scale; // создаём объект scale float calibration_factor = -0.64; // вводим калибровочный коэффициент float units; // задаём переменную для измерений в граммах float ounces; // задаём переменную для измерений в унциях void setup() { Serial.begin(57600); // инициируем работу последовательного порта на скорости 9600 бод scale.begin(DOUT_PIN, SCK_PIN); // инициируем работу с датчиком scale.set_scale(); // выполняем измерение значения без калибровочного коэффициента scale.tare(); // сбрасываем значения веса на датчике в 0 scale.set_scale(calibration_factor); // устанавливаем калибровочный коэффициент } void loop() { Serial.print("Reading: "); // выводим текст в монитор последовательного порта ounces = scale.get_units(10); // получаем значение с датчика, усреднённое по 10 измерениям units = ounces * 0.035274; // переводим вес из унций в граммы Serial.print(ounces); // выводим в монитор последовательного порта вес в граммах Serial.println(" grams"); // выводим текст в монитор последовательного порта }
Вывод значений веса с 4 полумостовых тензодатчиков, объединённых в мост в монитор последовательного порта (после калибровки)
#include "HX711.h" // подключаем библиотеку для работы с тензодатчиком uint8_t DOUT_PIN = 3; // указываем вывод DOUT, к которому подключен HX711 uint8_t SCK_PIN = 2; // указываем вывод SCK , к которому подключен HX711 HX711 scale; // создаём объект scale float calibration_factor = -0.77; // вводим калибровочный коэффициент float units; // задаём переменную для измерений в граммах float ounces; // задаём переменную для измерений в унциях void setup() { Serial.begin(57600); // инициируем работу последовательного порта на скорости 9600 бод scale.begin(DOUT_PIN, SCK_PIN); // инициируем работу с датчиком scale.set_scale(); // выполняем измерение значения без калибровочного коэффициента scale.tare(); // сбрасываем значения веса на датчике в 0 scale.set_scale(calibration_factor); // устанавливаем калибровочный коэффициент } void loop() { Serial.print("Reading: "); // выводим текст в монитор последовательного порта ounces = scale.get_units(10); // получаем значение с датчика, усреднённое по 10 измерениям units = ounces * 0.035274; // переводим вес из унций в граммы Serial.print(ounces); // выводим в монитор последовательного порта вес в граммах Serial.println(" grams"); // выводим текст в монитор последовательного порта }
Описание функций библиотеки:
Подключение библиотеки:
#include "HX711.h" // подключаем библиотеку для работы с платой HX711 #define DT A0 // Указываем номер вывода, к которому подключен вывод DT #define SCK A1 // Указываем номер вывода, к которому подключен вывод SCK HX711 scale; // создаём объект для работы с тензодатчиком
Функция begin();
- Назначение: инициирование работы микросхемы;
- Синтаксис: begin(ПАРАМЕТР_1, ПАРАМЕТР_2, ПАРАМЕТР_3);
- Параметры:
- Обязательные:
- ПАРАМЕТР_1 — указание вывода Arduino, к которому подключен вывод DOUT микросхемы HX711;
- ПАРАМЕТР_2 — указание вывода Arduino, к которому подключен вывод SCK микросхемы HX711;
- Необязательный:
- ПАРАМЕТР_3 — указание коэффициента усиления по входу: 32 (канал В), 64/128 (канал А). Если параметр не указан, будет установлено значение 128.
- Обязательные:
- Возвращаемые значения: Нет;
- Примечание:
- Функцию необходимо вызвать до обращения к любым другим функциям библиотеки;
- Функцию достаточно вызвать один раз в коде
setup
;
- Пример:
scale.begin(DT, SCK); // инициируем работу с датчиком
Функция is_ready();
- Назначение: проверка готовности АЦП к работе;
- Синтаксис: is_ready();
- Параметры: нет
- Возвращаемые значения:
- true - готов к работе / false - не готов;
- Примечание: нет;
- Пример:
scale.is_ready(); // проверка готовности АЦП к работе
Функция set_gain();
- Назначение: установка коэффициента усиления;
- Синтаксис: set_gain(ПАРАМЕТР);
- Параметры:
- ПАРАМЕТР - значение коэффициента усиления: 32, 64, 128;
- Возвращаемые значения: нет;
- Примечание:
- Для канала А это значения 64 или 128;
- Для канала В это значение 32;
- Пример:
scale.set_gain(64); // Устанавливаем значение коэффициента усиления равным 64 (канал А)
Функция read();
- Назначение: считывание "сырых" значений из АЦП;
- Синтаксис: read();
- Параметры: нет;
- Возвращаемые значения: "сырое" значение из АЦП;
- Примечание:
- Можно указать как до функции
set_scale()
, так и после неё. Это влияет на конечный результат, так как в первом случае калибровочный коэффициент не учитывается;
- Можно указать как до функции
- Пример:
scale.read(); // Считывание "сырых" значений из АЦП
Функция read_average();
- Назначение: запрос среднего значения веса из АЦП (в унциях);
- Синтаксис: read_average(ПАРАМЕТР);
- Параметры:
- ПАРАМЕТР — количество измерений, взятых из АЦП, по которым вычисляется среднее значение;
- Возвращаемые значения: среднее значение измерений из АЦП;
- Примечание:
- Можно указать как до функции
set_scale()
, так и после неё. Это влияет на конечный результат, так как в первом случае калибровочный коэффициент не учитывается; - Для перевода веса из унций в граммы, необходимо полученное значение умножить на
0.035274
; - Пример:
scale.read_average(10); // считывание среднего значения по 10 измерениям
Функция get_value();
- Назначение: запрос значения, скорректированного с учётом веса тары (в унциях);
- Синтаксис: get_value(ПАРАМЕТР);
- Параметры:
- ПАРАМЕТР — количество измерений, взятых из АЦП, по которым вычисляется среднее значение;
- Возвращаемые значения: значение веса с учётом тары;
- Примечание:
- Можно указать как до функции
set_scale()
, так и после неё. Это влияет на конечный результат, так как в первом случае калибровочный коэффициент не учитывается; - Для перевода веса из унций в граммы, необходимо полученное значение умножить на
0.035274
;
- Можно указать как до функции
- Пример:
scale.get_value(10); // Запрос среднего значения веса (по 10 замерам), из которого уже вычтена масса тары
Функция get_units();
- Назначение: запрос значения, скорректированного с учётом веса тары и калибровочного коэффициента (в унциях);
- Синтаксис: get_units(ПАРАМЕТР);
- Параметры:
- ПАРАМЕТР — количество измерений, взятых из АЦП, по которым вычисляется среднее значение;
- Возвращаемые значения: значение веса с учётом тары и калибровочного коэффициента;
- Примечание:
- Можно указать как до функции
set_scale()
, так и после неё. Это влияет на конечный результат, так как в первом случае калибровочный коэффициент не учитывается; - Для перевода веса из унций в граммы, необходимо полученное значение умножить на
0.035274
; - Пример:
scale.get_units(5); // Запрос среднего значения веса (по 5 замерам), из которого уже вычтена масса тары и внесён калибровочный коэффициент
Функция tare();
- Назначение: запрос значения тары, который будет вычтен из конечного значения веса (в унциях);
- Синтаксис: tare(ПАРАМЕТР);
- Параметры:
- ПАРАМЕТР — количество измерений, взятых из АЦП, по которым вычисляется среднее значение;
- Возвращаемые значения: значение веса тары;
- Примечание:
- Для перевода веса из унций в граммы, необходимо полученное значение умножить на
0.035274
; - Пример:
scale.tare(3); // Запрос среднего значения веса тары (по 3 замерам)
Функция set_scale();
- Назначение: задание калибровочного коэффициента для перевода "сырых" значений АЦП в "удобочитаемые";
- Синтаксис: set_scale(ПАРАМЕТР);
- Параметры:
- ПАРАМЕТР — значение калибровочного коэффициента;
- Возвращаемые значения: нет;
- Примечание:
- Пример:
scale.set_scale(-4.5); // Установка калибровочного коэффициента
Функция get_scale();
- Назначение: запрос значения установленного калибровочного коэффициента;
- Синтаксис: get_scale();
- Параметры: нет
- Возвращаемые значения: значение калибровочного коэффициента;
- Примечание: нет;
- Пример:
scale.get_scale(); // Запрос калибровочного коэффициента
Функция set_offset();
- Назначение: задание веса тары "вручную" (в унциях);
- Синтаксис: set_offset(ПАРАМЕТР);
- Параметры:
- ПАРАМЕТР — значение веса тары (в унциях);
- Возвращаемые значения: нет;
- Примечание:
- Для перевода веса из унций в граммы, необходимо полученное значение умножить на
0.035274
; - Пример:
scale.set_offset(14175); // Установка веса тары, равной 14175 унций или 500 грамм
Функция get_offset();
- Назначение: запрос значения установленного веса тары (в унциях);
- Синтаксис: get_offset();
- Параметры: нет
- Возвращаемые значения: значение веса тары;
- Примечание:
- Для перевода веса из унций в граммы, необходимо полученное значение умножить на
0.035274
; - Пример:
scale.get_offset(); // Запрос веса тары
Функция power_down();
- Назначение: перевод модуля в спящий режим;
- Синтаксис: power_down();
- Параметры: нет
- Возвращаемые значения: нет;
- Примечание: нет;
- Пример:
scale.power_down(); // Перевод модуля в спящий режим
Функция power_up();
- Назначение: вывод модуля из спящего режима;
- Синтаксис: power_up();
- Параметры: нет
- Возвращаемые значения: нет;
- Примечание: нет;
- Пример:
scale.power_up(); // Вывод модуля из спящего режима
Применение:
- системы контроля и измерения веса;
- концевые датчики, системы;
Обсуждение