Digital Write D0 & D1 LOW doesn't drive the pin low

I have a new Arduino Uno and I have discovered that
DigitalWrite D0 & D1 LOW doesn't drive the pin low.

Did something change or am I doing something wrong?

show your code, please...

Yes, post code. You most likely forgot to use pinMode(pin, mode) commands?

Lefty

I'll save him/her the trouble ...

void setup ()
{
  Serial.begin (115200);
  
  pinMode (0, OUTPUT);
  pinMode (1, OUTPUT);
  
  digitalWrite (0, LOW);
  digitalWrite (1, LOW);
}

void loop () {}

On my Uno Rev 3, LEDs on D0 and D1 glow brightly.

However if you remove the Serial.begin() they don't.

1 Like

Really!

What leds? wired to ground or +5vdc?
Led wired to output pins also require resistors, what value?

:wink:

So does rev 1 have some new behavior about pins 0 and 1 ? Or is it another opiboot feature?

Are these questions addressed at me?

What leds?

Normal cheap ones. Forward voltage 1.92V.

wired to ground

Yes.

Led wired to output pins also require resistors, what value?

150 ohms.

I'm measuring 2.67 mA out of D0.

And 16.55 mA out of D1.

Just a tease, the real question is about the need for a serial.begin before pins 0 and 1 function as output pins? is that a new behaviour with rev1 or what?

Well I think that the Serial.begin takes over the pins. With it out you get to use them as you will.

Bear in mind the gentle pull-up of the USB chip. That is going to put some current on those pins. I think I commented on that before.

Ok, I remember now the 1k series resistors to a signal output and signal input pins of the serial converter.

Well, that is very peculiar and subtle...

I had the Serial.begin (115200) statement at the end of my setup function after the pin mode definitions and not before the
pin mode definitions and that made all the difference which now allows D0 & D1 being written to a LOW state.

Is this a recent change with v1.0?

I have been using V 22 for some time and never encountered this phenomenon before...

Thanks for the help!

Ooops - I spoke too soon.

If I put these in the loop, once I write the value high, it can not be set low again...

I got tired of measuring it with the meter so I tied a LED & 370 ohm resistor from D0 to ground to monitor it
The LED stays on once a HIGH is written to D0 and does not go off indicating that DO has not been set to a Low state
even though the code performs digitalWrite(D0,LOW)...

What is going on?

Here is my simplified code that produces these results:

void setup ()
{
Serial.begin (115200);

pinMode (0, OUTPUT);

digitalWrite (0, LOW);

}

void loop () {

digitalWrite (0, HIGH);
delay(3000); // delay 3 secs

digitalWrite (0, LOW);
delay(3000); // delay 3 secs
}

Well, D0 and D1 are used for serial comms. It isn't particularly surprising that, if you are using serial, there is a clash. Further, the "idle" state in async serial is a continuous "high". Which is what you are seeing.

In fact it doesn't make sense to turn serial on, and then try to use D0/D1 for other purposes. What will become of the serial comms? Decide which you are going to do... use serial or use the pins for other purposes.

Because of the internal way the Atmega328 and the USB chip are connected you are probably better off leaving those two pins for serial anyway. Find another way of doing what you want, like a shift register chip (costs around $1).

Or just use a part with more IO pins (and hardware 2 serial ports), like this '1284 Duemilanove style board.
Bare PCB $4.50, mostly thruhole, with options for FTDI Basic/FTDI Cable, or a USB/Seriall adapter.
Need to get one assembled for better show & tell!

As D0 is Rx and therefore an input when using serial I suspect that the serial library is changing it back to an input.

When you do the digitalWrite (0, LOW); that probably looks like a start bit to the UART and it may even be used as a PC int by the library (I don't have access to the code at present so can't check).

I suspect that if you had proper test equipment you would see the pin go high after one character time when the UART generated a RX char available interrupt and the serial library was called.


Rob

We can explain the 17 mA that I measured on D1, because if the LED had a 1.9V voltage drop, then I = (5 - 1.9) / 150 which gives about 20 mA. Close enough. And this is because once you initialize the serial port, it is the job of the UART to keep the Tx line high unless it is sending something.

But what about the Rx line? (D0). That's an input, right? Well it's an input on the Atmega328, but an output on the Atmega8U2 USB interface chip. However it goes through a 1K resistor before hitting D0. Now the Atmega8U2 doesn't know whether or not the "main" chip is listening for serial data, so it has to keep that pin high (M8TXD). So, I = (5 - 1.9) / (1000 + 150) giving 2.7 mA.

Now since I measured 2.67 mA going through the LED that agrees exactly with the theory.

But what if you set the pinMode? Doesn't that override the USART? Well, no. According to page 197 of the datasheet:

Bit 4 – RXENn: Receiver Enable n

Writing this bit to one enables the USART Receiver. The Receiver will override normal port operation for the RxDn pin when enabled.

Bit 3 – TXENn: Transmitter Enable n

Writing this bit to one enables the USART Transmitter. The Transmitter will override normal port operation for the TxDn pin when enabled.

So in other words, once you enable serial comms, the "normal operation" of D0 and D1 is overridden.

And even if you don't, you have to contend with D1 being driven high by the Atmega8U2 chip (through the 1K resistor).

The Receiver will override normal port operation for the RxDn pin when enabled.

Interesting and thanks Nick. I guess that's what data sheets are for eh?


Rob

Is there a way to turn the Serial functions off and force the atmel part to use pins D0 & D1 exclusively as an input or output instead of RXD or TXD or snything else for that matter?

Thanks for the tips everyone... this issue has me a little befuddled to say the least...

Don't use Serial.begin().

But remember what I said above about the Rx line being pushed high by the USB chip. Maybe find another way.

Of course, if you have a "bare bones" board (not a development board like the Uno) then you won't have this problem.

irethedo:
Thanks for the tips everyone... this issue has me a little befuddled to say the least...

The board is designed to be easy to use. Hence the USB interface. You pay a price for that ease of use.