Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[bascom] moja wersja openservo, ZS-M218 i L293D

wader_669 29 Sep 2009 15:24 2564 6
  • #1
    wader_669
    Level 28  
    Robie 2D skaner z udzialem serwa i dalmierza sharpa. Pierwszy pomysl byl kupic normalne serwo i nie przerabiac go. Wady: nie podobalo mi sie to sterowanie pwm i nie wiedzialem kiedys serwo dotarlo na to polozenie co chcialem.
    Wiec stwierdzilem, ze rozbiore serwo, dodam mostek-h, prockek z adc i sam bede sterowal silniczkiem.
    Problem teraz jest taki, ze serwo sie kolysze w nieskonczonosc, zamiast sie zatrzymac. Czasem jak pomoge palcem to przestaje sie kolysac.
    Myslalem, ze to powod procek, ze jest za wolny. Kupilem kwarc 16Mhz no i nic. Nastepnie myslalem, ze moze zle ustawiam stany na wejsciu mostka, ze nie hamuje silniczka. Jednak wszystko bylo ok. Pozniej testowalem jak sie zachowuje serwo jak zmienjsze predkosc i bylo juz w miare ok, tylko serwo poryszalo sie troche za wolno. Nastepnie zwiekszylem rozpietosc, gdzie serwo ma sie zatrzymac i juz sie nie kolysalo, jednak ta rozpietosc byla troche za duza.

    Ktos ma pomysl jak to rozwiazac ?

    Dodaje kod.
    Code:

    '******* procek *******
    $regfile = "m8def.dat"
    $crystal = 16000000

    $hwstack = 60
    $swstack = 60
    $framesize = 60

    '******* pwm *******
    Config Pinb.1 = Output
    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Disconnect , Prescale = 1

    Pwm1a = 255

    '****** mostek-h ******
    Config Pind.5 = Output
    Config Pind.6 = Output



    Portd.5 = 0
    Portd.6 = 0

    H1 Alias Portd.5
    H2 Alias Portd.6

    '******* adc **********
    Config Adc = Single , Prescaler = Auto , Reference = Avcc
    Dim Wart_ac As Word

    Cls
    Start Adc
    Do
    Wart_ac = Getadc(1)

    If Wart_ac < 375 Then
    H1 = 1
    H2 = 0
    Elseif Wart_ac > 407 Then
    H1 = 0
    H2 = 1
    Elseif Wart_ac < 407 Or Wart_ac > 375 Then
    H1 = 1
    H2 = 1
    End If
    Loop : End



    Dodano po 14 [minuty]:

    Dodam jeszcze, ze l293d czesc logiczna jak i czesc sterowania silniczkow zasilam z 5V
  • Helpful post
    #2
    MirekCz
    Level 35  
    1.Użyj PWM do sterowania prędkością silnika. W najprostszym rozwiązaniu możesz np. do połowy obecnej rozpiętości jeszcze ruszać silnikiem z 50-75% wypełnieniem PWM itd.

    2.Zastosuj sterowanie PID. Po odpowiednim dobraniu parametrów powinno śmigać ok (oczywiście w połączeniu z PWM)
  • #3
    wader_669
    Level 28  
    Code:

    '******* procek *******
    $regfile = "m8def.dat"
    $crystal = 16000000

    $hwstack = 60
    $swstack = 60
    $framesize = 60

    '******* pwm *******
    Config Pinb.1 = Output
    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Disconnect , Prescale = 1

    Pwm1a = 255
    '****** mostek-h ******
    Config Pind.5 = Output
    Config Pind.6 = Output

    Portd.5 = 0
    Portd.6 = 0

    H1 Alias Portd.5
    H2 Alias Portd.6

    '******* adc **********
    Config Adc = Single , Prescaler = Auto , Reference = Avcc
    Dim Wart_ac As Word

    '****** zmienne ****

    Dim Ustawione As Word
    Ustawione = 900

    Const Tolerancja = 15

    Dim Ustawione_dol As Word
    Dim Ustawione_gora As Word

    Ustawione_dol = Ustawione - Tolerancja
    Ustawione_gora = Ustawione + Tolerancja

    Dim Pid_dol As Word
    Dim Pid_gora As Word

    Dim Pwm1 As Byte

    Const Pid_tolerancja = 60

    Pid_dol = Ustawione_dol - Pid_tolerancja
    Pid_gora = Ustawione_gora + Pid_tolerancja

    Declare Sub Wyswietlacz

    Cls
    Start Adc
    Do
    Wart_ac = Getadc(1)

    If Wart_ac < Ustawione_dol Then
       If Wart_ac => Pid_dol Then
       Pwm1 = Ustawione - Wart_ac
       Pwm1 = 255 - pwm1
       Pwm1a = Pwm1
       End If
    H1 = 1
    H2 = 0
    Elseif Wart_ac > Ustawione_gora Then
       If Wart_ac =< Pid_gora Then
       Pwm1 = Wart_ac - Ustawione
       Pwm1 = 255 - pwm1
       Pwm1a = Pwm1
       End If
    H1 = 0
    H2 = 1
    Elseif Wart_ac < Ustawione_gora Or Wart_ac > Ustawione_dol Then
    H1 = 1
    H2 = 1
    End If
    Loop : End


    Dodano po 3 [minuty]:

    Napisalem taki kod gdzie wczesniej zalancza sie pwm i zmniejsza predkosc, zanim dojdzie do pozycji ustalonej. Pomoglo troche, nie kolysze sie w nieskonczonosc. Nadal wynik nie jest super, ale to chyba doprawienia.

    Musze troche wiecej poczytac o PID, ale glowna zasade chyba zrozumialem.
  • #4
    _Robak_
    Level 33  
    W serwomechanizmach raczej nie stosuje sie PID tylko PD. PID nie daje sie bo masz wtedy podwojne calkowanie, silnik calkuje napiecie i druga calka w regulatorze. Dlatego lepiej dac PD.
  • #5
    wader_669
    Level 28  
    Narazie brak czasu, ale musze jeszcze poczytac o pid i pd. Teraz zrobilem tak jak pokazalem wyzej, po prostu troche przed oczekiwana pozycja dalem pwm, ktore spowalnia silniczek i dziala.
  • #6
    MirekCz
    Level 35  
    _Robak_ wrote:
    W serwomechanizmach raczej nie stosuje sie PID tylko PD. PID nie daje sie bo masz wtedy podwojne calkowanie, silnik calkuje napiecie i druga calka w regulatorze. Dlatego lepiej dac PD.


    Nie za bardzo kumam z tymi całkami? Możesz jaśniej? Jaka całka w silniku? PS.Może Tobie chodzi o moment bezwładności? :)

    Ja generalnie I przeważnie daje tyle co kot napłakał - tylko po to, żeby układ dochodził do właściwej wartości i oscylował dookoła niej. Bez I w niektórych wypadkach (szczególnie przy silniku, który poniżej pewnego napięcia przestaje zupełnie działać) zawsze zatrzymasz się przed uzyskaniem właściwej wartości.
  • #7
    _Robak_
    Level 33  
    No wiec tak ;) Silnik calkuje napiecie, biorac pod uwage kat obrotu jako wyjscie ukladu. Czyli, jesli napiecie jest stale to kat zmienia sie tak jak dla funkcji y=x. bardziej fachowo to transmitancja takiego ukladu wynosi k(s)=k/s. Jednak rzeczywisty silnik to inercja pierwszego rzedu i k(s)=k/(1+sT). Stala czasowa T dosc latwo wyznaczyc. Jest to 2/3 czasu potrzebnego na osiagniecie wartosci zadanej dla skoku jednostokowego. Drugie calkowanie mialbys w regulatorze PID. Drugiego calkowania w sterowniku sie nie daje, bo jak sie domyslam moga powstawac oscylacje. W kazdym razie pamietam jeszcze z laborek ze w serwach stosuje sie regulatory PD. PID owszem tez, ale nastroic to juz jest ponoc ciezko, owszem da sie, nawet na slepo, na wlasne oczy widzialem. Ale nie wiem jak to ma sie ze sztuka doboru nastaw :)

    Edit: Poprawka do tego co na gorze :) k/s jest kiedy wyjsciem jest kat, natomiast k/(1+sT) jest gdy wyjsciem jest predkosc :)