How to set output HIGH without pulse?

I have a system that starts running at a low input, to be controlled by an Arduino Nano Every board.
After power-up the output of the Arduino is set as input, thus high impedance, the internal pull up of the system keeps it's input high.
In setup() of the Arduino I want to set my output to OUTPUT, but I don't want the system to start yet.

With the Arduino UNO R3 I have two options:
Method 1:

digitalWrite(pin, HIGH);
pinMode(pin, OUTPUT);

This method does exactly what a sentient being would expect.

Method 2:

pinMode(pin, INPUT_PULLUP);
pinMode(pin, OUTPUT);

To use this method one NEEDS TO KNOW how the Output Register is abused, and is thus not portable.

But I want to use the Nano Every because of reasons.

Method 2 does not affect the Output Register, and rightfully so.

Method 1 doesn't work because Arduino thinks I want to set the pull up resistor. Setting the mode to output hereafter will pull the output down, with undesired results.

So here is my question: how can I keep the output high, no pulse?

I might miss something, but even if I have never used a nano Every, I can't really get your point: if the other system starts running at low input I see it has an internal pullup, so why do you need to also set a pullup on the Arduino side?

Or don't just use an external (47k?) "physical" pullup from the pin and +5V to prevent it from floating?

1 Like

I don't want to set the pull up resistor in my Arduino. I also don't want the output to be pulled low, even for a short period.

Once upon a time in a chip factory far far away:

Designer: "Boss, I found a neat feature that our customers surely will appreciate: internal pull up resistors. But to do this I want to reorganize the registers."

Boss (angry): "Have you any idea what messing with the registers is gonna cost us?"

Note: changing registers might break some of the existing software, the customers affected will not appreciate that.

So they found a way: use the Output Register for something it wasn't intended for. They used it to switch the pull up resistor when the pin is input.

Note: they also found a way to use the Input Register for something else: writing a 1 to it toggles the Output Register, but Arduino doesn't support that feature.

A quarter of a century later, another boss at last saw the necessity for innovation and a new line (with the 4809) was produced.

And now we're waiting for Arduino to see the light, because they still think 328 style. So when I issue the statement that should set the Output Register they still think that I want to set the pull up resistor, while that can be done with it's own statement.

External pull-up resistor?

Which arduino? On an Uno Like PORTB=0x01; DDRB=0x01;?

If you were doing that with registers on the 4809, what does that mean?

versus the Uno/328P's

Always a problem when you create an API based on a specific hardware, and then find it is not generic. Change the API and break existing code, or propagate the hardware specific feature?

It seems the author had some doubt, but went ahead with the side effect anyway :

/* Old implementation has side effect when pin set as input -
		pull up is enabled if this function is called.
		Should we purposely implement this side effect?
		*/

Personally, I would have added OUTPUT_LOW and OUTPUT_HIGH to the API.

1 Like

It's quite simple: if I switch to output mode I don't want the output to be pulled low. Using the Arduino language I can achieve that with a 328. But with a 4809 I can't.
Yes, I can use direct register access, but I feel it should be possible like it is in a 328.

1 Like

Yes, they implemented the side effect. But they forgot to implement the primary effect, namely setting the Output Register.

Ah.. Here:

Wasn't that "side effect" the main effect before there was a pinMode command?

Here it is:

The pullup resistors are controlled by the same registers (internal chip memory locations) that control whether a pin is HIGH or LOW. Consequently, a pin that is configured to have pullup resistors turned on when the pin is an INPUT, will have the pin configured as HIGH if the pin is then switched to an OUTPUT with pinMode(). This works in the other direction as well, and an output pin that is left in a HIGH state will have the pullup resistors set if switched to an input with pinMode().

Prior to Arduino 1.0.1, it was possible to configure the internal pull-ups in the following manner:

pinMode(pin, INPUT);           // set pin to input
digitalWrite(pin, HIGH);       // turn on pullup resistors

-- https://docs.arduino.cc/learn/microcontrollers/digital-pins/

That doc says it should work exactly like you want:

"Consequently, a pin that is configured to have pullup resistors turned on when the pin is an INPUT, will have the pin configured as HIGH if the pin is then switched to an OUTPUT with pinMode()."

No, the doc describes what happens in the 328, and ignores the differences in other processors like the 4809.
What I want is not possible using the Arduino language for the 4809.

1 Like

It may well be exactly what happens on the 328, but it also describes pullup behavior on other than 328 AVRs and the due.

I would read it as that the doc describes the API. And that the implementation on the 4809 is in error.

The primary/natural use of digitalWrite(pin,level) is to set (or stage) the output level, and the side effect of setting the output level on the 328-like processors is that it happens to set the pullup resistor.

I agree, worth a bug report. The behaviour of 328 is not replicated in 4809, and that is a regression in the semantics of the API.

1 Like

They tried and failed. In my view, the clean implementation is to make the digitalWrite do what it must do, without side effect. The function of that side effect has it's own, designated statement. I can imagine a place for implementing the side effect in emulation mode.

Seems like you'd need to change this bit:

to write the output pin to match the pullup state.

How can it be "pulled" low.
The code command makes it go low.
Unless you over load the output.

Please tell us the complete story, what are the controller and devices use and why are you worried about an output being "pulled" low?

Tom.... :smiley: :+1: :coffee: :australia:

I don't have a Nano Every, but I believe that if you execute these three commands on a Nano Every's 4809:

digitalWrite(pin,HIGH);
pinMode(pin,OUTPUT);
digitalWrite(pin,HIGH);

... the pin will do a weak pullup, then sink up to 20mA LOW, and then drive up to 20mA HIGH.

While on an Uno, the same commands will do a weak pullup HIGH, then drive 20mA high, and then redundantly keep driving 20mA high.

On the Nano Every, an external pullup wouldn't prevent the LOW on the pin, since it will drive the pulled-up signal down.

I suppose that you could also solve the problem using a diode if you neither want to mess with library nor use direct port manipulation.

Do you mean:


or:

Anyway, I used this example to find out if I overlooked something in the Arduino IDE or that the Arduino IDE is flawed.

The second illustration is correct in that the cathode of the diode (marked with a band) is connected to your "other system". This will stop any unwanted "LOWs" getting to that other system. But its not a pretty solution for what is effectively a software problem.

Clearly, as you have discovered, there is an inconsistency between the Arduino board packages for the Arduino Uno and the Arduino Nano Every because of the way the underlying hardware behaves and, as suggested, you could raise an issue in github: GitHub - arduino/ArduinoCore-megaavr: Arduino Core for the ATMEGA4809 CPU. If you do then Mention this thread because the type of solution proposed by @bobcousins in post #7, where an initial or default state is added to pinMode/output, looks good.