Relays offer the benefit of utilizing durable copper contacts, enabling them to handle high current loads with a relatively low input current. However, since the solenoid in the relay takes some time to actuate the contact, using Pulse Width Modulation (PWM) with a relay is ineffective. The Fast PWM signal is interpreted by the relay as an analog voltage, which may either turn the relay coil on or leave it off, but it doesn't operate as intended. For this reason, it’s generally advised not to use PWM signals for controlling relays. Despite this limitation, relays are highly effective for switching high-power devices with microcontrollers such as Arduino. This includes controlling AC/DC lighting, controlling dc motors, heaters, appliances, and virtually anything that operates on electrical power.
In robotics, relays prove indispensable as they allow both high-power loads to be controlled remotely and electronically. This opens up numerous possibilities for integration in robotic systems. For instance, a relay can serve as an emergency disconnect switch for power on large, remotely controlled robots or as a means to control an electric motor or lighting from a distance.
As previously discussed in earlier tutorial PWM motor speed control, an inductive load can generate a sudden high Back Electromotive Force (Back-EMF) when the solenoid of the relay coil is deactivated. This Back-EMF can potentially damage electronic components unless they are protected by a current-rectifying diode, such as the 1N4004 used in this setup. The diode is connected across the relay coil to protect the Arduino’s output pin from any damaging voltage spikes. This is illustrated by the circuit diagram below.
Although the relay in the example can be activated directly by the Arduino’s output current, many power relays require more than the 40mA available from an Arduino pin to operate properly. In such cases, a signal interface, typically in the form of a solid-state (electronic) transistor switch, is necessary to provide the additional current needed to activate the relay coil.
Programming Arduino with Relay
The following code monitors the push button connected to pin 2 of Arduino and depending on the state of the button, whether low or high, the relay is switched on and off on consecutive button presses.
const int relayPin = 9; // Pin connected to the relay
const int buttonPin = 2; // Pin connected to the momentary button
int relayState = LOW; // Track relay state (OFF by default)
int lastButtonState = HIGH; // Last button state for debouncing
int currentButtonState; // Current debounced button state
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50; // Debounce delay in milliseconds
void setup() {
pinMode(relayPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
digitalWrite(relayPin, relayState);
Serial.begin(9600);
Serial.println("Program started");
}
void loop() {
int reading = digitalRead(buttonPin);
// Reset the debouncing timer if the button state changed
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
// Check if button state is stable
if ((millis() - lastDebounceTime) > debounceDelay) {
// If the button state has changed:
if (reading != currentButtonState) {
currentButtonState = reading;
// Only toggle the relay if the new button state is LOW (pressed)
if (currentButtonState == LOW) {
relayState = !relayState;
digitalWrite(relayPin, relayState);
Serial.print("Relay State: ");
Serial.println(relayState ? "ON" : "OFF");
}
}
}
lastButtonState = reading;
delay(10); // Small delay to stabilize readings
}
This Arduino code is designed to control a relay using a momentary button. It includes debouncing logic to ensure the button press is stable before triggering any action.
Step-by-Step Explanation
1. Read Button State:
int reading = digitalRead(buttonPin);
- Reads the current state of the button pin (`HIGH` or `LOW`).
2. Reset Debouncing Timer:
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
- If the button state changes (`reading` is different from `lastButtonState`), the debouncing timer is reset to the current time (`millis()`). This ensures that the button state must remain stable for at least `debounceDelay` milliseconds before being considered valid.
3. Check Stability of Button State:
if ((millis() - lastDebounceTime) > debounceDelay) {
- Checks if the button state has remained stable for longer than the debounce delay (50 ms). If so, the state is considered valid.
4. Update Button State:
if (reading != currentButtonState) {
currentButtonState = reading;
- If the current reading differs from the `currentButtonState`, update `currentButtonState` to reflect the new stable state.
5. Toggle Relay on Button Press:
if (currentButtonState == LOW) {
relayState = !relayState;
digitalWrite(relayPin, relayState);
Serial.print("Relay State: ");
Serial.println(relayState ? "ON" : "OFF");
}
- If the button is pressed (`currentButtonState == LOW`), toggle the relay state (`relayState = !relayState`) and update the relay pin accordingly.
- A message is printed to the serial monitor indicating the new relay state.
6. Update Last Button State:
lastButtonState = reading;
- Updates `lastButtonState` to the current reading for use in the next iteration.
7. mall Delay:
delay(10);
- Adds a small delay to stabilize readings and prevent excessive CPU usage.
Key Features of the Code
1. Debouncing:
- The code uses a debouncing mechanism to filter out noise caused by mechanical switches. The button state must remain stable for at least 50 ms before being considered valid.
2. Relay Toggling:
- Each time the button is pressed, the relay toggles between `ON` and `OFF`.
3. Pull-Up Resistor:
- The button uses an internal pull-up resistor, simplifying the circuit design.
4. Serial Debugging:
- The code prints debug messages to the serial monitor, making it easier to track the relay's state during operation.
How It Works in Practice
1. When the program starts, the relay is initially off (`LOW`).
2. Pressing the button triggers the following sequence:
- The button state is read and debounced.
- Once the button press is validated, the relay toggles its state (`ON` → `OFF` or `OFF` → `ON`).
3. The relay state is logged to the serial monitor for debugging purposes.
Watch the following video demonstration of how it works.
Final Notes