logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Szarpnięcia manipulatora 6DOF przy transmisji RS232 z PC - jak to naprawić?

Lukis 04 Kwi 2008 16:48 3927 10
REKLAMA
  • #1 4992788
    Lukis
    Poziom 11  
    Posty: 48
    Witam
    Przez ostatni czas zabrałem się za budowę manipulatora, konstrukcja powstała ze sklejki 3mm ciętej laserowo, do napędu użyłem serw, wiadomo łatwe sterowanie i duży udźwig. Jednostką sterującą jest procesor AT89S52, program napisany został w assemblerze. Głównym programem sterującym jest program na komputerze. Komunikacja odbywa się poprzez port szeregowy RS232. Szkielet programu napisany w C++, z dodatkami winAPI, grafika pisana w OpenGL. W programie mamy możliwość podglądu aktualnego położenia robota i kąta każdego z ramion, nagrywania i odtwarzania sekwencji z plików.
    Wszystko pięknie ładnie ale mam jeden problem, którego jak na razie nie udało mi sie wyeliminować a mianowicie jak włączam zasilanie robota to ustawia się do pozycji startowej i utrzymuje ją bez problemów, kiedy tylko włączam program na PC i otwiera sie port szeregowy i zaczyna sie transmisja danych to ramie zaczyna wykonywać szarpnięcia wynikające chyba z tego, że dochodzą błędne liczby bo po każdym szarpnięciu wraca do swojej pozycji. Próbowałem zmieniać prędkości transmisji i nic nie pomogło, wymieniłem tez kabel na podwójnie ekranowany mikrofonowy i dalej to samo.
    Poniżej kilka zdjęć manipulatora i filmik z działania.

    Szarpnięcia manipulatora 6DOF przy transmisji RS232 z PC - jak to naprawić?

    Szarpnięcia manipulatora 6DOF przy transmisji RS232 z PC - jak to naprawić?

    Szarpnięcia manipulatora 6DOF przy transmisji RS232 z PC - jak to naprawić?

    Szarpnięcia manipulatora 6DOF przy transmisji RS232 z PC - jak to naprawić?


    A tak wygląda główne okno programu:

    Szarpnięcia manipulatora 6DOF przy transmisji RS232 z PC - jak to naprawić?

    A oto filmik z działania manipulatora, na którym widać trzęsienie się robota po włączeniu programu.





    Zamieszczam również program który odbiera dane i steruje serwami:
    
    $MOD52
    $DEBUG(asm.aof)
    
    ;********************;
    ;PROGRAM             ;
    ;********************;
    
    org 00H
    	LJMP Init
    
    
    ;********************;
    ;WEKTORY PRZERWAŃ    ;
    ;********************;
    
    org 0BH
    	LJMP 	PRZERWANIE
    
    org 23H
    	LJMP	intRS232
    
    ;********************;
    ;INIT 		     ;
    ;USTAWIENIA RS232 I  ;
    ;LICZNIKOW	     ;
    ;********************;
    org 30H
    
    Init:
    	MOV	SCON,#01000000B		;TRYB 1,
    	ORL	TMOD,#00100001B		;T1, 8BIT, AUTOMATYCZNE PRZEŁADOWANIE
    					;T0, 16BIT
    	ORL	PCON,#80H		;SMOD = 1
    	MOV	TH1,#0FAH		;PREDKOŚĆ 9600
    	
    	SETB	TR1			;START LICZNIKA T1
    	SETB	ES			;START UART'u
    	SETB	ET0			;ODBLOKOWANIE T0
    	SETB	EA			;ODBLOKOWANIE GLOBALNYCH PRZERWAŃ
    	SETB	REN			;ODBLOKOWANIE ODBIORNIKA
    
    	LJMP	WARTOSCI
    org 50H
    
    ;********************;
    ;POCZĄTKOWE WARTOŚCI ;
    ;********************;
    WARTOSCI:
    	MOV	R0,#69H
    
    	MOV	69H,#154
    	MOV	68H,#104
    	MOV	67H,#49
    	MOV	66H,#221
    	MOV	65H,#154
    	MOV	64H,#154
    
    	LJMP	BUFOR
    	
    
    		
    ;********************;
    ;MAIN PĘTLA GŁÓWNA   ;
    ;********************;
    
    MAIN:
    	
    
    
    ;********************;
    ;OBSŁUGA SERVA1      ;
    ;********************;
    
    	CLR	TR0
    	MOV	A,#9H
    	MOV	B,59H
    	MUL	AB
    	XCH	A,R5
    	MOV	A,#0FFH
    	CLR	C
    	SUBB	A,R5
    	MOV	TL0,A
    	MOV	R5,B
    	MOV	A,#0FFH
    	SUBB	A,R5
    	MOV	TH0,A
    	
    	MOV	P2,#00000001B
    	SETB	TR0
    
    	JNB	TF0,$
    
    ;********************;
    ;OBSŁUGA SERVA2      ;
    ;********************;
    
    	CLR	TR0
    	MOV	A,#9H
    	MOV	B,58H
    	MUL	AB
    	XCH	A,R5
    	MOV	A,#0FFH
    	CLR	C
    	SUBB	A,R5
    	MOV	TL0,A
    	MOV	R5,B
    	MOV	A,#0FFH
    	SUBB	A,R5
    	MOV	TH0,A
    
    	MOV	P2,#00000010B
    	SETB	TR0
    
    	JNB	TF0,$
    
    ;********************;
    ;OBSŁUGA SERVA3      ;
    ;********************;
    
    	CLR	TR0
    	MOV	A,#9H
    	MOV	B,57H
    	MUL	AB
    	XCH	A,R5
    	MOV	A,#0FFH
    	CLR	C
    	SUBB	A,R5
    	MOV	TL0,A
    	MOV	R5,B
    	MOV	A,#0FFH
    	SUBB	A,R5
    	MOV	TH0,A
    
    	MOV	P2,#00000100B
    	SETB	TR0
    
    	JNB	TF0,$
    
    ;********************;
    ;OBSŁUGA SERVA4      ;
    ;********************;
    
    	CLR	TR0
    	MOV	A,#9H
    	MOV	B,56H
    	MUL	AB
    	XCH	A,R5
    	MOV	A,#0FFH
    	CLR	C
    	SUBB	A,R5
    	MOV	TL0,A
    	MOV	R5,B
    	MOV	A,#0FFH
    	SUBB	A,R5
    	MOV	TH0,A
    
    	MOV	P2,#00001000B
    	SETB	TR0
    
    	JNB	TF0,$
    
    ;********************;
    ;OBSŁUGA SERVA5      ;
    ;********************;
    
    	CLR	TR0
    	MOV	A,#9H
    	MOV	B,55H
    	MUL	AB
    	XCH	A,R5
    	MOV	A,#0FFH
    	CLR	C
    	SUBB	A,R5
    	MOV	TL0,A
    	MOV	R5,B
    	MOV	A,#0FFH
    	SUBB	A,R5
    	MOV	TH0,A
    
    	MOV	P2,#00010000B
    	SETB	TR0
    
    	JNB	TF0,$
    
    ;********************;
    ;OBSŁUGA SERVA6      ;
    ;********************;
    
    	CLR	TR0
    	MOV	A,#9H
    	MOV	B,54H
    	MUL	AB
    	XCH	A,R5
    	MOV	A,#0FFH
    	CLR	C
    	SUBB	A,R5
    	MOV	TL0,A
    	MOV	R5,B
    	MOV	A,#0FFH
    	SUBB	A,R5
    	MOV	TH0,A
    
    	MOV	P2,#00100000B
    	SETB	TR0
    
    	JNB	TF0,$
    
    ;********************;
    ;OBSŁUGA SERVA7      ;
    ;********************;
    
    	CLR	TR0
    	MOV	A,#9H
    	MOV	B,5AH
    	MUL	AB
    	XCH	A,R5
    	MOV	A,#0FFH
    	CLR	C
    	SUBB	A,R5
    	MOV	TL0,A
    	MOV	R5,B
    	MOV	A,#0FFH
    	SUBB	A,R5
    	MOV	TH0,A
    
    	MOV	P2,#01000000B
    	SETB	TR0
    
    	JNB	TF0,$
    
    
    
    ;********************;
    ;OPUZNIENIE 3mS      ;
    ;********************;
    
    	CLR	TR0
    	MOV	TH0,#0F5H
    	MOV	TL0,#32H
    	SETB	TR0
    
    	JNB	TF0,$
    
    	
    ;********************;
    ;BUFOR PORTU RS232   ;
    ;********************;
    
    BUFOR:
    	MOV	59H,69H
    	MOV	58H,68H
    	MOV	57H,67H
    	MOV	56H,66H
    	MOV	55H,65H
    	MOV	54H,64H
    	MOV	5AH,68H
    
    	LJMP	MAIN
    
    ;********************;
    ;KONIEC PETLI GŁÓWNEJ;
    ;********************;
    
    
    ;********************;
    ;PRZERWANIE T0       ;
    ;********************;
    PRZERWANIE:
    	CLR	TF0
    	MOV	P2,#0H
    RETI
    
    
    	
    ;********************;
    ;OBSŁUGA RS232       ;
    ;********************;
    
    intRS232:
    	
    	clr	RI
    	MOV	A,SBUF
    	MOV	@R0,A
    	MOV	A,R0
    	CLR	C
    	SUBB	A,#64H
    	DEC	R0
    	JNZ	PETLA1
    	MOV 	R0,#69H
    PETLA1:
    	RETI
    
    
    
    END
    


    Może jakiś bardzie zaawansowany programista wymyśli lepszy sposób komunikacji i sterowania. Liczę na każdą waszą opinie która może pomóc w wyeliminowaniu tego problemu. Zależy mi również na czasie, ponieważ we wtorek mam dni otwarte w szkole i chciałbym zaprezentować swoją pracę.

    Kodu programu na PC nie zamieszczam gdyż zajmuje za dużo miejsca i praca ma iść również na konkurs więc na razie nie mogę udostępnić kodu.
  • REKLAMA
  • #2 4998582
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Masz zachwiania w sterowaniu serwami. Najprawdopodobniej podczas odbioru danych z RS232 serwo otrzymuje błędne pozycje(sygnały).

    Jeżeli serwa trzymają bez sygnałów sterujących(moje tak działa, ale nie wiem czy inne) to wyłączaj przerwanie timera na czas odbioru wiadomości przez RS232.
  • REKLAMA
  • #3 5001413
    Lukis
    Poziom 11  
    Posty: 48
    Jeżeli wyłączę przerwanie od timera na czas odbioru to może to spowodować wydłużenie impulsu sterującego, albo nawet brak jego wyłączenia. Więc takie rozwiązanie raczej nie pomoże, to że przesyłane są błędne dane to wiedziałem, ale chodzi mi o sposób ich eliminacji, nie mogę dodać bitu parzystości i dwóch bitów stopu, bo jak nie odbiorę jakiejś danej to pomyli się sterowanie. Więc potrzebny jest inny sposób na to aby pozbyć się zakłóceń.
  • #4 5001465
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Serwo nawet nie sterowane trzyma ... więc wyłączasz przerwanie, gdy linie sterujące są w stanie L.

    btw.
    Mój sposób poprawnej transmisji:
    PC->M: DANA1
    M->PC: ~DANA1
    PC: jeżeli DANA1 = ~DANA1(Odebrana) to wysyła kolejną. Jeżeli nie to wysyła np. 0xff(umowny znak błędu) i mikrokontroler traci poprzednią, a cała procedura się powtarza.

    Ja bym raczej popatrzał na te przerwania.
  • #5 5001565
    Lukis
    Poziom 11  
    Posty: 48
    co do przerwań, to te z portu szeregowego maja niższy priorytet, więc przychodzące dane nie zakłócą sterowania serwami, tak mi sie wydaje. Próbowałem też takiego sposobu, że z PC wysyłałem każdą dana dwa razy i potem w uC porównywałem je ze sobą, jak sie różniły to nie wpisywałem ich do komórek z których pobierane są dane do sterowania serwami. Jednak w niczym to nie pomogło, więc może problem leży po stronie przerwań akurat, bo słyszałem coś, że AT89S51 maja problemy z przerwaniami jak występują one za często. Mówisz żeby wyłączać przerwanie w czasie niskiego impulsu, ale trwa on tylko około 3-4ms, więc trochę mało czasu a co jeśli dana przyjdzie podczas sterowania serwami?
  • REKLAMA
  • #6 5001592
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    3-4ms? Ramka do serw ma 20ms przecież ...

    Nie pamiętam, ale chyba w '51 są też flagi przerwań. Kontroluj ręcznie flagę i odbieraj z SBUF dane tylko gdy przerwanie powinno się wywołać(nie wywołuj go automatycznie). Po odbiorze poinformuj PC jakąś stałą(np. 0xff) aby wiedział, że może wysłać kolejną daną. Zrozumiałeś? Mogę się mylić, bo właśnie piszę na zaliczenie pierwszy prosty program dla '51 ;) Jakieś I/O, więc nie porównuje tego do Twojego projektu ;)
  • #7 5001710
    Lukis
    Poziom 11  
    Posty: 48
    3-4ms trwa niski stan, bo obsługuje 8 serw po kolei więc jak każde będzie miało impuls 2ms to już daje 16ms, więc do pełnej ramki brakuje 4ms które są w stanie niskim, każde serwo ma te 18ms stanu niskiego, ale w większości czasu obsługiwane są kolejne serwa i czas w którym uC tak jakby nie robi nic to około 3ms. Spróbuje zrobić tak jak ty mówisz, jak dostane coś od PC to mu to odeśle, tam sobie porównam i podejmę odpowiednie działanie, ale do wtorku już nie zdążę, co nie oznacza, że projekt nie będzie dokończony :)

    Nie wiem czy wielka różnicę zrobi ręczne sprawdzanie flagi przerwania od RS'a, nie wydaje mi sie ale mogę sie mylić bo z assemblerem też długo nie pracuje.
  • #8 5001817
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Mając do dyspozycji coś tak potężnego jak assembler mógłbyś w inny sposób napisać kod. Właśnie ukończyłem zlecenie sterownika serw na AVR. Steruje serwami w ten sposób, że wszystkim daje H i po odpowiednim czasie wyłączam dowolne z nich(porównywanie z zadaną wartością). W assebblerze mógłbyś to dokładnie policzyć i program by śmigał, aż miło ;)

    Wytłumaczę dla pewności o co mi chodziło: po włączeniu zasilania wysyłasz do PC np. 0xff i on wie, że może wysłać bajt danych. Program mikrokontrolera steruje sobie serwami i w tym "wolnym" czasie sprawdza flagę układu szeregowego. Jeżeli odpowiedni stan(nie pamiętam który :P ) to coś tam sobie robisz z tą daną i odsyłasz do PC wartość np. 0xff, żeby wiedział o możliwości wysłania kolejnego bajtu, a jeżeli inny(niż ten którego nie pamiętam) to sterujesz dalej serwami.

    Serwa z tego co zauważyłem można wysterować jednym impulsem. Nie dając kolejnych serwo zatrzyma się w "zaprogramowanym" miejscu. Możesz specjalnie zatrzymywać serwa w określonej pozycji(lub jakaś przypadkowa) i właśnie w tym momencie wysłać np. 0xff do PC, aby wiedział o możliwości transmisji bufora do mikrokontrolera kończącego się znakiem np. 0xff, żeby mikrokontroler wiedział o zakończeniu bufora i mógł powrócić do obsługi serw :D Troszku to skomplikowane... ale działa ;)
  • REKLAMA
  • #9 5001862
    Lukis
    Poziom 11  
    Posty: 48
    Mam pytanko co do twojego sposobu sterowania, mianowicie na czym odmierzasz czas, który porównujesz z tym co przyszło z portu? Jest to licznik czy jakaś pętla?
    Bo z tego co zrozumiałem to włączasz każde wyprowadzenie sterujące, gdzieś liczysz czas i co jeden impuls liczący sprawdzasz czy nie powinieneś wyłączyć któregoś serwa, chyba dobrze Cię zrozumiałem.
  • #10 5001922
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Dobrze. Poniżej algorytm poglądowy:

    1.Stan H dla wszystkich
    2.Odczekanie minimum impulsu(pętla)
    3.Wyłaczyć S0?
    4.Wyłaczyć S1?
    5.Wyłaczyć S2?
    6.Wyłaczyć S3?
    7.Wyłaczyć S4?
    8.Wyłaczyć S5?
    9.Wyłaczyć S6?
    10.Wyłaczyć S7?
    11.Odczekuj czas pomiędzy stopniami(ja steruje serwami podając stopień wychylenia z PC).
    12. Powrót do punktu 3 jeżeli nie obsłużono wszystkich 120 stopni

    13. INNE FUNKCJE

    Żeby była jasność - punkt 1 jest odpalany z licznika o przepełnieniu co 20ms. Punkt 13 czyli wszystkie inne instrukcje są obsługiwane poza przerwaniem.
  • #11 5001944
    Lukis
    Poziom 11  
    Posty: 48
    Dobra już rozumiem w pełni twój sposób, no to czekam mnie pisanie programu od nowa niemalże, długo to nie potrwa ale pewnie poczekam z tym do skończenia matury, chyba ze nie wytrzymam i zabiorę się za to wcześniej, jedyne co jest pewne to to, że dam znać czy udało sie wyeliminować problem. Jak na razie dziękuje za pomoc.
    Pozdrawiam
    Łukasz

Podsumowanie tematu

✨ Problem dotyczy szarpnięć manipulatora 6DOF sterowanego serwomechanizmami za pomocą mikrokontrolera AT89S52 komunikującego się z komputerem przez port RS232. Po włączeniu zasilania manipulator utrzymuje pozycję startową, jednak podczas transmisji danych z PC pojawiają się zakłócenia powodujące błędne sygnały sterujące i szarpnięcia ramion. Dyskutowano o problemach z przerwaniami i błędami transmisji RS232, które mogą powodować niepoprawne dane sterujące serwami. Proponowano wyłączanie przerwań timera podczas odbioru danych, ręczne sprawdzanie flag przerwań, potwierdzanie poprawności danych przez echo i retransmisję, a także implementację algorytmu sterowania serwami polegającego na podawaniu impulsu wysokiego do wszystkich serw i wyłączaniu ich po określonym czasie, mierzonym licznikiem z przerwaniem co 20 ms. Zasugerowano, że serwa utrzymują pozycję bez ciągłego impulsu, co pozwala na optymalizację sterowania. Autor planuje przebudowę oprogramowania, aby poprawić stabilność transmisji i eliminować błędy powodujące szarpnięcia.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA