Ручной электронный счетчик метража на базе диспенсера для скотча

HardLizard

✩✩✩✩✩✩✩
1 Авг 2025
0
0
Появилась идея создать электронный ручной счетчик метража для измерения длинны троса, кабеля или шланга. За основу взял ручной диспенсер для скотча. Ардуино, Энкодер, дисплей, Аккумулятор, Плата зарядки, Преобразователь. Колесо 60мм поставить вместо катушки под скотч. На пружину поставить валик поменьше. Энкодер, ардуино и дисплей установить на кронштейне справа. Плату питания и аккум поставить в ручку.
 

Вложения

Мишутк

★✩✩✩✩✩✩
29 Мар 2025
86
35
Механическая часть потребует столько переделок, что ее проще с нуля изготовить на 3д принтере.
Электроника тривиальная, вопросов не вызывает.
С учетом цены похожих устройств на алишке за 5+ килорублей изделие для личного пользования стоит того, чтобы сделать самому.
 

Divin

★★★★✩✩✩
30 Янв 2021
463
207
@Геннадий П, извините за дилетантский вопрос, как положение прибора коррелирует с точностью измерений? Я могу представить что разность диаметров измеряемого материала влияет на точность , но положение прибора...,?
 

bort707

★★★★★★✩
21 Сен 2020
3,403
981
как положение прибора коррелирует с точностью измерений?
Думаю, Геннадий имеет ввиду положение ручки относительно поверхности. Представьте, что Вы начинаете измерять когда ручка горизонтальна("на три часа"), а заканчиваете - когда она в положении "на час". Вроде бы мелочь, можно и не заметить, а ошибка будет ни много ми мало радиус ролика.
 

HardLizard

✩✩✩✩✩✩✩
1 Авг 2025
0
0
@Мишутк, я изучал рынок таких устройств. Но на алишке не смотрел, поскольку стоял вопрос о закупе через организацию. Можете ссылки кинуть?
 

Мишутк

★✩✩✩✩✩✩
29 Мар 2025
86
35
Возможно ссылка "Например" не вставилась. У меня не открывается в разных браузерах.
Нда, деформировалась ссылка. Вчера после опубликования тыкал, проверял.
Но проще самому найти на алишке, "измеритель длины кабеля".
 

7Up

★✩✩✩✩✩✩
3 Июн 2021
147
10
Два валика, между ними трос, один валик с оптическим энкодером. Энкодер подключен к ардуино и считает импульсы
 

Divin

★★★★✩✩✩
30 Янв 2021
463
207
@7Up, колесико от мыши с щелями и энкодером, колесико крутиться...
 

selevo

✩✩✩✩✩✩✩
25 Апр 2020
25
4
@HardLizard,
Привет, сделал ?
вот попробуй:
C++:
#include <Arduino.h>
#include <EEPROM.h>

struct Config {
  uint8_t tick = 100;
  uint8_t encType = 1;      
  uint16_t diameter = 50;   
  uint16_t signalDist = 500; 
  uint16_t targetM = 0;
  uint16_t targetCM = 0;
  uint16_t targetMM = 0;
};

Config settings;
volatile long pulses = 0;
unsigned long lastSignalMillis = 0;
long totalTargetMM = 0;

void calculateTarget() {
  totalTargetMM = (settings.targetM * 1000L) + (settings.targetCM * 10L) + settings.targetMM;
}

double getMM() {
  return (pulses * (3.14159265 * settings.diameter)) / settings.tick;
}

void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  
  attachInterrupt(digitalPinToInterrupt(2), []() {
    if (settings.encType == 0) pulses++;
    else (digitalRead(3) == LOW) ? pulses++ : pulses--;
  }, RISING);

  EEPROM.get(0, settings); 
  calculateTarget();

  // ПРИВЕТСТВИЕ С ПЕРЕНОСОМ СТРОКИ
  Serial.println(F("Система готова к работе\nвведи ? для списка комманд."));
}

void loop() {
  if (Serial.available() > 0) {
    String cmd = Serial.readStringUntil('\n');
    cmd.trim();
    if (cmd.length() == 0) return;

    bool recognized = false;
    bool silentMode = false; 

    // --- Информационные команды (БЕЗ OK) ---
    if (cmd == "m?") { 
      Serial.println(getMM() / 1000.0, 2); 
      recognized = true; silentMode = true; 
    }
    else if (cmd == "cm?") { 
      Serial.println(getMM() / 10.0, 1); 
      recognized = true; silentMode = true; 
    }
    else if (cmd == "mm?") { 
      Serial.println((long)getMM()); 
      recognized = true; silentMode = true; 
    }

    // --- Остальные команды (С ПОДТВЕРЖДЕНИЕМ OK) ---
    else if (cmd == "?") {
      Serial.println(F("? - вывод списка комманд"));
      Serial.println(F("set? - вывод значений настроек"));
      Serial.println(F("m? - показать сколько отмоталось в метрах и два знака после запятой."));
      Serial.println(F("cm? - показать сколько отмоталось в сантиметрах."));
      Serial.println(F("mm? - показать сколько отмоталось в милиметрах."));
      Serial.println(F("save(1-16)- сохранить настройки в профиль 1...16 в eeprom если 0 то в текущий профиль."));
      Serial.println(F("load(1-16) - загрузить настройки из профиля 1...16 из eeprom если 0 то в текущий профиль."));
      Serial.println(F("tick (0-255) количество импульсов на оборот"));
      Serial.println(F("enc 0\\1 - тип энкодера\\тахометра 0- однопроводный 1- двухпроводный квадратурный"));
      Serial.println(F("diameter (1-65535) диаметр измерительного колеса в мм"));
      Serial.println(F("signal (0-65535) за сколько мм до конца метража начать подавать сигнал."));
      Serial.println(F("meters (0-65535) сколько метров отмотать 0 - не сигналить"));
      Serial.println(F("cm (0-65535) сколько сантиметров отмотать 0 - не сигналить"));
      Serial.println(F("mm (0-65535) сколько милиметров отмотать 0 - не сигналить"));
      recognized = true;
    } 
    else if (cmd == "set?") {
      Serial.println(F("--- Текущие настройки ---"));
      Serial.print(F("tick: ")); Serial.println(settings.tick);
      Serial.print(F("enc: ")); Serial.println(settings.encType);
      Serial.print(F("diameter: ")); Serial.println(settings.diameter);
      Serial.print(F("signal: ")); Serial.println(settings.signalDist);
      Serial.print(F("meters: ")); Serial.println(settings.targetM);
      Serial.print(F("cm: ")); Serial.println(settings.targetCM);
      Serial.print(F("mm: ")); Serial.println(settings.targetMM);
      recognized = true;
    }
    else if (cmd == "reset") { pulses = 0; recognized = true; }
    else if (cmd.startsWith("tick ")) { settings.tick = cmd.substring(5).toInt(); recognized = true; }
    else if (cmd.startsWith("enc ")) { settings.encType = cmd.substring(4).toInt(); recognized = true; }
    else if (cmd.startsWith("diameter ")) { settings.diameter = cmd.substring(9).toInt(); recognized = true; }
    else if (cmd.startsWith("daimeter ")) { settings.diameter = cmd.substring(9).toInt(); recognized = true; } 
    else if (cmd.startsWith("signal ")) { settings.signalDist = cmd.substring(7).toInt(); recognized = true; }
    else if (cmd.startsWith("meters ")) { settings.targetM = cmd.substring(7).toInt(); calculateTarget(); recognized = true; }
    else if (cmd.startsWith("cm ")) { settings.targetCM = cmd.substring(3).toInt(); calculateTarget(); recognized = true; }
    else if (cmd.startsWith("mm ")) { settings.targetMM = cmd.substring(3).toInt(); calculateTarget(); recognized = true; }
    else if (cmd.startsWith("save")) {
      int p = extractProfile(cmd);
      if (p >= 0 && p <= 16) { EEPROM.put(p * sizeof(Config), settings); recognized = true; }
    }
    else if (cmd.startsWith("load")) {
      int p = extractProfile(cmd);
      if (p >= 0 && p <= 16) { EEPROM.get(p * sizeof(Config), settings); calculateTarget(); recognized = true; }
    }

    if (recognized) {
      if (!silentMode) {
        Serial.print(cmd);
        Serial.println(F(" >> OK"));
      }
    } else {
      Serial.print(F("Ошибка: Неизвестная команда ["));
      Serial.print(cmd);
      Serial.println(F("]. Введите '?' для вывода списка команд."));
    }
  }

  handleSignal();
}

int extractProfile(String s) {
  int start = s.indexOf('(');
  int end = s.indexOf(')');
  if (start != -1 && end != -1) return s.substring(start + 1, end).toInt();
  return -1; 
}

void handleSignal() {
  if (totalTargetMM <= 0) { digitalWrite(13, LOW); return; }
  long remaining = totalTargetMM - (long)getMM();

  if (remaining <= 0) {
    digitalWrite(13, HIGH);
  } else if (remaining < settings.signalDist) {
    int interval = map(constrain(remaining, 0, settings.signalDist), 0, settings.signalDist, 40, 500);
    if (millis() - lastSignalMillis >= interval) {
      digitalWrite(13, !digitalRead(13));
      lastSignalMillis = millis();
    }
  } else {
    digitalWrite(13, LOW);
  }
}


UART колесный счетчик кабеля
Команды:
? - вывод списка комманд
set? - вывод значений настроек
m? - показать сколько отмоталось в метрах и два знака после запятой.
cm? - показать сколько отмоталось в сантиметрах.
mm? - показать сколько отмоталось в милиметрах.
reset- обнулить счетчик
save(1-16)- сохранить настройки в профиль 1...16 в eeprom если 0 то в текущий профиль.
load(1-16) - сохранить настройки в профиль 1...16 из eeprom если 0 то в текущий профиль.
tick (0-255) количество импульсов на оборот
enc 0\1 - тип энкодера\тахометра 0- однопроводный 1- двухпроводный квадратурный
daimeter (1-65535) диаметр измерительного колеса в мм
signal (0-65535) за сколько мм до конца метража начать подавать сигнал, по мере приближения к заданному значению сигнал будет учащаться.
meters (0-65535) сколько метров отмотать 0 - не сигналить
cm (0-65535) сколько сантиметров отмотать 0 - не сигналить
mm (0-65535) сколько милиметров отмотать 0 - не сигналить
 
Изменено: