Потенциометр линейного привода с обратной связью с Arduino

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

Примечание. Это руководство предполагает наличие предварительных знаний об основных электронных принципах, аппаратном и программном обеспечении Arduino. Если вы впервые используете Arduino, мы предлагаем изучить основы одного из многих замечательных руководств для начинающих, доступных через поиск в Google и на YouTube. Имейте в виду, что у нас нет ресурсов для оказания технической поддержки для пользовательских приложений, и мы не будем отлаживать, редактировать, предоставлять код или схемы соединений за пределами этих общедоступных руководств.

Компоненты

Проводка

Потенциометр линейного привода с обратной связью с Arduino

Обзор аппаратного и программного обеспечения для чтения позиции

Соберите схему, как указано выше, и загрузите приведенный ниже код. Вам нужно будет изменить строку 16 кода на вашу конкретную длину хода, в настоящее время она установлена ​​для 6-дюймового привода штока обратной связи.

Эта программа сначала выдвигает и полностью втягивает привод, чтобы найти минимальное и максимальное показание аналогового датчика от потенциометра (строки 27 и 28 кода). Это необходимо, потому что, несмотря на то, что диапазон показаний потенциометра составляет [0, 1023], на практике этот диапазон может быть уменьшен из-за передаточного числа внутри привода, не позволяющего потенциометру полностью вращаться до его предела.

После этой начальной последовательности калибровки привод будет непрерывно выдвигаться и втягиваться, выводя поток данных, отображающих текущую увеличенную длину линейного привода (в дюймах).

Код

https://gist.github.com/Will-Firgelli/8c78092ca850aa8a50ae36842b97150f
COPY
/* Firgelli Automations
 * Limited or no support: we do not have the resources for Arduino code support
 * 
 * Program enables momentary direction control of actuator using push button
 */
 
#include <elapsedMillis.h>
elapsedMillis timeElapsed;

int RPWM = 10;   
int LPWM = 11;
int sensorPin = A0;

int sensorVal;
int Speed=255;
float strokeLength = 6.0;                           //customize to your specific stroke length
float extensionLength;

int maxAnalogReading;
int minAnalogReading;

void setup() {
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(sensorPin, INPUT);
  Serial.begin(9600);
  maxAnalogReading = moveToLimit(1);
  minAnalogReading = moveToLimit(-1);
}

void loop(){
  Serial.println("Extending...");
  sensorVal = analogRead(sensorPin);
  while(sensorVal < maxAnalogReading){
    driveActuator(1, Speed);
    displayOutput();  
    delay(20);
  }
  driveActuator(0, Speed);
  delay(1000);
  
  Serial.println("Retracting...");
  sensorVal = analogRead(sensorPin);
  while(sensorVal > minAnalogReading){
    driveActuator(-1, Speed);
    displayOutput();  
    delay(20);
  }
  driveActuator(0, Speed);
  delay(1000);
}

int moveToLimit(int Direction){
  int prevReading=0;
  int currReading=0;
  do{
    prevReading = currReading;
    driveActuator(Direction, Speed);
    timeElapsed = 0;
    while(timeElapsed < 200){ delay(1);}           //keep moving until analog reading remains the same for 200ms
    currReading = analogRead(sensorPin);
  }while(prevReading != currReading);
  return currReading;
}

float mapfloat(float x, float inputMin, float inputMax, float outputMin, float outputMax){
 return (x-inputMin)*(outputMax - outputMin)/(inputMax - inputMin)+outputMin;
}

void displayOutput(){
  sensorVal = analogRead(sensorPin);
    extensionLength = mapfloat(sensorVal, float(minAnalogReading), float(maxAnalogReading), 0.0, strokeLength);
    Serial.print("Analog Reading: ");
    Serial.print(sensorVal);
    Serial.print("\tActuator extension length: ");
    Serial.print(extensionLength);
    Serial.println(" inches");  
}

void driveActuator(int Direction, int Speed){
  switch(Direction){
    case 1:       //extension
      analogWrite(RPWM, Speed);
      analogWrite(LPWM, 0);
      break;
   
    case 0:       //stopping
      analogWrite(RPWM, 0);
      analogWrite(LPWM, 0);
      break;

    case -1:      //retraction
      analogWrite(RPWM, 0);
      analogWrite(LPWM, Speed);
      break;
  }
}

Использование внешнего потенциометра для контроля положения

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

Проводка

Линейный привод с Arduino

Обзор аппаратного и программного обеспечения для управления положением

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

Программа, представленная ниже, перемещается в положение, установленное пользователем с помощью внешнего потенциометра. В строке 18 кода задается буферная переменная, которая используется позже в строках 36 и 39. Возможный буфер дает диапазон вокруг желаемого заданного положения, в котором привод остановится, это требуется, поскольку два потенциометра имеют склонность к флатату на +/- 2 единицы. Таким образом, если бы буфер не был включен, приводы будут сильно вибрировать вокруг заданного положения. Чтобы увидеть это в действии, установите буфер в строке 18 на ноль (не позволяйте исполнительным механизмам долго вибрировать, так как это может привести к повреждению).

Код

https://gist.github.com/Will-Firgelli/41ec87433f0aaa1abc33e79168076b3b
COPY
/* Firgelli Automations
 * Limited or no support: we do not have the resources for Arduino code support
 * 
 * Program enables momentary direction control of actuator using push button
 */
 
#include <elapsedMillis.h>
elapsedMillis timeElapsed;

int RPWM = 10;   
int LPWM = 11;
int sensorPin = A0;
int potPin = A1;
int potVal;

int sensorVal;
int Speed = 255;
int Buffer = 4;

int maxAnalogReading;
int minAnalogReading;

void setup() {
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(sensorPin, INPUT);
  pinMode(potPin, INPUT);
  Serial.begin(9600);
  maxAnalogReading = moveToLimit(1);
  minAnalogReading = moveToLimit(-1);
}

void loop(){
  potVal = map(analogRead(potPin), 0, 1023, minAnalogReading, maxAnalogReading);
  sensorVal = analogRead(sensorPin);
  if(potVal > (sensorVal+Buffer)){               //addition gives buffer to prevent actuator from rapidly vibrating due to noisy data inputs
    driveActuator(1, Speed);
  }
  else if(potVal < (sensorVal-Buffer)){             
    driveActuator(-1, Speed);
  }
  else{
    driveActuator(0, Speed);
  }
  Serial.print("Potentiometer Reading: ");
  Serial.print(potVal);
  Serial.print("\tActuator reading: ");
  Serial.println(sensorVal);
  delay(10);
}

int moveToLimit(int Direction){
  int prevReading=0;
  int currReading=0;
  do{
    prevReading = currReading;
    driveActuator(Direction, Speed);
    timeElapsed = 0;
    while(timeElapsed < 200){ delay(1);}           //keep moving until analog reading remains the same for 200ms
    currReading = analogRead(sensorPin);
  }while(prevReading != currReading);
  return currReading;
}

void driveActuator(int Direction, int Speed){
  switch(Direction){
    case 1:       //extension
      analogWrite(RPWM, Speed);
      analogWrite(LPWM, 0);
      break;
   
    case 0:       //stopping
      analogWrite(RPWM, 0);
      analogWrite(LPWM, 0);
      break;

    case -1:      //retraction
      analogWrite(RPWM, 0);
      analogWrite(LPWM, Speed);
      break;
  }
}

Share This Article
Tags: