Электронные весы Arduino + HX711 + Python

Мало купить Arduino и написать для него десяток программ, которые мигают светодиодами, реагируют на нажатие кнопок, и измеряют температуру воздуха терморезистором.
Рано или поздно нужно сделать своё первое законченное устройство, от которого будет польза.
Для меня таким устройством стал аппаратно-программный комплекс для снятия данных с датчика силы.

Задача

Передо мной встала задача измерять силу в пределах до 2000 кг (около 20 килоньютонов).
Для этого я купил балочный одноточечный датчик силы KELI SQB-A с максимальной нагрузкой до 500 кг (увеличить измеряемый диапазон я решил с помощью рычага).

Датчик силы

Датчик силы на 500 кг

Далее, выяснилось, что данный датчик выдаёт измеряемую величину в таком виде, что её придётся как-то подготавливать для ввода в компьютер.

Сначала была мысль подавать сигнал с датчика на микрофонный вход ПК (есть даже программы для того чтобы из ПК сделать асцилограф таким образом), но её я быстро похоронил, так как для ввода данных понадобилось преобразовывать сигнал в звуковые колебания, амплитуда которых как раз должна быть пропорциональна силе сигнала, на что у меня не хватало знаний в электронике.
В интернете я нашел информацию об АЦП (аналогово-цифровом преобразователе) HX711, который как раз и используется для тензодатчиков и электронных весов. Практически сразу же нашлась схема подключения этого АЦП к Arduino, на чём я и решил остановиться.

Схема подключения датчика, HX711, Arduino

Схема подключения датчика к HX711 и к Arduino

АЦП HX711

АЦП HX711

Код Arduino

Далее, потребовалось написать программу для Arduino, чтобы считывать данные, приходящие от HX711 на цифровые входы А0 и А1. К счастью, для этого АЦП уже есть стандартная библиотека.

1) В Arduino-IDE открываем интерфейс управления библиотекам
Управление библиотеками

2) В фильтр вбиваем «HX711» и нажимаем кнопку «Установить»
Фильтр и установка HX711

3) Добавляем библиотеку в код
Подключение библиотеки

4) Теперь пишем простой как пробка код и заливаем его в Ардуино:

#include <Q2HX711.h>
//Инициализируем библиотеку для считывания данных с входов A0 и A1
Q2HX711 hx711(A1, A0);
//Номер контакта для светодиода
const int led = 2;
 
void setup() {
  //Открываем последовательный порт на скорости 230400
  Serial.begin(230400);
  //Зажигаем светодиод (он у нас просто для индикации)
  digitalWrite(led, HIGH);
}
 
void loop() {
  //Пишем в порт число, считанное с HX711
  Serial.println(hx711.read());
}

При подключении Arduino к ПК через USB-кабель, и включении монитора последовательного порта, в него начинают сыпаться числа, даже если не подключёны АЦП HX711 и датчик. Если же они подключены, то числа сыпятся даже не случайные, а взаимосвязанные с силой нажатия на датчик.

Данные в мониторе порта

Считывание данных и преобразование их в килограммы или ньютоны

Числа, выдаваемые arduino, колеблются в пределах от 0 до 16 миллионов, при этом, «начало координат» находится примерно на 8 миллионах. То есть, когда на датчик не оказывается никакого давления, значение выдаётся близкое к 8000000, если давить на датчик, то значение будет уменьшаться, а если тянуть (создавать противоположное усилие), значение будет увеличиваться.

Чтобы как-то этими числами пользоваться, нужно иметь возможность сделать 2 вещи:

1) Определить ноль — найти то число, которое считать нулём. Например, если на датчик устанавливается какой-то обвес, который сам по себе что-то весит, то нулевая точка сместится (относительно датчика без всяких обвесов), поэтому нужна возможность выбирать за «начало координат» любое число.

2) Определить коэффициент, позволяющий переводить числа в килограммы или ньютоны. Ведь даже задав точку отсчёта, нам будет мало толку от чисел, например -18954 или +6780, тогда как мы не знаем, чем они соответствуют. То есть, нужно откалибровать датчик, положив на него груз известной массы, и вычислив коэффициент преобразования.

Таким образом, формула будет вот такой:
m = (r — r0) / k

где:

m — масса (или сила)
r — показания датчика в виде «сырых» чисел, передаваемых Arduino
r0 — показания датчика принятые за ноль (начало отсчёта)
k — коэффициент пропорциональности

Чтобы определить r0, достаточно засечь, какое число будет выдаваться при отсутствии нагрузки на датчик.

Как найти коэффициент пропорциональности:
1. Нужно положить на датчик известный груз, например в 5 килограмм. Можно вместо груза, приложить силу в известное количество ньютонов, контролируя её с помощью динамометра. Эту массу (или силу) будем обозначать mk
2. Нужно засечь, какое число в этот момент выдаёт Arduino, это число обозначим как rk
3. Подставим данные числа в вышеуказанную формулу:
mk = (rk — r0) / k
4. Получим значение k = (rk — r0) / mk

После того, как мы получили эти значения, можно вычислять массу (силу), приложенную к датчику, исходя из чисел, выдаваемых Arduino. Единственный минус — это не удобно делать через монитор порта. Так что нам нужен более удобный интерфейс.

Интерфейс на Python 3 и Qt

Графический интерфейс я решил написать на Python 3 с помощью библиотеки PyQt4.
Сразу предупреждаю, что интерфейс писался под Linux, поэтому для работы в Windows (например), его понадобится доработать, так как он использует Linux-овую систему адресации портов (то есть просто открывает порты из файлов /dev/ttyUSB0, /dev/ttyACM0 и т.д.)

Задачи интерфейса:
1) Уметь находить устройства, представляющие собой последовательные порты, и подключённые по USB.
2) Уметь подключаться к этим устройствам и отключаться от них
3) Уметь считывать числа, передаваемые Arduino в последовательный порт, после подключения к нему
4) Позволять удобно и легко засекать «начало координат», и вычислять коэффициент пропорциональности, с использованием заданного веса или силы
5) Сохранять данные в csv-файл, для последующей обработки в LibreOffice Calc (или в Excel), или любыми другими методами.

Графический интерфейс

Обычно я создаю графический интерфейс прямо в коде на Python, так как это позволяет выполнять позиционирование элементов программно, создавать наборы элементов в цикле, да и просто не позволяет мозгу зачерстветь. Но в этот раз я решил «нарисовать» форму в QtDesigner.
Сам QtDesigner без проблем можно установить из репозитория, если вы конечно используете Linux 🙂

apt-get install qt4-designer

Вот такую форму я нарисовал и сохранил в файл window.ui:
Дизайн интерфейса в QtDesigner

Дальше, понадобилось скомпилировать форму в питоний файл. Для этого есть инструмент, называемый pyuic (Python UI compiler), этот инструмент входит в библиотеку PyQt4, и, если у вас Debian, и PyQt4 вы устанавливали из репозитория, то лежит он по адресу /usr/lib/python3/dist-packages/PyQt4/uic/pyuic.py
Для удобства создадим bash-скрипт с именем pyuic, и вот таким нехитрым содержимым:

#!/bin/bash
python3 /usr/lib/python3/dist-packages/PyQt4/uic/pyuic.py $*

поместим этот скрипт в ~/bin (если эта папка у вас добавлена в PATH) или в любую папку типа /usr/bin, что позволит запускать скрипт просто так, набрав «pyuic» в консоли.

Теперь преобразуем ui-файл в модуль python:

pyuic ./window.ui -o ./window.py

(подразумевается, что запускаем находясь в папке с ui-файлом)

Как пользоваться полученным py-файлом:

В полученном файле главное — это класс вида:

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(555, 470)
        self.groupBox = QtGui.QGroupBox(MainWindow)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 541, 101))
        self.groupBox.setObjectName(_fromUtf8("groupBox"))
        # И так далее

в функции setupUi формируется весь графический интерфейс, нарисованный в файле window.ui (Имя класса может отличаться в зависимости от названия, которое вы дадите своему окношку в QtDesigner)

Таким образом, для использования достаточно следующего:
1) Импортировать файл window.py
2) Создать свой класс окна, наследованный от того же класса, который вы создавали в редакторе (QMainWindow, QDialog и т.д.)
3) В конструкторе класса создать объект типа Ui_MainWindow и вызвать setupUi(self), чтобы интерфейс был «натянут» на данное окно. Переменную типа Ui_MainWindow поместить куда-нибудь чтобы не пропала, так как через неё будем обращаться к элементам GUI.

Получение списка портов

Поскольку порты в Linux превращаются в tty-устройства, лежащие в /dev, то их то нам и надо, но не всех, а только тех, кто сидит на шине USB. Поскольку все tty-устройства также лежат в /sys/class/tty (в виде символических ссылок), достаточно прочитать, куда ведут эти ссылки, и отобрать те, у которых в пути присутствует /usb0/, /usb1/ и т.д.
Сделать это можно вот таким куском кода:

def get_ports(self):
    ports = []
    for path, files, dirs in os.walk("/sys/class/tty"):
        for file in files:
            fullname = "/sys/class/tty/" + file
            link = os.readlink(fullname)
            if re.search("/usb[0-9]+/", link):
                ports.append(file)
        break
    return ports

Общение с портом

Для работы с последовательным портом я использовал библиотеку pyserial, которая, как и многие другие, проста в использовании и прямолинейна как топор. Создал объект для работы с портом, задал параметры, открыл его, читаешь данные.
Единственный минус библиотеки — чтение данных в ней блокирующее, что является проблемой для графического интерфейса. Он не должен блокироваться при чтении.

Для того, чтобы обойти блокировку, я реализовал чтения порта в отдельном потоке, завернув всё это в отдельный класс.
При поступлении данных, объект класса посылает Qt-сигнал line_readed, на который подключён слот в объекте окна. Поскольку сигналы и слоты являются потоко-безопасными, их как раз проще всего использовать для передачи данных между потоками в приложении на PyQt

Вот такой получился класс:

class Serial(QtCore.QObject):
    def __init__(self, app):
        super().__init__()
        self.app = app
        self.serial = serial.Serial()
        self.read_thread = None
        self.stop_thread_event = None
 
    def open_connection(self, port, speed=SPEED):
        """
        Установить соединение с портом.
        Функция открывает соединение, запускает поток чтения данных, 
        подключает его к событию остановки (чтобы можно было оборвать жизнь потока)
        """
        self.serial.port = "/dev/" + port
        self.serial.baudrate = speed
        self.serial.open()
        if self.read_thread is not None:
            self.stop_thread_event.set()
            self.read_thread.join(1)
        self.stop_thread_event = threading.Event()
        self.read_thread = threading.Thread(target = self.read_loop, args=(self.stop_thread_event,))
        self.read_thread.start()
 
    def read_loop(self, stop_event):
        """
        Функция чтения. Бесконечный цикл, который надо запускать в потоке,
        в качестве параметра передаётся событие, по срабатыванию которого
        поток будет остановлен (ну а точнее просто цикл завершится)
        """
        print("read loop started")
        while not stop_event.is_set():
            if self.serial.isOpen():
                try:
                    line = self.serial.readline()
                except serial.serialutil.SerialException as e:
                    if ("device reports readiness to read but returned no data" in str(e)):
                        pass
                    else:
                        raise e
                self.data_arrived(line)
        print("read loop stopped")
 
    def close_connection(self):
        """
        Отключиться от порта.
        Закрывает порт, останавливает цикл чтения с помощью события.        
        """
        self.stop_thread_event.set()
        self.read_thread.join(1)
        self.serial.close()
        if self.serial.isOpen():
            print("Serial is not closed, as it should be!")
 
    def get_ports(self):
        """
        Служебная функция для получения списка портов
        """
        ports = []
        for path, files, dirs in os.walk("/sys/class/tty"):
            for file in files:
                fullname = "/sys/class/tty/" + file
                link = os.readlink(fullname)
                if re.search("/usb[0-9]+/", link):
                    ports.append(file)
            break
        return ports
 
    def data_arrived(self, line):
        """
        Обработчик считанных данных, запускает сигнал
        """
        self.line_readed.emit(line)
 
    # сигнал "строка считана", для подключения к коду окна.
    line_readed = QtCore.pyqtSignal(bytes)

Доступ к порту в Linux

Может оказаться, что у вас по умолчанию нет доступа к порту, появляющемуся в системе при подключении Arduino, например, это может быть порт /dev/ttyUSB0. Можно просто сменить на него права доступа, но это придётся делать каждый раз при подключении arduino заново.
Чтобы решить проблему раз и навсегда, нужно добавить вашего пользователя в группу, которой принадлежит создаваемый файл устройства порта.
Посмотрим, кто является владельцем порта:

# ls -l /dev/ttyUSB0

Обычно владельцем является пользователь root и группа dialout.
Добавляем себя в группу dialout (вместо «username» подставьте вашего пользователя, запуск от root):

# usermod -a -G dialout username

Калибровка датчика

Для калибровки в приложении имеются две кнопки и одно текстовое окошко. Одна кнопка позволяет задать ноль датчика, а другая — задать кэффициент пропорциональности. В окошко при этом нужно вписывать ту массу, или силу, которая приложена на датчик во время вычисления коэффициента.

Проблема: числа выходят из порта с некоторыми флуктуациями, при этом, значение нуля должно быть постоянным. В какой момент замерять этот ноль?
АЦП HX711 имеет гораздо большее разрешение нежели сам датчик. Ведь у АЦП числа варьируются от 0 до 16 миллонов, а, поскольку датчик в моём случае имеет максимум = 500 кг, то при таком разрешении, 1 единица, выдаваемая из АЦП представляет собой 6.25*10-5 кг. Что конечно намного меньше, чем точность датчика (она заявлена как 0.1 кг). Поэтому минимальное изменение сопротивление на тензорезисторе датчика сразу же превращается в огромное изменение выдаваемых чисел.
Решение: дадим пользователю нажать и подержать кнопку замера, при этом посчитав математическое ожидание получаемых измерений. Обе кнопки, что замеряющая ноль, что замеряющая коэффициент, должны при нажатии запускать процесс запоминания всех приходящих чисел. А при отпускании — нужно вычислять математическое ожидание пришедшей последовательности данных. Это и будет «ноль, находящийся в середине области флуктуаций» либо «величина показаний при взвешивании известного груза».

Таким образом, при нажатии кнопки «Засечь ноль», происходит следующее:

def captureZeroBegin(self):
    self.beginMeasure()

Функция beginMeasure просто сбрасывает накопляющие переменные:

def beginMeasure(self):
    self.captured_nums_avg = 0
    self.captured_nums_count = 0
    self.capture_in_progress = True

При отпускании кнопки происходит:

measured = self.endMeasure()
if measured is not None:
    self.ui.zeroKg.setText(str(round(measured, 4)))

Где функция endMeasure возвращает замеренное за время удержания кнопки среднее значение (при этом, останавливая замер):

def endMeasure(self):
    self.capture_in_progress = False
    if self.captured_nums_count == 0:
        return None
    else:
        return self.captured_nums_avg

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

def measure(self, num):
    if self.capture_in_progress:
        self.captured_nums_avg = (
            (self.captured_nums_avg * self.captured_nums_count + num) / (self.captured_nums_count + 1)
        )
        self.captured_nums_count += 1

Таким образом, с каждым вызовом measure, в переменной captured_nums_avg накапливается математическое ожидание замеренных значений.

Сохранение данных

Для работы с данными я выбрал обычный CSV-формат.
Для сохранения можно указать имя файла, и по нажатию кнопки «Начать запись», все приходящие значения начинают добавляться в файл. Когда нажата кнопка «Остановить запись», то данные перестают сыпаться в файл. Там же можно открыть файл с помощью вашего стандартного редактора CSV (используется xdg-open)

def startWriteFile(self):
    if not self.app.serial.serial.isOpen():
        QtGui.QMessageBox.warning(self, "Ошибка", "Подключение не установлено!")
    else:
        filename = self.ui.fileNameInput.text()
        try:
            if os.path.exists(filename):
                f = open(filename, "a")
            else:
                f = open(filename, "w")
                f.write("\ufeff")
                f.write("Время;Секунд прошло;Масса;Сырое значение;\n")
            self.file_descriptor = f
        except PermissionError as e:
            QtGui.QMessageBox.warning(self, "Ошибка создания фала", str(e))
 
        self.ui.fileNameInput.setEnabled(False)
        self.ui.startWriteButton.setEnabled(False)
        self.ui.stopWriteButton.setEnabled(True)

Где взять

Полный код приложения можно получить на GitHub: https://github.com/MihanEntalpo/MassGraph

Для того, чтобы запустить этот код, понадобится установить сам питон, и PyQt4:

# В Debian это так:
apt-get install python3 python3-pip python3-pyqt

и некоторые пакеты python3:

# опять же, в Debian
pip3 install pyserial pyyaml

Для запуска можно просто запустить скрипт massgraph.

Код Arduino лежит в папке arduino, на случай если вы столь ленивы, что не можете даже скопипастить код из статьи 🙂

Корпус и подключение

Для того, чтобы устройством было удобно пользоваться, оно должно быть не просто висящей на проводах платой Arduino, подключённой через висящий на проводах АЦП к датчику. Устройство должно быть заключено в удобный и более-менее прочный корпус.
Поэтому я приобрел небольшой пластмассовый корпус, Arduino Nano (так как обычная в этот корпус не влезала), разъёмы для изготовления переходника из USB-B на Mini-USB (у Arduino Nano как раз такой разъём), и сетевой разъём RJ-45 (для подключения датчика).

Корпус

Разъём USB-B

Разъём USB-B

Разъём Mini USB

Разъём Mini USB

Разъём RJ-45

Разъём RJ-45

Arduino nano

Arduino nano

Для подключения Arduino Nano к компьютеру через кабель, имеющий разъём USB-B, я спаял переходник, и вклеил его разъём в один из торцов корпуса. С другой стороны корпуса я вклеил разъём RJ-45, и припаял их к разъёму, который должен быть надет на HX711.

Также, я спаял переходник между платами HX711 и Arduino nano.

Переходник MiniUSB - USB-B

Переходник MiniUSB — USB-B

Разъём для датчика

Разъём для датчика

Вся схема в сборе

Вся схема в сборе

Светодиод, который виден торчащим из Ардуино, это как раз тот, который включается сразу при инициализации Arduino, чтобы показывать, что устройство включено. Для этого светодиода в корпусе просверлено отверстие.

После сборки в коробочку устройство приобретает более-менее цивильный вид:

Складываем компоненты в корпус

Складываем компоненты в корпус

Закрываем крышку

Закрываем крышку

Устройство в сборе, подключённое

Устройство в сборе, подключённое

Вид со стороны USB-разъёма

Вид со стороны USB-разъёма

Вид со стороны RJ-45

Вид со стороны RJ-45

Считыватель данных с датчика и его пользовательский интерфейс уже неплохо себя показал в работе.

Резюме: на современном рынке электроники есть множество компонентов, с помощью которых можно собрать почти всё что угодно, обладая минимальными знаниями. Ситуация не сравнима с теми годами, когда для того, чтобы ввести информацию с датчика в свой IBM286, нужно было самому паять АЦП, самому собирать для него интерфейс RS232, и заставить всё это работать, писать программу для работы с портом внутри ПК на Си с минимумом библиотек, и вообще без какого бы то ни было GUI.


8 комментариев

  • Ответить Эдик |

    Привет!

    Прочитал вашу статью, очень интересно, спасибо!

    Есть несколько вопросов. Если будет время, ответьте на них пожалуйста =)

    Я хочу собрать динамометр для измерения силы натяжения троса в пределах от 30 до 150кг. Эта штука будет использоваться для контроля тяги во время затягивания в небо =) Дельтапланов или парапланов. Там важно знать усилие.
    Хочу собрать его на ардуине.

    1. Тот датчик, что у вас в проекте в какой плоскости работает? Мне надо, чтобы он работал в растяжение или сжатие, т.е. вдоль своей оси.
    Пока планирую использовать вот этот датчик:
    https://ru.aliexpress.com/item/strain-gauge-pressure-sensor-S-load-cell-electronic-scale-sensor-Weighing-Sensor-10KG-20KG-50KG-100KG/1083523348.html?spm=2114.14010208.99999999.273.clNBhp

    2. Подружится ли сей датчик с АЦПшкой HX711?

    3. Самое главное, как реализована температурная компенсация в либе под HX711? Тензодатчик весьма критичен к перепадам температур. Я так думаю, что надо крепить к нему отдельный термометр и как-то компенсировать температурный дрейф. Или оно как-то уже решено?

    Заранее благодарен 🙂

    • Ответить mihanentalpo |

      Привет.
      1. Мой датчик работает на сжатие, давление осуществляется на эту круглую чёрную штуку на фотографии вверху, при этом стоять он должен на металлическом основании.
      Теоретически с помощью системы рычагов можно сделать чтобы он измерял силу натяжения троса. В принципе, тот датчик, что по ссылке, визуально похож на те датчики, которые я видел в продаже у российских компаний, работающие на растяжение-сжатие.
      2. Не видя dataSheet-а (технической документации) нельзя сказать точно, подойдёт ли он к HX711.
      3. Что касается температурной компенсации — я исхожу из того, что, при изменении окружающей температуры, измерения меняются пропорционально. Перед каждым измерением я снова «засекаю» коэффициент пропорциональности на известной массе и нулевую точку, поэтому считаю, что масса продолжает измеряться верно.

      Если же измерения меняются нелинейно, я бы сделал так:
      с помощью термометра и нескольких грузов с известной массой составил бы таблицу искажений измерения датчика, и, как ты и предложил, прицепил бы термодатчик к корпусу тензодатчика, и написал бы формулу для пересчёта показаний в соответствии с температурой. Однако тут надо сначала посмотреть насколько большая при этом погрешность, и будет ли она вообще иметь значения.

      Если же задача в том, чтобы датчик работал в диапазоне от -40 до +30 градусов, то можно попробовать сделать конструкцию с теплоизоляцией датчика.

  • Ответить Эдик |

    Спасибо за ответ!

    Диапазон температур будет где-то от -10 до +30 максимум.
    Скорее всего, сделаю как у вас: устанавливать «ноль» при включении прибора. Ибо зама затяжка длится около 5-10 минут максимум (со всеми подготовками и т.д.). А потом прибор выключается. А погрешность в 2-3 кг не существенна в моем случае.
    Но с температурой я поэкспериментирую ради интереса 🙂
    Датчик да, конструктивно похож под растяжение и сжатие. Надо будет у китайца попросить даташит.
    Спасибо еще раз!

  • Ответить Эдик |

    А еще вопрос, этот датчик как у вас?

    https://ru.aliexpress.com/item/New-Arrival-1PCX-200kg-electronic-platform-scale-load-cell-pressure-balanced-cantilever-load-weight-sensor-New/32703877639.html?spm=2114.14010208.99999999.262.AQqyCF

    Только мой на 200кг, а ваш на 500кг.
    С рычагами я придумал как сделаю) Собственно эти рычаги заложены в конструкцию датчика по ссылке в посту выше.
    Вот так:
    https://pp.userapi.com/c840222/v840222179/8d66/-qlXaUfOiv4.jpg

    Длина от датчика к платке HX711 сильно критична?(в плане наводок и т.д.) Какая у вас длина кабеля получилась?

    • Ответить mihanentalpo |

      У меня не такой датчик, но немного похож.
      Посмотрел переписку с магазином, вот такой у меня http://keli-cee.com/product-SQB-A,2.html , ошибся с указанием модели в статье.
      Длина у меня ровно такая, какая была изначально у провода датчика, я думаю что лучше эти провода не удлиннять, поскольку он хорошо экранирован, и без экрана на нём будут появляться электромагнитные наводки, и показания будут меняться.
      Лучше всего сразу же подключить к концу провода HX711, к нему сразу же подключить Arduino, а к нему какие-то кнопки для управления, и LCD-экран для отображения. Вам ведь, насколько я понял, не нужно подключать ваш механизм к ПК, и будет это не удобно. Лучше в этом случае, чтобы Arduino самостоятельно выполнял всю работу.

    • Ответить Иван |

      Эдуард, доброго времени суток.
      То устройство которое вы описываете называется «малинка».
      На моей практике уже две такие действующие системы. Обе реализованы на ардуине.
      Питание бортовое от прикуривателя автомобиля.
      Нюансов достаточно много. Если не забросили задумку, пишите, дам развернутые ответы.
      Датчик я использовал вот такой https://ru.aliexpress.com/item/strain-gauge-pressure-sensor-S-load-cell-electronic-scale-sensor-Weighing-Sensor-10KG-20KG-50KG-100KG/1083523348.html

  • Ответить vasus |

    Ответ Эдику про температуру. Как правило, на подобных датчиках имеются 4 одинаковых тензорезистора, 2 сверху, 2 снизу. Поэтому , если их температура одинакова. то и сопротивление будет одинакова в пределах допуска на партию. То есть , хочу сказать, что изменяя Т, дрейф ноля произойдет ну очень незначительно, и коэффициент пропорциональности измерений тоже. Но! они нанесены на алюминий, который сужается или расширяется в зависимости от Т и ввиду неоднородности по разному вверху и внизу. Вот это может заметно сметить ноль, о чем и говориться в характеристиках датчика представленной вами по ссылке, но говориться не о тензорезисторах , а о датчике целиком. Так что , калибровка ноля должна быть обязательна. А калибровать известными весами, это всегда неточно. Лучше аналитическим способом по напряжению входного сигнала

    • Ответить mihanentalpo |

      Спасибо, ценная информация на счёт температурного дрейфа за счёт аллюминиевых элементов.
      Калибровать известными весами — по сути именно это я, например, делаю в своей программе перед началом каких-то реальных измерений, правда, продолжаю полагать, что искажения будут линейными.

Оставить комментарий