Использование концевого выключателя для остановки шагового двигателя
Я строю машину с подвижной станиной, которая движется вперед и назад. Мне нужно включить концевой выключатель на двух концах, который гарантирует, что двигатели остановятся в двух крайних точках. У меня есть 2 шаговых двигателя, управляемых драйверами двигателей TB6600, я пытаюсь начать с 1 концевого выключателя (SS-5Gl2) и продвигаться оттуда.
Мой первый вопрос: как мне получить код для остановки шаговых двигателей, если концевой выключатель замкнут?
// Определяем подключения шагового двигателя и количество шагов на оборот:
#define dirPin1 2
#define stepPin1 3
#define dirPin2 5
#define stepPin2 6
#define stepsPerRevolution 200 // Нам может понадобиться изменить 200 на 1600, чтобы получить более точное управление, т.е. десятичные дроби вместо целых чисел
#define Lim1 8
int direction = 0;
int remainder = 0;
long travel = 0;
long revolutions = 0;
void setup() {
// Объявить выводы выводом:
pinMode(stepPin1, OUTPUT);
pinMode(dirPin1, OUTPUT);
pinMode(stepPin2, OUTPUT);
pinMode(dirPin2, OUTPUT);
pinMode(Lim1, OUTPUT);
//Желаемое расстояние перемещения в мм !!!! ставь сюда!!!!
travel = 1;
//Желаемое направление!!!! ставь сюда!!!! переместить кубик внутрь (против часовой стрелки) = 1, вернуться назад (по часовой стрелке) = 0 !!!!
//направление = 0; не сработало, нужно логическое значение?
// Установите направление вращения против часовой стрелки (затухание) или по часовой стрелке (затухание):
//if(direction = 1) digitalWrite(dirPin, HIGH);
//if(direction = 0) digitalWrite(dirPin, LOW);
//устанавливаем направление вручную, раскомментируем HIGH для входа, LOW для возврата
digitalWrite(dirPin1, LOW);
digitalWrite(dirPin2, LOW);
//digitalWrite(dirPin, LOW);
digitalWrite(Lim1, OFF) //
// вычисление количества оборотов на основе введенных мм. Пока не учитывает частичные обороты - переменная усечена, по умолчанию используются целые числа. Потребуется еще один цикл для обработки остатка
// Константа 6,659 (микрон) основана на шаге винта привода 1,25 мм и передаточном отношении в редукторе
revolutions = 1000.00*travel/6.659;
//попытка вывести сохраненное значение на ПК для целей отладки
Serial.print("revolutions = ");
Serial.print(revolutions,4);
}
void loop() {
// Шаговый двигатель делает X оборотов быстро, скорость (задержка), по-видимому, ограничена напряжением. 42v должно идти быстрее?
// Требуется вложенный цикл, потому что целые числа в UNO ограничены ~ 32k
for (int i = 0; i < revolutions; i++) {
if (digitalRead(Lim1 == OFF)){}
else {
for (int j = 0; j < stepsPerRevolution; j++) {
// Эти четыре строки дают 1 оборот:
digitalWrite(stepPin1, HIGH);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin1, LOW);
digitalWrite(stepPin2, LOW);
delayMicroseconds(250);
}
}
}
while(1){}
}
@303jw1095, 👍0
Обсуждение2 ответа
Лучший ответ:
Вы выполняете каждый шаг вручную непосредственно с помощью digitalWrite()
, поэтому принципом будет чтение вывода концевого выключателя на каждой итерации внутреннего цикла for
в Оператор if
. Что делать в этом операторе if
, зависит от того, что вы хотите сделать при нажатии концевого выключателя. В настоящее время у вас есть бесконечный пустой цикл после вашего кода двигателя. Поэтому, если вы хотите остановиться навсегда, в этом случае вы можете создать еще один бесконечный цикл. Итак, что-то вроде этого:
...
for (int j = 0; j < stepsPerRevolution; j++) {
if(!digitalRead(Lim1)){
while(true);
}
// These four lines result in 1 revolution:
digitalWrite(stepPin1, HIGH);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin1, LOW);
digitalWrite(stepPin2, LOW);
delayMicroseconds(250);
}
Обратите внимание, что это предполагает, что вы подключили концевой выключатель к земле и используете цифровой контакт с подтягивающим резистором.
Но у вас есть еще 2 проблемы с кодом концевого выключателя:
Вы устанавливаете контакт концевого выключателя
Lim1
в качестве вывода, хотя для считывания переключателя необходимо настроить его как ввод. И если вы хотите использовать подтягивающий резистор (в отличие от подтягивающего резистора), вы можете активировать внутреннюю подтяжку на том же шаге:... for (int j = 0; j < stepsPerRevolution; j++) { if(!digitalRead(Lim1)){ while(true); } // These four lines result in 1 revolution: digitalWrite(stepPin1, HIGH); digitalWrite(stepPin2, HIGH); delayMicroseconds(250); digitalWrite(stepPin1, LOW); digitalWrite(stepPin2, LOW); delayMicroseconds(250); }
При чтении концевого выключателя внутри внешнего цикла
for
вы пишетеpinMode(Lim1, INPUT_PULLUP);
Вы выполняете сравнение на равенство между
OFF
и номером контакта, а не междуOFF
и возвращаемым значениемdigitalRead()
. Здесь нужно правильно расставить скобки:if (digitalRead(Lim1 == OFF)){}
Выше я использовал эквивалентную форму
if(digitalRead(Lim1) == OFF){}
с оператором отрицания
!
Помимо того, что вам не хватает Serial.begin()
со скоростью передачи данных, которую вы хотите использовать, в setup()
.
Спасибо за ваш ответ, я действительно новичок и полностью запутался., @303jw1095
// Определяем подключения шагового двигателя и количество шагов на оборот:
#define dirPin1 5
#define stepPin1 2
#define dirPin2 6
#define stepPin2 3
#define stepsPerRevolution 200 // Нам может понадобиться изменить 200 на 1600 на
get more precise control, i.e. decimals verse integers'
#define limPin1 8
#define CW 0x1
#define CCW 0x0
int remainder = 0;
long travel = 0;
long revolutions = 0;
bool homed = false;
void setup() {
// Объявить выводы выводом:
pinMode(stepPin1, OUTPUT);
pinMode(dirPin1, OUTPUT);
pinMode(stepPin2, OUTPUT);
pinMode(dirPin2, OUTPUT);
pinMode(limPin1, INPUT_PULLUP);
//Желаемое направление!!!! ставь сюда!!!! переместить кубик (против часовой стрелки) = 1, назад
out(cw) = 0 !!!!
//направление = 0; не сработало, нужно логическое значение?
// Устанавливаем направление вращения против часовой стрелки (умираем) или по часовой стрелке
(die out):
//if(direction = 1) digitalWrite(dirPin, HIGH);
//if(direction = 0) digitalWrite(dirPin, LOW);
//устанавливаем направление вручную, раскомментируем HIGH для затвердевания, LOW для затухания
out
digitalWrite(dirPin1, LOW);
digitalWrite(dirPin2, LOW);
//попытка вывести сохраненное значение на ПК для целей отладки
Serial.begin(9600);
Serial.println("test");
}
// основная процедура
void loop() {
Homing();
}
void Homing() {
// Быстро вращаем шаговый двигатель X оборотов, скорость (задержка)
apparently limited by voltage. 42v should go faster?
//Требуется вложенный цикл, потому что целые числа в UNO ограничены
~32k
if (homed == false)
{
// вычисление количества оборотов на основе введенных мм. еще не
account for partial revs - variable is truncated, integers are
default.
Would need another loop to handle the remainder
// Константа 6,659 (микрон) основана на 1,25 мм приводном винте
pitch,
and ratio in gearbox
float travel = 2.0;
float revolutions = 1000.00*travel/6.659;
int totalStepsOut = revolutions * stepsPerRevolution;
Serial.print("revolutions = ");
Serial.println(revolutions,4);
digitalWrite(dirPin1, CCW);
digitalWrite(dirPin2, CCW);
for (int j = 0; j < totalStepsOut; j++) {
bool limState = digitalRead(limPin1);
if (limState == false)
{
// Лимит срабатывает
HomingReturn();
break;
}
else
{
//Лимит не срабатывает
// Эти шесть строк приводят к 1 обороту:
digitalWrite(stepPin1, HIGH);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin1, LOW);
digitalWrite(stepPin2, LOW);
delayMicroseconds(250);
}
}
}
// Добавьте сюда вещи, чтобы делать все, что вы хотите, после возвращения домой
Serial.println("Homed");
}
void HomingReturn()
{
//задаем направление для реверса
digitalWrite(dirPin1, CW);
digitalWrite(dirPin2, CW);
Serial.println("Reversing");
//Желаемое расстояние перемещения в мм !!!! ставь сюда!!!!
float travel = 0.1;
float revolutions = 1000.00*travel/6.659;
int totalStepsOut = revolutions * stepsPerRevolution;
for (int j = 0; j < totalStepsOut; j++) {
//веди машину обратно
digitalWrite(stepPin1, HIGH);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(250);
digitalWrite(stepPin1, LOW);
digitalWrite(stepPin2, LOW);
delayMicroseconds(250);
}
homed = true;
Serial.println("Done");
}
Как сейчас написано, ваш ответ неясен. Пожалуйста, [изменить], чтобы добавить дополнительные сведения, которые помогут другим понять, как это относится к заданному вопросу. Дополнительную информацию о том, как писать хорошие ответы, можно найти [в справочном центре](/help/how-to-answer)., @Community
- Как я могу использовать степпер для определенной степени?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Шаговый двигатель не поворачивается/не поворачивается против часовой стрелки
- Шаговый двигатель с концевыми выключателями
- Запустить два степпера одновременно
- Попытка понять постоянную скорость AccelStepper
- Шаговый двигатель - концевой выключатель положения
- Могу ли я запретить библиотеке Stepper удерживать двигатель?
// Эти четыре строки приводят к 1 обороту:
... это должно сказать// Эти шесть строк приводят к 1 шагу:
, @jsotola