Генерация случайного числа в ПЛК
Для реализации определенных задач потребовалась генерация случайных чисел.
Перечитав форумы, нашлось достаточно решений и мнений, но все они сводились к одному из трех решений:
- Использовать функцию случайного числа из библиотек.
- Генерировать случайное число от времени.
- Использовать непонятные длинные формулы.
Но каждое из решений не устроило, по той или иной причине.
Требуется быстрая генерация случайного числа, да еще с хорошей не повторяемостью чисел.
Мне попалась статья американского математика Джорджа Марсаглии (George Marsaglia) о генерации случайного числа путем простых действий. Данный метод называется Xorshift RNGs.
Со статьей в оригинале можно ознакомиться по ссылке: Xorshift RNGs. George Marsaglia. The Florida State University
На основе статьи написал функциональный блок, который отлично удовлетворяет всем требованиям, простой в реализации и работает во всех ПЛК, которые я использую в своих проектах.
Заголовок функционального блока:
FUNCTION_BLOCK xorshift
VAR_INPUT
In1: DWORD;
In2: DWORD;
END_VAR
VAR_OUTPUT
Out1: DWORD:=1;
Out2: DWORD:=2;
Random: REAL;
END_VAR
VAR
END_VAR
Код функционального блока:
in1 := in1 XOR SHL(in1,23);
in1 := in1 XOR SHR(in1,17);
in1 := in1 XOR in2;
in1 := in1 XOR SHR(in2,26);
random := (1.0/4294967295.0*(in1+in2))+0.5;
out1 := in1;
out2 := in1+in2;
Пример использования функционального блока:
VAR
RND:xorshift; (*Инициализация FB*)
END_VAR
RND(in1:=RND.out1,in2:=RND.out2); (*Генерация случайного числа*)
RND.Random; (*Случайное число*)
В каждом цикле ПЛК получаете сгенерированное случайное число с большим периодом повторения.
В переменной RND.Random
содержится значение от 0 до 1.
Категории
- Автоматизация (1)
- Диспетчеризация (1)
- Документация (4)
- Разработка (1)