W świecie płytek typu Arduino, łatwo jest realizować pojedyncze doświadczenia. Mruganie diodami, kilkakrotne obrócenie serwem, bipniecie buzzerem – do podstawowych eksperymentów wystarczy garść kabelków i kilka linijek kodu.
Trudności zaczynają się, gdy chcemy zrealizować jakieś konkretne zadanie, która wymaga połączenia kilku bloków funkcjonalnych. Wtedy wychodzą na jaw problemy z zasilaniem, dogadywaniem się niektórych elementów, poziomami logiki, niewystarczającą liczbą pinów oraz “hakami” w bibliotekach.
Kilka razy sprawdzałem już, co potrafi Digispark. Radzi sobie z generowaniem sygnałów cyfrowych, PWM czy odczytywaniem wartości sygnałów analogowych. Badanie pojedynczych funkcji to jednak nie to samo, co połączenie ich w pewną działającą całość. Dlatego właśnie postanowiłem sprawdzić klona Digisparka w warunkach “bojowych”.
Ten tekst oryginalnie opublikowałem na moim blogu uczymy.edu.pl. Tam też znajdziecie więcej szczegółów na temat Digisparka.
Cel
Celem projektu było skonstruowanie małego i taniego robota mobilnego, na częściach popularnie dostępnych na rynku (w szafie). Oparty na klasycznym, 3-punktowym podwoziu, napędzany dwoma serwa 360stopni, zasilany z baterii, zdalnie sterowany za pomocą pilota na podczerwień, wykonany z materiałów dostępnych pod ręką (jak metalowe klocki konstrukcyjne) – ot, taka zabawka sterowana za pomocą Digisparka.
Digispark
Będziecie potrzebować: (klona lub oryginalny) Digispark z bootloaderem micronucleus oraz kabel microUSB do programowania.
Za jednostkę sterującą użyłem klona Digispark’a. Digispark to nic innego jak AtTiny85 osadzony na zgrabnej płytce z wyprowadzeniami dla wszystkich pinów i dodatkowym stabilizatorem napięcia.
Co ciekawe, Digispark’a wyposażono w interfejs USB… ale taki emulowany przez oprogramowanie. Nie ma tu osobnego czipa do komunikacji w stylu CH340 w klonach Arduino. Wszystko realizują odpowiednie biblioteki i kilka sztuczek na granicy (albo trochę poza nimi) standardu USB.
Te sztuczki sprawiają, że Digispark bywa kapryśny. Przeprogramowanie układu czasami wymaga kilkukrotnego włożenia – wyciągnięcia go z portu USB komputera. Aktywny hub niewiele tu pomaga. Szkice czasem tylko udają, że się ładują. Bootloaderowi zdarza się zniknąć a piny nie zawsze działają zgodnie ze swoim przeznaczeniem… Brzmi jak wyzwanie, nieprawdaż?
Bootloader: niewielki kod w pamięci kontrolera, który umożliwia np. ładowanie Waszych programów przez USB z komputera (hosta).
Środowisko programowania…
Będziecie potrzebować: Arduino IDE z zainstalowanym wsparciem dla Digispark (pod Windows lub Linux)
Za środowisko programowania wybrałem Arduino IDE 1.5.8 dla Linux 64-bit (używam MINT 17.3), zmodyfikowane dla Digisparka. Dlaczego akurat to? Digispark, którego użyłem do tego projektu, swego czasu się zbuntował i konieczne było wgranie nowego bootloadera (zobacz; Digispark i micronucleus: crash). Niestety okazało się, że najnowsze Arduino IDE (1.6.6) pobrane ze strony arduino.cc, rozszerzone o wsparcie dla Digispark (zobacz: Digispark: jak zacząć pod Windows), nie obsługuje wersji micronucleus 2.+ – akurat tej, która jest dostępna na githubie Digistump. Użyłem więc starszej wersji środowiska, udostępnianej przez Digistump.
Dodatkowe narzędzia…
W trakcie rozwijania i testowania przydadzą się: przejściówka UART2USB (+Putty na hoście), analizator logiczny ewentualnie – oscyloskop. Jeżeli “zniknie” bootloader – przyda się programator ISP, np. USBASP2.
Niestety, z Digisparkiem nie zawsze wszystko idzie zgodnie z planem. Oczywiście idealną pomocą jest oscyloskop – ale to dość kosztowna “zabawka”. Alternatywnie polecam np. analizator logiczny. Podstawowe modele można kupić za bardzo rozsądne pieniądze.
Konieczna będzie przejściówka USB2UART. Dzięki niej użyjecie biblioteki SoftSerial do przesyłania logów z Digisparka i określenia kodów klawiszy pilota na podczerwień. Więcej o połączeniu szeregowym dowiecie się tutaj: Digispark: port szeregowy UART.
Budowa
Będziecie potrzebować: materiały do konstrukcji podwozia – kółka, klocki konstrukcyjne, klocki lego; płytkę stykową (do osadzenia wszystkich elementów) pojemnik na baterie, paski plastykowe do spinania elementów (tralki), recepturki, taśmę klejącą dwustronną.
Swoje roboty najczęściej buduję z metalowych klocków konstrukcyjnych. Swego czasu byłem nawet w ich muzeum w Police nad Metui – niektórzy czytelnicy na pewno kojarzą firmę Merkur. Ale i w Polsce mamy ciekawych producentów – np. firmę Alexander i jej serię Mały Konstruktor. Oczywiście bardzo lubię też lego – które łatwo łączą się z np. serwami.
Do konstruowania robotów często wykorzystuję tzw. “drewno cytrusowe”. Pochodzi ze… skrzynek na owoce wyproszonych z okolicznego warzywniaka. Niektóre skrzynki zrobiono ze zwykłej dykty – inne z 3mm sklejki – bardzo lekkiej i łatwej w obróbce (wystarczy nóż segmentowy).
Do montażu stosuję też paski plastykowe (tzw. tralki), dwustronną taśmę klejącą, recepturki – co tam podpadnie pod rękę.
Serwa
Będziecie potrzebować: silniki DC albo serwa 360 zasilane na 4-6V, najlepiej wyposażone w przekładnie – 100obr/min to już dość rozsądna szybkość.
Do napędu mojego robota planowałem użyć tanich silników RF-300A. Oryginalnie wykorzystywane są w napędach CD/DVD. Można je zasilać napięciem 3-6V. Na biegu jałowym zużywają 22mA, a przy zatrzymaniu wału maksymalnie 390mA.
Właściwie to kupiłem je głównie dlatego, że były tanie (ok. 5PLN/szt). Niestety okazały się za słabe. Przy ciężarze 4-rech baterii AA, 2 silniki mogły uciągnąć prototyp tylko na pełnej mocy, jedynie na wprost i po kafelkach – o jeździe po dywanie czy skręcaniu jednym silnikiem nie było mowy.
Inną opcja mogą być mini-silniczki z przekładniami, np. polulu. To świetne rozwiązanie. Takie napędy są naprawdę bardzo trwałe i dają niesamowity ciąg. Niestety… kosztują konkretne pieniądze.
W końcu zastosowałem 2 serwa 360st. Dokładniej są to zmodyfikowane Redoxy s90. Ze względu na sposób wykonania modyfikacji, steruje się nimi jak zwykłymi silnikami DC (prądu stałego) kluczując zasilanie sygnałem PWM. Przerobienie “normalnego” serwa na 360 nie jest takie trudne – sam zrobiłem to kilka razy (zobaczcie: Modyfikacja serwa tower pro sg90 na 360st).
Serwa przypiąłem do podwozia za pomocą 2 tralek. Użyłem też kółek lego – łatwo je przymocować do krzyżakowych orczyków serwa za pomocą cienkiego drutu.
Sterowanie silnikami: tranzystory
Będziecie potrzebować: tranzystory NPN, np. TIP122, rezystory bazowe – w zależności od silników i tranzystorów.
Z każdego z serw wychodzą 2 kabelki. Jeżeli podłączę je po prostu do + i masy zasilania – nie będę miał żadnej możliwości sterowania nimi. Oczywiście nie mogę też podłączyć kabelków bezpośrednio do AtTiny85 – pobór prądu z silników by je usmażył.
Dlatego podłączyłem je inaczej: jeden kabelek silniczka do “+” zasilania, a drugi – przez tranzystor do masy. Podłączając kabelek od silnika do kolektora tranzystora, którego emiter połączyłem z masą, będę mógł sterować przepływem prądu przez silnik. Tranzystor w stanie nasycenia, sterowany przez sygnał PWM podawany na bazę, będzie zachowywał się jak przełącznik. Włączając i wyłączając prąd (zgodnie z sygnałem PWM), będę sterował szybkością obrotową silników.
Pozostaje wybrać tranzystor. Kilka NPN znalazłem w szufladzie:
Polecam Wam świetny tekst na temat doboru tranzystorów i rezystora bazowego: How to Use A Transistor as a Switch.
Zacznijmy od Ic – maksymalnego prądu, jako może przepłynąć przez złącze kolektor-emiter. Zablokowane serwo tego typu pobierze nawet 500mA. Ic dla 2n2222 to 600mA – trochę za blisko granicy. TIP122 to 5A (wow!). bc547 – tylko 100mA, więc odpada ze stawki. bd139 ma Ic na poziomie 1.5A – też się nada.
Teraz sprawdzimy jaki prąd Ib musi popłynąć przez złącze baza-emiter, żeby tranzystor się nasycił. W przypadku bd139:
Widać to, że:
Ic = 10 * Ib
Czyli, żeby wygenerować 500mA, potrzebowalibyśmy prądu bazy 50mA. To znacząco za dużo dla AtTiny.
W instrukcji do TIP122 znajdziecie wykres 2.
Widać na nim, że:
Ic = 250 * Ib
Stąd dla 500mA, minimalny prąd bazy to 2mA. AtTiny wyrobi się bez problemu.
Z powyższego wykresu widać jeszcze jedno: napięcie Vbe nasycenia dla prądu 0.5A to ok. 1.4V. Informacja ta będzie nam potrzebna do wyznaczenia rezystora bazy Rb. Skoro zasilanie bazy będzie 5V, na złączu baza-emitor spadek wyniesie 1.4V, spadek napięcia na rezystorze musi wynieść 3.6V. Stąd:
I = U \ Rb,
Rb = U \ I = 3.6 \ 0.002 = 1750Ω
Rezystor 1750Ω powinien dać radę – ja użyję mniejszego (1kΩ), który da większy prąd bazy gwarantując nasycenie.
Podłączenie:
Tranzystory zamontowałem na płytce stykowej i podłączyłem do Digispark’a:
Zauważcie, że bazy tranzystorów podłączyłem do pinów P1 i P4 Digisparka.
Oczywiście w ten sposób będę mógł jedynie włączać/wyłączać silniki oraz regulować ich szybkość obracania się tylko w jedną stronę. Możliwość odwracania biegu dają dopiero układy takie jak L293D.
Zasilanie
Będziecie potrzebować: baterii lub akumulatorów – np. 4xAA, 2×14500, pudełka na akumulatory/baterie – najlepiej z wyłącznikiem, LM78S05 (jeżeli napięcie akumulatorów, baterii > 6v), jeżeli LM78S05: kondensatory 0.33uF i 0.1uF (330 i 100nF, oznaczenia 334 i 104), kabelki połączeniowe – męsko-męskie i męsko-żeńskie
Serwa wymagają zasilania ok. 4-6V. Z początku planowałem użyć pojemnika z 4-ma bateriami AA. Niestety baterie te – choć łatwo dostępne, dość dużo ważą. Postanowiłem zamienić je na 2 akumulatory LiIon z serii 14500. To bardzo ciekawe ogniwa. Mają rozmiar paluszków AA – a każda daje napięcie ok. 3.7 (naładowane nawet 4.3). Wystarczą więc tylko 2 połączone szeregowo.
Nie ma jednak nic za darmo: naładowane akumulatory dają razem ponad 8 woltów. Taki poziom napięcia mógłby uszkodzić napędy. Potrzebny jest więc dodatkowy stabilizator. LM78S05 powinien wystarczyć. Daje 5V na wyjściu przy maksymalnym prądzie 2A. Koszt ok. 1,5 PLN.
Model “s” może przewodzić dwa razy więcej prądu od wersji 7805. Wydawało mi się to bezpiecznym marginesem.
W jaki sposób podłączyć ten stabilizator? Instrukcja podaje tak:
Nie miałem pod ręką kondensatora 330nF – użyłem 220nF – też powinien być ok. Podłączyłem wszystko na płytce stykowej:
Odpowiednie umieszczenie pudełka z bateriami umożliwia też użycie jego przełącznika do włączania/wyłączania robota:
Zdalne sterowanie
Będziecie potrzebować: pilota na podczerwień, diodę IR odbiorczą, np. TSSOP2238, kondensator elektrolityczny ok. 4.7uF, podłączony między Vcc i GND. Dodatkowo, do zidentyfikowania kodów klawiszy pilota: przejściówkę UART2USB.
Do zdalnego sterowania robotem użyłem podczerwieni: zestawu pilot – dioda odbiorcza IR. Raczej nie próbujcie walczyć z diodą IR bez kondensatora między zasilaniem a masą. Będziecie dostawać przedziwne wyniki. Kolejne wciśnięcia tego samego klawisza mogą dawać inne kody.
Podłączenie jest bardzo proste:
Zasilanie Vcc podłączyłem do 5V (wyjście z 78S05), masę do masy GND, a pin OUT do P2 Digisparka.
Jeżeli chodzi o samego pilota – chwyciłem co leżało pod ręką – akurat zgrabny nadajnik od radiomagnetofonu sony.
W przypadku diod tego typu, bardziej skomplikowane jest samo oprogramowanie. Najpierw do nowego projektu dodajcie bibliotekę: DigisparkIrLib. W kodzie pojawią się dodatkowe nagłówki:
1 2 3 4 |
#include <IRLibTimer.h> #include <IRLibMatch.h> #include <IRLib.h> //... |
Biblioteka DigisparkIrLib wymaga drobnej modyfikacji. Odnajdźcie plik w katalogu Arduino IDE: ./hardware/digistump/avr/libraries/DigisparkIRLib/IRLib.h i zmieńcie linijkę:
1 |
#define MY_IR_PROTOCOL ... |
Tak, żeby określała rodzaj Waszego pilota; u mnie:
1 |
#define MY_IR_PROTOCOL PROTO_SONY |
Najczęściej:
1 |
#define MY_IR_PROTOCOL PROTO_NEC |
Takim protokołem posługuje się np. pilot Keyes:
Uwaga: dekoder przetworzy tylko sygnały z protokołu, który wybierzecie; tzn. jeżeli podacie:
1 |
#define MY_IR_PROTOCOL PROTO_SONY |
…biblioteka zdekoduje sygnały z pilota sony, ale nie keyes’a (który posługuje się protokołem nec’a). Generalnie można by włączyć wszystkie znane protokoły:
1 |
#define MY_IR_PROTOCOL ALL_IR_PROTOCOL |
…ale wtedy kod rozrośnie się tak, że nie zmieści się w AtTiny85.
Biblioteka DigisparkIrLib wczytuje sygnał ze wskazanej linii IR i umieszcza go buforze. Bufor ten przetwarza dekoder. Dekoder używa MY_IR_PROTOCOL, żeby poprawnie zinterpretować zawartość tego bufora. W przypadku poprawnego rozpoznania, dostaniecie liczbę (typu long), inną dla każdego przyciśniętego klawisza.
Teraz będziecie musieli określić, jakie kody generują się po wciśnięciu klawiszy na pilocie. Do pustego szkicu dodajcie bibliotekę DigisparkIrLib, DigisparkTinyPinChange oraz DigisparkSoftSerial. Teraz wpiszcie taki program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <IRLibTimer.h> #include <IRLibMatch.h> #include <IRLib.h> #include <SoftSerial.h> #include <TinyPinChange.h> //On the basis of Digistump examples //IR output connected to P2 #define IR_PIN 2 IRrecv My_Receiver(IR_PIN); IRdecode My_Decoder; //Softserial connectected to 0,1 (RX, TX) SoftSerial sserial(0,1); void setup() { sserial.begin(9600); //Print something to see that setup is working sserial.println("======"); My_Receiver.enableIRIn(); } void loop() { if (My_Receiver.GetResults(&My_Decoder)) { //decode received rawBuffer My_Decoder.decode(); //make sure you only look at your type of remote control if ( My_Decoder.decode_type == PROTO_SONY ) { sserial.print( My_Decoder.value ); sserial.println(); } My_Receiver.resume(); } } |
Pamiętajcie o “My_Receiver.resume()”, który przestawia odbiornik do wczytania kolejnego kodu z pilota.
Skomilujcie program i wgrajcie do Digisparka. Podłączcie diodę IR do zasilania, masy i pinu P2 Digisparka (pamiętajcie o kondensatorze). Połączcie pin RX przejściówki USB2UART do pinu P1 Digisparka. Pamiętajcie również o połączeniu mas Digisparka, przejściówki i diody IR. Wciskajcie przyciski na pilocie – na konsoli hosta (komputera, do którego podłączona jest przejściówka) zobaczycie kolejne kody klawiszy, np:
1 2 3 4 5 6 7 8 |
$cat /dev/ttyUSB0 ======== 21538 21538 21538 |
Dla Windows możecie użyć Putty otwierając port szeregowy przejściówki (COMx) z szybkością 9600.
Teraz już wiecie jakie kody generuje przyciśnięcie klawisza na pilocie zdalnego sterowania.
Oprogramowanie
Oprogramowanie jest niezbyt skomplikowane. Oprócz DigisparkIrLib, sketch wymaga dodania biblioteki DigisparkTinySoftPwm. Znając kody klawiszy pilota:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
#include <TinySoftPwm.h> #include <IRLibTimer.h> #include <IRLibMatch.h> #include <IRLib.h> //Using Digistump samples //Define pins #define PIN_LEFT 4 #define PIN_RIGHT 1 #define IR_PIN 2 //Define PWMs #define ENGINE_STOP 0 #define ENGINE_MAX 255 #define SPEED_STEP 5 //Variables controlling PWM for each engine int speedMeL = ENGINE_STOP; int speedMeR = ENGINE_STOP; //IR instance IRrecv My_Receiver(IR_PIN); IRdecode My_Decoder; void setup() { My_Receiver.enableIRIn(); pinMode(PIN_LEFT, OUTPUT); pinMode(PIN_RIGHT, OUTPUT); TinySoftPwm_begin(128, 0); } void loop() { //Taken from TinySoftPWMDemo: process PWM timers static uint32_t StartUs = micros(); if ((micros() - StartUs) &amp;amp;gt;= 60){ StartUs = micros(); TinySoftPwm_process(); } //Get results from decoder if (My_Receiver.GetResults(&amp;amp;amp;My_Decoder)){ //decode received rawBuffer My_Decoder.decode(); //make sure you only look at your type of remote control if ( My_Decoder.decode_type == PROTO_SONY ) { int key_value = My_Decoder.value; //IR kodes of remote controller switch (key_value) { case 21538://operate button - no action break; case 28962://function button - no action break; case 31526://band button - no action break; case 26150://play button - go! speedMeL = ENGINE_MAX; speedMeR = ENGINE_MAX; break; case 3622://stop button - stop! speedMeL = ENGINE_STOP; speedMeR = ENGINE_STOP; break; case 24870://left button - turn left speedMeL = ENGINE_MAX; speedMeR = ENGINE_STOP; break; case 4390://right button - turn right speedMeL = ENGINE_STOP; speedMeR = ENGINE_MAX; break; case 9250://volup button - go faster speedMeL += SPEED_STEP; speedMeR += SPEED_STEP; break; case 25634://voldown button - go slower speedMeL -= SPEED_STEP; speedMeR -= SPEED_STEP; break; } if (speedMeL < ENGINE_STOP )speedMeL = ENGINE_STOP; if (speedMeR < ENGINE_STOP )speedMeR = ENGINE_STOP; if (speedMeL > ENGINE_MAX )speedMeL = ENGINE_MAX; if (speedMeR > ENGINE_MAX )speedMeR = ENGINE_MAX; TinySoftPwm_analogWrite(PIN_LEFT, speedMeL); TinySoftPwm_analogWrite(PIN_RIGHT, speedMeR); } //Make receiver listen to a next code My_Receiver.resume(); } } |
Biblioteka IR wczytuje i dekoduje kody z pinu P2. Wynik jest porównany do kodów klawiszy pilota (np. 26150 oznacza wciśnięcie klawisza ‘play’). Jeżeli wciśnięto klawisz ‘play’ na pilocie, na P1 i P4 generowany jest sygnał PWM, który uruchamia silniki. Wciśnięcie ‘stop’ je zatrzymuje. W przypadku skręcania – zatrzymuję jeden silnik i kręcę drugim.
To oczywiście bardzo prosty algorytm – możecie go ulepszyć!
Efekty
Tak jeździ:
I kilka fotek:
Podsumowanie
No i udało się: robot reaguje na pilota, jeździ po dywanie – od biedy można by dołączyć do niego jeszcze kilka detali.
Podczas całej budowy okazało się, że największym problemem są… biblioteki. A dokładniej ich niepełna – i raczej nastawiona na programistów, niż użytkowników – dokumentacja. Trochę trzeba się naczytać kodu, żeby dowiedzieć się, że IR używa dodatkowego timera – blokując w ten sposób pin P0.
Sam klon Digispark też nie pomaga – pin P3 jest uruchamiany przez bootloader szukający hosta. Jeżeli podłączycie do P3 silnik – przy starcie czipu zacznie się obracać… P5 to reset – podanie na niego stanu niskiego, spowoduje zresetowanie układu (nie dotyczy to oryginalnych Digisparków, które mają wyłączoną możliwość zewnętrznego resetu).
Jeżeli jednak nie zniechęcą Was te przeszkody – efekty mogą być całkiem ciekawe.
Źródła
- How to use transistor as a switch
- Digispark: wiki
- Dokumentacja do tip122
- Kod oparty na przykładach dostarczonych ze środowiskiem
Świetny projekt.
Czytam Cię już od jakiegoś czasu, ale po raz pierwszy pozwalam sobie na komentarz. Nie wszystkie blogi potrafią zainteresować. Twój tak. Nie wszystkich blogerów można pozytywnie kojarzyć. Ciebie jak najbardziej. Jednym słowem – lubię tu bywać i mam nadzieję wracać tu częściej :)
To nie jest blog jednego autora, każdy może tutaj umieścić własny artykuł. A ten wpis jest pierwszym od Elektronika Bez Spięcia (
Arkadiusz Merta). Pozdrawiam :)
Post dosyć konkretny i bardzo treściwy,
Ostatnimi czasy był tutaj deficyt krótkich ale treściwych postów z dziedziny elektroniki, choć ostatnio wygląda to lepiej ;)
Testowałeś robota na innych podłożach? Oczywiście nie ma co oczekiwać cudów :D
A co do digisparka, nie łatwiej było włożyć gołą atmegę ? osobiście pozbyłem się takich problemów kupując klona uno i gdy zaprogramuje układ najprościej w świecie wyciągam z Arduino, wilk syty i owca cała. Choć pewnie lubisz wyzwania ;)
Cieszę się, jeżeli post się podobał. “Jeździka” testowałem na kafelkach i dywanie:) Serwa może nie są zbyt szybkie, ale oferują całkiem niezły ciąg – teraz pracuję nad ciężarówką z napędem na 2-osie:).
Oczywiście w tym projekcie można było zastosować wiele różnych czipów – atmega to jeden, esp8266 to kolejna ciekawa możliwość – jest ich pewnie więcej. Ale ten konkretny tekst pochodzi z dłuższej serii o digisparkach. Po kilku postach opisujących poszczególne funkcje, postanowiłem sprawdzić, jak zadziała w ramach większej całości. Zadziałał:)
Pozdrawiam,
Arek
Super projekt. Fajnie wszystko opisane krok po kroku :)
To jest super
Dzięki za artykuł, czy ten P3 i poszukiwanie hosta można jakoś wyłączyć. Zacząłem sie bawić digisparkiem klonem i zauważyłem napięcie ~3v na P3 w rożnych moich sketch-ach, myślałem że ja coś uwaliłem bo mi czasem głupoty się dzieją. Nie podłączałem P3 pod oscyloskop, być możne wtedy bym zauważył ze to więcej niż napięcie :] Z P5 już się pogodziłem z uwagi na prostotę programowania na początek;)
Witaj; to sprawka micronucleus’a: bootloadera dla Digispark. Obawiam się, że jak długo tam jest – tak już to będzie działać. Więcej o digisparkach: http://uczymy.edu.pl/wp/blog/category/digispark/