Electronics > Beginners
Trivial circuit upset by touching it
beatle:
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: ---#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
}
--- End code ---
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.)
Psi:
Sounds more like you have a grounding issue.
Your body will pull a floating circuit closer to mains earth
T4P:
Floating ground somewhere . ( Rather , disconnected ground )
steaky1212:
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.
beatle:
--- Quote from: Psi 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
--- End quote ---
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?
--- Quote from: Dave.S on May 01, 2012, 09:42:55 am ---Floating ground somewhere . ( Rather , disconnected ground )
--- End quote ---
If there is an open circuit somewhere, how can me touching one of the supply rails upstream from the fault fix it?
--- Quote from: steaky1212 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.
--- End quote ---
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!
Navigation
[0] Message Index
[#] Next page
Go to full version