Семя для randomSeed

Otto
Offline
Зарегистрирован: 26.06.2016

Есть свободные все 6 аналоговых выходов на Atmega8, которые намерен использовать для получения помех.

Atmega8 на печатной плате, сделал висящие в "воздухе" дорожки немного разной длины от пинов для улова разных значений помех.

 

Может есть какая более эффективная формула сложения, умножения, остатка от деления и т.д, что бы задействовать все выходы для максимально рандомного начального значения для "randomSeed"?

 

Попробовал такой подход, вроде неплохо:

uint16_t pull_seed = (A0 * A2) - A4 - (A1 / A3) + A5;

 

И скармливаю "pull_seed" randomSeed. Но уверен, что можно придумать более эффективную формулу с использованием всех неинициализированных пинов.

 

P.S. Смотрел одновременно на все порты через Serial и значения в покое на всех портах колышаться в очень маленьком диапазаоне.

Естественно поднося руку в пинам или перенося прототип в пространстве, значения прыгают, но суть в том, что прибор будет статичен, вот и заинтересовал вопрос выше, что бы увеличить диапазаон значений помех программным методом.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Антенну на пин приделай...

SergeiL
SergeiL аватар
Offline
Зарегистрирован: 05.11.2018

Otto пишет:

Есть свободные все 6 аналоговых выходов на Atmega8, которые намерен использовать для получения помех.

Atmega8 на печатной плате, сделал висящие в "воздухе" дорожки немного разной длины от пинов для улова разных значений помех.

 

Может есть какая более эффективная формула сложения, умножения, остатка от деления и т.д, что бы задействовать все выходы для максимально рандомного начального значения для "randomSeed"?

 

Попробовал такой подход, вроде неплохо:

uint16_t pull_seed = (A0 * A2) - A4 - (A1 / A3) + A5;

 

И скармливаю "pull_seed" randomSeed. Но уверен, что можно придумать более эффективную формулу с использованием всех неинициализированных пинов.

 

P.S. Смотрел одновременно на все порты через Serial и значения в покое на всех портах колышаться в очень маленьком диапазаоне.

Естественно поднося руку в пинам или перенося прототип в пространстве, значения прыгают, но суть в том, что прибор будет статичен, вот и заинтересовал вопрос выше, что бы увеличить диапазаон значений помех программным методом.

А если взять младшие 2 разряда с каждого аналогового порта и собрать сдвигом в 16-ти битную переменную?  

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Otto пишет:

...для максимально рандомного начального значения для "randomSeed"?

 

Не бывает "максимально рандомного" и "минимально рандомного".

Даже насчет просто "рандомного" уже есть вопросы: например, число 19283 - рандомное или нет?

 

Ну а для инициализации "особо рандомное" и не нужно - достаточно, чтобы при последующих запусках "затравка" различалась хотя бы на единицу.

Но в поисках совершенства выше был предложен оптимальный алгоритм: склеить из младших битов нескольких результатов замера.

nik182
Offline
Зарегистрирован: 04.05.2015

Рамдомность полученного значения не измениться от того сколько входов брать и как их скрещивать между собой. Достаточно одного значения с одного входа с достаточно длинной антенной. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Я вот тут подумал, как действительно качественно задать затравку, и у меня получилось что-то следующее:

1. Устанавливаем, что текущий вход у нас А0.

2. Читаем с текущего входа значение.

3. Если значение == 0, goto 8.

4. Если значение == 1023, goto 8.

5. Считываем предварительно сохраненное в EEPROM значение.

6. Если значение == считанному из EEPROM, goto 8.

7. goto 9.

8. Инкрементируем текущий вход, goto 2.

9. Записываем полученное число в EEPROM и пользуемся им как затравкой для ГПСЧ.

Правда, возникает вопрос: если мы перебрали все доступные входы, а искомого не нашли, что делать?

nik182
Offline
Зарегистрирован: 04.05.2015

Если правильно подобрать антенну, то значения будут плясать вокруг среднего значения 512 и никогда не дойдут до 0 или 1023. И никогда не будут повторяться два раза в подряд.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

А можно предложение от дилетанта (меня)?

Что если немного схему усложнить. Использовать для получения значения действительно «антенну», а для того чтобы в ней возбудить ток - использовать импульс/импульсы с другого выхода, длительность импульса(ов) в каких-то пределах выбирать рандомом (как инициализировать этот рандом - ну как-то, на ваш вкус (из простого)). А антенна пусть будет из себя представлять или обмотки «трансформатора/дросселя), но мне кажется просто скрученные пара проводов меж собой «косичкой» вполне сойдут. Один вывод на «антенный вход», второй на «ввод импульса/импульсов». Идея, скорее всего, безумная, но мне кажется удачная (хотя проверить не могу).

nik182
Offline
Зарегистрирован: 04.05.2015

Совершенно неудачная. С большой вероятностью получим одно и то же или близкое значение. Любое внешнее управление, привязанное по времени, а имея тактовый генератор и постоянное количество тактов между воздействием и считыванием значения, напроч убивают рандомность полученного результата. Вспомни измерение емкости конденсатора методом заряда-разряда на ноге МК.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

nik182 пишет:

Совершенно неудачная. С большой вероятностью получим одно и то же или близкое значение. Любое внешнее управление, привязанное по времени, а имея тактовый генератор и постоянное количество тактов между воздействием и считыванием значения, напроч убивают рандомность полученного результата. Вспомни измерение емкости конденсатора методом заряда-разряда на ноге МК.

Но тут же не совсем конденсатор, влияет межвитковая емкость, емкость корпуса (шасси). Да и не договорил. Нужно несколько выборок делать во время импульсов. Я сильно сомневаюсь, что специально одинаковые значения можно получить. Но точно не знаю.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Если в проекте есть RTC, используйте свёртку дата/времени как посев

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

Если в проекте есть RTC, используйте свёртку дата/времени как посев

лично я так и делал, по распределению не скажу, рандом брал в достаточно большом диапазоне (сотни)

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

DetSimen пишет:

Если в проекте есть RTC

А если нету?

DeGlucker
Offline
Зарегистрирован: 23.07.2014

Вместо RTC можно использовать WDT

#include <avr/wdt.h>   

volatile boolean flg;
volatile uint8_t rnd0;

void setup() {

  Serial.begin(115200);
  
  cli();
  wdt_reset();
  WDTCSR |= (_BV(WDCE) | _BV(WDE) |_BV(WDIE));
  WDTCSR  =  _BV(WDIE) | WDTO_1S;
  sei();
  while (!flg) {}
  
  wdt_enable (WDTO_1S);
  srand(rnd0);
  Serial.println(rnd0);
}

// ------------------------------------------------ //
ISR (WDT_vect) {

  rnd0 = TCNT0;
  flg = true;
}

// ------------------------------------------------ //
void loop() { }

Кахдые 2 сек. выдает seed

Otto
Offline
Зарегистрирован: 26.06.2016

Обдумал вашу критику и предложения и поступил немного по другому. 
Использовал стороннюю более лёгкую библиотеку Алекса Гайвера "Random16".

Там есть возможность сделать несколько независимых рандомайзеров, что как раз мне нужно было и значения непредсказуемы. Использовал для двух сидов два неинициализированных входа. Разница со встроенным в Arduino IDE random очень сильно заметна при одинаковых условиях. 

Результатом доволен, тема закрыта, всем спасибо!

SLKH
Offline
Зарегистрирован: 17.08.2015

nik182 пишет:

Совершенно неудачная. С большой вероятностью получим одно и то же или близкое значение. Любое внешнее управление, привязанное по времени, а имея тактовый генератор и постоянное количество тактов между воздействием и считыванием значения, напроч убивают рандомность полученного результата. Вспомни измерение емкости конденсатора методом заряда-разряда на ноге МК.

если на самом деле нужны случайные числа, то следует не гадать, а тестировать результаты.

см.,например, https://www.ulsu.ru/media/uploads/anako09%40mail.ru/2017/10/14/%D0%93%D1%80%D0%B8%D0%B3%D0%BE%D1%80%D1%8C%D0%B5%D0%B2.pdf или https://habr.com/ru/company/securitycode/blog/237695/

Но нужен ли весь этот матан ТС, мы не знаем.

Например, у меня в одном устройстве 2 компрессора должны звгружаться равномерно. Для этого служит припаянная к А0 проволочка и суперсверхкрутой фрагмент в сетапе:

if(analogRead(A0)%2 == 0)
{
PumpPin_1 = 3; 
PumpPin_2 = 4; 
}
else
{
PumpPin_1 = 4; 
PumpPin_2 = 3; 
}
Для конкретного применения рандомности вполне достаточно, даже если это творение не пройдет ни один серьёзный тест.
nik182
Offline
Зарегистрирован: 04.05.2015

Вот. Золотые слова. Исходной рамдомности встроенной хватит на 99% применений. Оставшийся 1% можно взять с аналового входа. Тут опять же вопрос, что дальше. Если первое число рандомить, а остальные брать из встроенного, то рамдомность будем получать всегда одинаковую. Не плохую, кстати. Если постоянно будем подрамдомливать с аналогового входа, то можем оказаться в ситуации ухудшения, как и улучшения.
Если уж совсем хочется въехать в тему рамдомных генераторов и алгоритмов, то можно прочитать как у STM с встроенным RND генератором всё устроено.