Jak mogę uzyskać unikalny identyfikator dla wszystkich moich płyt Arduino?

27

Po przesłaniu szkicu na jedną ze swoich tablic Arduino trudno jest dokładnie wiedzieć, jaki kod źródłowy doprowadził do tego szkicu.

Rzeczywiście, możesz zmienić kod źródłowy swojego szkicu na komputerze bez aktualizacji (w formacie binarnym) na swoją tablicę.

Wpadłem na pomysł stworzenia „ repozytorium szkiców ”, które będzie zapełniane, gdy tylko prześlę szkic do jednej z moich plansz. Następnie mogłem później pobrać kod źródłowy szkicu działającego na dowolnej mojej planszy.

W przypadku takiego repozytorium najpierw potrzebowałbym „ indeksu ”, który pozwoliłby mi dowiedzieć się, z którą tablicą jest powiązany kod źródłowy szkicu.

Zazwyczaj taki indeks powinien być unikalny dla każdej tablicy arduino.

Stąd moje pytanie: jak mogę uzyskać unikatowy identyfikator płyty Arduino?

Edytować:

Oto moja aktualna lista plansz (lista miniumum obsługiwana przez jedno unikalne podejście ID):

  • UNO R3
  • Mega 2560
  • Yun
  • Arduino Robot (muszą to być 2 tablice równoważne Leonardo)

W przyszłości mogę również budować własne płyty (odpowiednik Uno, ale bez kości, bez FTDI), dlatego jeśli podejście obsługuje również te, które byłyby lepsze.

jfpoilpret
źródło
1
@ jfpoilpret ... właśnie zobaczyłem ten post podczas przeglądania strony ... czy znalazłeś rozwiązanie lub najlepszy scenariusz jak to zaimplementować?
dinotom

Odpowiedzi:

14

Istnieje wiele technik, których możesz użyć tutaj, aby uzyskać unikalny identyfikator.

  1. Układy FTDI mają zaprogramowany unikalny numer seryjny. Można to uzyskać tylko od strony połączenia PC, o ile mi wiadomo.
  2. Niektóre układy z wbudowanym USB (np. ATmega8U2 / 16U2 / 32U2) mają unikalny identyfikator w danych podpisu, zwykle używany dla USB. Można łatwo uzyskać dostęp z obu stron połączenia. Obejmuje to ATmega16U2, który jest używany jako USB-> port szeregowy Arduino Uno R3.
  3. Niektóre układy z wbudowanym USB, ale bez unikalnego identyfikatora w sygnaturze, nadal będą miały zaprogramowany unikalny identyfikator w stosie USB (np. LUFA) używany do bootloadera lub DFU (Device Firmware Upgrade).
  4. Istnieje wiele układów z unikatowymi na całym świecie numerami seryjnymi , np. Microchip 11AA02E48 , wszystkie czujniki 1-Wire Dallas (w tym wspólny czujnik temperatury DS18B20) i inne szeregowe EEPROMS. Użyłem ich w sprzęcie produkcyjnym, który musi mieć unikalny adres MAC.
  5. Możesz zmodyfikować standardowy moduł ładujący Optiboot (lub dowolny inny moduł ładujący łódkę), aby mógł przechowywać i odpowiadać unikalnym identyfikatorem.

Problem polega na tym, że nie ma żadnej opcji oprócz 5, która będzie działać na wszystkich tablicach.

Jeśli twoje rozwiązanie będzie ogólne, sugeruję, że użycie identyfikatora USB nie jest rozwiązaniem. Mam ~ 30 płyt opartych na Arduino, a tylko 5 z nich ma wbudowany sprzęt USB. Wszystkie pozostałe wymagają programowania zewnętrznego kabla FTDI. Oznacza to, że wszyscy mieliby ten sam identyfikator.

Cybergibbons
źródło
2
Co masz zrobić z 30 płyt?
asheeshr
Głównie do bezprzewodowych sieci czujników. Mam tylko kilka prawdziwych Arduinos - Duemilanova, Seeeduino Mega i Uno. Wszystkie pozostałe to Teensy, Jeenodes, WiNodes, Nanodes i RFus.
Cybergibbons,
1
+1 za dokładną listę możliwych opcji, dzięki! Wolałbym unikać 4., ponieważ nie chcę dodawać określonego sprzętu do wszystkich moich płyt. 5. wygląda niebezpiecznie (łatwo wgrać ten sam zmodyfikowany bootloader na 2 różne tablice) i kłopotliwy (trzeba mieć inny kod źródłowy bootloadera do załadowania dla każdej płyty). Do tej pory USB ID i FTDI wydają się całkiem dobrymi rozwiązaniami, ale czy działają z wszystkimi moimi obecnymi płytami?
jfpoilpret
Czy Arduino ma globalnie unikalne identyfikatory seryjne? Jak to przeczytać?
lanse7pty
13

Chip nie ma żadnego unikalnego identyfikatora, o ile wiem ... ale możesz zaprogramować go w EEPROM swoich płyt.

Dokumentacja EEPROM

Pisałbyś pod konkretny adres, a następnie przyszłe szkice mogły odczytać identyfikator i zrobić z nim cokolwiek.


Po stronie hosta możesz także zobaczyć unikatowy identyfikator lub adres. Nie wiem wystarczająco dużo o urządzeniach USB, aby powiedzieć ci więcej, ale układ obsługujący komunikację USB może mieć unikalny identyfikator, którego możesz użyć. Twój kod Arduino nie byłby jednak w stanie tego użyć.

Alternatywnie, po prostu użyj drukarki etykiet i umieść etykietę na każdej płycie.

sachleen
źródło
2
Jeśli chodzi o unikalny aspekt pytania, GUID może to rozwiązać (z niewielkim marginesem błędu).
Matthew G.
Początkowo myślałem o użyciu do tego EEPROM; ale wymaga to dodatkowej pracy dla każdej płyty get: utwórz nowy unikalny identyfikator, a następnie zapisz go w pamięci EEPROM. Ponadto mogą występować niezgodności z bibliotekami używanymi przez moje szkice (które mogą zapisywać na ten sam adres EEPROM). Wreszcie w moim kontekście musiałbym odczytać identyfikator z mojego komputera, co jest trudniejsze. Unikalny identyfikator USB wydaje mi się bardziej interesujący.
jfpoilpret
Zgodnie z moją odpowiedzią, jeśli chcesz, aby było to ogólne rozwiązanie (dla większości ludzi i szerokiej gamy płyt), poleganie na identyfikatorze USB oznacza, że ​​ludzie używający kabli FTDI na płytach bez USB-> mostka szeregowego nie byliby w stanie korzystać z twojego systemu.
Cybergibbons,
8

Niektóre płyty, po podłączeniu do komputera, publikują swój numer seryjny. Mój Arduino Uno R3 mówi

[16818.451423] usb 3-2: SerialNumber: 85235353137351E02242

Chociaż nie jestem pewien, jak wyjątkowy jest.

Federico Fissore
źródło
Czy wszystkie tablice Arduino mają taką liczbę? Byłoby miło mieć listę desek, które mają jedną (lub nie).
jfpoilpret
1
Patrząc na kopalnie, nie mają takich opartych na 32u4, 328 i SAM3X8E
Federico Fissore
4

Według mojej najlepszej wiedzy, wszystkie układy USB mają unikalny numer seryjny, przynajmniej dla układów FTDI. W systemie Linux możesz łatwo przypisać do niego unikalne nazwy urządzeń, sprawdź moją stronę internetową .

Poza tym to, co opisujesz, jest w zasadzie prostą formą kontroli wersji . Upewnij się, że pliki źródłowe mają numery wersji. Aby zidentyfikować swoje Arduino, możesz nadać mu Serial.Print();nazwę i wersję kodu podczas setup();.

jippie
źródło
Tak, kontrola wersji jest mniej więcej tym, co chcę osiągnąć; ale ustawianie wersji w kodzie i zmienianie go za każdym razem, gdy zmienia się kod, nie jest opcją (zbyt łatwo zapomnieć). Obecnie używam github do swoich szkiców, ale chciałbym łatwo dowiedzieć się, która wersja tego szkicu jest obecnie uruchomiona na jednej planszy.
jfpoilpret
4
Istnieje makro dla daty i godziny kompilacji __DATE__oraz __TIME__. Tak przynajmniej możesz automatycznie przechowywać te informacje w pliku .hex @jfpoilpret
jippie
Dobrze, że nie myślałem o tych makrach do wersji.
jfpoilpret
2

Wątpię, czy interfejs USB w Uno daje unikalny numer seryjny. Dowolna liczba byłaby częścią kodu przesłanego do układu, który byłby zatem taki sam wśród wielu Unos.

Jednym z podejść jest układ DS2401 „Silicon Serial Number”, który wykorzystuje interfejs One-wire. Wymagałoby to tylko jednego wolnego kodu PIN i trochę kodu (prawdopodobnie byłby to problem).

Najmniej natrętną i prawdopodobnie najbardziej niezawodną metodą byłoby po prostu ponowne odczytanie kodu i sprawdzenie go. Właśnie to robię z moim detektorem sygnatur chipów . Wykrywa to jednak tylko (obecnie zapisany) podpis bootloadera. Dość niewielka zmiana, która może sumować MD5 cały kod szkicu.

Przykładowe dane wyjściowe:

Signature detector.
Written by Nick Gammon.
Signature = 1E  95  0F 
Fuses
Low = FF High = D6 Ext = FF Lock = CF

Processor = ATmega328P
Flash memory size = 32768
Bootloader in use: Yes
EEPROM preserved through erase: Yes
Watchdog timer always on: No
Bootloader is 512 bytes starting at 7E00

Bootloader:

7E00: 02 01 02 03 0405 06 07 08 09 0A 0B 0C 0D 0E 0F 
7E10: 02 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
7E20: 02 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
7E30: 02 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
...
7FB0: 02 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
7FC0: 02 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
7FD0: 02 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
7FE0: 02 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 
7FF0: 02 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 

MD5 sum of bootloader = 56 72 75 2D 5D B5 0D BA 25 10 DF BE 87 D2 A1 27 

Ta suma MD5 (ostatnia linia) jest faktycznie sygnaturą tego konkretnego programu ładującego. W rzeczywistości najnowsza wersja wyszukuje je w tabeli:

MD5 sum of bootloader = FB F4 9B 7B 59 73 7F 65 E8 D0 F8 A5 08 12 E7 9F 
Bootloader name: optiboot_atmega328

Więc, co możesz zrobić, to podczas przesyłania szkicu wygenerować sumę MD5 kodu szesnastkowego. Są na to dość proste sposoby. Następnie możesz wykonać operację „git tag” na kodzie źródłowym, a następnie (przy użyciu zautomatyzowanego lub ręcznego procesu) pamiętać, że konkretna suma kodu szesnastkowego MD5 reprezentuje kod szkicu w danym momencie.

Jakaś baza danych, taka jak:

Chip: Uno
MD5 sum: D8 8C 70 6D FE 1F DC 38 82 1E CE AE 23 B2 E6 E7 
Sketch: My_robot_sketch_42.ino
Git tag: version666

Teraz, aby zlokalizować źródło z tablicy, ustal sumę MD5 kodu (odczytując ją z tablicy), a następnie wyszukaj w swojej bazie danych.

Nick Gammon
źródło
1

Podłączyłem jednoprzewodowy czujnik temp., Z których każdy ma unikalny „ja”. Wszystkie szkice czytały „Ja przy starcie” i zapisywały adres przy każdym połączeniu szeregowym. Zrobiłem tarczę z całym sprzętem, którego potrzebowałem, więc jeśli potrzebowałbym uaktualnić Uno do Mega, urządzenie zachowałoby swoje unikalne ja.

vlad b.
źródło
0

Istnieje niewielka biblioteka do odczytu i zapisu niestandardowego identyfikatora sprzętu w pamięci EEPROM. Możesz go użyć, aby uniknąć popychania niewłaściwego szkicu do Arduino lub do identyfikacji urządzenia do innych celów.

https://github.com/skoumalcz/arduino-id-guard

Oświadczenie: Jestem autorem biblioteki :-)

gingo
źródło