Krawi92 Napisano Sierpień 1, 2021 Udostępnij Napisano Sierpień 1, 2021 Witam, dziś ruszyłem temat pwm. Udało mi się uruchomić na 2 kanałach tryb fast pwm 8 bit. Doczytałem, że za wartość wypełnienia odpowiadają rejestry porównawcze OCR1A i OCR1B, do nich należy wprowadzić wartość. Myślałem, że jak wybieram pwm 8 bitowy to maksymalna wartość to będzie 255.(od 0 do 255). Jednak w te rejestry mogę wpisać o wiele większą liczbę,.. przy 1023 świeci maksymalnie, przy 1024 baardzo słabo.. napisałem prosty program, rozjasniajaco-ściemniający 2 diody i wszystko OK, działa... #include <avr/io.h> #include <util/delay.h> #include<avr/interrupt.h> int main (){ DDRB |= 0b00000110; // Ustawienie portów wyjscia PB1 i PB2 // =INICJALIZACJA PWM= // TCCR1A |= (1<<WGM10)|(1<<WGM11)|(1<<COM1B1)|(1<<COM1A1); // tryb 8 bit i wlaczone 2 kanaly TCCR1B |= (1<<WGM12); // tryb 8bit fast PWM TCCR1B |= (1<<CS11); // prescaler 8 while(1) { for (int16_t i=0; i<1024; i++){ // pętla zwiekszająca wypelnienie OCR1A = i; OCR1B = i; _delay_ms(1); } for (int16_t i=1023; i>=0; i--) { // pętla zmniejszająca wypełnienie OCR1A = i; OCR1B = i; _delay_ms(1); } } } Chciałbym jednak zrozumieć, gdzie mój błąd w rozumowaniu, że do OCRxx mozna wprowadzać takie a nie inne wartości...
farmaceuta Sierpień 1, 2021 Udostępnij Sierpień 1, 2021 Teraz masz ustawiony tryb 10-bit...dla trybu 8-bit, masz miec tylko bity WGM10 i WGM12... 1
Krawi92 Sierpień 1, 2021 Autor tematu Udostępnij Sierpień 1, 2021 (edytowany) Napisze tylko "xD". Do zamknięcia, dzięki Albo dopytam jeszcze o jedną rzecz... Pamiętam z kursu arduino, że do sterowania servo potrzebujemy wygenerować sygnal o okresie 20ms.. czyli o częstotliwości 50Hz. Próbuje to podzielić jednak się nie udaje tak dokladnie Moj cpu taktuje 1MHz, więc najblizsza wartość 1 000 000/prescaler 64/256(8bitowy pwm) i otrzymam ok 61Hz. czyli ok 16ms... Jak to dokladnie skalibrować.. ? Edytowano Sierpień 1, 2021 przez Krawi92
ethanak Sierpień 1, 2021 Udostępnij Sierpień 1, 2021 Przy serwach nie jest specjalnie ważna częstotliwość, a bardziej czas trwania impulsu.
Krawi92 Sierpień 1, 2021 Autor tematu Udostępnij Sierpień 1, 2021 Hmmm Ok, sprawdzałem w nocie czy jest jakas tolerancja, ale sztywno pisze 20ms(50Hz). Spróbuje na trochę większej częstotliwości, zobaczymy czy zadziała
ethanak Sierpień 1, 2021 Udostępnij Sierpień 1, 2021 W której nocie? W powstającym właśnie robocie mam cztery rodzaje różnych (tanich) serw i wszystkie ładnie pracują zarówno na 50, jak i 60 Hz.
farmaceuta Sierpień 1, 2021 Udostępnij Sierpień 1, 2021 Na arduinowym pwm (okolo 490 Hz) servo dziala normalnie...no ale tu sie akurat zakres mniej wiecej miesci w specyfikacji serva jak @ethanak wspomnial...czyli max okres "wlaczenia" to 2ms...gdzie serwo ma miec miedzy 1-2ms...i pozostaly czas do 20ms to przerwa...na tym trybie pwm nie zrobisz tego...musisz inaczej kombinowac..ja to zrobilem tak ze do 1ms dodawalem cos z zakresu 1-2ms i pozniej od 20ms odjalem ten czas wlaczenia i ustawialem pin na wylaczenie i tak w kolko...
ethanak Sierpień 1, 2021 Udostępnij Sierpień 1, 2021 @farmaceuta a z ciekawości - co by było, gdybyś ustawił czas pauzy sztywno na 16 msec i nie bawił się w odejmowanie? Czyli: impuls o określonej zmiennej długości plus stała pauza? Ja jestem leniem i po prostu podpinam sterownik na I2C, nie bardzo mi się chce bawić w generowanie przebiegów na esp32 czy rpi pico (pomijając fakt, że jak masz dziesięć serw i jeszcze parę led to się piny kończą). Ale tam też mogę ustawić częstotliwość...
Krawi92 Sierpień 1, 2021 Autor tematu Udostępnij Sierpień 1, 2021 Yyyy czekajcie bo troche się pogubiłem. Ja napisze jakbym chciał to zrobić a Wy mi powiecie czy Ok Powiedzmy, że sobię ustawie 1Mhz/64 presc/ wybiore 8bitowy fast pwm... .. I pozycją serva sterujemy poprzez zmiane wartosci OCRxx ? Oj bo chyba coś źle mysle
ethanak Sierpień 1, 2021 Udostępnij Sierpień 1, 2021 A co złego się stanie jak spróbujesz? Najwyżej nie wyjdzie
Krawi92 Sierpień 1, 2021 Autor tematu Udostępnij Sierpień 1, 2021 Nie no nic sie nie stanie, zaraz zaczne to skladac. Na arduino to bylo prostackie, nie martwilem sie takimi rzeczami, byla gotowa biblioteka servo.h podlaczalem i działało. Teraz jak to zaczynam poznawać od srodka to jednak trzeba sie nad tym duzo glebiej pochylic.
ethanak Sierpień 1, 2021 Udostępnij Sierpień 1, 2021 (edytowany) No to poczytaj sobie kod biblioteki servo dla Arduino. Naprawdę ciekawe! A zauważ, że biblioteka nie korzysta w ogóle ze sprzętowego pwm, a jakoś jest w stanie w czasie rzeczywistym machać dwunastoma serwami... Edytowano Sierpień 1, 2021 przez ethanak
farmaceuta Sierpień 1, 2021 Udostępnij Sierpień 1, 2021 (edytowany) 47 minut temu, ethanak napisał: @farmaceuta a z ciekawości - co by było, gdybyś ustawił czas pauzy sztywno na 16 msec i nie bawił się w odejmowanie? Czyli: impuls o określonej zmiennej długości plus stała pauza? Bedzie dzialac z roznymi "pauzami"... ja to tak sobie zrobilem jako cwiczenie.. (troszke sie zakrecilem..ja nie odejmuje tylko licze sobie i w odpowiednim momencie robie co mam robic...) #include <avr/io.h> #include <avr/interrupt.h> #include <util/atomic.h> volatile uint16_t x = 0; //uint16 = 50Hz / uint8 = prawie 8 razy wieksza czestotliwosc (x sam sie "przekreci" po 256 przerwaniach volatile uint8_t pw = 0; void setup() { Serial.begin(115200); DDRD |= (1 << PD2); //pin 2 jako wyjscie TCCR2B &= 0x00; TCCR2A &= 0x00; TCCR2A |= (1<<WGM21); //CTC tryb TCCR2B |= (1<<CS21); //preskaler na 8 // TCCR2B |= (1<<CS20); //preskaler na 0 TIMSK2 |= (1<<OCIE2A); //wlaczenie przerwania od porownania OCR2A = 20; //255 max //przypisanie wartosci startowej do licznika sei(); // przerwania globalne wlacz } void loop() { //pw = map(analogRead(A0), 0, 1023, 0, 100); pw++; if(pw == 100) { pw = 0; } delay(50); } ISR (TIMER2_COMPA_vect) { x++; if (x < (100 + pw)) { //1ms + wartosc wypelnienia 0-100 (1ms) PORTD |= (1 << PD2); //stan wysoki } else { if (x < 2000) { //20ms cykl PORTD &= ~(1 << PD2); //stan niski } else { x = 0; // jesli minelo 20ms zacznij od nowa liczyc } } } z tym ze u mnie rozdzielczosc to 0-100...przerwanie nastepuje co 10us, a jak juz wiadomo zakres dla serwa to 1-2ms...ten sam kod lekko zmieniony tak zeby "pauza" byla sztywna tez dziala bez zarzutu, przerwy co 10ms/20ms/50ms a nawet 100ms tez dziala z tym ze przy tych dluzszych przerwach juz widac/slychac wyraznie "kroki"... Edytowano Sierpień 1, 2021 przez farmaceuta
Pomocna odpowiedź
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ę »