З 08.01.2021р. магазин працює в закритому режимі, у зв`язку із локдауном самовивозів не буде !
Arduino в Украине
(098) 067-12-26 Київстар (098) 067-12-26   Київстар
(066) 142-24-48 Vodafone (066) 142-24-48   Vodafone
(098) 067-12-26 Lifecell (063) 642-36-59   Lifecell
 info@arduino.ua
Графік роботи магазину:
Пн-Пт: 9.00 - 19.00
Сб: 10.00 - 19.00
Нд: вихідний
м. Київ, вул. Васильківська, 30
ст.м. "Васильківська"
Каталог

Protocol Droid или доступ к устройствам и работа с ними по средствам различных протоколов передачи данных и не только.

Protocol Droid - это интерфейсная плата, предназначенная для помощи разработчикам встроенного программного обеспечения и энтузиастам в тестировании и отладке их проектов, особенно в ситуациях, когда нет подходящего оборудования для

Программатор AVR ISP Version 2.0 для микроконтроллеров AVR

На просторах Aliexpress можно найти программатор AVR ISP Version 2.0 для микроконтроллеров AVR. Среди множества подобных устройств он выделяется своей простотой и

Музыкальный медиа центр на базе Raspberry Pi Zero W и Pimoroni Pirate Audio

В данной статье, мы опишем процесс создания музыкального медиа центра, c возможностью удаленного управления на базе мини-компьютера Raspberry Pi Zero W (Изображение - №1), звуковой платы расширения Pimoroni Pirate Audio Headphone Amp 24bit/192KHz

Особистий сервер CalDAV на одноплатному комп’ютері

«That's just perfectly normal paranoia. Everyone in the Universe has that.» Douglas Adams, The Hitchhiker's Guide to the Galaxy Ця стаття для тих, хто хоче синхронізувати свої календарі, списки справ і контакти між кількома пристроями, але не хоче

Подключение датчика BlTouch и его аналогов к 3D принтеру

Предыстория: собрал я 3D принтер на связке Mega2560 + Ramps 1.3 + экран RepRap Full Graphic Smart Controller 128x64 с прошивкой Marlin 2.0.х, но механика оставляла желать лучшего. Перед каждой печатью приходилось с помощью листа А4 калибровать стол по 40
Напиши партнеры https://hacklab.kiev.ua/!

Працюємо за даташитом: тензометр

2020-07-17

Всі статті →

Антон Царіцинський

Тензометри застосовуються для вимірювання величини механічного навантаження. В побуті найбільш відомим пристроєм, в якому можемо знайти тензометри, є електронні ваги ( рис. 1 ):

Рис. 1A - Тензометри з підлогових ваг

Рис. 1В - Тензометри з ручних ваг

Серед датчиків для ARDUINO також є тензометри ( рис. 2 ):

Рис. 2 – Популярний тензометр для ARDUINO

Цей датчик працює за резистивним принципом. На ньому розташовані тонкі провідники, які міцно скріплені з його поверхнею, по яких тече слабкий струм. Прикладена механічна сила призводить до виникнення деформацій, в тому числі й на вказаній поверхні, через що провідник розтягується або стискається: змінюється його довжина і площа перетину. Через це змінюється електричний опір, параметри струму, які можна виміряти і, таким чином, судити про ступінь навантаження. До ARDUINO тензометр підключають через аналогово-цифровий перетворювач ( АЦП ). Популярним і дешевим АЦП є HX711 у вигляді готового модуля ( рис. 3 ).

Рис. 3 – Модуль на базі HX711

Даташит за посиланням: https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf

Модуль має два канали А і В, які відрізняються коефіцієнтом посилення: 64 або 128 – для каналу А; 32 ( фіксовано ) – для каналу В. З мікроконтролером модуль спілкується через контакти DT ( лінія передача даних, вихідний ) і SCK ( лінія тактування, вхідний ). Варіант підключення показаний на ( рис. 4 ). Для чого там кнопка, стане зрозуміло згодом.

Рис. 4 – Схема підключення

Тестовий стенд можна побачити на ( рис. 5 ).

Рис. 5 – Тестовий стенд

 

Спілкування з HX711

Розберемося з протоколом передачі даних, бо тут немає рідних SPI або I2C. На сторінці 4 даташиту дізнаємось, що результатом вимірювання є 24-бітне число. Спосіб його отримання наступний:

1) заводимо 32-бітну змінну для зберігання 24-бітного результату (на сторінці 8 даташиту можна знайти приклад коду на мові C, в якому використовують беззнаковий unsigned long; я ж надав перевагу знаковому long, оскільки при подальшому калібруванні результати обчислень можуть бути від’ємними, а примусово приводити типи мені лінь);

2) аналізуємо стан сигналу на DT: високий рівень свідчить про те, що дані ще не готові, тож нам залишається чекати, поки рівень не зміниться на низький;

3) починаємо читати результат вимірювання окремими бітами. Загальна схема процесу показана на ( рис. 6 ) ( сторінка 5 даташиту ).

Рис. 6 – Протокол взаємодії з HX711

За один такт по SCK читаємо один біт, починаючи зі старшого ( MSB ). Для цього:

  • переводимо SCK у високий рівень;
  • зсуваємо змінну результату на одиницю вліво;
  • читаємо поточний біт в молодший біт змінної результату;
  • переводимо SCK в низький рівень.

Повторюємо цю послідовність 24 рази;

3) Число отримали, але це ще не все. Треба додати ще 1…3 такти для визначення каналу і коефіцієнта посилення для наступного зчитування (табл. 1 ).

Кількість тактів Канал Коефіцієнт посилення
25 A 128
26 B 32
27 A 64

Табл. 1 – Вибір каналу і коефіцієнта посилення

Таким чином, загалом кожний цикл спілкування з HX711 складається з 25…27 тактів по лінії SCK;

4) Тут треба повернутися на сторінку 4 даташиту. Наше 24-бітне число видається в доповненому коді ( англ. two’s complement ) в діапазоні від 0х800000 ( або 8388608 в десятковій системі ) до 0x7FFFFF ( або 8388607 ). Для вірної інтерпретації над результатом необхідно здійснити операцію XOR, яка фактично підлаштовує старший біт. Виглядатиме це так:

результат ^= 0x800000

Те ж саме можна побачити в прикладі з даташиту ( сторінка 8 ). Насамкінець, звертаємо увагу на допустимий час виконання операцій ( табл. 2 зі сторінки 5 даташиту; також дивись рис. 6 ).

Позначення Мін Типове Макс Одиниця
T1 0.1     мкс
T2     0.1 мкс
T3 0.2 1 50 мкс
T4 0.2 1   мкс

Табл. 2 – Допустимі часові проміжки

Найбільш важливим для нас є обмеження часу T3 ( перебування лінії SCK у високому рівні ) – 50 мікросекунд. Якщо перетримати, HX711 увійде в режим зниженого енергоспоживання ( при 60 мкс, див. сторінку 5 даташиту ), при поверненні до низького логічного рівня по SCK модуль перезавантажиться і повернеться до нормальної роботи. Оскільки функції digitalWrite() і digitalRead() виконуються кілька мікросекунд, то можемо використати їх при програмуванні протоколу, хоча для збільшення продуктивності доцільно працювати напряму через порти. В скетчі, що додається, це реалізовано у вигляді класу TENZO ( файли tenzo.h і tenzo.cpp ). Основну роботу виконує функція TENZO::readRaw().

 

Калібрування

Перед «бойовим» застосування тензометра потрібно встановити відповідність його показань реальному навантаженню. Для цього можуть застосовуватися вантажі, маса яких відома, наприклад, еталонні гирі (рис.7).

Рис. 7 – Еталонні гирі

Між навантаженням F і показаннями тензометра P можна ввести лінійну залежність (рис. 8)

P = calib*F + offset

де calib, offset – шукані коефіцієнти.

 

Рис. 8 – Залежність між навантаженням і показаннями тензометра

Коефіцієнт offset можна знайти з умови відсутності навантаження, тобто коли F=0. В цьому випадку тензометр видаватиме деяке умовно-стале ( шум, дрифт ніхто не відміняв ) число P0. Таким чином

offset = P0 (1)

Коефіцієнт calib знайдемо за допомогою еталонного навантаження Fе і відповідно еталонного показання Pе

calib = (Pе – offset) / Fе (2)

Навантаження будемо розраховувати за формулою

F = (P – offset) / calib (3)

Калібрування також реалізовано в класі TENZO за допомогою функцій:

  • TENZO::tare() – запам’ятовує коефіцієнт offset за формулою (1). Через дрифт нуля тензометра перед вимірюванням слід натиснути кнопку, після чого буде викликано цей метод;
  • float TENZO::setCalib(float Fe) – розраховує і повертає коефіцієнт calib за формулою (2) на основі величини еталонного навантаження Fe, яке в скетчі задається користувачем через монітор порта. Цей коефіцієнт можна записати в константу CALIB у файлі tenzo.h. Остаточне вимірювання довільного навантаження виконується функцією float TENZO::read(), в якій використовується формула (3).

 

Фільтрування

HX711, як і багатьом іншим АЦП, притаманний шум, який можна зменшити шляхом фільтрування. Я не є спеціалістом з теорії обробки сингалів, тож зазвичай використовую просте експоненційне згладжування: "Wiki: Експоненційне_згладжування" , є й інші назви.

Yn = Xn + α*(Xn – Yn-1) (4)

Де n – поточна ітерація; X – сигнал, отриманий на поточній ітерації; Y – відфільтрований сигнал; α – коефіцієнт посилення, обирається з інтервалу [0; 1]; чим менше значення, тим сильніше згладжування, і навпаки. Зазвичай α = 0,05…0,1.

На кожній ітерації алгоритм потребує дві величини: за поточну і попередню ітерації, тож на першій ітерації приймаємо:

Y1 = X1 (5)

Робота алгоритму показана на рис. 9.

Рис. 9 – Експоненційне згладжування: синя лінія – нефільтровані дані; червона лінія – фільтровані дані

Видно, як фільтровані дані відстають від нефільтрованих через мале значення коефіцієнта посилення ( рис. 10; на тензометр послідовно встановлюються і знімаються гирі 100г і 50г. ).

Рис. 10 – Запізнення експоненційного згладжування: синя лінія – нефільтровані дані; червона лінія – фільтровані дані

Зважаючи на наявність різких перепадів вимірюваного навантаження ( становили або зняли гирю ), можна внести корективу щодо коефіцієнта посилення: якщо дані міняються незначно ( наприклад, до 1 грама ), то α = 0,05; якщо ж змінення значне ( більше 1 грама ), то α = 0,95. Таким чином, на різкі стрибки алгоритм буде реагувати швидко. Така модифікація експоненційного фільтра підглянута в AlexGyver "адаптивний коеффіцієнт"

Роботу нового алгоритму в тих же умовах показано на рис. 11.

Рис. 11 – Експоненційне згладжування з адаптивним коефіцієнтом: синя лінія – нефільтровані дані; червона лінія – фільтровані дані

В скетчі фільтр реалізовано у вигляді класу EFILTER ( файли efilter.h і efilter.cpp ). Основні функції:

  • EFILTER::begin(float x0) – початок роботи за формулою (5);
  • float EFILTER::get(float x) – для кожної наступної ітерації за формулою (4).

 

Додатково…

В скетчі також є класи кнопки ( BUTTON, для ручного тарування ) і таймера ( TIMER, для забезпечення рівних проміжків часу між зчитуваннями показань тензометра, виведення результату через Serial ). Основні методи:

  • boolean BUTTON::pressed() – повертає true, якщо кнопку натиснули;
  • boolean TIMER::isExpired() – повертає true, якщо час таймера вичерпаний;
  • TIMER::reset() – перезапускає таймер.

Інтервал таймера ( в мілісекундах ) встановлюється при виклику його конструктора.

Посилання:

Ваша оцінка статті:

Відмінно
Добре
Задовільно
Погано
Дуже погано

Дякуємо Вам за звернення! Ваш відгук з'явиться після модерації адміністратором.
Поки немає відгуків на цю статтю.
оплата картами Visa і MasterCard