Marioslul Napisano Styczeń 22, 2011 Udostępnij Napisano Styczeń 22, 2011 Witam, niedawno czytałem sobie EdW pożyczone od kumpla i natknąłem się na artykuł "robot dla każdego, czyli także dla ciebie". Po dokładnym przemysleniu sprawy (ok 30 sekund zastanawiania się) postanowiłem zamówić całosć z avt. Płytki już zlutowane, pisałem, a własciwie zmieniałem nieco programy dołączone do tego kursu(dotyczące zabawy z diodą led, która jest na płytce głównej robota). W międzyczasie udało mi się uwalić jedną atmegę i zmienić programator (starym musiałem wrzucać program nawet po 100 razy). Mam już nową atmegę, ale nie wiem czy reszta płytek nadal jest sprawna (mostek H L293D, moduł czujników). Nie mam jak tego sprawdzić ponieważ nawet nie wiem czy kod który wrzucam do pamięci procesora ma prawo uruchomić silniki. Zamieszczam kod, który odpowiada za sterowanie PWM silników: #define F_CPU 8000000UL #include "stdio.h" #include "stdlib.h" #include <avr/io.h> #include <util\delay.h> #include <avr/interrupt.h> #define cbi(add,bit) ((add) &= ~(1 << bit)); #define sbi(add,bit) ((add) |= (1 << bit)); #define Led PORTB #define silnikl PORTD void init_PWM(void) { sbi(DDRD,4); sbi(DDRD,5); TCCR1A|=_BV(COM1A1); TCCR1A|=_BV(COM1B1); TCCR1A|=_BV(WGM10); TCCR1B|=_BV(WGM12); TCCR1B|=_BV(CS11); OCR1AH=0x00; OCR1AL=225; OCR1BH=0x00; OCR1BL=225; } void init_TIMER(void) { TCCR0=0x03; TCNT0=0x00; TIMSK=0x01; } int main(void) { init_TIMER(); init_PWM(); } Zamieszczam też schematy płytki mózgu i płytki z mostkiem H. Złącze 2 służy do łączenia tych płytek ze sobą. Prosiłbym o wskazówki - jak uruchomić silniki bądź o poprawienie kodu (który pewnie jest bez sensu). Schemat mózgu Schemat mostka Cytuj Link do komentarza Share on other sites More sharing options...
Rico Styczeń 23, 2011 Udostępnij Styczeń 23, 2011 Co do samego uruchamiania silników, testuj je najpierw bez PWM, enable na sztywno jeden lub zero, bo widzę że nie ustawiasz sobie kierunku obrotów silnik, są to wejścia IN1 IN2 i IN3,IN4 ( na jednym musi być zero a na drugim jeden) żeby silnik się kręcił, zmiana obu stanów spowoduje zmianę kierunku obrotów. Co do PWM wydaje mi się wszystko OK, nie wiem tylko po co "init_TIMER" 1 Cytuj Link do komentarza Share on other sites More sharing options...
Marioslul Styczeń 23, 2011 Autor tematu Udostępnij Styczeń 23, 2011 Witam ponownie i dzięki Ci Rico 😉 . Poradziłem już sobie ze sterowaniem silnikiem. Problem w tym, że działa tylko jeden z nich. Na tym działąjącym mam napięcie 4,35 V, a na drugim ciągle 0. Chyba wszystkie kombinacje wypróbowałem w programie ale wciąż nic. Zamieszczam programik testowy silników. Jesli ktos by miał jakies sugestie co może być nie tak, to bardzo bym prosił o napisanie posta. #define F_CPU 8000000UL #include "stdio.h" #include "stdlib.h" #include <avr/io.h> #include <util\delay.h> #include <avr/interrupt.h> #define cbi(add,bit) ((add) &= ~(1 << bit)); #define sbi(add,bit) ((add) |= (1 << bit)); #define Led PORTB void init_PWM(void) { sbi(DDRD,4); sbi(DDRD,5); DDRD |= _BV(DDD5); DDRD |= _BV(DDD4); TCCR1A|=_BV(COM1A1); TCCR1A|=_BV(COM1B1); TCCR1A|=_BV(WGM10); TCCR1B|=_BV(WGM12); TCCR1B|=_BV(CS11); OCR1AH=0x00; OCR1AL=255; //lewy OCR1BH=0x00; OCR1BL=255; } int main(void) { int zliczacz=0; int a=0; while(a==0) { if(bit_is_clear(PINB, 3)) { a=a+1; } } while(a==1) { init_PWM(); while(zliczacz%2==0) { sbi(DDRB,2); OCR1AL=255; OCR1BL=255; sbi(DDRD, 2); cbi(DDRD, 3); sbi(DDRD, 6);//lewy cbi(DDRD, 7);//lewy _delay_ms(10000); OCR1AL=0; OCR1BL=0; _delay_ms(1000); zliczacz=zliczacz+1; cbi(DDRB, 2); } while(zliczacz%2==1) { OCR1AL=255; OCR1BL=255; cbi(DDRD, 2); sbi(DDRD, 2); cbi(DDRD, 6); //lewy sbi(DDRD, 7); //lewy _delay_ms(10000); OCR1AL=0; OCR1BL=0; _delay_ms(1000); zliczacz=zliczacz+1; } } } Edit: Już wszystko ok. Gapa ze mnie i nie widziałem, że jeden kabelek jest słabo przylutowany do silnika. 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
Marioslul Marzec 4, 2011 Autor tematu Udostępnij Marzec 4, 2011 Witam ponownie. Przez jakis czas robot leżał w kącie, ale postanowiłem w końcu do niego wrocić i pomajstrować. Podpiąłem czujnik, tzw. wąs. Aby sprawdzić czy wszystko jest ok napisałem prosty programik. Robot stoi w miejscu, a gdy wąs będzie wcisnięty to robot ma ruszyć do przodu. No i rusza, tyle że napięcie na silnikach wynosi niespełna 2 volty, przez co porusza się bardzo wolno. Czujnik jest podpięty pod port ADC, zamieszczam kod w nadziei, że znów ktos pomoże 🙄 . sbi(ADCSRA,ADEN); sbi(ADCSRA,ADPS1); sbi(ADMUX,ADLAR); init_PWM(); while(1) { sbi(DDRB,2); OCR1AL=0; OCR1BL=0; sbi(DDRD, 2); cbi(DDRD, 3); sbi(DDRD, 6);//lewy cbi(DDRD, 7);//lewy if(bit_is_set(PINA, 5)) { OCR1AL=255; OCR1BL=255; } } Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
Armir Marzec 4, 2011 Udostępnij Marzec 4, 2011 1. Pozmieniaj cbi i sbi. Nie powinno się tego używać i mogą nie działać w nowym winavr. 2. Zmierz napięcie na pinach en. Powinno być ok 5v. Cytuj Link do komentarza Share on other sites More sharing options...
mactro Marzec 4, 2011 Udostępnij Marzec 4, 2011 Dlaczego działasz na rejestrze DDRx? On służy tylko do ustawienia czy dany pin jest wejściem czy wyjściem. Jeśli chcesz zmienić wartość wystawioną na wyjściu, zapisuj ją do rejestru PORTx. Cytuj Link do komentarza Share on other sites More sharing options...
Marioslul Marzec 25, 2011 Autor tematu Udostępnij Marzec 25, 2011 Witam, mam kolejny problem. Kupiłem serwo tower pro sg-5010 i chcę nim sterować za pomocą OC0 czyli PB3. Zastanawiam się jak ustawić ten dzielnik częstotliwosciowy, przy liczniku timer1 było to ICR1, a przy timer0 nie mam pojęcia co wpisać. Po wgraniu poniższego programu do procka serwo robi niewielki ruch w lewo i tak zostaje. Szukałem rozwiązania w przykładach, ale każdy do sterowania serwa używa OC1A lub OC1B. Z datasheeta atmela też nic nie wydedukowałem. #define F_CPU 8000000UL #include "stdio.h" #include "stdlib.h" #include <avr/io.h> #include <util\delay.h> #include <avr/interrupt.h> #define cbi(add,bit) ((add) &= ~(1 << bit)); #define sbi(add,bit) ((add) |= (1 << bit)); void init_PWM(void) { DDRB |=_BV(DDB3); TCCR0 |= _BV(WGM00); TCCR0 |= _BV(CS01); TCCR0 |= _BV(COM01); //??? IC0 = 10000; ??? OCR0=750; } int main(void) { sbi(PORTB, 3); init_PWM(); while(1) { OCR0=750; _delay_ms(3000); OCR0=850; _delay_ms(3000); } } Nie wiem jak ustawić wartosć tego rejestru w miejscu oznaczonym znakami zapytania. 😕 Proszę o pomoc. Cytuj Link do komentarza Share on other sites More sharing options...
hakroom Marzec 25, 2011 Udostępnij Marzec 25, 2011 Marioslul wybrałeś jak tryb PWM, Phase Correct (PWM, korekcja fazy) zatem maksymalna wartość do której zlicza licznik to 255 (0xFF). Za pomocą rejestru OCR0 ustawiasz liczbę impulsów do zliczenia nie więcej niż 255. Jedynie w trybie CTC możesz sobie ustalić maksymalną wartość do której zlicza licznik. Cytuj Link do komentarza Share on other sites More sharing options...
Marioslul Marzec 26, 2011 Autor tematu Udostępnij Marzec 26, 2011 Dziękuję za pomoc hakroom. Wpadłem na pomysł, żeby do sterowania serwa wykorzystać przerwanie od timera0, jednak najpierw chciałem zrobić prosty programik testujący - zapalający i gaszący diodę. Przerwanie niestety nie działa, próbowałem używać gotowców i też nie działają. Co może być nie tak? #define F_CPU 8000000UL #include "stdio.h" #include "stdlib.h" #include <avr/io.h> #include <util\delay.h> #include <avr/interrupt.h> #define cbi(add,bit) ((add) &= ~(1 << bit)); #define sbi(add,bit) ((add) |= (1 << bit)); void init_PWM(void) { DDRB |=_BV(DDB2); //pb2 jako wyjscie DDRB |=_BV(DDB3); //pb3 jako wyjscie TCCR0 |= _BV(WGM00); //phase correct TCCR0 |= _BV(CS02) | _BV(CS00); //preskaler 1024 TCCR0 |= _BV(COM01); //clear OCx on compate match TCNT0=0x00; TIMSK=0x01; //overflow interrupt enabled } SIGNAL (SIG_OVERFLOW0) { cli(); //wylaczenie przerwan na czas dzialania tego przerwania sbi(PORTB, 2); //dioda _delay_ms(50); cbi(PORTB, 2); _delay_ms(100); sei(); //zezwolenie na przerwania } int main(void) { sbi(PORTB, 3); init_PWM(); sei(); while(1) { } } Edit: Zostawilem przerwania na jakis czas, udało mi się uruchomić serwo ale strasznie piszczy i bardzo wolno zmienia pozycję, czasami potrafi się zatrzymać na kilka sekund i rusza dalej. Zmienna x odpowiada za wychylenie serwa (bezpiecznie wartosci to zakres od 31 do 40). Wywalając asm ("nop") serwo zatrzymuje się na blokadzie i nie jestem w stanie znaleźć takiego x przy którym mógłbym zmieniać jego położenie. Ponownie proszę o pomoc 🙄 . #define F_CPU 8000000UL #include "stdio.h" #include "stdlib.h" #include <avr/io.h> #include <util\delay.h> #include <avr/interrupt.h> #define cbi(add,bit) ((add) &= ~(1 << bit)); #define sbi(add,bit) ((add) |= (1 << bit)); int main(void) { int x=32; DDRB |= (1<<3); //wyjscie dla serwa while(1) { sbi(PORTB,3); // serwo for (int z=0; z<x;z++) { asm ("nop") ; //funkcja nie robiaca nic } cbi(PORTB,3); } return 0; } Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
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!