Skocz do zawartości

JacekW

Użytkownicy
  • Zawartość

    6
  • Rejestracja

  • Ostatnio

Reputacja

0 Neutralna

O JacekW

  • Ranga
    2/10

Informacje

  • Płeć
    Mężczyzna
  • Lokalizacja
    Kraków
  • Zawód
    Student
  1. Zastanawiałem się czy zamiast tego nie wystaczyło by dać krańcówki do której po włączeniu zasilania człon dojeżdzałby w celu wyzerownia pozycji. Co o tym myślicie? Pozdrawiam
  2. Hej, dzięki za odpowiedź Zacznę od końca - co do enkoderów magnetycznych, szczerze powiedziawszy nigdy sie nimi nie bawiłem, pozostaje pytanie co do ceny takiej zabawki. Enkoderów optycznych natomiast posiadam dosyć dużo (rozprute drukarki). Potencjometr odrzuciłem z racji ze na uc na którym pracuję posiadam jedynie przetwornik 10 bitowy, a dokładność określenia pozycji na końcu ramienia o długości 40 cm chciałem uzyskać grubo poniżej 1/10 mm. Zewnętrznej karty pomiarowej nie chcę podłączać z racji podniesienia kosztów całego ustrojstwa. Pozdrawiam
  3. Z tym ze właśnie chciałem potencjometr ząstapić enkoderem optycznym...
  4. Witam, od pewnego czasu nosze się z zamiarem zbudowania manipulatora, jednakże prześladuje mnie pewien problem. Posiadam kilka silników DC z przekładnia ślimakową (przełożenie 1/91), jednak nie mam jak dobrać się do wału silnika, dopiero do wyjścia przekładni. Umieszczając jednak enkoder na wyjściu przekładni otrzymam jednak stosunkowo niska dokładność. Dlatego też zastanawiałem się na przyłożeniu do wału jakiejś maleńkiej przekładni planetarnej (1/25 by już dało rade). Czy ktoś ma pomysł gdzie w ogóle można szukać takich rzeczy w rozsądnej cenie? Pozdrawiam
  5. Ooops, zapomniałem wyczyścić komentarze . Zmiana wartości nie rozwiązała, wydaje mi się ze sęk leży w samych przerwaniach. Skróciłem procedure w celu zaobserwowania kiedy wartość będzie inkrementowana, obwarunkowałem tak żeby w teorii przeskoczył cały cykl enkodera (inkrementacja przy stanie 11, wraz z zapaleniem flagi ze inkrementacja nastąpiła, aby nie powtarzając jej w nieskończoność, gaszenie flagi przy stanie 11) __irq void PIOINT3_IRQHandler(void){ if(((LPC_GPIO3 -> DATA)&(mENCODER_CHNLL_A|mENCODER_CHNLL_B)) == mENCODER_CHNLL_A){ if(sEncoder1.ucEncoderReg <1){ sEncoder1.iEncoderPosition++; sEncoder1.ucEncoderReg++; }; } else if(((LPC_GPIO3 -> DATA)&(mENCODER_CHNLL_A|mENCODER_CHNLL_B)) == mENCODER_CHNLL_B){ } else if(((LPC_GPIO3 -> DATA)&(mENCODER_CHNLL_A|mENCODER_CHNLL_B)) == (mENCODER_CHNLL_A | mENCODER_CHNLL_B)){ sEncoder1.ucEncoderReg=0; } else if(((LPC_GPIO3 -> DATA)&(mENCODER_CHNLL_A|mENCODER_CHNLL_B)) == 0 ){ }; LPC_GPIO3 -> IC = (mENCODER_CHNLL_A|mENCODER_CHNLL_B); }; W mainie ustawiłem żeby zapalił diodę po 100 cyklach. Efekt jaki uzyskałem to zapalenie diody może po 4 czy pięciu przejściach... Zawsze pozostaje opcja ze coś w elektronice jest nie halo... Pozdrawiam [ Dodano: 04-11-2012, 02:21 ] Ok, rozwiązałem problem, leżał w skopanym algorytmie. Dziekuję uprzejmie za pomoc
  6. Witam, otóż uwidziało mi się ostatnio pobawić enkoderem optycznym wyprutym z drukarki. Stwierdziłem ze kod napisze na przerwaniach z GPIO (żeby nie zamulać procą ciągłym sprawdzaniem stanu) Umyślało mi się przerwania wyzwalać na oba zbocza. Z racji ze debugger Keil'a nie bardzo radzi sibie z symulowaniem tychże przerwań, w celu sprawdzenia jak działają, napisałem krótka obsługę przerwań zapalającą diodę w zależności od kanału z którego system przyjmuje przerwania. Jak dotad działało, wraz z odpalaniem, kolejnego kanału, następowała zmiana świecenia się diodek zestawu. Kod obsługi przerwania poniżej: __irq void PIOINT3_IRQHandler(void){ if(LPC_GPIO3 -> MIS == mENCODER_CHNLL_A){ LedCtrl(LED1); LPC_GPIO3 -> IC = mENCODER_CHNLL_A; } else if(LPC_GPIO3 -> MIS == mENCODER_CHNLL_B){ LedCtrl(LED2); LPC_GPIO3 -> IC = mENCODER_CHNLL_B; } else if(LPC_GPIO3 -> MIS == (mENCODER_CHNLL_A | mENCODER_CHNLL_B)){ LPC_GPIO3 -> IC = (mENCODER_CHNLL_A|mENCODER_CHNLL_B); }; }; Problem zaczął pojawiać, gdy stwierdziłem ze zliczę ilość zapalania się kanału A enkodera wraz z obrotem, napisałem bardzo prostą funkcję: volatile int iCtr = 0; __irq void PIOINT3_IRQHandler(void){ if(LPC_GPIO3 -> MIS == mENCODER_CHNLL_A){ LPC_GPIO3 -> IC = mENCODER_CHNLL_A; iCtr ++; } else if(LPC_GPIO3 -> MIS == mENCODER_CHNLL_B){ LPC_GPIO3 -> IC = mENCODER_CHNLL_B; } else if(LPC_GPIO3 -> MIS == (mENCODER_CHNLL_A | mENCODER_CHNLL_B)){ LPC_GPIO3 -> IC = (mENCODER_CHNLL_A|mENCODER_CHNLL_B); }; if(iCtr >= 1000){ LedCtrl(LED1); }; }; Z racji ze przerwania odpalały się na zbocza, naiwnie wierzyłem ze obracając w tę samą stronę stan w którym wartość iCtr jest inkrementowana, wyzwoli się raz na impuls enkodera. Efekt był taki ze może po 30 impulsach enkodera zapalała się dioda sygnalizująca osiągniecie przez licznik wartości 1000... W tym miejscu nadmienię, że sam enkoder połączony jest z uC buforem hc573N(kanał) enkodera podłaczony równolegle do 2 wejść scalaka), jedno wyjście scalaka podpięte są przez dzielnik(2 rezystory po jedem MOhm)dając na wyjściu 2,5 V które leci do enkodera. 2 wyjście bufora podpięte do diody LED, przez co umożliwiłem sobie obserwowanie stanu enkodera. Sam enkoder połaczony jest z płytką bufora metrowej długości przewodem, natomiast płytka z zestawem uruchomieniowym za pomocą kabelków goldpin. Z racji ze działanie programu sypało się już w tym miejscu napisana przezemnie funkcja obsługi enkodera działała sobie jak chciała... // Encoder Reg Values #define mENCODER_REG_CHANNEL_A 0x01 #define mENCODER_REG_CHANNEL_B 0x02 #define mENCODER_CHNG_VAL 0x04 struct sEncoder{ int iEncoderPosition; char ucEncoderReg; /* * Bit Function * 0 Encoder Channel A * 1 Encoder Channel B * 2 Encoder Change Value */ }; __irq void PIOINT3_IRQHandler(void){ if(LPC_GPIO3 -> MIS == mENCODER_CHNLL_A){ if(sEncoder1.ucEncoderReg == mENCODER_REG_CHANNEL_A|mENCODER_CHNG_VAL){ sEncoder1.iEncoderPosition++; sEncoder1.ucEncoderReg &= ~mENCODER_CHNG_VAL; }; sEncoder1.ucEncoderReg = mENCODER_REG_CHANNEL_A; LPC_GPIO3 -> IC = (mENCODER_CHNLL_A); } else if(LPC_GPIO3 -> MIS == mENCODER_CHNLL_B){ if(sEncoder1.ucEncoderReg == mENCODER_REG_CHANNEL_B|mENCODER_CHNG_VAL){ sEncoder1.iEncoderPosition--; sEncoder1.ucEncoderReg &= ~mENCODER_CHNG_VAL; }; sEncoder1.ucEncoderReg = mENCODER_REG_CHANNEL_B; LPC_GPIO3 -> IC = (mENCODER_CHNLL_B); } else if(LPC_GPIO3 -> MIS == (mENCODER_CHNLL_A | mENCODER_CHNLL_B)){ if(sEncoder1.ucEncoderReg == mENCODER_REG_CHANNEL_A){ sEncoder1.iEncoderPosition--; } else if(sEncoder1.ucEncoderReg == mENCODER_REG_CHANNEL_B){ sEncoder1.iEncoderPosition++; }; sEncoder1.ucEncoderReg |=mENCODER_CHNG_VAL; LPC_GPIO3 -> IC = (mENCODER_CHNLL_A|mENCODER_CHNLL_B); } else if(LPC_GPIO3 -> MIS == (LPC_GPIO3 -> MIS)&~(mENCODER_CHNLL_A | mENCODER_CHNLL_B)){ sEncoder1.ucEncoderReg &= ~(mENCODER_REG_CHANNEL_A|mENCODER_REG_CHANNEL_B|mENCODER_CHNG_VAL); LPC_GPIO3 -> IC = (mENCODER_CHNLL_A|mENCODER_CHNLL_B); }; }; Sama inicjalizacja przerwań : #define mENCODER_CHNLL_A 0x00000010 #define mENCODER_CHNLL_B 0x00000020 #define mCLEAR_INTERRUPT_REGISTER 0x00000001 #define mENABLE_CLK_GPIO 0x00000040 #define mPULL_DOWN_ENABLE 0x00000000 #define mPORT_ENC_BITS 0x00000030 void Init_Encoder(void){ LPC_SYSCON -> SYSAHBCLKCTRL |= mENABLE_CLK_GPIO; LPC_IOCON -> PIO3_4 = mPULL_DOWN_ENABLE; LPC_IOCON -> PIO3_5 = mPULL_DOWN_ENABLE; LPC_GPIO3 -> DATA &= ~mPORT_ENC_BITS; LPC_GPIO3 -> DIR &= ~( mENCODER_CHNLL_A | mENCODER_CHNLL_B ); LPC_GPIO3 -> IS &= ~( mENCODER_CHNLL_A | mENCODER_CHNLL_B ); //GPIO as edge sensitive LPC_GPIO3 -> IBE |= (mENCODER_CHNLL_A | mENCODER_CHNLL_B );//Both edges trigerring an interrupt LPC_GPIO3 -> IE = mENCODER_CHNLL_A | mENCODER_CHNLL_B; NVIC_EnableIRQ(EINT3_IRQn); }; Podsumowując, zastanawiam się gdzie spaprałem kod + to czy przypadkiem nie spaprałem dodatkowo elektroniki. dodam ze na przewodzie enkodera nie ma dławika. Gdyby ktoś był na tyle uprzejmy przebić się przez mój post i podać kilka sugestii byłbym dozgonnie wdzięczny. Pozdrawiam
×
×
  • Utwórz nowe...