Author Topic: Trivial circuit upset by touching it  (Read 6479 times)

0 Members and 1 Guest are viewing this topic.

Offline beatleTopic starter

  • Contributor
  • Posts: 27
  • Country: lv
Trivial circuit upset by touching it
« on: May 01, 2012, 09:01:08 am »
Hello!

I had an erratic circuit on my hands the day before, most likely to some dumb beginner's mistake, but I cant figure it out. Before you ask I don't have an oscilloscope to test it with (I am currently shopping for one).

I made a simple quick timer for a friend, that is supposed to beep regularly after 15 s or 30 s or 1 min intervals selected by a button press (for exercising). For that purpose I have:
a msp430g2432 uC,
a 10k pullup to !RST,
a pjezo buzzer connected to P1.4 and P1.5,
a button to P1.3,
a external watch crystal

I am using a breadboard.

The current code I am using:
Code: [Select]
#include <msp430.h>
#include <sys/types.h>

#define     BUZZ1                   BIT5
#define     BUZZ2                   BIT4
#define     BUZZ_DIR               P1DIR
#define     BUZZ_OUT               P1OUT

#define     BTN_DIR         P1DIR
#define     BTN_IN          P1IN
#define     BTN_OUT         P1OUT
#define     BTN_REN         P1REN
#define     BTN             BIT3

#define     BEEP_LENGHT     200
#define     BEEP_FREQ       200
#define     BEEP_PAUSE      8000

#define     TIMER_15S      1024     // 2s currently for testing

void initialize(void);
static void __inline__ delay(register uint16_t n);
void beep(int);
void start_timer(void);
void stop_timer(void);

int mode = 0;

int main(void)
{
    delay(1);
    initialize();
    delay(1);

    while (1) {
    }
}

void initialize(void)
{
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT

    BUZZ_OUT &= ~(BUZZ1 + BUZZ2);  //  off
    BUZZ_DIR |= BUZZ1 + BUZZ2;     // Set as output

    BTN_DIR &= ~BTN;  // Set input
    BTN_REN |=  BTN;  // Enable pulldown
    P1IES &= ~BTN;   // low -> High is selected with IES.x = 0.
    BTN_OUT &= ~BTN;  // Set pulldown
    P1IFG &= ~BTN;  // To prevent an immediate interrupt, clear the flag for  P1.3 before enabling the interrupt.
    P1IE |= BTN;    // Enable interrupts for P1.3

    BCSCTL3 |= XCAP_3; //12.5pF cap- setting for 32768Hz crystal
    delay(50000);   // let crystal stabilize
    BCSCTL1 |= DIVA_3; // ACLK/8

    _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interrupt
}

static void __inline__ delay(register uint16_t n)
{
    __asm__ __volatile__ (
            "1: \n"
            " dec %[n] \n"
            " jne 1b \n"
            : [n] "+r"(n)
            );
}


void start_timer(void)
{
    TACCR0 = 0; // Stop timer
    TACTL = MC_0; // Halt timer

    switch (mode) {
        case 1:
            TACCR0 = TIMER_15S; // 512 -> 1 sec, 30720 -> 1 min
            break;
        case 2:
            TACCR0 = TIMER_15S * 2;
            break;
        case 3:
            TACCR0 = TIMER_15S * 4;
            break;
        default :
            beep(4);
            return;
            break;
    }

    TACTL = TASSEL_1 + ID_3 + MC_1 + TACLR; // ACLK, /8, upmode, clear timer
TACCTL0 = CCIE;         // Enable interrupts for CCR0.
}

void stop_timer(void)
{
    TACCR0 = 0; // Stop counting
    TACTL = MC_0; // Halt timer
TACCTL0 &= ~CCIE;         // Disable interrupts for CCR0.
}

void beep(int times)
{
    int i;

    BUZZ_OUT |= BUZZ1;
    while (times>0) {
        times--;
        i = 0;
        while (i<BEEP_LENGHT) {
            i++;
            BUZZ_OUT ^= BUZZ1 + BUZZ2;
            delay(BEEP_FREQ);
        }
        delay(BEEP_PAUSE);
    }
    BUZZ_OUT &= ~(BUZZ1 + BUZZ2);  //  off
}

    __attribute__((interrupt(TIMERA0_VECTOR)))
void Timer_A (void)
{
    beep(mode);
}

__attribute__((interrupt(PORT1_VECTOR)))
void Btn_press(void)
{
    stop_timer();
    switch(P1IFG&BIT3) {
        case BIT3:
            P1IFG &= ~BIT3;    // clear the interrupt flag
            mode++;
            if (mode>3) {
                mode = 0;
                break;
            }
            beep(mode);
            if (mode != 0) {
                start_timer();
            }
            break;
        default:
            P1IFG = 0;    // probably unnecessary, but if another flag occurs
            // in P1, this will clear it.  No error handling is
            // provided this way, though.
            break;
    }
    delay(65000);
    P1IFG &= ~BIT3;    // clear the interrupt flag
}

I am powering it with a 3.3V from mains power supply that I made for another project, but latter I want to use a 3V button cell.

The circuit and code works more or less as it should, but ONLY when I am touching one of the power rails with my finger! If not, the uC just freezes and does no beeping.

My main hypotheses as of why it is happening, was that the power supply is too noisy and I acted as a smoothing capacitor, but I tried adding capacitors of various values to no effect and I have powered other uC projects from the same supply before.

Now I am only guessing.. to little noise to start the quartz crystal oscillating (I am suspicious that it doesn't work that way) that my body is inducing in the circuit as a antenna? - tried adding a long wire to power rail and wrapping it around noisy lamp. No.

Wrong loading capacitances for external watch crystal (I am using soft controlled 11pF ones from the MSP430,  I have no idea what is the required values for my crystal) - tried changing it whit some 2.2pF parts in series. Nope (? I guess it should at least function, if with wrong frequency, and see no reason for it to work perfectly when I am touching the ) or 3.3V wire).

I suspect that the problem is connected to the fact that I am using deep sleep mode in my uC and waking up only to service timer interrupts (that is driven by the external crystal) and maybe something is incorrectly configured, but I have no clue how me touching the circuit can affect it in any way..

So, if someone can point me to a possible cause for this, please let me know!
(And sorry about the long write-up. I am not a native speaker and therefore very clumsy with English.)

 

Online Psi

  • Super Contributor
  • ***
  • Posts: 9930
  • Country: nz
Re: Trivial circuit upset by touching it
« Reply #1 on: May 01, 2012, 09:23:31 am »
Sounds more like you have a grounding issue.
Your body will pull a floating circuit closer to mains earth
« Last Edit: May 01, 2012, 09:26:29 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline T4P

  • Super Contributor
  • ***
  • Posts: 3697
  • Country: sg
    • T4P
Re: Trivial circuit upset by touching it
« Reply #2 on: May 01, 2012, 09:42:55 am »
Floating ground somewhere . ( Rather , disconnected ground )
 

Offline steaky1212

  • Regular Contributor
  • *
  • Posts: 95
  • Country: gb
    • Steaky - Sleep is overrated
Re: Trivial circuit upset by touching it
« Reply #3 on: May 01, 2012, 10:20:47 am »
does it work when powered from the watch battery?

start simple, and have the uc just run a flashing LED in a for loop. That way you ensure the uc is running without having to worry about isr's.
Does the circuit work when connected to your PC for programming/debugging?

Connect the circuit ground to your PC ground - resolving the grounding issue.
 

Offline beatleTopic starter

  • Contributor
  • Posts: 27
  • Country: lv
Re: Trivial circuit upset by touching it
« Reply #4 on: May 01, 2012, 11:02:44 am »
Sounds more like you have a grounding issue.
Your body will pull a floating circuit closer to mains earth

I hadn't considered that. I am quite the beginner so forgive me if I am being silly, but if my power supply uses an isolating transformer does it still mean that my circuit ground should be close to mains earth?

Floating ground somewhere . ( Rather , disconnected ground )
If there is an open circuit somewhere, how can me touching one of the supply rails upstream from the fault fix it?

does it work when powered from the watch battery?

start simple, and have the uc just run a flashing LED in a for loop. That way you ensure the uc is running without having to worry about isr's.
Does the circuit work when connected to your PC for programming/debugging?

Connect the circuit ground to your PC ground - resolving the grounding issue.

You are right, I should have used a reductionist approach for this.
Haven't tested with the battery yet, will buy one and check it out. And I have been doing it in a very bad way - programming chip in the Lounchpad socket and moving it to the breadboard every time. Attaching the Lounchpad to the circuit will give me multiple benefits.

You guys are very helpful, I will try these things out when I get home and report back. Thank you for your input, I was quite stuck!
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11622
  • Country: my
  • reassessing directives...
Re: Trivial circuit upset by touching it
« Reply #5 on: May 01, 2012, 02:59:32 pm »
Quote
but if my power supply uses an isolating transformer does it still mean that my circuit ground should be close to mains earth?
not necessarily, as long as your circuit gnd is tied to psu's 0V rail. your circuit will floating with your psu, no problem there. what others meant is you have disconnected/broken ground plane/net somewhere. or maybe you didnt put the right spike suppression value capacitor on power rail, try 10-100nF near your mcu power pin. if you've checked your power and ground line/traces to no fault, then maybe your not so good power supply triggering mcu brownout detection. try to disable it in software/fuse and see if it fixes it.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline Neilm

  • Super Contributor
  • ***
  • Posts: 1546
  • Country: gb
Re: Trivial circuit upset by touching it
« Reply #6 on: May 01, 2012, 06:35:18 pm »

If there is an open circuit somewhere, how can me touching one of the supply rails upstream from the fault fix it?

It could easily be a dry joint and your touching the circuit is disturbing the circuit and making the connection. You could try touching the circuit with something non-conductive.

Neil
Two things are infinite: the universe and human stupidity; and I'm not sure about the the universe. - Albert Einstein
Tesla referral code https://ts.la/neil53539
 

Offline beatleTopic starter

  • Contributor
  • Posts: 27
  • Country: lv
Re: Trivial circuit upset by touching it
« Reply #7 on: May 01, 2012, 08:02:02 pm »

If there is an open circuit somewhere, how can me touching one of the supply rails upstream from the fault fix it?

It could easily be a dry joint and your touching the circuit is disturbing the circuit and making the connection. You could try touching the circuit with something non-conductive.

Neil

Yes, I had similar scenarios in mind when the glitch showed. I tried both to poke the circuit with stick and shake it (no reaction), and, to be extra sure that it is a electronic not mechanical problem, I added a long wire to the power rail (no effect) and then touched it's other exposed end (circuit starts working).

Following received advice I bought a battery cell today and tested my circuit with it - works perfectly both when I am touching it and when I am not! So indeed the problem lies with my power supply. I will put using it in other projects on hold until I get my DSO to debug it. It interests me what exactly is wrong with it but now I don't have the means to find out and I am still quite puzzled of the exact mechanism how the fault worked.

Thanks everyone for your time and advice!
 

Offline bfritz

  • Regular Contributor
  • *
  • Posts: 134
  • Country: us
Re: Trivial circuit upset by touching it
« Reply #8 on: May 01, 2012, 09:21:52 pm »
From the list of components you give, I see one thing missing...

A bypass capacitor on the power pins of the uC.  There is a reset circuit in the uC (even if the brownout circuitry is disabled) that keeps the uC from running code, until the power supply is above some voltage.  As the uC starts to run, it can pull pretty sizeable pulses of current.  If this current is coming from a power supply at the end of 1' of leads, those leads act like inductors, and the voltage at the pins of the uC can drop far enough to put the uC into reset.  The fix is to add a power source locally, ie: the bypass cap.

The board works when you touch the power rails, as you act like a capacitor, enough to make the circuit work.

I would look at the datasheet for the micro, and use whatever they suggest.  It will likely need to be at least a 0.1uF ceramic capacitor.  Make sure it is connected via very short leads directly to the location on your breadboard to the power pins of the micro.

Anyway... that would be my first guess.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf