W praktycznie każdym projekcie opartym na Arduino prędzej czy później pojawia się kwestia jak przenieść gotowy projekt na „czysty” mikrokontroler. Sposobów na wykonanie tego jest kilka, poczynając od użycia zewnętrznego programatora USBasp, kończąc na programowaniu mikrokontrolera używając płytki Arduino.
W tym artykule chciałbym przedstawić moim zdaniem najlepszą metodę przenoszenia swoich projektów na „czyste” kontrolery AVR, a zarazem jedną z tańszych.
Do tego celu posłużymy się donglem USB-to-serial opartym na układzie PL2303, którego możemy znaleźć na Ebay w cenie od 1 USD za sztukę i darmową przesyłką. Taka „przystawka” nie tylko zasili nasz mikrokontroler z portu USB, a także pozwoli go zaprogramować podobnie jak standardowe Arduino i umożliwi komunikację z komputerem przez standardową bibliotekę Serial.
W tym przykładzie użyłem mikrokontrolera Atmega8-16PU, aczkolwiek metoda ta może zostać wykorzystana dla innych mikrokontrolerów AVR, w tym także z serii Attiny.
Sterowniki
Do naszego dongla PL2303 należy zainstalować sterowniki nim zaczniemy go używać. Niektórzy sprzedawcy na Ebay podają linki do „własnych” sterowników, które powinny działać z ich urządzaniem. Niestety z własnego doświadczenia wiem, że z tym jest różnie, dlatego najlepiej pobrać te sterowniki bezpośrednio od producenta układu (albo raczej od producenta oryginalnego układu scalonego, gdyż te dostępne na Ebay raczej do oryginalnych nie należą).
Sterowniki można znaleźć pod tym adresem (w chwili pisania artykułu najnowsze sterowniki były w wersji 1.9.0):
http://www.prolific.com.tw/US/ShowProduct.aspx?p_id=225&pcid=41
Po zainstalowaniu sterowników dongla powinien on być widoczny w menadżerze urządzeń w kategorii Porty (COM i LPT) pod nazwą Prolific USB-to-Serial Comm Port (COMx) gdzie x to numer wirtualnego portu COM.
Bootloader i konfiguracja Arduino IDE
Zanim będziemy mogli wrzucać własne programy na mikrokontroler, musimy zaprogramować go odpowiednim bootloaderem Arduino. Jest to operacja jednorazowa dla każdego mikrokontrolera, aczkolwiek wymaga ona użycia zewnętrznego programatora np. USBasp, płytki Arduino, a nawet w przyszłości naszego „klona” opartego o PL2303. W tym wypadku użyję Arduino UNO R3 w roli programatora.
Na początek musimy zaopatrzyć się w plik HEX bootloadera. Przechodzimy więc na stronę Optiboot skąd pobieramy paczkę przygotowanych bootloaderów (w chwili pisania tego artykułu najnowsza wersja paczki to 5.0a):
https://code.google.com/p/optiboot/downloads/list
W pobranym archiwum znajdujemy dwa pliki, które nas interesują:
– bootloaders/optiboot/optiboot_atmega8.hex – plik bootloadera.
– boards.txt – plik konfiguracyjny Arduino IDE.
Plik bootloadera należy skopiować do katalogu hardware/Arduino/bootloaders/optiboot w instalacji Arduino IDE. Może się zdarzyć że mamy już taki bootloader zapisany w instalacji Arduino, aczkolwiek warto zamienić go z tym, którego przed chwilą pobraliśmy.
Następną rzeczą, którą musimy wykonać, jest dodanie wpisu do pliku boards.txt znajdującego się w hardware/Arduino dla naszego mikrokontrolera.
W teorii moglibyśmy skopiować całą sekcję dla Atmegi8 z boards.txt dostarczonego w archiwum Optiboot, aczkolwiek jest z tym mały problem. Konfiguracja Atmegi8, która dostarczona została z Optiboot konfiguruje mikrokontroler w taki sposób, aby pracował on na częstotliwości 16 Mhz. Problem polega na tym, iż Atmega8 nie będzie pracować z taką częstotliwością, jeżeli nie podłączymy do niej zewnętrznego oscylatora. Jako że w tym artykule chciałbym przedstawić najprostszy sposób zaprogramowania mikrokontrolera skonfigurujemy go tak, aby używał wbudowanego oscylatora 8 Mhz pomijając całkowicie potrzebę dołączania zewnętrznego kwarcu.
Poniżej podałem konfigurację dla Atmegi8 pracującej na częstotliwości 8 Mhz, którą to należy wkleić do pliku boards.txt (najlepiej na jego koniec) znajdującego się w hardware/Arduino.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
r8i.name=ATmega8 @ 8 MHz r8i.upload.maximum_size=7168 r8i.upload.protocol=arduino r8i.upload.speed=57600 r8i.bootloader.low_fuses=0xa4 r8i.bootloader.high_fuses=0xdc r8i.bootloader.path=optiboot r8i.bootloader.file=optiboot_atmega8.hex r8i.bootloader.unlock_bits=0x3F r8i.bootloader.lock_bits=0x0F r8i.build.mcu=atmega8 r8i.build.f_cpu=8000000L r8i.build.core=arduino r8i.build.variant=standard |
Po zapisaniu zmian w pliku, restartujemy Arduino IDE (jeżeli było włączone), a następnie sprawdzamy czy w menu narzędzia -> płytka znajduje się wpis Atmega8 @ 8Mhz.
Wgrywanie bootloadera przez Arduino
Na początek musimy „przekształcić” Arduino w programator. Aby to zrobić z menu plik -> przykłady wybieramy pozycję ArduinoISP. Następnie należy podłączyć Arduino do komputera, wybrać odpowiedni port COM, upewnić się że mamy wybraną odpowiednią płytkę w menu narzędzia -> płytka (w moim przypadku Arduino UNO), a wybrany programator to AVRISP mkII. Nie pozostaje nic innego, jak wgrać szkic ArduinoISP na płytkę Arduino.
Po wykonaniu powyższych czynności, łączymy na płytce stykowej nasze Arduino w roli programatora do mikrokontrolera.
Aby wgrać odpowiedni bootloader, musimy dokonać paru zmian w Arduino IDE:
– narzędzia -> płytka: ustawiamy na Atmega 8 @ 8Mhz.
– narzędzia -> programator: ustawiamy na Arduino as ISP.
Po dokonaniu powyższych zmian, a także upewnieniu się, że wszystko zostało poprawnie podłączone wybieramy opcję narzędzia -> wypal bootloader.
Jeżeli wszystko zostało wykonane poprawnie możemy już odłączyć Arduino, gdyż od tej chwili jedyna rzecz jaka będzie potrzebna do zaprogramowania tego kontrolera, to wspomniany wyżej dongle PL2303.
Wgrywanie szkiców
Podłączamy nasz mikrokontroler według schematu poniżej, dołączając LED z rezystorem i przycisk (zwróćcie szczególną uwagę na umiejscowienie pinów w donglu).
W tym wypadku LED został podłączony do cyfrowego pinu numer 13, a przycisk do pinu reset.
Tutaj właśnie pojawia się jedyna różnica w programowaniu Arduino, a programowaniu mikrokontrolera przez PL2303. Podczas programowania w pewnym momencie należy zresetować kontroler, aby ten mógł odebrać dane i to musimy robić ręcznie. Niestety z jakichś przyczyn wszyscy producenci tego dongla uparli się, aby na nóżce numer 5 podawać zbędne napięcie 3.3V, zamiast wyprowadzić nóżkę resetującą programowany kontroler, szczególnie że PL2303 ma możliwość zresetowania programowanego układu (mając trochę wprawy w lutowaniu można sobie spokojnie wyprowadzić pin numer 2 z PL2303 właśnie do resetowania mikrokontrolera automatycznie).
Po podłączeniu wszystkiego jak na powyższych schemacie, a także podłączeniu dongla do komputera, przechodzimy do konfiguracji Arduino IDE (podobna konfiguracja jak dla standardowego Arduino, jedynie inna płytka).
– narzędzia -> płytka: ustawiamy na Atmega 8 @ 8Mhz.
– narzędzia -> programator: ustawiamy na AVRISP mk II.
Oczywiście należy także ustawić odpowiedni port COM.
Następnie z menu plik -> przykłady -> 01. Basics wybieramy Blink, czyli proste miganie LED podłączonej do pinu 13 i klikamy przycisk „załaduj”, aby zaprogramować mikrokontroler.
Przechodzimy do najtrudniejszej czynności, czyli zsynchronizowania resetu kontrolera z rozpoczęciem przesyłania szkicu. W momencie kiedy pasek kompilacji dojdzie do samego końca, szybko wciskamy i puszczamy przycisk reset, tak aby układ był zresetowany w momencie kiedy dojdzie do komunikacji z nim. Wymaga to trochę wprawy i u każdego będzie to wyglądać troszeczkę inaczej, aczkolwiek po kilku próbach powinniście być w stanie „trafiać” za każdym razem.
Poprawne zresetowanie układu rozpoznamy poprzez szybkie miganie niebieskich diod na donglu.
Słowo na koniec
Cała przedstawiona operacja może się wydawać dość skomplikowana i czasochłonna, aczkolwiek chciałbym zwrócić uwagę na to, iż większość czynności jakie tutaj wykonujemy są jednorazowe dla danego mikrokontrolera. Bootloader musimy wgrać tylko raz, zaraz po jego zakupie.
Przy użytkowaniu takich mikrokontrolerów zapewne szybko pojawi się pytanie jakie nóżki kontrolera odpowiadają za piny cyfrowe, jakie za analogowe .itd.
Mapowanie tych pinów w Atmega8 znajdziecie pod adresem (mapowanie jest bardzo podobne dla innych kontrolerów AVR w obudowie DIP28, aczkolwiek zalecam najpierw to sprawdzić):
http://arduino.cc/en/Hacking/PinMapping
Pamiętajcie też, że w tym wypadku użyłem Atmegi8, która może i przypomina z wyglądu Atmegę328 znajdującą się w Arduino UNO, aczkolwiek ma ona znacznie mniej pamięci. W przypadku kiedy używamy dużo „ciężkich” bibliotek Arduino, to miejsce szybko się wyczerpie. Dlatego też polecałbym zaopatrzyć się w kilka różnych mikrokontrolerów np. Atmega8, Atmega168, Atmega328 i zawsze starać się używać najmniejszego (i jednocześnie najtańszego) z nich, szczególnie że są one o wiele tańsze niż cała płytka Arduino.
Najlepiej jest kupić dongla z wyprowadzonym resetem – są niewiele droższe. Z własnego doświadczenia wiem że trafić w odpowiedni moment z wciśnięciem reset jest baaardzo ciężko.
Zależy które układy, np. taki FT232RL kosztuje ponad 4 razy tyle.
Zresztą, zawsze można sobie przylutować mały kondensator do nóżki numer dwa i wyprowadzić go na 5 goldpin (przecinając ścieżkę z 3.3V).
Odnośnie ręcznego resetowania. Wszystko zależy od tego, jaki bootloader jest użyty.
W przypadku bootloaderów optiboot okres oczekiwania na rozpoczęcie pracy jest dość długi. Mogę Ci zagwarantować, że po kilku próbach trafienie w odpowiedni moment przychodzi za każdym razem bez pudła.
Jakby tego było mało możesz sobie skompilować bootloader samodzielnie (optiboot dostarcza też źródła) z jeszcze dłuższym czasem oczekiwania.
faktycznie jest ok 4x droższa ale w polskim sklepie podzielam opinię @pentos że jest wygodniej
Właściwie to porównywałem to do ceny na Ebay: ponad 4 USD to stosunku do 1 USD za PL2303.
Fakt, jest wygodniej, ale to musi sobie każdy odpowiedzieć na pytanie sam czy opłaca się tyle dokładać.
Osobiście wybrałem układy przedstawione powyżej, ale to ja – dusigrosz. ;-)
ja wezmę ten co podlinkowałem aby bezproblemowo programować “mój” wynalazek
PS
http://www.ebay.com/itm/USB-2-0-to-TTL-UART-6PIN-Module-Serial-Converter-CP2102-STC-PRGMR-Brand-New-TL-/231182473919?pt=LH_DefaultDomain_0&hash=item35d38c9abf
:D
Inna sprawa, że przylutować przewód do pinu nr 2 układu pl2303 to też nie lada sztuka.
Jak się postarasz to dasz radę. Mnie się udało przylutować się lutownicą transformatorową
Może źle myślę, ale jaki jest sens robienia tego, skoro i tak musimy wgrywać bootloader przez arduino, więc równie dobrze możemy programować całość przez arduino (skoro i tak już je musimy użyć)?
No pewnie, że tak można.
Co jednak w przypadku kiedy stworzysz jakieś urządzenie oparte na mikrokontrolerze, które trzeba będzie przeprogramować. Będziesz za każdym razem szukał Arduino (tudzież innego programatora) i podpinał przewody?
Moim zdaniem o wiele łatwiej jest kupić kilka, bądź kilkanaście takich układów, a następnie przylutować je bezpośrednio do wytrawionej płytki uzyskując w ten sposób absurdalnie tanie Arduino.
Dodatkowo, Arduino potrzebujesz tylko raz dla danego mikrokontrolera, aby wgrać bootloader.
Można i tak. Ja jednak wolałbym wyprowadzić sobie piny do programowania gdzieś na płytce i używać do tego arduino. Dużo czasu by mi to nie zabrało, a przecież nie przeprogramowuje się już złożonych układów codziennie.
Kwestia gustu. ;-)
Aczkolwiek sam artykuł nie mówi wyłącznie o programowaniu kontrolera przez PL2303. Instrukcje i sposoby konfiguracji w nim zawarte można wykorzystać przy programowaniu przez inne układy (o którym chociażby wspomniał kolega niżej), a także przez samo Arduino.
Nie do końca się zgodzę, miałem kiedyś problem z bootloaderem dla Atmega328p ponieważ nie współpracował z modułem do komunikacji radiowej, natomiast bootloader dla uno działał poprawnie tylko jak wgrać program dla atmegi z bootloaderem UNO, skoro programatorem jest UNO. Ta metoda ma sens. Mimo to uważam, że zakup programatora jest łatwiejszy.
Trochę moim zdaniem sztuka dla sztuki. Fakt że przy odrobinie wysiłku można za pomocą układu za $1 zaprogramować ATmegę, ale chyba prościej, szybciej i dużo wygodniej kupić USBasp ($2.4 łącznie z transportem) i mieć zwyczajny programator bez bawienia się w bootloadery, lutowanie pinów i wciskanie resetu.
Pewnie, że można. Napisałem przecież, że istnieje wiele różnych metod programowania “czystego” kontrolera.
Napisałem także iż jest to, moim zdaniem (!) najlepsza metoda na wykonanie tej czynności. Nie wiem jak inni, ale ja zdecydowanie wole mieć wlutowany taki układ na stałe do płytki z kontrolerem, podłączyć kabelek i móc od razu programować kontroler kiedy znajduje się on bezpośrednio w układzie zamiast bawić się w podłączanie USBasp.
No właśnie, kwestia gustu :) Dla mnie z kolei łatwiej jest kupić jeden USBasp, a do kontrolera dolutować tylko plastikowe gniazdo programowania (2×3 lub 2×5). Podłączenie to tylko wepnięcie kabelka.
Dokładnie USBAsp wychodzi dużo taniej i jest równie wygodne (podłączasz kabelek programatora, którego nie da się odwrotnie podłączyć jeśli używasz standardowych gniazdek i sam programator wpinasz w USB – koniec). Nie trzeba używać Arduino, które samo w sobie jest dużo droższe, nie trzeba do każdego zbudowanego układu dołączać wspomnianego kontrolera, który wychodzi również drożej w porównaniu do wtyczki i kilku elementów biernych. Układ PL2303 też pobiera energię i dodatkowo wymaga zainstalowanego bootloadera (więc zostaje mniej pamięci na nasz program), a jeśli coś skopiemy to znów trzeba podłączyć mikrokontroler do zaprogramowania bezpośrednio. Taki układ nie pozwala na zmianę fusebitów, więc skazani jesteśmy na ustawienia, które zaprogramujemy podczas wgrywania bootloadera. Poza tym użycie tego adaptera uniemożliwia wykorzystania w tym samym czasie innego źródła zasilania (np. baterii), więc znów trzeba kombinować – wg informacji katalogowych napięcie na wejściu/wyjściu może wynosić od -0.3 do VDD+0.3V (więc układ musi być zasilany aby móc obciążać/podawać napięcie na jego piny).
Jeśli chodzi o samo programowanie to rzeczywiście usbasp jest trochę lepszym rozwiązaniem. Ale on nie może obsługiwać komunikacji przez UART. Układ który prezentuje kolega pozwala też na transmisję danych, co bywa bardzo przydatne.
A mi wywala błąd przy próbie zaprogramowania przejściówką pl2303hx moją atmege8. Przez usbasp działa i bootloader też wypalony.. a tu błąd: avrdude: usbdev_open(): did not find any USB device “usb”
Troche pokombinowałem, pobawiłem się i teraz znowu taki błąd mi wywala:
avrdude: stk500_getsync(): not in sync: resp=0x00
Podczas próby kontaktu PL2303 z układem powinna zaświecić się przynajmniej jedna niebieska dioda na PL2303. Czy tak się dzieje? Jeżeli tak, to ile razy miga?
Czy podłączyłeś wszystko poprawnie? Szczególnie zwróć uwagę na to, że RX z dongla musi zostać podłączony do TX na kontrolerze, a TX do RX.
podłączone mam dobrze. A na pl2303 mignie sobie bardzo słabo dioda TX 3 razy.
Rozumiem, że resetujesz kontroler ręcznie nim dojdzie do jakiejkolwiek komunikacji?
Zmieniałeś cokolwiek w konfiguracji, którą wyżej podałem do boards.txt?
Warto byłoby też podłączyć diodę jak na drugim schemacie. Ten bootloader powinien ją zamigać kilka razy po puszczeniu przycisku reset, co sygnalizowałoby jego poprawną pracę.
Tak resetuję ręcznie.
Miałem już wgrany swój plik boards do atmegi8. ale wgrałem też ten twój i nie działa. Nic nie modyfikowałem. A atmega jest też nowa.
Ogólnie rzecz biorąc ta konfiguracja powinna działać z tym właśnie bootloaderem (jedyne co zmieniłem, to prędkość transmisji – jako że kontroler działa na 8 Mhz, to prędkość / 2 + odpowiednie fusy).
Jeżeli wgrywałeś inny bootloader, bądź wgrałeś go na innej konfiguracji niż podałem, może to nie działać.
Zalecałbym upewnić się, że konfiguracja jest prawidłowa, bootloader w IDE to ten, który podałem, zrestartować Arduino IDE i przez usbasp wgrać go ponownie, a następnie sprawdzić czy w ogóle wszedł poprawnie (myk z diodą o którym wspomniałem wyżej). Dopiero wtedy zabierać się za PL2303.
Niestety, ale brak synchronizacji w przypadku programowania kontrolerów przez serial może oznaczać wiele rzeczy. Przy takich zabawach wszystko musi być idealnie ze sobą zgrane, w przeciwnym wypadku w życiu to nie zadziała.
DZIĘKUJE :) Wgrałem od nowa pliki, wypaliłem bootloader jeszcze raz i działa :) dzięki jeszcze raz
Dzięki za wpis, postaram się przetestować w praktyce.
Czy samego dongla mozna oprogramowac?
Chodzi o to czy mógłby udawac HID klawiature USB?
Popieram pomysł – tym bardziej, że też coś takiego mi przyszło kiedyś do głowy :) Dodatkowo odłączyłem od układu goldpin z napięciem 3,3V i przyłączyłem do niego kynarem trzecią nóżką układu PL2303 (RTS_N). Dzięki temu mam automatyczny Reset przy programowaniu.
Chciałbym tym sposobem zaprogramować atmegę 8 plikiem hex. Jak to zrobić?
Hej, mam problem, po wklejeniu tekstu do pliku boards w programie wyskakuje mi bład:
Property line ‘?# See: http://code.google.com/p/arduino/wiki/Platforms‘ in file C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt is invalid
Mógłby ktoś udostępnić plik boards z poprawnie wklejonym txt do pliku?