Touching breadboard affects IO pin performance

Thread Starter

aeroguy

Joined Sep 16, 2009
40
Howdy,

I've encountered something interesting, which is sure to be educational for me.

My PIC18F45K22 is breadboarded with pin RE0 set as a digital input with an external 10k pullup, and a simple push button.

The pic is programed to blink an LED when I push the button.

When I energize the circuit, I can generally push the button once and the light will blink. Further attempts at pushing the button yield no response.

However, if I touch the metal part of the breadboard, or even the top of the pic chip surface, the light blinks every time I push the button.

I jumpered my meter to the IO pin to see how the voltage with the button depressed changed when I touch the board. The voltage was reduced from essentially zero, to -2 mV or so. When the button is not depressed, the pin voltage is ~4.7 V, as expected.

Any idea what is happening here?

Kind regards,
Eric
 
Last edited:

Thread Starter

aeroguy

Joined Sep 16, 2009
40
"Adrenalina" - I can't upload an image from work here. However, I'm sure you know what a pullup/switch arrangement looks like on an I/O pin.

See code below:

_______

Rich (BB code):
/*
INCLUDES
*/
#include <p18f45k22.h>
#include <stdio.h>
#include <timers.h>
#include <delays.h>
#include <usart.h>
/*
CONFIGURATION
*/
#pragma config FOSC = INTIO7
#pragma config PLLCFG = OFF 
#pragma config PRICLKEN = ON 
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRTEN = OFF
#pragma config BOREN = ON
#pragma config BORV = 285
#pragma config WDTEN = OFF
#pragma config CCP2MX = PORTB3
#pragma config PBADEN = OFF
#pragma config CCP3MX = PORTB5
#pragma config HFOFST = OFF
#pragma config T3CMX = PORTC0
#pragma config P2BMX = PORTD2
#pragma config MCLRE = INTMCLR
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CP2 = OFF
#pragma config CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF
#pragma config WRT3 = OFF
#pragma config WRTC = OFF
#pragma config WRTB = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF
#pragma config EBTR3 = OFF
#pragma config EBTRB = OFF
/*
DEFINES
*/
#define ON 1
#define OFF 0
#define TRUE 1
#define FALSE 0
 
 
//void timer_isr (void);
 
void main (void);
void int01_isr (void);
void Blinkra0 (void);
void strobera0 (void);
void Button1pressed (void);
void Button2pressed (void);
void Button3pressed (void);
void Button4pressed (void);
 
//static unsigned char s_count = 0;
 
union 
{
struct
{
unsigned Int0:1; //flag to indicate a RB0 (int0) interrupt
unsigned None:7;
} Bit;
unsigned char Byte;
} Intxflags;
 
union 
{
struct
{
unsigned But1:1; //flag to indicate a RE0 button push
unsigned But2:1; //flag to indicate a RE1 button push
unsigned But3:1; //flag to indicate a RE2 button push
unsigned But4:1; //flag to indicate a RE3 button push
unsigned Push:1; //flag to indicate a button has been pushed
unsigned False:1; //flag to indicate a button has not been pushed
unsigned Disable:1; //flag to indicate a pause before listening to button again
unsigned None:1;
} Bit;
unsigned char Byte;
} Butxflags;
 
//Declare variables
unsigned int butcount;
unsigned int nbounce;
unsigned int ioloopcount;
unsigned int nioloop;
unsigned int noinputportvalue;
unsigned int maskporte;
 
void main (void)
{
// Disable global interrupts for initialization
INTCONbits.GIE = OFF;
// Initialize internal oscillator speed to 4Mhz
OSCCONbits.IRCF0 = 1;
OSCCONbits.IRCF1 = 0;
OSCCONbits.IRCF2 = 1;
 
// Initialize the special function registers TRISA and PORTA.
PORTA = 0x00; //Clear PORTA pins
TRISA = 0x00; //All of PORTA is output
// Initialize the special function registers TRISB and PORTB.
// RB0 is input (INT0)
PORTB = 0x00; 
TRISB = 0x01;
WPUBbits.WPUB0 = 1; // Configure RB0 (INT0) with weak pullup
// Initialize the special function registers TRISE and PORTE.
// all 4 PORTE pins will be inputs (for buttons)
ANSELEbits.ANSE0 = 0;
PORTE = 0x01;
TRISE = 0x01;//set just RE0 as input during debugging. Note, pullup required on RE0 to RE2
// Interrupt configuration
RCONbits.IPEN = 0; // Disable interrupt priority
INTCON2bits.RBPU = 0; // Enable weak pullups
INTCON2bits.INTEDG0 = 0;// INT0 (RB0) triggers on falling edge
//INTCON2bits.RBIP = 0; // Interrupt on change is low priority 
INTCONbits.TMR0IE = OFF;// Disable Timer0 overflow interrupt
INTCONbits.RBIE = OFF; // Disable PORTB interrupt on change
INTCONbits.PEIE = ON; // Enable peripheral interrupts
INTCONbits.INT0E = ON; // Enable INT0 interrupt
INTCONbits.INT0F = 0; // Clear external INT0 interrupt flag
INTCONbits.RBIF = 0; // Clear PORTB IOC interrupt flag
INTCONbits.GIE = ON; // Enable interrupts
//INTCONbits.GIEL = ON; // Disable Lo-priority interrupts
//INTCONbits.GIEH = ON; // Enable High-priority interrupts
 
// configure USART. This is baud 9600 for Fosc 4MhzS
Open1USART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
25 );
 
 
 
//Initialize variables and flags
Intxflags.Byte = 0; // Clear user interrupt flags
Butxflags.Byte = 0; // Clear button IO flags
butcount = 0; // counter to time how long a button is pressed for
nbounce = 3; // this is arbitrary at the moment..
ioloopcount = 0; // this counter will help decide when to resume responding to buttons
nioloop = 10; // this many loops must be made between button pushes. Arbitrary for now..
noinputportvalue = 1; //true for only one porte pin configured for input;
maskporte = 0;
// Begin Infinite Loop
while (TRUE)
{
//blinkra0();
 
// Poll input buttons
// All 4 inputs high should equal 0x0F I think.
 
if(!Butxflags.Bit.Disable) {
if(PORTEbits.RE0!=noinputportvalue) {
if(butcount<<nbounce) {
butcount ++;
} else {
 
maskporte = 0x0F & PORTE; // mask pertinent PORTE bits for peace of mind
switch (maskporte)
{
case 0x00: //Button 1 pushed
Butxflags.Bit.But1 = 1;
break;
/* case 0x0D: //Button 2 pushed
Butxflags.Bit.But2 = 1;
break;
case 0x0B: //Button 3 pushed
Butxflags.Bit.But3 = 1;
break;
case 0x07: //Button 4 pushed
Butxflags.Bit.But4 = 1;
break;*/
default: //No button still pushed
Butxflags.Bit.False = 1;
break;
}
butcount = 0;
if(!Butxflags.Bit.False) {
Butxflags.Bit.Push = 1; //A button has really been pushed
 
} else {
Butxflags.Byte = 0;
}
 
}
}
} else {
ioloopcount ++;
}// close if Disable loop
 
if(ioloopcount>=nioloop) {
Butxflags.Bit.Disable = 0;
ioloopcount = 0;
}
 
 
// CHECK ALL FLAGS AND DO STUFF AS REQUIRED
 
if(Intxflags.Bit.Int0) {
// DO INTERUPT STUFF HERE IF DESIRED
//Delay10KTCYx(0);
Intxflags.Bit.Int0 = 0; // clear interupt flag
//while (Busy1USART()); // Makes sure the usart isn't busy
//putc1USART('a');
//Delay10KTCYx(0);
}
 
if(Butxflags.Bit.Push) {
switch (Butxflags.Byte)
{
case 0x11: //Button 1 pushed
Button1pressed();
break;
case 0x12: //Button 2 pushed
Button2pressed();
break;
case 0x14: //Button 3 pushed
Button3pressed();
break;
case 0x18: //Button 4 pushed
Button4pressed();
break;
default: //No button still pushed
//clear out the counters/flags
Butxflags.Byte = 0;
break;
}
Butxflags.Byte = 0x00;
Butxflags.Bit.Disable = 1; // Don't respond to another for a while
}
 
} // big while loop
}
 
#pragma code high_vector=0x08
void high_vector (void)
{
if(INTCONbits.INT0IF) {
_asm GOTO int01_isr _endasm 
}
}
 
/*
* Returns the compiler to the default code section.
*/
#pragma code
 
#pragma interrupt int01_isr
void int01_isr (void)
{
INTCONbits.INT0IF = 0; //Clear the INT0 interrupt flag 
Intxflags.Bit.Int0 = TRUE;
}
 
void Button1pressed (void)
{
Blinkra0();
 
}
void Button2pressed (void)
{
 
}
void Button3pressed (void)
{
 
}
void Button4pressed (void)
{
 
}
 
void Blinkra0 (void)
{
PORTAbits.RA0 = ON;
Delay1KTCYx(0); // delay 256000 cycles (0.064 seconds?)
PORTAbits.RA0 = OFF;
// Delay1KTCYx(0); // delay 256000 cycles (0.064 seconds?)
}
void strobera0 (void)
{
PORTAbits.RA0 = ON;
Delay1KTCYx(100); // delay 100000 cycles
PORTAbits.RA0 = OFF;
Delay1KTCYx(100); // delay 100000 cycles
 
Last edited by a moderator:

Thread Starter

aeroguy

Joined Sep 16, 2009
40
It'a almost like the threshold for the schmitt trigger is a perfect 0V, and that the pin is regarded as having value=1 (logic high) when the voltage at the pin is a few millivolts above zero.

Somehow my touching the ground plane of the circuit creates that tiny voltage reduction that causes the schmitt trigger to switch to logic low when the button is pressed.

Seems very strange to me.
 

Thread Starter

aeroguy

Joined Sep 16, 2009
40
Okay, I've narrowed down my issue and can take it from here.

The problem wasn't the logic level at my RE0 pin. I was testing for the value of all 4 PORTE pins. Apparently, my touching the breadboard is affecting a floating pin state on PORTE (on a pin other than RE0). I'll figure out what it is specifically tonight and report back for reference.

Please disregard my request for help.

thanks
 

ErnieM

Joined Apr 24, 2011
8,043
It's best to set any unconnected pins as outputs, or inputs and ground them. Floating inputs can cause resets.
<chuckling> There are posts going on for dozens of pages on the Microchip Forums trying to determine the "best" way to do this.

One of the worst ways is to leave them as floating inputs. Simon sez don't do that.
 

MrChips

Joined Oct 2, 2009
21,156
Many times in hindsight we learn not to assume anything.

Couple of things to watch for, one already mentioned. Make sure all unused inputs are tied to GND or something similar.

Sometimes those solderless breadboards do not make proper contact with IC pins. Pushing down on chips will sometimes fix this problem.
 

Thread Starter

aeroguy

Joined Sep 16, 2009
40
Thanks for the comments, guys. I've definitely learned something I can take away from the experience. The memory will be reinforced by having pulled my hair out for 12 hours on this.. :)

Floating inputs bad.
 
Last edited:

atferrari

Joined Jan 6, 2004
3,964
Thanks for the comments, guys. I've definitely learned something I can take away from the experience. The memory will be reinforced by having pulled my hair out for 12 hours on this.. :)

Floating inputs bad.
Good you solved it! In your way of knowledge you could even loose some hair as well.

I am a long time user of breadboard (bought some 15++ years ago) where I developed everything with micros even something now, running at 20 MHz.

I stopped having surprises like that when I became definitely thorough with wiring and the configuration of the micro prior turning the power on.

Otherwise, buy it, ready made. :D
 

ErnieM

Joined Apr 24, 2011
8,043
Thanks for the comments, guys. I've definitely learned something I can take away from the experience. The memory will be reinforced by having pulled my hair out for 12 hours on this.. :)

Floating inputs bad.
Soon you may have the day when you notice either power or ground is unconnected on a chip (or six) on your board, but the board is still working great so no one else on your team will even look at your findings.
 
Top