Providing access to the Mode Button and RGB LED from GPIO

Is it possible to have buttons and led’s that are connected to the available GPIO pins use the led_int() and button_init() functions in src/hw_config.c? The benefit would be that we can then use core functions like BUTTON_GetState(), BUTTON_GetDebouncedTime() and LED_On/Off(), LED_Toggle(), etc that are already available? I’d like to do this within my sketch rather than directly in the firmware.

I tried LED_Init(D5); in my setup() but received a -fpermissive error I’m guessing because only certain pins have been defined to use this function.

Project examples: A) I’d like to add a ‘reset wifi’ button that can be mounted to out side of my embedded project that when pressed for 10 seconds will put the Core’s wifi config in listening mode. This would support moving the product from network to network, etc. B) I’d like to have a RGB Led mounted to the exterior of the product that mimics the Core’s state. The core will not be visible or accessible to the end user.

If this is possible, can you provide an example?

Regarding your External Mode button question… I think you could get it done with hacking up the internal functions… but it’s pretty easy with just some user code. I whipped this up which works well:

#include <application.h>

#define MODE_PIN D5
uint32_t lastCheck = 0;
uint32_t debounceCount = 0;

void setup() {
  lastCheck = millis();

void loop() {
  // Every 100ms, check if the External Mode Button is pressed
  if(millis()-lastCheck > 100) {
    // Reset the lastCheck time
    lastCheck = millis();

    // Debounce input for 10 seconds!!
    if(digitalRead(MODE_PIN) == LOW)
      debounceCount += 100; // add up all of these 100ms
      debounceCount = 0; // if the input is ever high, reset the count
    // Has it been pressed for 10 seconds?
    if(debounceCount > (100*10*10)) {
      // Perform same SmartConfig code that main.cpp does

I haven’t looked into mimicking the Core’s RGB LED, but I’m assuming you’d just need to read the states and do the same thing. A little more complicated considering the RGB led updates via an interrupt service routine… so your not going to be able to do the same thing via user code super easy. Also since the core-firmware uses PWM to control the onboard RGB, it’s not going to be easy to do from the standpoint of potentially making the core-firmware just use some of your external pins as an RGB led #2. I think a TIMER based ISR in user code that reads the onboard RGB led state variables, and controls a Neopixel might be a good approach. Still, not easy.

Hmm, maybe just add a LIGHT PIPE to the on-board RGB :smile:

1 Like

Another option is to just unsolder the onboard LED and buttons, then solder up some wire to the pads. Not 100% ideal, but the best option if you can’t spare the extra GPIO.

1 Like

Unless soldering on an I2C GPIO expander is easier :slight_smile:

I do like this idea, and I’ve added it to our backlog:

I’ve been trying to provide access to the Mode Button but I didn’t succeed. I tried @BDub code and I don’t know why but does not compile:

In file included from ../inc/spark_wiring.h:29:0,
from ../inc/application.h:29,
from the_user_app.cpp:1:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
the_user_app.cpp: In function 'void loop()':
the_user_app.cpp:29:27: error: 'SPARK_SOCKET_CONNECTED' was not declared in this scope
// Has it been pressed for 10 seconds? 
the_user_app.cpp:29:52: error: 'SPARK_HANDSHAKE_COMPLETED' was not declared in this scope
// Has it been pressed for 10 seconds? 
make: *** [the_user_app.o] Error 1

Has there been any improvement in that issue?


@lia I updated the above example with the current newer implementation of main.cpp.

Basically the new code you can use to put the Core into Listening Mode is WiFi.listen();. It’s really that easy!

There is currently one caveat that has been fixed with a pull request, but is not merged into the main code… that is that it doesn’t work when the WLAN is asleep (i.e. powered down)… so to prevent that from being an issue we wrap the call in a test, like so:


If you wish to also delete all saved profiles you need to add WiFi.clearCredentials(); before WiFi.listen();

The feature for extending the Mode button to an external pin is still open, but not complete at this time so I hope this gets you what you need for now! :slight_smile:



What I want to do is to have the same behaviour you have pressing the MODE and RST button of the Spark but with external buttons.

The RST is very easy just connecting the button to the specific pin but I do not know how to do with the MODE button

I have tried including @BDub code in mine but I receive this error;

"…/src/Senergy20.cpp: In function ‘void loop()’:
…/src/Senergy20.cpp:238:22: error: ‘class WiFiClass’ has no member named ‘listen’

I have been looking for the WiFiClass and I have only in spark_wiring_wifi.h:


#include "spark_wiring.h"

typedef enum
} WiFi_Status_TypeDef;

class WiFiClass
	WiFiClass() {}
    ~WiFiClass() {}

	static void on(void);
	static void off(void);
	static WiFi_Status_TypeDef status(void);

extern WiFiClass WiFi;


Looks like maybe you are building locally and don’t have the latest master. The WiFi class grew and has a bunch of new member functions now. Try pulling lastest from all 3 repos and see how that goes.

Related to this thread… Can I just temporarily (or permanently) turn off the Spark’s built-in RGB LED that is driven by your internal ISR? If so, how would I do that? Is there a master disable macro or state(on/off) call somewhere? Thanks!

Docs is always a good place…

1 Like

Documentation links are 404 after the rebranding.

Try this one: