CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Digital Dice

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Maliha



Joined: 08 Dec 2012
Posts: 7

View user's profile Send private message

Digital Dice
PostPosted: Sun Dec 09, 2012 12:16 am     Reply with quote

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: 19504

View user's profile Send private message

PostPosted: Sun Dec 09, 2012 2:04 am     Reply with quote

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

View user's profile Send private message Send e-mail

help me also
PostPosted: Sun Dec 09, 2012 6:38 am     Reply with quote

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: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Dec 09, 2012 7:37 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Dec 09, 2012 9:18 am     Reply with quote

Can you please elaborate a little on how to time the pressing of button?
_________________
Believe it!
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Dec 09, 2012 9:26 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Dec 09, 2012 1:40 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Dec 12, 2012 12:52 pm     Reply with quote

Thank you so much every one. I finally figure out a way to do it Smile
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

View user's profile Send private message

PostPosted: Wed Dec 12, 2012 2:51 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 13, 2012 12:41 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 13, 2012 1:13 am     Reply with quote

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).
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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