Измеритель силы хвата. Когда реально переоценил свою силу

в 8:26, , рубрики: arduino, Nokia 3310, selectel, сила хвата, тензометрические датчики
Измеритель силы хвата. Когда реально переоценил свою силу - 1

Приветствую!

Недавно вспоминал свои школьные годы и как проходило наше свободное время. Многие из нас занимались спортом. На уроках по физ-ре учитель частенько устраивал разного рода соревнования (это не как сейчас, детей один раз за зиму выпускают на лыжах, а остальное время в зале). Обычно это был бег, подтягивания, прыжки в длину и т.д. (именно по соревновательной системе), но все перевернулось, когда были устроены состязания по армрестлингу, да еще и между разными классами. После этого на переменах мы искали свободный стол, чтобы продолжить состязания – это было очень интересно. Кто ходил в спортзал, начали усиленно заниматься своими предплечьями и плечами. Почти у каждого был кистевой эспандер. Нет, я учился не в спортивной школе, а на физмате. Просто у нас не было телефонов и планшетов. С того времени прошло уже больше 20 лет, но я до сих пор люблю спорт, на сколько это позволяет время.

Недавно наткнулся на дисплей от телефона Nokia 3310 и решил его запустить на Arduino nano. Для вывода графики использовал библиотеку «Adafruit_PCD8544.h», именно на таком драйвере реализован дисплей. Разрешение составляет 84х48 точек. Получилось очень даже ничего, как мне кажется.

Измеритель силы хвата. Когда реально переоценил свою силу - 2
Рис.1. Первый запуск дисплея.

Дисплей лежит без дела и пылится. Сразу рекой полились мысли, для чего бы его можно было использовать. И внезапно пришла идея сделать кистевой силомер (конечно, они есть в продаже и даже электронные). Начал изучать различные варианты датчиков веса для моего применения. Самый удобный – это тензодатчик на растяжение, но цена в несколько раз превышает стоимость балочного датчика на изгиб.

Измеритель силы хвата. Когда реально переоценил свою силу - 3
Рис.2. Тензодатчик балочного типа на 200 кг.

Когда мне пришла эта болванка, я был очень удивлен, так как выбирал именно по весовым характеристикам, а не по габаритам, что было напрасно. Длина датчика около 145мм. Ну ладно, будем работать с тем, что имеем.

Пока посылка, не торопясь шла из Китая, я решил сделать плату и начать писать софт. В тот момент я еще не знал, что проблемой будет не железо и софт, а именно корпус и механика.

Чтобы уменьшить габариты устройства я отказался от использования модуля Arduino nano и делал схему на сразу ATmega328P, но оставив при этом CH340C для возможности прошивки через USB. Для подключения тензодатчика использовал популярную микросхему HX711. Так как это все-таки «носимое» устройство – не обойтись без аккумулятора. Схема зарядки построена на микросхеме LTC4054ES5 (по-простому LTH7). Чтобы не выдумывать тумблеров на включение/выключение устройства (не в сон ведь загонять), решил поставить датчик касания на TTP223 и рубить питание транзистором IRLML6401. Так как все это у меня было в виде модулей, предварительно отмакетировал.

Измеритель силы хвата. Когда реально переоценил свою силу - 4
Рис.3. Схема измерителя силы хвата.

Чтобы не утомлять вас кучей картинок сделал несколько коллажей для отражения процесса работы над устройством.

Измеритель силы хвата. Когда реально переоценил свою силу - 5
Рис.4. Процесс макетирования.

Аккумулятор взял плоский на 1000мАh. Его хватает на четверо суток непрерывных измерений и отображения информации на дисплее. Печатная плата получилась габаритами 54х36 мм.

Измеритель силы хвата. Когда реально переоценил свою силу - 6

Все это, конечно, замечательно, но как теперь сделать сами ручки для деформации балки? У нас есть принтер, но, как я предположил, он не выдержит такую нагрузку. Если у кого-то есть опыт реализации чего-то подобного и достаточно прочного, просьба поделиться. При 3Д печати обычно используется частичное заполнение внутренних полостей, например сотами. Может можно сделать полное заполнение или использовать какое-то хитрое направление слоев друг относительно друга. Использовать ребра жесткости? Не знаю.

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

Измеритель силы хвата. Когда реально переоценил свою силу - 7
Рис.5. Заготовки для ручки.

Получилось три заготовки. Пара одинаковых и центральная часть, которая будет «ходить» при сжимании рукоятки. Покрыл мебельным воском и немного заполировал. Порядка недели (вечерами в свободное время) у меня ушло, чтобы придумать как будут крепиться алюминиевые уголки и как сделать вырезы, чтобы одно другому не мешало. Сначала уголки прикручивались к фанере всего двумя винтами, но нагрузка оказалась слишком большой и отверстия начинали разбалтываться. В итоге осталось только одно слабое место – это центральная часть на четырех винтах к уголку, но мое «рукопожатие» выдерживает.

Чтобы закрыть электронику решил все-таки прибегнуть к помощи принтера и напечатать крышку с вырезом для дисплея.

Измеритель силы хвата. Когда реально переоценил свою силу - 8
Рис.7. Верхняя крышка.

Рисовать умею только в SketchUp и то плохо, но в целом, все достаточно просто и удобно. Поставил очередную пробную версию программы. Печатаю.

Измеритель силы хвата. Когда реально переоценил свою силу - 9
Рис.6. Первая печать крышки.

Вот то самое заполнение, про которое я говорил выше. Принтер накладывает четыре слоя пластика, затем соты, затем закрывает.

Измеритель силы хвата. Когда реально переоценил свою силу - 10
Рис.8. Первый блин комом.

В какой-то момент заготовка оторвалась и получилась вот такая борода. При следующей печати нанес на стекло принтера специальный лак. Рекомендую.

Измеритель силы хвата. Когда реально переоценил свою силу - 11
Рис.9. Размещение электроники.

Дисплей закрепил на тонкий двухсторонний скотч. Контакт для тач-кнопки сделал в виде медного лепестка с отверстием, в который будет вкручен саморез крепления крышки. Тыкаем в головку самореза – включаем/выключаем устройство.

Пока все это делал оторвал разъем на дисплее. Нашел у себя другой от Nokia 3410. В интернетах пишут, что для него нужно использовать другую библиотеку, так как его разрешение 96х65 пикселей. Уже смирился, что придется переписывать код, но этого не понадобилось. Поменял в исходниках библиотеки разрешение на свое и все заработало. Оставил так. Этот дисплей намного приятнее по отображению шрифтов.

Измеритель силы хвата. Когда реально переоценил свою силу - 12
Рис.10. Дисплей от Nokia 3410.

Запилил отображение процесса зарядки в виде молнии в углу. Получилось симпатично.

Да, как бы это ни было печально, но мой рекорд составил всего 49 кг. Ни 200, ни 100, а всего 49. Думаю, что дело в преобразовании величин в скетче программы (нет).

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include "HX711.h"
#include <EEPROM.h>

Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 8);

#define ADC_CHARGE A6
#define TEST_LED 14
#define nCHARGE 19

int MAX_Weight = 0;
int lenght_line = 0;
float units = 0;
float ounces = 0;
int inc_ounces = 0;
int max_ounces = 0;

HX711 scale;

void setup() {
  Serial.begin(115200);
  analogReference(INTERNAL);
  //GPIO
  pinMode(TEST_LED, OUTPUT);
  pinMode(nCHARGE, INPUT_PULLUP);
  //pinMode(ADC_CHARGE, INPUT);
  analogWrite(ADC_CHARGE, LOW);
  //LCD
  display.begin();
  display.cp437(true);
  display.setContrast(60);
  display.clearDisplay();
  //HX711
  scale.begin(3, 2);
  //EEPROM
  if (EEPROM.read(0) > 200) EEPROM.update(0, 0);
  MAX_Weight = EEPROM.read(0);
  delay(10);
}

void loop() {
  display.clearDisplay();

  display.drawLine(80, 3, 82, 3, BLACK);
  display.drawRect(78, 4, 7, 9, BLACK);
  lenght_line = analogRead(ADC_CHARGE);
  if (lenght_line < 496) lenght_line = 496;
  if (lenght_line > 643) lenght_line = 643;
  lenght_line = map(lenght_line, 496, 643, 0, 5); // 496(3.3V)-643(4.2V)
  display.drawLine(80, 10, 80, 10 - lenght_line, BLACK);
  display.drawLine(81, 10, 81, 10 - lenght_line, BLACK);
  display.drawLine(82, 10, 82, 10 - lenght_line, BLACK);

  display.drawRect(0, 0, 96, 65, BLACK);
  display.setCursor(11, 5);
  display.setTextColor(BLACK, BLACK);
  display.setTextSize(1);
  display.print(utf8rus("Сила хвата"));
  display.drawLine(0, 15, 96, 15, BLACK);

  for (int i = 0; i < 10; i ++) units = + scale.get_units(), 10;
  units / 10;
  ounces = units * 0.035274 / 1000;

  display.setCursor(18, 26);
  display.setTextSize(2);
  display.print((int)(ounces));
  display.setCursor(59, 26);
  display.print(utf8rus("кг"));

  if (max_ounces < ounces)
    max_ounces = ounces;

  if (ounces > MAX_Weight) {
    MAX_Weight = ounces;
    EEPROM.update(0, MAX_Weight);
    digitalWrite(TEST_LED, HIGH);
    delay(500);
    digitalWrite(TEST_LED, LOW);
  }

  display.drawLine(0, 49, 96, 49, BLACK);
  display.setCursor(13, 54);
  display.setTextSize(1);
  display.print(utf8rus("Рекорд:"));
  display.setCursor(55, 54);
  display.print(MAX_Weight); //EEPROM
  display.setCursor(75, 54);
  display.print(utf8rus("кг"));

  if (digitalRead(nCHARGE) == 0) {
    display.fillTriangle(87, 3, 91, 7, 89, 7, BLACK);
    display.fillTriangle(89, 7, 91, 12, 87, 8, BLACK);
    display.drawLine(87, 3, 91, 12, BLACK);
  }

  if ((int)ounces > 5) {
    inc_ounces = 1;
  }

  if (((int)ounces < 5) && (inc_ounces == 1)) {
    for (int k = 0; k < 3; k++) {
      display.clearDisplay();
      display.drawRect(0, 0, 96, 65, BLACK);
      display.display();
      delay(400);
      display.clearDisplay();
      display.drawRect(0, 0, 96, 65, BLACK);
      if (max_ounces < 10)
        display.setCursor(39, 22);
      else if (max_ounces < 100)
        display.setCursor(31, 22);
      else if (max_ounces >= 100)
        display.setCursor(23, 22);
      display.setTextSize(3);
      display.print(max_ounces);
      display.display();
      delay(600);
    }
    inc_ounces = 0;
    max_ounces = 0;
  }
  display.display();
  delay(10);
}

По софту вроде ничего сложного. Инициализируем библиотеки (работа с дисплеем, весами, русскими буквами и EEPROM).

При старте читаем из EEPROM «рекорд», чтобы отобразить его на экране. Так как мне не нужно экономить батарейку в loop() постоянно обновляю весь экран (и часто). Уровень заряда отрисовываю просто исходя из остаточного напряжения на аккумуляторе. Делаю замеры датчика веса, запоминаю максимальное, если значение в какой-то момент стало меньше пяти (ослабили хват), трижды мигаю максимальным значением на экране. Если показание датчика, больше записанного в EEPROM – сохраняю. Вот и все. На экране все выглядит красиво и ничего лишнего, хотя сам код далеко не идеален.

Что примечательно. Тензодатчик стандартный и построен на основе резистивного моста, перекос сопротивления которого происходит в результате растягивания/сжатия его элементов. Получается схема тоже стандартная. Подключаю, измеряю и ничего. Методом «тыка» (по измерениям мультиметром ничего не понятно) получилась такая схема: Е+ — красный, Е- — зеленый, А- — белый, А+ — черный. Странно, но такого варианта я не встречал.

В итоге получилась вот такая конструкция. Громоздко, много винтов, уголков и фанеры, но вполне работоспособно.

Измеритель силы хвата. Когда реально переоценил свою силу - 13
Рис.11. Итоговый результат.

Спасибо за внимание и успехов!

Автор: the_bat

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js