Jump to content
Sign in to follow this  
jrlane

Why Do You Hate Me Pic

Recommended Posts

I'm beating my head against the wall trying to figure out what i thought would be a trivial task. Last night it took me longer than i expected to get the right configuration for my 16f88's just to flash some led's. Well i finally got that to work now i'm on to simply reading a switch and having a hell of a time.

 

My connections are simple, Vdd and Vss, an led through a 200ohm resister from porta.0 to ground. I'm then using a 10k resister to connect Vdd to porta.1 to simulate a switch. What is happening is randomness. I have tried a few different examples on how to read a switch but they all seem to do the same thing, it seems to randomly blink the LED, and on occasion (at least it seems), blink when i connect the resister to input.

 

Please lend me a hand fellas :(

#include <system.h>

#pragma DATA _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO
#pragma DATA _CONFIG2, _IESO_OFF & _FCMEN_OFF

#pragma CLOCK_FREQ 8000000


void main() {
// Set up the Analog selection register
ansel = 00000000b;  // 1=Analog, 0=Digital  RA1 as analog
trisa = 00000010b;  // 1=input, 0=output	RA1 as input (for analog)
trisb = 00000000b;
porta=0; portb=0;
osccon.6 = 1;
osccon.5 = 1;
osccon.4 = 1;

while(1)
{
	unsigned short timer = 0; // 16-bit variable
	while( porta.1 ); // wait for switch to be OFF
	while( !(porta.1) ); // wait for switch to be ON (pressed)
	// switch must be on....
	delay_ms(100); // debounce

	while( porta.1 )   // loop until switch is released
	{
		delay_ms(10);
		timer++;
	}

	if( timer < 100 )
	{ 
		porta.0=1;
		delay_ms(1000);
		porta.0=0;
	}
	else
	{
	   	porta.0=1;
		delay_ms(500);
		porta.0=0;
		delay_ms(500);
		porta.0=1;
		delay_ms(500);
		porta.0=0;
	}
	//porta.0=1; porta.7=1;
	//delay_ms(analog); delay_ms(analog);
	//porta.0=0; porta.7=0;
	//delay_ms(analog); delay_ms(analog);
}
}

Share this post


Link to post
Share on other sites
I'm beating my head against the wall trying to figure out what i thought would be a trivial task. Last night it took me longer than i expected to get the right configuration for my 16f88's just to flash some led's. Well i finally got that to work now i'm on to simply reading a switch and having a hell of a time.

 

My connections are simple, Vdd and Vss, an led through a 200ohm resister from porta.0 to ground. I'm then using a 10k resister to connect Vdd to porta.1 to simulate a switch. What is happening is randomness. I have tried a few different examples on how to read a switch but they all seem to do the same thing, it seems to randomly blink the LED, and on occasion (at least it seems), blink when i connect the resister to input.

 

Please lend me a hand fellas :(

#include <system.h>

#pragma DATA _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO
#pragma DATA _CONFIG2, _IESO_OFF & _FCMEN_OFF

#pragma CLOCK_FREQ 8000000


void main() {
// Set up the Analog selection register
ansel = 00000000b;  // 1=Analog, 0=Digital  RA1 as analog
trisa = 00000010b;  // 1=input, 0=output	RA1 as input (for analog)
trisb = 00000000b;
porta=0; portb=0;
osccon.6 = 1;
osccon.5 = 1;
osccon.4 = 1;

while(1)
{
	unsigned short timer = 0; // 16-bit variable
	while( porta.1 ); // wait for switch to be OFF
	while( !(porta.1) ); // wait for switch to be ON (pressed)
	// switch must be on....
	delay_ms(100); // debounce

	while( porta.1 )   // loop until switch is released
	{
		delay_ms(10);
		timer++;
	}

	if( timer < 100 )
	{ 
		porta.0=1;
		delay_ms(1000);
		porta.0=0;
	}
	else
	{
	   	porta.0=1;
		delay_ms(500);
		porta.0=0;
		delay_ms(500);
		porta.0=1;
		delay_ms(500);
		porta.0=0;
	}
	//porta.0=1; porta.7=1;
	//delay_ms(analog); delay_ms(analog);
	//porta.0=0; porta.7=0;
	//delay_ms(analog); delay_ms(analog);
}
}

 

Just figured it out!!!

 

My code works perfectly. The problem was how i had the switch hooked up. You should have the off position pull the input pin to ground, then pressing the switch should bring the pin high.... floating pins are a BAD IDEA.

Share this post


Link to post
Share on other sites

Back in the days of TTL logic, one usually wired LEDs between the output and +5V (with a resistor), and almost always wired swirches between the input and 0V, with a pull-up resistor if you were sensible (TTL didn't really float). This was because of the asymmetric input and output stages of TTL.

 

You will still see a lot of circuits that use inverted logic (0=ON) for LEDs and switches, even 30 years later with a different IC technology and it isn't all the ossified habits of those 'old farts' still in the design game! :(

 

If you look carefully at the output specs in the datasheet, you will see that many PICs are somewhat better at sinking current than sourcing it. This means that an actice low LED can be a bit brighter. Also there are so called 'weak pull-ups', internal pullup resistors that can be activated so an active low switch no longer needs an external pull-up. You will find them on Port B of the 16F88 and most other 18 pin PICs.

 

You are right about not leaving inputs floating, but you may not realise yet that it applies to ALL inputs that are not actively driven, even unused ones. It is actually possible for a pin set as an input that your code does not use at all to cause problems! The general cure for UNUSED pins is set them as a LOW output (LOW to reduce the risk of short circuits).

Share this post


Link to post
Share on other sites

Glad you found the problem. Sometimes it still helps to whip out the old multimeter to measure things. Or an oscilloscope if you're so blessed. If you measured the voltage at the input pin when you push the button, you'd catch such problems quickly.

 

You are right about not leaving inputs floating, but you may not realise yet that it applies to ALL inputs that are not actively driven, even unused ones. It is actually possible for a pin set as an input that your code does not use at all to cause problems! The general cure for UNUSED pins is set them as a LOW output (LOW to reduce the risk of short circuits).

 

Today's engineers still seem to screw this up. We have a nifty Frigidaire dryer that started acting funny (randomly switching modes, and showing error code E68) after 3 years. After some probing and measuring, I found that some (maybe all) of the switch inputs going direct to the microcontroller didn't have external pull-downs, and one of the inputs seemed to be floating. After some research which showed that TONS of people had the same issue, i found a post from someone who'd also had the problem, and solved it by adding a 10k pulldown to the problem input. I tried adding the resistor to ours, and bingo the problem was fixed.

 

Google "frigidaire dryer E68" for the fireworks.

Edited by kenn

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...