random seed ?
henrib75
Posts: 20
in Propeller 1
Hello,
Like many others, I'm struggling to get randomness on the P1... Let me explain my problem. My setup starts up and displays random words (from a list) on the screen. I'm using the "?" from the spin function to get a random long word each time it's displayed. It works very well, but the order is always the same every time I start up... My device starts up on its own and has no interaction (buttons, etc.) where I could get randomness... I have only one free pin that I could use (by leaving it free and reading what it receives over a certain period to get a different seed each time I start up?). I'm open to simple ideas... thanks

Comments
I used to do a lot of programming for the Halloween and Escape Rooms industries, so randomness was something that was important. A forum member (Heater?) provided a Spin version of a C algorithm for better pseudorandom numbers. I'm strict about formatting, so I touched it up and added a randomize(lo, hi) method for my use.
If you download the attached program to a P1 EEPROM and open a terminal, then reset the P1 and you'll see a new list every time it runs. This happens because the cnt register is used to seed the PRNG, and small variations on boot-up time of the P1 help make the starting seed different. I used this object so often it's included in my standard P1 template.
If you don't want to use this object you might try seeding your random value with the cnt register -- maybe that's enough.
Hi,
P1 can read a resistive sensor with a RC combination with one pin. You can use a photoresistor or a ntc temperature sensor. Use only the lowest bits of a reading and add this several times to the pseudo random sequence.
Cheers Christof
A few moments later...
It turns out that you can seed your random value with cnt and get different values. I think think the idea behind the KISS random generator is to have randomness with very even distribution -- that may not be important to what you're doing. If it's not, try this:
pub main | prng, i, r setup prng := cnt term.tx(term#CLS) repeat i from 0 to 9 r := (?prng & $7FFFFFF) // 1001 term.fstr2(string("%1d %4d\r"), i, r)There's also the RealRandom.spin object (comes with PripellerTool) that generates true random numbers without any external components (but does require a cog) by cleverly abusing the PLL and video hardware.
I don't understand how the CNT can play a role? It will always be the same since my application starts automatically; it will always take the same amount of time to reach the code that uses the CNT?
When downloading the program from the PC, CNT will be slightly different each time because [complicated reasons].
However, the EEPROM boot always takes the same amount of time, so this isn't very useful in that case.
I need to regain a grip on this too... Presumably one could fire up RealRandom to get the seed and then kill that cog...
Tried to do RealRandom as inline assembly with Flexprop, but that doesn't work for some reason...
Perhaps because the P1 initially starts in RC mode, and it does spend a bit of time to see if it was an IDE that caused the reset -- all the while, the cnt register is being updated at the RC speed (which will wobble).
As I just pointed out, the P1 boots in RC mode and that will never be exactly the same speed -- there seems to be enough variation in the initial value of cnt to be useful PRNG seed. Even in the RealRandom object that Chip wrote there is this line
Maybe you should try the demo code....
Just to put this to bed, here's a ridiculously simple program that demonstrates the cnt register can be used and the random seed. I downloaded this program to EE (use F11) and pressed the reset button several times -- notice how the value is DIFFERENT every time.
Final test: I captured the cnt register BEFORE doing anything else. Instead of pressing reset, I unplugged the FLiP module and then plugged it back in. Yes, the cnt register values (other than the first) are close, but they are NOT the same. Feeding this in to the PRNG will give you a different sequence each time.
What goes on there is more complex though. It does a WAITVID to synchronize to the video hardware, which is clocked off PLLA. PLLA is deliberately fed with clock glitches to keep it from locking. So when WAITVID hits the WHOP, an indeterminate amount of time has passed and the low bits of CNT are randomized.
@JonnyMac but maybe it’s a finite range of values that isn’t as good as 32 bits ?
I don't know that it matters because the goal is to have a different seed on start-up -- after that the PRNG is going to do what it does, and even very small changes will cause a difference in the pseudorandom sequence.
Well probably depends on how random the seed needs to be…. App dependent for sure.
If the seed is feeding a PRNG, I don't think it needs wild randomness, it just needs to be different on boot up -- after that, the PRNG algorithm is in control and you're just entering the list of pseudorandom values at a different point. When I coded Halloween and Escape Room props we had a trigger input, so we would constantly call the PRNG until a trigger event; this added real randomness to the prop. That said, the OP doesn't seem to have or want to use an external trigger. I think my experiments here have shown than for most apps it's not necessary, and I would submit that there is no advantage to seeding the P1 PRNG with RealRandom versus using the cnt register at the start of the program.