Random command not working

Thread Starter

mark Edward Easterling

Joined Sep 28, 2017
3
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
 

Mark Hughes

Joined Jun 14, 2016
409
;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?
 
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
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:
if b1 > 200 then showsix ; test random number and jump
if b1 > 150 then showfive
if b1 > 100 then showfour
if b1 > 50 then showthree
if b1 > 10 then showtwo
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:
Random W0
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
 
Last edited:

Thread Starter

mark Edward Easterling

Joined Sep 28, 2017
3
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
 
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

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:
' ****** 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
sertxd("Random Number==",#w0,13,10); <---
;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:
sertxd("showone",13,10); <---
;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:
sertxd("showtwo",13,10); <---
;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:
sertxd("showthree",13,10); <---
;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:
sertxd("showfour",13,10); <---
;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:
sertxd("showfive",13,10); <---
;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:
sertxd("showsix",13,10); <---
;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
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:

Thread Starter

mark Edward Easterling

Joined Sep 28, 2017
3
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
 
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. /--/
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.
 
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:
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
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:
if w0 > 55535 then showsix ; test random number and jump
if w0 > 45535 then showfive
if w0 > 35535 then showfour
if w0 > 25535 then showthree
if w0 > 15535 then showtwo
if w0 > 5535 then showone
goto main ; redraw if w0 is less than 5536
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.
 
Top