Czasami, tworząc projekt z użyciem siłownika liniowego, próbujemy rozwiązać problem, którego nie dałoby się rozwiązać bez zalet, jakie dają te mechanizmy. Innym razem chcemy po prostu ułatwić sobie zadanie, automatyzując je. A od czasu do czasu tworzymy coś tylko dlatego, że możemy. To jeden z takich projektów.
W tym artykule wyjaśnimy, jak wykorzystać czujnik ultradźwiękowy do pomiaru odległości do obiektu i na tej podstawie automatycznie zmieniać pozycję skoku siłownika. Choć nie powstało to z myślą o konkretnej aplikacji, możliwości są praktycznie nieograniczone.
Czego będziesz potrzebować
- 1 x RobotPower MegaMoto Motor Driver Shield
- 1 x Arduino Uno
- 1 x Ultra-Sonic Sensor
- 1 x PA-04-12-400-HS-24VDC (może to być dowolny siłownik ze sprzężeniem zwrotnym z czujnika Halla)
- 1 x PS-20-24 (lub dowolny zasilacz 24 VDC o wydajności co najmniej 6 A)
Do sterowania używamy Arduino Uno z driverem silnika MegaMoto. Nasz siłownik to PA-04-12-400-HS-24VDC. Ważne, aby siłownik posiadał jakieś sprzężenie zwrotne, dzięki czemu Arduino może monitorować jego pozycję – sprawdzi się dowolny system sprzężenia zwrotnego w siłowniku liniowym; np. sprzężenie z potencjometru też byłoby tu skuteczne. Potencjometr będzie mniej dokładny, ale ma tę zaletę, że po zaniku zasilania nie wymaga przeprowadzania procedury bazowania (homing). Kod należałoby też odpowiednio zmodyfikować.
Krok 1: Okablowanie

Okablowanie w tym projekcie jest bardzo proste. Skorzystamy tylko z jednego z dwóch czujników Halla w PA-04-HS – nie ma znaczenia którego (pin 4 lub 5). Rozkład pinów poniżej dotyczy 6-pinowego złącza Molex dołączonego do PA-04-HS:

6-pinowe złącze siłownika do Arduino/MegaMoto
- Pin 3 do 5V
- Pin 2 do GND
- Pin 1 do pinu 2 w Arduino
- Pin 4 do A w MegaMoto
- Pin 5 do B w MegaMoto
Czujnik ultradźwiękowy do Arduino/MegaMoto
- VCC do 5V
- GND do GND
- Trig do pinu 8
- Echo do pinu 7
MegaMoto do zasilacza
- + do V+
- - do V-
Krok 2: Programowanie Arduino
Kod użyty w tym poradniku to zmodyfikowana wersja tego, którego użyliśmy w innym wpisie, Hall Effect Sensors 1: Position Control. Zachęcamy do zapoznania się z tym tutorialem, aby lepiej zrozumieć, jak wykorzystujemy czujnik Halla do kontroli położenia! Czujnik ultradźwiękowy działa tak, że wysyła impuls ultradźwiękowy wyzwalany przez jeden z pinów GPIO Arduino. Impuls odbija się od obiektu i jest wykrywany przez odbiornik. Gdy odbiornik wykryje impuls, wysyła sygnał do Arduino. Na tej podstawie możemy obliczyć odległość, mierząc czas między nadaniem a odbiorem, a następnie przeliczyć ten pomiar na cale.
Położenie siłownika wyznaczamy, zliczając liczbę impulsów generowanych przez czujnik Halla (dokładniej opisaliśmy to w przywołanym wyżej wpisie). Pozycję skoku w calach możemy określić, znając liczbę impulsów na cal generowanych przez dany siłownik i dzieląc nasz licznik impulsów przez tę wartość. Gdy zarówno odczyt z czujnika ultradźwiękowego, jak i z czujnika Halla są przeliczone na cale, kod staje się dużo czytelniejszy i prostszy. Od tego momentu zasadniczo mówimy Arduino: „jeśli obiekt jest w odległości x cali, wysuń siłownik o x cali”. Wgranie poniższego kodu pozwoli wdrożyć model sterowania położeniem siłownika na podstawie odległości dla naszych siłowników PA-04-12-400-HS-24VDC. W kolejnym kroku omówimy możliwe modyfikacje kodu.
[code]
/* The purpose of this code it to be able to measure the distance of an object and position the stroke of a linear acuator accordingly.
* The required components are an Arduion Uno, a PobotPower MegaMoto Driver, and an Ultra sonic sensor.
* Written by Progressive Automations 2/02/21
*/
#define PWMA0 6
#define PWMB0 5
#define enable0 13 //pins for MegaMoto
#define hall0 2 //interrupt pins for hall effect sensors
#define echoPin 7 //echo pin on ultra sonic sensor
#define trigPin 8 //output on ultra sonic sensor
float duration, distance;
int enable = 0; //enable pin for megaMoto
int count[] = {0};
int currentPos = 0;//current position
int threshold = 100;//position tolerance
int destination = 0;
bool forwards = false;
bool backwards = false;// motor states
void setup() {
pinMode(PWMA0, OUTPUT);
pinMode(PWMB0, OUTPUT);//set PWM outputs
pinMode(enable0, OUTPUT);
digitalWrite(enable0, LOW);//set enable and turn board OFF
pinMode(hall0, INPUT);
digitalWrite(hall0, LOW);//set hall, set low to start for rising edge
attachInterrupt(0, speed0, RISING); //enable the hall effect interupts
pinMode(trigPin,OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
//homeActuator();//fully retracts actuator
Serial.println("READY");
}//end setup
void loop() {
getDistance();//measure distance of object from ultra sonic sensor
currentPos = count[0];
if(distance < 13) //ignore value if greater than stroke length
{
destination = distance * 275; //translate measured distance (in inches) to desired stroke position (in pulses)
}
if ((destination >= (currentPos - threshold)) && (destination <= (currentPos + threshold))) stopMoving();//stop acuator if it is in the desired position
else if (destination > currentPos) goForwards();
else if (destination < currentPos) goBackwards();
Serial.print("Counts: "); Serial.println(count[0]);
Serial.print("currentPos: "); Serial.println(currentPos);
Serial.print("Destination: "); Serial.println(destination);
}//end loop
void speed0() {
//Serial.println("Update 1");
if (forwards == true) count[0]++; //if moving forwards, add counts
else if (backwards == true) count[0]--; //if moving back, subtract counts
}//end speed0
/*void ReadInputs() {
sw[0] = digitalRead(switch0), sw[1] = digitalRead(switch1);//check switches
currentPos = count[0];
}//end read inputs
*/
void goForwards()
{
forwards = true;
backwards = false;
//Serial.println("Moving forwards");
digitalWrite(enable0, HIGH);//enable board
//Serial.print(" Speeds "), Serial.print(spd[0]), Serial.print(", "), Serial.print(spd[1]);
//Serial.print(" Counts "), Serial.println(count[0]);
analogWrite(PWMA0, 255);
analogWrite(PWMB0, 0);//apply speeds
}//end goForwards
void goBackwards()
{
forwards = false;
backwards = true;
//Serial.println("Moving backwards");
digitalWrite(enable0, HIGH);//enable board
//Serial.print(" Speeds "), Serial.print(spd[0]), Serial.print(", "), Serial.print(spd[1]);
//Serial.print(" Counts "), Serial.println(count[0]);
analogWrite(PWMA0, 0);
analogWrite(PWMB0, 255);//apply speeds
}//end goBackwards
void stopMoving()
{
forwards = false;
backwards = false;
Serial.println("Stopped");
analogWrite(PWMA0, 0);
analogWrite(PWMB0, 0);//set speeds to 0
delay(10);
digitalWrite(enable0, LOW);//disable board
}//end stopMoving
void getDistance()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(10);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration/58.2/2.5;
Serial.print("Distance:"); Serial.println(distance);
}
void homeActuator() //fully retract actuator and set count to 0
{
goBackwards();
delay(25000);//change this value to the amount of time it takes for the actuator to fully retract
count[0] = {0};
}
[/code]
Krok 3: Modyfikowanie kodu
Wartość threshold określa, jak dokładnie pozycja siłownika powinna odpowiadać odczytowi z czujnika ultradźwiękowego. Zwiększenie jej zmniejszy dokładność, a zmniejszenie – odwrotnie. Ustawiając tę wartość na 100, w praktyce mówimy Arduino, by nie poruszało siłownikiem, o ile impulsy z czujnika Halla i czujnika ultradźwiękowego są w odległości do 100 impulsów względem siebie. Zbyt niska wartość może sprawić, że siłownik będzie poruszał się szarpanie, próbując osiągnąć idealną pozycję.

Zmień tę wartość na długość skoku Twojego siłownika (lub o cal większą). Dzięki temu Arduino będzie ignorowało wartości zbyt wysokie.

Zmień tę wartość na liczbę impulsów na cal dla Twojego siłownika.

Podsumowanie
Mamy szczerą nadzieję, że ten projekt okaże się dla Ciebie przydatny – lub przynajmniej ciekawy! Śmiało modyfikuj go i dostosuj do swoich potrzeb. Jak zawsze, chętnie zobaczymy wszelkie powiązane projekty – niezależnie od tego, czy wykorzystasz ten pomysł, czy stworzysz coś innego z użyciem naszych produktów! Możesz skontaktować się z nami e‑mailem pod adresem sales@progressiveautomations.com oraz telefonicznie pod numerem 1-800-676-6123.