LMV358 on Uno question.

Summary:
Why does the LMV358P act as a pullup resistor on e.g. an Uno board?

Description:
I'm trying to understand the behaviour of the onboard led on an Uno. On a real Uno, the onboard led is on by default when the sketch starts running; on a SparkFun Redboard (and possibly a number of clones without the opamp) it's off.

I wrote a little test sketch to read the relevant registers using direct port manipulation to check what is happening.

void setup()
{
  Serial.begin(57600);
  delay(500);

  Serial.println("after bootloader");
  printPort(DDRB, PORTB, PINB);
}

void loop()
{
}

void printPort(byte dir, byte port, byte pin)
{
  Serial.print("DDRB =    "); Serial.println(dir, HEX);
  Serial.print("PORTB =   "); Serial.println(port, HEX);
  Serial.print("PINB =    "); Serial.println(pin, HEX);
  Serial.print("Pin 13 =  "); Serial.println((pin & 0x20) == 0x20 ? "HIGH" : "LOW");
  Serial.println();
}

The result (below) clearly indicates that pin 13 is input, no internal pullup and reading the pin results in a HIGH.

after bootloader
DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

To check for noise (on a floating input), I modified the above sketch to pick up any changes on PINB in loop()

void setup()
{
  Serial.begin(57600);
  delay(500);

  Serial.println("after bootloader");
  printPort(DDRB, PORTB, PINB);

  Serial.println("starting loop()");
}

void loop()
{
  static byte oldPinValue;
  static bool firstRun = true;

  byte dir = DDRB;
  byte port = PORTB;
  byte pin = PINB;

  if (firstRun == true || oldPinValue != pin)
  {
    firstRun = false;
    oldPinValue = pin;
    printPort(dir, port, pin);
  }
}

void printPort(byte dir, byte port, byte pin)
{
  Serial.print("DDRB =    "); Serial.println(dir, HEX);
  Serial.print("PORTB =   "); Serial.println(port, HEX);
  Serial.print("PINB =    "); Serial.println(pin, HEX);
  Serial.print("Pin 13 =  "); Serial.println((pin & 0x20) == 0x20 ? "HIGH" : "LOW");
  Serial.println();
}

The sketch works as expected showing changes on pins when I touch the pins on the Uno board; the exception is pin 13 which is consistently high.

after bootloader
DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

starting loop()
DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    28
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    21
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    23
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3B
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    22
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3E
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    30
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    22
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    26
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    24
Pin 13 =  HIGH


DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    22
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    24
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    24
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    24
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    24
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    2F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    2F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    2F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    2F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    2A
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    27
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    22
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    27
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    23
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    23
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    25
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    23
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    22
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    22
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    22
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    27
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    24
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3F
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3E
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    3C
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    38
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    30
Pin 13 =  HIGH

DDRB =    0
PORTB =   0
PINB =    20
Pin 13 =  HIGH

So it looks like the LMV356 acts as a pullup resistor and the question is why? I looked at the schematic of the Uno as well as LMV358 datasheet but I have no idea which parameters and / or images will give this information in the datasheet; the block diagram in the datasheet is not much help (to me).

Any insight appreciated.

Note:
I'm not looking for a workaround; just understanding.

sterretje:
Why does the LMV358P act as a pullup resistor on e.g. an Uno board?

It doesn't.

Some (smaller/older) Arduinos have an onboard LED/resistor directly connected to pin13.
That loads the pin, so you can't use it anymore as an input.

Bigger/newer boards have solved this with an opamp buffer.
The opamp input doesn't load the pin, and the LED is driven by the opamp output.

Behaviour of the LED depends on the bootloader.
Not sure which ones flash/uses the LED, and which ones don't.

If you're using pin13 for something important (relay, motor), you should know the behaviour of that pin during bootup.
Leo..

My wording might not be correct but with an Uno R3 the led is on when the sketch starts and the two codes prove that the pin is configured as input (DDRB = 0) once the bootloader is finished.

Why is the led on?

Nothing else is connected to that opamp input than the MCU.
But the voltage on a "floating" opamp input and a "floating" MCU input could be high enough to drive the opamp output above the working voltage of the LED.

Try with a very high value bleed resistor (1Megohm) connected between pin13 and ground.
Leo..

PINB = 20

  • you mean it reads as 20 (hex I presume) - if you assign to the PINB register
    it will toggle the pin state for each bit set.

Wawa:
But the voltage on a "floating" opamp input and a "floating" MCU input could be high enough to drive the opamp output above the working voltage of the LED.

I don't like the word "could" :wink: Any means to calculate based on specifications of the 328P and the LMV358?

Wawa:
Try with a very high value bleed resistor (1Megohm) connected between pin13 and ground.

That worked. A pinMode(13, OUTPUT) is cheaper :wink: Unless you run out of program space 8)

MarkT:

  • you mean it reads as 20 (hex I presume) - if you assign to the PINB register
    it will toggle the pin state for each bit set.

Yes, that is hex; sorry for that, should have put a 0x in front of it (although the code would have made it clear :wink: ).

sterretje:
I don't like the word "could" :wink:

Then avoid floating inputs!

I don't like the word "could" :wink: Any means to calculate based on specifications of the 328P and the LMV358?

Floating ATmega inputs are specifically "undefined". I couldn't find anything in the LMV358 datasheet about floating inputs, but high-impedance inputs of any kind are prone to noise pickup, and since op-amps are often used as... amplifiers... (or open-loop as high-gain comparators) it would be unusual to leave the input(s) floating.