(Klon) Digispark i USB: jak zacząć pod Windows 7?

Digispark to właściwie kontroler AtTiny85 (w wersji SMD) z możliwością podłączenia przez port USB. Wgrywając na niego odpowiednie oprogramowanie, Digispark może „udawać”, że jest klawiaturą, joystickiem – albo po prostu portem szeregowym, przez który można wymieniać dane z hostem (czyli urządzeniem, do którego jest podłączony).

IMG_1026„Udawać” jest tu jak najbardziej właściwym określeniem. Digispark nie ma bowiem na pokładzie żadnego dodatkowego czipu USB: wszystko jest realizowane w oprogramowaniu samego AtTiny. Oprogramowanie to opiera się to na projekcie V-USB specjalnie stworzonym dla kontrolerów AVR (firmy produkującej m. in. AtTiny i AtMega napędzające Arduino).


Pierwsze kroki dla Linux: Klon Digispark (AtTiny85 na USB/Linux)

V-USB

Mimo że podłączamy go do USB, Digispark nie ma na płytce żadnego dodatkowego czipu odpowiedzialnego za komunikację po tym interfejsie. W przypadku tanich klonów Arduino UNO, do komunikacji z komputerem wykorzystywany jest wyspecjalizowany układ CH340. W przypadku mniejszego Nano rolę tą pełni np. czip FTDI. W oryginalnym Arduino UNO, komunikacją z komputerem po USB zajmuje się dodatkowy kontroler z serii AtMega16u2 z wgranym  specjalnym oprogramowaniem.

V-USB działa na podobnej zasadzie jak oprogramowanie AtMega16u2. Jako że jest biblioteką – możecie go po prostu dołączać do swoich szkiców dla Digisparka. Niestety ma  niemałe wymagania co do sprzętu. Potrzebuje ponad 2kB flash-u i 128 bajtów RAM. AtTiny85 jest wyposażony w 8kB flash, 512B RAM. Są to parametry wystarczające dla V-USB, ale po odliczeniu miejsca na bootloader – na kod zostaje mniej niż połowa pamięci programu.

W tej części zajmę się DigiCDC, dzięki któremu Wasz Digispark pojawi się jako wirtualny port szeregowy.

Krok 1: Arduino IDE dla Digispark

Instrukcje na podstawie: Connecting and Programming Your Digispark.

Pobierzcie Arduino IDE z ze strony arduino.cc. Użyjcie menu „Plik/Preferencje” („File/Preferences”).

Clipboard03W otwartym okienku, w polu „Dodatkowe adresy URL…” wpiszcie:

http://digistump.com/package_digistump_index.json

Teraz wybierzcie „Narzędzia/Płytka…/Menedżer płytek” („Tools/Board…/Boards Manager”).

Clipboard05Na liście odszukajcie element „Digistump AVR Boards by Digistump” i kliknijcie „Instaluj”:

Clipboard06Po chwili na liście płytek pojawi się cały zestaw Digispark – wybierzcie „Digispark (Default – 16.5 mhz)”

Clipboard07Krok 2: pusty program na Digispark…

Spróbujcie wgrać pusty projekt na Waszego Digisparka. Na razie nie podłączajcie go do USB. Otwórzcie nowy projekt i wciśnijcie „Załaduj”. Po chwili IDE poprosi Was o wpięcie Digispark „Plug in device now„:

Clipboard09Teraz podłączcie Digispark’a do portu USB:

Clipboard17

Czasami wymaga to kilku prób – nie zrażajcie się:) Generalnie Digisparka trzeba często usuwać i ponownie wkładać do portu USB.

Krok 3: urządzenie USB?!

Poniższe instrukcje przećwiczyłem na Windows 7. Na Windows 8/10 możecie mieć dodatkowo problemy z podpisami sterowników.

Teraz pobierzcie sterowniki do micronucleusa. Znajdziecie je na githubie digistumb. Dla Widnows załadujcie plik „micronucleus-2.0a4-win.zip” i rozpakujcie w znanym miejscu – np. c:\tmp\digikey.

Jeżeli podłączycie Digispark’a do port USB komputera z Windows – ten będzie próbował do niego dopasować sterowaniki.

Clipboard02Skończy się to porażką – ale w Menedżerze urządzeń powinno pojawić się „Other Devices/Unknown Device”. Kliknijcie na to urządzenie i wybierzcie opcję „Update driver”. Wskażcie miejsce na dysku, gdzie zapisaliście sterowniki micronucleusa:

Pozwólcie im się zainstalować:

Zauważcie, że system wybrał „Digispark Bootloader”. Gdy skończone, menedżer urządzeń zacznie widzieć już  „DigiUSB”:

Krok 4: czas na DigiCDC

Teraz zamienimy naszego Digisparka w urządzenie, które potrafi transmitować dane po USB do komputera. W tym celu otwórzcie Arduino IDE i przykładowy szkic „Plik/Przykłady/DigisparkCDC/Echo. Ja go trochę zmodyfikowałem:

Załadujcie ten kod na Digisparka. Wyciągnijcie go z USB i włóżcie ponownie. Zauważcie, że w Menadżerze Urządzeń nazwa zmieniła się z „Other Devices/Unknown Device” na „Digispark Serial”:

Jeszcze raz uzupełnijcie sterowniki z tej samej paczki (prawy klawisz na „Digispark Serial” i „Update Drivers”):

Zauważcie, że teraz system będzie prosił o dodanie portu COM/LPT:

Jeżeli wszystko pójdzie dobrze, powinien się pojawić nowy port wirtualny – u mnie COM18:

Nie pozostaje nic innego, jak w „Narzędzia/Port” ustawić COM18 i uruchomić monitor portu szeregowego (na 9600):

Sukces:)

Podsumowanie

Digispark można łatwo zamienić w urządzenie USB transmitujące dane. Możecie podłączyć go po USB do Waszej maszyny Windowsowej. Potencjometr na wejściu analogowym Digisparka można np. wykorzystać do ściemniania ekranu. Dlaczego nie?

Źródła

11 komentarzy do “(Klon) Digispark i USB: jak zacząć pod Windows 7?”

  1. Próbuję zrobić zabawkę na którą składa się klon digisparka, buzzer, servo i 2 diody. Kiedy jednak ładuję program ze zmienną unsigned long (żeby to zgrać w millis()) to ten nie chce wystartować, czy natrafiłeś na taki problem?
    Jeśli używam po prostu long to po pewnym czasie następuje zawieszenie się urządzenia (ok 2,5 min choć powinno chyba chodzić parę dni)
    Pozdrawiam i dziękuję za super artykół.

    1. Witaj,
      powodów może być wiele. Wydaje mi się, że tu nie chodzi o typ danych (bo digispark powininen „strawić” longa), może o sam program? A może o podłączenia? „Debuggowanie” – bo tak się ten proces nazywa – proponuję zacząć od podstaw. Odłącz digisparka od układu. Spróbuj go zaprogramować osobno. Czy na pewno wybrałeś dobry procesor w Tools/Board? A może w programie jest jakiś błąd? Spróbuj prześledzić co się dzieje na wyjściach. Najlepszy jest oscyloskop, potem analizator logiczny – ale czasem wystarczy nawet dioda podłączona do portu. Jeżeli soft Ci rusza – spróbuj zbudować swój układ najpierw na płytce stykowej. Upewnij się, że prototyp działa włączając poszczególne bloki – potem całość. Dopiero jak działa, weź się za lutowanie.
      Potencjalnie:
      – buzzer bierze nawet 30mA – mam nadzieję, że nie podłączyłeś go bezpośrednio pod Digispark?
      – Serwo: wprowadza duże zakłócenia w zasilaniu – może spróbuj wetknąć kondensatory między zasilanie i masę?
      – diody: czy dałeś odpowiednie rezystory? Zwykle 300ohm starcza…

      Jeżeli wyślesz mi program – mogę spojrzeć. Przeczytaj również pozostałe teksty o digispark – niektóre porty mogą blokować digisparka (zob. http://uczymy.edu.pl/wp/blog/2017/03/31/digispark-klony-slow-o-portach-kompendium/).

      Daj znać jak poszło:)
      Pozdrawiam,
      Arek

      1. Dzięki za odpowiedź, przerobiłem program i teraz unsigned long działają (choć nie wiem do końca co tam było źle), być może problemem był za duży buzzer podłączony bezpośrednio pod pin (przez jakiś czas pracowałem w firmie zbierającej elektrozłom i mam ich kilka) zmieniłem go na mniejszy (sbt-11p) i dałem rezystor 330, dodatkowo dałem kondensator zaraz za źródłem zasilenia (1000uF powinien chyba dobrze kompensować skoki wynikające z pracy servo oraz buzzera) teraz program działa przez dość długi czas bez problemów, wszystko oczywiście na razie jest na breadboardzie.
        Układ działa na 4 paluszkach – podpięte pod serwo (SG90) i pod digisparka w miejsce 5V, wiem że to średni pomysł, ale na 9V (gdybym chciał podpiąć pod VIN) musiałbym zmniejszać napięcie na 5V żeby servo się nie spaliło i z tego co doczytałem układ działałby na czymś takim dużo krócej.
        Czy powinienem to jakoś zabezpieczyć? mam LM317T i kondensatory 1000 i 330 więc teoretycznie mogę wysterować na 5V niezależnie od tego czy paluszki mają łącznie 5,5 czy 6,5V (choć wolałbym tego nie robić bo całość ma się zmieścić w opakowaniu po serku wiejskim PIĄTNICA)
        Czy digispark powinien się nagrzewać? Czy powinienem przykleić do jego scalaków jakieś miedziane blaszki żeby lepiej się chłodził (nie parzy da radę utrzymać go w palcach 😉 )?
        Mam nie lada problem ze zmuszeniem servo do działania przy zmianie taktowania na 1mhz (16,5 – śmiga, 8 – jest ok, 1 – zacina się w jednej pozycji i chodzi o jeden stopień w górę i dół) nie znalazłem o tym za bardzo info w sieci.
        Nie dawałem rezystorów do diod, są z obudów starych komputerów i monitorów crt (takie 2 kolorowe pomarańczowo zielone) przy 3v nie dzieje im się krzywda, czy dać je mimo wszystko?

        Dziękuję jeszcze raz za odpowiedź i pozdrawiam,

        kod:

        #include

        SoftRcPulseOut servo;

        unsigned long currentMillis = 0;

        int servoInterval = 20;

        unsigned long counterStartLED;
        byte onBoardLedState = LOW;

        unsigned long counterStartSERVO;

        unsigned long lastServoUpdate;

        // used to record whether the LEDs are on or off

        byte bigLedState = LOW; // LOW = off

        byte servoState = LOW;

        byte servoTracking = LOW;

        byte servoWorkingSlowly = LOW;

        byte servoUp = LOW;

        int servoWaitTime = 0;

        unsigned int ledIntervalGlow;
        unsigned int ledIntervalBlack;

        int toneToPlay;

        // the setup function runs once when you press reset or power the board

        void setup() {

        // initialize digital pin LED_BUILTIN as an output.
        pinMode(0,OUTPUT);
        pinMode(1, OUTPUT);
        servo.attach(2);
        servo.setMaximumPulse(2200);
        pinMode(3,OUTPUT);
        pinMode(4,OUTPUT);
        }

        //void(* resetFunc) (void) = 0;

        // the loop function runs over and over again forever

        void loop() {

        //digitalWrite(1, HIGH);

        currentMillis = millis();

        blinkingOnBoard();

        SoftRcPulseOut::refresh(); //without argument, refresh occurs every 20 ms (internal to the lib)

        FastRotToAngle();

        justRotateServo();

        if (servoTracking == HIGH){
        digitalWrite(0, HIGH);
        }

        else

        {
        digitalWrite(0, LOW);
        }

        // if(millis()> 135000){
        // resetFunc(); //call reset
        // }
        }

        void FastRotToAngle(){

        if (servoState == LOW){
        servoWaitTime = random(7000,14000);
        counterStartSERVO = currentMillis;
        servoState = HIGH;
        }

        else{

        if( currentMillis > counterStartSERVO + servoWaitTime)
        {
        noTone(4);
        servoTracking = HIGH;
        servo.write(random(20,180));
        servoState = LOW;
        }
        }
        }

        void justRotateServo(){

        if (servoTracking == LOW){
        int angle = servo.read();
        if(servoWorkingSlowly ==LOW){
        lastServoUpdate = currentMillis;
        servoWorkingSlowly = HIGH;
        }

        else

        {
        if( currentMillis > lastServoUpdate + servoInterval){
        if( servoUp == HIGH){
        if( angle 20){
        angle–;
        servo.write(angle);
        }

        else
        {
        servoUp = HIGH;
        }
        }
        servoWorkingSlowly = LOW;
        }
        }
        }

        else
        {
        if( currentMillis > lastServoUpdate+2000){
        servoTracking = LOW;
        }
        }
        }

        void blinkingOnBoard(){

        if(onBoardLedState == LOW){
        onBoardLedState = HIGH;
        counterStartLED = currentMillis;
        ledIntervalGlow = random(0,200);
        ledIntervalBlack = random(0,200) + ledIntervalGlow;
        toneToPlay = random(100, 2000);
        }

        else
        {
        if(currentMillis < counterStartLED + ledIntervalGlow){
        digitalWrite(1, HIGH);
        digitalWrite(3, LOW);
        if (servoTracking == LOW){
        tone(4, toneToPlay);
        }
        }
        else{

        if( currentMillis < ledIntervalBlack + counterStartLED){
        digitalWrite(1, LOW);

        if (servoTracking == LOW)
        {
        digitalWrite(3, HIGH);
        }
        noTone(4);
        }
        else{
        onBoardLedState = LOW;
        }
        }
        }
        }

        1. Hej,
          tak na szybko:
          – Polecam poczytać o zasilaniu: http://mikrokontrolery.blogspot.com/p/spis-tresci.html#dzial_zasilanie_zaklocenia
          – Buzzer: wydaje mi się, że najbezpieczniej będzie użyć tranzystor, spójrz tutaj: http://uczymy.edu.pl/wp/blog/2015/08/29/buzzer/
          – Wstawianie ponad 5.5v dla AtTiny85 jest ryzykowne, powyżej 6v możesz je uszkodzić. Niestety wbudowany stabilizator na VIN Ci się nie przyda – ma dropout na poziomie 2v (a lm317 wymaga minimum 3v różnicy między wyjściem i wejściem), więc potrzebowałbyś podać na niego co najmniej 7v; popatrz jednak na LDO, które mają droput np. 0.28v: http://electropark.pl/przetwornice-dc-stabilizatory-impulsowe/9299-lp2985-5-0-15a-stabilizator-ldo-sot23-5.html.
          – Digispark, jak wszystko przez co płynie prąd, grzeje się – ale tu problemem może być zbyt wysokie napięcie zasilające.
          – nie bardzo wiem jakie masz diody, ale w przypadku LED ZAWSZE powinieneś używać rezystorów (np360ohm)… a ich brak, to kolejny powód dla którego AtTiny się grzeje!
          – Poczytaj o serwach tutaj: http://uczymy.edu.pl/files/RPi_13_pwm_dla_serw.pdf; tekst jest o RPi – ale początek Ci się przyda:)
          Pozdrawiam,
          A

  2. Witam. Robię wszystko według poradnika, mogę normalnie wgrywać programy przez arduino IDE jednak po wgraniu digi cdc w menadżerze urządzeń nadal pokazuje się: nieznane urządzenie USB( nieprawidłowy deskryptor konfiguracji). To samo przy próbie wgrania micronucleus-2.0a4. Co mogę z tym zrobić?

      1. Używam windows 8.1. Wyłączyłem automatyczną instalację sterowników oraz sprawdzanie podpisów sterowników i nadal bez efektów. Próbuję na przemian instalować sterowniki, automatycznym instalatorem zadig, oraz po pojawieniu się w menadżerze urządzeń, z folderu micronucleus-2.0a4. Na chwilę obecną po wpięciu w usb w menadżerze urządzeń pokazuje się dodatkowa zakłada: libusb32 win devices i w niej urządzenie micronucleus, a po pięciu sekundach oczekiwania na program znika i pojawia się jako to wyżej wspomniane, nieznane urządzenie usb z błędem deskryptora.

Dodaj komentarz