Skocz do zawartości

Elvis

Użytkownicy
  • Zawartość

    2596
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    189

Wszystko napisane przez Elvis

  1. Sorki, jeśli źle zrozumiałem. Nie chodziło mi o piekarnik, tylko o piec do montażu elementów smd.
  2. SeerKaza, to ty gadasz głupoty. Obudowy TQFP64 (SMD, raster 0.5mm) da się lutować zwykłą lutownicą. Ja nie próbowałem, ale widziałem jak inni lutują - więc da się. Natomiast BGA raczej nie da się zlutować w domowych warunkach. Gorące powietrze nie podgrzeje wszystkich padów równomiernie. Poza tym konieczna byłaby kontrola temperatury. O ile wiem konieczny jest piec. [ Dodano: 29 Mar 10 09:25 ] Jednak ludzie wszystko domowymi metodami zrobią: http://www.elektroda.pl/rtvforum/topic73518.html Ale i tak łatwiej poradzić sobie z LQFP. Tak, czy inaczej jest to dużo wyższa szkoła jazdy niż AVR, nawet w smd. Samo wykonanie płytki pod taki procesor to trudna sprawa. Więc trzeba zamawiać pcb - a to kosztuje i trwa. Dla BGA konieczne są płytki wielowarstwowe, więc kosztuje jeszcze więcej.
  3. Właśnie błędy konkretnych procesorów mi chodziło, nie o cały rdzeń. Ale to w każdym procesorze się zdarza. Jak chodzi o stm32lib to jest rzeczywiście super łatwo programować, niestety kosztem wydajności. Chciałem sprawdzić, czy na prawdę I/O mają prędkość 50MHz. Przy stm32lib prędkość max to ok. 2-3MHz. Dopiero bezpośredni zapis do rejestrów + maksymalna optymalizacja dało 50MHz. Ale i tak biblioteka bardzo przyjemna.
  4. Bardzo polecam cortex-m3. Co prawda nie są pozbawione błędów, ale wiele rozwiązań jest udoskonalonych w porównaniu z ARM7. Testowałem STM32 oraz NXP (LPC176x) i osobiście wolę NXP - głównie ze względu na doświadczenie w programowaniu LPC2148. Natomiast dużym plusem STM32 jest standardowa biblioteka oferowana przez producenta. Jak chodzi o kompilatory, to coraz lepiej radzi sobie z nowymi procesorami gcc. Polecam środowisko Rowley (CorssStudio) - bardzo łatwo rozpocząć przygodę z nowymi procesorami. Natomiast jak chodzi o darmowe narzędzia, to CortexM3 mają standardową bibliotekę obsługi dostarczaną przez ARM oraz STM32 mają dedykowaną bibliotekę producenta. Główny problem moim zdaniem to obudowy - raster 0.5mm nie jest łatwy w domowych warunkach. Oczywiście tylko SMD, przewlekanych procesorów brak Najtańsze moduły z zalutowanymi procesorami ma w ofercie (chyba) propox. jednak taki moduł to już wydatek rzędu 90-100zł.
  5. To ja głosuję, że winny jest brak diód w mostku. Kiedyś testowałem silnik krokowy w podobnym układzie - indukowało się ponad 100V... Ale najlepiej sprawdzić podłączając diody, jak zacznie działać, to będzie odpowiedź.
  6. Ja bym proponował jeszcze raz sprawdzić, czy to nie problem z zasilaniem. Spróbuj odłączyć silniki i ręcznie "pochodzić" chwilę robotem. Jeśli nie będzie się resetował, to może jednak skoki zasilania - kondensatory powinny pomóc. Jak nadal będzie problem, to proponuję bardzo skrócić program - najpierw zrobić jazdę bez czujników - np. 2sek prosto, 2 sek w prawo 2 sek w lewo. Póżniej dodać obsługę 1 czujnika i zobaczyć czy działa. Dalej kolejno dodawać następne czujniki - jak się popsuje to będzie wiadomo gdzie szukać błędu.
  7. Strasznie kombinujesz. Na pewno nie byłoby łatwo. Gdybyś po prostu podłączył tranzystor pnp do wyjścia procesora, to niezależnie od stanu linii procesora tranzystor by przewodził. Musiałbyś mieć wyjście open-colector oraz rezystor podciągający. Z open-colector można sobie jeszcze poradzić (sztuczka jak przy i2c, zamiast wystawiania 1, zmiana kierunku działania portu), ale pull-up nie wiem, czy nie byłby szkodliwy dla procesora. Ja polecam wersję: bipolarny npn, polowy z kanałem P.
  8. co do bipolarnych to tak, ale BUZ11 jest ma kanał N więc nie polecam.
  9. Na mój gust to przepełniasz stos. Funkcja Jedz wywołuje np. Prosto, następnie prosto wywołuje Jedz. Zamiast Call używaj Goto (tak przynajmniej jest w Basic-u, bo Bascom-a nigdy nie używałem). Jeśli używasz Call, to na końcu procedury musi być z niej powrót (pewnie przez Return).
  10. Moim zdaniem polecony IRLZ44 nie najlepiej się nadaje. Nie wiem jaki schemat chcesz zastosować, ale najlepszym rozwiązaniem jest zaproponowane przez madman07-a. Czyli tranzystor npn, którym wysterujesz MOSFET. Wtedy nie jest potrzebny model "L". IRLZ44 się nie nadaje, bo potrzebny będzie MOSFET z kanałem P, a nie N. Takie rozwiązanie sprawdzałem na 12V, działa bardzo dobrze. Jeśli zastosujesz MOSFET z kanałem N, to obie części układu nie będą miały wspólnej masy. Może to być akceptowalne, i wtedy IRLZ44 nie stanowi problemu.
  11. A jaki prąd płynie przez to 24V? Bo jeśli przewidujesz większy pobór prądu oraz rzadkie przełączanie, to może zwykły przekaźnik?
  12. Ponieważ sporo osób pyta o kody źródłowe, załączam kody dla RFM12 oraz HM-T868S. RFM12B_T.zip RFM12B_R.zip HM_FSK.zip
  13. Nie chciało mi się wierzyć, że enum nie działa. I słusznie, pobrałem kompilator arduino i sprawdziłem. Działa dokładnie jak w C. Nie lubię wklejać kodów na forum, ale tym razem zrobię wyjątek: #include <LiquidCrystal.h> //biblioteka do obslugi LCD enum { KIERUNEK_STOP, KIERUNEK_PROSTO, KIERUNEK_W_LEWO, KIERUNEK_OW_LEWO, KIERUNEK_W_PRAWO, KIERUNEK_OW_PRAWO }; LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //LCD podpięty pod te piny int irLPin = 0; // Analog PIN 0; Left IR int irCPin = 1; // Analog PIN 1; Center IR int irRPin = 2; // Analog PIN 2; Right IR int irLval; // Left IR int irCval; // Center IR int irRval; // Right IR const int lewy1Pin = 32; // lewy silnik 32 const int lewy2Pin = 34; // lewy silnik 34 const int prawy1Pin = 36;// prawy 36 const int prawy2Pin = 38;//prawy 36 const int lewyonPin = 8; // wlacz lewy H-bridge const int prawyonPin = 9; // wlacz prawy H-bridge const int ledPin = 13; // LED int j; int czulosc = 500; //czulosc czujnikow IR const int czujnik = 5; int dystans = 0; int i; int PWM1 = 127; //wypelnienie PMW max 255 tu 1/2 max int PWM2 = 64; //wypelnienie PMW tu 1/4 max int kierunek = KIERUNEK_PROSTO; // kierunek jazdy robota void setup() { lcd.begin(16, 2); // inicjuj lcd 16x2 pinMode(irLPin, INPUT); // ustawienie pinu czujnikow jako wejscia pinMode(irCPin, INPUT); pinMode(irRPin, INPUT); pinMode(ledPin, OUTPUT); // ustawienie pinu LED jako wyjscia // ustawienia wyjsc silnika pinMode(lewy1Pin, OUTPUT); pinMode(lewy2Pin, OUTPUT); pinMode(prawy1Pin, OUTPUT); pinMode(prawy2Pin, OUTPUT); pinMode(lewyonPin, OUTPUT); pinMode(prawyonPin, OUTPUT); pinMode(czujnik, INPUT); // ustawienie wyjscia SHARP // wlaczenie silnikow lewy,prawy analogWrite(lewyonPin, 255); //wlacz prawy z pelnym wypelnieniem PWM analogWrite(prawyonPin, 255);//wlacz lewy z pelnym wypelnieniem PWM } void loop() { Look(); decyzja(); sterowanie(); LCD(); //sprawdzanie(); } void Look() //sprawdz czujniki { for (j =0; j <3; j++) { irLval = analogRead(irLPin); irCval = analogRead(irCPin); irRval = analogRead(irRPin); dystans = analogRead(czujnik); //oczytaj warotsc z SHARP } //delay(50); } void jedz() // jedz do przodu { analogWrite(lewyonPin, PWM1); //wlacz prawy analogWrite(prawyonPin, PWM1);//wlacz lewy digitalWrite(lewy1Pin, LOW); // do przodu sil1 digitalWrite(lewy2Pin, HIGH); // do przodu sil1 digitalWrite(prawy1Pin, LOW); // do przodu sil2 digitalWrite(prawy2Pin, HIGH);// do produ sil2 } void wstecz()//jedz w tyl { analogWrite(lewyonPin, PWM1); //wlacz prawy analogWrite(prawyonPin, PWM1);//wlacz lewy digitalWrite(lewy1Pin, HIGH); // set leg 1 of the H-bridge high digitalWrite(lewy2Pin, LOW); // set leg 2 of the H-bridge low digitalWrite(prawy1Pin, HIGH); // set leg 1 of the H-bridge high digitalWrite(prawy2Pin, LOW); } void tyllewo() { analogWrite(lewyonPin, PWM1); //wlacz prawy analogWrite(prawyonPin, PWM2);//wlacz lewy digitalWrite(lewy1Pin, HIGH); // set leg 1 of the H-bridge high digitalWrite(lewy2Pin, LOW); // set leg 2 of the H-bridge low digitalWrite(prawy1Pin, HIGH); // set leg 1 of the H-bridge high digitalWrite(prawy2Pin, LOW); } void tylprawo() { analogWrite(lewyonPin, PWM2); //wlacz prawy analogWrite(prawyonPin, PWM1);//wlacz lewy digitalWrite(lewy1Pin, HIGH); // set leg 1 of the H-bridge high digitalWrite(lewy2Pin, LOW); // set leg 2 of the H-bridge low digitalWrite(prawy1Pin, HIGH); // set leg 1 of the H-bridge high digitalWrite(prawy2Pin, LOW); } void owlewo() //skrec ostro w prawo { analogWrite(lewyonPin, PWM1); //wlacz prawy analogWrite(prawyonPin, 0);//wlacz lewy digitalWrite(lewy1Pin, LOW); // przod digitalWrite(lewy2Pin, HIGH); // przod digitalWrite(prawy1Pin, LOW); // tyl digitalWrite(prawy2Pin, HIGH); // tyl } void wlewo() //skrec w prawo { analogWrite(lewyonPin, PWM1); //wlacz prawy analogWrite(prawyonPin, PWM2);//wlacz lewy digitalWrite(lewy1Pin, LOW); // przod digitalWrite(lewy2Pin, HIGH); // przod digitalWrite(prawy1Pin, LOW); // tyl digitalWrite(prawy2Pin, HIGH); // tyl } void wprawo() // skrec w lewo { analogWrite(lewyonPin, PWM2); //wlacz prawy analogWrite(prawyonPin, PWM1);//wlacz lewy digitalWrite(lewy1Pin, LOW); // tyl digitalWrite(lewy2Pin, HIGH); // tyl digitalWrite(prawy1Pin, LOW); // przod digitalWrite(prawy2Pin, HIGH); // przod } void owprawo() // skrec ostro w lewo { analogWrite(lewyonPin, 0); //wlacz prawy analogWrite(prawyonPin, PWM1);//wlacz lewy digitalWrite(lewy1Pin, LOW); // tyl digitalWrite(lewy2Pin, HIGH); // tyl digitalWrite(prawy1Pin, LOW); // przod digitalWrite(prawy2Pin, HIGH); // przod } void stoj() { analogWrite(lewyonPin, 0); //wlacz prawy analogWrite(prawyonPin, 0);//wlacz lewy digitalWrite(lewy1Pin, LOW); // tyl stop digitalWrite(lewy2Pin, LOW); // tyl stop digitalWrite(prawy1Pin, LOW); // przod stop digitalWrite(prawy2Pin, LOW); // przod stop } void LCD() { lcd.setCursor(0,0); lcd.print("L"); lcd.print(irLval); //lcd.setCursor(0,5); lcd.print("C"); lcd.print(irCval); //lcd.setCursor(0,13); lcd.print("R"); lcd.print(irRval); //delay(100); //lcd.setCursor(0,0); //lcd.print("L "); //lcd.setCursor(0,5); //lcd.print("C "); //lcd.setCursor(0,13); //lcd.print("R "); //delay(100); lcd.setCursor(1,1); lcd.print("Dystans:"); // wyświetl wartość dla dystansu lcd.print(dystans); delay(100); } void decyzja () { if ((irLval >czulosc) && (irCval <czulosc) && (irRval >czulosc)) { kierunek = KIERUNEK_PROSTO; } else if((irLval <czulosc) && (irCval >czulosc) && (irRval >czulosc)) { kierunek = KIERUNEK_W_PRAWO; } else if((irLval >czulosc) && (irCval >czulosc) && (irRval <czulosc)) { kierunek = KIERUNEK_W_LEWO; } else if((irLval <czulosc) && (irCval <czulosc) && (irRval >czulosc)) { kierunek = KIERUNEK_OW_PRAWO; } else if((irLval >czulosc) && (irCval <czulosc) && (irRval <czulosc)) { kierunek = KIERUNEK_OW_LEWO; } if((irLval >czulosc) && (irCval >czulosc) && (irRval >czulosc)) { kierunek = KIERUNEK_STOP; } } void sterowanie() { static int kierunek_poprzedni = KIERUNEK_STOP; // poprzedni kierunek jazdy if (kierunek_poprzedni==kierunek) return; switch (kierunek) { case KIERUNEK_PROSTO: jedz(); break; case KIERUNEK_W_LEWO: wlewo(); break; case KIERUNEK_OW_LEWO: owlewo(); break; case KIERUNEK_W_PRAWO: wprawo(); break; case KIERUNEK_OW_PRAWO: owprawo(); break; case KIERUNEK_STOP: default: stoj(); break; } kierunek_poprzedni=kierunek; } [ Dodano: 22 Mar 10 10:02 ] Nigdy wcześniej arduino nie używałem, ale jak już pobrałem postanowiłem sprawdzić, co to takiego. Więc jest to najzwyklejsze C, kompilator to najzwyklejszy WinAVR, czyli gcc. W katalogu arduino-0018\hardware\tools\avr jest cały pakiet. Czyli jak ktoś poznał arduino to przy okazji nauczył się C. Poza WinAVR arduino daje jakieś IDE napisane w Javie (ja wolę AVRStudio, ale co kto lubi). Najciekawsze są biblioteki. W katalogu arduino-0018\libraries są gotowe biblioteki do obsługi LCD, eeprom, servo, silnika krokowego i wielu innych. Napisane są w standardowym C++, więc nawet jeśli ktoś nie planuje używać arduino może te biblioteki wykorzystać.
  14. To nieprawda. ASCII jest 7-bitowe, jeśli nie wierzysz sprawdź na wikipedii. Co prawda używa się 8 bitowego kodowania, ale to już nie jest ascii. Kody >127 nie należą do standardu.
  15. W C++ można pominąć enum przed deklaracją zmiennej, więc kod był w C++ poprawny. Niestety w C trzeba powtarzać enum przed typem zmiennej.
  16. Nie podłączaj nigdy bezpośrednio - zawsze przez rezystor 100-470ohm.
  17. Jeśli już to: enum NKierunkek kierunek = KIEUNEK_PROSTO; Ale sprawdzałem pod gcc i keil enum {X1, X2 }; i kompilowało bez problemu.
  18. Jest jak najbardziej poprawna. Ma tylko taką wadę, że za rok ciężko sobie przypomnieć co znaczy "kierunek = 2". Jeśli enum nie działa można wykorzystać instrukcję #define, czyli #define KIERUNEK_PROSTO 1 #define KIERUNEK_STOP 2 #define KIERUNEK_PRAWO 3 #define KIERUNEK_LEWO 4
  19. Ja bym proponował małą zmianę - chyba nieco lepiej byłoby mieć rezystory R1-R5 (podciągające) na płytce z czujnikami (o ile tylko jest miejsce). Po pierwsze można wtedy przetestować płytkę czujników zwykłym multimetrem (będzie sygnał napięciowy). Po drugie płytkę można będzie łatwo wykorzystać np. w kolejnym robocie.
  20. Tak jak woltomierz, czyli równolegle. Ale na wszelki wypadek sprawdź co piszą w instrukcji.
  21. Możesz podzielić funkcję sterowanie() na dwie części. Oddzielnie podejmować decyzję (logika programu) gdzie jechać, oddzielnie wykonywać polecenie (sterowanie silnikiem). Dodatkowo warto przechowywać ostatnią decyzję w zmiennej np. globalnej. Czyli: 1) zdefiniuj zmienną globalną: int kierunek = KIERUNEK_PROSTO; ; 2) zdefiniuj wartości dla zmiennej kierunek: enum { KIERUNEK_PROSTO, KIERUNEK_STOP, KIERUNEK_PRAWO, KIERUNEK_LEWO, ... }; 3) zamiast funkcji sterowanie() utwórz 2 funkcje: ustal_kierunek() i steruj_silnikiem() void ustal_kierunek() { if ((irLval >czulosc) && (irCval <czulosc) && (irRval >czulosc)) { kierunek = KIERUNEK_PROSTO; } else if((irLval <czulosc) && (irCval >czulosc) && (irRval >czulosc)) { kierunek = KIERUNEK_PRAWO; } ... } void steruj_silnikiem() { switch (kierunek) { case KIERUNEK_PROSTO: jedz(); break; case KIERUNEK_STOP: .... } } W takiej wersji, jeśli funkcja ustal_kierunek() nie zmieni kierunku, robot będzie jechał zgodnie z poprzednią decyzją. A przy okazji masz oddzielony kod podejmujący decyzje od wykonawczego.
  22. Chyba wiem dlaczego nie działa. Trzeba zdefiniować stałą STARTUP_FROM_RESET. W oknie "Project Explorer" kliknij prawym klawiszem na projekcie i wybierz Properties. Następnie poszukaj "Preprocessor Options"->"Preprocessor Definitions" i dodaj STARTUP_FROM_RESET. [ Dodano: 18 Mar 10 09:47 ] Dwa słowa wyjaśnienia. Przed uruchomieniem funkcji głównej programu, czyli main() dzieje się całkiem sporo. Warto otworzyć plik "Philips_LPC210X_Startup.s" - jest tworzony przez CrossStudio podczas zakładania projektu. W tym pliku zdefiniowany jest wektor przerwań oraz procedura obsługi reset-u (czyli prawdziwy początek programu). Linia 150 i kolejne definiuje od czego nasz program się rozpoczyna: reset_handler_address: #ifdef STARTUP_FROM_RESET .word reset_handler #else .word reset_wait #endif Czyli jeśli nie ma zdefiniowanej stałej STARTUP_FROM_RESET po resecie procesor przechodzi do fragmentu reset_wait gdzie znajduje się nieskończona pętla. Dopiero jeśli zdefiniujemy STARTUP_FROM_RESET po resecie następuje skok do reset_handler i program rozpoczyna się normalnie (reset_handler m.in. konfiguruje PLL, dostęp do pamięci Flash). Takie działanie może wydawać się nieco dziwne, ale jest bardzo przydatne podczas pracy z JTAG-iem. W procesorach ARM (nie wiem czy wszystkich, LPC na pewno) JTAG nawiązuje połączenie z procesorem gdy ten już pracuje. Czyli przez JTAG wykonywany jest reset, procesor wykonuje kawałek programu i dopiero wtedy JTAG zatrzymuje jego działanie (oraz uruchamia program ponownie, tym razem z debuggerem). Oznacza to, że początek programu wykonywany jest 2 razy, a co gorsze jeśli na początku programu jest coś co wyłączy JTAG nie będzie możliwości pracy z JTAG-iem, nie będzie można nawet wgrać innego programu (pozostaje możliwość przez RS232). Aby temu zapobiec CrossStudio domyślnie tworzy nieskończoną pętlę na początku programu. Gdy nasz program jest już przetestowany i gotowy, można zdefiniować stałą STARTUP_FROM_RESET i pozbyć się pętli przed programem.
  23. Pamiętaj, żeby odłączyć przewód programujący - inaczej procesor będzie w trybie bootloadera. Czyli spróbuj tak: odłącz wszystkie przewody od płytki, następnie podłącz tylko zasilanie. [ Dodano: 17 Mar 10 10:53 ] Szkoda, że nie uruchomiłeś JTAG-a. Łatwiej jest diagnozować błędy. Na początek można uruchomić program w trybie debug i sprawdzić czy w ogóle działa. Przy okazji - na pewno masz LED podpięty tam gdzie był w module olimex-a?
  24. Prawdopodobnie najwięcej zajmuje biblioteka liczb zmiennopozycyjnych. Lepszym rozwiązaniem jest stablicowanie wyników, a następnie interpolowanie. Dokładność jest oczywiście mniejsza, ale powinna wystarczyć. Najprościej jest zrobić tak: 1) wybierasz liczbę punktów (czyli dokładność), np. 32 2) dzielisz przedział wyników na 32 równe (tak jest najłatwiej) części 3) w excelu wyliczasz ile wynosi wynik dla każdego przedziału 4) wyniki wstawiasz do programu jako tablicę liczb unsigned int Następnie odczytujesz dane z czujnika (dana[1]) i na jej podstawie wybierasz gotowy wynik z tablicy. Lepszą dokładność uzyskasz dodając interpolację wyników.
  25. Jakby co to mam program w C. W bascomie nie programuję, ale pewnie jest jeszcze łatwiej - wystarczy w module podłączonym do HM-T868S wysłać dane na uart, a w podłączonym do HM-R868S odczytać. HM_FSK.zip
×
×
  • Utwórz nowe...