Skocz do zawartości

Pomysły na pomiar pozycji silnika liniowego w celu obliczania prędkości


Kamro

Pomocna odpowiedź

Witam serdecznie.

Buduję aktualnie silnik liniowy z mikrokontrolerem STM32L476RG, który składa się z dwóch części:

- szyny (część nieruchoma) na której naklejone są magnesy neodymowe naprzemiennie biegunami o wymiarach 30x15x1 mm. Długość szyny to 2m.

-wózka (część ruchoma), który jest wyposażony w dwa elektromagnesy i poruszą się na czterech kółkach zrobionych z łożysk typu V, które są ustawione na szynie.

Wózek jest wyposażony w analogowe czujniki Halla, które służą zarówno do pomiaru natężenia pola szyny jak i do określania sterowania elektromagnesami. Znajdują się odpowiednio w odległości 10, 20 oraz 45 mm od początku wózka (zakładamy, że początek wózka jest idealnie w tym samym miejscu co początek magnesu szyny). 

I tutaj mam pytanie do Państwa o sposoby pomiaru pozycji wózka względem szyny. Aktualnie mam dwa rozwiązania:

1. Enkoder z Halli.

Poprzez wykrywanie przejść przez 0 czujników jestem w stanie określać zmianę pozycji wózka o 15mm. Wynika to z takiego, a nie innego ułożenia czujników na wózku. Dodatkowo zaimplementowałem algorytm wykrywający zmianę kierunku poruszania się wózka. Niestety z powodu niedoskonałości szyny czasem algorytm źle wykrywa przejście przez 0 i głupieje zmieniając niepotrzebnie pozycję. Udało mi się to w większości przypadków wyeliminować poprzez dodanie histerezy, gdy dany czujnik już raz przejdzie przez 0. Niestety jednak nie bardzo wychodzi mi w tym rozwiązaniu obliczanie prędkości. Próbowałem do tego wykorzystać timer i robić to różniczkowaniem numerycznym, jednak jakość estymacji nie powala. Poniżej kod. Dodam że korzystam z DMA na ADC, zmienne x_calculated oraz vel_calculatedsą globalne.

Pozycja:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
	if (hadc->Instance == ADC3)
	{
		static int32_t HALL_LEFT_PREV = 0, HALL_RIGHT_PREV = 0;
		static int8_t direction = 1, zero_crossing_first = 0, enable_left = 1, enable_right = 1;
		int32_t HALL_LEFT, HALL_RIGHT;
		const int32_t treshold = 250;
		HALL_LEFT = ADC_HALL[0] - ADC_OFFSET_HALL0;
		HALL_RIGHT = ADC_HALL[2] - ADC_OFFSET_HALL2;
		if ((HALL_LEFT < 0 && HALL_LEFT_PREV > 0) || (HALL_LEFT > 0 && HALL_LEFT_PREV < 0) || (HALL_RIGHT < 0 && HALL_RIGHT_PREV > 0) || (HALL_RIGHT > 0 && HALL_RIGHT_PREV < 0))
		{
			if (((HALL_LEFT < 0 && HALL_LEFT_PREV > 0) || (HALL_LEFT > 0 && HALL_LEFT_PREV < 0)) && enable_left)
			{
				if (zero_crossing_first == 1)
				{
					direction = -direction;
					enable_left = 0;
				}
				zero_crossing_first = 1;

			}
			if (((HALL_RIGHT < 0 && HALL_RIGHT_PREV > 0) || (HALL_RIGHT > 0 && HALL_RIGHT_PREV < 0)) && enable_right)
			{
				if (zero_crossing_first == 2)
				{
					direction = -direction;
					enable_right = 0;
				}
				zero_crossing_first = 2;
			}

			x_calculated += 15 * direction;
		}
		if (!enable_right)
		{
			if (HALL_RIGHT > treshold || HALL_RIGHT < -treshold)
			{
				enable_right = 1;
			}
		}
		if (!enable_left)
		{
			if (HALL_LEFT > treshold || HALL_LEFT < -treshold)
			{
				enable_left = 1;
			}
		}

		HALL_LEFT_PREV = HALL_LEFT;
		HALL_RIGHT_PREV = HALL_RIGHT;
	}
}
/*

Prędkość:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
	if (htim->Instance == TIM7)
	{
		static int32_t prev_x = 0;
		vel_calculated = (x_calculated - prev_x) * 10;
		prev_x = x_calculated;

	}
}

2. Czujnik odległości HC-SR04

Inny pomysłem zrealizowanym było użycie czujnika ultradźwiękowego. Co prawda czujnik działa zadowalająco, gdy nie ma dodatkowych przeszkód wokół szyny, jednak do poprawnego działania wymagał ode mnie użycia zarówno filtru medianowego jak i dolnoprzepustowego w programie. Z tego względu pomiary są opóźnione i implementacja regulatora prędkości nie działa za bardzo poprawnie. Poniżej kod (wykonywany w pętli głównej z użyciem timera software'owego). Ilość próbek dla filtru medianowego to 21, a alfa dolnoprzepustowego wynosi 0,01.

		if ((HAL_GetTick() - TimerUCSample) > UC_SAMPLE_PERIOD)
		{

			start1 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
			stop1 = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_2);
			uint16_t input1 = FilterMedianUpdate(&filter_median, (stop1 - start1));
			x = FilterLowPassUpdate(&lpf, input1) * sonic_speed;
			velocity = abs(FilterLowPassUpdate(&lpf, (x - x_prev) / (0.001 * UC_SAMPLE_PERIOD)));
			x_prev = x;
			TimerUCSample = HAL_GetTick();
		}

 3. Enkoder inkrementalny

Była również próba użycia enkodera inkrementalnego, do którego za pomocą paska byłby przyczepiony wózek. Jednak pomysł ten został odrzucony ze względu na dodatkowego siły oporu działające na wózek, które (ze względu na słabe elektromagnesy) powstrzymywały wózek od jakiejkolwiek jazdy.

 

Do silnika chciałbym użyć regulatora prędkości, by poruszał się z zadaną prędkością. Jednak ze względu na niezbyt dobre pomiary pozycji jak i prędkości nie bardzo jestem w stanie to zadanie zrealizować.

 

Będę bardzo wdzięczny za wszelkie rady, pomysły jak i uwagi.

Pozdrawiam

Link do komentarza
Share on other sites

Enkoder magnetyczny albo foto nie wprowadza żadnych dodatkowych mechanicznych oporów.

Zamiast ultradżwięku możesz użyć ToF.

Istnieją silniki krokowe.

 

 

Edytowano przez ethanak
Link do komentarza
Share on other sites

Pomiędzy czujnikami halla zamontować mikropaski z czujnikiem optycznym. Lub użyć do tego celu kodu graya. Coś na wzór jak działa suwmiarka elektroniczna. Czujnik ultradźwiękowy to nietrafiony pomysł gdyż prędkość rozchodzenia fali zależy od wielu czynników temperatura, wilgotność zanieczyszczenie pyłami. Czujnik ToF jest podatny na zanieczyszczenia optyki. 

https://youtu.be/LB3j4dgQaBE?si=udGPwoDa6iCQPJbr

Edytowano przez _LM_
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Pomyślałem o takich jak się w drukarkach stosuje, bądź stosowało. Była to folia z napylonymi paskami, działało to jak przysłona na czujnik optyczny. W ten sposób kontroler mógł na podstawie zaliczonych impulsów oszacować miejsce położenia karetki. Czyli w istocie był to prost enkoder 

Edytowano przez _LM_
Link do komentarza
Share on other sites

Hmm, nie bardzo jestem w stanie sobie to wyobrazić. Bo na ten moment widzę to tak, że ten pasek musiał by się ciągnąć przez całą szynę i wtedy ten czujnik szczelinowy by był na wózku. Chyba, że @_LM_ widzisz to jakoś inaczej to chętnie posłucham 🙂 

Link do komentarza
Share on other sites

9 godzin temu, _LM_ napisał:

Pomyślałem o takich jak się w drukarkach stosuje, bądź stosowało. Była to folia z napylonymi paskami, działało to jak przysłona na czujnik optyczny. W ten sposób kontroler mógł na podstawie zaliczonych impulsów oszacować miejsce położenia karetki. Czyli w istocie był to prost enkoder 

Podobne stosuje się w liniałach optycznych do maszyn "ręcznych"/manualnych (tokarek, frezarek) 😉 

Edytowano przez H1M4W4R1
  • Lubię! 1
Link do komentarza
Share on other sites

Myślę że @H1M4W4R1 podał eleganckie rozwiązanie, są gotowe liniały optyczne, masz punkt odniesienia. Fakt że 2kzł za 2000mm liniału może wydawać się dużo. No to jeszcze garść informacji w temacie https://www.ebmia.pl/wiedza/porady/automatyka-porady/linial-magnetyczny/ 

https://www.ebmia.pl/linialy/9618-tasma-magnetyczna-mt25-xx-50-1-dokladnosc-35um-m.html 187zł za metr to nie jest tragedia 

Edytowano przez _LM_
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.