Приветствую, Хабр!

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



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


Рис.1. Первый запуск дисплея.

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


Рис.2. Тензодатчик балочного типа на 200 кг.

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

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

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


Рис.3. Схема измерителя силы хвата.

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


Рис.4. Процесс макетирования.

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



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

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


Рис.5. Заготовки для ручки.

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

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


Рис.7. Верхняя крышка.

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


Рис.6. Первая печать крышки.

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


Рис.8. Первый блин комом.

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


Рис.9. Размещение электроники.

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

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


Рис.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 – сохраняю. Вот и все. На экране все выглядит красиво и ничего лишнего, хотя сам код далеко не идеален.

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

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


Рис.11. Итоговый результат.

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

Комментарии (18)


  1. juray
    07.07.2025 10:23

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


    1. the_bat Автор
      07.07.2025 10:23

      Спасибо что прочитали) Датчик купил на 200 кг. Думаю, что на 100 кг хватило бы с запасом. В крайнем случае на 150. Просто они достаточно сильно отличаются по габаритам.


      1. Lev3250
        07.07.2025 10:23

        То есть вы не можете повиснуть на турнике на одной руке?

        UPD, почитал по теме. Куча разных техник и методик подсчёта.

        Вопрос по прибору: удобно ли лежит в руке? может с другим хватом были бы и другие результаты?


        1. the_bat Автор
          07.07.2025 10:23

          Могу. Висеть и сжимать - это разные вещи. Вот повиснуть на пальцах могу, а потом сжать турник на одной руке - не могу.


          1. Lev3250
            07.07.2025 10:23

            о, это, кстати, очень интересный тест! Повиснуть на кончиках пальцев и потом сжать кисть. Завтра по дороге на работу попробую


            1. the_bat Автор
              07.07.2025 10:23

              Отпишитесь потом, интересно что получилось.

              Много зависит от Вашего веса и развития предплечья и кисти.


        1. the_bat Автор
          07.07.2025 10:23

          Ручки вполне удобные, только средняя тонковата, но сжимать не больно. Не знаю, думаю с более удобной ручкой результат не будет сильно выше.


  1. Daddy_Cool
    07.07.2025 10:23

    ~50 кг в импульсе выглядит адекватно. Интуитивно - удержать в течение секунды мешок с цементом... Дольше уже вряд ли.


    1. the_bat Автор
      07.07.2025 10:23

      Да, я когда увидел результат решил загуглить (да, с опозданием). Обычный хват в среднем до 70 кг. Альпиниста бы сюда или легкоатлета с турника )


      1. Maccimo
        07.07.2025 10:23

        Альпиниста бы сюда

        Спортивного скалолаза, трудника или боулдерингиста.


  1. xirahai
    07.07.2025 10:23

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

    Фото платы индикации с тензодатчиком


  1. SysManOne
    07.07.2025 10:23

    Зашёл увидеть фотачки рукастых поцов, ломающих каптанкрэш на митапах, а тут ... "когда инженерам нечего делать". Ну и так, от адепта хвата, ЖКИ может и ничего, но ручки - хавно.


    1. the_bat Автор
      07.07.2025 10:23

      Вы совершенно правы! Ничего лучшего и удобного сделать не смог. Подозреваю что нужно лить из пластика, да и конфигурацию менять. Сколько у Вас хват, если не секрет?


      1. SysManOne
        07.07.2025 10:23

        Поддержу, эргономика ручек, особенно на больших усилиях играет крайне важную роль. У меня есть знакомый, который гвозди 200-к и 100-ки ломает (за каким-то хреном) десятками. Но у него маленькая ладошка, и развить усилие на ручке, когда её не захватить - сложно и результаты будут разными же у людей с разными ладонями. Ваша ручка - это хват под большой и указательный пальцы, а типа как CoC - эксплуатируют мышцы мизинца в большей степени.

        В идеале, для тренировочного процесса конечно же рукоять из чего-то тактильно приятного, что бы делать множество повторений. У меня есть Роберт Барабан, тренироваться на его рукоятях, если ладони не как лопаты - совершенно не возможно. А если адепт ещё и айти-шник-блоггер с пухленькими ручёнками - то ему будет очень болезно.

        Мой хват: 85-88кг, на FOH 5. У Девона Ларрата, к слову, около 70. ;-)

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


        1. the_bat Автор
          07.07.2025 10:23

          Очень впечатляет. Если год рождения у Вас в профиле правильный, то уважение вдвойне.


        1. the_bat Автор
          07.07.2025 10:23

          У меня, кстати, такой. 200LB. Хорошая штука.


    1. vvzvlad
      07.07.2025 10:23

      Да нормальные ручки, что вы.

      Единственная претензия — думается мне, сила хвата может зависеть от размера этих ручек. У пружинных безменов это достигается само-собой, а вот тут кому-то возможно будет длина неподходящая.


      1. SysManOne
        07.07.2025 10:23

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

        И очень часто за "силой" чего-либо скрываются совсем разные вещи - одни считают что вис на турнике - это очень сильно для рук; другие считают что надо сильно что-то сжимать в моменте; оставшиеся могут считать, что таскать носилки с бетоном на 10 метров - это очень круто для силы хвата.