Концевые упоры для шагового двигателя

Мне нужно добавить несколько конечных остановок к этому коду шагового двигателя. Я использую одну ось джойстика для управления кареткой, которая вращается взад и вперед на длинном винте. У меня есть переключатели холла на обоих концах, я просто хочу, чтобы он перестал двигаться в этом направлении, когда сработает выключатель.

Я не писал этот код, но он отлично работал бы, если бы я мог просто добавить конечные остановки. Если у меня есть переключатели, подключенные к контактам 2 и 3.

Как я мог бы написать что-то вроде: если вывод 2 идет высоко, остановите двигатель в этом направлении, а затем то же самое для вывода 3 в противоположном направлении?

#include <AccelStepper.h> // accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)

//Pins
const byte Analog_X_pin = A0; // x-axis readings
const byte enablePin = 7;

//Variables
int Analog_X = 0;             //x-axis value
int Analog_X_AVG = 0;         //x-axis value average
  //---------------------------------------------------------------------------- 
void setup() {
  Serial.begin(9600);
  //----------------------------------------------------------------------------    
  //PINS
  pinMode(Analog_X_pin, INPUT);
  pinMode(enablePin, OUTPUT);
  //----------------------------------------------------------------------------  
  InitialValues(); // averaging the values of the 3 analog pins (values from potmeters)
  //----------------------------------------------------------------------------  
  // Stepper parameters
  // setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000);     //SPEED = Steps / second  
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2    
  stepper.setSpeed(1000);
  delay(1000);
}

void loop() {
  ReadAnalog();  
  stepper.runSpeed(); // step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadAnalog() {
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    digitalWrite(enablePin, HIGH);  // enable the driver
    stepper.setSpeed(5*(Analog_X-Analog_X_AVG));   
  } else {
    digitalWrite(enablePin, LOW);   // disable the driver
    stepper.setSpeed(0);
  }
  // Reading the potentiometer in the joystick: 
  Analog_X = analogRead(Analog_X_pin);  
  // if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
  // This is a sort of a filter for the inaccuracy of the reading
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    stepper.setSpeed(5 * (Analog_X-Analog_X_AVG));    
  } else {
    stepper.setSpeed(0);
  }
}

void InitialValues() {
  //Set the values to zero before averaging
  float tempX = 0;
  //----------------------------------------------------------------------------  
  // read the analog 50x, then calculate an average. 
  // they will be the reference values
  for (int i = 0; i<50; i++) {
    tempX += analogRead(Analog_X_pin);  
    delay(10); //allowing a little time between two readings
  }
  //----------------------------------------------------------------------------  
  Analog_X_AVG = tempX/50; 
  //----------------------------------------------------------------------------  
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");  
}

, 👍1


2 ответа


1

Вот что я придумал. Обратите внимание, что функция ReadLimits вызывается после ReadAnalog и перед runSpeed. В этом порядке шагомер не будет двигаться в направлении конечного выключателя, если он нажат.

PS поскольку вы использовали setAcceleration, не нужно ли вызывать run вместо runSpeed?

void loop()
{
  ReadAnalog();
  ReadLimits();  
  stepper.runSpeed(); //sшаг двигателя (это приведет к увеличению скорости двигателя на 1 шаг в каждом цикле на неопределенный срок)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//читывает входные данные, предполагая, что у них есть подтягивающие резисторы.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
}

отредактируйте, чтобы избежать некоторой путаницы; вот весь код со встроенным моим предложением:

#include <AccelStepper.h> // accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)

//Pins
const byte Analog_X_pin = A0; // x-axis readings
const byte enablePin = 7;

//Variables
int Analog_X = 0;             //x-axis value
int Analog_X_AVG = 0;         //x-axis value average
  //---------------------------------------------------------------------------- 
void setup() {
  Serial.begin(9600);
  //----------------------------------------------------------------------------    
  //PINS
  pinMode(Analog_X_pin, INPUT);
  pinMode(enablePin, OUTPUT);
  //----------------------------------------------------------------------------  
  InitialValues(); // averaging the values of the 3 analog pins (values from potmeters)
  //----------------------------------------------------------------------------  
  // Stepper parameters
  // setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000);     //SPEED = Steps / second  
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2    
  stepper.setSpeed(1000);
  delay(1000);
}

void loop()
{
  ReadAnalog();
  ReadLimits();  
  stepper.runSpeed(); //step the motor (this will step the motor by 1 step at each loop indefinitely)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )//read input, assuming they have pull-up resistors.
  {
    stepper.setSpeed(0);
  }
}

void ReadAnalog() {
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    digitalWrite(enablePin, HIGH);  // enable the driver
    stepper.setSpeed(5*(Analog_X-Analog_X_AVG));   
  } else {
    digitalWrite(enablePin, LOW);   // disable the driver
    stepper.setSpeed(0);
  }
  // Reading the potentiometer in the joystick: 
  Analog_X = analogRead(Analog_X_pin);  
  // if the value is 25 "value away" from the average (midpoint), we allow the update of the speed
  // This is a sort of a filter for the inaccuracy of the reading
  if (abs(Analog_X-Analog_X_AVG) > 50) {
    stepper.setSpeed(5 * (Analog_X-Analog_X_AVG));    
  } else {
    stepper.setSpeed(0);
  }
}

void InitialValues() {
  //Set the values to zero before averaging
  float tempX = 0;
  //----------------------------------------------------------------------------  
  // read the analog 50x, then calculate an average. 
  // they will be the reference values
  for (int i = 0; i<50; i++) {
    tempX += analogRead(Analog_X_pin);  
    delay(10); //allowing a little time between two readings
  }
  //----------------------------------------------------------------------------  
  Analog_X_AVG = tempX/50; 
  //----------------------------------------------------------------------------  
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");  
}
,

Спасибо за ответ, я попробовал то, что вы отправили, если я прикоснусь к контакту 2 или 3 gnd. или 5 В, все равно ничего не произойдет, двигатель не остановится ни в том, ни в другом направлении. Я не очень разбираюсь в кодировании, я попытался нанять кого-нибудь для этого, и после 2 дней устранения неполадок и пересмотра кода он все еще не работает. Код работает идеально, за исключением того, что я не могу добавить конечные точки. Любая помощь будет очень признательна., @edrummer

Вы добавили подтягивающие резисторы или использовали " pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP)"?, @Gerben

Почему вы добавили "ReadAnalog(); stepper.runSpeed ()" в конце предоставленной мной функции ReadLimits?, @Gerben

См. Мое **правка** выше., @Gerben

Я думаю, что это все, если у меня есть контакты 2 и 4, подключенные к 5 В, он работает нормально, когда я вместо этого подключаю соединительный провод к gnd или + он останавливает двигатель в этом направлении. Прости меня, я действительно не знаю, что я делаю, когда дело доходит до этого. Итак, у меня есть переключатели Холла для остановок, включаю ли я pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); или мне нужны подтягивающие резисторы? если да, то какую ценность, пожалуйста? Я очень благодарен вам за помощь, может быть, теперь я смогу закончить это., @edrummer

Понял, добавленные входные подтягивания отлично работают,, @edrummer

Это зависит от датчиков эффекта Холла. Некоторым требуется подтягивающий резистор. `INPUT_PULLUP " включает подтягивающий резистор, который находится внутри чипа Arduino. Нет никакой разницы между включением этого подтягивающего резистора в программном обеспечении или наличием физического (35 Ком) подтягивающего резистора на выводе. Значение резистора в данном случае на самом деле не имеет значения., @Gerben


-1

Вот что я попытался сделать:

#include <AccelStepper.h> //accelstepper library
AccelStepper stepper(1, 8, 9); // direction Digital 9 (CCW), pulses Digital 8 (CLK)
//Pins
 const byte Analog_X_pin = A0; //x-axis readings
 const byte enablePin = 7;
 const byte leftSwitch = 2;
 const byte rightSwitch = 3; 
//Variables
 int Analog_X = 0; //x-axis value
 int Analog_X_AVG = 0; //x-axis value average

void setup()
{
 
  //SERIAL
  Serial.begin(9600);
  //----------------------------------------------------------------------------    
  //PINS
  pinMode(Analog_X_pin, INPUT);
  pinMode(enablePin, OUTPUT);
  //----------------------------------------------------------------------------  
  InitialValues(); //усреднение значений 3 аналоговых выводов (значения из счетчиков)
  //----------------------------------------------------------------------------  
  //Параметры шага
  //настройка некоторых значений по умолчанию для максимальной скорости и максимального ускорения
  stepper.setMaxSpeed(2000); //СКОРОСТЬ = Шаги / секунды
  stepper.setAcceleration(1000); //УСКОРЕНИЕ = Шаги /(секунда)^2
  stepper.setSpeed(1000);
  delay(1000);
}
void loop()
{
  ReadAnalog();
  ReadLimits();  
  stepper.runSpeed(); //шаг двигателя (это приведет к шагу двигателя на 1 шаг в каждом цикле бесконечно)
}

void ReadLimits()
{
  if( digitalRead(2)==LOW && stepper.speed()>0 )//считывающий вход, предполагая, что у них есть подтягивающие резисторы.
  {
    stepper.setSpeed(0);
  }

  if( digitalRead(3)==LOW && stepper.speed()<0 )
  {
    stepper.setSpeed(0);
  }
  
  ReadAnalog();  
  stepper.runSpeed(); //шаг двигателя (это приведет к шагу двигателя на 1 шаг в каждом цикле бесконечно)
}
void ReadAnalog()
{
  if(abs(Analog_X-Analog_X_AVG)>50)
  {
      digitalWrite(enablePin, HIGH);  // enable the driver
      stepper.setSpeed(5*(Analog_X-Analog_X_AVG));   
  }
  else
  {
      digitalWrite(enablePin, LOW);   // disable the driver
      stepper.setSpeed(0);
  }
  //Считывание потенциометра в джойстике: 
  Analog_X = analogRead(Analog_X_pin);  
  //если значение равно 25 "значению, удаленному" от среднего (середины), мы разрешаем обновление скорости
  //This is a sort of a filter for the inaccuracy of the reading
  if(abs(Analog_X-Analog_X_AVG)>50) 
  {
  stepper.setSpeed(5*(Analog_X-Analog_X_AVG));    
  }
  else
  {
    stepper.setSpeed(0);
  }
}
void InitialValues()
{
  //Установите значения равными нулю перед усреднением
  float tempX = 0;
  //----------------------------------------------------------------------------  
  //прочитайте аналоговое значение 50x, затем вычислите среднее значение. 
  //они будут опорными значениями
  for(int i = 0; i<50; i++)
  {
    tempX += analogRead(Analog_X_pin);  
    delay(10); //позволяет немного времени между двумя показаниями
  }
  //----------------------------------------------------------------------------  
  Analog_X_AVG = tempX/50; 
  //----------------------------------------------------------------------------  
  Serial.print("AVG_X: ");
  Serial.println(Analog_X_AVG);
  Serial.println("Calibration finished");  
}
,

**Вы хотите сказать, что это каким-то образом ответ** на ваш вопрос? Если это так, было бы неплохо прояснить это. Или это дополнительная информация, которая должна быть **[отредактирована в ваш вопрос](https://arduino.stackexchange.com/posts/80980/edit)**?, @timemage

Похоже, что функция ReadAnalog() в конце кода ReadLimits() отменит любую скорость набора(0), выполненную с помощью тестов ограничения., @Dave X