attiny 412 serial number

I'm using attiny412 with 433MHz transmitters in a sensor 'network'. I have several (10-20) devices which I need to uniquely identify. The sensors send data to a ESP8266 for subsequent handling. Currently all that I send is the sensor ID.

Clearly the 412 is short of pins, so setting an ID is problematic unless each device is programmed with an individual ID. This is not an option.

I realised that the 412 has a 'unique' serial number and wondered if I might use this. I was encouraged by the data book which confirms this, but it wasn't entirely obvious to me how to access/read the serial number.

With a little inspired guesswork & a little trial & error, I produced the following code:

//this seems to retrieve the 10 byte serial number - need to verify - seems ok
//will give problems with tx library if a value is 0x00 - string terminator
  byte msga[10];    //this array holds the ten byte serial number
  msga[0]=SIGROW.SERNUM0;
  msga[1]=SIGROW.SERNUM1;
  msga[2]=SIGROW.SERNUM2;
  msga[3]=SIGROW.SERNUM3;
  msga[4]=SIGROW.SERNUM4;
  msga[5]=SIGROW.SERNUM5;
  msga[6]=SIGROW.SERNUM6;
  msga[7]=SIGROW.SERNUM7;
  msga[8]=SIGROW.SERNUM8;
  msga[9]=SIGROW.SERNUM9;
//now convert the msga[] binary array to msg[] ASCII HEX array
  const byte table[] ={"0123456789ABCDEF"};   //lookup table. Binary nibl to HEX ASCII digit
  byte msg[21];   //array for ASCII HEX representation of serial number
  for (byte i=0;i<strlen(msga);++i) //convert 10 byte serial number to 20 byte ASCII HEX serial number
  {
    msg[2*i]=table[(msga[i]>>4) &0x0F];   //convert high nibl. Shift right 4 & mask & lookup
    msg[2*i+1]=table[msg[i] &0x0F];       //low nibl. Mask & lookup
  }
  msg[21]=0x00;     //zero terminate string for tx library

  //send function accepts an array of bytes as first argument
  //second argument is the length of the array
  send((byte*)msg, strlen(msg));

The transmitter library I'm using expects a null terminated string, so I convert the binary array to ASCII hex in another array prior to transmission.

This seems to work fine. I've tried (briefly) with a few devices & they consistently produce unique serial numbers.

I'm looking for confirmation that what I'm doing makes sense(!) I hate it when I don't fully understand code that I've written, even if it (apparently) works.

Ian

Your strategy is fine, but your code has a bug, and is more complicated than it needs to be.
The usual problem with using the built-in serial number is that it isn't the same size (bytes) as the "unique IDs" that you might need (ie ethernet addresses, which are 6 bytes.)

The bug:

  msg[21]=0x00;     //zero terminate string for tx library

arrays are 0-based, so the 21st element of msg is msg[20]; Right now, you're overwriting data one past the end of the array. Who knows what that'll do...
Simpler:
The chip serial number is is normal memory, and is sequential, so you can eliminate the intermediate array and do something like:

#define SERNUM_SIZE 10  // Number of bytes in the on-chip serial number
byte msg[SERNUM_SIZE*2 + 1];   //array for ASCII HEX representation of serial number
const byte *serno = &SIGROW.SERNUM0;  // pointer to the sernums
  for (byte i=0;i<SERNUM_SIZE;++i) //convert 10 byte serial number to 20 byte ASCII HEX serial number
  {
    msg[2*i]=table[(serno[i]>>4) &0x0F];   //convert high nibl. Shift right 4 & mask & lookup
    msg[2*i+1]=table[serno[i] &0x0F];       //low nibl. Mask & lookup
  }
  msg[2*SERNUM_SIZE] = 0;

Thank you so much westfw, that's great :slight_smile:
Thanks too for spotting the bug - what a facepalm :frowning:

Cheers
Ian