Thank you. I could not think of a practical example that quickly.
This is true and an exception to discipline when the user has a relay connected. Should this particular use case shift us from delivering the conventional way of teaching Arduino IO?
Set the direction as output
Write value to the output
- For a LOW activated relay connected to a GPIO, I avoid the 3.5μs low level by first writing a HIGH to the GPIO, then set the GPIO pin to output.
would affect any low triggered device..
i think it should be taught..
otherwise how are you not teaching theories that contradict practical applications??
sorry.. ~q
Someone faced the annoyance/problem with his chattering relays at power up and a solution was devised to stop chattering by executing digitalWrite(DPin, HIGH) first and then the pinMode(DPin, OUTPUT).
-
Teaching the problem and the solution to the problem would definitely transfer useful skills to the recipients.
-
The oscilloscope images displayed above demonstrates things nicely.
- Below demonstrates how the problem can be compounded.
If a for(…) loop was used to set several GPIOs as outputs without first setting the pin HIGH, we can see how the timing gets worse.
This reflects the fundamental doctrine of learning.
My native language: এটি শিক্ষার মৌলিক দর্শনকে প্রতিফলিত করে।
Before joining as a faculty member at a university, I spent about 18 years in engineering practice, where I frequently faced the challenge of identifying problems; once a problem was traced, the solution was usually straightforward.
- That’s why there is a benefit for teaching the use of an oscilloscope. It aids in the graphical
demonstration of debugging electronic circuits and software.
There has been a note here several years ago that the preferred way is:
pinMode(D10, INPUT_PULLUP);
pinMode(D10,OUTPUT);
Can't remember why anymore, both ways act the same, maybe for portability across processors.
Setting the pin HIGH before setting it to OUTPUT prevents the pin from briefly going LOW during bootup. This was used a lot for opto isolated relay modules, to prevent activation during boot.
Leo..
Not fictitious. It is a correct representation of the actual state of the I/O pin. It may or may not be the state the programmer intended.
The above code enables the internal pull-up resistor (Fig-1, post #1); as a result, the D10 pin is pulled up to VCC (5 V), which prevents the low-acting relay coil from drawing energizing current and thus stops chattering.
If this was not fictitious, then it would have been able to source 20 mA current, but it can't.
Referring to fig. 1, after digitalWrite(pin, HIGH) the LED in causes a voltage at the pin between VILmax and VIHmin. When digitalRead(pin) reads the actual state, it returns a '0' or a '1'. Indetermined would be the correct term, not fictitious HIGH.
Talking about not being able to source 20mA, weak HIGH might be more descriptive.
(Still assuming UNO R3.)
That voltage is deterministic and is equal to approx.:
(5-2/((20k + 50k)/2) + 2.2k) * 2.2k; as a result
digitalRead(2) will return LOW.
Actual UNO R3 Measurement shows: after executing these codes:
digitalWrite(2, HIGH);
Serial.print("Logic level DPin-2: ");Serial.println(digitalRead(2), BIN);
Serial.print("Voltage at DPin-2: "); Serial.print((5.0/1023)*analogRead(A0), 1); Serial.println(" V");
Logic level at DPin-2: 0
Voltage at DPin-2: 1.8 V //loded by: R1-LED1 of Fig-1 of #1
This isn't true, or shouldn't be true, or wasn't true.
digitalWrite() writes the PORT register, regardless of whether the port is in INPUT or OUTPUT mode. On an ATmega328p, that also enables the pullup resistor. A subsequent pinMode(p. OUTPUT) changes the DDR register, but the PORT register is still a 1, so you should get a full 5V output and full LED brightness. There's an "assumption" that the brief period of "only pullup" on the way to "strong 5V output" is OK, especially compared with the "brief period of strong GND when you wanted 5V.")
This is what I see on my Uno; I don't know how to explain what you claim to see.
void setup() {
digitalWrite(13, HIGH); // pullup enabled; LED at reduced brightness.
delay(3000);
pinMode(13, OUTPUT); // output driver enabled: full brightness
delay(3000);
digitalWrite(13, HIGH); // no change.
delay(3000);
digitalWrite(13, LOW); // LED off
}
Also note that the pullup resistor is "weak" - approximately 20+k, so if you were driving the LED with only the pullup, you would see far less than 1/2 high (at least, if it were a pure voltage divider and not an LED circuit.) (although with modern LEDs, it may be bright enough to look "half bright", even with resulting low current.)
Your statements are not fully true/correct:
(1)
G2 is on, becase U2-Q is HIGH and both U1-Q and PUD are LOW
LED1 is powered from Vcc via Rip and R1. It depends on the LED, how much of shine the current 5V/50k ~0.1mA (or 5V/20k ~0.25mA or anything between) will make. Probabelly something dim.
Division of voltage is on the point 2(pin output) between Rip going to +5V and R1+LED going to ground, which would affect, what value woud digitalRead(2) get - probabely LOW, not HIGH.
(2) to make LED1 fully bright G1 must be enabled and output HIGH. Rip would not affect much the result and in case of HIGH it would just little contribute to the HIGH, but it is disabled by Q1, Q2 anytime when G1 is enabled.
To be so, the U1-Q and U2-Q must be both HIGH. It is true, if last write to DDR was 1 and last write to PORT was 1, regardless on order, in which it happened.
The behavior spotted by sterretje happens, because the PORT for pin2 was not written yet and is therefore LOW from reset (see reset line on U2). When DDR for pin2 is set to OUTPUT, the LOW value is send out.
I have an observation based on the execution of only digitalWrite(2, HIGH) without pinMode(2, OUTPUT) before or after; the experimental result is presented in #34.
The plain understanding of the execution of digitalWrite(2, HIGH) stands as asserting VOH on DPin-2. However, it is being told in many posts that the purpose of the code is to enable the Rip. Yes, it does so at reset time when DPin-2 is input by default; but, it does not match with the context -- use pinMode(DPin, INPUT_PULLUP) to connect Rip.
In as usaul manner, I set the direction as output first and then write the value.
Someone had a relay chattering noise at start up and then the solution was devised as to execute digitalWrite(2, HIGH) first and then execute pinMode(2, OUTPUT).
The voltage that guarantees an input to be seen as LOW in an UNO R3 is 0.3VCC = 1.5V.
The voltage that guarantees an input to be seen as HIGH in an UNO R3 is 0.7VCC = 3.5V.
If the actual voltage at a pin is between these voltages (for instance 1.8V) the state of the pin at digitalRead(pin) is dependent on factors within the Schmitt trigger AND its history, in short: indetermined.
Regard the following sequence in setup():
digitalWrite(pin, HIGH);
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
In the UNO R3 (ATmega328P) this results in:
Weak HIGH (pull up)
Strong HIGH (+5V)
Third line has no effect.
In the Nano Every (ATmega4809) this results in:
Weak HIGH (pull up)
Strong GND
Strong HIGH (+5V)
This makes me wonder how other boards will process this.
Read the link in the opening post. That started this discussion.
I read the opening post again and followed the references. It indeed tells how the UNO R4 behaves at that sequence of statements.
From what I read in the references I get the impression that the problem can worked around by using direct register access, which might be somewhat more complicated than in AVR.
The total impression, not only from this thread, is that the team of Arduino took the functions they invented for the AVR (UNO) and one by one adapted them for another processor, without looking at the big picture.
Still doesn't answer how other boards will process similar sequences.
