I am running into a problem on a very basic functionality.
I want to read the state of an LED. I have confirmed that under the specified circumstances, the LED receives 1.9V.
I try to read its state with this code:
#define LED_1 5
void setup()
{
pinMode(LED_1, INPUT);
}
void loop()
{
int led_state = 0;
if ( digitalRead(LED_1) ) led_state = 1;
Serial.println("LED State is: ");
Serial.println(led_state);
}
However, most of the time, the led_state
is 0
. Sometimes, it goes to 1
, but then quickly goes back to 0
.
Is it because the voltage is low?
EDIT: I am hooking power directly to one pin of the LED, and the other pin goes to GND (from the same DC power supply). Also, the power pin from the LED enters inside Arduino Digital Pin 5.
-
What LED button do you have? How is it wired? What Arduino are you using?chrisl– chrisl2022年10月31日 13:26:41 +00:00Commented Oct 31, 2022 at 13:26
-
If it's wired how I think it is the analogRead would be better for it. Or internal analog comparator module (depends on MCU, there might not be library for it) or external OpAmp/comparatorKIIV– KIIV2022年10月31日 13:29:19 +00:00Commented Oct 31, 2022 at 13:29
-
@chrisl Sorry it was not a button. I made a typo in the question, it is corrected now. Just a standard LED. I am using arduino uno.user1584421– user15844212022年10月31日 13:31:49 +00:00Commented Oct 31, 2022 at 13:31
-
@KIIV Thanks! Can I do analogRead(), on Arduino Digital Pin 5? I am on Arduino Uno.user1584421– user15844212022年10月31日 13:33:59 +00:00Commented Oct 31, 2022 at 13:33
-
No, you'll have to wire it into some analog pin. And then you'll have to compare the value with some threshold (basically making software comparator)KIIV– KIIV2022年10月31日 13:36:14 +00:00Commented Oct 31, 2022 at 13:36
3 Answers 3
For the CMOS logic the treshold is usually 1/2 Vcc, therefore you might get lucky with arduino 3.3V Arduinos, but it's still in undefined area. That usual threshold can also change with operating temperature (like 5V WS2812 stopped working in the winter if you were using 3V3 mcu as a driver)
So what are the possible solutions?
route it to the Ax pin and use analogRead + condition (basically software comparator)
if the previous is too slow, you can use AC module on the mega328p (Analog Comparator), but you'll most likely have to dig into the datasheet and use specific pin or pins (compare it against internal 1V1 reference or external one set by potentiometer)
external OpAmp/Comparator (this one can be used with the original pin, note comparator needs pullup, opamp doesn't)
NPN transistor (1k or bigger between base and Anode of the LED, internal pullup or external one between Vcc and Collector, Emmiter to the ground)
-
1I just note, for completion.... If you wire up an LED and you try to read it, make sure the GND is common between the LED and the Arduino.user1584421– user15844212022年11月04日 21:10:10 +00:00Commented Nov 4, 2022 at 21:10
A digital input on the Arduino Uno is guaranteed to read LOW
if the
input voltage is less than 1.5 V. It is guaranteed to read HIGH
if that voltage is above 3.0 V. For any voltage in between, you
have no guarantees.
That being said, the datasheet of the microcontroller shows some
"typical" characteristics. According to those, the input should switch
to HIGH
when the input voltage goes above 2.6 V, and switch to
LOW
when it goes below 2.1 V. There is an hysteretic range in
between.
Note, however, that there is no guarantee that your input will behave like in the typical characteristics. The only guarantees are for voltages below 1.5 V and above 3.0 V.
-
I made an experiment, providing up to 5V in the LED. I could still see the input oscillate from 0 to 1 back to 1. Why is this happening? I didn't cross over the 5V threshold.user1584421– user15844212022年10月31日 14:58:13 +00:00Commented Oct 31, 2022 at 14:58
-
1@user1584421: I do not know what is happening in your setup because: 1. You cannot "provide" 5V to an LED without burning something. 2. The code you posted does not even compile. Please, edit your question: add a schematic of your circuit, and a version of the code that can be tested.Edgar Bonet– Edgar Bonet2022年10月31日 15:08:21 +00:00Commented Oct 31, 2022 at 15:08
-
Thanks! I updated the question.user1584421– user15844212022年10月31日 15:21:29 +00:00Commented Oct 31, 2022 at 15:21
-
1@user1584421: You should never power an LED like this, as you may burn the LED, the power supply, or both. Always use a current-limiting resistor. If nothing burned, chances are the PSU itself is limiting the current, and thus not providing 5 V to the LED.Edgar Bonet– Edgar Bonet2022年10月31日 15:59:43 +00:00Commented Oct 31, 2022 at 15:59
-
Yes, you were right. The PSU was limiting the current. I managed to solve this problem with analogRead(). And by having a common GND between the PSU and the Arduino. Thank you very much for your highly informative post!user1584421– user15844212022年11月01日 10:48:10 +00:00Commented Nov 1, 2022 at 10:48
On my understanding, this is what you made my understanding
But i think you should do it this way
Here is the code
int value;
float input;
int delaytime=500;
void setup() {
pinMode(value,INPUT);
Serial.begin(9600); //serial bud rate
}
void loop() {
value=analogRead(A2);
input=(value*5.0)/1022.0;
Serial.println(value);
Serial.println("LED state is: ");
Serial.println(input);
delay(delaytime);
}