Setting an random LED high - Page 1
Forum section: electronics / general

author: pelle.jansen
author_rank: Contributor
timestamp: February 07, 2012, 04:56:19 pm
content: Hello all,For a project I need to set an random led high.So what I would have to do is:1. create a random number between 0 and 72. save that number in a variable3. light the led4. save same random number in different variable5. generate new random number6. compare old and new random number: if they are equal generate new random number.run rest of code.Yesterday in the shoutbox I got pretty far but just barely not there. I do have an random number using rand() but i think it is in binary and between 0b00000000 and 0b11111111 so 0 and 255 decimal. Any idea how to convert it to decimal? The function doesn't take arguments so the only thing I can come up with is to make the function recursive and let it run until it is within parameters. Timing does not matter. It doesn't have to be completely random. Pseudo random is good enough.Than there is still the issue of setting and clearing the same led as number in the variable. You cant just use RD num = 1; so how would you do that?I have something like it running in Python but there you have the great random.randrange()EDIT: i am using the Hi Tech C compiler

author: Unknown
author_rank: Unknown
timestamp: February 07, 2012, 05:21:13 pm
content: How many LEDs do you have? 8?

author: pelle.jansen
author_rank: Contributor
timestamp: February 07, 2012, 05:27:38 pm
content: Quote from: Alex on February 07, 2012, 05:21:13 pmYes. 8 LEDs with their appropriate resistors ofcourse.

author: Simon
author_rank: Unknown
timestamp: February 07, 2012, 05:52:04 pm
content: just start with a number, do something to it like multiply and divide it, add or subtract numbers, use a longish number then just use the last decimal digit or do it all in binary and you can just use the last 4 digits, light up the let that corresponds to the number then rerun the computation, you can add in the check that your not using the same number again.The actual syntax will depend on the language your using

author: pelle.jansen
author_rank: Contributor
timestamp: February 07, 2012, 06:11:28 pm
content: Quote from: Simon on February 07, 2012, 05:52:04 pmI use C with the hi tech picc compiler.Wouldn't that give the same number every time? Or you would have to randomize the calculations you would need something random again. I already have an random number but it is 8 bit binary 00000000 to 11111111. It would be a solution to let just a single bit count or to convert the binary number to decimal.

author: Simon
author_rank: Unknown
timestamp: February 07, 2012, 06:14:34 pm
content: if you start with a large number and do some random calculation on it, and then do the same calculation on the result, and then do the same calculation on the result you will keep getting different numbers, you just need to use the last digit(s)for example:startA = 256A = A*25/7B = (last digit)Led = Bgoto start

author: Jad.z
author_rank: Regular Contributor
timestamp: February 07, 2012, 06:21:29 pm
content: Here is a link to a Binary to Decimal conv c code:http://www.daniweb.com/software-development/c/code/216372

author: 8086
author_rank: Super Contributor
timestamp: February 07, 2012, 06:27:30 pm
content: To make it random, you can use the ADC (assuming you have one) and read the least significant bits and use them as a seed for your random number generator.

author: Simon
author_rank: Unknown
timestamp: February 07, 2012, 06:28:39 pm
content: what will you supply the ADC with ?

author: 8086
author_rank: Super Contributor
timestamp: February 07, 2012, 06:30:49 pm
content: Quote from: Simon on February 07, 2012, 06:28:39 pmWhatever you like. Nothing. It's just going to be reading noise anyway.

author: Simon
author_rank: Unknown
timestamp: February 07, 2012, 06:32:43 pm
content: thats true, I was wondering where could you get some random noise, maybe just connect an opamp to it and an "aerial" on the opamp input, it can pick up mains hum or anything doing around. remember that micro-controller ADC don't have particularly high input impedences, will they just made noise ?

author: 8086
author_rank: Super Contributor
timestamp: February 07, 2012, 06:48:15 pm
content: I would expect an on-chip ADC to produce some internal noise even without any input...probably enough to affect the first few LSBs, depending on the resolution. You should get at least one random bit from ADC noise whatever you use, really.

author: SeanB
author_rank: Super Contributor
timestamp: February 07, 2012, 07:48:43 pm
content: If you are going to use the on board ADC just use 2 resistors to provide it a half supply voltage, and read it as a seed. There will be enough noise on the lower bits if you are using the internal reference and no decoupling cap on the input to the ADC, especially if the chip is not in a low power mode at the time. Then take the random number output and AND it with 00000111 binary, to mask out a value between 0 and 7 dec. Then you can either use a table to drive the outputs or use any other method as you now have a random number with 8 variations.

author: Unknown
author_rank: Unknown
timestamp: February 07, 2012, 08:07:55 pm
content: You can convert it to decimal in software, but then you have to divide by 32. You must utilise the full range of the random number generated by the rand function, otherwise sometimes no LEDs will be on.Here is a lightweight solution without multiplications and divisions. You can do a simple set of if/elseif statements. You might need to change this to compile under HITECH C. The idea is to decimate the number into ranges.unsigned char var; //declarevar = rand (); //initialise by generating a random number 0...255.if ((var>=0) && (var<=31)) light_led(1);elseif ((var>=32) && (var<=63)) light_led(2);elseif ((var>=64) && (var<=95)) light_led(3);.....elseif ((var>=223) && (var<=255)) light_led(;Even if you get the logic a bit wrong, only 1 led will light up because of the elseif statement.Simples!EDIT: Sean, the method in your last post above will not work, it only samples regions inside the dynamic range of the random variable. Most of the times the bitwise operation it will return 0. For example, if the random number is 8 in decimal i.e. 0x00001000, then 0x00001000 & 0x00000111 = 0x00000000 i.e. 0.

author: Jad.z
author_rank: Regular Contributor
timestamp: February 07, 2012, 08:21:09 pm
content: What you people are suggestingis a bit too much for his simple application.You are suggesting to use white noise, to generate a completely random number, for someone who clearly stated that pseudo random is good enough. And lets not forget that the range he needs is 0 to 7 now how random that have to bePlus he is a beginner who have just started experimenting with PICs and flashing some LEDs; i don't think ADC come next, not yet.

author: pelle.jansen
author_rank: Contributor
timestamp: February 07, 2012, 08:58:23 pm
content: I could also use the timer. The PIC16F877A i am using has 3 build in timer modules. All of them are still free but I seem to be unable to set the OPTION_REG register to set the timer options. I get the error "conflicting declarations for variable "OPTION_REG"(/Microchip/Hi_Tech_C_MIDRANGE/include/pic16f877a.h:639). When I go to that line in question it is the volatile unsigned char OPTION REG @0c081. Now I am not that familiar with .h files but it looks fine. Otherwise would it be a good idea to just let the timer run at a low speed, reset when it reaches 7 and read the timer when needed? That might work. Otherwise counting pulses from an external 555 timer ic should also do the trick. By reading the value and resetting when it reaches 7 it should give me an random number. It is just a little fun prototype so it doesn't has to be perfect.@Jad.z You can learn a lot in 3 weeks. About a month ago I barely knew what a microcontroller was. Now I at least master digital IO and know how to use other things. Like timers. When the option register is not giving you an headache.

author: IanB
author_rank: Super Contributor
timestamp: February 07, 2012, 09:39:56 pm
content: Quote from: pelle.jansen on February 07, 2012, 04:56:19 pmI think you have a bit of a misunderstanding here, perhaps. As far as a computer is concerned a number is a number. The number "5" for example is the same number in binary or in decimal (or in hex or in octal). It is only the representation on paper that changes, not the size of the number. So there is no need to convert to decimal. You just calculate with the number as an integer--for example, add and subtract, multiply and divide as required.

author: PedroDiogo
author_rank: Regular Contributor
timestamp: February 07, 2012, 10:10:50 pm
content: Quote from: pelle.jansen on February 07, 2012, 04:56:19 pmI suggest you pick the 3 LSB (as you only need to light 8 LEDs) from the output of the rand() function and convert it to decimal.I can see a simple way to convert it to decimal:Code:#define BIT(word, n) ((word >> n) & 1)#define randToDecimal(word) BIT(word,0) + BIT(word,1)*2 + BIT(word,2)*4void main (){int randomNumber = rand();printf("Random number: %d\n", randomNumber);printf("3 LSB to decimal:%d\n",randToDecimal(randomNumber));}And then use the result to light up the appropriate LED.However you could use the rand() output to directly light a random number of LEDs each time, without converting it to decimal.

author: Jad.z
author_rank: Regular Contributor
timestamp: February 07, 2012, 10:12:06 pm
content: Actually I once read a code that generate a random number by counting the bounces of a tactile switch.A bit off topic, but here is an application note on switch bounce:http://pdfserv.maxim-ic.com/en/an/AN287.pdfAnd here is an example on debouncing using software:http://www.secondvalleysoftware.com/hardware/io/pdfs/softDebounce.pdfExtra one (I know you can't speak assembly, but you can read the description of the steps)http://members.ee.net/brey/Debounce.PDF

author: senso
author_rank: Frequent Contributor
timestamp: February 08, 2012, 12:54:20 am
content: There is also the shift solution.int i = rand() % 8;PORTA = 1<<i;And its done.

author: TerminalJack505
author_rank: Super Contributor
timestamp: February 08, 2012, 01:26:30 am
content: Since you're just playing around, Senso's code is all you probably need. The C function rand() returns a pseudo-random number of so many bits. (Consult your compiler documentation.) You then use the C modulus operator like Senso shows in his example to turn the number rand() returns into a number between, in your case, 0 and 7.The problem with rand() is that every time you power-up or reset, the numbers it generates will be the same as last time. If you're worried about that then read up on the srand() function. This provides a 'seed' for the pseudo-random number generator. Where do you get a good seed? Read the Wikipedia page for "Hardware random number generator." You basically need a white noise source such as a thermistor or avalanche diode. You might be able to utilize a timer and/or even some sort of user interaction to seed the generator as well.You need to seed the generator only once after power-on/reset.

author: Psi
author_rank: Super Contributor
timestamp: February 08, 2012, 01:45:30 am
content: id probably just program an array of random numbers into the micros eeprom and step through the array index jumping in steps derived from the value obtained and values either side of it.But to avoid the exact values at startup you'd need to periodically store the current random value in eeprom and use that to seed the system at startup.

author: TerminalJack505
author_rank: Super Contributor
timestamp: February 08, 2012, 02:31:15 am
content: I guess the funny thing about randomness, at least on microcontrollers, is that it isn't simple. You can get a good seed on a PC just by using the timer. (As in the date and time, how many seconds the PC has been running, etc.) You generally don't have this luxury on a MCU.It's not terribly satisfying to see your program do the exact same thing each time you power it up when it is supposedly doing something 'at random.' LOL.Some MCU have built-in temperature sensors. The lower-order bits of that sensor is another source of 'random' bits for your seed.

author: eliocor
author_rank: Unknown
timestamp: February 08, 2012, 10:13:15 am
content: I think it is very simple:Code:unsigned char Value=0, oldValue=0 ;for (;;){Value = rand() & 0x07 ; // mask all most significant bits except the 3 LSB:// 'Value' is between 0 and 7if (Value != OldValue){OldValue = Value ;// light the 'nth' LED using the number (0-7) stored in 'Value'}}If you need a seed for your random generator, the suggestion to use the Least Significant Bits (LSB) of an ADC channel is a good one.

author: pelle.jansen
author_rank: Contributor
timestamp: February 08, 2012, 04:29:56 pm
content: Quote from: eliocor on February 08, 2012, 10:13:15 amThis workes like a charm! Does just what I need it to do. Thanks for the input all.

author: Unknown
author_rank: Unknown
timestamp: February 08, 2012, 05:40:39 pm
content: Does it? Lets test it. Say the rand funtion returns 16. What value will be stored in value and which led will light up?

author: eliocor
author_rank: Unknown
timestamp: February 09, 2012, 12:49:12 am
content: Quote from: Alex on February 08, 2012, 05:40:39 pmReally simple:16 = 00010000 in binaryANDing the 0x07 mask to 16 results:00010000 AND 00000111 = 00000000so the result is 0The 0x07 mask sets to 0 the most significant bits of your number:00000xxxOnly the bit marked with 'x' will remain untouched.The operation is the same as follows:Value = rand() % 8 ;but using the '&' operator (AND) is faster and (to me) more readable

author: Unknown
author_rank: Unknown
timestamp: February 09, 2012, 12:54:23 am
content: Quote from: eliocor on February 09, 2012, 12:49:12 am...and thats why no LED (or only the first LED) will light up for generated numbers that do not have any of the three LSBs set. Thats a lot of numbers.

author: IanB
author_rank: Super Contributor
timestamp: February 09, 2012, 01:02:01 am
content: Quote from: Alex on February 09, 2012, 12:54:23 amI don't get that. There are 8 LEDs and 8 values, 0 - 7.0 => LED #1,1 => LED #2,2 => LED #3,...,7 => LED #8.

author: Unknown
author_rank: Unknown
timestamp: February 09, 2012, 01:33:26 am
content: Quote from: IanB on February 09, 2012, 01:02:01 amIf the OP just copies the number stored in 'value' to the LED port then only 3 of the LEDs will light up, LED 1-3. A binary to decimal decoder will have to be implemented. Thats one issue.The other issue is that a portion of the dynamic range of the random number generated is being utilised. If the binary representation of the number generated by the rand function does not contain any 1 in the 3 LSBs then the masked value will be 0. In other words, you are not scaling the random number to fit 8 LEDs, you are truncating it.

author: senso
author_rank: Frequent Contributor
timestamp: February 09, 2012, 02:27:02 am
content: Yes, I never use the % in my micro-controllers code, only in pic32 that as hardware modulus and so its as fast as doing it or the &, but I was typing with one hand because I was freezing with cold, and I wanted to pass the idea to the OP, there are lots of options to choose from.One way to get some random seeds is to read an analog channel, and you probably can make it more random if you read it 16 times and only store the first(bit 0) of each reading and then make a 16 bits value out of it.

author: IanB
author_rank: Super Contributor
timestamp: February 09, 2012, 02:35:07 am
content: Quote from: Alex on February 09, 2012, 01:33:26 amWhat "LED port"? What makes you think the OP is going to do something that won't work? You have constructed a straw man argument based on an imaginary hypothesis in order to knock it down. I think you should give the OP more credit, especially since this:Quote from: pelle.jansen on February 08, 2012, 04:29:56 pmI mean, if the OP has tested it and found it working, why do you think it only lights 3 LEDs?Quote from: Alex on February 09, 2012, 01:33:26 amHere you do have a point. Taking the lowest few bits of a random number will reduce the randomness significantly. But for the purposes of this exercise it was accepted higher up the thread that perfection was not required. Nevertheless, it is as well to be aware of the limitations of the algorithm chosen.

author: Unknown
author_rank: Unknown
timestamp: February 09, 2012, 03:21:02 am
content: Ian, we have to work with fragmented info here. Regarding ports, the op mentioned 8 leds with resistors. Thats a typical reply of a number of leds connected to an output port of the mcu. Pelle, how have you connected your leds? The connection method is important as it links with the code.About the 3 leds. The op quoted a block of code that doesnt do bcd conversion. As you say the op says it works, so there is a conversion taking place at some point. That should be mentioned.Maybe if i had used past tense it would be even more clear what i meant, which is the scenario thay no conversion is used.Thats all there is to the above points.I am glad you understood what i meant about the range of the number. This piece of info is crucial if what you want is equal probability for all leds.

author: IanB
author_rank: Super Contributor
timestamp: February 09, 2012, 03:49:22 am
content: My interpretation is that the MCU has eight of its pins designated as outputs. Each pin is connected to an LED via a current limiting resistor. Set the output high to turn on the LED, set the output low to turn off the LED.The above code was posted:Code:unsigned char Value=0, oldValue=0 ;for (;;){Value = rand() & 0x07 ; // mask all most significant bits except the 3 LSB:// 'Value' is between 0 and 7if (Value != OldValue){OldValue = Value ;// light the 'nth' LED using the number (0-7) stored in 'Value'}}It all depends what code lies behind "light the 'nth' LED using the number (0-7) stored in 'Value'". This comment tells me the intent is clearly understood, but we don't have sight of the actual code. Maybe there is a pair of functions like this:Code:unsigned char Value=0, oldValue=0 ;for (;;){Value = rand() & 0x07 ; // mask all most significant bits except the 3 LSB:// 'Value' is between 0 and 7if (Value != OldValue){OldValue = Value ;clear_LED(OldValue);light_LED(Value);}}I won't try to write these functions; they could be written using a switch() statement, or more simply by indexing the output pins off of Value. Something like "set_pin(base+value);" even. (Where set_pin(index) sets the state of the indexed output pin to high.)

author: l4rtt-1
author_rank: Contributor
timestamp: February 09, 2012, 08:56:00 am
content: Quote from: IanB on February 09, 2012, 03:49:22 amOr just as simple as:PORTX = 1 << Value;

author: pelle.jansen
author_rank: Contributor
timestamp: February 10, 2012, 11:41:18 am
content: Hi allFirst I want to thank you all for your input!I did get it working with the srand() reading an input from the analog channel which is floating. There is only one thing: I had to use 8(!) if statements to get it to work. It works but is very ugly of course. Every way I try to solve it it doesn't work. Some tips would me much appreciated!Code:/******************************************************* Pelle Jansen* 5 - 2 - 2012** Sets a random LED high, LED can be cleared by pressing corresponding button.** PIC16F877A** X1: 8 MHZ, 2 22 pF capacitors to ground* Code is still ugly as shit, please bear with me.* *****************************************************/#include <htc.h> // main PIC header file#include <stdlib.h> // Reqired for randomize() and rand()#include "delay.h" // for DelayUs()#include "delay.c" // for some reason necessary for DelayMs()/* External high speed 8 MHZ crystal oscillator, Watchdog timer disabled* brouwn out reset enabled, EEPROM protection disabled* write protect disabled, code protect disable, Low voltage programming disabled* power on timer enabled.*/__CONFIG(FOSC_HS & WDTE_OFF & BOREN_ON & CPD_OFF & WRT_OFF & CP_OFF & LVP_OFF & PWRTE_ON);/*system*/#define XTAL_FREQ 8 MHZ/*functions*/int rando(){int value;value = rand() & 0x07;return value;}/*main function*/void main (void){TRISD=0x00; // PORTD as outputTRISB=0xff; // PORTB as inputADCON1 = 0b00010000;ADCON0 = 0b00000001;DelayUs(1);GO_DONE = 1;while (GO_DONE);srand(ADRESH);int randval, oldval, out;randval=rando();while (1) // infinite loop{if (randval != oldval){PORTD = 1 << randval;if (RB0 == 0){out=0;}else if (RB1 == 0){out=1;}else if (RB2 == 0){out=2;}else if (RB3 == 0){out=3;}else if (RB4 == 0){out=4;}else if (RB5 == 0){out=5;}else if (RB6 == 0){out=6;}else if (RB7 == 0){out=7;}if (out==randval){randval=rando();oldval=randval;}else{continue;}}else{randval=rando();}}}Analog inputs were a lot easier than I thought. A good read trough the datasheet gave me everything I needed.

author: eliocor
author_rank: Unknown
timestamp: February 10, 2012, 01:06:25 pm
content: 1) it is more than 15 years I'm not using PICs, so I hope I remember correctly the I/O port syntax...2) I modified the code without trying to compile it, so maybe there are some errors in it3) You never mentioned you was checking an input port (PORTB) and required to read its status: I hope to understand there can be a bit set to 0 and you have to identify it...4) i removed your 'rando()' function because you need to call it only 1 time...Code:void main (void){TRISD=0x00; // PORTD as outputTRISB=0xff; // PORTB as inputADCON1 = 0b00010000;ADCON0 = 0b00000001;DelayUs(1);GO_DONE = 1;while (GO_DONE);srand(ADRESH);unsigned char randval=0, oldval=0, out, i; // they are UNSIGNED CHAR!!!!randval=rando();while (1) // infinite loop{randval = rnd() & 0x07 ; // only values from 0 to 7if (randval != oldval){// assign value to the 'old' variableoldval = randval ;// light the 'n'th ledPORTD = 1 << randval ;// scan the 8 input ports// 'out' is set to 0xFF to avoid undefined casesfor (out=0xFF, i=0 ; i<8 ; i++){// check if input port 'i' is set to '0'// the loop will be exited at the first occurrence of '0' on PORTB// be careful! if every bit of PORTB is set to '1', 'out' value is UNDEFINED!!!if (!(PORTB & (0x01 << i))){out = i ; // set 'out' to number of port found to 0break ; // exit from the loop: I have found a bit set to 0}}}}}[added some hours later]Corrected the code to use Bitwise AND operator (&), instead of Logical AND operator (&&)

author: pelle.jansen
author_rank: Contributor
timestamp: February 10, 2012, 02:04:16 pm
content: Quote from: eliocor on February 10, 2012, 01:06:25 pm1. 15 years is a long time. What do you use now?2. There were some errors but they were easy to correct.3. I thought it would be relatively easy. Just reading a input and writing it in a variable sounds soo simple but it isn't.4. Actually 2 timesBut... it doesnt work. Your for loop seems to always return 8 (all leds light if you assign it to PORTD). Here is the modified code:Code:/******************************************************* Pelle Jansen* 5 - 2 - 2012** PIC16F877A**Sets a random LED high, LED can be cleared by pressing corresponding button.** X1: 8 MHZ, 2 22 pF capacitors to ground** *****************************************************/#include <htc.h> // main PIC header file#include <stdlib.h> // Reqired for randomize() and rand()//#include "delay.h" // for DelayUs()#include "delay.c" // for some reason necessary for DelayMs()/* External high speed 8 MHZ crystal oscillator, Watchdog timer disabled* brown out reset enabled, EEPROM protection disabled* write protect disabled, code protect disable, Low voltage programming disabled* power on timer enabled.*/__CONFIG(FOSC_HS & WDTE_OFF & BOREN_ON & CPD_OFF & WRT_OFF & CP_OFF & LVP_OFF & PWRTE_ON);/*system*/#define XTAL_FREQ 8 MHZ/*main function*/void main (void){TRISD=0x00; // PORTD as outputTRISB=0xff; // PORTB as inputADCON1 = 0b00010000;ADCON0 = 0b00000001;DelayUs(5);GO_DONE = 1;while (GO_DONE);srand(ADRESH);unsigned char randval=0, oldval=0, out, i;randval = rand() & 0x07; //while (1) // infinite loop{if (randval != oldval){PORTD = 1 << randval;for (out=0xFF, i=0 ; i<8 ; i++){// check if input port 'i' is set to '0'// the loop will be exited at the first occurrence of '0' on PORTB// be careful! if every bit of PORTB is set to '1', 'out' value is UNDEFINED!!!if (!(PORTB && (0x01 << i))){out = i; // set 'out' to number of port found to 0break; // exit from the loop: I have found a bit set to 0}}if (out==randval){oldval=randval;randval= rand() & 0x07;}}elsecontinue; // is this necessary?}}I am still pretty unfamiliar with the &, &&, | etc operators. That happens when you get spoiled by learning a high level language first

author: eliocor
author_rank: Unknown
timestamp: February 10, 2012, 02:22:58 pm
content: 1) mostly Freescale and Arm (NXP/ST)2)what is the use of your reading on PORTB: please can you explain it?3) same for this piece of code:if (out==randval){oldval=randval;randval= rand() & 0x07;}It is really not clear (to me) what you want to do...I have the slight impression there is something 'cheesy'....

author: pelle.jansen
author_rank: Contributor
timestamp: February 10, 2012, 02:28:26 pm
content: It is stated in the comment on top of code.*Sets a random LED high, LED can be cleared by pressing corresponding button.It is part of a little fun reaction time game.

author: eliocor
author_rank: Unknown
timestamp: February 10, 2012, 02:37:26 pm
content: BTW, I wrote the wrong operator:instead of '&&' (logical AND)you have to put the '&' (bit AND):if (!(PORTB & (0x01 << i)))in such way it will exit when it will find the FIRST 0 (counting from B0 to B7).Sorry for the inconvenience (it was written in a hurry)

author: pelle.jansen
author_rank: Contributor
timestamp: February 10, 2012, 02:46:14 pm
content: Quote from: eliocor on February 10, 2012, 02:37:26 pmYup, that did itNo problem. It just proves that yore humanOnly thing was that I tried for like 15 minutes before thinking it won't work.Can you give me some clarification about those operators? I am totally unfamiliar with them and my C tutorial doesn't cover it for some reason.Thanks for your input!

author: pelle.jansen
author_rank: Contributor
timestamp: February 10, 2012, 02:53:54 pm
content: Or not.The PIC seems to freeze after a sort whileWhat could cause this?

author: eliocor
author_rank: Unknown
timestamp: February 10, 2012, 03:03:28 pm
content: No idea about the freezing, but I do not think it depends on the code...regarding the Bitwise operations, please take a look at the following links:http://en.wikipedia.org/wiki/Bitwise_operationhttp://en.wikipedia.org/wiki/Bitwise_operations_in_C

author: pelle.jansen
author_rank: Contributor
timestamp: February 10, 2012, 04:35:35 pm
content: Thanks, I will definitely read through that article!Now up to solving that darn freeze problem

author: pelle.jansen
author_rank: Contributor
timestamp: February 10, 2012, 08:56:30 pm
content: Hi all,I rebooted my Mac, unplugged and replugged my PicKit 3 and TADA it worked. Some strange glitch in the compiler or MPLAB X I guess. Well for all of you interested, here is the final code. Fully annotated so everyone will understand what I am trying to do.Code:/******************************************************************************** Pelle Jansen ** 10 - 2 - 2012 ** V1.1 ** Free to distribute, use, modify, whatever you like ;) ** ** Designed for PIC16F877A ** ** Reaction time game ** Sets a random LED high, LED can be cleared by pressing corresponding button.** ** X1: 8 MHZ, 2 22 pF capacitors to ground ** RA0: for random number. LEAVE FLOATING! ** Entire PORTB: 8 switches to ground with external Pull up resistors ** Entire PORTD: 8 LEDs with corresponding resistors ** *******************************************************************************/#include <htc.h> // main PIC header file#include <stdlib.h> // Reqired for randomize() and rand()#include "delay.c" // for some reason necessary for DelayMs()/* External high speed 8 MHZ crystal oscillator, Watchdog timer disabled* brouwn out reset enabled, EEPROM protection disabled* write protect disabled, code protect disable, Low voltage programming disabled* power on timer enabled.*/__CONFIG(FOSC_HS & WDTE_OFF & BOREN_ON & CPD_OFF & WRT_OFF & CP_OFF & LVP_OFF & PWRTE_ON); // config bits/*Defenitions. Defines, global variables funcions etc*//*system*/#define XTAL_FREQ 8 MHZ /*required for DelayUs() and DelayMs()*//*user*/// add user defenitons/*macro's*///add user macro's/*main function*/void main (void){/*Digital initilization*/TRISD=0x00; // PORTD as outputTRISB=0xff; // PORTB as input/*Analog initilization*/ADCON1 = 0b00010000; // set analog config registersADCON0 = 0b00000001;DelayUs(20); // wait for analog channel 0 to get a readingGO_DONE = 1;while (GO_DONE)// wait for reading to complete;srand(ADRESH); // seed the random analog input value to the rand() function/*Local variable defenition*/unsigned char randval, oldval=0, out, i; // variable definiton/*initilization*/randval = rand() & 0x07; // get initial random number between 0 and 7/*Main infinite loop*/while (1){if (randval != oldval){ // make sure the number is not the same as the last onePORTD = 1 << randval; // set the value on LEDs shiftet one to the leftfor (out=0xFF, i=0 ; i<8 ; i++){ // check each for 0 the loop will be exited at the first occurrence of '0' on PORTB// be careful! if every bit of PORTB is set to '1', 'out' value is UNDEFINED!!!if (!(PORTB & (0x01 << i))){out = i; // set 'out' to number of port found to 0break; // exit from the loop: I have found a bit set to 0}}if (out==randval){ // if the random number is equal to the number gotten from the buttonsoldval=randval; // set the oldval variable to the current (old) random numberrandval= rand() & 0x07; // generate new random number between 0 and 7}else{ // if the random value equals to the old random valueoldval=randval; // set the oldval variable to the current (old) random numberrandval= rand() & 0x07; // generate new random number between 0 and 7}}}}Thanks all for your support. Couldn't have done it without your support guys!