Skocz do zawartości

Problem z PWM


fazi787

Pomocna odpowiedź

Witam. Jestem podczas budowy robota line follower. Na sam początek dla testu ,,wrzuciłem'' do robota prosty program. Wykorzystuje on tylko 3 z 7 czujników CNY70: ( prawy, lewy i środkowy)

$regfile = "m16def.dat"
$crystal = 16000000

Config Portc = &B11111111 : Portc = &B00000000
Config Portd = &B11111111 : Portd = &B00000000
Config Portb = &B11111111 : Portb = &B00000000
Config Porta = &B00000000 : Porta = &B00000000


Config Adc = Single , Prescaler = Auto , Reference = Avcc
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1



Silnik_lewy_a Alias Portd.3
Silnik_lewy_b Alias Portd.2
Silnik_prawy_b Alias Portd.0
Silnik_prawy_a Alias Portd.1
Dioda1 Alias Portc.0
Dioda2 Alias Portc.1

Const Granica = 500

Dim Czujnik_lewy As Single
Dim Czujnik_srodkowy As Single
Dim Czujnik_prawy As Single
Dim W As Word

Set
Dioda1 = 1
Waitms 50
Dioda1 = 0
Dioda2 = 1
Waitms 50
Dioda2 = 0
Set Dioda1
Set Dioda2
Waitms 125
Set Silnik_lewy_a : Reset Silnik_lewy_b
Set Silnik_prawy_a : Reset Silnik_prawy_b


Do

  Reset Dioda1
  Reset Dioda2

  Gosub Wczytaj_stany_przetwornikow
  If Czujnik_srodkowy > Granica Then
     Pwm1a = 140
     Pwm1b = 140
  Elseif Czujnik_lewy > Granica Then
     Pwm1a = 0
     Pwm1b = 140
  Elseif Czujnik_prawy > Granica Then
     Pwm1a = 140
     Pwm1b = 0
  Else
     Pwm1a = 140
     Pwm1b = 140
  End If
Loop
End

Wczytaj_stany_przetwornikow:
Start Adc
W = Getadc(0)
W = Getadc(0)
Stop Adc
Czujnik_lewy = W
Start Adc
W = Getadc(5)
W = Getadc(5)
Stop Adc
Czujnik_srodkowy = W
Start Adc
W = Getadc(4)
W = Getadc(4)
Stop Adc
Czujnik_prawy = W
Return

Silniki się kręcą cały czas tą samą prędkością, a czujniki nie reagują na linię.

Próbowałem wrzucić na robota jeszcze jeden program, który by przetestował silniki:

regfile = "m16def.dat"
$crystal = 16000000

Config Portc = &B11111111 : Portc = &B00000000
Config Portd = &B11111111 : Portd = &B00000000
Config Portb = &B11111111 : Portb = &B00000000
Config Porta = &B00000000 : Porta = &B00000000


Config Timer1 = Pwm , Pwm = 8 , Prescale = 1 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up

Dioda Alias Portc.0
Mset1b Alias Portd.0
Mset1a Alias Portd.1
Mset2a Alias Portd.3
Mset2b Alias Portd.2


Set Mset1a : Reset Mset1b
Set Mset2a : Reset Mset2b

Pwm1a = 140
Pwm1b = 140


Dim Zwalnianie As Byte
Zwalnianie = 0

  Do

     If Zwalnianie = 0 Then
        Pwm1a = Pwm1a + 1
        Pwm1b = Pwm1b + 1
     Else
        Pwm1a = Pwm1a - 1
        Pwm1b = Pwm1b - 1
     End If

     If Pwm1a = 255 Then
        Zwalnianie = 1
     Elseif Pwm1a = 140 Then
        Zwalnianie = 0
     End If

     Waitms 50


  Loop

End

Niestety silniki zachowują się tak samo, czyli kręcą się cały czas z tą samą prędkością.

Podaje jeszcze schemat robota:

Bardzo proszę o pomoc.

Link do komentarza
Share on other sites

Nie zawsze wszystko od razu działa. Uruchamiaj układ po kawałku.

Może zacznij od sprawdzenia, czy w ogóle możesz jakkolwiek sterować silnikami. Wyłącz oba PWMy i zamiast tego wystawiaj różne kombinacje sygnałów sterujących mostkiem.

Np. wystaw na stałe 1-0 na SILNIK1A-1B is sprawdź, czy wystawienie 1 na PWM1 odpali silnik, a 0 zatrzyma. Potem to samo dla 0-1 na SILNIK1A-1B. Dla 0-0 niezależnie od PWM1 silnik powinien stać. To samo dla 1-1. Powtórz taki sam test dla drugiego silnika. Jeżeli wszystko jest OK to już wiesz, że ten fragment hardware działa i zabierz się za PWM.

Wpisz jeszcze raz ostatni program (ten ze zmienną zwalnianie) i podłącz się do wyjść PWM zwykłym woltomierzem. Przy wstawionym w pętlę oczekiwaniu 50ms napięcie na woltomierzu powinno zmieniać się od 0 do 5V z okresem ok 26s, tj. 13 sekund w górę i 13 sekund w dół. Zmieniając wypełnienie PWM 0-100% zmieniasz jego wartość średnią od zera do Vcc procesora - możesz to zweryfikować zwykłym miernikiem.

Ogólnie: testy jakie robisz powinny bazować na tym co już działa. Jeśli zaczynasz od zera, niczego nie możesz być pewien, więc testy muszą być proste. Sprawdzasz pojedyncze piny, częstotliwość pracy procesora (za pomocą pomiaru czasu opóźnień) zapalanie diodek (chyba są odwrotnie na schemacie więc raczej się nie zapalą - sprawdzałeś to?), pojedyncze sygnały do mostka - jak opisałem powyżej, czujniki - każdy osobno wypuszczając jego sygnał np. na (już sprawdzoną) diodę LED itd. Powoli rozszerzasz krąg pewności aż osiągniesz granice układu - dopiero wtedy możesz zacząć prawdziwą zabawę w pisanie programów.

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

Dzięki za odpowiedź. Zrobiłem tak jak mówiłeś. Powoli wszystko dokładnie sprawdzałem. Jeśli chodzi o takie proste sterowanie silnikami to wszystko działa. Tak jak pisałeś: 0 silnik się zatrzymuje, 1 silnik rusza. Wpisałem jeszcze raz ten program sterujący silnikami (ten ze zmienną zwalnianie) i podłączyłem multimetr do wyjść PWM.

Okazało się, że silniki działają prawie tak jak trzeba, tylko, że bardzo powoli. Na multimetrze napięcie zmienia się w zakresie około 2.5 - 5V w czasie około półtorej minuty! Co do diody. Na schemacie jest błąd, ale ogólnie dobrze je podłączyłem. Sterowanie nimi nie sprawia żadnych problemów, działają tak jak należy 🙂

Nie wiem dalej co może być powodem tak działających silników.

Link do komentarza
Share on other sites

No tak, przepraszam, nie zauważyłem, że dolny zakres PWM w programie to nie jest 0 tylko 140. W takim razie zmiany napięcia 2.5V -> 5V i z powrotem są OK.

Ja widzę dwa problemy:

Pierwszy to czasy. Popatrz, jeśli w pętli masz opóźnienie 50ms i wykonujesz ją 255-140=115 razy to taka jedna rampa rosnącego PWM powinna zamykać się w 115*0.05=5.75s. Jeśli w rzeczywistości trwa to o wiele dłużej, to masz coś pokręcone z taktowaniem procesora. Być może kompilator "myśli", że masz 8MHz a naprawdę procek chodzi z 1MHz? Sprawdź fusebity.

Drugi problem to sam mostek. Nie wiem jakie masz silniki, ale zasilając driver z 7V do silnika dostaje się pewnie max ze 4.5V. Jeśli silniki są np. na 6V, to masz odpowiedź. Najprościej będzie jak odpalisz jeszcze raz program testowy co to wystawiał statyczne zera i jedynki na porty, włączysz nim silnik w którąkolwiek stronę na full i zmierzysz względem masy:

- napięcie zasilania

- napięcie na jednym końcu silnika

- napięcie na drugim końcu silnika.

Pierwsze pokaże Ci czym Twój system dysponuje, drugi pomiar pokaże jak wiele spada na mostku od strony plusa a ostatni ile mostek pożera od strony masy (albo odwrotnie). Na silniku zostanie oczywiście zasilanie minus oba spadki na mostku - możesz to sprawdzić mierząc napięcie bezpośrednio na silniku.

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

Silniki jakie używam to pololu 30:1. Problem z silnikami rozwiązany 🙂 Wystarczyło zmienić fusebity. Czyli ten program który przyspiesza i zwalnia silniki działa. Co do tego prostego programu line follower, to tu nadal jest problem. Na czujniku CNY70 na dwóch pinach jest minnus ( są one podpięte pod mase), na trzecim stale jest około 1,7V a na czwartym ( tym który jest podpięty pod mikrokontroler) jest około 2,5V - 3V gdy czujnik jest nad zwykłą ( nie czarną) powierzchnią i 4,8V gdy czujnik jest nad czarną powierzchnią. Czy tak powinno być?

Myślę ogólnie, że wina może leżeć po stronie czujników.

Dodam jeszcze, że bardzo stabilizator mi się grzej, choć nie ma nigdzie spięć.

Link do komentarza
Share on other sites

Jak możesz to zrób zdjęcie płytki z czujnikami (po obu stronach - góra. dół) i może jeszcze płytki z uC.

Załącz zasilanie i telefonem zobacz, czy wszystkie czujniki się "palą", tzn. diody IR w czujnikach.

Link do komentarza
Share on other sites

Jeżeli czujniki działają i zmienia im się napięcie na kolektorach pod wpływem zmiany podłoża, to jest OK. Czy to samo jest na wejściach procesora - sprawdź to, to jeden z testów.

Znów popełniasz ten sam błąd co na początku - próbujesz odpalać skomplikowany program nad którym nie panujesz, nie mając przetestowanego sprzętu. Korzystaj z diodek LED - to wskaźniki tego co robi program. Zacznij od analizy jednego czujnika. Zmierz go przetwornikiem i zapalaj diodę LED gdy np. odczyt ADC przekroczy jakąś granicę - to bardzo prosty test i na pewno napiszesz go bezbłędnie. Żadnych PWM, żadnych skomplikowanych analiz. Potem to samo powtórz dla reszty czujników, po kolei dla każdego osobno. Zapisuj sobie napięcia "jasne" i "ciemne".

Jak ustawić granicę? Masz dwa wyjścia : doświadczalnie i analitycznie.

Pierwsze podejście jest dla niekumatych: zmieniasz granicę tyle razy, aż testowa dioda LED zacznie się zapalać i gasnąć przy pokazywaniu czujnikowi białego i czarnego.

Drugie jest fajniejsze i bazuje na znajomości zasady działania przetwornika. Przy tych ustawieniach jakie zrobiłeś, przetwornik oddaje liczbę 1023 gdy napięcie wejściowe jest prawie równe Vcc a liczbę 0 gdy dostaje 0V. Jaki wynik odczytasz z ADC gdy napięcie z czujnika wynosi 3V? Proste: (3V/5V) *1024=614. Dla 4.8V będzie to (4.8/5)*1024=983. Obie te liczby są większe niż granica jaką ustawiłeś obecnie w programie, czyli 500.

Jak chcesz, żeby program wykrywał zmianę stanu czujnika, skoro ten nie jest w stanie przekroczyć granicy? Ustaw ją gdzieś w połowie między wartościami mierzonymi dla białego i czarnego (np. 750...800) a będzie dużo lepiej.

Jeszcze raz powtarzam: powoli testuj sprzęt i swoje możliwości. Pisz programy tak proste, byś nie miał wątpliwości co do ich działania, bo to one mają Cię upewnić, że hardware działa. Opieraj następne testy na wynikach tych już przeprowadzonych. Jeśli testujesz czujniki - sprawdzaj po jednym. Wcale nie jest powiedziane, że każdy czujnik ma taką samą czułość, więc być może trzeba będzie ustawić kilka różnych "granic". Najlepiej zarezerwuj dla każdego osobny próg. Ustal go poprzez pomiar woltomierzem dwóch napięć ("białego" i "czarnego"), przeliczenie Voltów na liczbę odczytywaną z ADC a potem ustalenie granicy gdzieś w połowie. Jeżeli uznasz, że zmiany napięć są za małe i będziesz chciał zwiększyć czułość, możesz oporniki w kolektorach zmienić np. z 10k na 22k.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dzięki za odpowiedź. Zacząłem od prostych testów, czyli zaświecania i gaszenia diód, a później miganie nimi. Wszystko działało. Przeszedłem do tych trudniejszym. Postanowiłem przetestować przycisk:

$regfile = "m16def.dat"
$crystal = 16000000

Config Portd = &B11111111 : Portd = &B00000000
Config Portc = &B11111111 : Portc = &B00000000
Config Portb = &B11111111 : Portb = &B00000000
Config Porta = &B00000000 : Porta = &B00000000

Dioda Alias Portc.0
Przycisk Alias Pinb.2

  Do

   If Przycisk = 0 Then
     Set Dioda
   Else
     Reset Dioda
   End If

  Loop

End

Czyli jeżeli nacisnę przycisk, dioda powinna się zaświecić. Wszystko działa.

Nadal są jednak problemy z czujnikami. Ustawiałem już chyba wszystkie wartości, i nadal nic.

$regfile = "m16def.dat"
$crystal = 16000000

Config Portd = &B11111111 : Portd = &B00000000
Config Portc = &B11111111 : Portc = &B00000000
Config Portb = &B11111111 : Portb = &B00000000
Config Porta = &B00000000 : Porta = &B00000000

Config Adc = Single , Prescaler = Auto , Reference = Avcc

Dioda1 Alias Portc.0

Dim Czujnik1 As Word

Const Linia = 800                                           

Start Adc

  Do

   Czujnik1 = Getadc(5)                                   '

   If Czujnik1 > Linia Then
     Set Dioda1
   Else
     Reset Dioda1
   End If

  Loop

End

Tak sobie myślę, że może to jest winna mikrokontrolera? Może jest uszkodzony?

Na pinach ADC sprawdzałem napięcie i jest ok, a mimo wszystko nic się nie dzieje.

Link do komentarza
Share on other sites

diód
- diod.
Tak sobie myślę, że może to jest winna mikrokontrolera? Może jest uszkodzony?

Wiesz co? Masz może jakiś czujnik na zbyciu? np. CNY70? Podłącz tylko jeden, który masz na zbyciu kabelkami na płytce stykowej i wgraj program do uC, który ma zapalić diodę LED jak Czujnik > Granica (to chyba umiesz napisać) i pojeździj nim nad białą kartką z czarnym paskiem taśmy izolacyjnej. Oczywiście z różnymi wartościami granicy. Jak już coś załapie, przetestuje kolejne kanały ADC.

Link do komentarza
Share on other sites

Config Adc = Single , Prescaler = 64 , Reference = Avcc


Dim W As Word
Dim Czujnik1 As Word

Do

Gosub Czytaj



    If Czujnik1 > Granica Then
         Set Dioda
    Else
         Reset Dioda

Loop
End

Czytaj:
Start Adc 
W = Getadc(0) 
W = Getadc(0) 
Stop Adc 
Czujnik1 = W
Return

Spróbuj na tym.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

No to tu już specjalista od BASCOMa jest potrzebny. W C wszystko wydaje się jakby prostsze 🙂

Fazi ustawia tryb single co jak rozumiem tylko włącza zasilanie i zegar ADC a konwersje startowane są poprzez Start ADC. Czy jedno Start ADC to jedna konwersja? Jeśli tak, to trzeba to umieścić w pętli. A jeśli naprawdę jedna, to podwójny odczyt jest bez sensu, bo pierwszy starzał i tak przetwornik robi podwójnie a wynik jest jeden.

Za trudne to dla mnie, bo warstwa BASCOMa oddziela skutecznie od tego co się tam naprawdę dzieje..

Brawo fazi za poprzednie testy. Pisz je tak, by wyciągać z nich ile się da. Jeżeli doprowadzasz znane napięcia i zaczynasz podejrzewać, że ADC ich nie mierzy, wymyśl jakiś inny sprawdzian. Czytaj dokumentację BASCOMa i przykłady tam zawarte. Zepsuty procesor (a właściwie sam przetwornik) to ostatnia rzecz jaka Ci się przydarzy.

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.