Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'enkoder'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino i ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - DIY
    • Projekty - DIY roboty
    • Projekty - DIY (mini)
    • Projekty - DIY (początkujący)
    • Projekty - DIY w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie

Kategorie

  • Quizy o elektronice
  • Quizy do kursu elektroniki I
  • Quizy do kursu elektroniki II
  • Quizy do kursów Arduino
  • Quizy do kursu STM32L4
  • Quizy do pozostałych kursów

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Imię


Strona

Znaleziono 5 wyników

  1. Cześć! Mam problem z enkoderem z Nucleo G491RE. Przy wyświetlaniu na monitorze portu szeregowego, po wykonaniu jednego kroku, wyświetla wartość co dwa(0,2,4...) natomiast podczas powolnego przekręcania w jednej chwili pokazują się normalnie nieparzyste wskazania, gdy enkoder jest w ułożeniu między pełnymi krokami. Niżej kod, ustawiłem w CubeIDE tim2 na prace z enkoderem 20 krokowym co pokrywa się z używanym przeze mnie. char msg[64]; uint32_t count; HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { count = __HAL_TIM_GET_COUNTER(&htim2); sprintf((char*)msg, "Odczyt: %d\n", count); HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 1000); HAL_Delay(200); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
  2. Jako że Trinket jest mały i w miarę w rozsądnej cenie, chciałem wykonać sterowanie jasnością taśmy LED, czy PowerLEDa. W tym celu zmontowałem układ jak na rysunku: Natomiast pojawił się problem z programem. W założeniu obroty w lewo enkodera mają ściemniać, a w prawo rozjaśniać. Do tego chciałem zaimplementować liniowość zmiany jasności LED, bo jak wiadomo zmiana widocznej jasności nie idzie w parze z wielkością wypełnienia PWM. Jako że inni już przede mną temat rozkminiali, to na bazie ich osiągnięć próbuję napisać program. Źródła to: Implementacja liniowej zmiany jasności LED<=> PWM https://gist.github.com/netmaniac/8be83f2e66ae25e949f1 Tu trochę bardziej rozpisana: https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ Oraz projekt na Trinketa - sterowanie głośnością muzyki w PC za pomocą enkodera i portu USB. https://learn.adafruit.com/trinket-usb-volume-knob Z uwagi na to że nie interesuje mnie sterowanie przez port USB to zmodyfikowałem w/w kod z uwzględnieniem liniowości jasności LED: https://pastebin.com/BHe8FKth #include <avr/power.h> #include <avr/pgmspace.h> #define PIN_ENCODER_A 0 #define PIN_ENCODER_B 2 #define TRINKET_PINx PINB #define PWM_PIN 1 #define krok 9 #define CIELPWM(a) (pgm_read_word_near(CIEL8+a)) const uint8_t CIEL8[] PROGMEM ={ 0,1,2,3,4,5,7,9,12,15,18,22,27,32,38,44, 51,58,67,76,86,96,108,120,134,148,163,180, 197,216,235,255}; static uint8_t enc_prev_pos = 0; static uint8_t enc_flags = 0; short int stan_pwm =0; void stepCorrectedPWM(int b) { analogWrite(PWM_PIN,CIELPWM(b)); } void setup() { if(F_CPU == 16000000) clock_prescale_set(clock_div_1); // set pins as input with internal pull-up resistors enabled pinMode(PIN_ENCODER_A, INPUT); pinMode(PIN_ENCODER_B, INPUT); pinMode(PWM_PIN, OUTPUT); digitalWrite(PIN_ENCODER_A, HIGH); digitalWrite(PIN_ENCODER_B, HIGH); analogWrite(PWM_PIN,0); // get an initial reading on the encoder pins if (digitalRead(PIN_ENCODER_A) == LOW) { enc_prev_pos |= (1 << 0); } if (digitalRead(PIN_ENCODER_B) == LOW) { enc_prev_pos |= (1 << 1); } } void loop() { int8_t enc_action = 0; // 1 or -1 if moved, sign is direction uint8_t enc_cur_pos = 0; // read in the encoder state first if (bit_is_clear(TRINKET_PINx, PIN_ENCODER_A)) { enc_cur_pos |= (1 << 0); } if (bit_is_clear(TRINKET_PINx, PIN_ENCODER_B)) { enc_cur_pos |= (1 << 1); } // if any rotation at all if (enc_cur_pos != enc_prev_pos) { if (enc_prev_pos == 0x00) { // this is the first edge if (enc_cur_pos == 0x01) { enc_flags |= (1 << 0); } else if (enc_cur_pos == 0x02) { enc_flags |= (1 << 1); } } if (enc_cur_pos == 0x03) { // this is when the encoder is in the middle of a "step" enc_flags |= (1 << 4); } else if (enc_cur_pos == 0x00) { // this is the final edge if (enc_prev_pos == 0x02) { enc_flags |= (1 << 2); } else if (enc_prev_pos == 0x01) { enc_flags |= (1 << 3); } // check the first and last edge // or maybe one edge is missing, if missing then require the middle state // this will reject bounces and false movements if (bit_is_set(enc_flags, 0) && (bit_is_set(enc_flags, 2) || bit_is_set(enc_flags, 4))) { enc_action = 1; } else if (bit_is_set(enc_flags, 2) && (bit_is_set(enc_flags, 0) || bit_is_set(enc_flags, 4))) { enc_action = 1; } else if (bit_is_set(enc_flags, 1) && (bit_is_set(enc_flags, 3) || bit_is_set(enc_flags, 4))) { enc_action = -1; } else if (bit_is_set(enc_flags, 3) && (bit_is_set(enc_flags, 1) || bit_is_set(enc_flags, 4))) { enc_action = -1; } enc_flags = 0; // reset for next time } } enc_prev_pos = enc_cur_pos; if (enc_action > 0) { // Jaśniej stan_pwm = stan_pwm + krok; } if (enc_action < 0) { //ciemniej stan_pwm = stan_pwm - krok; } if (stan_pwm >= 255) { stan_pwm=255; } if (stan_pwm <=1) { analogWrite(PWM_PIN,0); } else { stepCorrectedPWM(abs(stan_pwm/8)); } } I teraz problem. Kod działa w pewnym zakresie poprawnie. Tzn. gdy zwiększam jasność diody (enkoderem obrót w prawo) jasność wzrasta aż do maksymalnej i dalsze obracanie już jej nie zmienia, ale co ważne "odkręcanie" jasności (obrót w lewo) od razu reaguje zmianą wypełnienia PWM i spadkiem jasności. I ta część działa poprawnie. Ściemniając diody dochodzimy do wygaszenia i... dalsze obracanie w lewo niby już nic nie robi, ale niestety zakres obrotu domyślam się że nie kończy się na wygaszeniu tylko dalej obracając niejako "nabija się licznik" kroków. Czyli np. wykonując po wygaśnięciu diody jeszcze np. 4 obroty enkodera w lewo, musimy wykonać tyle samo w prawo + troszkę by znów dioda zaczęła jaśnieć. Moim założeniem jest to by przedział zmian jasności był 0-255 (tak jak w sygnale PWM), a nie jak obecnie również poniżej zera. Po prostu po wygaszeniu diody, niezależnie ile jeszcze obrotów w lewo wykonamy, jeden krok w prawo powinien już włączać diodę i zwiększać jej jasność. Problem niby trywialny, ale nie potrafię znaleźć gdzie tkwi błąd. Jako mniej eleganckie rozwiązanie, zawsze zostaje reset układu (przycisk w enkoderze), no ale to ostateczność. Coś doradzicie?
  3. Dzień dobry, Robię projekt który realizuje otwieranie i zamykanie drzwiami przesuwnymi w trybie automatycznym i ręcznym, pozycja drzwi ustalana jest za pomocą enkodera oraz przerwań w programie. Pytanie moje brzmi jak ustalić w programie że drzwi podczas zamykania lub otwierania się zatrzymały, czyli enkoder przestał zmieniać wartość. W praktyce chodzi o rewers, czyli jak drzwi np przy zamykaniu natrafią na jakąś przeszkodę to odbiją i zaczną się otwierać. Kombinowałem już na wiele różnych sposobów i jak na razie bezskutecznie. Poniżej załączam kod na jakim działam. #define PinA 2 #define PinB 3 #define AR 5 #define O 6 #define Z 7 #define RSD 8 #define RO 9 #define RZ 10 #define PO 11 #define PZ 12 #define PS 13 volatile long ilosc_impulsow = 0; long x = 30000; long y = (x / 5); long z = (x / 10); void setup() { pinMode(PinA, INPUT); pinMode(PinB, INPUT); pinMode(AR, INPUT); pinMode(O, INPUT); pinMode(Z, INPUT); pinMode(RSD, INPUT); pinMode(RO, INPUT); pinMode(RZ, INPUT); pinMode(PO, OUTPUT); pinMode(PZ, OUTPUT); pinMode(PS, OUTPUT); pinMode(4, OUTPUT); digitalWrite(PO, HIGH); digitalWrite(PZ, HIGH); digitalWrite(PS, HIGH); attachInterrupt(0, blinkA, CHANGE); attachInterrupt(1, blinkB, CHANGE); } void loop() { if (digitalRead(AR) == HIGH && digitalRead(RSD) == LOW && digitalRead(Z) == HIGH && digitalRead(O) == LOW) { while (ilosc_impulsow > 0 ) { digitalWrite(PZ, LOW); digitalWrite(PO, HIGH); digitalWrite(PS, HIGH); } } if (digitalRead(AR) == HIGH && digitalRead(RSD) == LOW && digitalRead(Z) == LOW && digitalRead(O) == HIGH) { while (ilosc_impulsow < x ) { digitalWrite(PZ, HIGH); digitalWrite(PO, LOW); digitalWrite(PS, HIGH); } } if (digitalRead(AR) == LOW && digitalRead(RSD) == HIGH && digitalRead(RZ) == HIGH && digitalRead(RO) == LOW) { while (ilosc_impulsow > 0) { if (ilosc_impulsow > x - z) { digitalWrite(PZ, LOW); digitalWrite(PO, HIGH); digitalWrite(PS, HIGH); } if (ilosc_impulsow > y && ilosc_impulsow < x - z) { digitalWrite(PZ, LOW); digitalWrite(PO, HIGH); digitalWrite(PS, LOW); } if (ilosc_impulsow < y) { digitalWrite(PZ, LOW); digitalWrite(PO, HIGH); digitalWrite(PS, HIGH); } } } if (digitalRead(AR) == LOW && digitalRead(RSD) == HIGH && digitalRead(RZ) == LOW && digitalRead(RO) == HIGH) { while (ilosc_impulsow < x ) { if (ilosc_impulsow < y) { digitalWrite(PZ, HIGH); digitalWrite(PO, LOW); digitalWrite(PS, HIGH); } if (ilosc_impulsow < x - z && ilosc_impulsow > y) { digitalWrite(PZ, HIGH); digitalWrite(PO, LOW); digitalWrite(PS, LOW); } if (ilosc_impulsow > x - z) { digitalWrite(PZ, HIGH); digitalWrite(PO, LOW); digitalWrite(PS, HIGH); } } } else { digitalWrite(PZ, HIGH); digitalWrite(PO, HIGH); digitalWrite(PS, HIGH); } } void blinkA() { if (digitalRead(PinB) == LOW && digitalRead(PinA) == HIGH && ilosc_impulsow > 0) { ilosc_impulsow--; } } void blinkB() { if (digitalRead(PinB) == HIGH && digitalRead(PinA) == LOW && ilosc_impulsow < x) { ilosc_impulsow++; } }
  4. Cześć. Posiadam silnik z wałem o średnicy 14 mm oraz enkoder z wałem o średnicy 6mm. W jaki sposób sprzęgnąć ze sobą te dwa wały?
  5. Cześć. Mam taki problem, mam program do obsługi radia i chcę za pomocą enkodera wybierać odpowiednie stacje. Mam zmienną do której zapisuje pozycje enkodera (wzorowałem się na kursie Forbota z stm32F4) potem za pomocą instrukcji switch sprawdzam tę pozycję i na tej podstawie wykonuję się odpowiedni case który ustawia stację, to nie jest optymalne bo muszę to zapętlać żeby co chwilę sprawdzać pozycję enkodera. Nie wiem czy słusznie, ale wydaje mi się że powinienem tutaj użyć przerwań i jakiejś funkcji callback. Moje pytanie brzmi jak skonfigurować Timer, a następnie co zrobić żeby program wykrywał zmianę pozycji enkodera? Dodam jeszcze że przeglądałem dokumentacje biblioteki HAL i dalej nie jestem w stanie tego zrobić. Mam nadzieję że w miarę jasno to przedstawiłem dołączyłem jeszcze screen aktualnego programu (jest bardzo prymitywny ale sprawdzałem czy wszystko inne działa :D)
×
×
  • 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.