real basic ground test, need help

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi I'm still new to this all but learning. I currently have an atmega 168 and I'm trying to detect ground on port C pin 4. Here is my attempt

DDRC &= ~0x10; // sets pin 4 to out
PORTC |= 0x10; //enable pull on pin 4
_delay_ms(10); // settle ( not sure if this is needed)
int testPin = (PINC & 0x10);
blinkLed (testPin);

Where did I go wrong? Or is this an over kill?

Thx as always.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ar least one problem is the very first line of code. You need to set the port as an INPUT. Leave the pull up resistor ON.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmm didnt work. maybe its my math? If I enable pull on pin 4 I should read 0x10, and if there is ground it should read 0. Then I & it by a mask of 0x10, but In either case I get 16 flashes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try using unsigned char instead of int for the testPin?
If you do that, you will have to change your function prototype to:

void blinkLed (unsigned char); 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What does your blinkLed function do? Post up the code for us. and what about the rest of the code? maybe poat all of it here so we can have a look :)

DDRC = 0x00;
PORTC |= (1<<4);

//delay if you want

while (1) {
  if (!(PINC & (1 << 4))) {
    //turn on LED
    //delay
    //turn off led
    //delay
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry guys I maybe should have include why I have that blink code. Its just my version of a debug. I use it to see whats what.. It works just fine. If I tell it to blink 1 time it will ;)

static void blinkLed(int n_times)
{
	int i;

	DDRD |= 6 << PD1;
	
	while (n_times--)
	{
	
		PORTD &= ~( 6 << PD1 );
		//PORTD |= 0x20;
		for (i=0; i<20; i++) _delay_ms(10);	
		//PORTD &= ~0x20; 
		PORTD |= 6 << PD1; 
		for (i=0; i<50; i++) _delay_ms(10);
	}
	
}

Maybe I should re cap just to make sure I didn't fail at explaining, as I often do.. All I need is a way to scene if a pin is grounded. It has to be pin PC4. If applied do this else do that.

Tnx for the replies!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok nevermind, it was my ground loop. I tested shorting the pin and it did indeed work. Thx for the help ka7ehk , I guess that was it.

It must be a diode in my external circuit if I measure from the lead I'm testing to ground. I get nothing, but the other way I get infinite resistance.

Not sure I can test for that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you have a diode in series with your switch, you will have maybe 0.5V to 0.6V (not 0.7 because of the low current generated by the pull up resistor). But, if you look at the required level to recognize as a low input, that is awfully close. So, I would not be surprised if you have problems.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey skunx.

Just one thing I noticed in your code which I learned myself recently. After your pin register declarations you have "settle ( not sure if this is needed)"

It is actually recommended to let the registers "synchronise" at that point, I think the nice way to do it is with the assembly command "nop", meaning No OPeration. The way to do it in C is to declare this above your code:

#define nop() __asm__ __volatile__("nop")

Then just put one of these

nop();

whenever you want to let everything sink in.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you both for your insight.

Last Edited: Thu. Jun 11, 2009 - 08:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

do the opposite. Put pin as input, disable pullup resister and put an external pull down resistor on.

Then you can go

if (PINC & (1<<4)) {
    //do stuff
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

do the opposite. Put pin as input, disable pullup resister and put an external pull down resistor on.

Why? It's far easier to simply invert the sense of a test in software than to add a component into the circuit. If Atmel were good enough to include internal pull-ups in the AVR design why not use them?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Care to elaborate, I'm lost

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Care to elaborate, I'm lost

A picture is worth 1,000 words. The right-hand option saves an external resistor.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yeah, i didnt see he has edited his post. He asked how to sense the 5V line using the uC instead of Gnd in the post before mine, thats why i said use pull down etc :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nedward wrote:
yeah, i didnt see he has edited his post. He asked how to sense the 5V line using the uC instead of Gnd in the post before mine, thats why i said use pull down etc :)
My fault nedward, I found an alternative and felt there was no reason to peruse that route. Very interesting though never thought about that. Glad to know it would work ;)