Thread: Set reset of flag.

  1. #1
    Registered User
    Join Date
    May 2012
    Posts
    11

    Set reset of flag.

    Hi.
    I am a new to C. I have an application where i get different inputs on a PIC16F724 which i then use to light up some leds and set outputs.
    The problem is that when i have a high on a input for a short period of time i wan't my output to stay on until i press a button that resets all the led's.
    I need a set reset function for all my inputs. I just can't ind a way to do it

    If you think the code is messy and not optimised, i just say it again, I AM NEW TO C

    The comments in the code are in danish, so just ignore them.
    The PIC drives two 74hc4515 decoder/demultiplexers which drives 30 led's. It should have been shift registers instead I guess, but now it's demultiplexers...

    Code:
    #include	<htc.h>
    
    #define _XTAL_FREQ 16000000
    int led1;
    int led2;
    int led3;
    int led4;
    int led5;
    main(void){
    /*Opsætning af inputs og outputs på de forskellige pins*/
    TRISC = 0xFF; /*Hele portC er input, I1-8*/
    TRISD = 0xFF; /*Hele portD er input, I9-16*/
    TRISE = 0x01; /*RE0 på portE er input I17 og de to sidste pin's er output's*/
    TRISA = 0; /*Hele portA er outputs, bruges internt til dioderne*/
    
    
    
    
    /*Sæt output 1 til relæ hvis en af input 1-8 er aktive*/
    if (PORTC >0){RE1=1;}
    else RE1=0;
    
    
    /*Lampetest*/
    if(RC7>0){lampetest();}
    
    
    /*Læsning af inputs*/
    if(RC0>0){led1=1;}
    if(RC1>0){led2=1;}
    if(RC2>0){led3=1;}
    if(RC3>0){led4=1;}
    if(RC4>0){led5=1;}
    if(RC6>0){led1=0; led2=0; led3=0; led4=0; led5=0;}
    
    
    /*Sæt dioder*/
    if(led1>0){PORTA = 0x40;}
    PORTA = 0xD0;
    if(led2>0){PORTA = 0x41;}
    PORTA = 0xD0;
    if(led3>0){PORTA = 0x42;}
    PORTA = 0xD0;
    if(led4>0){PORTA = 0x43;}
    PORTA = 0xD0;
    if(led5>0){PORTA = 0x44;}
    PORTA = 0xD0;
    }
    
    
    lampetest(void){
    PORTA = 0xD0;
    PORTA = 0x40;
    PORTA = 0x41;
    PORTA = 0x42;
    PORTA = 0x43;
    PORTA = 0x44;
    PORTA = 0x45;
    PORTA = 0x46;
    PORTA = 0x47;
    PORTA = 0x48;
    PORTA = 0x49;
    PORTA = 0x4A;
    PORTA = 0x4B;
    PORTA = 0x4C;
    PORTA = 0x4D;
    PORTA = 0x4E;
    }
    Help

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    based on the PIC datasheet, port A has 8 digital output bits. usually in something like this, to light a single LED, you need to set the corresponding bit (or clear it depending on your circuit). you code looks different. i see you are writing consecutive values to portA 40,41,42,43,44 to light the LED's. is that really how you do it? it could depending on your circuit but it would be unusual. can you describe your circuit a little? just what is connected to portA?

  3. #3
    Registered User
    Join Date
    May 2012
    Posts
    11
    Okay, maybe i wrote the question a bit to complicated. Also i included all the code, and not just the piece that i need help for. But as you ask, porta drives two demultiplexers 74hc4515 and the values i send is the bits and latch for each led. The circuit is not designed for what i use it for. I wan't to light up more led's at the same time, so to make the illusion of more led's being lit i just switch fast between them. If i should design the circuit i would use shift registers instead.
    The demultiplexers can only light one led at a time, so it is the wrong choice when i wan't for example 10led's on at the same time.

    But what i need help for is this:
    I have five inputs. If input one is on then led goes on, in2 on= led2 on and so on. Now if input one goes low i wan't led1 to stay on until i press the reset button, then all the led's should go off. The ones that still has a high input will go on again and stay on until i press the reset button and the input is low.
    Code:
    /*Læsning af inputs*/if(RC0>0){led1=1;}
    if(RC1>0){led2=1;}
    if(RC2>0){led3=1;}
    if(RC3>0){led4=1;}
    if(RC4>0){led5=1;}
    if(RC6>0){led1=0; led2=0; led3=0; led4=0; led5=0;}
    
    
    /*Sæt dioder*/
    if(led1>0){PORTA = 0x40;}
    PORTA = 0xD0;
    if(led2>0){PORTA = 0x41;}
    PORTA = 0xD0;
    if(led3>0){PORTA = 0x42;}
    PORTA = 0xD0;
    if(led4>0){PORTA = 0x43;}
    PORTA = 0xD0;
    if(led5>0){PORTA = 0x44;}
    PORTA = 0xD0;
    }
    This above is how i hoped it would work. If input RC0 goes high then led1 should have the value 1 and if led1 has the value 1 then send 0x40 to PORTA. This works fine. But if i turn RC0 low then led1 goes to 0 again, but i wan't it to stay 1 until i give a input on RC6 as the code says!

    Hope i explained it a bit better this time.
    Last edited by nic6911; 05-10-2012 at 02:26 PM.

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    11
    Set reset of flag.-pic-jpg

  5. #5
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    for this type of thing I would use a software state machine something like this. it may not be 100% correct. but its a start.
    Code:
    
    int state[5] = initialize to all 0
    int input[5] = current state of the inputs
    int reset = current state of reset button
    
    // turn all leds off to begin with
    
    // cycle through this at your update rate
    for(int i=0;i<5;++i) {
    	switch(state[i]) {
    	case 0: // LED is off
    		if (input[i] is high) {
    			// turn led on...
                led[i] = on
    			state[i] = 1;
    		}
    		else {
    			// do nothing, leave led off
    		}
    		break;
    	case 1: // looking for low signal or reset
    		// led is on and input was high
    		if (reset is pushed) {
    			// turn led[i] off but remember it should come back on when reset is released
                led[i] = off
    			state[i] = 2;
    		}
    		else if (input[i] is low) {
    			// turn led[i] off and keep it off until the signal goes high again
                            led[i] = off
    			state[i] = 0;
    		}
    		break;
    	case 2: // looking for reset released
    		// led was off but now looking for reset to go low
    		if (reset is released) {
    			// this led was on when reset was pushed, so turn led[i] on and keep it on
                led[i] = ON;
    			state[i] = 1;
    		}
    		else {
    			// do nothing, leave led[i] off
    		}
    		break;
    	default:
    		// shouldn't get here
    		break;
    	}
    }
    Last edited by dmh2000; 05-10-2012 at 05:03 PM.

  6. #6
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    i edited the code a couple of times so be sure to refresh

  7. #7
    Registered User
    Join Date
    May 2012
    Posts
    11
    Thanks for the reply I am totally new to this, so bear with me. But what does this mean int input[5] you define input as an integer but what does [5] do? is that the first 5 bits that are my inputs are assigned to? Could i then just write RC[5]? because PORTC is my inputs.
    I think i could use just case 0 and 1. I will get a high input turn led on an keep it on even though the input goes low - press reset which turns off all leds, i release reset button and then it checks which inputs are high and turns on the relevant led's.

    and just one more question. When i write
    Code:
    if(RC1>0){led2=1;}
    why doesn't it keep the value of led2 at 1 after RC1 goes low again? led2 could be defined as a bit. If RC1 goes high led2 equals 1, but it equals 0 when RC1 goes low again. I just can't understand why it goes lo when i haven't asked it to do so yet.

    Thank's again for your help, it is much appreciated!

  8. #8
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    the code i posted is mostly pseudocode. there are multiple ways to implement the actual code. the notation input[5] means that the variable 'input' is an array with 5 members. each of the members represents a bit. that is one way of representing bits. you would do 'index[0] = RC0;index[1] = RC1; etc at the top of the loop. you could declare that array as char input[5] to save memory, or you could simply use a single char with each bit meaning one input. the use of an array makes it easier to loop over. if you use a bit field (char with bits) then you need to AND and OR properly in each time through the loop to isolate particular bits. or if you really wanted to be awkward you could use a switch or series of if-then-else to isolate the particular bit during each pass through the loop.

    if the code is difficult to understand, then the best place to start here would be to draw the state machine in a diagram rather than code to figure out exactly what it should do.

  9. #9
    Registered User
    Join Date
    May 2012
    Posts
    11
    Hi again. The code is not that difficult, just takes som time reading it through a dozen of times to get it.
    The only thing that i still doesn't get is that when i give an input which turns the led on or gives it a 1, then it turns the led low again when the input goes low again. So in your code you turn the led on when the input is high, but it will tun off again when the input goes low. And i need it to stay on until i press the reset button, even though the input is low again. So i need it to latch the output in some sort of way. But i can't see your code doing that.

    I am used to programming ladder on a PLC and the funktion i would use there is SetReset - a input to set an output and another input to reset it...

  10. #10
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Since those are muxes, I'm assuming un-selected outputs get tri-stated, and you can't select more than one LED at a time, so it's fundamentally impossible to do what you are trying to do.

    There ARE ways around that, for example by cycling through the channels all the time really fast, you can give an illusion that more than one LED is on. However, for example, if you want all 16 LEDs on, they can all only be on at most 1/16 of the time, so it will be dim. This also requires some very tricky coding (I would do it using timer interrupts).

    You are correct that a shift register would make more sense.

  11. #11
    Registered User
    Join Date
    May 2012
    Posts
    11
    yeah i know this, i am also doing wha you suggest, just cycling really fast getting a dim light out of all the led's. I have not designed the circuit, it is a prototype and will be with shift registers on the next prototype.
    But about the Set Reset thing, would this do it for setting the bit and keep it high even though RC0 turns 0?
    Code:
    if(RC0>0){led1=led1|1;}
    Unfortionaly i can't test the suggestion on my circuit since i'm not home for a couple of days...
    Last edited by nic6911; 05-13-2012 at 02:22 AM.

  12. #12
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    That should set the lowest bit of led1.

    Generically, set and reset are usually implemented like this -
    Code:
    // set nth bit of x to 1
    x |= 1 << n;
    
    // set nth bit of x to 0
    x &= ~(1 << n);
    
    // flip the nth bit of x
    x ^= 1 << n;

  13. #13
    Registered User
    Join Date
    May 2012
    Posts
    11
    Okay, I will look through that! Thanks

    So i would just define x as char and then i have 8 set reset switches in that one byte i guess?
    Last edited by nic6911; 05-13-2012 at 02:33 AM.

  14. #14
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    That's what I would do.

  15. #15
    Registered User
    Join Date
    May 2012
    Posts
    11
    I tested it and got it to work! Thank's everybody for the help! Just a final question, do any of you have any good suggestions for a book regardin C programming for beginners?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. /gs flag
    By mystic-d in forum Tech Board
    Replies: 5
    Last Post: 01-20-2007, 04:38 AM
  2. reset a string?
    By john_murphy69 in forum C Programming
    Replies: 11
    Last Post: 02-19-2003, 02:55 PM
  3. Looking for a gcc flag
    By JLWinsett in forum Linux Programming
    Replies: 4
    Last Post: 12-26-2002, 11:39 AM
  4. how to reset getline?
    By MKashlev in forum C++ Programming
    Replies: 6
    Last Post: 08-11-2002, 08:51 AM
  5. help why does cnt not reset to 1??
    By datainjector in forum C Programming
    Replies: 4
    Last Post: 07-17-2002, 12:56 AM