pinMde weird behaviour?

[ide 1.6.5, mega board]

Hello,
I tied a led with a series resistor between ide pin 35 (cathode) and vcc (anode), and am running two variant v1 and v2 of a sketch

v1

void setup() {
  #define LED3_PIN 35
  pinMode(LED3_PIN, OUTPUT);
  digitalWrite(LED3_PIN, HIGH);
}
void loop() {
  delay(1000);
  pinMode(LED3_PIN, INPUT);
  delay(1000);
  digitalWrite(LED3_PIN, HIGH);
  pinMode(LED3_PIN, OUTPUT);

}

as expected, the led is at steady off

v2

void setup() {
  #define LED3_PIN 35
  pinMode(LED3_PIN, OUTPUT);
  digitalWrite(LED3_PIN, HIGH);
}
void loop() {
  delay(1000);
  pinMode(LED3_PIN, INPUT);
  delay(1000);
//  digitalWrite(LED3_PIN, HIGH);
  pinMode(LED3_PIN, OUTPUT);
}

The led oscillates (brightly) at 2Hz(?!) I'd think that since levels are either hi or hi z the led should be at steady off

Could someone please explain why?
Thanks in advance

Why are you going from input to output?

To control your LED, alternate from digitalWrite(35,HIGH) and digitalWrite(35,LOW)

LEDs connected to inputs can back feed into the controller and appear dim.

Put your defines, #define LED3_PIN 35, prior to setup()
.

For starters, in C++, (or any C for that matter) , the "#define" does NOT belong in the setup. It belongs BEFORE the setup. I don't know why you would do that unless this is your first C program.

Second, the setup is for just that , setup. The digitalWrite does not belong in the setup. There is no reason why it can't be there but just for the record, it doesn't belong there.

Third,
You have a pinMode in you void loop(), which obviously doesn't belong in the main loop since it is a setup function.

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

Fourth,
Last but certainly not least, you have a pinMode AFTER a digitalWrite. God knows
what possessed you to do that. Again, one can only conclude that not only have you never written a C program before, you have never seen one before either.
BEFORE you start coding, you might want to look at some IDE example programs.
What you have done is about the same as getting a car in a showroom floor and driving it right through the plate glass window...
It's best to learn something before you try to do something...

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

The last person I told that to said he was
"learning as I go..."

yeah, that doesn't really work all the time.

Fifth,
What LarryD said..

Sixth,
Why is a ledpin configured as an INPUT ?

void pinMode(uint8_t pin, uint8_t mode)
{
 uint8_t bit = digitalPinToBitMask(pin);
 uint8_t port = digitalPinToPort(pin);
 volatile uint8_t *reg, *out;

 if (port == NOT_A_PIN) return;

 // JWS: can I let the optimizer do this?
 reg = portModeRegister(port);
 out = portOutputRegister(port); //This is the PORTx register, which controls whether output is high or low when set output. 

 if (mode == INPUT) { 
 uint8_t oldSREG = SREG;
                cli();
 *reg &= ~bit;
 *out &= ~bit; //And here they clear it when you set the port input. 
 SREG = oldSREG;
 } else if (mode == INPUT_PULLUP) {
 uint8_t oldSREG = SREG;
                cli();
 *reg &= ~bit;
 *out |= bit;
 SREG = oldSREG;
 } else {  //this is when you set it output again. 
 uint8_t oldSREG = SREG;
                cli();
 *reg |= bit;
 SREG = oldSREG;
 }
}

So

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

will end up with the pin set as an output, and low.

Using pinMode() after a digitalWrite() call is not particularly unreasonable - consider, if you will, interfacing with a DHT-series temperature and humidity sensor. You need to pull the line low, and then let go of it (or weakly pull it up) and listen to what the DHT sends back. That means changing the pinMode() after writing to that pin. It's not hard to think of other examples where you have to change the pinMode(). digitalWrite()ing in setup() is fine - if that's part of what you need to do to initialize your sketch, for example, initializing an active low output to the HIGH state (and note that you can do the digitalWrite() before setting the pinMode() to output - it's just when you set it input that it messes with the value in the PORT register)

@LarryD
Thanks: just made a setup to focus on my issue (not to play with a led)

@DrAzzy
You showed how to analyse such problems and I'll sure use it next time I'm is the mud. I'll dive into it tomorrow. Honestly, I had the feeling I should code at a lower level to have things doing what I want them to to

Nice cats.
.

Have to agree with DrAzzy, digitalWrite before pinMode is not a weird thing.

Once used a single pin for a button and a LED at the same time. Button between GND and the pin, the led+resistor between Vcc and the pin. Output low = led on, input with pull up = led off/possible to read button. But this way you don't want to end up with it set as a output high. And if you switch from input pullup to output with pinMode(pin, OUTPUT) you're left with a pin that's a high output...

And this also shows pinMode can be fine in loop, no problem.

And no digitalWrite in setup? What a nonsens. If you want to initialize the output to high you just put it in setup....

So to answer the question, if you put a pinMode(pin, OUTPUT) after a pinMode(pin, INPUT) the output is set LOW. So you have to set it high again. And if you don't want any low time at all, set it high befor calling pinMode(pin, OUTPUT) :wink:

Honestly, I had the feeling I should code at a lower level to have things doing what I want them to to

I have no idea what that is supposed to mean.
There is no reason you needed pinMode the main loop , despite the fact that C++ allows it. By the same token there was no reason why you needed a digitalWrite in the setup. If you had wired the leds like most people do with the cathodes to GND and the resistor to the digital output, they would have been off by default. The point is that when you are learning it is best to develop good habits. Telling you that you can still both of those things is encourage you to do them and you really shouldn't.
You don't need pinMode in the main loop. There are times when you do but this is not one of them. There are times when you need to initialize something in the setup or you just want it to be executed one time only but this isn't one of those times. You posted because your led was oscillating intead of turning on for a second. If you had looked at the IDE Blink example you would see how it SHOULD
be done, (and there is no pinMode in the main loop and no digitalWrite in the setup either).
FYI, you didn't have any code to turn on your led in the sketch you posted:
In the following program, the led would only turn on (normally) , if with a

digitalWrite(LED3_PIN, LOW);

(which does not appear in the program)

void setup() {
  #define LED3_PIN 35
  pinMode(LED3_PIN, OUTPUT);
  digitalWrite(LED3_PIN, HIGH);
}
void loop() {
  delay(1000);
  pinMode(LED3_PIN, INPUT);
  delay(1000);
//  digitalWrite(LED3_PIN, HIGH);
  pinMode(LED3_PIN, OUTPUT);
}

Using pinMode() after a digitalWrite() call is not particularly unreasonable

It's also totally unnecessary if the sketch is written correctly, (like the Blink example). Justifying a mistake because you can think of occasions where it is necessary doesn't make it any less a mistake, which, is what it was.
If it had been written like the Blink example and if the led had been wired with the cathode to GND, it would have worked perfectly. The pinModes should be in the setup unless there is justifiable reason to put them in the loop. The digitalWrites should be in the loop unless there is a justifiable reason to put them in the setup.
Neither was necessary here if the code had been written correctly. And there is certainly no reason to configure an OUTPUT as an INPUT. (in this case. Dr Azzy cited a case where it would make sense. This is not one of them) pinMode(pin,INPUT); is for configuring a pin as an input (obviously). If that pin has a resistor and a led connected to it, it can't very well be an input , can it ?
Saying that pinMode(OUTPUT) would end up with the output LOW is like saying putting on the parking brake while your driving will end up with the car stopping. While this is true, it is not the recommended or normal way to do it and not something I would teach a beginner. If you want it low, use digitalWrite to set it LOW. That's what it's for.

Start by looking at the IDE examples. Don't start developing bad habits right off the bat. Follow the standard conventions until you know what you are doing.

If you want to emulate an open collector output, you have to make the pin Hi Z (input),
but in the loop I use bitClear and bitSet (bitSet(DDRx, pin)).

If you want to emulate an open collector output, you have to make the pin Hi Z (input),
but in the loop I use bitClear and bitSet (bitSet(DDRx, pin)).

While it's obvious you are trying to be helpful, it should also be obvious the OP is a beginner and probably has never heard of an Open collector.

It is clear that he is trying to sink the led current but based on his code, it is not clear if he knows this would require making the output LOW, (instead of HIGH).

The led oscillates (brightly) at 2Hz(?!) I'd think that since levels are either hi or hi z the led should be at steady off
Could someone please explain why?

Your code works as expected. Here, I've added comments:

void setup() {
#define LED3_PIN 35
  pinMode(LED3_PIN, OUTPUT);    // defaults LOW (LED ON)
  digitalWrite(LED3_PIN, HIGH); // now it's HIGH (LED OFF)
}
void loop() {
  delay(1000);                    
  pinMode(LED3_PIN, INPUT);     // now it's HIGHZ (LED OFF) 
  delay(1000);
  pinMode(LED3_PIN, OUTPUT);    // defaults LOW (LED ON)
}

Here, the LED stays off (no low level coding needed):

void setup() {
#define LED3_PIN 35
  pinMode(LED3_PIN, OUTPUT);    // defaults LOW (LED ON)
  digitalWrite(LED3_PIN, HIGH); // now it's HIGH (LED OFF)
}
void loop() {
  delay(1000);                    
  pinMode(LED3_PIN, INPUT_PULLUP); // pulled HIGH (LED OFF) 
  delay(1000);
  pinMode(LED3_PIN, OUTPUT);       // defaults HIGH (LED OFF)
}

Add delay(50); in between the 2 setup lines and you'll see the LED flash ON/OFF after upload or reset.

@raschemmel
Very well, let him forever be a beginner, matters not.

guy_c:
The led oscillates (brightly) at 2Hz(?!)

No it doesn't.

With two 1000mS delays you have a total cycle time of 2 seconds.
That corresponds to a frequency of 1/2 = 0.5Hz

If you wanted the led to always be off then why did you put two delays in the main loop and what is the purpose of the program ? (to do nothing?)

from 8-bit Atmel Microcontroller document 2549P–AVR–10/2012

If PORTxn is written logic one when the pin is configured as an input pin, the pull-up resistor is
activated. To switch the pull-up resistor off, PORTxn has to be written logic zero or the pin has to
be configured as an output pin.

This is why the compiler sets PORTxn to low when pinMode(PORTxn, INPUT no pullup)

septillion:
... And if you don't want any low time at all, set it high befor calling pinMode(pin, OUTPUT) :wink:

which elucidates why code in v1 does the right thing.

I don't want to address all the unpleasing comments: it make the author feel he's worthier writing it -bless him.

yes: .5Hz not 2Hz This was the most important thing in this not so interesting discussion.

@LarryD nice cats: They are! Not mine however, a photo I took in a village while waiting for tablets of marble for my windows. My cat, His Highness Dingi the First is tuxedo

If you knew this and the code does the right thing then why did you post ?
More importantly, , why didn't you begin your post with the Atmel document instead of ending it with it ?
Something doesn't add up . Are you now telling us this whole excercise was to confirm what the document says which you knew about but didn't believe ?
Why did you post if you knew this ?
Why do you need a pullup resistor if you're sinking led current ?
Why didn't you start your post by asking how to activate an internal
pullup resistor ? (which you can find if you Google it)
What do you need ? ( an input or an output ?)
I still don't see why you don't use digitalWrite to set it LOW instead of pinMode(OUTPUT) ?
You have a led connected to it so it IS an output.
Why do you want an internal pullup of a pin that is driving a led ?
(you don't need a pullup if you're sinking led current and you don't need a led if you are configuring an input as an open- collector.)
Something doesn't make sense about this post.
If you wanted to know how to configure an internal pullup all you had to do was ask and if that's what you were trying to do then why did you post ? (if it was working correctly)
If you want an internal pullup why don't you just use the "pinMode(pin#,internal_pullup); " statement like everyone else ?
DigitalPins

(in the setup, NOT the main loop)
None of this explains why you are putting #defines in the setup .
Why don't you just start over by telling us how much programming experience you have and why you really posted ? On the upside, "congatulations on reading the ATmega328 datasheet !" At 646 pages it can be very intimidating. You have gone where others fear to tread..
All I'm trying to do is get to the bottom of this because your story isn't adding up.
If you knew that configuring the pin as an input would make it low you wouldn't have said it should be HIGH or "steady state off" in your original post. What's the story ? We like people to just be honest with us and tell us they don't know instead of trying to beat around the bush.
The "normal" way to begin a post is the folliwing:

"Hi, I'm a noob, and I want to do the following:
blah,blah, blah..."
"I tried this...etc..." and [this] happened...etc..
Am I missing something ?"
"Is this correct ?"

It just seems like you could have saved time by explaining WHY you wrote the code that way (what you were trying to accomplish) instead of just posting the code and asking why it doesn't work the way you expected.

The only other questions I have is why you're just finding this out when you registered (on the forum) in 2011, and why you only have 138 posts and no karma in over 4 years ?
(and don't say "because of people like you !" , because I didn't register until 2014)

Easy: I downloaded the atmel doc to understand why pinmode code sent by DrAzzy was how it was.

Exceptionally, I am unsubscribing from this thread and would be gratefull if you had the kindness to ignore all my posts, and I aint talking for other forum members. All the best

Exceptionally, I am unsubscribing from this thread and would be gratefull if you had the kindness to ignore all my posts, and I aint talking for other forum members. All the best

Dude, it's YOUR thread. Unsubscribe yourself if you feel like it. Next time just tell us what you are trying to do and we can answer it in one sentence instead of all this
beating around the bush.

See you in another 4 years on next post...
FYI, if you just Google your topic with the word "arduino" at the beginning of the search string you can answer your own question most of the time. Now that you know something maybe you can help someone else for once and maybe get your first karma point after 5 years.

Raschemmel,

Why are you attacking a persons motives? Why are you beating this guy up about being here a long time and without karma?

They were clearly "curious", came here... and got some good answers from people who clearly know better what the "right" way is.

I have been here for ages... I feel that I more often "help" versus hinder and still I could give a pile of dog poop about Karma. Unlike you, I have never begged or panhandled for Karma. I'm probably proof that Karma in this forum is silly and should not be taken seriously for anything.

Raschemmel,

Why are you attacking a persons motives? Why are you beating this guy up about being here a long time and without karma?

They were clearly "curious", came here... and got some good answers from people who clearly know better what the "right" way is.

I don't know if "beating this guy up" is all that accurate.
You've been here eight years and have 45 karma points , which averages to about 5 1/2 /per year, while it is not going raise any eyebrows, at least demonstrates that you have made a concerted effort to help others (every once in a great while) and are not a "freeloader", per se. I think it is maybe unfair for someone who has 45 karma points in 8 years to criticize someone who has almost 250 karma points in just over two years. (about 5.5 for every one of yours and I'm proud of every one of them because I earned them) The OP, though he may not realize it, has abilities that others don't. You've been around long enough to know that most newbies are terrified of datasheets and won't attempt to read them if their life depended on it. They typically take one look at one and have a brain aneurysm. The OP was able to read an Atmel datasheet, extract the relevant section , and quote it, which is a hell of a lot more than most newbies can handle. I think he has something to offer and if all he did was read datasheets for people who are too scared to do it he would be doing the forum a service. I don't feel guilty for asking why the OP hasn't helped anyone in over 4 years. I don't think that is an unreasonable question. If I didn't think he was capable of helping others I wouldn't ask. I don't think it constitutes being rude or offensive to ask a member why , in over 4 years, with 138 posts, he has not taken a few minutes of his time to give back to the community. We can't expect the old retired guys (I'm not retired yet, though I am old) to carry the load all the time, although they certainly never complain about doing it. The forum would be a better place if everyone tried to help at least one other person a month. On the subject of begging for karma points, you are mistaken. I have only mentioned it maybe 6 times in over 10,000 posts (0.06%) and usually only if it is obvious the OP has no idea what it is or if they think it is a bad thing and the karma button is a way to complain about a poster (yes, it has happened ! A russian guy thought that. He said "traditionally karma is bad.." Maybe in Russia, but not here).
In any case, unlike you, I think the karma system is a good thing and it does provide a means for posters to thank those who help them. The flip side of the coin is it provides a way for "helpers" to show their "chevrons" as it were , for helping (all the thousands of hours that some do). The people usually complaining about the karma system are the people who don't have much.