Shop OBEX P1 Docs P2 Docs Learn Events
The random number generator — Parallax Forums

The random number generator

LightfootLightfoot Posts: 228
edited 2009-03-12 07:09 in General Discussion
I wish to generate a random number between 1 and 5 to light a random combination of LED's on the RB port. Only bits RB.0 to RB.4 are used as there are only 5 LED's. I have been messing around and I cannot get the thing to generate random numbers from 1 to 5. I checked the manual but the random statement is not well documented. What is the correct way to approach this?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Comments

  • PJMontyPJMonty Posts: 983
    edited 2009-03-10 04:02
    Lightfoot,

    Post your code so folks can see what you're doing.

    Thanks,
    PeterM
  • LightfootLightfoot Posts: 228
    edited 2009-03-10 04:15
    DEVICE         SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
    FREQ         4_000_000
    PROGRAM Start
    
    Start:
    
    ' Set all ports to outputs:
    tris_a = 0
    tris_b = 0
    tris_c = 0
    
    'All ports are off at the start: 
    ra = 0
    rb = 0
    rc = 0
    
    rnd var byte
    
    ' Main loop:
    DO
        rnd = RANDOM 5 
        rb = rnd
        pause 3000 
    LOOP
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-03-10 04:17
    You can find RANDOM in the SX/B help file. One solution, to get a value from 0 to 4 is like this:

    RANDOM seed
    index = seed // 5
    


    The // operator returns the remainder of a division; the remainder will always be 0 to the divisor minus one. Don't do the change the original seed as this will limit the "randomness" of your process.

    [noparse][[/noparse]Edit] If you're just wanting to active a single output on RB, add this line to my code above:

    RB = 1 << index
    

    Post Edited (JonnyMac) : 3/10/2009 4:30:06 AM GMT
  • LightfootLightfoot Posts: 228
    edited 2009-03-10 17:02
    The previous code, making the LEDs light in a random combination was just a test to see if I can get the the thing to work. What I am really doing with random numbers is generating them to execute subroutines that each perform a unique function. The random numbers always repeat in a uniform sequence so it is not truly random. IS there something wrong with the seed? In C++ this happens when the generator is not seeded properly.

    rnd var byte
    fxn var byte
    rnd = 0
    
    ' Main loop:
    DO
        RANDOM rnd
        fxn = rnd // 3
    
        IF fxn = 0 THEN
            LightLtoR
        ELSEIF FXN = 1 THEN    
            LightRtoL
        ELSE
            Chase
        ENDIF
    
    LOOP
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • PJMontyPJMonty Posts: 983
    edited 2009-03-10 17:33
    Lightfoot,

    Open the IDE. Click on Help->SX/B Help. Click on the "+" next to "Reference" to open it. Click on the "+" next to "Commands" to open it. Scroll as need to the entry labeled "RANDOM" and read it. Your answer is in the section labeled "Explanation".

    Thanks,
    PeterM
  • LightfootLightfoot Posts: 228
    edited 2009-03-10 17:39
    Oh, that's where the manual is. Thx

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-03-10 17:50
    Keep in mind that RANDOM is not truly random; it's called pseudo-random because it's based on an algorithm and given he same seed you'll get the same result from RANDOM. The only way to get true randomness is to insert some external event. I do a lot of work with prop control and in those programs RANDOM is continuously called until there is an external trigger. The external event brings true randomness to the behavior.
  • LightfootLightfoot Posts: 228
    edited 2009-03-11 16:36
    I checked out the digital dice but that is a little too advanced for me at this point. Could you perhaps post simpler code than that as an example for truly random code?

    Thanks,
    Lightfoot

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-03-11 22:56
    Can you use an external event for your randomness?
  • LightfootLightfoot Posts: 228
    edited 2009-03-12 00:34
    I am kind of a noob with SX basic, so what does this mean in terms of SX basic? I am a wizz when it comes to C++, however.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-03-12 01:23
    Let me try again: given the same seed you will always get the same result from RANDOM. If you introduce some external randomness (e.g. a button press) to the process -- this is what I do for Halloween prop control. Perhaps you if you described what you want your program to do -- in total -- we'd be able to give better guidance. Or post the code the way you'd write it in C++ for translation.
  • LightfootLightfoot Posts: 228
    edited 2009-03-12 01:46
    OK, there are six subroutines. Each routine causes the first five bits of the RB port to be manipulated in a certain lighting effect, as denoted by the comments in the code. What I want to do is have the main loop generate a truly random number between 0 and 5. Once a number is generated, an if/else if/else statement will select which of the subroutines will execute. For example, if the number is zero, the "LightRtoL" routine will run. One, the "LightLtoR" will execute.

    DEVICE         SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
    FREQ         4_000_000
    PROGRAM Start
    
    '********************************** Subroutines: *********************************
    LightLtoR         SUB 0
    LightRtoL         SUB 0
    Chase            SUB 0
    ChasetoCenter      SUB 0
    ChasefromCenter      SUB 0
    Disco          SUB 0
    '************************************* Main: *************************************
    Start:
    
    '**************************** Set up output registers: ***************************
    tris_b = 0
    '*****************************  Pullup unused pins: ******************************
    plp_a = 0
    plp_c = 0
    '************************ All RB pins are off at the start: ********************** 
    rb = 0
    '*********************************** Variables: **********************************
    i2 var byte
    i var byte 'For loop index variable.
    exp var byte 'Working storage variable for math computations.
    '*********************************** Main loop: **********************************
    DO
    
    LOOP
    '************************ Letters chase from right to left: **********************
    SUB LightRtoL
        exp = 32
        FOR i = 1 TO 5
            exp = exp / 2
            RB = RB + exp
            pause 1000
        NEXT
        RB = 0
        pause 1000
    ENDSUB
    '************************ Letters chase from left to right: **********************
    SUB LightLtoR
        exp = 1
        FOR i = 1 TO 5
            exp = exp * 2
            RB = exp - 1
            pause 1000
        NEXT
        RB = 0
        pause 1000
    ENDSUB
    '************************** Letters chase back and forth: ***********************
    SUB Chase
        exp = 1
        FOR i = 1 TO 5
            exp = exp * 2
            RB = exp - 1
            pause 150
        NEXT
    
        RB = 0
        
        exp = 32
        FOR i = 1 TO 5
            exp = exp / 2
            RB = RB + exp
            pause 150
        NEXT
        RB = 0
    
    ENDSUB
    '************************** Letters chase towards center: ***********************
    SUB ChasetoCenter
        exp = 8
        RB = 25
        FOR i = 1 TO 3
            rb = rb - exp 
            exp = exp - 1
            pause 150 
        NEXT
        RB = 0
    ENDSUB
    '************************** Letters chase from the center: ***********************
    SUB ChasefromCenter
        exp = 6
        RB = 4
        pause 150
        FOR i = 1 TO 2
            rb = rb + exp 
            exp = exp + 1
            pause 150
        NEXT
        RB = 0
    ENDSUB
    '************************ Letters flash like a strobe light: ***********************
    SUB Disco
        rb = 0
        pause 30
        rb = 255
        pause 30
    ENDSUB
    
    



    In case you are curious, the pins RB.0 to RB.4 are connected to a FET buffer. These power an array of LEDs arranged in a pattern of 5 letters. It is a sign I am making. It will read "ECTET"

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-03-12 06:56
    Again, RANDOM is based on an algorithm so it will never be truly random unless you apply some external event. If you can't have an external event then every time you power up the program it will run in the same order -- just the nature of RANDOM.
  • PJMontyPJMonty Posts: 983
    edited 2009-03-12 07:09
    Lightfoot,

    Does it truly matter if you have "actual" random values versus having "pseudo-random"? All random number generators in all languages use pseudo-random generators. The idea is that they appear random, and no human is likely to memorize the complete pattern. If you have an byte sized random value, then there are 256 different outputs until the pattern repeats. I have attached a tiny program that is a stripped down version of the Digital Dice program. Here are the outputs it generated:

    180, 0
    255, 3
    183 4
    201, 3
    104, 2
    131, 5
    10, 4
    173, 5
    220, 4
    199, 1
    



    The first number in each pair is the value that came out of the random function, and the second number is value scaled from 0 to 5. These correspond to the variables called "CurrRandom" and "ZeroToFive". Every time you run this program, you'll get the same sequence, but the fact is that while you may be able to memorize the first few outputs, you'll lose track long before you hit number 257 where the cycle repeats.

    If you run this in the debugger, you'll can see the values in the watch window. Just set the breakpoint on the line that says:

    goto RandomTester
    



    BTW, I used an SX48 for testing. If you use the SX28, just comment out the SX48 "Device" line and un-comment the SX28 line.

    Thanks,
    PeterM
Sign In or Register to comment.