digitalWrite(LED_BUILTIN, LOW); turns on the led

Hey, on my D1 mini pro board, the intern led turns on with digitalWrite(LED_BUILTIN, LOW); and off with digitalWrite(LED_BUILTIN, HIGH);

Is that normal? Or am I doing something wrong?

1 Like

How to blink a D1 Mini onboard LED (Mac, 7 Steps) – desertbot.io

For a standard Arduino, pulling the LED_BUILTIN to HIGH would turn the LED on . But on D1 Mini that actually turns the LED off .

1 Like

thanks!
is it the same for the other pins?

Do the other pins have built-in LED's?

If not, then that would depend on how the external LED is wired into the circuit weather they are illuminated with a HIGH or a LOW.

1 Like

@kaffemitmilf, your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advise on) your project :wink: See About the Installation & Troubleshooting category.

A LED (plus resistor) can be wired to a microcontroller in two ways

  1. between pin and GND in which case you have to drive the pin HIGH to switch the LED on.
  2. between pin and Vcc in which case you have to drive the pin LOW to switch the LED on.
1 Like

Let me add to that that on ESP8266 boards, many times (always as far as i know) the builtin LED is connected to a pin which modifies the 'boot-mode' when it is pulled 'LOW' at boot. (GPIO 0, 1 & 2) A LED connected active 'HIGH' will do that, so that is why they are connected active 'LOW'

1 Like

Congratulations, you have just discovered that there is no portable way in Arduino to turn an on board LED on and off.
I have had this discussion with people a few times on this forum and several members, including very senior ones, fail to understand the issue.

The issue is that while there is a portable way to determine the Arduino digital pin number for the LED, LED_BUILTIN, there is no portable way to determine the i/o pin output active level needed to turn the built in LED on and off.

I had suggested that the Arduino core library probably should add an API function to control the builtin LED and it was met with LOTS of criticism with many stating that that there was no need for it.
Clearly they don't understand the issue.

So as you have found out, as of today, there is no way to write a sketch that can control the on board LED that "just works" on all platforms.
You can either hard code it for given h/w platform, which means it won't work properly on other platforms, or you end up having to use conditional compilation so that the code can adjust to work properly on different h/w platforms.

It is a bit ironic that Arduino for all its great advances in ease of use and simplicity does not provide a portable way to control the on board LED.

--- bill

2 Likes

Jeez Bill. Need or not, You are saying

What you fail to realize is that there is on all the 'actual Arduino boards' all have an LED that is active HIGH. The ESP boards are from a different origin, and in fact all the other boards one can add and cores for separate MCU's

Yes but actually that information is just a macro that the pre-compiler executes, and in case of some boards (like ESP8266) can be set from the IDE, and can of course always be redefined.

Maybe yes, but since that feature is also wide used for educational purposes, from an educational point of view 'not that bad' and personally i actually think that's great ! In the case of ESP boards, it is actually relevant that the hardware does not get connected 'active-high' on some pins, and that is the reason that that LED is connected that way.
You see, when people find out about one thing they find out about something else in the process.
That's how i found out about it ! i added a LED to GPIO 2 of my ESP, and it was active HIGH, and it just wouldn't work ! Now if the Builtin LED in the IDE in the boards definitions would have been correct, i might have used that, but that is a different matter and in all honesty, i did learn about the LED_BUILTIN macro because i started to look for answers.

In this case, the choice is to add a function called setBuiltInLedState(boolean) which would work around our hardware differences, but i think that ruins lesson 1 of our programming course. That actually means that we don't get to explain about pin modes and states using the digitalWrite() and analogWrite(), in the examples, and we will be doing that using hardware that is external to the board, which is probably going to be less reliable, and there is nothing more frustrating than not being able to get even the very basics working by yourself.
As it is now, 99% of the people will get the blink example working, and will understand the basic IO through understanding & experience. Sure adding the function would the experience but not the understanding of basic IO functions. The rest is actually just C++.

But look, how about this, you create a library that does do that. A very simple file, no extra object, just an include file with a macro or whatever way you think it should be done. You post that on GitHub and then you can refer to that in topics here in which it comes up. That has been done before you.

Personally i think the cons outweigh the pros, and it should be the way it is now.
And don't forget that the whole thing is open source, and if it is perfect it could be added to the IDE's built-in libraries.. You never know, now that would recognition. I don't know if that's what you are after, but you know it really is a gathering of contributions, it is not really governed in that sense. This forum is though.

As I've said in the past many people seem to be opposed to the idea of a portable built in led control function.
IMO, the ones not seeing its value or are opposed to it, simply don't really understand or appreciate the issue.
Just my guess but I have a feeling they have not ever written code that needs to be fully portable so that it can run on many different platforms.
In Arduino land that would be something like a library.

Arduino is MUCH bigger than just Arduino.cc made Arduino boards.
Arduino is about ease of use and portability across all Arduino boards which includes all the 3rd party boards.
The current LED_BUILTIN macro cannot provide the needed portability to control the built in led across all the Arduino boards.

For my own libraries that need full portability for built in led control, I have gone through the trouble to create a portable led control function that works on all Arduino platforms.
While it is a PITA, it isn't difficult for me, given my experience level, but IMO, Arduino should be providing a capability to make it easier, especially for less technical users.

And in terms of educational purposes, I can't see how the lack of an led control function is any kind of an advantage over having one.

For example, IMO, it would better to start people off with a simple sketch that only needed to call the led control function.
This could give them exposure to the Arduino sketch setup()/loop() structure and then be used to demonstrate the basic function of the IDE, how to hook up the hardware for uploading and then how to upload a sketch.
Then advance to the next lesson that shows them how actually control an i/o pin by going to a lower level to set up the i/o pin using pinMode() and digitalWrite() to allow their sketch code to directly control an output pin level themselves, and for demonstration, use the LED_BUILTIN pin.

i.e. small steps. start off with something very simple that doesn't even need any h/w knowledge and slowly move to more advance stuff.

As a reminder, LED_BUILTIN has had issues over the years.
There was also the issue of Arduino.cc changing it from a macro to a const int at one point before changing it back (I was one of the ones that helped push them back to using a macro)
A macro is necessary to be able to tell if there is a built in LED.
The macro can be used to to indicate not only the digital pin that controls the LED but whether or not there is built in LED on the board.
I.e. no macro, no built in LED. This allows code to compile time adjust if there is no on board LED.
An led control function would take the led control portability to the next level by providing a common way to control the built in LED that works across all h/w platforms.

Today, if doing something simple like the "blink" example demonstration sketch, you can get away with setting the LED pin HIGH for 1 second and then LOW for 1 second.
The human observer won't notice the difference between an active high and an active low led and simply see an LED that blinks on/off each second.

Now write a sketch that short blinks an LED vs a 50% duty cycle.
For example blink an LED for 1/10 of second each 1/2 second.
i.e. on 100ms and then off 500ms.
Not so easy if you want the code to work on all Arduino platforms since you will have to use conditional compilation to adjust the active level to ensure the led is on and off the appropriate periods.
Having an Arduino core library function to turn on/off the built in LED would make it trivial since you could just call the core function and it would work no matter the platform.

--- bill

Well Bill you have your opinion, i have mine. I think you fail to see my point, Some parts are jus better when they are discovered. To me the first step is perfect the way it is. Making it smaller introduces people to it at a level which is not representative of how demanding it will be. I have no idea why

digitalWrite(LED_BUILTIN), HIGH);

should always result in the the LED turning 'on'
You would probably want to standardize switches in cars as well so they would all work exactly the same.
It doesn't, because it is connected differently on different boards. There are huge difference between boards on hardware levels, this needs to be explained. Most students just accept that it turns it 'on' on one board and turns it 'off' on another.
But seriously, and i mean that. If people want to really start at lesson 1, they should start with an UNO by the original vendor, and then the LED turns 'on' just the way it should according to you.

Well it's not that hard is it. Creating something for multiple boards will always involve that, and if one is not willing to do that, it will not be portable, as is with many things.
I fail to see why it can be that important to blink the internal LED to be honest, with such an accuracy, and i am sure that your abstract description of a problem exist, but in practicality does not really occur. For communication about a certain state in the running, i may blink the built in led, but by the time i am at that point in my programming that i know how the built in led on my board actually works. So that's all there is. I see it differently than you, i value other things more than you. If not many people agree with you, it should tell you something. My points are valid, i know they are.

Ah, so you do agree with me!
But most people tend to assume that setting the led pin high always results in turning the LED on.
But it isn't guaranteed.

In other words, just having LED_BUILTIN is not enough to be control the LED properly.

And THAT is why having a core function to control the built in LED would be useful.

Clearly from a point of view of not interested in or never having written code that must function across many platforms; it again seems to indicate a lack of understanding of the issue.

i.e. it isn't about getting code to work on a platform - that is often easy; it is about being able to create code that can function properly on all platforms.

I'll just leave it at suppose you have an application or library that wants to do something simple like create a "heart beat" led signal or flicker the built in LED when something happens.
i.e. the led is off most of the time but then flashes briefly to indicate something.
Today, it isn't possible to write code to do that and have it "just work" on all platforms without a buggered up set of ifdefs somewhere.
That isn't very friendly nor Arduino-like which is about providing a platform that abstracts the h/w.
And like I previously said, even though it is such a simple capability, as of today, there is no way to control the builtin in LED (explicitly turn it on or off) using Arduino s/w that works across all the Arduino h/w platforms.

--- bill

Read it again.

'platform is not the issue here. This is different hardware. Many supported hardware doesn't even have a LED built in. You have twisted some idea that you have in your mind.

There is methods to find out which board is in use, if it even has a LED and whether it is active HIGH or LOW, if you want to write code that works on both, it is not complex to do so.

If it is to difficult for you ? But again these are not different platforms, but different boards that can be programmed with the same open-source software, with their differences in hardware.

It is not that hard, look at something like neopixel libraries. a little harder to read.

What it is about is something that we differ on, in this thread, the OP learned more than he could possibly learn from your method, and important stuff as well.
This forum is about helping and teaching people, using Arduino, supporting people.
You on the other hand are a bit stuck on this. The reason that not many people agree is that you are not able to see the benefit of the situation as it is. Different boards that are supported have different ways of doing things and do not all have the same hardware.

The duty cycle is a dumb way of showing what is going on. It is better to use the speed of the pulsation. But as i said, my ATtiny13s don't have a LED, and the AVR's don't have PWM on the builtin LED like the ESP boards have etc..
The boards are not manufactured by the same people, not designed by the same people, and the cores are provided by different people again, and free of charge. We all want to improve the world, but i think you have gone onto a crusade for a cause that is wrong. I do not think that it is not important, i think it is important to keep it the way it is !!
But i do feel dumb for trying to convince you of that. As i said, there are huge benefits to the current situation and you should try and see them.
You know if it had to be done with port writes, i sort of would be in it, but as i said initially,
The first lesson should be representative to the whole course !

Just a final note and I'll take the rest of the discussion off line directly with Deva.

As this thread has shown there is no portable way to control the built in LED.
i.e. no simple api function that can turn a built in LED on or off that works consistently across ALL boards that have a built in LED.

Yes there is a macro LED_BUILTIN that if it exists represents the Arduino pin number to control the built in LED if the board has a built in LED. but there is no way to know the active level to turn on the LED.
Most boards use HIGH but some use LOW.

Because the active level is not indicated, there is no way to write code to control the built in LED that will work correctly on ALL Arduino boards without having to resort to either hard coding or attempting to use using conditional compilation (#if or #ifdfef) checking for board specific macros which is not always possible and is a maintenance nightmare.

--- bill

I wrote longer response privately, to fix the nightmare something like this would suffice

#if defined(__arm__) || defined(ARDUINO_ARCH_AVR)
  #define TURN_LED_ON  digitalWrite(LED_BUILTIN, HIGH)
  #define TURN_LED_OFF digitalWrite(LED_BUILTIN, LOW)
#else
  #define TURN_LED_ON digitalWrite(LED_BUILTIN, LOW)
  #define TURN_LED_OFF digitalWrite(LED_BUILTIN, HIGH)
#endif

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  TURN_LED_ON;
}

Of course without setting the pinMode it won't work, but that is a different matter.

1 Like

Deva,
Your first attempt would have failed even on some of the Arduino.cc made boards Even the modified attempt in post #14 won't work for all the known boards out there.
It will fail to work properly on quite a few vendors boards.

This exactly demonstrates what I said from the beginning back in post #7
There is no portable way to control the onboard LED and it is deceptively harder than it would seem to write code to control the built in LED that works on ALL boards.

--- bill

It is just showing a method, remember "I don't need it, i don't want it, i don't even want it to be there really, i think it is better the way it is !!" But you are so caught up in your crusade that you can not accept a straightforward solution to your problem. But then again, i don't think the LED is your actual problem, just a symptom of it.
I totally understand other members of this community 'burned you down !' Quite simply put, people don't agree with you, and you keep repeating your nonsense !

For all the civilized people still following along,
And getting back to the original post of asking why the LED didn't turn on when setting the LED_BUILTIN pin to HIGH but instead turned on when setting the pin to LOW,
Just keep in mind that as of today there is no simple/single/portable way to turn on a built in LED on all boards because the built in LED h/w varies across boards.
If there were an Arduino core library API function to control the LED, then there could be a common way to do it on all boards, but as of today, that doesn't exist, so you have to do things differently depending on the board.

Most boards out there will turn on the LED when the LED_BUILTIN pin is set to OUTPUT mode and set to HIGH but some use active low logic and require the pin to be set to LOW.

If you are wanting to write code, say an application or library that you want others to be able run on as many Arduino platforms/core/boards as possible and that code wants to control the built in LED for some purpose and you want the LED to function properly on all boards, it is deceptively harder than you would initially think to create the necessary conditional code to make sure it works properly on all of them.

--- bill

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.