When the Core starts up, all the D pins are actively pulled low by the Core, till instructed otherwise in setup(), which - in SYSTEM_MODE(AUTOMATIC) - only runs after the cloud connection is established (class constructors might run - in undefined order - before that).
While flashing the Core, this doesn't seem to be the case, but the JTAG pins do get internal pull resistors attached (see quote) which is especially noticable on D7 (blue on-board LED).
The expected and surely preferable way to treat all pins would be, to have them high impedance input and without any pull resistors from start till user code - and only user code - alters the pin mode.
As for JTAG pins, that might not be possible, but if it can't be helped, it needs clear documenting, in order to prevent users from attaching external circuitry, that couldn't cope with this default behaviour.
On the Spark Core, the A pins and pins RX & TX don't seem to suffer such issues.
For the Spark Photon and Spark Electron tests might be in order.
Whether all pins D3, D5, D6 and D7 should be connected to PULL DOWN resistors?
I noticed that the pin (D4 - JTAG_TDO - PB3 - Floating) and (D6- JTAG_TCK - PA14 - ~ 40k pull-down) has not troubled effect and without resistors.
When I connect pull up to D6 as recommended here https://github.com/spark/firmware/issues/414 , then shows up above mentioned problem.
Whether all pins should be connected to pull down including pin D6?
I’m not sure what your intended use of D6 is, but the table shown in this post is not intended to show default recommended external setup, but how to counteract the effects of the internal pull resistors if they get in your way.
If they don’t, there is no need for extra pull resistors.
@Carsten4207, could you elaborate how you did the measurement? To recreate your test setup and verify.
Hello,
I solved the problem
It’s about the electron. D0 - D7 are connected of the eght solid state relay through mosfet transistor.
To all pins I connect pull down resistor with a value 4,7K, and now no longer exist undefined conditions when turn the power of the electron.
I solved this very simply by using the fast io functions to set the desired initial value before configuring as an output and thus driving the output line.
pinSetFast(pin); // initialize to HIGH
pinSetMode(pin, OUTPUT); // enable output
or
pinResetFast(pin); // initialize to LOW
pinSetMode(pin, OUTPUT); // enable output
In reality, the library should have a setPinMode that takes a third argument which is the initial value. In my case I have some outputs that are active low and some that are active hi so I wrote a generic wrapper so I can change an output from active high to active low later and not worry about spreading HIGH and LOW around my code:
const int STOP = D0;
const int START = A0;
const int RESET = A1;
// define which outputs are active low
const int ACTIVE_LOW_MASK = (1 << STOP) | (1<<START));
const bool Off = false;
const bool On = true;
void setPinMode(int pin, PinMode mode, bool on) {
bool invert = (1<<pin) & ACTIVE_LOW_MASK;
if (invert) on = ! on;
if (on) pinSetFast(pin);
else pinResetFast(pin);
pinMode(pin, mode);
}
void pinOn(int pin) {
digitalWrite(pin, ACTIVE_LOW_MASK & (1<<pin) ? LOW : HIGH);
}
void pinOff(int pin) {
digitalWrite(pin, ACTIVE_LOW_MASK & (1<<pin) ? HIGH : LOW);
}
void pinToggle(int pin) {
if (digitalRead(pin)) digitalWrite(pin, LOW);
else digitalWrite(pin, HIGH);
}
void setup() {
setPinMode(START, OUTPUT, On);
setPinMode(STOP, OUTPUT, Off);
setPinMode(RESET, OUTPUT, Off);
}
That's not quite addressing the exact problem discussed here tho'
The point of this thread is that some JTAG pins act like outputs for a very brief moment before any of your code can run
So there is no software solution for that very "problem" (at least in user code).
Good point. I think though there are multiple issues as listed in the first post. My fix deals with the issues of enabling outputs with an initial value other than low so when the pin is configured by pinSetMode to be an OUTPUT, the state is under control of the user and a quick pulse to an unexpected state does not occur.
While I agree that setting the desired output state once the GPIO gets set as OUTPUT would be beneficial for some use cases, I do not really see any reference to this as an issue in my intial post.
Could you point me to that quote?
The first post referenced above mentions this code sequence:
pinMode(D0, OUTPUT);
digitalWrite(D0, HIGH);
This results in a driven low value in the interval between the pinMode and digitalWrite call which I think may be what some users are measuring. Use of pinSetFast eliminates this particular interval. On my board I also see a driven low spike of 50us shortly after power-on but that’s not enough to light up an LED or fire a relay to close but is certainly undesirable.
You are correct in pointing out that use of pinSetFast does not in any way address the behavior of the core in driving the outputs low briefly before user code starts or during programming.