# Pic Basic Question

Status
Not open for further replies.

#### Tako Kichi

##### New Member
Hi Folks,

I am in the process of writing my first PIC program (in PIC basic) for a hobby project and I have come across a problem that I just can't seem to resolve. I have literally spent tens of hours searching all the forums, lists, manufacturer data etc and I am still hitting a wall. I am hoping someone in here can point me in the right direction. I have a feeling that this is such a simple error that I am going to kick myself if/when I get it resolved! I am pleased that I have 95% of the program working considering I jumped into programming with both feet (this is NOT an easy first project) but this last little bit is begining to get tiresome :wink:

My program compiles just fine but when I run it through the 'Pic Simulator IDE' one of the sub-routines (and it just happens to be THE most important one) constantly gives an incorrect operation. I think the problem stems from the 'Random' command and its set-up, although I have completely removed the references to 'Random' in one version of the code and I still get the same error!

I have read all the references to 'Random' and I do understand that it will give the same pseudo random number from the same 'seed' so I was trying to 'seed' it by sampling the TMR0 timer. The idea was that the 'seed' would be placed in the variable just before the 'Random' command so that it will get a different 'seed' each time. I start the timer at the begining of the program so that it can free run off the internal clock (and I can watch it running on the simulator so I know it is running) then I read the TMR0 register and perform the 'Random' operation. The result is then truncated to give a number between 1 and 60. This is then converted to an equivalent time delay (in a loop.......I tried 'Pause' at first but I couldn't get that to work either!) Next I generate a second random number and depending on the value the program should choose between one of two options via an 'If....Then' statement.

My problem is that no matter what I do with regard to the 'Random' command (and even removing it) I still get the same time delay and the same option! I really do not understand what is going on at this point (as I said I am a newbie at this). I have included the pertinent bits of code below (the rest runs fine) and if anyone can spot the error please let me know so that I can stop banging my head against this wall :wink: The PIC in question BTW is a 16F818, using the internal oscillator option.

Thanks for any help.

Larry
-----------------------------

The set-up info..........

'set timer
option_reg = %11011000 'set TMR0 to internal clock

'set variables
RND VAR WORD 'set RND as variable

'set LOOP1 & 2 as variables for loops
LOOP1 VAR WORD 'set LOOP1 as variable
LOOP2 VAR WORD 'set LOOP2 as variable

The problem sub-routine.......

PB3SUB:
Low PBCONTROL 'turn off PB's
Low GLED 'turn off Green LED
High RLED 'turn on Red LED
'NOTE the above three lines work perfectly and the sub-routine falls apart from this point
RND=TMR0 'load TMR0 into RND
Random RND 'randomise RND
RND=(RND*60/65535)+1 'truncate RND TO fall between 1 and 60
For LOOP1=1 TO (RND*1000) 'pause for RND secs
Next LOOP1
RND=TMR0 'load TMR0 into RND a 2nd time
Random RND 'randomise RND a 2nd time
Low RLED 'turn off Red LED
IF RND>=32765 Then PB1SUB 'if RND is higher than mid point run PB1 sub-routine
GoTo PB2SUB 'if RND is lower than mid point run PB2 sub-routine

NOTE: The program ALWAYS gives the same time delay and ALWAYS returns the 'PB2SUB' routine instead of randomly delaying the time and randomly selecting between 'PB1SUB' and 'PB2SUB'

#### ivancho

##### New Member
I am not exactly sure if I follow... :? I have to think more about it..... but here is my 2 cents.

When truncating to get a number from 1-60 you are multiplying by 60. Lets assume you get a random number of 5000 ..... :shock: 60*5000 = 300000.... your RND variable is a 16 bit VAR with a MAX value of 65535 So you run into problems there.

I suggest you get a random number 1-60 like this:
Code:
RND = (RND // 61) + 1        'Returns a number between 1-60
There is a slight chance to get 61 when RND = 60... this can happen 1:65535 very small chance.
You also want to generate a random pause.... do you want this random pause to be in seconds? miliseconds?.....

You should use:
Code:
Pause RND     'For 1-60 miliseconds pause
________________or______________________
RND = (RND * 1000)
Pause RND     'For 1-60 seconds pause
:idea: You said you understand the pseudo random process right? Just to make sure the Ramdom command is not true random generator..... instead if you have the same steps in your program every time you start the PIC until it hit the random command, chances are you are always going to get the same random number, every start up.
To solve this the random number can be "seed" by an external event. Such as a sine wave generator on ADC pin. Or a temperature probe or a photocell or a RTC, etc.

Good Luck

Ivancho

#### Tako Kichi

##### New Member
Hi Ivancho,

I tried using <RND = (RND // 61) + 1> and it works fine now! :lol:

I guess it was a simple answer after all and I didn't spot the error in my original formula. :!: After running some tests in 'PIC Simulator IDE' I can see that it is indeed mixing up the time delays and mixing up the outputs as required. After running the first tests however I decided to reduce the time delay to a max of 30 seconds as 60 seconds was just too long a time to be waiting for the buzzer to go off.

You said you understand the pseudo random process right? Just to make sure the Ramdom command is not true random generator..... instead if you have the same steps in your program every time you start the PIC until it hit the random command, chances are you are always going to get the same random number, every start up.
To solve this the random number can be "seed" by an external event. Such as a sine wave generator on ADC pin. Or a temperature probe or a photocell or a RTC, etc.
I am seeding the random number by sampling the TMR0 timer which is operating as a free running clock. Originally I took the entire 16 bit value of TMR0 but I found that the results could be predicted somewhat depending on the time between the trigger inputs. I am now just using the lower 5 bits of TMR0 to seed the random variable. This seems to work better as the lower bits in the timer change much more quickly. The timer is first sampled 4 instruction lines after the sub-routine is triggered so it will be a random event anyway depending upon where in the clock cycle the button is pressed. It is sampled again after the time delay for the second choice in the subroutine so again it is going to be random. In fact I ran a series of 66 tests this afternoon (I was going for 100 but the sim prog timed out as it is only the demo version) and even when I got the SAME time delay I was getting DIFFERENT audio outputs which is just what I was looking for.

Thanks for your help with the formula as it would have taken me quite a while to spot that error.

Larry

Status
Not open for further replies.