|
|
View previous topic :: View next topic |
Author |
Message |
Maliha
Joined: 08 Dec 2012 Posts: 7
|
Digital Dice |
Posted: Sun Dec 09, 2012 12:16 am |
|
|
I am trying to make a digital dice with PIC16F877A. I am very new to PIC programming and CCS compiler. This is my code which is not working...
Code: |
#include <16f877a.h>
#define RAND_MAX 5
#include <stdlib.h>
#include <stdlibm.h>
#use delay (clock=20M)
//main program starts here
void main() {
setup_adc_ports(NO_ANALOGS);
set_tris_b (0b00000000);
int i;
i=rand()+1;
switch (i) {
case 1: output_b (0b00000110);
case 2: output_b (0b01011011);
case 3: output_b (0b01001111);
case 4: output_b (0b01100110);
case 5: output_b (0b01101101);
case 6: output_b (0b01111101);
default: output_b (0b01111111);
}
}
|
Can anyone tell me what is the problem here? This might be pretty stupid to most of you as this seems like a forum for very advanced programmers, but please help me, and in easy words too. :D _________________ Believe it! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Sun Dec 09, 2012 2:04 am |
|
|
What does it actually do?.
Thing is that as written, it'll give a fixed value output on the port, and then do nothing else. The value will be the same each time it is run.
First key thing is to understand 'rand'. It has nothing to do with random numbers!. It returns a _pseudo random_ sequence, where the statistical probability of each number is close to that of a genuine 'random' sequence. However the sequence always starts from the same place, and is dependant on 'srand'. So to get a 'random' wake up, you need to 'seed' (load a new trigger point for the sequence), from something that is hard to predict or is close to 'random'. Typical example would be to have the user hold down a key for a moment to start the sequence. Then 'time' this, and since the user would never be able to hold the key for the same time, the time would be a hard to predict starting point. This can then be fed into srand, and rand will then generate a new sequence based upon this seed.
Other typical seed things would be a value from an adc fed off a divider off a mains transformer. Since switch on will have nothing to do with the mains timing, the number will again be unlikely to repeat.
Second thing is as written, the code dies (drops off the end) after setting the output. Normally you'd want something like a key press to make it loop and produce a new number.
As a general comment, write your variable declarations using K&R C syntax. A lot of people are breaking this here, and it is the cause of some oddities.
In C, a variable declaration _must_ be at the start of a code section. So _before_ setting the adc ports and the tris.
Now later languages (C++ for example), allow 'mid code' declarations, and CCS now does accept these, _but_ they have a habit of going wrong. With your simple declaration, it'll probably work, but with complex declarations (structures etc.), they have a habit of not behaving as expected, and resulting in variables getting corrupted.....
It is much safer to stick with standard C syntax in this regard, otherwise it is a 'problem waiting to happen' in future code.
Best Wishes |
|
|
ahsansag93
Joined: 09 Dec 2012 Posts: 3
|
help me also |
Posted: Sun Dec 09, 2012 6:38 am |
|
|
Ttelmah wrote: | What does it actually do?.
Thing is that as written, it'll give a fixed value output on the port, and then do nothing else. The value will be the same each time it is run.
First key thing is to understand 'rand'. It has nothing to do with random numbers!. It returns a _pseudo random_ sequence, where the statistical probability of each number is close to that of a genuine 'random' sequence. However the sequence always starts from the same place, and is dependant on 'srand'. So to get a 'random' wake up, you need to 'seed' (load a new trigger point for the sequence), from something that is hard to predict or is close to 'random'. Typical example would be to have the user hold down a key for a moment to start the sequence. Then 'time' this, and since the user would never be able to hold the key for the same time, the time would be a hard to predict starting point. This can then be fed into srand, and rand will then generate a new sequence based upon this seed.
Other typical seed things would be a value from an adc fed off a divider off a mains transformer. Since switch on will have nothing to do with the mains timing, the number will again be unlikely to repeat.
Second thing is as written, the code dies (drops off the end) after setting the output. Normally you'd want something like a key press to make it loop and produce a new number.
As a general comment, write your variable declarations using K&R C syntax. A lot of people are breaking this here, and it is the cause of some oddities.
In C, a variable declaration _must_ be at the start of a code section. So _before_ setting the adc ports and the tris.
Now later languages (C++ for example), allow 'mid code' declarations, and CCS now does accept these, _but_ they have a habit of going wrong. With your simple declaration, it'll probably work, but with complex declarations (structures etc.), they have a habit of not behaving as expected, and resulting in variables getting corrupted.....
It is much safer to stick with standard C syntax in this regard, otherwise it is a 'problem waiting to happen' in future code.
Best Wishes |
cau u make a sample program of electronic dice for me? so that i could easily also understand :( |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Sun Dec 09, 2012 7:37 am |
|
|
comments...
The best teacher is practice!Some of us here have decades of PIC programming under our belt, and this forum is not a 'teacher of PIC C programming'.It is generally understood that people here have a basic idea of PICs,programming and hardware construction.
so...
Start with simple program to actually turn on the leds as YOU want them to be.First 1 LED ,then 2, ....up to six
Then maybe add a small(say /12 second) delay and go through the legal sequence of die numbers.
Then add code for the user to 'press a button' to 'roll the die'.Have this program display a number.
Once your're satified all is good, then add code to provide a 'random'
effect.
There are about 5 or 6 smaller 'sub-programs' you need to design and test before the final 'roll a die' program is done.
Start small, build upon your sucesses and failures.The more work you do, the better programmer you'll become.
Also be sure to add comments to your programs!! It costs NOTHING in code space and will save you hours if not days of time, later when you wonder WHY did I do 'this' or WHAT does 'that' do'?
hth
jay |
|
|
Maliha
Joined: 08 Dec 2012 Posts: 7
|
|
Posted: Sun Dec 09, 2012 9:18 am |
|
|
Can you please elaborate a little on how to time the pressing of button? _________________ Believe it! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Sun Dec 09, 2012 9:26 am |
|
|
super easy... use the 'search' engine this forum has !
There are several ways to implement the 'pressed button' function. It's up to YOU the programmer which one to choose is best for your application.
What works for me may not be best for you.
hth
jay |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Dec 09, 2012 1:40 pm |
|
|
Maliha wrote: | Can you please elaborate a little on how to time the pressing of button? | Like temtronic says, there are loads of ways.
It's usual to check the state of the button at intervals. You know that the button really has been pressed or released when several samples of the state agree.
It's up to you wether:-
1) To look for button depressed or release,
2) Use interrupts for checking button state.
3) Use interrupts for timing.
4) ................
Mike |
|
|
Maliha
Joined: 08 Dec 2012 Posts: 7
|
|
Posted: Wed Dec 12, 2012 12:52 pm |
|
|
Thank you so much every one. I finally figure out a way to do it
I used a button as an input and use the relative value of time interval (during which the button remained pressed) to provide the seed value for srand. Here is the code which I managed.
Code: | #include <16f877a.h>
#define RAND_MAX 5
#include <stdio.h>
#include <stdlib.h>
#include <stdlibm.h>
#use delay (clock=20000000)
//main program starts here
void main() {
setup_adc_ports(NO_ANALOGS);
set_tris_b (0b00000000); //Assigning port B as output
set_tris_d (0b11111111); //Assigning port D as input
int seg[6]={0b0000110,0b11011011,0b01001111,0b01100110,0b01101101,0b01111101};
int s;
int button;
button=input_state(PIN_D0);
//The following loop causes the seven segment display to flash numbers from 1 to 6 (just for fun) until the button at pin D0 is pressed
while (button==0) {
int a;
for (a=1; a<=6; a=a+1) {
output_b (seg[a]);
delay_ms (50);
button=input_state(PIN_D0); //Checks the state of button
}
}
//Button is pressed. Now count the number of 1ms intervals till the release of button
while (button==1) {
output_b (0b00000000);
s=s+1;
delay_ms (1);
button=input_state(PIN_D0);
}
int i;
srand(s); //Assigns the number of intervals as seed value
i=rand()+1;
output_b (seg[i]); //Finally the output
} |
_________________ Believe it! |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Dec 12, 2012 2:51 pm |
|
|
Congratulations on your solution!
Just one remark, have you noticed that you never get the value '1'?
And sometimes the output is unreadable?
Have a closer look at this code: Code: | i=rand()+1;
output_b (seg[i]); //Finally the output | An array starts counting at offset 0, so the array is 0 - 5. You are using 1 - 6...
The same error is present in the part where you roll the dice (until the key is pressed). |
|
|
Maliha
Joined: 08 Dec 2012 Posts: 7
|
|
Posted: Thu Dec 13, 2012 12:41 am |
|
|
Yes after you pointed out, I noticed that I was never getting a '1'. So, I changed the value of RAND_MAX to 6 and replaced that:
i=rand()+1;
with this:
i=rand(); _________________ Believe it! |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Dec 13, 2012 1:13 am |
|
|
Maliha wrote: | So, I changed the value of RAND_MAX to 6 | This is too large, now your dice goes from 1 to 7 (array 0-6). |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|