This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

capacitive touch

Other Parts Discussed in Thread: MSP430G2755

Communication on UART line triggers noise in nearby capacitive touch lines in MSP430G2755

All lines are used in the 40 pin micro,so the touch switches cannot be re-alligned  away from the uart line

The UART baudrate is decreased from 1Mhz to 9600Hz which gave a significant decrease in the noise induction on the touch lines.

Compromising the sensitivity is done to further reduce the noise.

But still there is a chance of noise on the touch lines and the miss triggering of the capacitive touch switches happens


Is there any hardware/software design solution to reduce the noise.

  • Hi Varun,

    Have you had a chance to review our Capacitive Touch Hardware Design Guide (SLAA576)?  This document discusses best practices for reducing the effects you are seeing.  You can find the document here: http://www.ti.com/lit/an/slaa576/slaa576.pdf.  Section 5.1.4 addresses cross talk with other signals.

    The touch sensors in your design are excited at a frequency that is typically between 500 kHz and 1.5 MHz.  As a result of this, the signals are most susceptible to interference in this frequency range.  This is why you observed a reduction in noise when you lowered your UART baud rate down from 1MHz to 9.6 kHz.

    I recommend that you investigate three different avenues to resolve the interference.  

    The first is obvious- we want to limit the ability of the UART signal to effect the capacitive sensing electrodes and their traces.  What does your layout look like?  I recommend splitting off the UART from the capacitive sensing electrodes as soon as possible, and not running the traces in parallel for any significant length.  If the signals need to cross each other, this is best done at a 90-degree angle.  Circuit ground may also be used as a shielding mechanism in the layout, though you will want to be careful to prevent a significant reduction in sensitivity.

    The second is not as obvious as the first.  It's possible to reduce the overall impact of the noise by increasing the signal of interest- in this case, the change in capacitance at the electrode.  If there is any way you can optimize your layout and/or mechanical design to improve sensitivity, you can move your thresholds up and out of the noise floor.  Again, the Hardware Design Guide that I mentioned above is a great reference here.  The fact that you are drastically impacted by the UART to the point of having false detections makes me think that there is very little sensitivity in the system.  Are you sensing through a thick overlay or an air gap?  Are the electrodes appropriately sized for the application?

    Third- you can apply some software techniques to deal with this kind of interference.  You can implement some basic de-bouncing logic- basically, requiring that a key be in detect for a certain number of samples in a row before you report it as a touch.  You could also apply a low-pass digital filter to smooth the signal.  I would consider these as tools to improve things further once the two approaches above are looked at.

    Walter

  • Quick and dirty workaround: as long as UART communication is going on, ignore touch events. (This works only if the UART is not used continuously.)
  • Dear Walter,

    Thank you for sending a detailed reply to my query. Will send it to my hardware team to review the issue ...

    Would like you to share a code snippet of touch interface done by my predecessor , I was given the task of adding UART communication without modifying the existing hardware and additionally adding an eeprom to the i2c line.


    #define NUM_SEN 5 // Defines number of sensors
    #define THRESHOLD 100 // Threshold for Switch sensing

    void main()

    {

    ...

    swithc_init();

    while(1)

    {

    ..

    switch_read();

    ..

    }

    }

    void switch_init(void)
    {
    unsigned char count1, count2;

    P3SEL &= ~( BIT6 | BIT7); // Touch switch pin selections
    P2SEL &= ~(BIT3); // Touch switch pin selections
    P3SEL2 &= ~(BIT6 | BIT7); // Touch switch pin selections
    P2SEL2 &= ~(BIT3); // Touch switch pin selections
    P4SEL &= ~( BIT0 | BIT7); // Touch switch pin selections
    P4SEL2 &= ~(BIT0 | BIT7); // Touch switch pin selections

    measure_count(); // Getting base count

    for (count1 = 0; count1 < NUM_SEN; count1++) // reading base count for all the channels
    base_cnt[count1] = meas_cnt[count1];

    for (count1 = 15; count1 > 0; count1--) // 15 sample average base count calculation for all channels
    {
    measure_count();
    for (count2 = 0; count2 < NUM_SEN; count2++)
    base_cnt[count2] = (meas_cnt[count2] + base_cnt[count2]) >> 1; // averaging
    }
    }

    void measure_count(void)
    {
    char key;

    TA1CTL = TASSEL_3 + MC_2; // Timer configuration for touch
    TA1CCTL2 = CM_3 + CCIS_2 + CAP; // timer configuration for touch

    for(key=0;key<2;key++)
    {
    P4DIR &= ~electrode_bit[key];
    P4SEL &= ~electrode_bit[key];
    P4SEL2 |= electrode_bit[key];
    __bis_SR_register(GIE);
    TA1CTL |= TACLR; // Clear Timer_A TAR
    delay(40);
    TA1CCTL2 ^= CCIS0;
    _nop();
    _nop();
    TA1CCTL2 ^= CCIS0; // Create SW capture of CCR1
    meas_cnt[key] = TA1CCR2; // Counter value storing
    P4SEL2 &= ~electrode_bit[key];
    }
    for (key = 2; key < 4; key++) // touch count calculation for 4 switches
    {
    P3DIR &= ~electrode_bit[key];
    P3SEL &= ~electrode_bit[key];
    P3SEL2 |= electrode_bit[key];
    __bis_SR_register(GIE);
    TA1CTL |= TACLR; // Clear Timer_A TAR
    delay(40);
    TA1CCTL2 ^= CCIS0;
    _nop();
    _nop();
    TA1CCTL2 ^= CCIS0; // Create SW capture of CCR1
    meas_cnt[key] = TA1CCR2; // Counter value storing
    P3SEL2 &= ~electrode_bit[key];
    }
    if (key == 4) // touch count calculation for 5th switch
    {
    P2DIR &= ~electrode_bit[key];
    P2SEL &= ~electrode_bit[key];
    P2SEL2 |= electrode_bit[key];
    __bis_SR_register(GIE);
    TA1CTL |= TACLR; // Clear Timer_A TAR
    delay(50); //16
    TA1CCTL2 ^= CCIS0;
    _nop();
    _nop();
    TA1CCTL2 ^= CCIS0; // Create SW capture of CCR1
    meas_cnt[key] = TA1CCR2; // Counter value storing
    P2SEL2 &= ~electrode_bit[key];
    key++;
    }
    }


    void switch_read(void)
    {
    unsigned char count1;

    for (count1 = 0; count1 < NUM_SEN; count1++) // calculation of key press for 5 keys
    {

    delta_cnt[count1] = base_cnt[count1] - meas_cnt[count1]; // Calculate delta: c_change

    if (delta_cnt[count1] < 0) // If negative: result increased
    { // beyond baseline, i.e. cap dec
    base_cnt[count1] = (base_cnt[count1] + meas_cnt[count1]) >> 1; // Re-average quickly
    delta_cnt[count1] = 0;
    cnt[count1] = 1;
    }
    if (delta_cnt[count1] > d_threshold[count1]) // Determine if key is pressed
    {
    cnt[count1]++; // debounse count
    if (cnt[count1] >= 20) // debounse check
    {
    cnt[count1] = 1;
    key_press[count1] = 1; // key pressed
    }


    // d_Threshold = delta_cnt[count1];
    key_pressed = count1 + 1; // key pressed
    }
    else
    {
    cnt[count1] = cnt[count1] - 2;

    if(cnt[count1] < 2)
    cnt[count1] = 0;
    key_press[count1] = 0; // removing the key press if delata count is not enough
    }
    }

    if (!key_pressed)
    { // if no keys are touched
    for (count1 = 0; count1 < NUM_SEN; count1++)
    base_cnt[count1] = base_cnt[count1] - 1; // Adjust baseline count
    d_repeat_delay=0;
    }

    }

  • Hi Varun,

    Walter is on vacations until 5/26. He will help with this request as soon as he is back.

    Regards,
    Daniel
  • Varun,

    I would also like to point out that timing issues might also be giving you trouble.  Looking through your code, I'm not sure what happens in the delay() function call, but it is absolutely critical that this time be consistent for each sample that is measured.  If the delay time varies, the results will vary, and that can look like a detection.  The most common thing to corrupt a measurement in a scenario like this is another interrupt (say, a UART interrupt) occurring during the delay period, which could potentially cause the delay time to increase.  Timing issues can look just like noise issues with this measurement mechanism.

    Walter

**Attention** This is a public forum