If you use INPUT, the pin is in a high impedance state and can pick up noise from the environment resulting in random HIGH or LOW. You can use an external resistor to pull the pin to a defined level (either GND or Vcc) to prevent that random reading; the input will be LOW or HIGH unless you force it externally to another level. A number of microcontrollers have that pull-up resistor built-in and you can enable that when you use INPUT_PULLUP.
You can have a look at the below image (by @LarryD)

Note
Some microcontrollers also have a built-in pull-down resistor; you will have to consult the datasheet (to save you the time, the AVR microcontrollers like the n328P in the Uno don't).
The code shown by @GoForSmoke demonstrates how it can be done. It might be slightly overwhelming so I have taken your blinkRled() to describe the process.
That function has four steps (LED high, delay, LED low and delay). You can change that to two steps by keeping track of the state of the LED.
void blinkRled(int milliseconds)
{
// remember the state of the LED; initial state HIGH
static uint8_t ledState = HIGH;
// set the LED to the current state
digitalWrite(RLED, ledState);
// change the LED state to the next state
ledState = !ledState;
// wait
delay(milliseconds);
}
This code will behave (nearly) the same as your code but it will now only block for 160ms. The difference is that if you release the switch when the LED is on or off, the LED will stay in that state.
Notes:
- uint8_t is the same as byte; I prefer the former as it will allow a little more consistency in my code as can be seen later.
- The variable ledState is local to the function. Local variables are only known inside the function and they will be lost when the function if finished. Use of the static keyword prevents that the value is lost when the function ends; from that perspective it is like a global variable that you declare outside a function.
In the next step you can get rid of the delay. We add a variable to keep track of the time that the last change happened.
void blinkRled(uint16_t milliseconds)
{
// remember the state of the LED
static uint8_t ledState = HIGH;
// last time that the LED was updated
static uint32_t lastUpdateTime;
...
...
}
Notes:
- All variables related to timing should be unsigned. uint32_t is the same as unsigned long but less typing

- The parameter for the function is now an unsigned 16-bit integer. The main reason to use the uint16_t instead of unsigned int is that the size of an int depends on the architecture; on an 8-bit processor it's 16 bits (two bytes), on a 32-bit processor it's 32 bits (4 bytes); the use of uint16_t (and int16_t) prevents confusion and possibly errors.
- The choice of 8-bit vs 16-bit vs 32-bit variables depends on your needs; if you have limited memory (as in the 328P on the Uno) you should limit the size of the variable to the minimum needed.
If your delay will never exceed 255 milliseconds, you use an uint8_t, if your delay will never exceed 65535 milliseconds you use uint16_t and else you use an uint32_t (good for 49 days and a bit); if you need longer delays, it gets a bit more complicated because the millis() function that we're going to use can only handle the maximum of 49 days and a bit.
And next you use that variable to check if it's time to do something
void blinkRled(uint16_t milliseconds)
{
// remember the state of the LED
static uint8_t ledState = HIGH;
// last time that the LED was updated
static uint32_t lastUpdateTime;
// check if it's time to update the LED
if (millis() - lastUpdateTime >= milliseconds)
{
// set the LED to the current state
digitalWrite(RLED, ledState);
// change the LED state to the next state
ledState = !ledState;
// remember the time that the last update was done
lastUpdateTime = millis();
}
}
This again behaves nearly the same as the previous version but now will immediately react on the switch being released.
- If you press the switch within your 160 milliseconds, the LED will not immediately switch on because millis() is less than 160 ms
- If you release the switch somewhere in a 160 milliseconds period and press it again, the function will initially continue where it was.
You can solve the first problem by adding another variable so the function always will set the first state when initially entered.
void blinkRled(uint16_t milliseconds)
{
// remember the state of the LED
static uint8_t ledState = HIGH;
// last time that the LED was updated
static uint32_t lastUpdateTime;
// flag to idnciate that the we need to execute the first time
static bool isRunning = false;
// check if it's the first time or that it's time to update the LED
if (isRunning == false || millis() - lastUpdateTime >= milliseconds)
{
isRunning = true;
// set the LED to the current state
digitalWrite(RLED, ledState);
// change the LED state to the next state
ledState = !ledState;
// remember the time that the last update was done
lastUpdateTime = millis();
}
}
Up to this point, the other parts of your code can stay unchanged.
The second problem (if it is a problem) can e.g. be solved as shown in @GoForSmoke's code by passing 0 for the milliseconds parameter and resetting the ledState and the isRunning flag.
The below full code demonstrates
#define RLED 13
#define SWITCH 2
// a global variable to remember the switch state
uint8_t switchState;
void setup()
{
pinMode(RLED, OUTPUT);
pinMode(SWITCH, INPUT_PULLUP);
}
void loop()
{
// read the switch
switchState = digitalRead(SWITCH);
// run the pattern
runPattern();
}
/*
Run the pattern
*/
void runPattern()
{
uint16_t redDelayTime;
if (switchState == LOW)
{
redDelayTime = 160;
}
else
{
redDelayTime = 0;
}
blinkRled(redDelayTime);
}
/*
Blink the red LED
In:
on time / off time
*/
void blinkRled(uint16_t milliseconds)
{
// remember the state of the LED
static uint8_t ledState = HIGH;
// last time that the LED was updated
static uint32_t lastUpdateTime;
// flag to idnciate that the we need to execute the first time
static bool isRunning = false;
// if reset instructed
if (milliseconds == 0)
{
// clear the flag so the next time the pattern is immediately started
isRunning = false;
// switch the LED off
digitalWrite(RLED, LOW);
// reset the ledState
ledState = HIGH;
// nothing else to do
return;
}
// check if it's the first time or that it's time to update the LED
if (isRunning == false || millis() - lastUpdateTime >= milliseconds)
{
isRunning = true;
// set the LED to the current state
digitalWrite(RLED, ledState);
// change the LED state to the next state
ledState = !ledState;
// remember the time that the last update was done
lastUpdateTime = millis();
}
}
Note the change in blinkRled() and the use of a global variable for the switch state; the global variable allows you to use that variable in any function. loop() and runPattern() are slightly changed.
Notes on variable scope (do some research on the web):
- Local variables and static local variables can only be changed in that function.
- Global variables can be changed anywhere; which create the risk that you modify them by accident in a function where they are not supposed to be changed.
- The IDE counts global and static local variables to give you the amount of memory used; it does not count local variables. So if you have a lot of local variables in a function you might run out of (RAM) memory. The IDE also does not count dynamically allocated memory (as e.g. used in Adafruits NeoPixel library).