How can I get random numbers on AVR?












2














I will try to make the game MegaMind. I need to get a random number, but how can I get these?



I have tried something:



secret_code[1] = random()&=6;









share|improve this question









New contributor




Dion123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Which AVR? Does it have a hardware random number generator, or an ADC?
    – Colin
    3 hours ago










  • On the ATMega328p I will create a random number!
    – Dion123
    3 hours ago






  • 2




    Here are four things I know about random numbers: 1) They're fiendishly hard to do 'really right'. 2) There are tons of well-documented algorithms on the Internet, there for the searching (hint, hint). 3) You can do an adequate job on a bitty little processor, particularly if it's for casual stuff like gaming. 4) I'm no expert beyond points 1, 2 & 3. Why don't you search, then tell us what you found and why you're either still confused or unhappy with your options? I suggest "good random number generator for gaming" as a starting point for your search.
    – TimWescott
    3 hours ago






  • 2




    "I have tried something:" -- So what happened? That line of code doesn't look like it would even compile -- a function call (random()) can't be an lvalue (for the operator &=).
    – Dave Tweed
    2 hours ago






  • 2




    This is a hard problem in general, so it's usually best to look at the specific need. What are the random numbers for? What else is going on? The early Simon electronic memory game for example used the low bits of a free running counter - technically the "random" patterns were determined by how long it took the user to push a button, but at a resolution which no human could recognize or game.
    – Chris Stratton
    2 hours ago


















2














I will try to make the game MegaMind. I need to get a random number, but how can I get these?



I have tried something:



secret_code[1] = random()&=6;









share|improve this question









New contributor




Dion123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Which AVR? Does it have a hardware random number generator, or an ADC?
    – Colin
    3 hours ago










  • On the ATMega328p I will create a random number!
    – Dion123
    3 hours ago






  • 2




    Here are four things I know about random numbers: 1) They're fiendishly hard to do 'really right'. 2) There are tons of well-documented algorithms on the Internet, there for the searching (hint, hint). 3) You can do an adequate job on a bitty little processor, particularly if it's for casual stuff like gaming. 4) I'm no expert beyond points 1, 2 & 3. Why don't you search, then tell us what you found and why you're either still confused or unhappy with your options? I suggest "good random number generator for gaming" as a starting point for your search.
    – TimWescott
    3 hours ago






  • 2




    "I have tried something:" -- So what happened? That line of code doesn't look like it would even compile -- a function call (random()) can't be an lvalue (for the operator &=).
    – Dave Tweed
    2 hours ago






  • 2




    This is a hard problem in general, so it's usually best to look at the specific need. What are the random numbers for? What else is going on? The early Simon electronic memory game for example used the low bits of a free running counter - technically the "random" patterns were determined by how long it took the user to push a button, but at a resolution which no human could recognize or game.
    – Chris Stratton
    2 hours ago
















2












2








2


1





I will try to make the game MegaMind. I need to get a random number, but how can I get these?



I have tried something:



secret_code[1] = random()&=6;









share|improve this question









New contributor




Dion123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I will try to make the game MegaMind. I need to get a random number, but how can I get these?



I have tried something:



secret_code[1] = random()&=6;






random-number






share|improve this question









New contributor




Dion123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Dion123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 3 hours ago









Dave Tweed

117k9145256




117k9145256






New contributor




Dion123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 3 hours ago









Dion123

161




161




New contributor




Dion123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Dion123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Dion123 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • Which AVR? Does it have a hardware random number generator, or an ADC?
    – Colin
    3 hours ago










  • On the ATMega328p I will create a random number!
    – Dion123
    3 hours ago






  • 2




    Here are four things I know about random numbers: 1) They're fiendishly hard to do 'really right'. 2) There are tons of well-documented algorithms on the Internet, there for the searching (hint, hint). 3) You can do an adequate job on a bitty little processor, particularly if it's for casual stuff like gaming. 4) I'm no expert beyond points 1, 2 & 3. Why don't you search, then tell us what you found and why you're either still confused or unhappy with your options? I suggest "good random number generator for gaming" as a starting point for your search.
    – TimWescott
    3 hours ago






  • 2




    "I have tried something:" -- So what happened? That line of code doesn't look like it would even compile -- a function call (random()) can't be an lvalue (for the operator &=).
    – Dave Tweed
    2 hours ago






  • 2




    This is a hard problem in general, so it's usually best to look at the specific need. What are the random numbers for? What else is going on? The early Simon electronic memory game for example used the low bits of a free running counter - technically the "random" patterns were determined by how long it took the user to push a button, but at a resolution which no human could recognize or game.
    – Chris Stratton
    2 hours ago




















  • Which AVR? Does it have a hardware random number generator, or an ADC?
    – Colin
    3 hours ago










  • On the ATMega328p I will create a random number!
    – Dion123
    3 hours ago






  • 2




    Here are four things I know about random numbers: 1) They're fiendishly hard to do 'really right'. 2) There are tons of well-documented algorithms on the Internet, there for the searching (hint, hint). 3) You can do an adequate job on a bitty little processor, particularly if it's for casual stuff like gaming. 4) I'm no expert beyond points 1, 2 & 3. Why don't you search, then tell us what you found and why you're either still confused or unhappy with your options? I suggest "good random number generator for gaming" as a starting point for your search.
    – TimWescott
    3 hours ago






  • 2




    "I have tried something:" -- So what happened? That line of code doesn't look like it would even compile -- a function call (random()) can't be an lvalue (for the operator &=).
    – Dave Tweed
    2 hours ago






  • 2




    This is a hard problem in general, so it's usually best to look at the specific need. What are the random numbers for? What else is going on? The early Simon electronic memory game for example used the low bits of a free running counter - technically the "random" patterns were determined by how long it took the user to push a button, but at a resolution which no human could recognize or game.
    – Chris Stratton
    2 hours ago


















Which AVR? Does it have a hardware random number generator, or an ADC?
– Colin
3 hours ago




Which AVR? Does it have a hardware random number generator, or an ADC?
– Colin
3 hours ago












On the ATMega328p I will create a random number!
– Dion123
3 hours ago




On the ATMega328p I will create a random number!
– Dion123
3 hours ago




2




2




Here are four things I know about random numbers: 1) They're fiendishly hard to do 'really right'. 2) There are tons of well-documented algorithms on the Internet, there for the searching (hint, hint). 3) You can do an adequate job on a bitty little processor, particularly if it's for casual stuff like gaming. 4) I'm no expert beyond points 1, 2 & 3. Why don't you search, then tell us what you found and why you're either still confused or unhappy with your options? I suggest "good random number generator for gaming" as a starting point for your search.
– TimWescott
3 hours ago




Here are four things I know about random numbers: 1) They're fiendishly hard to do 'really right'. 2) There are tons of well-documented algorithms on the Internet, there for the searching (hint, hint). 3) You can do an adequate job on a bitty little processor, particularly if it's for casual stuff like gaming. 4) I'm no expert beyond points 1, 2 & 3. Why don't you search, then tell us what you found and why you're either still confused or unhappy with your options? I suggest "good random number generator for gaming" as a starting point for your search.
– TimWescott
3 hours ago




2




2




"I have tried something:" -- So what happened? That line of code doesn't look like it would even compile -- a function call (random()) can't be an lvalue (for the operator &=).
– Dave Tweed
2 hours ago




"I have tried something:" -- So what happened? That line of code doesn't look like it would even compile -- a function call (random()) can't be an lvalue (for the operator &=).
– Dave Tweed
2 hours ago




2




2




This is a hard problem in general, so it's usually best to look at the specific need. What are the random numbers for? What else is going on? The early Simon electronic memory game for example used the low bits of a free running counter - technically the "random" patterns were determined by how long it took the user to push a button, but at a resolution which no human could recognize or game.
– Chris Stratton
2 hours ago






This is a hard problem in general, so it's usually best to look at the specific need. What are the random numbers for? What else is going on? The early Simon electronic memory game for example used the low bits of a free running counter - technically the "random" patterns were determined by how long it took the user to push a button, but at a resolution which no human could recognize or game.
– Chris Stratton
2 hours ago












2 Answers
2






active

oldest

votes


















3














From the AVR Libc Reference Manual, under stdlib.h: General utilities:




Function rand():



int rand(void)



The rand() function computes a sequence of pseudo-random integers in
the range of 0 to RAND_MAX (as defined by the header file
<stdlib.h>).



The srand() function sets its argument seed as the seed for a new
sequence of pseudo-random numbers to be returned by rand(). These
sequences are repeatable by calling srand() with the same seed
value.



If no seed value is provided, the functions are automatically seeded
with a value of 1.



In compliance with the C standard, these functions operate on int
arguments. Since the underlying algorithm already uses 32-bit
calculations, this causes a loss of precision. See random() for an
alternate set of functions that retains full 32-bit precision.




Basically, you want to use srand() to set a seed for rand() to use. rand() will generate the numbers based on the seed srand() provides.



A common way to get a seed for srand() is to use a timer that is based on some user action so you get a fairly unique sequence every time. If you don't change the seed, the number sequence will always be the same.






share|improve this answer























  • @evildemonic The timer won't help much if there is no RTC. On such a limited embedded platforms there are other sources of entropy required. Such as temperature-sensitive analog input. Update - well, a timer based on user action is an option. It's just that it is not always the case there is a user action before the result is required..
    – Eugene Sh.
    2 hours ago












  • @EugeneSh. This is why I specified based on user action. Since the OP is talking about a game, I doubt they need super true authentic random. If so, yes, using for instance an ADC value reading the noise on a diode or something could be better.
    – evildemonic
    2 hours ago












  • I appreciate you folks helping me improve my answer, and bring you up good points. Since this is a game, there should be user action at some point, and this can perhaps be 'forced' early on. The seed can be generated at any point before the random number is needed. Something as simple as timing how long it takes for the player to enter their name, or select an option from the opening menu. Without more input from the OP, it is hard to speculate on what they need and what we have to work with.
    – evildemonic
    2 hours ago










  • I'll be honest: on a programmer's website (such as stackexchange.com), the recommendation to use rand and srand would be worth a very comprehensive comment on why that is a very bad idea. These functions aren't reentrant-save, so interaction with their state from ISRs or multiple tasks is potentially catastrophic. If I was AVR, I'd honestly not include these functions. The way to go is not a random number generator with hidden global state, especially not on a microcontroller.
    – Marcus Müller
    1 hour ago












  • @MarcusMüller The re-entrant version of rand() is rand_r(). I'm not sure it is needed. I'm also not sure I follow you on why it would be a very bad idea to use rand() like this on an AVR or how it would be catastrophic unless you need to reproduce the sequence and haven't been careful about how you use it. Is there something inherent to hidden global states that make them inappropriate for microcontrollers?
    – evildemonic
    1 hour ago



















2














Random Numbers and Computers



Let us talk a second about what it takes to generate random numbers.



Randomness is very easy for humans to imagine or produce: Flip a coin. The result is random. The next time you flip the same coin, it will be random again, and there will be no correlation to the previous coin-flips.



That's way harder for processors. These are machines to be as deterministic as possible. Generally, when you build a digital circuit, any non-determinism ("random behaviour") is undesired.



In that framework, i.e. if your digital circuit (e.g. an AVR) works perfectly deterministically, then there's simply no way to generate truly random numbers. These numbers must always be a result of some calculation on numbers that were there before, so that there can only be a "seemingly" random sequence of numbers.

The next time you feed the same algorithm with the same "inital input", you get the same sequence of numbers. We call an algorithm that generates a seemingly random numbers a pseudo-random number generator (PRNG).



But that is practically always (aside from cryptography) an acceptable solution. There's typically a large numbers of initial states, and if the PRNG is any good, any of these initial states will yield a totally different, totally uncorrelated, totally fairly distributed sequence of numbers.



Pseudo-random number generation on microcontrollers in practice



On a microcontroller, you don't want to use a function like rand or srand with a hidden global state of a single pseudo random number generator (PRNG) - that is a waste of the little RAM you have, if you at some point can stop using the PRNG, and a recipe for disaster if you're interacting with the PRNG from interrupt routines.



Instead, use a "slim" random number generator function that takes and modifies an explicit, small state. The AVR stdlib possibly offers rand_r, but that's just a bad random number generator; with the same effort in state space and computation, you can get much "randomer" numbers.



For medium-to-high-quality PRNG, I personally use my state-external variant of the XOROSHIRO128+ algorithm. It requires 16B of state memory, and is probably far over the top for a microcontroller-based game.

The XORSHIFT32 algorithm, that XOROSHIRO128+ is indirectly based on, only uses four bytes of state, and should be plenty random for your use case, and will return one 32bit random number each call, and modify the state.



Seeding your PRNG



The real question is how to initialize the state (seed the PRNG). That seed determines the only seemingly random sequence of numbers that you'll get!



That is especially challenging on a small device like an AVR: You can't use something like the current time (which was always a bad seed, but someone started telling people it's good one :(, so people use that), because it has no notion of time; you can't use physically random things like the seek time of your hard drive, because there is no hard drive, and so on.



But: your microcontroller has an ADC, for example. So, simply get a series of ADC measurements and use the least significant bits, which should essentially be noise, to generate the initial state that you use for your PRNG. Maybe take an ADC measurement, XOR with the last measurement, shift up, take the next measurement, repeat 16 times, use that as initial state.






share|improve this answer























    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("schematics", function () {
    StackExchange.schematics.init();
    });
    }, "cicuitlab");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "135"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });






    Dion123 is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f414867%2fhow-can-i-get-random-numbers-on-avr%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    From the AVR Libc Reference Manual, under stdlib.h: General utilities:




    Function rand():



    int rand(void)



    The rand() function computes a sequence of pseudo-random integers in
    the range of 0 to RAND_MAX (as defined by the header file
    <stdlib.h>).



    The srand() function sets its argument seed as the seed for a new
    sequence of pseudo-random numbers to be returned by rand(). These
    sequences are repeatable by calling srand() with the same seed
    value.



    If no seed value is provided, the functions are automatically seeded
    with a value of 1.



    In compliance with the C standard, these functions operate on int
    arguments. Since the underlying algorithm already uses 32-bit
    calculations, this causes a loss of precision. See random() for an
    alternate set of functions that retains full 32-bit precision.




    Basically, you want to use srand() to set a seed for rand() to use. rand() will generate the numbers based on the seed srand() provides.



    A common way to get a seed for srand() is to use a timer that is based on some user action so you get a fairly unique sequence every time. If you don't change the seed, the number sequence will always be the same.






    share|improve this answer























    • @evildemonic The timer won't help much if there is no RTC. On such a limited embedded platforms there are other sources of entropy required. Such as temperature-sensitive analog input. Update - well, a timer based on user action is an option. It's just that it is not always the case there is a user action before the result is required..
      – Eugene Sh.
      2 hours ago












    • @EugeneSh. This is why I specified based on user action. Since the OP is talking about a game, I doubt they need super true authentic random. If so, yes, using for instance an ADC value reading the noise on a diode or something could be better.
      – evildemonic
      2 hours ago












    • I appreciate you folks helping me improve my answer, and bring you up good points. Since this is a game, there should be user action at some point, and this can perhaps be 'forced' early on. The seed can be generated at any point before the random number is needed. Something as simple as timing how long it takes for the player to enter their name, or select an option from the opening menu. Without more input from the OP, it is hard to speculate on what they need and what we have to work with.
      – evildemonic
      2 hours ago










    • I'll be honest: on a programmer's website (such as stackexchange.com), the recommendation to use rand and srand would be worth a very comprehensive comment on why that is a very bad idea. These functions aren't reentrant-save, so interaction with their state from ISRs or multiple tasks is potentially catastrophic. If I was AVR, I'd honestly not include these functions. The way to go is not a random number generator with hidden global state, especially not on a microcontroller.
      – Marcus Müller
      1 hour ago












    • @MarcusMüller The re-entrant version of rand() is rand_r(). I'm not sure it is needed. I'm also not sure I follow you on why it would be a very bad idea to use rand() like this on an AVR or how it would be catastrophic unless you need to reproduce the sequence and haven't been careful about how you use it. Is there something inherent to hidden global states that make them inappropriate for microcontrollers?
      – evildemonic
      1 hour ago
















    3














    From the AVR Libc Reference Manual, under stdlib.h: General utilities:




    Function rand():



    int rand(void)



    The rand() function computes a sequence of pseudo-random integers in
    the range of 0 to RAND_MAX (as defined by the header file
    <stdlib.h>).



    The srand() function sets its argument seed as the seed for a new
    sequence of pseudo-random numbers to be returned by rand(). These
    sequences are repeatable by calling srand() with the same seed
    value.



    If no seed value is provided, the functions are automatically seeded
    with a value of 1.



    In compliance with the C standard, these functions operate on int
    arguments. Since the underlying algorithm already uses 32-bit
    calculations, this causes a loss of precision. See random() for an
    alternate set of functions that retains full 32-bit precision.




    Basically, you want to use srand() to set a seed for rand() to use. rand() will generate the numbers based on the seed srand() provides.



    A common way to get a seed for srand() is to use a timer that is based on some user action so you get a fairly unique sequence every time. If you don't change the seed, the number sequence will always be the same.






    share|improve this answer























    • @evildemonic The timer won't help much if there is no RTC. On such a limited embedded platforms there are other sources of entropy required. Such as temperature-sensitive analog input. Update - well, a timer based on user action is an option. It's just that it is not always the case there is a user action before the result is required..
      – Eugene Sh.
      2 hours ago












    • @EugeneSh. This is why I specified based on user action. Since the OP is talking about a game, I doubt they need super true authentic random. If so, yes, using for instance an ADC value reading the noise on a diode or something could be better.
      – evildemonic
      2 hours ago












    • I appreciate you folks helping me improve my answer, and bring you up good points. Since this is a game, there should be user action at some point, and this can perhaps be 'forced' early on. The seed can be generated at any point before the random number is needed. Something as simple as timing how long it takes for the player to enter their name, or select an option from the opening menu. Without more input from the OP, it is hard to speculate on what they need and what we have to work with.
      – evildemonic
      2 hours ago










    • I'll be honest: on a programmer's website (such as stackexchange.com), the recommendation to use rand and srand would be worth a very comprehensive comment on why that is a very bad idea. These functions aren't reentrant-save, so interaction with their state from ISRs or multiple tasks is potentially catastrophic. If I was AVR, I'd honestly not include these functions. The way to go is not a random number generator with hidden global state, especially not on a microcontroller.
      – Marcus Müller
      1 hour ago












    • @MarcusMüller The re-entrant version of rand() is rand_r(). I'm not sure it is needed. I'm also not sure I follow you on why it would be a very bad idea to use rand() like this on an AVR or how it would be catastrophic unless you need to reproduce the sequence and haven't been careful about how you use it. Is there something inherent to hidden global states that make them inappropriate for microcontrollers?
      – evildemonic
      1 hour ago














    3












    3








    3






    From the AVR Libc Reference Manual, under stdlib.h: General utilities:




    Function rand():



    int rand(void)



    The rand() function computes a sequence of pseudo-random integers in
    the range of 0 to RAND_MAX (as defined by the header file
    <stdlib.h>).



    The srand() function sets its argument seed as the seed for a new
    sequence of pseudo-random numbers to be returned by rand(). These
    sequences are repeatable by calling srand() with the same seed
    value.



    If no seed value is provided, the functions are automatically seeded
    with a value of 1.



    In compliance with the C standard, these functions operate on int
    arguments. Since the underlying algorithm already uses 32-bit
    calculations, this causes a loss of precision. See random() for an
    alternate set of functions that retains full 32-bit precision.




    Basically, you want to use srand() to set a seed for rand() to use. rand() will generate the numbers based on the seed srand() provides.



    A common way to get a seed for srand() is to use a timer that is based on some user action so you get a fairly unique sequence every time. If you don't change the seed, the number sequence will always be the same.






    share|improve this answer














    From the AVR Libc Reference Manual, under stdlib.h: General utilities:




    Function rand():



    int rand(void)



    The rand() function computes a sequence of pseudo-random integers in
    the range of 0 to RAND_MAX (as defined by the header file
    <stdlib.h>).



    The srand() function sets its argument seed as the seed for a new
    sequence of pseudo-random numbers to be returned by rand(). These
    sequences are repeatable by calling srand() with the same seed
    value.



    If no seed value is provided, the functions are automatically seeded
    with a value of 1.



    In compliance with the C standard, these functions operate on int
    arguments. Since the underlying algorithm already uses 32-bit
    calculations, this causes a loss of precision. See random() for an
    alternate set of functions that retains full 32-bit precision.




    Basically, you want to use srand() to set a seed for rand() to use. rand() will generate the numbers based on the seed srand() provides.



    A common way to get a seed for srand() is to use a timer that is based on some user action so you get a fairly unique sequence every time. If you don't change the seed, the number sequence will always be the same.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 48 mins ago









    Marcus Müller

    31.5k35793




    31.5k35793










    answered 2 hours ago









    evildemonic

    1,890618




    1,890618












    • @evildemonic The timer won't help much if there is no RTC. On such a limited embedded platforms there are other sources of entropy required. Such as temperature-sensitive analog input. Update - well, a timer based on user action is an option. It's just that it is not always the case there is a user action before the result is required..
      – Eugene Sh.
      2 hours ago












    • @EugeneSh. This is why I specified based on user action. Since the OP is talking about a game, I doubt they need super true authentic random. If so, yes, using for instance an ADC value reading the noise on a diode or something could be better.
      – evildemonic
      2 hours ago












    • I appreciate you folks helping me improve my answer, and bring you up good points. Since this is a game, there should be user action at some point, and this can perhaps be 'forced' early on. The seed can be generated at any point before the random number is needed. Something as simple as timing how long it takes for the player to enter their name, or select an option from the opening menu. Without more input from the OP, it is hard to speculate on what they need and what we have to work with.
      – evildemonic
      2 hours ago










    • I'll be honest: on a programmer's website (such as stackexchange.com), the recommendation to use rand and srand would be worth a very comprehensive comment on why that is a very bad idea. These functions aren't reentrant-save, so interaction with their state from ISRs or multiple tasks is potentially catastrophic. If I was AVR, I'd honestly not include these functions. The way to go is not a random number generator with hidden global state, especially not on a microcontroller.
      – Marcus Müller
      1 hour ago












    • @MarcusMüller The re-entrant version of rand() is rand_r(). I'm not sure it is needed. I'm also not sure I follow you on why it would be a very bad idea to use rand() like this on an AVR or how it would be catastrophic unless you need to reproduce the sequence and haven't been careful about how you use it. Is there something inherent to hidden global states that make them inappropriate for microcontrollers?
      – evildemonic
      1 hour ago


















    • @evildemonic The timer won't help much if there is no RTC. On such a limited embedded platforms there are other sources of entropy required. Such as temperature-sensitive analog input. Update - well, a timer based on user action is an option. It's just that it is not always the case there is a user action before the result is required..
      – Eugene Sh.
      2 hours ago












    • @EugeneSh. This is why I specified based on user action. Since the OP is talking about a game, I doubt they need super true authentic random. If so, yes, using for instance an ADC value reading the noise on a diode or something could be better.
      – evildemonic
      2 hours ago












    • I appreciate you folks helping me improve my answer, and bring you up good points. Since this is a game, there should be user action at some point, and this can perhaps be 'forced' early on. The seed can be generated at any point before the random number is needed. Something as simple as timing how long it takes for the player to enter their name, or select an option from the opening menu. Without more input from the OP, it is hard to speculate on what they need and what we have to work with.
      – evildemonic
      2 hours ago










    • I'll be honest: on a programmer's website (such as stackexchange.com), the recommendation to use rand and srand would be worth a very comprehensive comment on why that is a very bad idea. These functions aren't reentrant-save, so interaction with their state from ISRs or multiple tasks is potentially catastrophic. If I was AVR, I'd honestly not include these functions. The way to go is not a random number generator with hidden global state, especially not on a microcontroller.
      – Marcus Müller
      1 hour ago












    • @MarcusMüller The re-entrant version of rand() is rand_r(). I'm not sure it is needed. I'm also not sure I follow you on why it would be a very bad idea to use rand() like this on an AVR or how it would be catastrophic unless you need to reproduce the sequence and haven't been careful about how you use it. Is there something inherent to hidden global states that make them inappropriate for microcontrollers?
      – evildemonic
      1 hour ago
















    @evildemonic The timer won't help much if there is no RTC. On such a limited embedded platforms there are other sources of entropy required. Such as temperature-sensitive analog input. Update - well, a timer based on user action is an option. It's just that it is not always the case there is a user action before the result is required..
    – Eugene Sh.
    2 hours ago






    @evildemonic The timer won't help much if there is no RTC. On such a limited embedded platforms there are other sources of entropy required. Such as temperature-sensitive analog input. Update - well, a timer based on user action is an option. It's just that it is not always the case there is a user action before the result is required..
    – Eugene Sh.
    2 hours ago














    @EugeneSh. This is why I specified based on user action. Since the OP is talking about a game, I doubt they need super true authentic random. If so, yes, using for instance an ADC value reading the noise on a diode or something could be better.
    – evildemonic
    2 hours ago






    @EugeneSh. This is why I specified based on user action. Since the OP is talking about a game, I doubt they need super true authentic random. If so, yes, using for instance an ADC value reading the noise on a diode or something could be better.
    – evildemonic
    2 hours ago














    I appreciate you folks helping me improve my answer, and bring you up good points. Since this is a game, there should be user action at some point, and this can perhaps be 'forced' early on. The seed can be generated at any point before the random number is needed. Something as simple as timing how long it takes for the player to enter their name, or select an option from the opening menu. Without more input from the OP, it is hard to speculate on what they need and what we have to work with.
    – evildemonic
    2 hours ago




    I appreciate you folks helping me improve my answer, and bring you up good points. Since this is a game, there should be user action at some point, and this can perhaps be 'forced' early on. The seed can be generated at any point before the random number is needed. Something as simple as timing how long it takes for the player to enter their name, or select an option from the opening menu. Without more input from the OP, it is hard to speculate on what they need and what we have to work with.
    – evildemonic
    2 hours ago












    I'll be honest: on a programmer's website (such as stackexchange.com), the recommendation to use rand and srand would be worth a very comprehensive comment on why that is a very bad idea. These functions aren't reentrant-save, so interaction with their state from ISRs or multiple tasks is potentially catastrophic. If I was AVR, I'd honestly not include these functions. The way to go is not a random number generator with hidden global state, especially not on a microcontroller.
    – Marcus Müller
    1 hour ago






    I'll be honest: on a programmer's website (such as stackexchange.com), the recommendation to use rand and srand would be worth a very comprehensive comment on why that is a very bad idea. These functions aren't reentrant-save, so interaction with their state from ISRs or multiple tasks is potentially catastrophic. If I was AVR, I'd honestly not include these functions. The way to go is not a random number generator with hidden global state, especially not on a microcontroller.
    – Marcus Müller
    1 hour ago














    @MarcusMüller The re-entrant version of rand() is rand_r(). I'm not sure it is needed. I'm also not sure I follow you on why it would be a very bad idea to use rand() like this on an AVR or how it would be catastrophic unless you need to reproduce the sequence and haven't been careful about how you use it. Is there something inherent to hidden global states that make them inappropriate for microcontrollers?
    – evildemonic
    1 hour ago




    @MarcusMüller The re-entrant version of rand() is rand_r(). I'm not sure it is needed. I'm also not sure I follow you on why it would be a very bad idea to use rand() like this on an AVR or how it would be catastrophic unless you need to reproduce the sequence and haven't been careful about how you use it. Is there something inherent to hidden global states that make them inappropriate for microcontrollers?
    – evildemonic
    1 hour ago













    2














    Random Numbers and Computers



    Let us talk a second about what it takes to generate random numbers.



    Randomness is very easy for humans to imagine or produce: Flip a coin. The result is random. The next time you flip the same coin, it will be random again, and there will be no correlation to the previous coin-flips.



    That's way harder for processors. These are machines to be as deterministic as possible. Generally, when you build a digital circuit, any non-determinism ("random behaviour") is undesired.



    In that framework, i.e. if your digital circuit (e.g. an AVR) works perfectly deterministically, then there's simply no way to generate truly random numbers. These numbers must always be a result of some calculation on numbers that were there before, so that there can only be a "seemingly" random sequence of numbers.

    The next time you feed the same algorithm with the same "inital input", you get the same sequence of numbers. We call an algorithm that generates a seemingly random numbers a pseudo-random number generator (PRNG).



    But that is practically always (aside from cryptography) an acceptable solution. There's typically a large numbers of initial states, and if the PRNG is any good, any of these initial states will yield a totally different, totally uncorrelated, totally fairly distributed sequence of numbers.



    Pseudo-random number generation on microcontrollers in practice



    On a microcontroller, you don't want to use a function like rand or srand with a hidden global state of a single pseudo random number generator (PRNG) - that is a waste of the little RAM you have, if you at some point can stop using the PRNG, and a recipe for disaster if you're interacting with the PRNG from interrupt routines.



    Instead, use a "slim" random number generator function that takes and modifies an explicit, small state. The AVR stdlib possibly offers rand_r, but that's just a bad random number generator; with the same effort in state space and computation, you can get much "randomer" numbers.



    For medium-to-high-quality PRNG, I personally use my state-external variant of the XOROSHIRO128+ algorithm. It requires 16B of state memory, and is probably far over the top for a microcontroller-based game.

    The XORSHIFT32 algorithm, that XOROSHIRO128+ is indirectly based on, only uses four bytes of state, and should be plenty random for your use case, and will return one 32bit random number each call, and modify the state.



    Seeding your PRNG



    The real question is how to initialize the state (seed the PRNG). That seed determines the only seemingly random sequence of numbers that you'll get!



    That is especially challenging on a small device like an AVR: You can't use something like the current time (which was always a bad seed, but someone started telling people it's good one :(, so people use that), because it has no notion of time; you can't use physically random things like the seek time of your hard drive, because there is no hard drive, and so on.



    But: your microcontroller has an ADC, for example. So, simply get a series of ADC measurements and use the least significant bits, which should essentially be noise, to generate the initial state that you use for your PRNG. Maybe take an ADC measurement, XOR with the last measurement, shift up, take the next measurement, repeat 16 times, use that as initial state.






    share|improve this answer




























      2














      Random Numbers and Computers



      Let us talk a second about what it takes to generate random numbers.



      Randomness is very easy for humans to imagine or produce: Flip a coin. The result is random. The next time you flip the same coin, it will be random again, and there will be no correlation to the previous coin-flips.



      That's way harder for processors. These are machines to be as deterministic as possible. Generally, when you build a digital circuit, any non-determinism ("random behaviour") is undesired.



      In that framework, i.e. if your digital circuit (e.g. an AVR) works perfectly deterministically, then there's simply no way to generate truly random numbers. These numbers must always be a result of some calculation on numbers that were there before, so that there can only be a "seemingly" random sequence of numbers.

      The next time you feed the same algorithm with the same "inital input", you get the same sequence of numbers. We call an algorithm that generates a seemingly random numbers a pseudo-random number generator (PRNG).



      But that is practically always (aside from cryptography) an acceptable solution. There's typically a large numbers of initial states, and if the PRNG is any good, any of these initial states will yield a totally different, totally uncorrelated, totally fairly distributed sequence of numbers.



      Pseudo-random number generation on microcontrollers in practice



      On a microcontroller, you don't want to use a function like rand or srand with a hidden global state of a single pseudo random number generator (PRNG) - that is a waste of the little RAM you have, if you at some point can stop using the PRNG, and a recipe for disaster if you're interacting with the PRNG from interrupt routines.



      Instead, use a "slim" random number generator function that takes and modifies an explicit, small state. The AVR stdlib possibly offers rand_r, but that's just a bad random number generator; with the same effort in state space and computation, you can get much "randomer" numbers.



      For medium-to-high-quality PRNG, I personally use my state-external variant of the XOROSHIRO128+ algorithm. It requires 16B of state memory, and is probably far over the top for a microcontroller-based game.

      The XORSHIFT32 algorithm, that XOROSHIRO128+ is indirectly based on, only uses four bytes of state, and should be plenty random for your use case, and will return one 32bit random number each call, and modify the state.



      Seeding your PRNG



      The real question is how to initialize the state (seed the PRNG). That seed determines the only seemingly random sequence of numbers that you'll get!



      That is especially challenging on a small device like an AVR: You can't use something like the current time (which was always a bad seed, but someone started telling people it's good one :(, so people use that), because it has no notion of time; you can't use physically random things like the seek time of your hard drive, because there is no hard drive, and so on.



      But: your microcontroller has an ADC, for example. So, simply get a series of ADC measurements and use the least significant bits, which should essentially be noise, to generate the initial state that you use for your PRNG. Maybe take an ADC measurement, XOR with the last measurement, shift up, take the next measurement, repeat 16 times, use that as initial state.






      share|improve this answer


























        2












        2








        2






        Random Numbers and Computers



        Let us talk a second about what it takes to generate random numbers.



        Randomness is very easy for humans to imagine or produce: Flip a coin. The result is random. The next time you flip the same coin, it will be random again, and there will be no correlation to the previous coin-flips.



        That's way harder for processors. These are machines to be as deterministic as possible. Generally, when you build a digital circuit, any non-determinism ("random behaviour") is undesired.



        In that framework, i.e. if your digital circuit (e.g. an AVR) works perfectly deterministically, then there's simply no way to generate truly random numbers. These numbers must always be a result of some calculation on numbers that were there before, so that there can only be a "seemingly" random sequence of numbers.

        The next time you feed the same algorithm with the same "inital input", you get the same sequence of numbers. We call an algorithm that generates a seemingly random numbers a pseudo-random number generator (PRNG).



        But that is practically always (aside from cryptography) an acceptable solution. There's typically a large numbers of initial states, and if the PRNG is any good, any of these initial states will yield a totally different, totally uncorrelated, totally fairly distributed sequence of numbers.



        Pseudo-random number generation on microcontrollers in practice



        On a microcontroller, you don't want to use a function like rand or srand with a hidden global state of a single pseudo random number generator (PRNG) - that is a waste of the little RAM you have, if you at some point can stop using the PRNG, and a recipe for disaster if you're interacting with the PRNG from interrupt routines.



        Instead, use a "slim" random number generator function that takes and modifies an explicit, small state. The AVR stdlib possibly offers rand_r, but that's just a bad random number generator; with the same effort in state space and computation, you can get much "randomer" numbers.



        For medium-to-high-quality PRNG, I personally use my state-external variant of the XOROSHIRO128+ algorithm. It requires 16B of state memory, and is probably far over the top for a microcontroller-based game.

        The XORSHIFT32 algorithm, that XOROSHIRO128+ is indirectly based on, only uses four bytes of state, and should be plenty random for your use case, and will return one 32bit random number each call, and modify the state.



        Seeding your PRNG



        The real question is how to initialize the state (seed the PRNG). That seed determines the only seemingly random sequence of numbers that you'll get!



        That is especially challenging on a small device like an AVR: You can't use something like the current time (which was always a bad seed, but someone started telling people it's good one :(, so people use that), because it has no notion of time; you can't use physically random things like the seek time of your hard drive, because there is no hard drive, and so on.



        But: your microcontroller has an ADC, for example. So, simply get a series of ADC measurements and use the least significant bits, which should essentially be noise, to generate the initial state that you use for your PRNG. Maybe take an ADC measurement, XOR with the last measurement, shift up, take the next measurement, repeat 16 times, use that as initial state.






        share|improve this answer














        Random Numbers and Computers



        Let us talk a second about what it takes to generate random numbers.



        Randomness is very easy for humans to imagine or produce: Flip a coin. The result is random. The next time you flip the same coin, it will be random again, and there will be no correlation to the previous coin-flips.



        That's way harder for processors. These are machines to be as deterministic as possible. Generally, when you build a digital circuit, any non-determinism ("random behaviour") is undesired.



        In that framework, i.e. if your digital circuit (e.g. an AVR) works perfectly deterministically, then there's simply no way to generate truly random numbers. These numbers must always be a result of some calculation on numbers that were there before, so that there can only be a "seemingly" random sequence of numbers.

        The next time you feed the same algorithm with the same "inital input", you get the same sequence of numbers. We call an algorithm that generates a seemingly random numbers a pseudo-random number generator (PRNG).



        But that is practically always (aside from cryptography) an acceptable solution. There's typically a large numbers of initial states, and if the PRNG is any good, any of these initial states will yield a totally different, totally uncorrelated, totally fairly distributed sequence of numbers.



        Pseudo-random number generation on microcontrollers in practice



        On a microcontroller, you don't want to use a function like rand or srand with a hidden global state of a single pseudo random number generator (PRNG) - that is a waste of the little RAM you have, if you at some point can stop using the PRNG, and a recipe for disaster if you're interacting with the PRNG from interrupt routines.



        Instead, use a "slim" random number generator function that takes and modifies an explicit, small state. The AVR stdlib possibly offers rand_r, but that's just a bad random number generator; with the same effort in state space and computation, you can get much "randomer" numbers.



        For medium-to-high-quality PRNG, I personally use my state-external variant of the XOROSHIRO128+ algorithm. It requires 16B of state memory, and is probably far over the top for a microcontroller-based game.

        The XORSHIFT32 algorithm, that XOROSHIRO128+ is indirectly based on, only uses four bytes of state, and should be plenty random for your use case, and will return one 32bit random number each call, and modify the state.



        Seeding your PRNG



        The real question is how to initialize the state (seed the PRNG). That seed determines the only seemingly random sequence of numbers that you'll get!



        That is especially challenging on a small device like an AVR: You can't use something like the current time (which was always a bad seed, but someone started telling people it's good one :(, so people use that), because it has no notion of time; you can't use physically random things like the seek time of your hard drive, because there is no hard drive, and so on.



        But: your microcontroller has an ADC, for example. So, simply get a series of ADC measurements and use the least significant bits, which should essentially be noise, to generate the initial state that you use for your PRNG. Maybe take an ADC measurement, XOR with the last measurement, shift up, take the next measurement, repeat 16 times, use that as initial state.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 1 hour ago

























        answered 1 hour ago









        Marcus Müller

        31.5k35793




        31.5k35793






















            Dion123 is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            Dion123 is a new contributor. Be nice, and check out our Code of Conduct.













            Dion123 is a new contributor. Be nice, and check out our Code of Conduct.












            Dion123 is a new contributor. Be nice, and check out our Code of Conduct.
















            Thanks for contributing an answer to Electrical Engineering Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f414867%2fhow-can-i-get-random-numbers-on-avr%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Eastern Orthodox Church

            Zagreb

            Understanding the information contained in the Deep Space Network XML data?