26

Once you have uploaded a sketch to one of your Arduino boards, it is hard to know exactly what source code led to that sketch.

Indeed, you may change the source code of your sketch on your PC without updating it (in binary format) to your board.

I had the idea of setting up a kind of "sketch repository" that would be populated as soon as I upload a sketch to one of my boards. Then I could retrieve, later on, the source code for a sketch running on any of my boards.

For such a repository, I would first need to have an "index" that would enable me to know which board the sketch source code is linked to.

Typically, such an index should be unique for every single arduino board.

Hence my question: how can I get a unique ID for an Arduino board?

Edit:

This is my current list of boards (the miniumum list to be supported by a single unique ID approach):

  • UNO R3
  • Mega 2560
  • Yun
  • Arduino Robot (that must be 2 Leonardo equivalent boards)

In the future, I may also build my own boards (Uno equivalent but barebones, without FTDI), hence if an approach also supports these that would be better.

  • 1
    @jfpoilpret...just saw this post while perusing the site..did you find a solution, or best case scenario on how to implement this? – dinotom May 2 '16 at 11:06
15

There are a number of techniques you could use here to get a unique ID.

  1. FTDI chips have a unique serial number programmed onto them. This can only be accessed from the PC side of the connection as far as I am aware.
  2. Some of the chips with built in USB (e.g. ATmega8U2/16U2/32U2) have a unique ID in the signature data, normally used for USB. Can easily be accessed from both sides of the connection. This includes the ATmega16U2 that is used as the USB->Serial bridge Arduino Uno R3.
  3. Some of the chips with built in USB but no unique ID in the signature will still have a unique ID programmed into the USB stack (e.g. LUFA) used for the bootloader or DFU (Device Firmware Upgrade).
  4. There are many chips with globally unique serial IDs in them e.g. the Microchip 11AA02E48, all of the Dallas 1-Wire sensors (including the common DS18B20 temperature sensor), and other serial EEPROMS. I've used these in production hardware that must have a unique MAC address.
  5. You could modify the standard Optiboot bootloader (or whichever boat loader you use) so that it can hold and respond with a unique ID.

The problem with these is that there is no option except 5 that will work across all boards.

If your solution is going to be a generic one, I would suggest that using a USB ID is not the way forwards. I have ~30 Arduino-based boards, and only 5 of them have built in USB hardware. All the rest of them need an external FTDI cable to be programmed. This means they would all have the same ID.

  • 2
    What do you do with 30 boards? – asheeshr Feb 18 '14 at 10:17
  • Mainly for wireless sensor networks. I only have a few real Arduinos - a Duemilanova, a Seeeduino Mega and an Uno. All the others are Teensy, Jeenodes, WiNodes, Nanodes and RFus. – Cybergibbons Feb 18 '14 at 11:26
  • 1
    +1 for a thorough list of possible options, thanks! I'd rather avoid 4. as I don't want to add specific hardware to all my boards. 5. looks dangerous (easy to upload the same modified bootloader to 2 different boards) and cumbersome (need to have different bootloaders source code to upload for every board). So far, USB ID and FTDI seem quite good solutions, but do they work with all my current board? – jfpoilpret Feb 18 '14 at 20:36
  • Does Arduino have globally unique serial IDs ? How to read it ? – lanse7pty Dec 16 '16 at 5:11
13

The chip doesn't have any sort of unique ID as far as I know.... but you could program one into the EEPROM of your boards.

EEPROM documetnation

You would write to a specific address and then future sketches can read the ID and do whatever with it.


You may also be able to see a unqiue ID or address on the host side. I don't know enough about USB devices to tell you more, but the chip handling USB communication might have a unique ID you could use. Your Arduino code would not be able to use this, though.

Alternatively, just use a label maker and put a label on each board.

  • 2
    As far as the unique aspect of the question, a GUID could solve that (within some tiny margin of error). – Matthew G. Feb 18 '14 at 1:44
  • I had originally thought of using the EEPROM for that; but that requires additional work for every board get: create a new unique ID, then write it to the EEPROM. Also, there may be incompatibilities with libraries used by my sketches (that may write to the same EEPROM address). Finally in my context, I would need to read the ID from my PC, which is more difficult. The USB unique ID seems more interesting to me. – jfpoilpret Feb 18 '14 at 4:12
  • As per my answer, if you want this to be a generic solution (for most people, and a wide range of boards), relying on the USB ID means that people using FTDI cables on boards without a USB->Serial bridge would not be able to use you system. – Cybergibbons Feb 18 '14 at 8:28
8

Some boards, when connected to a computer, publish their serial number. My Arduino Uno R3 says

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

Though I'm not sure how unique it is.

  • Do all Arduino boards have such a number? It would be nice to have the list of boards that have one (or not). – jfpoilpret Feb 18 '14 at 4:14
  • 1
    Looking at mines, 32u4 based ones don't, 328 and SAM3X8E ones do have it – Federico Fissore Feb 18 '14 at 8:06
4

To the best of my knowledge the USB chips all come with a unique serial number, at least for the FTDI chips. On Linux you can easily assign unique device names from that, check my website.

Other than that, what you are describing is pretty much a simple form of version control. Make sure your source files have version numbers. To identify your Arduino, you can make it Serial.Print(); name and version of the code during setup();.

  • Yes version control is more or less what I want to achieve; but setting a version in code and changing it every time the code changes is not an option (too easy to forget). I currently use github for my sketches, but I'd like to easily find out what version of what sketch is currently running on one board. – jfpoilpret Feb 18 '14 at 20:18
  • 4
    There is a macro for compilation date and time __DATE__ and __TIME__. So at least you can automatically store that info in your .hex file @jfpoilpret – jippie Feb 18 '14 at 20:55
  • Good point, I hadn't thought about these macros for versioning. – jfpoilpret Feb 18 '14 at 20:59
2

I doubt that the USB interface on the Uno gives you a unique serial number. Any number would be part of the code uploaded to the chip which would therefore be the same amongst multiple Unos.

One approach is the DS2401 "Silicon Serial Number" chip which uses the One-wire interface. That would only require one free pin, and some code (the code would be the problem, possibly).

The least intrusive method, and probably the most reliable, would be to simply read back the code and sum-check it. That is exactly what I do with my chip signature detector. However that only detects (as currently written) the bootloader signature. A fairly minor change and it could MD5-sum the entire sketch code.

Example output:

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 

That MD5 sum (last line) is effectively the signature of that particular bootloader. In fact the most recent version looks them up in a table:

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

So what you could do is, when uploading a sketch, generate a MD5 sum of the hex code. There are fairly simple ways of doing that. Then you could do a "git tag" operation on your source code, and then (using some automated or manual process) remember that a particular MD5 sum of hex code represents the sketch code at a particular moment.

Some sort of database like:

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

Now to locate the source from the board, you establish the MD5 sum of the code (by reading it back from the board) and then look it up in your database.

1

I connected a one wire temp sensor that each come with an unique I'd. All the sketches read the I'd on boot and wrote the address on every serial connection. I made a shield with all the hardware I needed so if I needed to upgrade from Uno to Mega the device kept its unique I'd.

0

There is tiny library for reading and writing your custom hardware ID to EEPROM. You can use it to avoid pushing wrong sketch to your Arduino or to identify device for other purposes.

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

Disclaimer: I'm author of the library :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.