I want to make hardware ID of a board without using microcontroller or any kind of pre programmed eeprom. All boards of same type will have the same ID. One ID per board type.

I was thinking of using i2c I/O expander and connect different combination of input pins to vcc via resistors to define ID of a board.

Is that good way of doing it? Will that be robust enough?

  • 1
    \$\begingroup\$ What will the ID be used for ? As an input to a MCU ? If yes, why don't you just put the ID in the prgram flash ? Generating one firmware per board type shouldn't be a big constraint. \$\endgroup\$ – dim lost faith in SE May 3 '16 at 8:50
  • \$\begingroup\$ Actually the board itself will not have MCU, it is plug-in board and MCU on host board needs to detect plug-in board type. \$\endgroup\$ – Gossamer May 3 '16 at 9:19
  • \$\begingroup\$ Can you binary code a bunch of spare pins on the connector? \$\endgroup\$ – Transistor May 3 '16 at 9:21
  • \$\begingroup\$ I dont have spare pins, thats the problem. But i have i2c, spi and uart interface. \$\endgroup\$ – Gossamer May 3 '16 at 9:23
  • 1
    \$\begingroup\$ In taht case, I/O expander is indeed a solution. But they are big and costly. Using the smallest MCU you can find may actually be cheaper. \$\endgroup\$ – dim lost faith in SE May 3 '16 at 9:26

If you have a spare ADC input then a good way to do this is with a simple resistor divider. R1 on the Main board and R3 on the Daughter board form the divider. Different daughter boards will have a different value of R3 to present a voltage to the ADC which depends on the board fitted.


simulate this circuit – Schematic created using CircuitLab

  • \$\begingroup\$ Although this is a good idea for OP's problem of identifying various board types, he stated in the comments that the boards do not have spare pins. \$\endgroup\$ – strnk May 3 '16 at 15:37
  • 1
    \$\begingroup\$ A – kinda – crude hack could be to use different pull-up resistors for the I2C wires, then e.g. measure how much current you can source on them. \$\endgroup\$ – Michael May 3 '16 at 17:27

You say a micro in the base unit needs to identify the board type, and that these plugin boards already have a IIC bus going to them.

This is a no-brainer. Put some device the micro can detect on the IIC bus at a unused address. The easiest would probably be the cheapest and smallest IIC EEPROM you can find. In manufacturing you can write whatever information you want into the first few bytes of the EEPROM.

You say you don't want to use a EEPROM or a micro, but give no justification for such arbitrary and seemingly silly restrictions. We can only assume this is then for religious reasons, which have no place in engineering. Do your job right and use the best-fitting solution.

I just checked, and the Microchip 24AA00 16-byte IIC EEPROM is available in a SOT-23 package and costs 18 cents in singles, 14 cents in volume. All you would need is this chip and a bypass cap. You'd have to come up with a really good reason this isn't a good solution.

  • \$\begingroup\$ No religious reasons :) I see your point. I thought of avoiding pre-programming, but I can make that as part of board test cycle... \$\endgroup\$ – Gossamer May 3 '16 at 12:40
  • 2
    \$\begingroup\$ @Olin While I agree that this is probably indeed the most practical solution, I have to say that I empathize with the OP's desire to avoid a programming step during assembly/testing. It's just easier to have a difference in the BOM or circuit, unless you're anyway building a bed-of-nails testing rig or something similar. See my answer for a possible (untested, though) two-pin alternative that does not require programming. \$\endgroup\$ – Timo May 3 '16 at 13:39
  • 1
    \$\begingroup\$ +1. As an alternative, use something like this: digikey.com/en/product-highlight/a/atmel/… which gives you a larger EEPROM and a unique (per device) ID for around the same price. That way you get a free-ish serial number. If you want to avoid programming, you could just record all the serial numbers somewhere central. \$\endgroup\$ – abligh May 3 '16 at 13:44
  • \$\begingroup\$ @Timo If the OP wants to avoid programming, Digikey programs Olin's part at added value. digikey.com/product-detail/en/microchip-technology/24AA00T-I-OT/… \$\endgroup\$ – Scott Seidman May 3 '16 at 15:44
  • \$\begingroup\$ While I agree with the argument that justifications for such limits are needed, there are cases where there are valid reasons for such decisions. There are security environments where additional memory can actually be a security concern, limiting the ability to use your board in the environments you had intended. \$\endgroup\$ – Cort Ammon - Reinstate Monica May 3 '16 at 16:04

You can use a preprogrammed unique serial number chip, some of which have a "family" ID that does not change. Maxim has that type of part. Just ignore the unique serial number part.

  • \$\begingroup\$ They have an I2C version as well (DS28CM00). However the 8bit family code is always 0x01 indicating it is a DS2401. Not sure how you would use that to identify different boards. \$\endgroup\$ – Tom Carpenter May 3 '16 at 15:45

Update: the first version of this answer was wildly wrong, corrected below.

Update 2: added analysis of the required steps between the resistors, and made the method work with a single pin

The following might work, using just one GPIO pins and one pin on the connector. However, I have not tested this:

  • add a simple RC section to the board to be tested. The resistor should be large enough that a short to ground from an IO pin won't damage the pin. The R is then made available on the connector to the base board. You fix the C, and the value of the R will be the board ID.
  • and output pin IO1 is then driven high by the MCU, for a time long enough to guarantee that the capacitor is fully charged. Then, the pin is made a high-Z input, and the time taken until a read of the pin IO1 becomes zero is measured. This time gives you an estimate of Rt, which identifies the board.


simulate this circuit – Schematic created using CircuitLab

Here, R1 is simply to limit the current from the IO pin, and depending on the smallest Rt and the maximum capacitive load of the MCU pins you might be able to do without it. Anyway, \$R1 \ll Rt\$, so that the MCU can fully charge the cap.

Of course, you won't be able to identify many variants with this, as there's a limit to the smallest resistor you can use from the IO pin current limits, and due to tolerances in the capacitor, the IO pin threshold voltage, and so on, you will need to use rather widely spaced values of R for reliable identification.

As pointed out by TomCarpenter, taking the worst case thresholds for $V_h$ and $V_l$ for the IO pins, the spacing has to be rather large. Specifically, as the capacitor discharges, it follows the equation $$ V(t) = V_{cc} e^{-t/\tau}, $$ where \$\tau = R_t C\$ is the time constant. Let there be two different board with time constants \$\tau_1\$ and \$\tau_2\$, and \$\tau_1 < \tau_2\$. Let us require that the time \$t_1\$ for the board with the shorter time constant to discharge to the lower threshold \$V_l\$ is shorter than the time \$t_2\$ for the board with the longer time constant to decay to the upper threshold \$V_h\$. In equations, we have $$ V_l = V_{cc} e^{-t_1/\tau_1}\\ V_h = V_{cc} e^{-t_2/\tau_2},\\ $$ and we require that \$t_1 < t_2\$. This gives us $$ \frac{R_{t_2}}{R_{t_1}} = \frac{\tau_2}{\tau_1} < \frac{\log\frac{V_l}{V_{cc}}}{\log \frac{V_h}{V_{cc}}}. $$ Inserting, for example, the values \$V_l = 1.5V\$ and \$V_l = 3.5\$ with \$V_{cc} = 5V\$ gives \$\frac{R_{t_2}}{R_{t_1}} > 3.38\$ (you would of course check these values from the datasheet of your MCU). So the difference between the values of \$R_t\$ has to be at least that much, plus a little margin for other tolerances, which means that if you want to have three distinct ID's, the shortest and longest times already have a ratio of about 30.

In practice, for a given type of MCU, and since the voltage is always changing in the same direction when measuring, the variance in threshold is not likely to be quite that big. However, as the manufacturer typically does not provide that data, you'd have to test it, and you'd have to test it on quite a few devices to have enough confidence to use this in production. Even then, this might legitimately be considered a bit of a hack rather than a robust solution.

Further, as @TomCarpenter pointed out, while the voltage is between the thresholds there will be increased current consumption.

So overall, this might be useful if:

  1. you're really adamant to not have a programming step. If you're willing to have one, then Olin's method is absolutely the way to go.
  2. you don't have very many distinct types of boards.
  3. You're doing this once at startup, where having to wait reasonably long for the ID, and the temporarily increased current consumption, doesn't matter.
  4. You don't mind adding one extra pin to the board connector, and you have one extra IO pin on the MCU.
  • \$\begingroup\$ The problem with this approach is that the low->high threshold is not fixed. It is generally somewhere between 1.5V and 3.5V for a 5V MCU, which is a massive range of uncertainty. On top of that many manufacturers recommend not floating the inputs at mid voltage range because it massively increases power dissipation (both the MOSFETs on the CMOS input buffers end up turned on at the same time). \$\endgroup\$ – Tom Carpenter May 3 '16 at 13:50
  • \$\begingroup\$ @TomCarpenter This is true, which is why I said that one will need widely spaced resistor values. The power consumption thing is of course true also, but I'm assuming this is done once at startup, where it may not be such a big issue. As I commented to Olin's suggestion, I think his method is better, if one is willing to have a programming step during assembly or testing. \$\endgroup\$ – Timo May 3 '16 at 13:55
  • \$\begingroup\$ @TomCarpenter assuming that the exact threshold could vary indeed anywhere between 1.5V and 3.5V, for you example, then requiring that the time it takes for the smaller resistor value to reach the lower threshold is longer than the time for the higher resistor value to reach the higher threshold gives a minimum ratio of R's of 3.4. So each consecutive R has to be 3.4 times the previous in order to guarantee separation. So as I said, this becomes impractical quickly as the number of distinct ID''s grows. \$\endgroup\$ – Timo May 3 '16 at 14:07
  • \$\begingroup\$ However, I would expect that for any specific real MCU, as long as you're always going from low to high voltage, the threshold for a given pin of a given make and model would not vary quite as much, so with a bit of testing one should be able to get away with a somewhat tighter spacing. \$\endgroup\$ – Timo May 3 '16 at 14:07
  • \$\begingroup\$ @TomCarpenter: I added an analysis of the required resistor spacing (and made the solution work with one pin). \$\endgroup\$ – Timo May 3 '16 at 15:32

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.