Здравствуйте. Занялся проектом умной пасеки. Проект как и код взяты со странички https://habr.com/ru/post/444326/ что говорит о том что прошивка рабочая.
Но. Пытаюсь скомпилировать код, и выдает ошибку no matching function for call to ‘HX711::HX711(int, int)’
Arduino: 1.8.19 (Windows 10), Плата:»Arduino Pro or Pro Mini, ATmega328P (3.3V, 8 MHz)»
bee:6:20: error: no matching function for call to ‘HX711::HX711(int, int)’
HX711 scale0(10, 14);
^
In file included from C:UsersAlekseyDocumentsArduinoprojectsbeebee.ino:4:0:
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:30:3: note: candidate: HX711::HX711()
HX711();
^~~~~
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:30:3: note: candidate expects 0 arguments, 2 provided
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:19:7: note: candidate: constexpr HX711::HX711(const HX711&)
class HX711
^~~~~
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:19:7: note: candidate expects 1 argument, 2 provided
bee:7:20: error: no matching function for call to ‘HX711::HX711(int, int)’
HX711 scale1(11, 14);
^
In file included from C:UsersAlekseyDocumentsArduinoprojectsbeebee.ino:4:0:
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:30:3: note: candidate: HX711::HX711()
HX711();
^~~~~
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:30:3: note: candidate expects 0 arguments, 2 provided
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:19:7: note: candidate: constexpr HX711::HX711(const HX711&)
class HX711
^~~~~
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:19:7: note: candidate expects 1 argument, 2 provided
bee:8:20: error: no matching function for call to ‘HX711::HX711(int, int)’
HX711 scale2(12, 14);
^
In file included from C:UsersAlekseyDocumentsArduinoprojectsbeebee.ino:4:0:
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:30:3: note: candidate: HX711::HX711()
HX711();
^~~~~
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:30:3: note: candidate expects 0 arguments, 2 provided
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:19:7: note: candidate: constexpr HX711::HX711(const HX711&)
class HX711
^~~~~
C:Program Files (x86)ArduinolibrariesHX711-mastersrc/HX711.h:19:7: note: candidate expects 1 argument, 2 provided
exit status 1
no matching function for call to ‘HX711::HX711(int, int)’
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
«Показать подробный вывод во время компиляции»
Помогите разобраться, как исправить ошибку.
Loading
Общие сведения:
Тензодатчики (типа «мост» и типа «полу-мост») и микросхема 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 (см. рисунок выше!):
Провода тензодатчика | Выводы микросхемы 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(); // Вывод модуля из спящего режима
Применение:
- системы контроля и измерения веса;
- концевые датчики, системы;
Ссылки:
- Библиотека HX711;
- Тензодатчик мостовой 1кг;
- Тензодатчик мостовой 5кг;
- Тензодатчик мостовой 10кг;
- Тензодатчик мостовой 20кг;
- Тензодатчик полумостовой 50кг;
- Микросхема HX711;
- DataSheet;
-
Здравствуйте. 2 года назад собрал прибор для измерения тяги модели ракетного двигателя. Ничего нового не изобретал: HX711, arduino nano, micro Sd card. Прибор регулярно простаивал(бывало по пол года) но работу свою делал, без ошибок. Однако недавно начались проблемы(после 4 месяцев простоя), без USB от ПК, записывалась каша, при этом стоит «на горячую» подключить к пк, так становится все нормально. Так же если выключить ардуино в диспетчере устройств(или удалить драйвер) тоже начиналась писаться каша. Как это решать, я не знаю. Пробовал ставить фильтры в питание, испольнозавать телефон в качестве Serial порта, ничего не помогает. Прошу помочь. Вот код программы:
#include «HX711.h» // для датчика
#include <SPI.h> // для карты памяти
#include <SD.h> // для карты памяти
#include <EEPROM.h> // для номерации эксперементов.const int button = 7;
const int LCD_RED = 5;
const int LCD_BLUE = 6;
const int START = 4;
const uint8_t PIN_CS = 10; // указываем номер вывода arduino подключенного к выводу CS адаптера
const int time_one = 10;
long ad0 = 0;
long ad1 = 0;
long ad2 = 0;
boolean control = 0;
float ad3;
int x = 0;
int y = 0;
int z = 0;
int p = 0;
File myFile; // Для работы с файлами
HX711 scale(A1, A0); // Указываем ввыводы с датчиком
float calibration_factor; // калибровка!
float units; // датчик
float ounces; // датчикvoid setup() {
delay(10000);
pinMode(LCD_RED, OUTPUT); // инициализация ввыводов ардуино
pinMode(LCD_BLUE, OUTPUT); // инициализация ввыводов ардуино
pinMode(START, INPUT); // инициализация ввыводов ардуино
pinMode(button, INPUT); // инициализация ввыводов ардуино
digitalWrite(button, HIGH); //Устанавливаем подтяжку для кнопки
scale.set_scale();
scale.tare(); //Сбрасываем на 0
scale.set_scale();
//scale.set_scale(125.2);
while (!Serial) {
; // ожидаем соединение последовательного порта
}
if (!SD.begin(PIN_CS)) {
while(1){
digitalWrite(LCD_RED, HIGH); // ошибка
delay(200);
digitalWrite(LCD_RED, LOW);
delay(200);
}
}
for(int h = 0; h<=5; h++){ // мигаем светодиодом
digitalWrite(LCD_BLUE, HIGH);
delay(50);
digitalWrite(LCD_BLUE, LOW);
delay(50);
}}
void loop() {
if(digitalRead(button) != 1){
delay(10);
if(digitalRead(button) != 1){
ad0 = millis();
while(1){
digitalWrite(LCD_RED, HIGH);
if(digitalRead(button) != 0){
delay(10);
if(digitalRead(button) != 0){
ad1 = millis();
digitalWrite(LCD_RED, LOW);
break;
}
}
}
if((ad1—ad0) > 2000){
setting();
}
else{
XP();
}
}
}
}void XP(){
digitalWrite(LCD_BLUE, HIGH); // подаем сигнал о начале эксперемента
while(1){
if(digitalRead(START) == 1){
delay(10);
if(digitalRead(START) == 1){
break;
}
}
}
digitalWrite(LCD_BLUE, LOW); // даём сигнал об окончании отсчета
myFile = SD.open(«EXP.txt», FILE_WRITE); // Открываем файл для записи, если файла нет, то создаем его.
if(!myFile){ // Проверяем открыт ли файл.
while(1){
delay(200); // файл не открыт
digitalWrite(LCD_RED, HIGH);
delay(200);
digitalWrite(LCD_RED, LOW);
}
}
myFile.println(«»); // Отступаем от прошлых записей.
myFile.print(«Experiment»); // пишем эксперемент.
myFile.print(EEPROM.read(0)); // Даем ему номер. ( на карте их могут быть несколько, и в них надо как-то орентироваться)
myFile.println(«»);// Отступаем от прошлых записей.
EEPROM.write(0, (EEPROM.read(0) + 1)); // прибавляем 1 к номеру эксперемента.
digitalWrite(LCD_RED, HIGH); // даем сигнал о начале записи
// units = scale.get_units(), 10;
//digitalWrite(START, HIGH); // Даем сигнал на запуск эксперемента
ad0 = millis(); // записываем время начало эксперемента
myFile.println(«»);
myFile.print(» «);
myFile.print(ad0); // записываем время
myFile.println(«»);
while(1){
units = scale.get_units(), 10; // Считываем показания датчика.
ad2 = millis(); // записываем окончания считывания
myFile.print(units); // записываем показания
myFile.print(» «);
ad3 = (ad2—ad0)/1000.00;
myFile.println(ad3); // записываем время
//if((ad2 — ad0) >= 10000){ //
// digitalWrite(START, LOW);
//}
if(digitalRead(button) != 1){ // нажата ли кнопка?
delay(10);
if(digitalRead(button) != 1){
myFile.println(«End to Experiment»);
myFile.close();
while(1){
digitalWrite(LCD_BLUE, HIGH);
digitalWrite(LCD_RED, LOW);
delay(100);
digitalWrite(LCD_BLUE, LOW);
digitalWrite(LCD_RED, HIGH);
delay(100);
}
}
}
delay(100);
}
}void setting(){
if(SD.exists(«EXP.txt»)){
SD.remove(«EXP.txt»);
}
myFile = SD.open(«EXP.txt», FILE_WRITE); // Открываем файл для записи, если файла нет, то создаем его.
if(!myFile){ // Проверяем открыт ли файл.
while(1){
delay(200);
digitalWrite(LCD_RED, HIGH);
delay(200);
digitalWrite(LCD_RED, LOW);
}
}
myFile.println(«»); // Отступаем от прошлых записей.
myFile.print(«calibration_smartPhone «); // пишем эксперемент.
myFile.print(EEPROM.read(0)); myFile.print(«: «); // Даем ему номер. ( на карте их могут быть несколько, и в них надо как-то орентироваться)
units = scale.get_units(), 10; // Считываем показания датчика.
ounces = units/141.8;
myFile.println(ounces);
myFile.println();
myFile.println(units);
units = scale.get_units(), 10;
units = units / ounces;
myFile.println();
myFile.println(units);
myFile.close();
control = 0;
for(int n = 0;n<=9;n++){
units = scale.get_units(), 10;
if(((units / ounces)<=130) || ((units / ounces)>=150)){
control = 1;
break;
}
delay(100);
}
if(control == 1){
for(int y = 0;y<=5;y++){
delay(500);
digitalWrite(LCD_RED, HIGH);
delay(500);
digitalWrite(LCD_RED, LOW);
}
}
else{
for(int y = 0;y<=5;y++){
digitalWrite(LCD_BLUE, HIGH);
delay(500);
digitalWrite(LCD_BLUE, LOW);
delay(500);
}
}
} -
Может sd карта деградирует? Если заменить?
-
Возможно, но данные пишутся структурировано, показатели веса космические.
Последнее редактирование: 4 окт 2020
-
@LeTaGa, а зачем вы ожидаете соединение по последовательному порту, если в дальнейшем его не используете?
По моему, эта запись нужна для Arduino Leonardo, попробуйте закомментировать ее.while (!Serial) {
; // ожидаем соединение последовательного порта
} -
Скорее всего у вас на ардуине сгорел стабилизатор напряжения на входе и поэтому когда вы подключаете к ПК у вас все работает как надо, а без него дуркует. Если в у вас там использована ардуина, попробуйте заменить на анлогичную, если есть в наличии.
-
Да в том то и дело что с питание все нормально. Проблемы начинаются если нет соединения с ПК, т.е. если подключить к выключенному пк, удалить драйвер на ардуино или просто выключить его в диспетчере устройств. Питания там податься напрямую в 5в, автономно питается от литевого аккумулятора на 12в, через крену на 5в. Пробовал питать через USB(подключал к повер банку, и заряднику) не помогло.
-
РЕШЕНИЕ. Проблему решил. Если в крации, дело в hx711. Разобрал устройство, и тыкнул мультиметром на линию 5в, при подключении USB от пк, на линии было 4.6в, потом отключил ардуино в диспетчере устройств, и напряжение поднялось до 4.8в ( в этот момент и начинаются глюки). Подключил ЛБП к линии 5в, и стал понижать напряжение, все завелось на напряжении 4.5в, потом организовал отдельное питание 4.5в для HX711 (все остальное питал от 5в), и все заработало как надо. Позже заменю HX711, и отпишусь, устранился ли дефект.
-
Проблема может быть в аналоговом питании. Чип по аналоговому питанию можно запитать напрямую от цифрового, а можно через его собственный регулятор (добавляется транзистор, два резистора и конденсатор). Соотв, эти элементы могут сбоить, а вы будете грешить на чип. Гляньте в ДШ чипа.
-
Приветствую всех! Подскажите, пожалуйста, как правильно подключить тактовую кнопку и светодиоды, чтобы программа, которая в первом сообщении топика, работала. Тоже собираю в настоящее время стенд для проверки тяги модельных двигателей на основе Искры Нано. Но, подключив все компоненты (HX711, модуль SD, тактовую кнопку и два светодиода), программа не работает, светодиоды на включение контроллера никак не реагируют, равно как и на нажатие кнопки. Моих мозгов пока не хватает ( Буду очень благодарен!
Последнее редактирование: 4 авг 2021
-
ДВС или БКД?
Схему подключения покажите.
-
Двигатели ракетные твердотопливные.
Контакты модуля HX711 DT и SCK подключены к пинам A1 и А0 соответственно.
Контакты модуля карты памяти: MISO — пин 12, MOSI — пин 11, SCK — пин 13, CS — пин 10.
Светодиоды синий и крысный: минус обоих светодиодов подлючен к земле, плюс синего — пин 6, плюс красного — пин 5.
Тактовая кнопка: контакты подтягивающего напряжения (замкнуты на кнопке) — один на пин 7, второй через резистор 10 кОм к земле, третий контакт с кнопки (замыкается при нажатии) — на пин 4.Где я накосячил? ( Прошу сильно ногами не пинать. Только начинаю разбираться в этом.
Последнее редактирование: 4 авг 2021
-
Сделал схему подключения во фритце для наглядности. Точнее, так, как я подключил.
Вложения:
-
Stend.jpg
- Размер файла:
- 395,3 КБ
- Просмотров:
- 100
-
-
У кнопки 4 контакта, они соединены попарно.
Мне кажется в этом что-то не так.
Может не работает из-за этого? -
Здравствуйте. Прошу прощения за задержку. На этом форуме я редкий гость). Светодиоды у вас не загораются из-за неправильного подключения. Плюсовые выводы нужно ввести к пинам D6 и D5.
Кнопку нужно подключить так, чтоб она замыкала пин D7 на GND, подтяжку делать не нужно, т.к. она подключается внутри ардуино. Пин D4 это вход для пиротехнического пульта. Все остальное у вас вроде как правильно. Схема оригинала:
У модуля HX711 есть 2-е скорости обновления данных. 10Гц и 80 Гц. Отрывок их даташита:
Так же модуль достаточно капризный к питанию(возможно мне так повезло, и это только у меня), ему нужно напряжение 4.6в. Со временем нужное напряжение может начать “гулять”, поэтому вам потребуется мини ЛБП, для питания схемы. Так же этот модуль начинает менять показания в зависимости от температуры, из-за чего запись данных сразу в ньютонах невозможна, данные нужно обрабатывать после записи в Excel.
Большинство дешёвых датчиков не могут работать при температурах ниже -5г. Если планируются испытания на сильном морозе, то следует продумать теплоизоляцию, и подогрев.
Шлейф от датчика нужно скрутить в косичку для уменьшения помех.
Далее руководство по эксплуатации.
Программа имеет 2 режима работы, это настройка и запись.
Запись активируется при коротком нажатии кнопки, после чего будет ждать сигнал от пиротехнического пульта. После получения сигнала от пульта, начнется запись. При нажатии кнопки запись будет остановлена, а программа уйдет в бесконечный цикл.
Настройка активируется при зажатии кнопки больше 2сек. При этом на датчик нужно положить груз с заранее известной массой(её необходимо указать в программе), по умолчанию там 141.8г. Если на карте памяти будет файл с данными, то он удалится, и будет создан новый. Далее в новый файл будут записаны данные калибровки. После будет включён режим теста, программа будет получать записи, и сравнивать их с первой записью, если изменения в пределах +-10г, то будет мигать светодиод на пине D6, а если нет, то светодиод на пине D5. При повторном нажатии кнопки, программа выйдет из режима настройки.
Теперь как обработать данные.
Открываем таблицу в Excel, запихиваем туда данные, после чего берём вес двигателя (в ньютонах), до его запуска, и просто делим первую запись на вес двигателя. Далее делим на получившееся число все остальные записи. При испытаниях в сильный мороз, показания будут гулять, поэтому проделывать это нужно с несколькими записями, и смотреть где отклонения меньше. Данные калибровки из режима настройки дадут показания в граммах, можно использовать для проверки работоспособности (индикатор переохлаждения датчика).
-
#include «HX711.h» // для датчика
#include <SPI.h> // для карты памяти
#include <SD.h> // для карты памяти
#include <EEPROM.h> // для номерации эксперементов.const int button = 7;
const int LCD_RED = 5;
const int LCD_BLUE = 6;
const int START = 4;
const uint8_t PIN_CS = 10; // указываем номер вывода arduino подключенного к выводу CS адаптера
const int time_one = 10;
long ad0 = 0;
long ad1 = 0;
long ad2 = 0;
boolean control = 0;
float ad3;
float conf = 141.8; //масса груза
int x = 0;
int y = 0;
int z = 0;
int p = 0;
File myFile; // Для работы с файлами
HX711 scale(A1, A0); // Указываем ввыводы с датчиком
float calibration_factor; // калибровка!
float units; // датчик
float ounces; // датчикvoid setup() {
//delay(10000);
pinMode(LCD_RED, OUTPUT); // инициализация ввыводов ардуино
pinMode(LCD_BLUE, OUTPUT); // инициализация ввыводов ардуино
pinMode(START, INPUT); // инициализация ввыводов ардуино
pinMode(button, INPUT); // инициализация ввыводов ардуино
digitalWrite(button, HIGH); //Устанавливаем подтяжку для кнопки
scale.set_scale();
scale.tare(); //Сбрасываем на 0
scale.set_scale();
//scale.set_scale(125.2);
while (!Serial) {
; // ожидаем соединение последовательного порта
}
if (!SD.begin(PIN_CS)) {
while(1){
digitalWrite(LCD_RED, HIGH);
delay(200);
digitalWrite(LCD_RED, LOW);
delay(200);
}
}
for(int h = 0; h<=5; h++){ // мигаем светодиодом
digitalWrite(LCD_BLUE, HIGH);
delay(50);
digitalWrite(LCD_BLUE, LOW);
delay(50);
}}
void loop() {
if(digitalRead(button) != 1){
delay(10);
if(digitalRead(button) != 1){
ad0 = millis();
while(1){
digitalWrite(LCD_RED, HIGH);
if(digitalRead(button) != 0){
delay(10);
if(digitalRead(button) != 0){
ad1 = millis();
digitalWrite(LCD_RED, LOW);
break;
}
}
}
if((ad1—ad0) > 2000){
setting();
}
else{
XP();
}
}
}
}void XP(){
digitalWrite(LCD_BLUE, HIGH); // подаем сигнал о начале эксперемента
while(1){
if(digitalRead(START) == 1){
delay(10);
if(digitalRead(START) == 1){
break;
}
}
}
digitalWrite(LCD_BLUE, LOW); // даём сигнал об окончании отсчета
myFile = SD.open(«EXP.txt», FILE_WRITE); // Открываем файл для записи, если файла нет, то создаем его.
if(!myFile){ // Проверяем открыт ли файл.
while(1){
delay(200); // файл не открыт
digitalWrite(LCD_RED, HIGH);
delay(200);
digitalWrite(LCD_RED, LOW);
}
}
myFile.println(«»); // Отступаем от прошлых записей.
myFile.print(«Experiment»); // пишем эксперемент.
myFile.print(EEPROM.read(0)); // Даем ему номер. ( на карте их могут быть несколько, и в них надо как-то орентироваться)
myFile.println(«»);// Отступаем от прошлых записей.
EEPROM.write(0, (EEPROM.read(0) + 1)); // прибавляем 1 к номеру эксперемента.
digitalWrite(LCD_RED, HIGH); // даем сигнал о начале записи
// units = scale.get_units(), 10;
//digitalWrite(START, HIGH); // Даем сигнал на запуск эксперемента
ad0 = millis(); // записываем время начало эксперемента
myFile.println(«»);
myFile.print(» «);
myFile.print(ad0); // записываем время
myFile.println(«»);
while(1){
units = scale.get_units(), 10; // Считываем показания датчика.
ad2 = millis(); // записываем окончания считывания
myFile.print(units); // записываем показания
myFile.print(» «);
ad3 = (ad2—ad0)/1000.00;
myFile.println(ad3); // записываем время
//if((ad2 — ad0) >= 10000){ //
// digitalWrite(START, LOW);
//}
if(digitalRead(button) != 1){ // нажата ли кнопка?
delay(10);
if(digitalRead(button) != 1){
myFile.println(«End to Experiment»);
myFile.close();
while(1){
digitalWrite(LCD_BLUE, HIGH);
digitalWrite(LCD_RED, LOW);
delay(100);
digitalWrite(LCD_BLUE, LOW);
digitalWrite(LCD_RED, HIGH);
delay(100);
}
}
}
// delay(100);
}
}void setting(){
if(SD.exists(«EXP.txt»)){
SD.remove(«EXP.txt»);
}
myFile = SD.open(«EXP.txt», FILE_WRITE); // Открываем файл для записи, если файла нет, то создаем его.
if(!myFile){ // Проверяем открыт ли файл.
while(1){
delay(200);
digitalWrite(LCD_RED, HIGH);
delay(200);
digitalWrite(LCD_RED, LOW);
}
}
myFile.println(«»); // Отступаем от прошлых записей.
myFile.print(«calibration_smartPhone «); // пишем эксперемент.
myFile.print(EEPROM.read(0)); myFile.print(«: «); // Даем ему номер. ( на карте их могут быть несколько, и в них надо как-то орентироваться)
units = scale.get_units(), 10; // Считываем показания датчика.
ounces = units/conf;
myFile.println(ounces);
myFile.println();
myFile.println(units);
units = scale.get_units(), 10;
units = units / ounces;
myFile.println();
myFile.println(units);
myFile.close();
while(1){
units = scale.get_units(), 10;
if(((units / ounces)<=(conf—10)) || ((units / ounces)>=(conf+10))){
delay(250);
digitalWrite(LCD_RED, HIGH);
delay(250);
digitalWrite(LCD_RED, LOW);
}
else{
digitalWrite(LCD_BLUE, HIGH);
delay(250);
digitalWrite(LCD_BLUE, LOW);
delay(250);
}
if(digitalRead(button) != 1){
delay(100);
if(digitalRead(button) != 1){
break;
}
}
}
}
Offline
Зарегистрирован: 13.01.2020
Всем привет!
Пытаюсь сделать простой весовой дозатор для воды: нажал кнопку, через реле включается водяная помпа, в небольшую емкость наливается определенное кол-во воды, помпа отключается.
Все бы ничего, но:
1. приходится долго держать кнопку запуска (до 2 сек), чтобы запустить процесс — (хотя это не так страшно, как следующая проблема)
2. когда вес достигает необходимого предела, прерывание реле происходит со значительной задержкой, и вес процентов на 5-10 превышает необходимый.
Что делать?
Скетч далее. Скомпановал сам.
Опыт с Ардуино у меня всего неделя, поэтому прошу отнестись с пониманием.