Crosstalk between switches on AVR 88P

Discussion in 'Embedded Systems and Microcontrollers' started by KaloyanP, Feb 10, 2013.

  1. KaloyanP

    Thread Starter New Member

    May 27, 2012
    Hello, I have been working on an embedded programming problem and ran into a very weird problem that I kind of solved. However, I don't really understand why my solution works.

    This is the code I use to initialize the switches:

    Code ( (Unknown Language)):
    1. inline void switch_init(void)
    2. {
    3.     PCMSK2|=(1<<SW1|1<<SW2|1<<SW3); //allow interrupts for switches
    4.     DDRD&=~(1<<SW1|1<<SW2|1<<SW3); //set pins to input
    5.     PORTD|=(1<<SW1|1<<SW2|1<<SW3);
    6. }
    This is how I read them:

    Code ( (Unknown Language)):
    1.         if(PCIFR&1<<PCIF2)//pin change interrupt on Port D
    2.         {
    3.             if(reg.bounce!=1){
    4.                 unsigned char port;//can be merged with the bottom one
    5.                 port=PIND&((1<<SW3)|(1<<SW2)|(1<<SW1));
    6.                 if(reg.sw1&reg.sw2&reg.sw3){reg.pause^=1;}//toggle the pause
    7.                 reg.sw1=(port&(1<<SW1))>>SW1;
    8.                 reg.sw2=(port&(1<<SW2))>>SW2;
    9.                 reg.sw3=(port&(1<<SW3))>>SW3;
    10.                 reg.bounce=1;
    11.                 i1=0;
    12.             }
    14.             PCIFR|=1<<PCIF2;//reset the interrupt flag
    15.         }
    And this is the culprit line that, when commented, solved my problems:

    Code ( (Unknown Language)):
    1. DDRD|=(1<<PD3);//turn on the motor pin
    I have three switches, wired to pins PD[0:2].

    They are all hardware and software debounced, I have confirmed the operation of the hardware debouncer on an oscilloscope, it works perfectly. The software is a simple 20-40ms timer that disregards readings from the buttons. Also, I wait about a second before depressing the button after I have pressed it and vice versa. Thus, I can be 95% sure that no bouncing occurs.

    The problem is the following: If I have all three switches active, the last one (SW3, for example) does not behave properly. It refuses to behave when its especially noisy neigbor, PD3 is set to output (DDRD|=1<<PD3; ). There is a 10kHz PWM signal on this pin. The same happens to SW2, connected to PD1. SW1 (PD0) always behaves.

    I noticed that whenever I try and measure the voltage on PD2 with a rather cheap multimeter (i.e. "low" resistance, probably in the order of 1M), the system would behave correctly about 9 out of 10 times. Thus, I decided to put a rather weak 100k pullup on the PD2 pin. I also put caps between all the switch pins and ground. I still get the occasional error, but its now usable.

    This leads me to believe that the problem is somewhere in the silicon. Is it somehow possible that the rapid switching of the PD3 (OC02B) pin can be the culprit? What else should I test for to make sure that its not my circuitry thats the problem?

    P.S. Please, don't be too harsh on the grammar of this post, its 4AM here and I have been staring at LEDs and code for far too long today.
  2. tshuck

    Well-Known Member

    Oct 18, 2012
    I think you should post a schematic and your code(not snippets) we can see what is going on...