Random command not working

Discussion in 'General Electronics Chat' started by mark Edward Easterling, Sep 28, 2017.

  1. mark Edward Easterling

    Thread Starter New Member

    Sep 28, 2017
    3
    0
    Hi,
    The random command is not working, when I press C.1 to start the sequence it goes straight through each time to 'showone'. Any suggestions as I am a little new at basic programming.
    Thanks
    Mark

    serout B.7,N2400,(254,1);set B.7, as output for LCD
    let dirsC = %00000000 ;set pinsC as inputs or outputs
    let dirsB = %11111111 ;set pinsB as inputs or outputs(pin B.0
    ;symbol key_pos = b0 ; number of keys pressed
    ;symbol key_value = b1 ; value of key pressed

    main:
    random b1 ; generate a random number

    pause 500 ; wait for display to initialise
    serout B.7,N2400,(254,1) 'clear display
    pause 30
    serout B.7,N2400,(254,131) ; move to end of first line
    serout B.7,N2400,("ENTER CODE") ;first line of code

    if pinC.1 = 1 then makenumber ; test switch
    goto main
    makenumber:
    Random b1
    if b1 > 55000 then showsix ; test random number and jump
    if b1 > 44000 then showfive
    if b1 > 33000 then showfour
    if b1 > 22000 then showthree
    if b1 > 11000 then showtwo

    showone:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("1")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showtwo:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("2")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showthree:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("3")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showfour:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("4")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showfive:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("5")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showsix:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("6")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main
     
  2. Mark Hughes

    Member

    Jun 14, 2016
    270
    22
    ;symbol key_value = b1 ; value of key pressed

    So a couple of things:
    1) What language is this and what compiler are you using?
    2) Doesn't that semicolon at the beginning of this line negate the variable declaration?
    3) What is the size of the random variable supposed to be and do you have to declare that? (Or does symbol do that for you?)
    4) What does the documentation indicate the output value range of Random to be and how do you use the command? Should it be B1=random?
    5) Why not explicitly declare the goto loop for B1 as well and put in a return statement after the last value?
    6) Why not print out what B1 is to serial for debugging?
     
  3. wayneh

    Expert

    Sep 9, 2010
    14,775
    5,268
    The output of the random function (is it Random or random - you used both) needs to be scaled into the range you are using.
     
    cmartinez likes this.
  4. Raymond Genovese

    Active Member

    Mar 5, 2016
    971
    534
    Hi Mark, welcome to the forum.

    I think I see your problem. B1 is an 8-bit number and will *always* fail your tests and fall through to showone.

    To illustrate,try using these statements:
    Code (Text):
    1.  
    2. if b1 > 200 then showsix ; test random number and jump
    3. if b1 > 150 then showfive
    4. if b1 > 100 then showfour
    5. if b1 > 50 then showthree
    6. if b1 > 10 then showtwo
    7.  
    Now, b1 will be in the range of 0-255 and will go to various branches.
    You can use the statement random w0 to get a 16 bit number that will range from 0-655235.

    Refresh yourself on how picaxe basic defines dedicated variables.

    Also - get in the habit of using endif for each if - it will save you time in the long run.
    edit: I have to correct myself again - for single line if-then statements, no endif is used.

    Finally, when you make a request like this, you absolutely have to give more information. You can't expect the readers to magically know what you are using and what you are doing. I recognize the syntax as picaxe basic, but I have no idea which chip and how you have a switch hooked up.

    Hope this helps and let us know

    Edited to add:
    I did not test the solution, but for other readers who may not be familiar:

    Picaxe BASIC has dedicated variables. W0 is a 16 bit dedicated variable and can be referenced as two 8-bit variables, B0 and B1.

    The RANDOM command:, e.g. "random w0" will place a random value into w0 in the range 0-65535

    The appropriate syntax is random [16-bit var]. I am not sure what random b1 will do, I assumed that it would use W0 without testing it.

    Better to use the appropriate W0 or other 16 bit value rather than b1 and do it that way.

    IOW:
    Code (Text):
    1.  
    2. Random W0
    3. if W0 > 55000 then showsix ; test random number and jump
    4. if W0 > 44000 then showfive
    5. if W0 > 33000 then showfour
    6. if W0 > 22000 then showthree
    7. if W0 > 11000 then showtwo
     
    Last edited: Sep 28, 2017
    Mark Hughes likes this.
  5. KeepItSimpleStupid

    Distinguished Member

    Mar 4, 2014
    2,830
    497
    based on no language, I'll say this in BASIC. RND is a number between 0 an 1

    RANDOMIZE; is a directive to change the seed
    x=INT((6*RND+1)*10)/10 is a number between 1 and 6.
     
    Mark Hughes likes this.
  6. Mark Hughes

    Member

    Jun 14, 2016
    270
    22
    I think Raymond's got the answer. Try it and get back to us.
     
  7. mark Edward Easterling

    Thread Starter New Member

    Sep 28, 2017
    3
    0
    Hi all,
    I have tried what Raymond suggested but still no joy. It is on PIC-AXE Basic editor software. Any other suggestions?

    Cheers
    Mark

    ' ****** Dice using random command *****
    serout B.7,N2400,(254,1);set B.7, as output for LCD
    let dirsC = %00000000 ;set pinsC as inputs or outputs
    let dirsB = %11111111 ;set pinsB as inputs or outputs(pin B.0
    ;symbol key_pos = b0 ; number of keys pressed
    ;symbol key_value = b1 ; value of key pressed

    main:
    random w0 ; generate a random number
    ;let key_pos = 0
    pause 500 ; wait for display to initialise
    serout B.7,N2400,(254,1) 'clear display
    pause 30
    serout B.7,N2400,(254,131) ; move to end of first line
    serout B.7,N2400,("ENTER CODE") ;first line of code

    if pinC.1 = 1 then makenumber ; test switch
    goto main
    makenumber:
    if w0 > 55000 then showsix ; test random number and jump
    if w0 > 44000 then showfive
    if w0 > 33000 then showfour
    if w0 > 22000 then showthree
    if w0 > 11000 then showtwo

    showone:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("1")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showtwo:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("2")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showthree:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("3")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showfour:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("4")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showfive:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("5")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showsix:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("6")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main
     
  8. Raymond Genovese

    Active Member

    Mar 5, 2016
    971
    534
    It would help us, help you, if you provided a more complete description of the situation.

    You have not said what picaxe chip that you are using.
    You have not said how you have the switch hooked up to C.1.
    You have not said what lcd screen that you are using or how it is hooked up.


    That being said, I rewrote your program to remove ALL of the LCD commands.
    I hooked up a switch to C.1, using a 08M2 chip, exactly as illustrated below (from http://www.technologystudent.com/pics/outin2.htm)
    except that I connected the switch to pin 6, rather than pin 3 as illustrated. On the 08M2 chip, pin 6 corresponds to C.1 and pin 1 is Vcc.

    You are using a different picaxe chip (since you refer to a B port). The point is that the switch needs to be configured as the diagram below shows and it should be connected to the pin representing c.1
    [​IMG]
    Below is your program, modified as I said. I also added statements to print the random number and to print which of the 'show" routines it goes through. The debugging print outs are accomplished using the "sertxd" command. When you run the program, open a "terminal" within the picaxe editor (see the picaxe manuals for detailed instructions, but it is quite easy). The output of the "sertxd" commands go to the built-in terminal in the Picaxe editor. In this way, you can see the random values and see where the program goes.

    Before you run the program, remove all of your connections to the LCD screen and make sure that the switch is hooked up correctly.

    Code (Text):
    1.  
    2. ' ****** Dice using random command *****
    3. ;serout B.7,N2400,(254,1);set B.7, as output for LCD
    4. ;let dirsC = %00000000 ;set pinsC as inputs or outputs
    5. ;let dirsB = %11111111 ;set pinsB as inputs or outputs(pin B.0
    6. ;symbol key_pos = b0 ; number of keys pressed
    7. ;symbol key_value = b1 ; value of key pressed
    8.  
    9. main:
    10. random w0 ; generate a random number
    11. sertxd("Random Number==",#w0,13,10); <---
    12. ;let key_pos = 0
    13. pause 500 ; wait for display to initialise
    14. ;serout B.7,N2400,(254,1) 'clear display
    15. pause 30
    16. ;serout B.7,N2400,(254,131) ; move to end of first line
    17. ;serout B.7,N2400,("ENTER CODE") ;first line of code
    18.  
    19. if pinC.1 = 1 then makenumber ; test switch
    20. goto main
    21. makenumber:
    22. if w0 > 55000 then showsix ; test random number and jump
    23. if w0 > 44000 then showfive
    24. if w0 > 33000 then showfour
    25. if w0 > 22000 then showthree
    26. if w0 > 11000 then showtwo
    27.  
    28. showone:
    29. sertxd("showone",13,10); <---
    30. ;serout B.7,N2400,(254,195) ; move to start of second line
    31. ;serout B.7,N2400,("1")
    32. wait 1
    33. ;serout B.7,N2400,(254,195) ; move to start of second line
    34. ;serout B.7,N2400,("#")
    35. goto main
    36.  
    37. showtwo:
    38. sertxd("showtwo",13,10); <---
    39. ;serout B.7,N2400,(254,195) ; move to start of second line
    40. ;serout B.7,N2400,("2")
    41. wait 1
    42. ;serout B.7,N2400,(254,195) ; move to start of second line
    43. ;serout B.7,N2400,("#")
    44. goto main
    45.  
    46. showthree:
    47. sertxd("showthree",13,10); <---
    48. ;serout B.7,N2400,(254,195) ; move to start of second line
    49. ;serout B.7,N2400,("3")
    50. wait 1
    51. ;serout B.7,N2400,(254,195) ; move to start of second line
    52. ;serout B.7,N2400,("#")
    53. goto main
    54.  
    55. showfour:
    56. sertxd("showfour",13,10); <---
    57. ;serout B.7,N2400,(254,195) ; move to start of second line
    58. ;serout B.7,N2400,("4")
    59. wait 1
    60. ;serout B.7,N2400,(254,195) ; move to start of second line
    61. ;serout B.7,N2400,("#")
    62. goto main
    63.  
    64. showfive:
    65. sertxd("showfive",13,10); <---
    66. ;serout B.7,N2400,(254,195) ; move to start of second line
    67. ;serout B.7,N2400,("5")
    68. wait 1
    69. ;serout B.7,N2400,(254,195) ; move to start of second line
    70. ;serout B.7,N2400,("#")
    71. goto main
    72.  
    73. showsix:
    74. sertxd("showsix",13,10); <---
    75. ;serout B.7,N2400,(254,195) ; move to start of second line
    76. ;serout B.7,N2400,("6")
    77. wait 1
    78. ;serout B.7,N2400,(254,195) ; move to start of second line
    79. ;serout B.7,N2400,("#")
    80. goto main
    81.  
    I tested the program on a 08m2 and it works as it should. The random numbers are displayed and when I press the switch, the name of the show routine that it entered is displayed. Here is a screenshot of the output:

    sshot1.jpg


    Let us know if this works for you or, if it does not, exactly what happens.
     
    Last edited: Sep 29, 2017
  9. mark Edward Easterling

    Thread Starter New Member

    Sep 28, 2017
    3
    0
    Hi,
    Sorry I am using an 18m2, I can make it work using an 08m2. C.1 is hooked up as above but on pin 18 of the 18m2. The LCD works fine its generating the random number that is proving a little awkward. I have now used random w0, which is working but it goes through 9 times to 'showone' before it starts being a random number.

    ' ****** Dice using random command *****
    serout B.7,N2400,(254,1);set B.7, as output for LCD
    let dirsC = %00000000 ;set pinsC as inputs or outputs
    let dirsB = %11111111 ;set pinsB as inputs or outputs(pin B.0
    ;symbol key_pos = b0 ; number of keys pressed
    ;symbol key_value = b1 ; value of key pressed

    main:
    random w0 ; generate a random number
    ;let key_pos = 0
    pause 500 ; wait for display to initialise
    serout B.7,N2400,(254,1) 'clear display
    pause 30
    serout B.7,N2400,(254,131) ; move to end of first line
    serout B.7,N2400,("ENTER CODE") ;first line of code

    if pinC.1 = 1 then makenumber ; test switch
    goto main
    makenumber:
    if w0 > 55000 then showsix ; test random number and jump
    if w0 > 44000 then showfive
    if w0 > 33000 then showfour
    if w0 > 22000 then showthree
    if w0 > 11000 then showtwo


    showone:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("1")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showtwo:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("2")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showthree:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("3")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showfour:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("4")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showfive:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("5")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main

    showsix:
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("6")
    wait 1
    serout B.7,N2400,(254,195) ; move to start of second line
    serout B.7,N2400,("#")
    goto main
     
  10. Raymond Genovese

    Active Member

    Mar 5, 2016
    971
    534
    When you enter code in the message, type in "[ code ]" at the beginning and "[ /code ]" at the end of the code lines (don't use the quotation marks or spaces, I had to use those so it wouldn't act on the text in this message). This makes the program more readable.

    "I have now used random w0, which is working but it goes through 9 times to 'showone' before it starts being a random number. "

    What does that mean? Remember, I am not where you are. Adding W0 was a few messages ago and your response was a simple "no joy". Does it display the random number exactly 9 times, going to showone each time, or one time that you were watching? Most importantly, what were the values of W0? If the values were less than 11000, that is exactly what you are telling it to do!

    How is the switch hooked up, because until you press the switch, it should simply go get another random value without going to any show routine. That is what I showed you on the screenshot. Now if your switch is bouncing all over the place or is not hooked up correctly, that is another matter.

    Did you run the program with the terminal program to display the output values or not?

    I understand how tough it is to debug a program through messages, but you have to appreciate the fact that I already know how to write a program to simulate a die. If I am suggesting to you to remove the connections to the LCD and run the short program using the terminal to output variables, it is because I am trying to help you understand what the program is doing.

    In these situations, there is a golden rule - "Divide and conquer". Strip the program down to a point where it works as it should doing something and build it back up.
     
  11. Raymond Genovese

    Active Member

    Mar 5, 2016
    971
    534
    There are two other issues to deal with once you get this far. The first is your switch processing, assuming that you want one clean press and release.

    You need to debounce the switch input. Picaxe basic thoughtfully has a 'button' command to take care of this - check out the syntax and use it. Also, you want to check that the button has been released before you select another die.

    Then there are the die probabilities.

    W0 will be in the range of 0-65535. Never mind for the moment that these are not truly random numbers – let’s just accept that they are close.
    Given your statements

    Code (Text):
    1. makenumber:
    2. if w0 > 55000 then showsix ; test random number and jump
    3. if w0 > 44000 then showfive
    4. if w0 > 33000 then showfour
    5. if w0 > 22000 then showthree
    6. if w0 > 11000 then showtwo
    7.  
    You get the following results if you assume that each of the possible numbers, 0-65535, are equally likely to occur:
    There are 65535-55000=10535 possible numbers for showsix (p=.1608)
    There are 55000-44000=11000 possible numbers for showfive (p=.1679)
    There are 44000-33000=11000 possible numbers for showfour (p=.1679)
    There are 33000-22000=11000 possible numbers for showthree (p=.1679)
    There are 22000-11000=11000 possible numbers for showtwo (p=.1679)
    There are 11000-0=11000 possible numbers for showone (p=.1679)

    So, you have a die that is biased against getting a ‘6’.
    Since 65535/6=10922.5, you can’t get an equal representation of the probabilities for each number – that .5 is a problem.

    There are a number of ways to deal with this and one quick and dirty way to improve it is to use this code:
    Code (Text):
    1.  
    2. if w0 > 55535 then showsix ; test random number and jump
    3. if w0 > 45535 then showfive
    4. if w0 > 35535 then showfour
    5. if w0 > 25535 then showthree
    6. if w0 > 15535 then showtwo
    7. if w0 > 5535 then showone
    8. goto main ; redraw if w0 is less than 5536
    9.  
    Now you have six bins of 10000 equally likely (p=.1666) numbers. It creates a situation where there will be a small and irregular delay while it occasionally has to redraw a number that fits the intervals, but will not be noticeable. The advantage is that the die is no longer biased.

    Hope this helps.
     
Loading...