Skocz do zawartości

Serwo + potencjometr - problem ze sterowaniem


Panicz74

Pomocna odpowiedź

Witam,

Sprzęt:

-Atmega644P + kwarc 16mgh,
-Serwo TowerPro GS-5010, (na pinie PD5/OC1A)

-potencjometr A10k. (na pinie PA0/ADC0)

-środowisko Eclipse Luna,

Problem:

Za pomocą załączonego kodu, gdy steruje potencjometrem, ciężko ustawić je w zadanej pozycji. Albo szarpie i nie może się ustawić albo od razu przesuwa się do końca i szarpie. Pewnie coś źle zrobiłem w kodzie. Takie problemy mam zarówno na taktowaniu obecnym 16mgh jak i na fabrycznym 1mgh. Pewnie coś źle obliczyłem.

Może ktoś mądrzejszy ode mnie poradzi co tu jest nie tak?

Oto kod:

#include <avr/io.h>
#include <avr/interrupt.h>

static volatile uint16_t rezultat10bit;

int main(void)
{
DDRD |= 0xFF;
TCCR1A |= 1<<WGM11 | 1<<COM1A1 | 1<<COM1A0;
TCCR1B |= 1<<WGM12 | 1<<WGM13 | 1<<CS10;

ICR1 = 10000;

ADCSRA |= 1<<ADPS2;
ADMUX |= (1<<REFS0) | (1<<REFS1);
ADCSRA |= 1<<ADIE;
ADCSRA |= 1<<ADEN;

sei();

ADCSRA |= 1<<ADSC;

float y1 = 100;
float y2 = 8000;

float m = (y2 - y1)/1023;


while (1)
{
OCR1A = ICR1 - (m * rezultat10bit) + 800;
}
}
ISR(ADC_vect)
{
uint8_t theLowADC = ADCL;
rezultat10bit = ADCH<<8 | theLowADC;


ADCSRA |= 1<<ADSC;
}

[ Dodano: 06-05-2015, 23:03 ]

Oto filmy jak działa ten program. Gdy zatrzymuje serwo w danym położeniu nie może ono wypośrodkować położenia. Na pewno coś zmaściłem w kodzie, tylko właśnie nie wiem co.... 🙁

Link do komentarza
Share on other sites

Źle ustawiasz timer - masz prescaler 1 (patrz datasheet: Table 14-6) i źle ustawiasz ICR1.

Muszą one być ustawione tak aby zachodziła równość: F_CPU / prescaler / ICR1 = 50

Wartość OCR1A powinna być dobierana od 5% do 10% ICR1 (1ms - 2ms).

datasheet

Link do komentarza
Share on other sites

Zasilanie mam 5V z zasilacza sieciowego D-Link. Mam podłączone tylko to serwo do układu więc tylko ono może generować spadek napięcia.

[ Dodano: 07-05-2015, 21:46 ]

Wojciechu, to znaczy, że przykładowo dla 1mgh jak by te obliczenia wygladały? Wiem, że dla was to proste ale ja się dopiero tego uczę 🙁

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

Z tabelki "Table 14-6" odczytujemy możliwe wartości prescalera, są to:

1, 8, 64, 256, 1024.

Z datasheet dowiadujemy się także, że Timer1 jest 16-bitowy, czyli wartość ICR1 musi się mieścić w przedziale: 0..65535.

Przekształcamy wzór: F_CPU / prescaler / ICR1 = 50 do postaci takiej aby wyliczyć jedną z niewiadomych (niewiadome to: prescaler i ICR1) przy zgadywaniu drugiej z nich. Łatwiej jest zgadywać z pośród 5 wartości niż 65536-u, więc wyprowadzamy wzór na ICR1. Wygląda on następująco: ICR1 = F_CPU / prescaler / 50

Dla przykładowego F_CPU = 1MHz (tak się zapisuje megaherc) wygląda to następująco:

prescaler = 1 -> ICR1 = 1000000 / 1 / 50 = 20000

prescaler = 8 -> ICR1 = 1000000 / 8 / 50 = 2500

prescaler = 64 -> ICR1 = 1000000 / 64 / 50 = 312,5

prescaler = 256 -> ICR1 = 1000000 / 256 / 50 = 78,125

prescaler = 1024 -> ICR1 = 1000000 / 1024 / 50 = 19,53125

Następnie sprawdzamy, które wyliczone ICR1 są mniejsze od 65536 i wybieramy największe z nich aby mieć jak największą rozdzielczość ustawiania OCR1A.

Mamy więc: prescaler = 1 i ICR1 = 20000, teraz wyznaczamy już tylko 5% i 10% z ICR1, co powie nam jak mamy zmieniać OCR1A aby uzyskać na wyjściu impuls w przedziale 1ms - 2ms.

Ten zakres to: od 1000 do 2000

Podsumowując dla F_CPU = 1MHz otrzymujemy:

prescaler = 1 - ustawiamy tylko bit CS10

ICR1 = 20000

OCR1A od 1000 do 2000

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

No i warto zwrócić uwagę, że ani pobranie wartości zmiennej "rezultat10bit" ani operacja zapisu do OCR1A nie są atomowe (niepodzielne) a to znaczy, że przerwanie może wejść pomiędzy dwoma 8-bitowymi dostępami do obiektów 16-bitowych (do zmiennej lub do rejestru). Tak więc program główny może np. wziąć do obliczeń jedną "połowę" ze starej wartości zmiennej rezultat10bit a drugą z nowej. Jeżeli np. poprzednia wartość tej zmiennej wynosiła 0x01FE a zmieniła się na 0x0202 (zmiana o 4) a program pobrał młodszy bajt tuż przed zmianą (czyli 0xFE) a starszy już po (czyli 0x02) to w rezultacie "zobaczy" wartość 0x02FE - z błędem aż 0x00FC. W takich przypadkach trzeba synchronizować dostępy albo "producenta" danych albo ich "konsumenta" do wspólnego zasobu jakim w tym przypadku jest zmienna rezultat10bit. Najprościej to zrobić wprowadzając 1-bitowy znacznik (tzw. semafor).

Przerwanie (producent danych):

1. Odczytaj wynik z ADC.

2. Jeśli semafor jest wyzerowany to wpisz wynik do zmiennej rezultat i ustaw semafor.

3. Wróć z przerwania.

Program obliczeniowy (konsument danych):

1. Jeżeli semafor jest ustawiony to oblicz nowy OCR1A na podstawie wartości zmiennej rezultat po czym (dopiero wtedy) wyzeruj semafor.

W tym algorytmie przerwanie nigdy nie zapisze nowej wartości do zmiennej (tj. nie wygeneruje nowych danych i nie ustawi semafora) dopóki program nie skorzysta z poprzednich wyników i nie potwierdzi tego wyzerowaniem semafora.

Link do komentarza
Share on other sites

A możecie mi wytłumaczyć jeszcze jedną kwestię prescalera?

prescaler = 1 - ustawiamy tylko bit CS10

Rozumiem, że ustawienie tego bitu daje nam prescaler = 1. A jeśli chciałbym ustawić prescaler = 8 lub prescaler = 16? Jakie bity wtedy ustawić? CS11? CS12?

Rozumuje to tak, że jeśli mam prescaler = 1, to serwo będzie szukało jak najbardziej bliskiego miejsca pomiędzy liczbami całkowitymi. Czyli jeśli zwiększę na prescaler = 8 to serwo zatrzyma się między, np. 0 - 8, ale też przestanie drgać bo nie będzie musiało już szukać tego bardzo wąskiego zakresu prescaler = 1 (0 - 1).

Czy dobrze rozumuję???

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.