Датчик толщины нити (филамента)
В данной статье расскажу реализацию своей идеи датчика толщины филамента на основе 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) – два значения в кадре.
На основе такого датчика легко построить систему измерения сечения нити путем установки нескольких датчиков под различными углами обзора нити.
Кроме того, датчик можно использовать для обнаружения обрыва нити.