DIGITAL GPIO start-up glitch

Why of the digital pins appears start-up glitch.
When connecting LED or other consumers as relay, start-up power appears shortly inclusion. When I use the analog pins configured as digital outputs everything is fine.
How to avoid this appearance?

Hmm, it sounds like the pin values are floating before your setup() function is called? Does that sound right? (Someone please feel free to correct me if I’m not understanding)

You can set the pinMode earlier by putting those requests in a class constructor, which will be called before setup() is called.

class RunBeforeSetup {
public:
	RunBeforeSetup() {
		pinMode(A0, OUTPUT);
	}
};

RunBeforeSetup runBeforeSetup;

Maybe that would help? You could also try pulling your GPIO line high or low as needed with some pull-up / pull-down resistors?

Thanks,
David

2 Likes

Hi Dave,
I tried your solution but without success.
When I use the pin D0, D1 … appear start-up glitch, when I use A0, A1, … then run stable.

class RunBeforeSetup {
public:
	RunBeforeSetup() {
		pinMode(D0, OUTPUT);
                digitalWrite(D0, HIGH);

               /*pinMode(A0, OUTPUT);
                digitalWrite(A0, HIGH);*/
	}
};

And by using the pull-up / pull-down resistors the same thing happens.
If you can test this. I noticed that all digital pins including D7 which is connected to the blue led, lights up when you turn on the power. This is an extremely short period and hardly noticeable, you can do testing with an oscilloscope.

Ohh… Thanks for that tip! That’ll come in handy! :smiley:

1 Like

@wgbartley Whether you try the solution and whether it works?

Whether there some other solution? Again I tried but without success, whether I’m wrong somewhere or there is a problem with setting the digital pins. Very strange that it only happens with digital pins.

developer_bt, the STM32F10x manual says:

During and just after reset, the alternate functions are not active and the I/O ports are
configured in Input Floating mode

Input floating mode means that the lines will float to some voltage depending on what is on the pins at power-up. So that mode will persist until the start-up code sets the digital pins.

You say you get a “glitch”, can you explain what that means?

1 Like

Hi @peekay123
I have connected 4 Channel Relay board to digital pins.
When run power appears shortly ON / OFF on all outputs.
When I use the analog pins configured as digital outputs everything is fine, not appears shortly ON / OFF.
This Relay Board has an inverted logic. To turn the relay used low logic level.
Initialization code is as follows:

class RunBeforeSetup {
    public:
    		pinMode(D0, OUTPUT);  // set output
                    digitalWrite(D0, HIGH); //Off Relay
    
// This function without undefined conditions on boot even in setup ()
                   /*pinMode(A0, OUTPUT); // // set output
                    digitalWrite(A0, HIGH); ////Off Relay */
    	}
    };
    
    RunBeforeSetup runBeforeSetup;

Hi @developer_bt

I have not had a chance to test this but perhaps you could try direct port control to force the outputs high like this:

PIN_MAP[D0].gpio_peripheral->BSRR = PIN_MAP[D0].gpio_pin; //force pin high
//now make it an output
pinMode(D0, OUTPUT);

Are you sure the Spark core is doing this? Have you tried disconnecting the core from the relay board and see if the relay board by itself has a problem?

I have a SainSmart relay board that’s is “inverted” like the one you have. I consider the power being ON when the Core boots as a feature. It lets me know when the Core has booted and is connected to the Cloud.

You can use a transistor to invert the pins on boot. @psb777 did that with a relay in one of the posts in the Controlling a SPDT relay, OFF = HIGH, so that it remains OFF at start up thread.

I agree with bko. I can’t see floating pins being able to sink 4+ milliamps to turn on the relays. The only other possibility is a condition in the boot-up code that somehow toggles the pins. I will have to test this with my scope somehow.

There is some time between the call to pinMode() and the call to digitalWrite() where it might be low.

[Sorry for the earlier post, I wasn’t finished editing yet!]

bko, you are quite correct and your proposed code is the only option since digitalWrite() expects pinMode() to already be set. Good catch!

Thank you all for the advice.

I will do testing with the logic analyzer and will post the results here.
Unfortunately I do not have an oscilloscope to do testing.

OK, here’s my full sketch:

class RunBeforeSetup {
public:
	RunBeforeSetup() {
	    PIN_MAP[D0].gpio_peripheral->BSRR = PIN_MAP[D0].gpio_pin;
	    pinMode(A0, OUTPUT);
	    digitalWrite(D0, HIGH);
	}
};

RunBeforeSetup runBeforeSetup;

void setup() {

}

void loop() {

}

This gives the best results so far, yet during startup I can see the LED on the relay board flash for a few milliseconds. Not enough to actually actuate the relay though. Adding a pull up resistor doesn’t seem to affect anything.

3 Likes

Hi @Hypnopompia

You could try adding a 0.1uF cap from the output pin of the core to the +3.3V supply pin. This is a little unconventional, but it should help and I don’t think it will slow down the turn-on much.

No love with the 0.1uF cap.

I also just noticed that there’s a difference between powering on the core and just hitting reset. Even with the RunBeforeSetup constructor, when you first power on the core, there’s a ~2 second delay in changing the pin state, whereas a reset is only a few milliseconds.

I’ve got my inverters ordered already, so I think I’ll just go that route instead of trying to mess with this in software.

1 Like

That does seem like the best way to go. The first two seconds part is odd–I will try to look into that tonight when I get home.

1 Like

That 2-second delay happens even without the fancy RunBeforeSetup code.

Hello,
Like I said I did the test with logic analyzer.
Initialization code is as follows:

#define REL1 A7

class RunBeforeSetup {
public:
	RunBeforeSetup() {

   
        PIN_MAP[D0].gpio_peripheral->BSRR = PIN_MAP[D0].gpio_pin;
	    pinMode(D0, OUTPUT);
	    digitalWrite(D0, HIGH);
	  
	   PIN_MAP[A7].gpio_peripheral->BSRR = PIN_MAP[A7].gpio_pin;  
	    pinMode(REL1, OUTPUT);
	    digitalWrite(REL1, HIGH);
    
	}
};

RunBeforeSetup runBeforeSetup;

The results for pin D0 are as follows:

  • When booting low logic level for a period of 686 ms.
  • When reset just a 1.29 ms.

Booting
 

Reset

1 Like