Контроль диаметра нити
- Войдите на сайт для отправки комментариев
Вобщем собрал экструдер для нити 3D принтера...
Все хорошо екструдер работает шнек вращяется плачстик плавится нитка пошла.
Но чтоб диаметр нити был равномерным Я решил собрать не большую конструкцию для получения значений диаметра с помощю фоторезистора и светодиода, а какк эти значения заставить работать ... тут я так понимаю нужно использовать if else но как правильно? если к примеру когда нить нужного диаметра показатили примерно 610 это уже выводит монитор порта...
сейчас шаговик тянет нить с выставленой задержкой 60 но это примерно и нить тянется не нужного диаметра но тянется... что нужно дописать чтобы это значение менялось на необходимое чтоб показатели с фоторезистора колибались в раене 620-600
вот пример скетча
int PhotoRes = 0;
int stp = 13;
int dir = 12;
void setup(){
Serial.begin(9600);
pinMode (PhotoRes, INPUT);
pinMode(stp, OUTPUT);
pinMode(dir, OUTPUT);
}
void loop() {
Serial.println(analogRead(PhotoRes));
delay(10);
digitalWrite(stp, HIGH);
delay(60);
digitalWrite(stp, LOW);
delay(60);
}
Не одного коментария, ну и не удивительно), все заходят читают и думают что за идиот )
Я не обижаюсь), Я уже привык), мне просто трудновато дается программирование)
но все же прошу вашей помощи с написанием алгоритма...
а пока у меня выходит такая эксперементальная картина:
#include <AccelStepper.h> AccelStepper Stepper1(1,13,12); int PhotoRes = 0; int stp = 13; int dir = 12; void setup(){ Serial.begin(9600); pinMode (PhotoRes, INPUT); } void loop() { Serial.println(analogRead(PhotoRes)); Stepper1.move(analogRead(PhotoRes)); Stepper1.run(); }Движок вращяется со скоростю получаемой с фоторезистора, а мне нужно чтобы скорость вращения двигателя колебалась, в нужние моменты притормаживал либо наоборот ускорялся для удержания нужного значения к примеру "610"
#include <AccelStepper.h> AccelStepper Stepper1(1,13,12); #define PhotoRes 0 int Speed = 610; // начальная скорость int diameter = 0; int interval=100; // здесь задаем задержку,мс (скорость изменения скорости вращения) int stp = 13; int dir = 12; unsigned long prev = 0; void setup(){ Serial.begin(9600); pinMode (PhotoRes, INPUT); } void loop() { diameter = analogRead(PhotoRes); Serial.println(diameter); if (millis()-prev>interval) { if (diameter>610) Speed++; else if (diameter<610)Speed--; prev=millis(); } Stepper1.move(Speed); Stepper1.run(); }Коллеги, а вы уверены, что функция stepper.move(distance) имеет какое-то отношение к скорости вращения двигателя ?
Здесь http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html подробно расписано.
я просто написал как переменную скорости менять, а уж двигателем рулить думал ТС уже умеет.
наверное так надо?
#include <AccelStepper.h> AccelStepper Stepper1(1,13,12); #define PhotoRes 0 int Speed = 610; // начальная скорость int diameter = 0; int interval=100; // здесь задаем задержку,мс (скорость изменения скорости вращения) int stp = 13; int dir = 12; unsigned long prev = 0; void setup(){ Serial.begin(9600); pinMode (PhotoRes, INPUT); } void loop() { diameter = analogRead(PhotoRes); Serial.println(diameter); if (millis()-prev>interval) { if (diameter>610) Speed++; else if (diameter<610) Speed--; Stepper1.setSpeed (Speed); prev=millis(); } // Stepper1.runSpeed(); Stepper1.run(); }Шикарно) огромное спасибо
а как отключить инверсию?
Если лначение падает ниже 0 двигатель в другую сторону начинаетт вращятся...
в строку 26 добавить :
Вобщем собрал экструдер для нити 3D принтера...
Все хорошо екструдер работает шнек вращяется плачстик плавится нитка пошла.
Но чтоб диаметр нити был равномерным Я решил собрать не большую конструкцию для получения значений диаметра с помощю фоторезистора и светодиода, а какк эти значения заставить работать ... тут я так понимаю нужно использовать if else но как правильно? если к примеру когда нить нужного диаметра показатили примерно 610 это уже выводит монитор порта...
сейчас шаговик тянет нить с выставленой задержкой 60 но это примерно и нить тянется не нужного диаметра но тянется... что нужно дописать чтобы это значение менялось на необходимое чтоб показатели с фоторезистора колибались в раене 620-600
вот пример скетча
int PhotoRes = 0; int stp = 13; int dir = 12; void setup(){ Serial.begin(9600); pinMode (PhotoRes, INPUT); pinMode(stp, OUTPUT); pinMode(dir, OUTPUT); } void loop() { Serial.println(analogRead(PhotoRes)); delay(10); digitalWrite(stp, HIGH); delay(60); digitalWrite(stp, LOW); delay(60); }В таких вещах я думаю необходимо применение закона регулирования, П например или ПИ заглаза хватит.
В коде от MaksVV
Вместо (при таком подходе реакция будет медленной, т.к. при каждом этом событии скорость регулируеться на +-1)
if (millis()-prev>interval) { if (diameter>610) Speed++; else if (diameter<610) Speed--; Stepper1.setSpeed (Speed); prev=millis(); }нужно примерно это (В этом коде при каждом проходе скорость будеть изменяться пропорционально ошибке регулирования СРАЗУ на необходимую величину для устранения рассогласования)
Пример П (пропорционального регулятора)
if (millis()-prev>interval) { int error=(610-diametr);//рассоглосование (задание - текущее значение) Speed=error*kP;//kP - коэффициент пропорциональности (подбирается эксперементально) //для обеспечения минимальной ошибки регулирования //и не допущения колебательного процесса Stepper1.setSpeed (Speed); prev=millis(); }Но лучше применить ПИ регулятор который позволить более точно регулировать толшину нити и со временем скомпенсировать износ механизма подачи) ,а значения полученные с аналогово входа необходимо какнибудь фильтровать или усреднять для получения стабильной величины которую принимаем за дествительное значение толщины нити.
всё правда, но может и мой простой вариант будет норм работать, если задержкой interval поиграться (поменьше сделать) или вообще в луп поставить.
всё правда, но может и мой простой вариант будет норм работать, если задержкой interval поиграться (поменьше сделать) или вообще в луп поставить.
Все равно как часто будет вызываться расчет скорости, если скорость будет меняется +-1. Для выхода на нужное значение потребуется время, а по П закону сразу получаем первое приближение необходимой скорости, но с ним невозможно выдти на задание т.к. при рассогласовании равном 0 скорость тоже будет равна 0…
Так что лучше использовать ПИ закон, он и реакцию даст и точность.
как это все равно? Если чаще прибавлять/убавлять +-1, скорость быстрее меняться и будет.
если в лупе крутить, даже не знаю сколько понадобиться времени, чтобы в от края до края скорость прокрутить. пару миллисекунд, а то и меньше. Я думаю нитка не успеет растолстеть или похудеть
как это все равно? Если чаще прибавлять/убавлять +-1, скорость быстрее меняться и будет.
если в лупе крутить, даже не знаю сколько понадобиться времени, чтобы в от края до края скорость прокрутить. пару миллисекунд, а то и меньше. Я думаю нитка не успеет растолстеть или похудеть
Да я грубо говорю что время уйдет, понятно что это быстро происходит, но П еще быстрей. Если скорость необходимо на 10 поднять, то прибавляя по 1 надо 10 проходов, а П регулятор в первом же проходе на 10 увеличит сразу грубо говоря.
Ребятя огромное вам спасибо! Все действительно не так гладко...
Я сейчас все єто тестирую и думаю еще внести изменения добавить щетчик оборотов шнека...
Скоро напишу
Еще раз большое спасибо!
А какова точность измерения диаметра нити фоторезистором? вы вобще меряли как изменяются показания в зависимости от диаметра? я думаю что это будет на уровне шума... Ну или фоторезистор нужен специальный, или там оптика к ниму. Вобще такие вещи лазером меряются имхо.
Стандартная нить диаметр хорошо выдерживает. А такая приспособа разве что для плохой нити типа из бутылок полосками нарезанной, там измерение диаметра неактуально имхо, гуляют другие параметры...
а почему бы не другой вариант: берем цифровой штангельциркуль, добавляем к нему крепеж ролика и пружину. ролик вроде такого
https://gloimg.gbtcdn.com/gb/2015/201507/goods-img/1502212953347191875.jpg
пружина всегда прижимает чтобы точно повторять толщину, а такой ролик не даст нити соскочить или встать неправильно. а считать значения со штангельциркуля в гугле описано
https://www.google.ru/search?newwindow=1&q=%D0%B0%D1%80%D0%B4%D1%83%D0%B...
точность на порядки выше чем фоторезистор и т.д.
С новым годом! важаемие!
с этим кодом получается немножко не то...
Подскажите пожалуйста как добавить диапазон при котором скорость будет равна последнему значению до вхождения в этот диапазон типа не ">=555" и не "<=550"
С новым годом! важаемие!
с этим кодом получается немножко не то...
Подскажите пожалуйста как добавить диапазон при котором скорость будет равна последнему значению до вхождения в этот диапазон типа не ">=555" и не "<=550"
А код где?
#include <AccelStepper.h> AccelStepper m(1,12,11); #define p 1 int f = 250; // диаметр int s; // скорость int d; int i = 100; // здесь задаем задержку,мс (скорость изменения скорости вращения) int stp = 12; int dir = 11; unsigned long v; void setup(){ Serial.begin(115200); pinMode (p, INPUT); m.setMaxSpeed(2000); // предельная скорость } void loop() { d = analogRead(p); // Serial.print(s); Serial.println(d); if (millis()-v>i) { if (d<f) s++; else if (d>f) s--; v = millis(); } if (s<1) s=1; m.setAcceleration(500); // ускорение двигателя m.move(s); m.run(); }Немного притерпел изменений...
#include <AccelStepper.h> AccelStepper m(1,12,11); #define p 1 int f = 250; // диаметр int s; // скорость int d; int i = 100; // здесь задаем задержку,мс (скорость изменения скорости вращения) int stp = 12; int dir = 11; unsigned long v; void setup(){ Serial.begin(115200); pinMode (p, INPUT); m.setMaxSpeed(2000); // предельная скорость } void loop() { d = analogRead(p); // Serial.print(s); Serial.println(d); if (millis()-v>i) { //расчет скорости по ПИД закону регулирования //Параметры регулятора #define kP 150//коэффициент пропорциональности ПОДОБРАТЬ (примерно равен скорости при которой получается нужная толщина) #define p_min 0.0//минимум П составляющей - не < 0 #define p_max 100.0//максимум П составляющей - не > 2000 #define kI 0.100//коэффициент интегрирования ПОДБИРАТЬ #define i_min 0.0//минимум И составляющей #define i_max 700.0//максимум И составляющей #define kd 0//коэффициент диференциирования ПОДБИРАТЬ если надо #define d_ctl 300.0//зона пропорциональности ust-d_ctl ПОДБИРАТЬ #define out_min 0//минимальная скорость #define out_max 2000//максимальная скорость //Расчет скорости uint8_t out = 0; static float i = 0; static float ed = 0; float e, p; float d; e = (f- d); //ошибка регулирования p = (d< f- d_ctl) ? p_max : (d> f) ? p_min : (kP * e); //П составляющая i = (i < i_min) ? i_min : (i > i_max) ? i_max : i + (kI * e); //И составляющая d = kd * (e - ed); //Д составляющая ed = e; out = (p + i + d < out_min) ? out_min : (p + i + d > out_max) ? out_max : p + i + d; v = millis(); } m.setAcceleration(500); // ускорение двигателя m.move(s); m.run(); }С применением ПИ регулятора
Както так.
Еще необходимо добавить фильтрацию аналогового входа и вывод в порт для настройки регулятора
мне уже страшно от этого кода... мозг взорвется
#include <AccelStepper.h> AccelStepper m(1,12,11); #define p 1 int f = 280; // диаметр int s; // скорость int d; int i = 100; // здесь задаем задержку,мс (скорость изменения скорости вращения) int stp = 12; int dir = 11; unsigned long v; void setup(){ Serial.begin(115200); pinMode (p, INPUT); m.setMaxSpeed(2000); // предельная скорость } void loop() { d = analogRead(p); // Serial.print(s); Serial.println(d); if (millis()-v>i) { //расчет скорости по ПИД закону регулирования //Параметры регулятора #define kP 150//коэффициент пропорциональности ПОДОБРАТЬ (примерно равен скорости при которой получается нужная толщина) #define p_min 279.0//минимум П составляющей - не < 0 #define p_max 281.0//максимум П составляющей - не > 2000 #define kI 0.100//коэффициент интегрирования ПОДБИРАТЬ #define i_min 100.0//минимум И составляющей #define i_max 50.0//максимум И составляющей #define kd 1//коэффициент диференциирования ПОДБИРАТЬ если надо #define d_ctl 100.0//зона пропорциональности ust-d_ctl ПОДБИРАТЬ #define out_min 10//минимальная скорость #define out_max 2000//максимальная скорость //Расчет скорости uint8_t out = 0; static float i = 0; static float ed = 0; float e, p; float d; e = (f- d); //ошибка регулирования p = (d< f- d_ctl) ? p_max : (d> f) ? p_min : (kP * e); //П составляющая i = (i < i_min) ? i_min : (i > i_max) ? i_max : i + (kI * e); //И составляющая d = kd * (e - ed); //Д составляющая ed = e; out = (p + i + d < out_min) ? out_min : (p + i + d > out_max) ? out_max : p + i + d; v = millis(); } m.setAcceleration(500); // ускорение двигателя m.move(s); m.run(); }а можно както по проще ну хотяби типа
if diametr = 279, 280, 281, то speed = (последней урегулированой скорости)
else if diametr < 279, то speed++
else if diametr > 281 то speed--
ну гдето примерно так...
мне уже страшно от этого кода... мозг взорвется
#include <AccelStepper.h> AccelStepper m(1,12,11); #define p 1 int f = 280; // диаметр int s; // скорость int d; int i = 100; // здесь задаем задержку,мс (скорость изменения скорости вращения) int stp = 12; int dir = 11; unsigned long v; void setup(){ Serial.begin(115200); pinMode (p, INPUT); m.setMaxSpeed(2000); // предельная скорость } void loop() { d = analogRead(p); // Serial.print(s); Serial.println(d); if (millis()-v>i) { //расчет скорости по ПИД закону регулирования //Параметры регулятора #define kP 150//коэффициент пропорциональности ПОДОБРАТЬ (примерно равен скорости при которой получается нужная толщина) #define p_min 279.0//минимум П составляющей - не < 0 #define p_max 281.0//максимум П составляющей - не > 2000 #define kI 0.100//коэффициент интегрирования ПОДБИРАТЬ #define i_min 100.0//минимум И составляющей #define i_max 50.0//максимум И составляющей #define kd 1//коэффициент диференциирования ПОДБИРАТЬ если надо #define d_ctl 100.0//зона пропорциональности ust-d_ctl ПОДБИРАТЬ #define out_min 10//минимальная скорость #define out_max 2000//максимальная скорость //Расчет скорости uint8_t out = 0; static float i = 0; static float ed = 0; float e, p; float d; e = (f- d); //ошибка регулирования p = (d< f- d_ctl) ? p_max : (d> f) ? p_min : (kP * e); //П составляющая i = (i < i_min) ? i_min : (i > i_max) ? i_max : i + (kI * e); //И составляющая d = kd * (e - ed); //Д составляющая ed = e; out = (p + i + d < out_min) ? out_min : (p + i + d > out_max) ? out_max : p + i + d; v = millis(); } m.setAcceleration(500); // ускорение двигателя m.move(s); m.run(); }а можно както по проще ну хотяби типа
if diametr = 279, 280, 281, то speed = (последней урегулированой скорости)
else if diametr < 279, то speed++
else if diametr > 281 то speed--
ну гдето примерно так...
Ну тогда в своём коде частоту изменения скорости увеличьте хотябы до 1 сек.
И фильтрацию значений с аналогового входа добавьте, хотябы среднее из 10.
как это пишется?) пожалуйста!
Перед тем как скорость рассчитать проверяете диаметр и если он вне диапазона то регулирует скорость, а если нет проскакиваете.
Я не знаю как зафиксировать показатели последней скорости...
как это пишется?) пожалуйста!
Если (диам<100 и диам>300){
Если (диам<100) скорость++;
Иначе если (диам>300) скорость--;
}
Примерно
А по фильтрам в поиск.
такого не будит
как соеденить сюда еще дисплей? Я подключил дисплей, дисплей работает виводит диаметр но двигатель отваливается(((
#include <AccelStepper.h> AccelStepper m(1,12,11); #include <SPI.h> #include <Wire.h> #include <Adafruit_SSD1306.h> // Подключаем библиотеку программных драйверов для монохромных дисплеев #include <Adafruit_GFX.h> // Подключаем библиотеку для работы с текстом и графикой #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); #define p 1 //int f = 245; int s; // начальная скорость int d; int i = 1; // здесь задаем задержку,мс (скорость изменения скорости вращения) int stp = 12; int dir = 11; unsigned long v; void setup(){ display.begin(SSD1306_SWITCHCAPVCC); //Активируем дисплей // Serial.begin(115200); pinMode (p, INPUT); m.setMaxSpeed(2000); display.clearDisplay(); // Очищаем дисплей и буфер перед выводом display.setTextColor(WHITE); // Устанавливаем цвет шрифта (WHITE, BLACK) display.setTextSize(4); // Устанавливаем размер шрифта (от 1 до 4) // Выводим слово Temp display.setCursor(30,20); // Устанавливаем позицию вывода (x,y - левый верхний угол области вывода) display.print(String(d)); // Записываем показания датчика в строковом формате в буфер display.display(); } void loop() { d = analogRead(p); m.setAcceleration(2000); m.move(s); m.run(); if (millis()-v>i) { if (d>231) s--; else if (d<229) s++; else if (d=230)s; v = millis(); } if (s<1) s=1; display.clearDisplay(); // Очищаем дисплей и буфер перед выводом display.setTextColor(WHITE); // Устанавливаем цвет шрифта (WHITE, BLACK) display.setTextSize(4); // Устанавливаем размер шрифта (от 1 до 4) // Выводим слово Temp display.setCursor(30,20); // Устанавливаем позицию вывода (x,y - левый верхний угол области вывода) display.print(String(d)); // Записываем показания датчика в строковом формате в буфер display.display(); }точнее он крутится но ели ели и не меняется скорость
такого не будит
Я паражен... Откуда я могу знать что у Вас будет. Я просто пример написал. А вы перед тем как скорость регулировать сначала проверьте толщину и уж если она не в пределах то переходите к регулировке скорости.
Как совместить дисплей с движком?
Del
такого не будит
я не ТС. Я про то, что условие никогда не выполнится. тут нужно "или"
я не ТС. Я про то, что условие никогда не выполнится. тут нужно "или"
Пардон. С замечанием согласен.
Только ради Вас и немножечко себя... Идея не нова...
В течении месяца попробуем написать скетч для Arduino nano, uno... измерение толщины будет производится механически, через рычаг или разницу плеч, с помощью датчика холла, или даже нескольких... протяжка, униполярным двигателем и энкодер помощь...
за основу взят аналоговый датчик ss49e и его возможность "открываться" или закрываться при поднесении к нему магнита. Работает от 5v и не нужны ни какие дополнительныесть резисторы.
Будет реализовано несколько режимов работы.
Ожидание. В котором можно затянуть нить в протяжный механизм с помощью энкодера, поворачивая двигатель на определенное количество шагов ...
Работа. Двигатель вращается и подстраивается под "эталонное" значение, это значение задается 3 режимом, долгим удержанием кнопки, в зависимости от отклонения, а на 1 см около 1000 значений, двигатель ускоряется или замедляется на 0.1 оборота, так же с энкодера.
В данный момент, это частично теория, поскольку еще нет корпуса и двигателя... а холл продается в любых радиодеталях ценой меньше 50р....
Так же энкодер можно заменить 2 кнопками....
Возможно чуть позже реализуем расчет скорости для компенсации растояния от экструдера до датчика.
Уважаемый Dyrman не изобретайте велосипед. Для регулировки тощины необходим ПИД регулятор, а не какойто расчет скорости для компенсации...
Работал я одно время с термопласт автоматами, так там толщину регулируют скоростью экструдера. При пуске вытягивают из экструдера стренгу (так её машинисты называли), протягивали через ванну с водой для охлаждения, а от туда в протяжный механизм (он тянет с постоянной скоростью), тощину меряли на выходе микрометром с роликами, а регулировали толщину скоростью подачи шнека.
В Вашем случае главное это измерить тощину с необходимой точностью и пременить ПИД регулятор для потдержания неоходимой.
Ну значит будем регулировать скорость экструдера. А нятяжка будет постоянной, делов то, перекинуть управление. Тут же основное в том что бы точно измерить пластик.... если работали с промышленным экструдер ом, поделитесь опытом...
Какой раствор в ванной? Охлаждается ли ванная или она теплая? Присутствует ли сушка? На промышленных линиях находил микрометр, на али 900р, работал он через подвижный валик-подшипник, на Вашей линии так же было? Какая сила была на натяжителе?
Сразу хочу сказать, опыта в этом деле пока что нет, поэтому хотел скоростью экструдера регулировать текучесть, а протяжкой толщину, то есть чем быстрее протяжка, тем тоньше нить, и на оборот... с экструдер ом так же, чем дольше пластик внутри, тем больше он вариться и тем самым он более ждикий на выходе... как бы двойная регулировка для поиска золотой середины.
Я основывают на видео "Линия производства нити для 3D принтера" красный филамент из бокового экструдера
Примерно так
Да, на такие промышленные линии так же натыкался.
Все сходится. Может будет совет по шнеку? Есть разные отзывы на древесный бур и по бетону, какой лучше?
В проекте мы хотим сделать шоковую ванну, дно охлаждать элементами пелье, на их горячей стороне установить радиаторы, и через трубу выдувать теплый воздух на "сушилку", это 7 роликов на подшипниках, диаметром не более 10см, нить будет проходить от одного ролика к другому перекрестно, обдуваться, возможно будет мягкая щетка или губка, после чего попадает на центрующие ролики, измеритель толщины, протяжка, энкодер. Последние 3 стараюсь сделать в одном модуле. На счет намотки не думали даже, но думаю стоит посмотреть как наматывают нити, канаты, кабеля и тросы.
В остальном, жду Тарантулу, и буду все печатать... шредера чертеж нужен? Для лазера
Помучавшись некоторое время с екструдером получился следующий код и все вроде работает с помощю фоторезистора но со временем показания фоторезистора начинают падать и в результате измерения получаются не точные... вот код:
#include <AccelStepper.h> AccelStepper m(1,12,11); #define p 1 int minSpeed = 1000; //Минимальная скорость int s; //cкорость последня long d; //Среднее показание прибора int i = 10; //здесь задаем задержку, мс (скорость изменения скорости вращения) unsigned long v; void setup(){ Serial.begin(9600); m.setMaxSpeed(2700); m.setAcceleration(1000); } void loop(){ if (millis() - v > i) { //Снимаем 10 раз показания прибора и считаем среднее значение. d = 0; for (int k=0; k<10; ++k) { d = d + analogRead(p); } d = d/10; Serial.println(d); Serial.println(-s); if (s < minSpeed) s = minSpeed; if (d > 140) s--; else if (d < 139) s++; v = millis(); if (s>2700) s=2700; if (s<1000) s=1000; } m.setSpeed(s); m.runSpeed(); }И мне пришла идея использовать датчик освещенности BH1750 у него показатели намного точнее и диапазон показаний намного шире...но как его правильно вписать в код? при моих попытках его туда запихнуть получается что шаговик остонавливается и показания виводимие в порт идет начальные на момент загрузки ардуино идальше не меняются и шаговик опять же стоит на месте тоесть все не работает( , и еще при заливке стандартного скетча идущего с библиотекой BH1750 максимальная скорость считывания 150милисекунд есле меньше то он точно так же зависает и показивает одну и туже цифру... вот код:
#include <Wire.h> #include <BH1750.h> BH1750 lightMeter(0x23); #include <AccelStepper.h> AccelStepper m(1, 12, 11); int minSpeed = 1000; //Минимальная скорость int s; //скорость последняя long d; //Среднее показание прибора int i = 10; //здесь задаем задержку, мс (скорость изменения скорости вращения) unsigned long v; void setup() { Serial.begin(9600); m.setMaxSpeed(2700); m.setAcceleration(1000); Wire.begin(); if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE_2)); } void loop() { if (millis() - v > i) { //Снимаем 100 раз показания прибора и считаем среднее значение. d = 0; for (int k = 0; k < 10; ++k) { d = d + lightMeter.readLightLevel(); } d = d / 10; Serial.println(d); Serial.println(-s); if (s < minSpeed) s = minSpeed; if (d > 140) s--; else if (d < 139) s++; v = millis(); if (s > 2700) s = 2700; if (s < 1000) s = 1000; } m.setSpeed(s); m.runSpeed(); }Помогите пожалуйста как ихи скомпоновать...
я не уверен, но возможно эта статья Вам поможет, проверьте, идут ли данные с датчика.
ТЫК
или же если не получается, попробуйте подключить по i2c.
ТЫК
Да нет же сам датчик работает Я же говорю что сам датчик работает... и я же дал пример работы всей системи с фоторезистором но теперь в место фоторезистора нужно в код вписать етот датчик...
а вот пример со стандартной библиотеки с которым все работает в порт выходят данные....
/* Advanced BH1750 library usage example This example has some comments about advanced usage features. Connection: VCC -> 3V3 or 5V GND -> GND SCL -> SCL (A5 on Arduino Uno, Leonardo, etc or 21 on Mega and Due, on esp8266 free selectable) SDA -> SDA (A4 on Arduino Uno, Leonardo, etc or 20 on Mega and Due, on esp8266 free selectable) ADD -> (not connected) or GND ADD pin is used to set sensor I2C address. If it has voltage greater or equal to 0.7VCC voltage (e.g. you've connected it to VCC) the sensor address will be 0x5C. In other case (if ADD voltage less than 0.7 * VCC) the sensor address will be 0x23 (by default). */ #include <Wire.h> #include <BH1750.h> /* BH1750 can be physically configured to use two I2C addresses: - 0x23 (most common) (if ADD pin had < 0.7VCC voltage) - 0x5C (if ADD pin had > 0.7VCC voltage) Library uses 0x23 address as default, but you can define any other address. If you had troubles with default value - try to change it to 0x5C. */ BH1750 lightMeter(0x23); void setup(){ Serial.begin(9600); // Initialize the I2C bus (BH1750 library doesn't do this automatically) Wire.begin(); // On esp8266 you can select SCL and SDA pins using Wire.begin(D4, D3); /* BH1750 has six different measurement modes. They are divided in two groups; continuous and one-time measurements. In continuous mode, sensor continuously measures lightness value. In one-time mode the sensor makes only one measurement and then goes into Power Down mode. Each mode, has three different precisions: - Low Resolution Mode - (4 lx precision, 16ms measurement time) - High Resolution Mode - (1 lx precision, 120ms measurement time) - High Resolution Mode 2 - (0.5 lx precision, 120ms measurement time) By default, the library uses Continuous High Resolution Mode, but you can set any other mode, by passing it to BH1750.begin() or BH1750.configure() functions. [!] Remember, if you use One-Time mode, your sensor will go to Power Down mode each time, when it completes a measurement and you've read it. Full mode list: BH1750_CONTINUOUS_LOW_RES_MODE BH1750_CONTINUOUS_HIGH_RES_MODE (default) BH1750_CONTINUOUS_HIGH_RES_MODE_2 BH1750_ONE_TIME_LOW_RES_MODE BH1750_ONE_TIME_HIGH_RES_MODE BH1750_ONE_TIME_HIGH_RES_MODE_2 */ // begin returns a boolean that can be used to detect setup problems. if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) { Serial.println(F("BH1750 Advanced begin")); } else { Serial.println(F("Error initialising BH1750")); } } void loop() { uint16_t lux = lightMeter.readLightLevel(); Serial.print("Light: "); Serial.print(lux); Serial.println(" lx"); delay(1000); }в delay пишу 150 вместо1000 тоесть одной секунды и все работает но дело не в етом, а в том что в последнем примере Я чтото не так указал и датчик выбивате одно значение полученое на момент замуска ардуинки и тулит его в порт постоянно и неизменно и при етом еще и шаговик стоит на месте а он должен вращятся хотмбы с мнимальной скоростю...
#include <AccelStepper.h> AccelStepper m(1,12,11); #define p 1 int f = 250; // диаметр int s; // скорость int d; int i = 100; // здесь задаем задержку,мс (скорость изменения скорости вращения) int stp = 12; int dir = 11; unsigned long v; void setup(){ Serial.begin(115200); pinMode (p, INPUT); m.setMaxSpeed(2000); // предельная скорость } void loop() { d = analogRead(p); // Serial.print(s); Serial.println(d); if (millis()-v>i) { //расчет скорости по ПИД закону регулирования //Параметры регулятора #define kP 150//коэффициент пропорциональности ПОДОБРАТЬ (примерно равен скорости при которой получается нужная толщина) #define p_min 0.0//минимум П составляющей - не < 0 #define p_max 100.0//максимум П составляющей - не > 2000 #define kI 0.100//коэффициент интегрирования ПОДБИРАТЬ #define i_min 0.0//минимум И составляющей #define i_max 700.0//максимум И составляющей #define kd 0//коэффициент диференциирования ПОДБИРАТЬ если надо #define d_ctl 300.0//зона пропорциональности ust-d_ctl ПОДБИРАТЬ #define out_min 0//минимальная скорость #define out_max 2000//максимальная скорость //Расчет скорости uint8_t out = 0; static float i = 0; static float ed = 0; float e, p; float d; e = (f- d); //ошибка регулирования p = (d< f- d_ctl) ? p_max : (d> f) ? p_min : (kP * e); //П составляющая i = (i < i_min) ? i_min : (i > i_max) ? i_max : i + (kI * e); //И составляющая d = kd * (e - ed); //Д составляющая ed = e; out = (p + i + d < out_min) ? out_min : (p + i + d > out_max) ? out_max : p + i + d; v = millis(); } m.setAcceleration(500); // ускорение двигателя m.move(s); m.run(); }С применением ПИ регулятора
Както так.
Еще необходимо добавить фильтрацию аналогового входа и вывод в порт для настройки регулятора
Доброго времени! Хотя тема старая но интерес возник по ПИД регулированию датчиков света.
вопрос: от какого значения отталкиваться при подборе коэффициентов ПИД в этом коде?
и как можно реализовать фильтрацию аналогового входа и вывод в порт для настройки регулятора
#include <AccelStepper.h> AccelStepper m(1,12,11); #define p 1 int f = 250; // диаметр int s; // скорость int d; int i = 100; // здесь задаем задержку,мс (скорость изменения скорости вращения) int stp = 12; int dir = 11; unsigned long v; void setup(){ Serial.begin(115200); pinMode (p, INPUT); m.setMaxSpeed(2000); // предельная скорость } void loop() { d = analogRead(p); // Serial.print(s); Serial.println(d); if (millis()-v>i) { //расчет скорости по ПИД закону регулирования //Параметры регулятора #define kP 150//коэффициент пропорциональности ПОДОБРАТЬ (примерно равен скорости при которой получается нужная толщина) #define p_min 0.0//минимум П составляющей - не < 0 #define p_max 100.0//максимум П составляющей - не > 2000 #define kI 0.100//коэффициент интегрирования ПОДБИРАТЬ #define i_min 0.0//минимум И составляющей #define i_max 700.0//максимум И составляющей #define kd 0//коэффициент диференциирования ПОДБИРАТЬ если надо #define d_ctl 300.0//зона пропорциональности ust-d_ctl ПОДБИРАТЬ #define out_min 0//минимальная скорость #define out_max 2000//максимальная скорость //Расчет скорости uint8_t out = 0; static float i = 0; static float ed = 0; float e, p; float d; e = (f- d); //ошибка регулирования p = (d< f- d_ctl) ? p_max : (d> f) ? p_min : (kP * e); //П составляющая i = (i < i_min) ? i_min : (i > i_max) ? i_max : i + (kI * e); //И составляющая d = kd * (e - ed); //Д составляющая ed = e; out = (p + i + d < out_min) ? out_min : (p + i + d > out_max) ? out_max : p + i + d; v = millis(); } m.setAcceleration(500); // ускорение двигателя m.move(s); m.run(); }С применением ПИ регулятора
Както так.
Еще необходимо добавить фильтрацию аналогового входа и вывод в порт для настройки регулятора
Доброго времени! Хотя тема старая но интерес возник по ПИД регулированию датчиков света.
вопрос: от какого значения отталкиваться при подборе коэффициентов ПИД в этом коде?
и как можно реализовать фильтрацию аналогового входа и вывод в порт для настройки регулятора
Для фильтрации данных с аналогового входа есть множество вариантов, например вычислять среднее из 10 измерений. Можно взять 9 замеров, ранжировать, взять 5е, при следующем измерении выкинуть первое, все сдвинуть на 1, на последнее место поставить новое поступившее значение, снова ранжировать и т.д.. Можно взять 20% от первого измерения и 80% от второго и посчитать среднее (на таком способе проблемы с реакцией).
При подборе ПИД коэффициентов сначала подбирают кП до такого значения чтобы ошибка регулирования была минимальна и не было автоколебаний, потом кИ понемногу добавляют, кД может и ненужен будет.
В общем все эксперементально. Ну и в сети есть несколько стандартных способов тангенциальный и еще какието.
Удачи в изысканиях!
Если где неправильно написал поправьте.
Помучавшись некоторое время с екструдером получился следующий код и все вроде работает с помощю фоторезистора но со временем показания фоторезистора начинают падать и в результате измерения получаются не точные... вот код:
#include <AccelStepper.h> AccelStepper m(1,12,11); #define p 1 int minSpeed = 1000; //Минимальная скорость int s; //cкорость последня long d; //Среднее показание прибора int i = 10; //здесь задаем задержку, мс (скорость изменения скорости вращения) unsigned long v; void setup(){ Serial.begin(9600); m.setMaxSpeed(2700); m.setAcceleration(1000); } void loop(){ if (millis() - v > i) { //Снимаем 10 раз показания прибора и считаем среднее значение. d = 0; for (int k=0; k<10; ++k) { d = d + analogRead(p); } d = d/10; Serial.println(d); Serial.println(-s); if (s < minSpeed) s = minSpeed; if (d > 140) s--; else if (d < 139) s++; v = millis(); if (s>2700) s=2700; if (s<1000) s=1000; } m.setSpeed(s); m.runSpeed(); }И мне пришла идея использовать датчик освещенности BH1750 у него показатели намного точнее и диапазон показаний намного шире...но как его правильно вписать в код? при моих попытках его туда запихнуть получается что шаговик остонавливается и показания виводимие в порт идет начальные на момент загрузки ардуино идальше не меняются и шаговик опять же стоит на месте тоесть все не работает( , и еще при заливке стандартного скетча идущего с библиотекой BH1750 максимальная скорость считывания 150милисекунд есле меньше то он точно так же зависает и показивает одну и туже цифру... вот код:
#include <Wire.h> #include <BH1750.h> BH1750 lightMeter(0x23); #include <AccelStepper.h> AccelStepper m(1, 12, 11); int minSpeed = 1000; //Минимальная скорость int s; //скорость последняя long d; //Среднее показание прибора int i = 10; //здесь задаем задержку, мс (скорость изменения скорости вращения) unsigned long v; void setup() { Serial.begin(9600); m.setMaxSpeed(2700); m.setAcceleration(1000); Wire.begin(); if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE_2)); } void loop() { if (millis() - v > i) { //Снимаем 100 раз показания прибора и считаем среднее значение. d = 0; for (int k = 0; k < 10; ++k) { d = d + lightMeter.readLightLevel(); } d = d / 10; Serial.println(d); Serial.println(-s); if (s < minSpeed) s = minSpeed; if (d > 140) s--; else if (d < 139) s++; v = millis(); if (s > 2700) s = 2700; if (s < 1000) s = 1000; } m.setSpeed(s); m.runSpeed(); }Помогите пожалуйста как ихи скомпоновать...
В этом коде можно немного подправить чтобы увеличить скорость реакции
Вместо
if (d > 140) s--; else if (d < 139) s++;Нужно увеличивать и уменьшать не на единицу, а на разницу между заданным и измеренным
error= 140 (заданная) - d s=s+error; //тут проверять на выход из диапазона мин махТак будет пошустрее
//тут проверять на выход из диапазона мин мах
Не могли бы пояснить это утверждение?
//тут проверять на выход из диапазона мин мах
Не могли бы пояснить это утверждение?
Я так понимаю что s это скорость, соответственно она не может быть <0 и > максимальной.
if (s<s_min) { s=s_min; } if (s>s_max) { s=s_max; }примерно так.
Да...
А нельзя ли дальше оптимизировать, ставя вместо "int" ов uint8_t или uint16_t?
Это может повлиять на скорость исполнения кода?
Или что может повлиять?
Или может если на STM32 загрузить может ли увеличится скорость?
Оно и так должно все работать нормально.
А переменные нужно выбирать в соответствии с размерностью значений которые в них будут хранится.
#include <Wire.h> #include <BH1750.h> BH1750 lightMeter(0x23); #include <AccelStepper.h> AccelStepper m(1, 12, 11); int minSpeed = 1000; //Минимальная скорость int s; //скорость последняя long d; //Среднее показание прибора int i = 10; //здесь задаем задержку, мс (скорость изменения скорости вращения) unsigned long v; void setup() { Serial.begin(9600); m.setMaxSpeed(2700); m.setAcceleration(1000); Wire.begin(); if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE_2)); } void loop() { if (millis() - v > i) { //Снимаем 100 раз показания прибора и считаем среднее значение. d = 0; for (int k = 0; k < 10; ++k) { d = d + lightMeter.readLightLevel(); } d = d / 10; Serial.println(d); Serial.println(-s); if (s < minSpeed) s = minSpeed; error= 140 (заданная) - d s=s+error; //тут проверять на выход из диапазона мин мах if (s<s_min) { s=s_min; } if (s>s_max) { s=s_max; } v = millis(); if (s > 2700) s = 2700; if (s < 1000) s = 1000; } m.setSpeed(s); m.runSpeed(); }но выдает ошибку
Принято к сведению.
Не могли бы подправить?
Нет.
Нет так нет! Не очень то и нужен! Просто для интереса. А чё такие вредные здесь? Кидаются...