Skip to content

Arduino Example

Arduino

This example assumes you are using the latest version of the Arduino IDE on your desktop. If this is your first time using Arduino IDE, library, or board add-on, please review the following tutorials.

Note

If you've never connected an CH340 device to your computer before, you may need to install drivers for the USB-to-serial converter. Check out our section on "How to Install CH340 Drivers" for help with the installation.

For the scope of this tutorial, we will highlight the example from the GitHub repository to get started. Head to the GitHub repository to download the example

Upload Arduino Example

After unzipping the compressed files, navigate to the example: ... > SparkFun_Soft_Power_Switch_USB-C-main > Examples > SoftPowerSwitchMk2_Example > SoftPowerSwitchMk2_Example.

If you have not already, connect the Soft Power Switch's power, OFF, and PUSH to your Arduino's GPIO pins. In this case, we used the SparkFun IoT RedBoard - ESP32 Development Board. Depending on your microcontroller, you may need to adjust the pin connections and definitions with respect to the microcontroller's GPIO pins. Then connect the USB from the IN to your computer's USB port. Press the power button to turn the Soft Power Switch ON.

Soft Power Switch - USB-C SparkFun IoT RedBoard -
ESP32 Development Board
VOUT 5V (or V)
GND GND
OFF 32 (or A4)
PUSH 14
Uploading Code to ESP32 IoT RedBoard with Soft Power Switch Connected
Uploading Code to ESP32 IoT RedBoard with Soft Power Switch Connected

For users using an Arduino microcontroller, select your board in the Tools menu (in our case the SparkFun ESP32 RedBoard IoT RedBoard) and the correct Port it enumerated on. You can also copy or paste the code as shown below. Then click "Upload".

    /*
      Control the power to a system using the SparkFun Soft Power Switch Mk2
      By: Nathan Seidle
      Adapted by: Paul Clark
      SparkFun Electronics
      Date: March 14th, 2024
      License: MIT. See license file for more information

      This example assumes the OFF pin is connected.

      A simple tap of the power button will turn on the system. If the power button is not being pressed
      (accidental tap) the system will turn off after ~20ms. If the system turns on and sees the power
      button held for 0.5s, it will begin normal operation.

      During normal system operation, if user presses the power button for 2s, the system
      will shut down. This means the power button can also be used as a general 'select' button as
      long as user doesn't hold button for more than 2s.

      This example will output serial states. If you are powering your board over a USB connection then
      the power button can't do its job. We did our testing by connecting the TX and GND pins of a RedBoard to
      an external USB to Serial adapter. That way the battery + Soft Power Switch could control power
      to the board.  
    */

    //Hardware connections - GPIO pins (change these as required)
    int _PUSH = 14; // Connect this GPIO to the PUSH breakout pad
    int _OFF = 32; // Connect this GPIO to the OFF breakout pad

    int STAT_LED = LED_BUILTIN;

    unsigned long powerPressedStartTime = 0;

    int debounceDelay = 20;

    //Uncomment the following line to turn on shutdown time measurements
    //#define PRINT_TIMER_OUTPUT

    void setup()
    {
      Serial.begin(115200);
      Serial.println("Soft Power Switch Mk2 example");

      pinMode(_PUSH, INPUT_PULLUP);

      //User has pressed the power button to turn on the system
      //Was it an accidental bump or do they really want to turn on?
      //Let's make sure they continue to press for two seconds
      Serial.print("Initial power on check");
      powerPressedStartTime = millis();
      while (digitalRead(_PUSH) == LOW)
      {
        //Wait for user to stop pressing button.
        //What if user has left something heavy pressing the power button?
        //The soft power switch will automatically turn off the system! Handy.
        delay(100);

        if ((millis() - powerPressedStartTime) > 500)
          break;
        Serial.print(".");
      }
      Serial.println();

      if ((millis() - powerPressedStartTime) < 500)
      {
        Serial.println("Power button tap. Returning to off state. Powering down");
        powerDown();
      }

      Serial.println("User wants to turn system on!");
      powerPressedStartTime = 0; //Reset var to return to normal 'on' state

      //Here we display something to user indicating system is on and running
      //For example an external display or LED turns on
      pinMode(STAT_LED, OUTPUT);
      digitalWrite(STAT_LED, HIGH);

      Serial.println("Press 'r' to enter infinite loop to test power-down override");
      Serial.println("Press 'z' to do a powerdown");
      Serial.println("Press and hold power button for 2s to do a powerdown");

      while (Serial.available()) // Flush the Serial RX buffer
        Serial.read();
    }

    void loop()
    {
      if (Serial.available())
      {
        char incoming = Serial.read();

        if (incoming == 'z')
        {
          Serial.println("Power down");
          powerDown();
        }
        else if (incoming == 'r')
        {
          Serial.println("System locked. Now hold power button to force power down without using software");

          //Here we wait for user press button so we can time it
          while (digitalRead(_PUSH) == HIGH)
            delay(1);

          powerPressedStartTime = millis();
          Serial.println("Doing nothing, waiting for power override to kick in");
          while (1)
          {
    #ifdef PRINT_TIMER_OUTPUT
            Serial.println(millis() - powerPressedStartTime);
    #endif
            delay(1);

            if(digitalRead(_PUSH) == HIGH) break;
          }
          Serial.println("User released button before forced powered could complete. Try again, but hold power button for 7s");
          powerPressedStartTime = 0; //Reset var to return to normal 'on' state
        }
      }

      if (digitalRead(_PUSH) == LOW && powerPressedStartTime == 0)
      {
        //Debounce check
        delay(debounceDelay);
        if (digitalRead(_PUSH) == LOW)
        {
          Serial.println("User is pressing power button. Start timer.");
          powerPressedStartTime = millis();
        }
      }
      else if (digitalRead(_PUSH) == LOW && powerPressedStartTime > 0)
      {
        //Debounce check
        delay(debounceDelay);
        if (digitalRead(_PUSH) == LOW)
        {
          if ((millis() - powerPressedStartTime) > 2000) // Check if button has been held for >= 2 seconds
          {
            Serial.println("Time to power down!");
            powerDown();
          }
        }
      }
      else if (digitalRead(_PUSH) == HIGH && powerPressedStartTime > 0)
      {
        //Debounce check
        delay(debounceDelay);
        if (digitalRead(_PUSH) == HIGH)
        {
          Serial.print("Power button released after ms: ");
          Serial.println(millis() - powerPressedStartTime);
        }
        powerPressedStartTime = 0; //Reset var to return to normal 'on' state
      }
    }

    //Immediately power down
    void powerDown()
    {
      //Indicate to user we are shutting down
      digitalWrite(STAT_LED, LOW);

      Serial.println("Pulling OFF high");
      Serial.flush();

      powerPressedStartTime = millis();

      pinMode(_OFF, OUTPUT);
      digitalWrite(_OFF, HIGH); // Pull OFF high to turn the power off

      while (1)
      {
    #ifdef PRINT_TIMER_OUTPUT
        Serial.println(millis() - powerPressedStartTime);
    #endif
        delay(1);
      }
    }

After uploading the code, disconnect the Arduino from your COM port. Then wire a 3.3V Serial Basic Breakout to the Arduino's serial UART. In this case, we connected to the SparkFun IoT RedBoard - ESP32 Development Board. Depending on your microcontroller, you may need to adjust the pin connections and definitions with respect to the microcontroller's UART pins.

3.3V Serial Basic SparkFun IoT RedBoard
- ESP32 Development Board
TXO 3/RX-0
RXI 1/TX-0
GND GND
3.3V Serial Basic Connected to ESP32 IoT RedBoard Hardware UART
3.3V Serial Basic Connected to ESP32 IoT RedBoard Hardware UART

Initial Boot

Open the Serial Monitor or terminal emulator of your choice, and connect to the 3.3V Serial Basic Breakout's COM port with the baud rate set to 115200. Insert a USB power source into the Soft Power Switch's IN port. Hit the reset button on the Soft Power Switch. Since we are using the ESP32, we will see an initial output when the microcontroller boots up. If the button is not held down for 0.5 seconds, you will receive the following message as shown below.

Soft Power Switch Mk2 example
Initial power on check
Power button tap. Returning to off state. Powering down
Pulling OFF high
Arduino Output Soft Power Switch - USB-C with No Button Press on Startup
Arduino Output Soft Power Switch - USB-C with No Button Press on Startup

Note

You may receive a different output when directly connecting the Soft Power Switch to a computer's COM port rather than using a separate 3.3V Serial Basic. When using the Soft Power Switch directly, part of the ESP32 boot up and Serial.print() messages may be cut off as the IoT RedBoard - ESP32 is being powered up.

Normal Operation - Power On

Press down on the button for just over 0.5 seconds (but no longer than 2 seconds) to power your Arduino for normal system operation. Once the ESP32 boots up, you should see the following output. A timer will begin checking the length of time that the button has been pressed down. Once the button has been released, you will receive an output indicating the amount of time that the button has been pressed down after 0.5 seconds.

Soft Power Switch Mk2 example
Initial power on check....
User wants to turn system on!
Press 'r' to enter infinite loop to test power-down override
Press 'z' to do a powerdown
Press and hold power button for 2s to do a powerdown
User is pressing power button. Start timer.
Power button released after ms: 300
Arduino Output Soft Power Switch - USB-C Normal Operation - Power On
Arduino Output Soft Power Switch - USB-C Normal Operation - Power On

Note

The wake-up time can be tweaked to your own user experience. We found 500ms for power up work really well.

Normal Operation - Power Off

Let's try turning the power off under normal operation. Press the power button for 2 seconds to power down the Arduino. You will receive the following output. You will also notice that the power LEDs on the SparkFun IoT RedBoard - ESP32 turn off indicating that there is no power.

User is pressing power button. Start timer.
Time to power down!
Pulling OFF high
Arduino Output Soft Power Switch - USB-C Normal Operation Power Down
Arduino Output Soft Power Switch - USB-C Normal Operation Power Down

Note

The power-down time can be tweaked to your own user experience. We found 2s for power-down work really well. If you decide to adjust the power-down time, make sure to not exceed ~10 seconds as the force power down will take into effect.

System Lock and Power Down via Arduino Serial Monitor

Remember the output from earlier? There were additional options to control the Soft Power Switch from the Arduino Serial Monitor. Press down on the power button for 0.5 seconds to enter the normal operation again. You will be presented with two options:

  • r — Sending an r will cause the Arduino to enter an infinite loop to test power-down override. This will lock the system and force the Soft Power Switch to only shutdown when the button is pressed down rather then sending a character to the Arduino to power down. When locking the system, you will need to press the button down for 7 seconds to force the Soft Power Switch to power down. Once the button has been pressed down for 7 seconds, the Soft Power Switch will shut power off at the OUT port.
  • z — Sending a z will power down the Arduino.
Arduino Output Soft Power Switch - USB-C Normal Operation - Power On
Arduino Output Soft Power Switch - USB-C Normal Operation - Power On

Let's send an r to lock the system to force the Soft Power Switch - USB-C to power down. Then press down on the power button for 7 seconds. You will receive the following message indicating that the system is locked. Once the power button is pressed down, an additional message on the next line will be output to indicate that we are waiting for the power override. After 7 seconds, power will be disabled at the OUT port and the IoT RedBoard - ESP32 will turn off.

System locked. Now hold power button to force power down without using software
Doing nothing, waiting for power override to kick in
Arduino Output Soft Power Switch - USB-C Button Override
Arduino Output Soft Power Switch - USB-C Button Override

Note

If the button is released before 7 seconds, you will receive the following message indicating that the forced power down could not be completed when the system is locked. This will break out of the infinite loop and require you to send another r through the serial terminal in order to test the power-down override again.

User released button before forced powered could complete. Try again, but hold power button for 7s

Arduino Output Soft Power Switch - USB-C Unable to Force Power Down
Arduino Output Soft Power Switch - USB-C Unable to Force Power Down