Strange behaviour of pin13 on breadboard Atmega 328

I must have spent 2 hours yesterday trying to find a wiring fault when the problem was in fact a programming fault.

I have an Atmega 328 on stripboard and using its 8MHz internal clock. One of the tasks is to detect a HIGH or LOW from 6 LDRs with voltage dividers using 68k resistors as pullups. Five of them worked fine but the LDR connected to pin 13 did not respond at all. After a lot of frustration it became clear that even with the LDRs disconnected but the pullups in place pin 13 was reporting LOW when it should have been reporting HIGH.

The solution was to add pinMode(13, INPUT); to the code. I had omitted that because it is my understanding that all pins are initialized as INPUT - but not pin 13, it would seem.

I wondered if the Atmega 328 I was using yesterday was faulty but I have reproduced the problem on another Atmega 328 with the short program below. Without the pinMode() lines pin 13 reports LOW and pin 12 reports HIGH. With the pinMode() lines pin 13 correctly reports HIGH.

// tested on a breadboard Atmega 328 using its internal 8MHz clock
// Pins 13 and 12 are connected to Vcc with 68k resistors

void setup() {

    Serial.begin(38400);
    Serial.print(__FILE__);
    Serial.print(' ');
    Serial.print(__DATE__);
    Serial.print(' ');
    Serial.println(__TIME__);

    //~ pinMode(13, INPUT);
    //~ pinMode(12, INPUT);
}

void loop() {
    byte val13 = digitalRead(13);
    byte val12 = digitalRead(12);
    Serial.print("Val13 "); Serial.print(val13);
    Serial.print(" Val12 "); Serial.print(val12);
    Serial.println();
    delay(500);
}

Just wondering if anyone else has encountered this and knows why it happens.

...R

I guess the bootloader has left it in that state after using pin13 to flash some activity on the led.

That's why I get paranoid, and I initialise anything I possibly can ... manually. This includes variables ---- too many times been bitten to allow assumed defaults to get me.

But definitely helpful that you reported this one Robin2 ..... definitely good to know.

6v6gt:
I guess the bootloader has left it in that state after using pin13 to flash some activity on the led.

Seems very probable. Why didn't I think of that.

...R

Correct, the LED pin is set to an output in the bootloader, but I can't find a place where it's configured as an input again:

The execution of the following blank sketch confirms that the DPin-13/PB5 lines comes up as an output line following the loading of a blank sketch.

void setup() 
{
  Serial.begin(9600);
  Serial.print(DDRB, BIN); //prints: 100000 (DPin-13/PB5 is Output)
}

void loop() 
{
 
}

Robin2:
. . . Why didn't I think of that.

After 2 intensive hours of trouble shooting you are simply not thinking straight!
I've just had a similarly frustrating experience building an arduino to audio application (speaking clock) on a breadboard. It eventually got so noisy (and I had to constantly jiggle wires to quieten it all down for a few minutes) that I was forced prematurely to put it all on a solder board. There was still some residual noise. Then I discovered, after hours of troubleshooting, that some of the noise was due to certain activity on the I2c bus (which had previously been masked by the breadboard bad connection noise). I had to redesign the whole software.

GolamMostafa:
The execution of the following blank sketch confirms that the DPin-13/PB5 lines comes up as an output line following the loading of a blank sketch.

void setup() 

{
  Serial.begin(9600);
  Serial.print(DDRB, BIN); //prints: 100000 (DPin-13/PB5 is Output)
}

void loop()
{

}

That depends on which bootloader you're using.

AWOL:
That depends on which bootloader you're using.

Considering the quoted text, the safe side would be to configure the directions of the IO lines as per requirement?

GolamMostafa:
Considering the quoted text, the safe side would be to configure the directions of the IO lines as per requirement?

A sensible bootloader would leave the pins in the processor's reset state.

AWOL:
A sensible bootloader would leave the pins in the processor's reset state.

In that case, all IO lines will come up as input lines without internal pull-ups. As the user is not sure what boot-loader has been fused in his AVR, he should configure the IO lines to meet his requirements.

AWOL:
A sensible bootloader would leave the pins in the processor's reset state.

That is very true but following my experience as I can't be certain what the bootloader does I think it is safer to assume that all the pins I plan to use must have their modes set.

To be honest I don't think a sensible bootloader should do anything with any pin other than Rx and Tx which are essential for bootloading.

...R

Robin2:
That is very true but following my experience as I can't be certain what the bootloader does I think it is safer to assume that all the pins I plan to use must have their modes set.

Oh come on. You have the ability to tell EXACLTY what the bootloader does.
The IDE includes the source code to the bootloader. (in fact it includes several different bootloaders)
All you have to do to be certain what the bootloader does is look at the code.
It is small amount of code in a single module that is fairly well commented and isn't' that complicated.
The IDE includes all the files including a makefile to allow anyone to be able to rebuild the code from source.
The IDE also includes the ability to burn a new bootloader.
So not only do you have everything you need to see what the bootloader does but you have everything you need to be able to build the bootloader from source and install it, including the ability to modify it to do something else should you desire to alter its behavior.

To be honest I don't think a sensible bootloader should do anything with any pin other than Rx and Tx which are essential for bootloading.

Perhaps, but many users like and use the blinking led to tell if the board is "alive".
You have everything you need to rebuild the bootloader of your choice to do something different should you want/need that behavior.

One thing I will say, is that I just went and looked at the optiboot bootloader code and I did see what I consider to be a bug, that I will shortly be filing a github issue for. If you set the define LED_START_FLASHES to 0 it correctly disables the flashes, however it still sets the LED pin to an output. It should not do this.

--- bill

bperrybap:
One thing I will say, is that I just went and looked at the optiboot bootloader code and I did see what I consider to be a bug, that I will shortly be filing a github issue for. If you set the define LED_START_FLASHES to 0 it correctly disables the flashes, however it still sets the LED pin to an output. It should not do this.

Where does it do this?

#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
  /* Set LED pin as output */
  LED_DDR |= _BV(LED);
#endif

Looks alright to me?

PieterP:
optiboot/optiboot/bootloaders/optiboot/optiboot.c at 29bca68f13c09bccb16f2383e5d50f5b6f6a4da6 · Optiboot/optiboot · GitHub

bperrybap:
Oh come on. You have the ability to tell EXACLTY what the bootloader does.
The IDE includes the source code to the bootloader. (in fact it includes several different bootloaders)
All you have to do to be certain what the bootloader does is look at the code.

Oh come on YOU.

I have more enjoyable things to do with my time than study bootloader code looking for some arcane feature I am not even aware it might have. Sheesh.

...R

While this is unrelated to the bootloader leaving the pin in output mode,
this LED output pin issue when LED flashes is set to zero was actually fixed in the official version of optiboot 5 years ago:

So this is a case of the Arduino IDE using/providing an older version of the optiboot bootloader.
(5 years old is quite old....)
It would interesting to know which version of the bootloader are they actually burning into the official boards to see if it matches the source they are providing.

One of the first things I always do with any AVR Arduino board I buy is to burn a bootloader that I have built from source.
That way I know what bootloader code it is in it, particularly for the clone boards.
That and I rarely ever use the LED pin for anything, since the pin is driven as an output by the bootloader.

In the larger picture, using the LED pin can be difficult given the various different LED circuitries used on that pin over the years.
Some will create loads and some will cause the LED to light up when the pin is input mode.
This is one of the reasons I try to avoid using the pin.

--- bill

Robin2:
Oh come on YOU.

I have more enjoyable things to do with my time than study bootloader code looking for some arcane feature I am not even aware it might have. Sheesh.

...R

Not aware? But I assume you know that the LED is blinked by the bootloader, right?

The bootloader blinks the LED.
That means the bootloader must control the LED pin which requires changing registers from their default state.
Using a pin that is used as an output by the bootloader comes with limitations.
You must understand those limitations to be able to use it.

I'll agree that the bootloader probably should put the pin back to its default state before calling application code, but even if it did, there are still limitations on how that pin can be used because the bootloader is using it to control an LED, and there is also external h/w dangling off that LED pin. The external h/w connected to the LED pin on the Arduino boards that can vary between Arduino board versions, and depending on that external h/w there are different limitations and/or restrictions.

So it isn't just a s/w issue in the bootloader of using that pin and leaving it in output mode, there are also h/w considerations that vary by board and board version that must be taken into consideration when using that pin.
i.e. if you rebuilt the bootloader to never touch that pin, you still have certain limitations when using that pin that can vary depending on which Arduino board and which version of the board you are using since there is extern h/w attached to that pin.

--- bill

Ok, so some of this LED pin stuff is coming back to me.
I remember not being happy with how it worked, particularly on the newer Arduino boards.
With the newer onboard LED circuit used on the newer revision boards, the LED is on whenever the pin is not driven low.
This is very different from the older design that required driving the pin high to turn on the LED.

So if you went in an "fixed" the bootloader to put the LED pin back into input mode, the LED would be left on,
That is likely a behavior that many people may not understand and may not like.

IMO that is a h/w design issue on the Arduino boards as I don't think a pin in input mode should turn on an LED.

Like I said, using the LED pin has limitations.

--- bill

bperrybap:
But I assume you know that the LED is blinked by the bootloader, right?

It never occurred to me. I am using a bootloader with an Atmega 328 on a breadboard and I have no LED connected to it to observe the bootloading process.

I have been using Nick Gammon's bootloader program. I have no idea what bootloader code it uses - it just works.

...R

Seems like it might be easier to use a USBasp device along with PeterVH & my version of the USBasp firmware.
Cheap, fairly foolproof with builtin support in the IDE and auto sets the SCK clock to the fastest reliable rate the part can handle including for virgin parts or parts not using a crystal.

That way you know what bootloader you are getting or could use it to upload the code instead of using a bootloader at all.
With no bootloader, your issue with the LED pin completely goes away.

--- bill