В данной статье расскажу реализацию своей идеи датчика толщины филамента на основе USB микроскопа.
Из известных в интернете реализаций датчика толщины нити, мой вариант является “самым, самым”. Датчик самый простой в повторении, самый дешевый и самый точный, но и самый большой из известных.
Известно, что в промышленных условиях нить изготавливается путём выдавливания расплавленного пластика с определённой скоростью в охлаждающую ванну. Сопла для нити диаметром 2,85 мм и 1,75 мм на самом деле имеют одинаковый размер, но нить растягивается больше или меньше, когда выходит из сопла.
Регулируя скорость выдавливания и растягивания, система может производить нить любого желаемого размера на одном и том же диаметре сопла. Как и любая механическая система, она нуждается в постоянной настройке для поддержания этого баланса. Обычно это делается путём измерения нити лазером после её охлаждения и передачи этой информации обратно в систему. У лучших производителей нитей есть несколько лазеров и очень быстрые контуры обратной связи. Некоторые из лучших производителей обеспечивают разницу в толщине между любыми двумя точками нити в пределах +-20 мкм, а некоторые из худших производителей допускают отклонения до +-100 мкм.
При 3D печати пластик подаётся в экструдер принтера с постоянной линейной скоростью, что приводит к изменению объёма пластика, выходящего из сопла в единицу времени. При наилучших условиях мы наблюдаем изменение объёма расплавленного пластика примерно на 1%. При наихудших условиях изменение может составить более 10%.
Когда экструдер 3D принтера получает на 10% больше пластика, он просто выталкивает его и продолжает работать. Однако, если нить достаточно сильно отличается от идеальной, это может привести к видимым дефектам на печати, а, в худшем случае, к сбою печати из-за избыточного или недостаточного выдавливания пластика.
Для устранения этой проблемы используют управление скоростью печати в зависимости от текущей толщины, либо объема нити.
Таким образом, как для производства, так и для печати важное значение имеет возможность измерить толщины, а еще лучше, площади сечения нити.
Для реализации такого датчика использовал USB микроскоп с ПЗС матрицей 640x480. При этом погрешность измерения датчика составила порядка 3 мкм.
Доработка такого микроскопа сводится к сверлению сквозного отверстия диаметром 3 мм в пластмассовой насадке и установке за ним относительно объектива белого экрана из бумаги. Для нити белого цвета экран делается из черной бумаги. Прозрачной нити у меня нет, поэтому рекомендаций дать не могу.

Для более точного измерения толщины нитей диаметром 2. 85 мм и 1.75 мм можно сделать два сквозных отверстия диаметрами 3 мм и 2 мм, либо использовать для каждой нити свою насадку.
В результате получаем вот такое устройство:

Для измерения толщины нити написал программу на основе OpenCV:
#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
VideoCapture cap;
int camId = 0; long m = 80;
cap.open(camId); if (!cap.isOpened()) { cout << "Camera not found at " << camId; return -1; }
long w = cap.get(CAP_PROP_FRAME_WIDTH);long h = cap.get(CAP_PROP_FRAME_HEIGHT);long fps = cap.get(CAP_PROP_FPS);
printf("%dx%d,fps=%d\n", w, h, fps);
long rows = 0;//Количество строк
long cols = 0;//Количество столбцов
int* pсl; //граница нити слева
int* pсr; //граница нити справа
int* hz; //гистограмма
Mat frame; Mat frame1;
long r; long c;//Текущий номер строки.
long c_beg; long c_end; //начальный и конечный столбец расположения нити.
//--------------------------
while (true) {
bool grabSuccess = cap.read(frame);
if (grabSuccess == false) {printf("Erro to grab a frame"); return 1; }
imshow("frame", frame);
cvtColor(frame, frame1, COLOR_RGB2GRAY);
if (rows == 0) {
rows = frame1.rows ; cols = frame1.cols; c_beg = 0; c_end=cols;
pсl = (int*)malloc(rows * sizeof(int));
pсr = (int*)malloc(rows * sizeof(int));
hz = (int*)malloc(cols * sizeof(int));
}
//--------
c = 0; while (cols > c)hz[c++] = 0;
int* pxl = pсl; int* pxr = pсr;
for (r = 0; r <rows; r++) {
uchar* e = frame1.ptr<uchar>(r); //указатель на строку
uchar* p = e;
*pxr = 0; *pxl = 0; c = 0; while (cols > c++) {
if (*p<m) *p = 0; else *p = 255;
if (*pxl == 0) { if (*p == 0)*pxl= c;} //левый край
else { if (*p == 0) { int z = *pxl; if (z) { while (c > z) e[z++] = 0; *pxr = c; } } }
*p++; } //Обходим все столбцы:
hz[*pxr - *pxl]++;
pxr++; pxl++;
} //Обходим все строки
imshow("frame1", frame1);
//--------
long s = 0; c = 0; while (cols > c) { long z = hz[c]; if (z > 1) { s += z; printf("%d(%d);", c, z); } c++; }
printf("s=%d\n",s);
//--------------------------
if (waitKey(10) == 27) { cout << "quit by esc"; break; }
}
free(hz); free(pсl); free(pсr);
return 0;
}
Результат работы датчика:
На рис. 116 мм и 15 мм - это размеры изображения на экране. Они позволяют проверить правильность работы программы. 116 мм соответствуют 640 пиксель.


Например: 437(2);439(11);440(118);441(244);442(96);443(8)
437- толщина нити , (2) – два значения в кадре.
На основе такого датчика легко построить систему измерения сечения нити путем установки нескольких датчиков под различными углами обзора нити.
Кроме того, датчик можно использовать для обнаружения обрыва нити.
Комментарии (16)
Pridachin_N_L
01.06.2025 06:43Огромная благодарность за статью, сам собирался реализовать что то подобное но думал в сторону камеры на распбери. Микроскоп хорошая идея! Есть ли в планах увязать это с клипером?
ABy
01.06.2025 06:43Интересно, но какой в этом практический смысл?
Dominikanez
01.06.2025 06:43Для пластика от недорогих поставщиков трудно ожидать калиброванного прутка. В этом случае можно в режиме реального времени корректировать базовый поток прутка, заданный при подготовке детали к печати. Это существенно сыграет на качестве печати, особенно массивных деталей. А в некоторых случаях это может спасти многочасовую печать, если диаметр прутка существенно увеличивается и его надо очень медленно тянуть. У меня вот буквально на днях запороло 16-часовую печать недорогим TPU 90А от Kingroon, его диаметр сильно гуляет по всей катушке. Такая надстройка наверняка спасла бы ситуацию
Vindicar
01.06.2025 06:43Прикольно, но: как быть с разными цветами филамента, например, с белым или почти белым?
Я бы рассмотрел такую опцию: меняете цвет на BGR2HSV, и тогда уже можно выбирать из двух каналов: насыщенность S и яркость V, а также выбирать обычный или инвертированный порог в зависимости от фона.
Если не хочется заставлять пользователя что-то настраивать, я бы сделал фон двуцветным (половина чёрная, половина белая). Тогда можно будет каждую половину анализировать отдельно и выбирать более подходящую по величине дисперсии яркости (на подходящей половине дисперсия будет больше). Это уменьшает анализируемый участок филамента, но зато позволяет вообще не задумываться о тёмном/светлом цвете.
nikolz Автор
01.06.2025 06:43Для нити белого цвета экран делается из черной бумаги. Прозрачной нити у меня нет, поэтому рекомендаций дать не могу.
Forever73
01.06.2025 06:43За статью спасибо! Но просьба написать продолжение: как увязать это с клиппером и пример работы на реальном плохом филаменте
svistkovr
01.06.2025 06:43Для измерения толщины лучше использовать механический тактильный датчик. Пруток пропускается через два прорезиненных ролика на пружинке и замеряется расстояние между роликами. Аналогичный механизм работает в шариковой ручке, там вместо прутка идёт дозировка чернил. Замерять можно как через оптопару так и ёмкостным способом. Для точности в 0.13-0.05 мм под FDM принтеры этого с головой хватит. Помимо толщины с такого датчика можно получать карту шероховатости поверхности прутка.
Преимущество перед камерой в том что идёт поток единичного значения в реалтайме, в то время когда на камере надо пройтись по всей матрице пикселей несколько раз и ещё какую-то обработку по распознаванию сделать.P.S. Также такой датчик можно напрямую подключить через простой дифференциатор к блоку управления скоростью и через обратную связь управлять скоростью движения прутка в реальном времени.
Fqyeh29
01.06.2025 06:43По сути можно совместить. Филаментом двигать ролики, и камерой измерять смещение
nikolz Автор
01.06.2025 06:43Решение с роликами и электронным микрометром есть в интернете. Мое решение для задач, в которых требуется на порядок более точное измерение. Кроме того, оно проще и надежнее, так как нет движущихся частей.
xSVPx
01.06.2025 06:43Вы камерой точнее чем микрометром измеряете ? На порядок ? Есть какие-то подтверждения этого ? Чем меряли результаты в долях микрон ?
Вся надежность рассыпается сразу как только филамент другого цвета или "несуществующий прозрачный" попадется. В целом такие микроскопы сделаны из говна и веток, он сам по себе ненадежный совершенно...
nikolz Автор
01.06.2025 06:43Вы не поняли суть статьи.
В данной статье применен самый простейший USB микроскоп с матрицей 640x480.
Проблема не в том, какая у вас камера, а в том как вы получите четкое и стабильное изображения участка шириной в 2-3 мм.
--------------------
Можете провести очень простой эксперимент. Возьмите линейку и получите фотографию ее делений.
Потом сравните вот с этим изображением с данного USB микроскопа:
Изображение участка линейки 2 мм через USB микроскоп 640x480 пиксель.. Если получите лучше, то будет интересно узнать об этом.
---------------------
Относительно надежности USB микроскопов.
Эти микроскопы настолько простые в конструкции,
что в них нечему ломаться. У меня такой микроскоп работает более 10 лет.
buratino
очень интересно, но нифига не понятно.
Какой микроскоп использовался из 100500 возможных неясно, кто такое OpenCV - непонятно, ссылку на проект кто запрещает давать, религия?
Почему на фото взялся провод - неясно. Как внезапно на поле размером 480 пикселей и 116 мм провод диаметром 280 мкм внезапно получился 85 пикселей и 15 мм будет понятно вероятно только укуренному Илону Маску
Измерений много, кто мешает начертить пару графиков по результатам-то.....
Forever73
Согласен..., в первой иллюстрации явно есть ошибки в размерах: 116мм и 15мм. Они взрывают мозг-он начинает много думать, но ответа не находит..:)
nikolz Автор
Это размеры на экране. Они позволяют проверить правильность работы программы.
Добавил пояснение в статью.