NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Support Forum » Can PD0 and PD1 be used for regular input/output?

February 17, 2010
by dav1dr4y
dav1dr4y's Avatar

I'm running out of pins. I am trying to implement Sparkfun's Clockit clock code. (Interesting exercise since I am having to reverse the logic from their common cathode LED display to my common anode one.)

Should I be able to use PD0 and PD1? I have tried but they don't seem to function as expected. Are these pins lost to me even when not in program mode? Is there some place I can learn more about how the bootloader works?

Thanks, David

February 17, 2010
by pbfy0
pbfy0's Avatar

You can, just don't include uart.h. Including uart.h starts the uart on PD0 and PD1 so it will always be high (idle) if no data is sent.

February 18, 2010
by dav1dr4y
dav1dr4y's Avatar

Thanks a lot for the reply. It's encouraging since it seems like we are on to a solution. But... I am not including uart.h in my code. I only have

#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>

I can see when my program is running that pd0 is held low and pd1 is held high (using the very clever $2.50 logic probe from phanderson.com).

I'll mess with these includes some when I get home this evening to see if one of them can be eliminated and let me have pd0 and pd1 back.

/David

February 18, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi dav1dr4y,

The reason the UART module is turned on even though you didn't explicitly turn it on is because the bootloader turns it on before it ever runs your code. You need to explicitly deactivate it in your main function if you want to be able to use those two pins. This happens to be as easy as doing

UCSR0B = 0;

We had to do it as part of the SPI Multi Panel LED Array in order to get those two pins back, since we were only using the SPI bus for communication. You can see it in action in the code there.

Humberto

February 18, 2010
by dav1dr4y
dav1dr4y's Avatar

Ha ha! Thanks! That works perfectly. Now I have the additional two more outputs I need.

Thanks, David

July 02, 2011
by Ralphxyz
Ralphxyz's Avatar

Well I am having a problem trying to use PORTD

I would think this code would do nothing!

    // led7a.c
    // for NerdKits with ATmega328p
    // rhulslander gmail.com

    #define F_CPU 14745600

    #include <stdlib.h>
    #include <inttypes.h>

    #include <avr/io.h>
    #include <avr/pgmspace.h>

    #include "../libnerdkits/io_328p.h"
    #include "../libnerdkits/delay.h"
    //#include "../libnerdkits/lcd.h"
    //#include "../libnerdkits/uart.h"

    int main (void)
    {

        UCSR0B = 0;                 // turn off the UART call from the bootloader
            return 0;
    }

A led on PD1 lights brightly with 4.7v.

PD0 -89mv
PD1 +4.7v
PD2 1.667v
PD3 1.673v
PD4 1.671v
PD5 261mv
PD6 1.641v
PD7 1.641v

My voltage regulator is really hot and shutting down on thermal overload.

Maybe it would be simpler to just ask what is wrong with this code?

I get the same results as above!

I am just trying to light 7 leds using PORTD

// led7a.c
// for NerdKits with ATmega328p
// rhulslander@gmail.com

#define F_CPU 14745600

#include <stdlib.h>
#include <inttypes.h>

#include <avr/io.h>
#include <avr/pgmspace.h>

#include "../libnerdkits/io_328p.h"
#include "../libnerdkits/delay.h"
//#include "../libnerdkits/lcd.h"
//#include "../libnerdkits/uart.h"

int main (void)
{

    UCSR0B = 0;                 // turn off the UART call from the bootloader

    /* set PORTD for output*/   
    // DDRD means Data Direction for PORTD
    //DDRx is DataDirection Register Sets PD0, PD1, PD2, PD3, PD4, PD5, PD6 and PD7 high  11111111

//* 
//  DDRD = 0x00;                // turn off all of PORTD
    DDRD = 0xFF;                // ? turn on all of PORTD?

    while (1) 
    {
    PORTD |= (1<<PD7);       // Led ON  turns on the internal pull-up resistor which pulls the pin (PD7) high
    delay_ms(500);
    PORTD &= ~(1<<PD7); // Led OFF

    PORTD |= (1<<PD6);  // Led ON
    delay_ms(500);
    PORTD &= ~(1<<PD6); // Led OFF

    PORTD |= (1<<PD5);       // Led ON  
    delay_ms(500);
    PORTD &= ~(1<<PD5); // Led OFF

    PORTD |= (1<<PD4);  // Led ON
    delay_ms(500);
    PORTD &= ~(1<<PD4); // Led OFF

    PORTD |= (1<<PD3);        // Led ON 
    delay_ms(500);
    PORTD &= ~(1<<PD3); // Led OFF

    PORTD |= (1<<PD2);  // Led ON
    delay_ms(500);
    PORTD &= ~(1<<PD2); // Led OFF

    PORTD |= (1<<PD1);  // Led ON
    delay_ms(500);
    PORTD &= ~(1<<PD1); // Led OFF

    PORTD |= (1<<PD0);  // Led ON
    delay_ms(500);
    PORTD &= ~(1<<PD0); // Led OFF
//*/    
        return 0;
}

Thanks,

Ralph

July 02, 2011
by esoderberg
esoderberg's Avatar

Ralph,

What current are you pulling through each IO pin? It may be too much; from the data sheet, page 313, absolute max ratings:

DC Current per I/O Pin ............................................... 40.0 mA

DC Current VCC and GND Pins................................ 200.0 mA

Eric

July 02, 2011
by Rick_S
Rick_S's Avatar

I'm with Eric, are you using current limiting resistors? Without them, you risk damaging things including your micro if you try to draw more than it can supply.

Rick

July 02, 2011
by Noter
Noter's Avatar

Turning on one led at a time and then off before moving to the next is what your code does. No problem with that even without limiting resistors. I think you must have a wiring problem somewhere or a short in the breadboard.

July 02, 2011
by Ralphxyz
Ralphxyz's Avatar

Yeah there "should" not be a problem, I am using 390 Ω resistors.

Does the code look correct?

The wiring works for other projects with out overheating the voltage regulator.

Like Paul said the code steps through the led every half second.

But it doesn't, PD1 lights constantly @ 4.7v PD0 and PD% do not light or glow PD2,3,4,5 and 7 just lightly glow constantly @ 1.6v.

There must be something in the code.

For some reason I can not get my Multi-meter to read amperage, it used to work but the regulator is scorching and switching off on termal overload (I believe or at least it stops putting out voltage).

Ralph

July 02, 2011
by Noter
Noter's Avatar

Oops -

It doesn't compile, lot's of errors so who knows what is loaded on the mpu.

July 02, 2011
by Noter
Noter's Avatar

Sorry, I was using the wrong makefile - it compiles with only one warning but you should fix that anyway.

What is the purpose of the return statement? Do you intend to only execute the while loop once?

July 03, 2011
by Rick_S
Rick_S's Avatar

I always use current limiting resistors on the micro's outputs for LEDS. I never drive them directly. One thing I have still never gotten my head wrapped around is why it is OK to use LED's directly on one of the micro's outputs without a current limiting resistor. If the micro is designed to source/sink a max of 40mA per pin, what is to prevent it acting like a fuse and blowing if something connected to it tries to draw more current than that?

The datasheet also states:

  • 3) Although each I/O port can sink more than the test conditions (20 mA at VCC = 5V, 10 mA at VCC = 3V) under steady state conditions (non-transient), the following must be observed: ATmega48PA/88PA/168PA/328P:

    1] The sum of all IOL, for ports C0 - C5, ADC7, ADC6 should not exceed 100 mA.
    2] The sum of all IOL, for ports B0 - B5, D5 - D7, XTAL1, XTAL2 should not exceed 100 mA.
    3] The sum of all IOL, for ports D0 - D4, RESET should not exceed 100 mA.
    
  • If IOL exceeds the test condition, VOL may exceed the related specification. Pins are not guaranteed to sink current greater than the listed test condition.

  • 4) Although each I/O port can source more than the test conditions (20 mA at VCC = 5V, 10 mA at VCC = 3V) under steady state conditions (non-transient), the following must be observed: ATmega48PA/88PA/168PA/328P:

    1] The sum of all IOH, for ports C0 - C5, D0- D4, ADC7, RESET should not exceed 150 mA.
    2] The sum of all IOH, for ports B0 - B5, D5 - D7, ADC6, XTAL1, XTAL2 should not exceed 150 mA.
    
  • If IIOH exceeds the test condition, VOH may exceed the related specification. Pins are not guaranteed to source current greater than the listed test condition.

So based on that, depending on whether you are sinking or sourcing it can do more/less based on the number of i/o's used.

I think I've read on the forum here that the micro itself acts like a resistor in the circuit thus limiting the current to the LED. OK, I'm not sure exactly where that comes from but if I am to take that as fact, what is the "resistance" of the micro so current can be calculated?

I would really like someone to show this to me so I can understand it better, I've looked many times and have never really found a definative answer.

Rick

July 03, 2011
by Ralphxyz
Ralphxyz's Avatar

I tried to track down that warning but could not find a solution or logic on why it was happening!

The return is just an artifact of previous projects this code is built off.

I think this started with the Nerdkit led-blink project which has the return.

So I just always leave it there.

I had not thought about the need or what it might do.

I got rid of the low voltage glow on PD2,3,4,5 and 7 by removing the lcd but PD1 is still constantly @ 4.7v.

Other than the return is there anything else wrong with the code?

Why is PD1 lit?

Ralph

July 03, 2011
by Noter
Noter's Avatar

The warning is because you are missing the final closing brace for main(). Add a } to the end and the warning will go away. Also get rid of the return if you want the while to keep looping.

I usually connect an led directly to the mcu without a resistor and have had no problems. Seems I read an explaination somwhere in the nerdkits documentation early on. The only time I use a current limiting resistor is when I want to be sure the current draw is minimized like in my triac switch project using a transformerless AC to DC power supply.

July 03, 2011
by esoderberg
esoderberg's Avatar

mike's answer to resistance of IO

July 03, 2011
by Rick_S
Rick_S's Avatar

And in the second to last paragraph he ties it all together with this:

  • "So if you're driving an LED's anode from a microcontroller pin, with the cathode connected to ground, you'll run about (5.0-2.0)/30.8 = 97mA through the LED. "

That's WAY beyond the rading for a given pin (MAX 40mA) and nearly the rating for a given port (Max 100mA). So unless the LED is not running constant wouldn't you risk either LED or Microcontroller or both being damaged???

Of Course in the third post of the thread, Mike does clarify a bit and seems to confirm what I thought.

  • "Great! Note that if you aren't using PWM or otherwise limiting the average current to the LEDs, I still recommend a series resistor (or just do PWM). Otherwise, you could very well see excess heating of your LEDs, and a consequent permanent degradation in their performance.. But if you're "bouncing" between several different LEDs, then you're almost certainly safe."

It would appear to me that for projects like the traffic light or where someone is just turning on an LED, they should always use a current limiting resistor. In multiplexed applications or PWM applications, they would not have to but having one on there would not hurt.

So my conclusion would be the safest and only guaranteed method of ensuring you don't cause accidental damage would be to always use a current limiting resistor in series with your LED's.

Rick

July 03, 2011
by bretm
bretm's Avatar

From battery, its fine to run one led without limiting resistor. From wall supply, not. Even the basic led blink runs really weird on my mcu because of over-current unless i use a battery.

July 03, 2011
by Ralphxyz
Ralphxyz's Avatar

Gee it is nice to have such great "Quote" highlighting!

Now back to my problem.

Is there something about my code that is causing PD1 to light constantly and the other LEDs to not light?

Oh, I always use 390Ω limiting resistors.

Ralph

July 03, 2011
by Ralphxyz
Ralphxyz's Avatar

This is/was strange I found my problem! It is working now.

I previously tried to use PORTB so I had a wire between PB0 and a led, which I have neglected to remove.

If I have a wire from PB0 to a led --> resistor --> Gnd.

My program freezes with PD1 staying lit.

If I remove the wire and reset, the program runs as expected.

Thanks for the input and discussion about needing to use resistors.

Ralph

July 03, 2011
by Rick_S
Rick_S's Avatar

Sorry Ralph, Didn't mean to hijack your thread. It's just something I always had wondered about and with all the new people around, I didn't want the burning up their mcu's or diodes accidentally. And if I was wrong and they weren't needed, I could save some breadboard space when prototyping.

As to why having an LED on a different port altogether would have any effect on your program, I would guess it's probably because the pin it happend to be on was the bootloader enable pin. The combo was most likely acting as a pull-down and putting you in program mode so your program is never really starting. What you are probably seeing is the default state of the pins on that port.

Rick

July 03, 2011
by Ralphxyz
Ralphxyz's Avatar

No problem Rick it is so easy to move a conversation off a given topic.

At least the discussion about using resisters was relevant.

A true "Hijack" of a thread is when someone ask something not even remotely relevant to the discussion.

I think one can be safe not using resisters as long as you know what you are doing (not on for long and PWM).

I on the other hand should always use resisters.

Ralph

July 03, 2011
by Rick_S
Rick_S's Avatar

So, do you think the chip was in programming mode and that's what you were seeing??

July 03, 2011
by Noter
Noter's Avatar

I'm glad for the discussion on the limiting resistors. I just measured the current drawn by a led connected without a limiting resistor and it was 60ma. I am suprised I haven't ruined a mcu or at least a port because I have done this a lot even with 100% duty cycle on the led for minutes at a time.

For sure I'll be using the limiting resistors in the future unless maybe there will be a low duty cycle for a led.

July 04, 2011
by Rick_S
Rick_S's Avatar

Well Noter, that is a definative answer. It's good to know an actual meter reading so now we can be confident in recommendations to use the resistors. So why do you think the NK guys don't put this in the guide? Instead they lead you to believe it's ok without the resistor in the blink program where they show the LED w/o a resistor. Granted they are flashing the LED but not quickly. They also are basing it on battery power. Either way though, I would not think it would be a good habit for new folks to form.

bretm, why do you think it's ok from battery power? Is there that much restriction through the regulator? A fresh 9V battery can output between 150mA to 200mA from what I've read.

Ralph, did you determine if the chip was going into program mode?? Just curious.

Rick

July 04, 2011
by Ralphxyz
Ralphxyz's Avatar

I have gotten different results, one time it definitely was in programming mode but when I tried again it wasn't.

There is 19.5 megaΩ PB0 --> LED --> 390Ω resistor --> Gnd plus you add the internal resistor.

I guess the bootloader could see that as a low but there is 2.8v on PD0 from the yellow USB wire with no power to the mcu.

There is 2.9v with power on to the mcu. So I do not know how the bootloader would see a low.

Ralph

Post a Reply

Please log in to post a reply.

Did you know that you need to think about wires differently when you're transmitting signals more than a few inches? Learn more...