Как создать уникальный ID устройства и записать в EEPROM
- Войдите на сайт для отправки комментариев
Сб, 26/01/2019 - 12:04
Стоит задача чтобы каждый контроллео в мей сборке имел уникальный ID.
hardware id не доступно в большинстве arduino. Надо лепить свой аелоспиед.
Пока что придумал вот такую конструкцию:
1. при старте приложения оно читает первые 16+4 байт EEPROM ( последние 4 байта - контрольная сумма )
2. если не ОК то генерит случайные 16 байт , считает crc32 для них и пишет в память:
unsigned char uniqueid[20] = { 0 }; void createUniqueId() { for( int i = 0; i < 16; i++ ) uniqueid[ i ] = analogRead( 0 ); ((uint32_t*)&uniqueid[ 16 ])[0] = CRC32::calculate(uniqueid, 16); for (int i = 0; i < 20; i++) EEPROM.write( i, uniqueid[ i ] ); } void setup() { if( !checkUniqueId() ) createUniqueId() }
вопрос такой: насколько надежно конструкция uniqueid[ i ] = analogRead( 0 ); сгенерит 20 уникальных байт?
Можно ли как то прикинуть на какое кол-во устройств будут повторения?
Может быть уже есть готовые решения чтобы действительно уникальный ID сгенеритьи прописать в память?
Может быть уже есть готовые решения чтобы действительно уникальный ID сгенеритьи прописать в память?
Есть секретный ресурс http://arduino.ru/forumy/programmirovanie , а на нем функция random() с готовым примером.
Подключаете ардуино к компу, а на компе генерерируете UUID и передаете ардуине для записи во флеш. Уникальность гарантируетчя.
Может быть уже есть готовые решения чтобы действительно уникальный ID сгенеритьи прописать в память?
Есть секретный ресурс http://arduino.ru/forumy/programmirovanie , а на нем функция random() с готовым примером.
random - это псевдослучайный ГСЧ. секвенция "случайных" чисел будет одна и та же на всех устройствах.
а у analogRead слишком низкая энтропия - всего 10 бит
поэтому randomSeed(analogRead(0)); будет генерить одни и теже "случайные" числа на каждом из 1023 устройств.
риск что в одной партии сгенерится одинаковый серийный номер слишком велик
Подключаете ардуино к компу, а на компе генерерируете UUID и передаете ардуине для записи во флеш. Уникальность гарантируетчя.
Это таки да, но хочется максимально упростить процесс.
Подключаете ардуино к компу, а на компе генерерируете UUID и передаете ардуине для записи во флеш. Уникальность гарантируетчя.
Это таки да, но хочется максимально упростить процесс.
так написаиь прогу и все автоматом будет происходить
но хочется максимально упростить процесс.
Если нужна гарантия уникальности, то это самое простое решение - дальше упрощать некуда.
Хорошая идея. При таком способе генерации повторения маловероятны. Энтропия неподключенного входа АЦП очень велика, а ты еще и несколько замеров собираешь... все ОК.
Взять замеров с АЦП сколько не жалко, от масива замеров посчитать хеш, любой какой приглянится. Он или его часть и будет ID.
Генератор уникальных чисел можно получить из текущей даты и времени, а "случайные" числа - из времени (с секундами), например, через тригонометрические функции.
осталось дето время взять ;)
Генератор уникальных чисел можно получить из текущей даты и времени, а "случайные" числа - из времени (с секундами), например, через тригонометрические функции.
вот только встроенных часов в arduino нет
Подключил к компьютеру и получил свой номер, если до этого не было.
Можно к компьютеру, можно модуль часов для первого включения подкупить.
Хорошая идея. При таком способе генерации повторения маловероятны. Энтропия неподключенного входа АЦП очень велика, а ты еще и несколько замеров собираешь... все ОК.
Не верю я в "энтропию" аналогового входа.. А если он по грязи на плате будет замкнут на массу - будем получать все время числа в районе нуля.
Можно к компьютеру, можно модуль часов для первого включения подкупить.
Если уж что то и подкупать то DS1990 - вско дешевле часов будет.
Можно небольшой внешний EEPROM (типа 24С16) использовать для хранения счетчика порядкового номера. Подключать его при первом включении, считывать номер, добавлять единицу и записывать обратно.
Может быть уже есть готовые решения чтобы действительно уникальный ID сгенеритьи прописать в память?
Есть секретный ресурс http://arduino.ru/forumy/programmirovanie , а на нем функция random() с готовым примером.
random - это псевдослучайный ГСЧ. секвенция "случайных" чисел будет одна и та же на всех устройствах.
а у analogRead слишком низкая энтропия - всего 10 бит
поэтому randomSeed(analogRead(0)); будет генерить одни и теже "случайные" числа на каждом из 1023 устройств.
риск что в одной партии сгенерится одинаковый серийный номер слишком велик
16 байт на уникальный номер - это ж сколько триллионов объем выпуска планируется?
запрограммировать вход с подтяжкой, коротнуть на землю и взять micros().
при паранойе - повторить несколько раз.
при паранойе - повторить несколько раз.
Боюсь, без нейролептиков и антипсихотиков это будет недостаточно эффективно :(
вот только встроенных часов в arduino нет
__TIME__
Если контроллеры не будут писаться пачками ежесекундно, то вариант "md5(__DATE__ + __TIME__) -> EEPROM" представлятся неплохим вариантом. md5 можно на что-нить покороче заменить, наверняка. С другой стороны - зачем EEPROM, если эта строка будет генерироваться на старте... Разве что побыстрее стартанет МК. Да и то - замерять надо, что накладней выйдет.
P.S. да и хэш там для красоты, в принципе... повыкидывать со строки всё, что "не цифра" - всё равно получится нарастающая величина...
P.P.S. Сорри, не учел, что __DATE__ выдает месяц словом и не подумал, что контроллеры могут шиться одной и той же компиленной прошивкой. Но, если перед каждой прошивкой будет перекомпиляция, то нашёл способ брать unix timestamp: https://stackoverflow.com/questions/23032002/c-c-how-to-get-integer-unix-timestamp-of-build-time-not-string - он то будет уникальным в пределах секунд.
UNIX time достаточно.)
UNIX time достаточно.)
Как оказалось - его не так просто отобрать у компилятора...
Отобрать __DATE__ __TIME__ , а самому перевести в свой "UNIX-time".
Ну, вот выше как раз ссылка на готовый стероидный юникстайм со стековерфлоу.