محرک خطی بازخورد پتانسیومتر با آردوینو

در این مثال ما نشان خواهیم داد که چگونه با استفاده از Arduino سیگنال Firgelli's Feedback Rod Actuator را بخوانید و آن را به اندازه گیری فاصله تا چه اندازه میله گسترش داده شده تبدیل کنید. این آموزش بر اساس مبانی بحث شده در آموزش "کنترل سرعت موتور درایور با آردوینو"، توصیه می کنیم قبل از ادامه ، آن آموزش را مرور کنید.

توجه: این آموزش دانش قبلی را با اصول اولیه الکترونیکی ، سخت افزار و نرم افزار آردوینو در نظر گرفته است. اگر اولین بار است که از Arduino استفاده می کنید ، پیشنهاد می کنیم اصول را از یکی از بسیاری از آموزش های عالی مبتدی برای جستجو در Google و YouTube بیاموزید. لطفاً توجه داشته باشید که منابعی برای ارائه پشتیبانی فنی برای برنامه های سفارشی نداریم و خارج از این آموزشهای عمومی که موجود نیست ، اشکال زدایی ، ویرایش ، ارائه کد یا سیم کشی را انجام نمی دهیم.

اجزاء

سیم کشی

محرک خطی بازخورد پتانسیومتر با آردوینو

بررسی اجمالی سخت افزار و نرم افزار برای موقعیت خواندن

مدار را به صورت بالا جمع کرده و کد زیر را بارگذاری کنید. شما باید خط 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;
  }
}

استفاده از پتانسیومتر خارجی برای کنترل وضعیت

مثال بالا نشان داده است که چگونه می توان از عملکرد بازخورد میله خواند ، اما می گوید که ما می خواهیم محرک را به یک موقعیت خاص منتقل کنیم ، چگونه این کار را انجام دهیم؟ بخش زیر با استفاده از پتانسیومتر خارجی به عنوان ورودی کاربر برای موقعیت تنظیم شده مورد نظر محرک ، چنین وضعیتی را مرور می کند. در عمل می توانید این مثال را تغییر دهید تا ورودی کاربر را از هر شکلی که می خواهید بگیرید.

سیم کشی

محرک خطی با آردوینو

بررسی اجمالی سخت افزار و نرم افزار برای کنترل موقعیت

سیم کشی تقریباً مشابه قسمت اول این آموزش است ، فقط اکنون یک پتانسیومتر خارجی به پین ​​آنالوگ 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: