Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Question about programming trick

Status
Not open for further replies.

romel_emperado

Advanced Member level 2
Joined
Jul 23, 2009
Messages
606
Helped
45
Reputation
132
Reaction score
65
Trophy points
1,318
Location
philippines
Activity points
6,061
Hi guys, :)



I Have question :) in this scenario I have 8 parallel inputs w/ 8 switches and it is being pulled up by 8 resistors, so the normal values of my input read by the PIC when no switches pressed is 255.(all 8bit input are high/1)

the switch used is a push button switch.. NORmally open

when I press one switch located at PORTA.RA0 the input value will now be 255 -1 = 254..

the switch is momentary when I dont push it it will go back and the input value again will be 255.

so now the problem is I want to hold that value until the next activity of the switch. (the value 254)

I want to store that value inside a variable without losing it even if the switch is not press anymore

I tried something like this but after sometime inside a while 1 loop the value 254 disappear..

this is my code:

PHP:
if(input != 255) //when any of the switch is pressed
store = input 

return store;
 
Last edited:

hey

you are going to return to the store
let when you return again the store will again check the input which now changed so it stores the new input
 
It will not return the new input because of the if condition the thing will happen is the value of store become zero
 

Oh i dont know how to programme in c
but you can use something like this

in value is not equaal to 255 store the current input value
wait for release the key
return to check the value on port
if value is 255 return to check the value again
if value is less than 255 goto store it
return to check the value on port
 
yes Im thinking something like that but it will the variable will not hold the value..
 

There are a few possible options. First of all you need to realize you may have the effects of "button bounce" to deal with either by software of hardware. Assuming you have taken care of the "bounce" issue, f you want to poll for changes on the 8 I/O lines, I would something like the following:

Passed by value with static variable:

Code:
unsigned char pollButtons(void)
                    {
                       static unsigned char store;
                       unsigned char sinput;
                       
                       sinput = input; // Basically a shadow register see comment below

                       if(sinput != 255)
                       {
                          store = sinput;
                       }

                       return store;
                    }

Or you could do something like this:

Passed by reference using pointers

Code:
void main(void)
      {
         unsigned char state;

         while(1)
          {
             pollButtons(&state);
          }
      }


void pollButtons(unsigned char * store)
      {
         unsigned char sinput;
         sinput = input;           // prevents the value of input from changing during the loop test and the assignment statement;
                       
          if(sinput != 255)
          {
                *store = sinput;
          }

      }


Your intermittent values maybe due to switch or button bounce effects which may require additional coding to manage the problem.

BigDog
 
still not working.. Is there a switch bounce in proteus?

the 8bit input comes from a input shift register.

every time we pressed any button at the input it will be stored in a variable data. what I am trying to do is when we pressed any key it should remain until next key is press. what is happening here is I pressed any key I can get the value then if I release the switch it will go back to the normal state which is 255 since all 8bits are pulled up by a resistor.

This is the unchanged code of mine..

I did lot of techniques I know but failed.. hehe

PHP:
void main()
{
   while(1)
   {
      PORTB = get_inputDATA();
   }

}


PHP:
unsigned char get_inputDATA()
{
	int i,data;
	

	SPI_InLatch = 1; //load data
	SPI_InLatch = 0;

	SPI_PLOAD = 0;
	SPI_PLOAD = 1;
	

	for (i=7; i>=0; i--)
	{
		if(SPI_SI)
		data |= (1 << i); //store data received
		toogle_clock();
	}

	
	return data;

}


---------- Post added at 03:51 ---------- Previous post was at 03:49 ----------

I tried something like this but it only remain few seconds then the value of the variable became 0

if(input != 255) //when any of the switch is pressed
store = input

return store;


---------- Post added at 04:09 ---------- Previous post was at 03:51 ----------

I think I got it.. I need not to always called it in a supper loop but I will just detect if any key is press...

---------- Post added at 04:38 ---------- Previous post was at 04:09 ----------

not working.

I think it is because of the 8bit input is converted into serial data by input shift register
 

I think I got it.. I need not to always called it in a supper loop but I will just detect if any key is press...

You still may have problems with switch bounce. You have 8 potential sources of bounce, complicated by retrieval through a shift register.

A possible software solution maybe once an active switch has been detected, delay for a specified amount of time, then take another reading of the switch status and compare the two sets of data. If the two sets of data match, the switches have settled the reading can be considered stable. The problem with this approach is the actual duration of the delay can be in the range of 25mS to 150mS, depending on several factors. It is more of an art than a science.

Some examples in C:

Switch Input and Debounce

12F675 Tutorial 2 : Switch debounce

Two software alternatives:



The Best Switch Debounce Routine Ever

An interesting study of switch bounce:

A Guide to Debouncing

And of course there is always hardware debouncing:

How to de-bounce a switch using CMOS & TTL

Switch Debouncing


Let me know if you are still have problems with the previous code issue.

BigDog
 

Hold on.

Another option is to implement an external interrupt trigger using 8-input NAND gate to edge trigger the external interrupt when a button/switch is pushed.

Utilizing an external interrupt would remove the necessity to constantly poll the shift register inputs. Your ISR could also handle the switch debouncing.

BigDog

---------- Post added at 04:06 ---------- Previous post was at 03:50 ----------

Try this main() with your existing get_inputDATA() routine:

Code:
void main()
{
   unsigned char switchstate = 0xFF;

   while(1)
   {
      switchstate = get_inputDATA();

      if(switchstate != 0xFF)
          PORTB = switchstate;


   }

}

Let me know the results.

BigDog
 
just a suggestion...
If you are using PIC, can't you use EXT INTR on PortB; it has Interrupt on change facility.

May be it can work.

---------- Post added at 07:52 ---------- Previous post was at 07:51 ----------

when ISR gets called; use a static variable to store the data.
 

hi Srorrpeio,

the 8bit data is received serially from the input shift register so we cannot use external interrupt.
 

still not working.. Is there a switch bounce in proteus?

No there is not and that is why I find it very strange, there is something else going wrong but I can't figure it out.

Alex
 
the Idea is very simple but it's very difficult for me how to do it.. lol :) hihi

when I read from my input a value of 128 then I want to store that 128 forever as long as the system is up and it will only change if another key is press..
 

there is nothing wrong with the idea and if(input != 255) should prevent data from changing.
Are you sure that it is not a wrong read from the chip (74HC597), some kind of timing that is not met and you receive wrong data?

what is the new value that you get when the stored data gets lost, you press a specific button and the value gets stored, when the data is lost as you say without pressing any other button what is the new value that is assigned because it is surely different from 255 since it can pass the condition if(input != 255).
 

what is the new value that you get when the stored data gets lost, you press a specific button and the value gets stored, when the data is lost as you say without pressing any other button what is the new value that is assigned because it is surely different from 255 since it can pass the condition if(input != 255).

the value stored and then without pressing another key the value lost and became zero.


PHP:
unsigned char get_inputDATA()
{
    int i,data;
    

    SPI_InLatch = 1; //load data
    SPI_InLatch = 0;

    SPI_PLOAD = 0;
    SPI_PLOAD = 1;
    

    for (i=7; i>=0; i--)
    {
        if(SPI_SI)
        data |= (1 << i); //store data received
        toogle_clock();
    }

    


 
   if(input != 255) //when any of the switch is pressed
   store = input 

   return store; 
}

I check the returned value by doing this

PHP:
PORTB = get_inputDATA()

it displays the correct value whatever key I pressed but after some sometime it will become zero and that's the problem.. I want to retain it until the next key press.
 

So the data returned from the serial read are 0 which probably means that something is wrong with your code when you read the chip data, try to add a 1us delay between toggle of the 74HC597 pins.
 
now I added 2ms delay between toogle and also i tried 1us delay

still the same after 1 second or 2 the value will become zero..



PHP:
int get_inputDATA()
{
	int data = 0,i;

	SPI_InLatch = 1; //load data
	SPI_InLatch = 0;

	SPI_PLOAD = 0;
	SPI_PLOAD = 1;
	

	for (i=7; i>=0; i--)
	{
		if(SPI_SI)
		data |= (1 << i); //store data received
		toogle_clock();
	}

	//return data;
	if(data != 255)
	store = data;

	return store;

}



void toogle_clock()
{
	SPI_Clk = 1;
	delayms(2);
	SPI_Clk = 0;
}
 

add it in EVERY toggle

SPI_InLatch = 1; //load data
delayus(1);
SPI_InLatch = 0;

SPI_PLOAD = 0;
delayus(1);
SPI_PLOAD = 1;

1us would be enough
 
Still the same but it's improving the value retained now for 3 seconds... :)

I just can't understand why it is happening..

I wrote a code also before but it was about keypad in every pressed the value will retain in PORTx until the next press.. I did that using the trick I applied here but this one is I don't understand how to retain the value.. :)

---------- Post added at 09:58 ---------- Previous post was at 09:57 ----------

Im already out of Idea.. don't know why it is happening..
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top