29

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.

Nick Gammon
  • 38,901
  • 13
  • 69
  • 125
jfpoilpret
  • 9,162
  • 7
  • 38
  • 54

8 Answers8

16

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.

Cybergibbons
  • 5,420
  • 7
  • 34
  • 51
14

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.

sachleen
  • 7,565
  • 5
  • 40
  • 57
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.

Federico Fissore
  • 1,281
  • 7
  • 10
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();.

jippie
  • 2,901
  • 14
  • 23
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.

Nick Gammon
  • 38,901
  • 13
  • 69
  • 125
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.

vlad b.
  • 749
  • 2
  • 7
  • 13
1

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 :-)

gingo
  • 111
  • 1
0
#include <avr/boot.h>
#ifdef __AVR_ATmega2560__  /// check if a MEGA2560 is in use
#define USEMEGA_ID         ///
void setup()
{
#ifdef __AVR_ATmega2560__
  cli();
  int data3, data4;
  data3 = boot_signature_byte_get(0x04) * 256;
  data4 = boot_signature_byte_get(0x01);
  sei();
  MegaID = data3 + data4;
#endif
Serial.begin(115200);
  Serial.print("MegaID             \t: "); Serial.println(MegaID);
}

// This will show you a 3 digit MegaID
// You can now create different setups for different MEGA2560  with the same source code
sempaiscuba
  • 1,042
  • 9
  • 21
  • 32