Skocz do zawartości

Elvis

Użytkownicy
  • Zawartość

    2587
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    189

Posty napisane przez Elvis


  1. Jeśli znasz C++ łatwo będzie Ci przejść na C. Jest trochę drobnych różnic, ale ogólnie C++ to nadzbiór C. Więc wystarczy zrezygnować z klas, przestrzeni nazw, czy szablonów i program bez problemu skompiluje się w C.

    Jak dla mnie główna różnica to konieczność deklarowania zmiennych na początku bloku oraz brak biblioteki STL.

    Są za to kompilatory C++ na uC. Nie polecam, bo kod bywa bardzo długi, ale jak ktoś lubi C++ to można używać.


  2. Skoro generuje skrypt, to znaczy, że sam php działa.

    Proponuję usunąć killall ze skryptu, wykonać i sprawdzić czy proces minicom będzie uruchomiony.

    Jeśli tak to wiadomo, że chociaż minicom startuje.

    Kolejny test to byłoby sprawdzenie, czy coś przez COM wysyła. Jeśli masz 2 porty w komputerze, można połączyć ze sobą (skrosowane oczywiście) i zobaczyć czy coś wysyła.

    Jeśli nie masz 2 portów, to trzeba poszukać jakiegoś emulatora COM. Pod windows polecam com0com, pod linuxa niestety nie wiem co można wykorzystać.

    Możesz jeszcze spróbować wpisać ścieżki bezwzględne do wszystkich plików, ale nie wiem czy to pomoże.


  3. To jeśli chodzi o ULN2065 trzeba pamiętać o diodach zabezpieczających. Te które są wbudowane w układ - trzeba je podłączyć (piny 1 i 8). Inaczej bardzo duże napięcia będą się indukowały przy przełączaniu.

    I sterując nie można wykorzystywać 2 uzwojeń jednocześnie (tylko sterowanie pełnokrokowe). Traci się w ten sposób 40% mocy, ale inaczej przez mostek popłynąłby prąd 2x 1,5A.

    Ogólnie polecam L298, chociaż na początek można sprawdzić ULN2065.


  4. Do sterowania proponuję wykorzystać mikrokontroler.

    Samo sterowanie silnikiem przez mostek H (żeby można było w obie strony kręcić silnikiem), np. popularnym na forum L293.

    Do tego dodać 2 krańcówki (mikroprzełączniki na końcach). Gdy peryskop dojedzie do mikroprzełącznika, procesor będzie wyłączał silnik.

    Ogólnie układ jak w prostym robocie, wszystko opisywane wielokrotnie na forum. Jedyna różnica, to układ czujników - zamiast po bokach robota, to przy peryskopie.


  5. Możliwości sterowania silnika krokowego jest mnóstwo.

    Można dać ULN2803 i po 2 kanały równolegle, jednak może nie wystarczyć do Twojego silnika, więc może inny ULN, np. ULN2065B.

    Dla większych prądów najlepiej dać 4 tranzystory MOSFET. Przykładowo IRFL024 - dostępne w TME, cena niewiele ponad 1 zł za szt.

    Inny problem to sterowanie silnikiem krokowym. Zasilanie go prądem 1,5A jest bez sensu. Lepiej dać układ, w którym prąd można regulować.

    Proste rozwiązanie to np. L297 + L298.

    • Pomogłeś! 1

  6. Jak chodzi o czujniki, to moim zdaniem optyczne od myszki odpadają. Muszą być bardzo blisko podłoża, żeby poprawnie działały. W przypadku poduszkowca to raczej nierealne. Poza tym podłoże musi być idealnie płaskie - a po co poduszkowiec, żeby po stole latać.

    Może warto pomyśleć o czujnikach ultradźwiękowych? Są dobre na większe odległości.


  7. Raczej nie spaliłeś, tylko źle ci doradzili.

    Optotriak będzie działał tylko z prądem przemiennym. Triak uruchamiany jest prądem bramki, niestety do wyłączenia konieczne jest wyłączenie zasilania. W przypadku prądu przemiennego triak wyłączany jest przy przejściu przez zero. Jeśli podłączyłeś do prądu stałego, to raz włączony będzie przewodzić, aż do wyłączenia zasilania.


  8. Uruchomiłem program na płytce olimex-a z atmega128 (http://olimex.com/dev/pdf/AVR/AVR-MT-128-SCH-REV-A.pdf).

    Konieczne były drobne zmiany, ale działa:

        // PROGRAM OBSLUGUJACY WYSWIETLACZ LCD (2X16 ZNAKOW) //
       // Atmega16, 4Mhz, //
       /////////////////////////////////////////////////////
    
       //--------------------------------------------------
       // Biblioteki:
    
       #include <avr/io.h>
       #include <inttypes.h>
    
    	#define F_CPU 4000000
    	#include <util/delay.h>
    
       //--------------------------------------------------
    
       // Makra upraszczajace dostep do portow:
    
       #define PORT(X) XPORT(X) //podanie w programie: PORT(D) zinterpretuje jako "PORTD"
       #define XPORT(X) (PORT##X)
    
       #define PIN(X) XPIN(X)
       #define XPIN(X) (PIN##X)
    
       #define DDR(X) XDDR(X)
       #define XDDR(X) (DDR##X)
    
       //--------------------------------------------------
       // Definicje wyprowadzen:
    
       #define LCD_RS 0
       #define LCD_RSPORT C
    	#define LCD_RW 1
    	#define LCD_RWPORT C
       #define LCD_E 2
       #define LCD_EPORT C
       #define LCD_DPORT C
       #define LCD_D4 4
    
       //--------------------------------------------------
       // Komendy sterujace wyswietlaczem:
    
       #define LCDC_CLS 0x01
       #define LCDC_HOME 0x02
       #define LCDC_MODE 0x04
       #define LCDC_MODER 0x02
       #define LCDC_MODEL 0
       #define LCDC_MODEMOVE 0x01
       #define LCDC_ON 0x08
       #define LCDC_ONDISPLAY 0x04
       #define LCDC_ONCURSOR 0x02
       #define LCDC_ONBLINK 0x01
       #define LCDC_SHIFT 0x10
       #define LCDC_SHIFTDISPLAY 0x08
       #define LCDC_SHIFTR 0x04
       #define LCDC_SHIFTL 0
       #define LCDC_FUNC 0x20
       #define LCDC_FUNC8b 0x10
       #define LCDC_FUNC4b 0
       #define LCDC_FUNC2L 0x08
       #define LCDC_FUNC1L 0
       #define LCDC_FUNC5x10 0x4
       #define LCDC_FUNC5x7 0
       #define LCDC_CGRAM 0x40
       #define LCDC_DDRAM 0x80
    
       //---------------------------------------------------
       // Definicje opoznien:
    
       void delay250ns() 
    	{
    		volatile int i;
    		for (i=0;i<2;i++)
    		  i=i;
    	}
    
    
       #define delayus8(t)\
       {asm volatile( \
       "delayus8_loop%=: \n\t"\
       "nop \n\t"\
       "dec %[ticks] \n\t"\
       "brne delayus8_loop%= \n\t"\
       : :[ticks]"r"(t) );}
       //DEC - 1 cykl; BRNE - 2 cykle; +1 x nop; Zegar 4Mhz
    
       void delay100us8(uint8_t t)
       {
       while(t>0)
       {
       delayus8(100)
       --t;
       }
       }
    
    
       //-------------------------------------------------
       // Funkcje niskiego poziomu:
    
    
       #define LCD_EPULSE() \
       {PORT(LCD_EPORT) |= 1<<LCD_E; \
       delay250ns(); \
       PORT(LCD_EPORT) &= ~(1<<LCD_E);}
       // LCD_EPULSE - strobuje dostep do wyswietlacza (zalaczamy czas na pobranie danych lub rozkazow)
    
    
       void LCD_sendHalf(uint8_t data)
       {
       data = (data & 0x0F) << LCD_D4;
       PORT(LCD_DPORT) = (PORT(LCD_DPORT) & ~(0x0F<<LCD_D4)) | data;
       LCD_EPULSE();
       }
    
       void LCD_send(uint8_t data)
       {
       LCD_sendHalf(data>>4); //starsza czesc
       LCD_sendHalf(data); //mlodsza czesc
       delayus8(120);//120 us
       }
    
       //-------------------------------------------------
       // Funkcje wysylajace komendy i dane:
    
       void LCD_command(uint8_t command)
       {
       PORT(LCD_RSPORT) &= ~(1<<LCD_RS); //przeslanie instrykcji; RS = 0
       LCD_send(command);
       }
    
       void LCD_data(uint8_t data) //przeslanie danych do DD RAM; RS = 1
       {
       PORT(LCD_RSPORT) |= 1<<LCD_RS;
       LCD_send(data);
       }
    
       void LCD_cls(void) //czyszczenie wyswietlacza
       {
       LCD_command(LCDC_CLS);
       delay100us8(48);
       }
    
       void LCD_home(void) //ustawianie wyswietlacza w pozycji home
       {
       LCD_command(LCDC_HOME);
       delay100us8(50);
       }
    
       //-------------------------------------------------
       // Inicjacja Wyswietlacza:
    
       void LCD_init(void)
       {
       delay100us8(150);
       PORT(LCD_RSPORT) &= ~(1<<LCD_RS);
       LCD_sendHalf((LCDC_FUNC | LCDC_FUNC8b));
       delay100us8(41);
       LCD_sendHalf((LCDC_FUNC | LCDC_FUNC8b));
       delay100us8(2);
       LCD_sendHalf((LCDC_FUNC | LCDC_FUNC4b));
       //teraz jest juz 4b, koniec korzystania z sendHalf
       LCD_command(LCDC_FUNC | LCDC_FUNC4b | LCDC_FUNC2L | LCDC_FUNC5x7);
       LCD_command(LCDC_ON);
       LCD_cls();
       LCD_command(LCDC_MODE | LCDC_MODEL);
       LCD_command(LCDC_ON | LCDC_ONDISPLAY);
       }
    
       //-------------------------------------------------
       //PETLA GLOWNA:
    
       int main(void)
       {
       //inicjalizacja portow
       DDR(LCD_DPORT) |= 1<<LCD_E | 1<<LCD_RW | 1<<LCD_RS | 0x0F<<LCD_D4;
    	PORT(LCD_RWPORT) &= ~(1<<LCD_RW);
    
       DDRA |= 1<<0;//podciagniecie diodki sprawdzajacej czy program przejdzie
    
    	_delay_ms(100);
       //przygotowanie wyswietlacza
       LCD_init();
    
       //podanie danych na wyswietlacz
    	LCD_cls();
       LCD_data('H');
       LCD_data('E');
       LCD_data('L');
       LCD_data('L');
       LCD_data('O');
    
       PORTA |= 1<<0;//wl. diodki sprawdzajacej
    
    	while (1) ;
    
       return 0;
    
       }
    
    

    [ Dodano: 31 Mar 10 10:20 ]

    Definicję F_CPU należy oczywiście przenieść do pliku make, ale na szybko jest w kodzie.

    Musiałem dodać opóźnienie przed inicjalizacją lcd - 100ms, inaczej czasem pojawiały się krzaki.

    Zmieniłem procedurę opóźniającą. Lepiej użyć _delay_us zamiast niej. To co było nie chciało mi się kompilować.

    Dodałem jeszcze obsługę pinu RW - płytka olimex ma wyprowadzony, więc musiałem go wyzerować.

    Jeszcze jedna zmiana to dodanie LCD_cls() przed wyświetlaniem napisu. Inaczej wyświetlał tylko 'H'.

    Kod powinien działać, jeśli nie, to sprawdź czy hardware jest na pewno sprawny.

    • Lubię! 1

  9. Takie aktywne czekanie ma kilka poważnych wad. Po pierwsze jest mało dokładne. Jeśli w trakcie wystąpi przerwanie, to czas będzie inny. Dla 1-wire może to mieć znaczenie, więc trzeba wyłączać przerwania czekając, co z kolei może powodować problemy procedur działających na przerwaniach.

    Dodatkowy problem to pobór prądu. Procesory ARM potrafią sporo pobrać. W końcu 60MHz to sporo. Więc czekanie w pętli to marnowanie czasu i prądu.

    Najlepiej jest uruchomić timer i uśpić procesor. Wtedy mamy dokładność działania, brak opóźnień przerwań i oszczędność prądu.


  10. Jak chodzi o biblioteki to niestety na arm jest trudniej.

    Nigdy nie używałem, ale znalazłem bibliotekę ArmLib - http://hubbard.engr.scu.edu/embedded/arm/armlib/index.html , w niej jest trochę funkcji, które wydają się ciekawe.

    Najprościej opóźnienie zrobić na pętli - oscyloskopem wyregulować i chodzi.

    Niestety dokładność jest wtedy bardzo słaba.

    Jeśli opóźnienia maja być dokładnie mierzone pozostaje użyć timer. LPC21xx ma 2 timery. Można wykorzystać jeden do tworzenia opóźnień, albo wprowadzić globalny licznik czasu i za jego pomocą tworzyć opóźnienia.

    Jest jeszcze jedna możliwość, uruchomić RTOS, np. FreeRTOS - http://www.freertos.org/ . Dopiero wtedy procesor nie będzie marnował czasu czekając aktywnie w pętlach.


  11. 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.


  12. 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.


  13. 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ł.


  14. 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.

    • Lubię! 1

  15. 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.


  16. 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).

    • Lubię! 1
×
×
  • Utwórz nowe...