Photo of MegaMoto Plus H-bridge for Arduino Model: LC-80 by Progressive Automations

Część I: Jak monitorować sprzężenie zwrotne siłownika liniowego?

Anna Sapiga
Anna Sapiga
PA Engineer

W dzisiejszym poradniku pokażemy, jak sprawdzić, jaką siłę wywiera siłownik liniowy, monitorując pobierany przez niego prąd. To jeden z naszych bardziej zaawansowanych poradników, wymagający nieco złożonego kodowania, kalibracji i programowania. Omówimy monitorowanie wejścia analogowego i sposób wykorzystania jego funkcji. W tym projekcie użyjemy MegaMoto Plus, siłownika liniowego (korzystamy z naszego mini siłownika PA-14), Arduino Uno oraz zasilacza o napięciu co najmniej 12V.

Zdjęcie mini siłownika PA-14, Arduino Uno i zasilacza

Aby zacząć, musimy wykonać okablowanie, aby wszystko ze sobą połączyć. Zacznij od wpięcia MegaMoto do Arduino, po prostu umieść MegaMoto na górze Uno. Następnie podłącz przewód z terminala BAT+ znajdującego się na MegaMoto do pinu Vin na Uno.

Zdjęcie mostka H MegaMoto Plus dla Arduino Model: LC-80 firmy Progressive Automations


Teraz musimy podłączyć przewody siłownika liniowego do zacisków A i B na MegaMoto oraz podłączyć zasilanie 12V do BAT+ i GND do BAT-. Musimy też podłączyć dwa przyciski sterujące, łącząc każdy między niewykorzystanym pinem a GND. Zalecamy podłączyć przyciski na płytce stykowej.

Zdjęcie przewodów siłownika liniowego podłączonych do zacisków A i B na MegaMoto oraz zasilania 12V do BAT+ i GND do BAT-


Teraz czas na kodowanie z użyciem Arduino Uno. Chcemy zaprogramować przyciski tak, aby sterowały wysuwaniem i chowaniem siłownika. Monitorowanie prądu rozpocznie się, gdy siłownik zacznie się wysuwać, co pozwoli nam sprawdzić, czy przekracza on maksymalny limit prądu. Jeśli limit zostanie przekroczony, siłownik automatycznie się zatrzyma, dopóki nie zdecydujesz się go schować. Biorąc pod uwagę, że silniki w siłownikach mają duży skok prądu przy pierwszym zasileniu, wprowadzimy krótkie opóźnienie, zanim zaczniemy monitorować prąd. Ten kod potrafi również rozpoznać, kiedy siłownik osiągnął swoje wyłączniki krańcowe, czyli gdy prąd spada do 0.

const int EnablePin = 8;
const int PWMPinA = 11;
const int PWMPinB = 3; // pins for Megamoto
const int buttonLeft = 4;
const int buttonRight = 5;//buttons to move the motor
const int CPin1 = A5; // motor feedback

int leftlatch = LOW;
int rightlatch = LOW;//motor latches (used for code logic)
int hitLimits = 0;//start at 0
int hitLimitsmax = 10;//values to know if travel limits were reached
longlastfeedbacktime = 0; // must be long, else it overflows
int firstfeedbacktimedelay = 750; //first delay to ignore current spik
int feedbacktimedelay = 50; //delay between feedback cycles, how often you want the motor to be checked
currentTimefeedback = 0; // must be long, else it overflows unceTime = 300; //amount to debounce buttons, lower values makes the buttons more sensitivelong lastButtonpress = 0; // timer for debouncing
long currentTimedebounce = 0;
int CRaw = 0; // input value for current readings
int maxAmps = 0; // trip limit
bool dontExtend = false;
bool firstRun = true;
bool fullyRetracted = false;//program logic
void setup()
{
Serial.begin(9600);
pinMode(EnablePin, OUTPUT);
pinMode(PWMPinA, OUTPUT);
pinMode(PWMPinB, OUTPUT);//Set motor outputs
pinMode(buttonLeft, INPUT);
pinMode(buttonRight, INPUT);//buttons
digitalWrite(buttonLeft, HIGH);
digitalWrite(buttonRight, HIGH);//enable internal pullups
pinMode(CPin1, INPUT);//set feedback input
currentTimedebounce = millis();
currentTimefeedback = 0;//Set initial times
maxAmps = 15;// SET MAX CURRENT HERE
}//end setup
void loop()
{
latchButtons();//check buttons, see if we need to move
moveMotor();//check latches, move motor in or out
}//end main loop
void latchButtons()
{
if (digitalRead(buttonLeft)==LOW)//left is forwards
{
currentTimedebounce = millis() - lastButtonpress;// check time since last press
if (currentTimedebounce > debounceTime && dontExtend == false)//once you've tripped dontExtend, ignore all forwards presses
{
leftlatch = !leftlatch;// if motor is moving, stop, if stopped, start movingfirstRun = true;// set firstRun flag to ignore current spike
fullyRetracted = false; // once you move forwards, you are not fully retracted
lastButtonpress = millis();//store time of last button press
return;
}//end if
}//end btnLEFT
if (digitalRead(buttonRight)==LOW)//right is backwards
{
currentTimedebounce = millis() - lastButtonpress;// check time since last press
if (currentTimedebounce > debounceTime)
{
rightlatch = !rightlatch;// if motor is moving, stop, if stopped, start moving
firstRun = true;// set firstRun flag to ignore current spike
lastButtonpress = millis();//store time of last button press
return;
}//end if
}//end btnRIGHT
}//end latchButtons
void moveMotor()
{
if (leftlatch == HIGH) motorForward(255); //speed = 0-255
if (leftlatch == LOW) motorStop();
if (rightlatch == HIGH) motorBack(255); //speed = 0-255
if (rightlatch == LOW) motorStop();
}//end moveMotor
void motorForward(int speeed)
{
while (dontExtend == false && leftlatch == HIGH)
{
digitalWrite(EnablePin, HIGH);
analogWrite(PWMPinA, speeed);
analogWrite(PWMPinB, 0);//move motor
if (firstRun == true) delay(firstfeedbacktimedelay); // bigger delay to ignore current spike
else delay(feedbacktimedelay); //small delay to get to speed
getFeedback();
firstRun = false;
latchButtons();//check buttons again
}//end while
}//end motorForward

void motorBack (int speeed)
{
while (rightlatch == HIGH)
{
digitalWrite(EnablePin, HIGH);
analogWrite(PWMPinA, 0);
analogWrite(PWMPinB, speeed);//move motor
if (firstRun == true) delay(firstfeedbacktimedelay);// bigger delay to ignore current spike
else delay(feedbacktimedelay); //small delay to get to speed
getFeedback();
firstRun = false;
latchButtons();//check buttons again
}//end while
dontExtend = false;//allow motor to extend again, after it has been retracted
}//end motorBack
void motorStop()
{
analogWrite(PWMPinA, 0);
analogWrite(PWMPinB, 0);
digitalWrite(EnablePin, LOW);
firstRun = true;//once the motor has stopped, reenable firstRun to account for startup current spikes
}//end stopMotor

void getFeedback()
{
CRaw = analogRead(CPin1); // Read current
if (CRaw == 0 && hitLimits < hitLimitsmax) hitLimits = hitLimits + 1;
else hitLimits = 0; // check to see if the motor is at the limits and the current has stopped
if (hitLimits == hitLimitsmax && rightlatch == HIGH)
{
rightlatch = LOW; // stop motor
fullyRetracted = true;
}//end if
else if (hitLimits == hitLimitsmax && leftlatch == HIGH)
{
leftlatch = LOW;//stop motor
hitLimits = 0;
}//end if
if (CRaw > maxAmps)
{
dontExtend = true;
leftlatch = LOW; //stop if feedback is over maximum
}//end if
lastfeedbacktime = millis();//store previous time for receiving feedback
}//end getFeedback


Nowy i udoskonalony mini siłownik PA-01 (następca PA-14) to obecnie oferowany model z wieloma dodatkowymi korzyściami. Aby się przekonać, porównaj tabele poniżej i aktualizuj z pełnym spokojem!

 

PA-01

PA-14

Opcje obciążenia dynamicznego

16, 28, 56, 112, 169, 225 lbs

35, 50, 75, 110, 150 lbs

Maksymalne obciążenie

225 lbs

150 lbs

Najszybsza prędkość

3.54 "/sec

2.00"/sec

Klasa szczelności IP

IP65

IP54

Opcje skoku

1" to 40"

1" to 40"

Sprzężenie zwrotne efektu Halla

Optional

No

Dzięki temu podstawowemu kodowi z powodzeniem będziesz monitorować sprzężenie zwrotne swojego siłownika liniowego. W części II bardziej szczegółowo omówimy działanie kodu i sposób jego edycji. Mamy nadzieję, że ten wpis był pomocny – wypatruj części II w nadchodzących tygodniach. Jeśli chcesz zamówić któreś z użytych w przykładzie urządzeń lub chcesz dowiedzieć się więcej o naszych produktach, prosimy skontaktuj się z nami.