Forum Rule: Always post complete source code & details to reproduce any issue!

# Thread: Best Teensy 3.1 Random Number Generator?

1. ## Best Teensy 3.1 Random Number Generator?

I'm about to port a project from Arduino Uno to Teensy 3.1 that relies on unpredictable random numbers. On the Uno I use this bit of awesome code called Probably Random:

https://gist.github.com/endolith/2568571

As you can see, it uses the AVR Watchdog Interrupt for entropy, so I assume it won't compile on Teensy. Is there another method I can use on Teensy 3.1 to return "truly" random numbers? Or at least an entropy method that makes the Arduino Random() function usable? Thanks for the help!

2. read A/D that whose input pin is floating and yielding noisy numbers?
sum as unsigned all bytes in RAM?
else have to build some hardware like reversed biased diode hooked to A/D.

These are just once, to seed the standard PNG library code.

3. Some time ago I looked into porting this library, but using the LPTMR from the 1 kHz slow clock source rather than the watchdog.

4. Originally Posted by PaulStoffregen
Some time ago I looked into porting this library, but using the LPTMR from the 1 kHz slow clock source rather than the watchdog.
Cool! Mark me down as one who would use such a thing. Or any drop-in function that returns a unique byte every time the Teensy boots (with no clock).

5. You could use a random source, such as the least-significant bits of a 16-bit ADC reading, to seed an LFSR (see the wiki article here: http://en.wikipedia.org/wiki/Linear_...shift_register).

LFSRs can be arranged to be maximal length, in that they don't repeat values until having output all other values. To get the seed for say a 16-bit LFSR, take 4 16-bit ADC readings, and take the 4 LSBs off each (eg. the "noise") and concatenate into a 16-bit seed. Perhaps then have the LFSR generate a random number of readings prior to outputting useful values.

6. Originally Posted by nox771
You could use a random source, such as the least-significant bits of a 16-bit ADC reading, to seed an LFSR (see the wiki article here: http://en.wikipedia.org/wiki/Linear_...shift_register).

LFSRs can be arranged to be maximal length, in that they don't repeat values until having output all other values. To get the seed for say a 16-bit LFSR, take 4 16-bit ADC readings, and take the 4 LSBs off each (eg. the "noise") and concatenate into a 16-bit seed. Perhaps then have the LFSR generate a random number of readings prior to outputting useful values.
You could also XOR with the individual Teensy's MAC address -- they are unique.

Code:
```#include <stdlib.h>

#define LEDpin   13

void setup() {
uint8_t m[6];
char MAC[] = "X11:22:33:44:55:66";

// Setup Serial connection
Serial.begin(9600);
pinMode(LEDpin, OUTPUT); digitalWrite(LEDpin, HIGH);
while (!Serial) {digitalWrite(LEDpin, HIGH); delay(10); digitalWrite(LEDpin, LOW); delay(80); }

FTFL_FCCOB0 = 0x41;             // Selects the READONCE command
FTFL_FCCOB1 = 0x0E;             // read the given word of read once area
// -- this is one half of the mac addr.
FTFL_FSTAT = FTFL_FSTAT_CCIF;   // Launch command sequence
while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) {}
// Skip FTFL_FCCOB4 as it's always 0.
*(m+0) = FTFL_FCCOB5;       // collect only the top three bytes,
*(m+1) = FTFL_FCCOB6;       // in the right orientation (big endian).
*(m+2) = FTFL_FCCOB7;

FTFL_FCCOB1 = 0x0F;             // read the given word of read once area
FTFL_FSTAT = FTFL_FSTAT_CCIF;   // Launch command sequence
while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) {}
// Skip FTFL_FCCOB4 as it's always 0.
*(m+3) = FTFL_FCCOB5;       // collect only the top three bytes,
*(m+4) = FTFL_FCCOB6;       // in the right orientation (big endian).
*(m+5) = FTFL_FCCOB7;

for (int i=0; i < 6; i++) {Serial.write(itoa(m[i]+0x100, MAC, 16)+1); Serial.write(i < 5 ? ':' : '\n');}
}

void loop() {} // dummy```

7. Here's a copy of the Entropy library ported to Teensy3.

You'll need to create an empty wdt.h file in hardware/teensy/cores/teensy3/avr. Or just comment out the line #include line in Entropy.h.

Please let me know how this works for you?

8. Originally Posted by PaulStoffregen
Please let me know how this works for you?
Brilliant! Works perfectly. Thank you so much.

9. Walter Anderson has updated the official Entropy library with Teensy 3.x support.

10. I just unzipped the latest Entropy lib. Example DICE compiles for UNO and teensy ++ 2, but for teensy 3 I get compiles errors

Code:
```sketchbook/libraries/Entropy/Entropy.cpp: In member function 'uint32_t EntropyClass::random()':
sketchbook/libraries/Entropy/Entropy.cpp:92:16: error: 'ATOMIC_RESTORESTATE' was not declared in this scope
sketchbook/libraries/Entropy/Entropy.cpp:92:35: error: 'ATOMIC_BLOCK' was not declared in this scope
sketchbook/libraries/Entropy/Entropy.cpp:93:3: error: expected ';' before '{' token```
OK, i added #include <util/atomic.h> to Entropy.cpp. that seemed to fix it.
still worked for UNO, for DUE the include needs to be inside #ifndef ARDUINO_SAM_DUE
Paul can you let Walter Anderson know?

11. I checked the Teensy core, and found that Paul has provided equivalents for the Atomic functions. So I modified the header file to inlcude the util/atomic.h file if TEENSYDUINO is defined. I have uploaded the corrected Entropy.h file to the google code page as well as prepare a new zip file Entriopy-v1.0.1.zip which includes the bug fix. The correct fix (utils/atomic.h should NOT be included for the #ifndef ARDUINO_SAM_DUE is:

// Separate the ARM Due headers we use
#ifdef ARDUINO_SAM_DUE
#include <sam.h>
#include <sam3xa/include/component/component_trng.h>
#endif

#ifdef TEENSYDUINO
#include <util/atomic.h>
#endif

#ifdef __AVR__
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/atomic.h>
#endif

12. Looks like this is fixed in version 1.0.1. I'm updating the copy on the PJRC website and in the upcoming Teensyduino 1.19...

13. Cool! Thanks!

14. Nice library implementation.
Is there any way to use this to just get an initial seed, and then turn off the ISR so that it does not interrupt any more?
I'm thinking that an end or stop method would be a nice and handy addition. The idea is I could grab an initial seed value, and then use the IRQ/watchdog for something else.

15. Originally Posted by xxxajk
Nice library implementation.
Is there any way to use this to just get an initial seed, and then turn off the ISR so that it does not interrupt any more?
I'm thinking that an end or stop method would be a nice and handy addition. The idea is I could grab an initial seed value, and then use the IRQ/watchdog for something else.
On this site, Arduino random seed I have an example sketch on how to use the same basic approach on an AVR to just seed the pseudo-random number generator. If you look at the source code for the entropy library, it should be easy to modify that example for whichever teensy you want.

Now for the downside, while the example sketch uses fewer resources than the library, and the interrupt is turned off after the seed is generated, it is still attached to the interrupt vector. You'll need to find an example of how (if possible) to reassign the interrupt vector to a different handler.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•