Arduino UNO Q - 4-Channel Relay Module

Do you want one board to run a lamp, a fan, a pump and a heater, and switch each of them from your phone? A 4-channel relay module makes that possible. On the Arduino UNO Q, the STM32 MCU drives the four relay inputs, while the Linux side talks to the internet and passes your Telegram commands down to the MCU.

In this tutorial, you will learn:

Arduino UNO Q 4-Channel Relay Module

WARNING

The relay contacts can carry mains voltage, and a mistake there can give a deadly shock. Only work on mains wiring if you really know how to do it safely, or ask a trained person for help. For your first tests, switch low-voltage DC loads (24V or less).

Why one 4-channel board and not four single relays? It takes up less room, it is usually cheaper, and you run fewer wires. The code does not change at all: every relay still has its own control pin.

Hardware Preparation

1×Arduino UNO Q
1×USB Cable for Arduino Uno Q
1×4-channel Relay Module
1×5V Power Adapter
1×Jumper Wires
1×Recommended: Screw Terminal Block Shield for Arduino Uno
1×Recommended: Sensors/Servo Expansion Shield for Arduino Uno
1×Recommended: Breadboard Shield for Arduino Uno
1×Recommended: Enclosure for Arduino Uno
1×Recommended: Prototyping Base Plate & Breadboard Kit for Arduino UNO

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of 4-Channel Relay Module

Think of the module as four switches that your code flips. The pins come in three groups, and each group has one job.

Pinout

4-Channel Relay Module Pinout
Group Pins Job in your project
Power DC+, DC- Feed the four relay coils. DC+ goes to an external 5V supply, DC- to its GND
Signal IN1, IN2, IN3, IN4 One input per relay. The Arduino UNO Q MCU sets each one HIGH or LOW
Output COMx, NOx, NCx (x = 1 to 4) The switch side of each relay, where your load is wired
Trigger jumpers 4 jumpers Choose high-level or low-level trigger for each relay

Power pins

The coils need real current, so they get their own 5V source. The DC- pin must also be joined to a GND pin of the Arduino UNO Q. Without that common ground, the MCU signal has no reference and the relays act at random.

Signal pins

IN1 drives relay 1, IN2 drives relay 2, and so on up to IN4. The MCU pins on the UNO Q output 3.3V for HIGH. Most of these modules use optocoupler inputs that switch fine at 3.3V. If a relay does not react, test it with the trigger jumper set to the other level.

Output pins

Every relay has three screw terminals:

  • COMx (common): one wire of your load circuit always goes here.
  • NOx (normally open): connected to COM only while the relay is active. Use it for a device that should stay off by default, such as a pump.
  • NCx (normally closed): connected to COM while the relay is idle. Use it for a device that should keep running if the board loses power.

Trigger jumpers

With high-level trigger, a HIGH on INx makes the relay pull in. With low-level trigger, the logic is reversed. The code in this tutorial expects high-level trigger, so set all four jumpers that way.

Never used a single relay before? The Arduino UNO Q - Relay tutorial shows how to hook up a load and explains the difference between normally closed and normally open in more detail.

Wiring Diagram

Four coils together pull more current than the board's 5V pin should give, so the relay module gets its own 5V adapter. The MCU only sends 3.3V control signals on D2 to D5.

You work with three power sources here:

  • The USB-C cable (or another supply) that powers the Arduino UNO Q. It is not drawn in the image.
  • A 5V adapter just for the relay coils.
  • The supply of your loads (for example 12VDC, 24VDC or 220VAC).
The wiring diagram between Arduino UNO Q 4-channel relay module

This image is created using Fritzing. Click to enlarge image

Relay Module Pin Arduino UNO Q
DC+ 5V of the relay adapter (not the board)
DC- GND of the relay adapter and GND of the Arduino UNO Q
IN1 Pin 2
IN2 Pin 3
IN3 Pin 4
IN4 Pin 5

※ NOTE THAT:

On the load side, one adapter is enough when all four devices run on the same voltage. A 12V fan and a 24V valve, for example, each need a supply of their own.

How To Program For 4-Channel Relay Module

A relay input behaves like an LED pin: the MCU just writes HIGH or LOW to it.

  • In setup(), make the four relay pins outputs with pinMode():
pinMode(PIN_RELAY_1, OUTPUT); pinMode(PIN_RELAY_2, OUTPUT); pinMode(PIN_RELAY_3, OUTPUT); pinMode(PIN_RELAY_4, OUTPUT);
  • Activate a relay by writing HIGH with digitalWrite(). Here relay 3 pulls in:
digitalWrite(PIN_RELAY_3, HIGH);
  • Release it again with LOW. The other three relays keep their state:
digitalWrite(PIN_RELAY_3, LOW);

Arduino UNO Q Code

The Arduino UNO Q has two processors:

  • The STM32 MCU sets the four relay pins. Switching is simple, real-time hardware work, so it belongs here
  • The Qualcomm MPU runs Debian Linux with Wi-Fi and Python
  • In this first step, only the MCU runs code. The Bridge section later lets Linux take over the control

The sketch below is a quick wiring test. It pulls in all four relays, waits one second, drops them, waits again, and prints every step to the console.

/* * This Arduino UNO Q code was developed by newbiely.com * * This Arduino UNO Q code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-4-channel-relay-module */ // Arduino UNO Q - 4-Channel Relay Module: switch all four relays on and off every second // Wiring: IN1 -> D2, IN2 -> D3, IN3 -> D4, IN4 -> D5, DC+ -> external 5V, DC- -> external GND and Arduino UNO Q GND // The MCU pins give 3.3V logic. The relay coils get their power from the external 5V supply. #define PIN_RELAY_1 2 // The Arduino UNO Q pin connected to the IN1 pin of relay module #define PIN_RELAY_2 3 // The Arduino UNO Q pin connected to the IN2 pin of relay module #define PIN_RELAY_3 4 // The Arduino UNO Q pin connected to the IN3 pin of relay module #define PIN_RELAY_4 5 // The Arduino UNO Q pin connected to the IN4 pin of relay module // The setup function runs once on reset or power-up void setup() { Serial.begin(115200); delay(1500); // initialize digital pin as an output. pinMode(PIN_RELAY_1, OUTPUT); pinMode(PIN_RELAY_2, OUTPUT); pinMode(PIN_RELAY_3, OUTPUT); pinMode(PIN_RELAY_4, OUTPUT); } // The loop function repeats indefinitely void loop() { Serial.println("Turn on all"); digitalWrite(PIN_RELAY_1, HIGH); digitalWrite(PIN_RELAY_2, HIGH); digitalWrite(PIN_RELAY_3, HIGH); digitalWrite(PIN_RELAY_4, HIGH); delay(1000); Serial.println("Turn off all"); digitalWrite(PIN_RELAY_1, LOW); digitalWrite(PIN_RELAY_2, LOW); digitalWrite(PIN_RELAY_3, LOW); digitalWrite(PIN_RELAY_4, LOW); delay(1000); }

Detailed Instructions

First time with Arduino UNO Q? Read Getting Started with Arduino UNO Q first.

  • Wire: Follow the wiring diagram. Leave the high-voltage side unconnected for this test.
  • Connect: Plug the Arduino UNO Q into your computer with the USB-C cable.
  • Open Arduino App Lab: Wait until it finds your Arduino UNO Q.
  • Create a new App: Click the Create New App button.
Create New App in Arduino App Lab on Arduino UNO Q
  • Name it, for example FourRelayTest, and click Create.
Arduino App Lab App folders and files on Arduino UNO Q
  • Paste the sketch: Copy the code above into sketch/sketch.ino. Keep the other files as they are. No library is needed.
  • Run: Click the Run button.
Click Run button in Arduino App Lab on Arduino UNO Q
  • Test it: Every second you should hear four clicks at once, and the four small LEDs on the module should blink together.

App Lab Console Output

DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
Message (Enter to send a message to "Newbiely" on usb(2820070321))
New Line
9600 baud
[2026-10-20 09:00:02] Turn on all [2026-10-20 09:00:03] Turn off all [2026-10-20 09:00:04] Turn on all [2026-10-20 09:00:05] Turn off all [2026-10-20 09:00:06] Turn on all [2026-10-20 09:00:07] Turn off all

The two lines take turns once per second. If only some relays click, one of the IN wires sits on the wrong pin or is loose. If they work in reverse (on when the console says off), move the trigger jumpers to high-level trigger.

Bridge: Linux + MCU

Now the Linux side gives the orders, and the MCU still does the switching:

  • The relay module is wired to the MCU on D2 to D5. The MPU has no direct access to those pins
  • The MCU offers relay_on and relay_off (each takes a channel number from 1 to 4), plus all_on and all_off, all registered with Bridge.provide_safe() because they write to pins
  • It also offers get_states with Bridge.provide(). This returns the saved states as four characters, for example 1010, and never touches a pin
  • Python calls these with Bridge.call(), for example Bridge.call("relay_on", 2)
  • ⚠️ /dev/ttyHS1 (Linux) and Serial1 (MCU) are RESERVED by the router — never open them in your code

In short: Python picks a channel → MCU writes the matching pin → that relay switches its load.

MCU Code (Bridge)

/* * This Arduino UNO Q code was developed by newbiely.com * * This Arduino UNO Q code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-4-channel-relay-module */ // Arduino UNO Q - 4-Channel Relay Module controlled from Linux via Bridge // The MCU owns the four relay pins. Linux (Python) only calls the functions below. // Wiring: IN1 -> D2, IN2 -> D3, IN3 -> D4, IN4 -> D5, DC+ -> external 5V, DC- -> external GND and Arduino UNO Q GND #include "Arduino_RouterBridge.h" #define PIN_RELAY_1 2 // D2 -> IN1 #define PIN_RELAY_2 3 // D3 -> IN2 #define PIN_RELAY_3 4 // D4 -> IN3 #define PIN_RELAY_4 5 // D5 -> IN4 const int RELAY_PINS[4] = {PIN_RELAY_1, PIN_RELAY_2, PIN_RELAY_3, PIN_RELAY_4}; int relay_state[4] = {LOW, LOW, LOW, LOW}; // latest state of each relay void setRelay(int channel, int state) { if (channel < 1 || channel > 4) { Monitor.println("Unknown relay channel: " + String(channel)); return; } relay_state[channel - 1] = state; digitalWrite(RELAY_PINS[channel - 1], state); Monitor.println("Relay " + String(channel) + ": " + (state == HIGH ? "ON" : "OFF")); } // channel: 1..4 void relay_on(int channel) { setRelay(channel, HIGH); } void relay_off(int channel) { setRelay(channel, LOW); } void all_on() { for (int i = 0; i < 4; i++) { relay_state[i] = HIGH; digitalWrite(RELAY_PINS[i], HIGH); } Monitor.println("All relays: ON"); } void all_off() { for (int i = 0; i < 4; i++) { relay_state[i] = LOW; digitalWrite(RELAY_PINS[i], LOW); } Monitor.println("All relays: OFF"); } // Read-only callback: returns the saved states as 4 characters, e.g. "1010" String get_states(String arg) { String states = ""; for (int i = 0; i < 4; i++) { states += (relay_state[i] == HIGH) ? "1" : "0"; } return states; } void setup() { Bridge.begin(); Monitor.begin(); for (int i = 0; i < 4; i++) { pinMode(RELAY_PINS[i], OUTPUT); digitalWrite(RELAY_PINS[i], LOW); // start with every relay off } // These functions touch hardware pins, so they are registered with provide_safe Bridge.provide_safe("relay_on", relay_on); Bridge.provide_safe("relay_off", relay_off); Bridge.provide_safe("all_on", all_on); Bridge.provide_safe("all_off", all_off); Bridge.provide("get_states", get_states); Monitor.println("Arduino UNO Q 4-Channel Relay Bridge ready"); } void loop() {}

Python Code (Bridge)

The Python script plays a small light show: it turns relays 1 to 4 on one by one, then off in the reverse order, reads back the states, and finally switches all four together.

""" This Arduino UNO Q script was developed by newbiely.com This Arduino UNO Q script is made available for public use without any restriction For comprehensive instructions and wiring diagrams, please visit: https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-4-channel-relay-module """ from arduino.app_utils import * import time # Linux side: run a short demo on the 4-channel relay module through Bridge def show_states(): states = str(Bridge.call("get_states")) print(f"States (relay 1-4): {states}") def loop(): # Switch the relays one after another, like a chaser for channel in range(1, 5): print(f"Relay {channel}: ON") Bridge.call("relay_on", channel) time.sleep(1) show_states() for channel in range(4, 0, -1): print(f"Relay {channel}: OFF") Bridge.call("relay_off", channel) time.sleep(1) show_states() print("All relays: ON") Bridge.call("all_on") time.sleep(2) print("All relays: OFF") Bridge.call("all_off") time.sleep(2) App.run(user_loop=loop)

Detailed Instructions

  • Create a new App: In Arduino App Lab click Create New App, name it FourRelayBridge, and click Create.
  • Paste the MCU sketch into sketch/sketch.ino, and add the library:
  • Install the library: Click the Add sketch library button (the open book icon with a + sign) in the left sidebar.
Add sketch library in Arduino App Lab on Arduino UNO Q
  • Search for Arduino_RouterBridge created by Arduino and click the Install button.
My Apps / DIYables Apps
Run
Bricks
No bricks added...
Sketch Libraries
No sketch libra...
Files
python
sketch
.gitignore
README.md
app.yaml
sketch.ino
Add sketch library
Arduino_RouterBridge Arduino

This library provides a simple RPC bridge for Arduino UNO Q boards, allowing communication between the board and other devices using MsgPack serialization.

0.4.1
Install
More Info
  • Paste the Python code into the Python file of the same App.
  • Run: Click the Run button. The relays pull in one after another, then drop out from relay 4 back to relay 1.
  • Check both consoles: The MCU Monitor shows what each pin did. The Python console shows what Linux asked for.

App Lab Console Output

DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
Message (Enter to send a message to "Newbiely" on usb(2820070321))
New Line
9600 baud
[2026-10-20 10:15:00] Arduino UNO Q 4-Channel Relay Bridge ready [2026-10-20 10:15:02] Relay 1: ON [2026-10-20 10:15:03] Relay 2: ON [2026-10-20 10:15:04] Relay 3: ON [2026-10-20 10:15:05] Relay 4: ON [2026-10-20 10:15:06] Relay 4: OFF [2026-10-20 10:15:07] Relay 3: OFF [2026-10-20 10:15:08] Relay 2: OFF [2026-10-20 10:15:09] Relay 1: OFF [2026-10-20 10:15:10] All relays: ON [2026-10-20 10:15:12] All relays: OFF
DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
[2026-10-20 10:15:02] Relay 1: ON [2026-10-20 10:15:03] Relay 2: ON [2026-10-20 10:15:04] Relay 3: ON [2026-10-20 10:15:05] Relay 4: ON [2026-10-20 10:15:06] States (relay 1-4): 1111 [2026-10-20 10:15:06] Relay 4: OFF [2026-10-20 10:15:07] Relay 3: OFF [2026-10-20 10:15:08] Relay 2: OFF [2026-10-20 10:15:09] Relay 1: OFF [2026-10-20 10:15:10] States (relay 1-4): 0000 [2026-10-20 10:15:10] All relays: ON [2026-10-20 10:15:12] All relays: OFF

Telegram

Four relays often means four rooms or four machines. With a bot, you can turn on the porch lamp on your way home, or check that the heater is really off after you left. Each relay gets a friendly name in the script, so the replies say "Fan" instead of "relay 2". The bot only obeys your own chat ID, so a stranger who finds your bot cannot switch your devices.

MCU sketch: Keep the same MCU sketch from the Bridge section.

Python Code (Telegram)

""" This Arduino UNO Q script was developed by newbiely.com This Arduino UNO Q script is made available for public use without any restriction For comprehensive instructions and wiring diagrams, please visit: https://newbiely.com/tutorials/arduino-uno-q/arduino-uno-q-4-channel-relay-module """ from arduino.app_utils import * import requests import time TELEGRAM_BOT_TOKEN = "YOUR_TELEGRAM_BOT_TOKEN" CHAT_ID = "YOUR_CHAT_ID" # only this chat may switch the relays API_URL = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}" # Give each relay a name that fits your project RELAY_NAMES = {1: "Lamp", 2: "Fan", 3: "Pump", 4: "Heater"} HELP_TEXT = ( "Arduino UNO Q 4-Channel Relay Bot\n" "/on 1-4 - turn one relay on (example: /on 2)\n" "/off 1-4 - turn one relay off (example: /off 2)\n" "/allon - turn all relays on\n" "/alloff - turn all relays off\n" "/status - show the state of every relay" ) last_update_id = 0 def get_updates(): try: resp = requests.get(f"{API_URL}/getUpdates", params={"offset": last_update_id + 1, "timeout": 5}, timeout=10) data = resp.json() if data.get("ok"): return data["result"] except Exception as e: print(f"Error getting updates: {e}") return [] def send_message(chat_id, text): try: requests.post(f"{API_URL}/sendMessage", data={"chat_id": chat_id, "text": text}, timeout=10) except Exception as e: print(f"Error sending message: {e}") def status_text(): states = str(Bridge.call("get_states")) lines = [] for channel in range(1, 5): is_on = len(states) >= channel and states[channel - 1] == "1" lines.append(f"Relay {channel} ({RELAY_NAMES[channel]}): {'ON' if is_on else 'OFF'}") return "\n".join(lines) def read_channel(parts): # Returns 1..4, or None if the command has no valid channel number if len(parts) == 2 and parts[1].isdigit() and 1 <= int(parts[1]) <= 4: return int(parts[1]) return None def loop(): global last_update_id for update in get_updates(): last_update_id = update["update_id"] if "message" not in update: continue chat_id = update["message"]["chat"]["id"] text = update["message"].get("text", "").strip() print(f"Received: {text}") if str(chat_id) != str(CHAT_ID): send_message(chat_id, "Sorry, this bot only takes orders from its owner.") continue parts = text.split() command = parts[0] if parts else "" if command in ("/on", "/off"): channel = read_channel(parts) if channel is None: send_message(chat_id, f"Usage: {command} 1-4 (example: {command} 3)") continue if command == "/on": Bridge.call("relay_on", channel) send_message(chat_id, f"Relay {channel} ({RELAY_NAMES[channel]}) is ON.") else: Bridge.call("relay_off", channel) send_message(chat_id, f"Relay {channel} ({RELAY_NAMES[channel]}) is OFF.") elif command == "/allon": Bridge.call("all_on") send_message(chat_id, "All 4 relays are ON.") elif command == "/alloff": Bridge.call("all_off") send_message(chat_id, "All 4 relays are OFF.") elif command == "/status": send_message(chat_id, status_text()) else: send_message(chat_id, HELP_TEXT) time.sleep(1) App.run(user_loop=loop)

Detailed Instructions

  • Replace YOUR_TELEGRAM_BOT_TOKEN with the token that BotFather gives you. No bot yet? Follow How to Create a Telegram Bot.
  • Replace YOUR_CHAT_ID with your own Telegram chat ID. Messages from any other chat are refused.
  • Change the names in RELAY_NAMES to match what you wired to each relay.
  • Paste the code into the Python file of your App (keep the Bridge MCU sketch), then click Run.
  • Send /status to your bot, then try /on 2 and /alloff.

App Lab Console Output

DIYables_Apps
Stop
sketch.ino
1#include "Arduino_RouterBridge.h"
Serial Monitor
Python
[2026-10-20 18:42:05] Received: /status [2026-10-20 18:42:20] Received: /on 1 [2026-10-20 18:42:31] Received: /on 3 [2026-10-20 18:43:10] Received: /off 1 [2026-10-20 18:44:02] Received: /alloff
Telegram
Telegram 12:45
Welcome to Telegram!
ArduinoBot 10:19
Chatting with Arduino...
telegram-botfather
BotFather Yesterday
Your bot has been created.

ArduinoBot

bot
Today
/status
10:15 AM ✓✓
Relay 1 (Lamp): OFF Relay 2 (Fan): OFF Relay 3 (Pump): OFF Relay 4 (Heater): OFF
10:16 AM
/on 1
10:17 AM ✓✓
Relay 1 (Lamp) is ON.
10:18 AM
/on 3
10:19 AM ✓✓
Relay 3 (Pump) is ON.
10:20 AM
/off 1
10:21 AM ✓✓
Relay 1 (Lamp) is OFF.
10:22 AM
/alloff
10:23 AM ✓✓
All 4 relays are OFF.
10:24 AM

OpenClaw

You can adapt the OpenClaw to this tutorial by refering the instruction on Arduino Uno Q - OpenClaw Tutorial

Project Ideas

Here are some builds where the MCU handles the relays and Linux handles the brains:

  • Four-Zone Garden Watering: One valve per relay. Python checks the weather forecast online and skips watering on rainy days
  • Smart Room Panel: Lamp, fan, heater and night light on the four channels, with a Telegram command for each and a schedule kept in Python
  • Aquarium Controller: Light, filter, air pump and heater, where Linux logs every switch to a file so you can see the daily pattern
  • Tutorial Power Guard: Each tool socket gets a relay, and a Telegram /alloff cuts every tool at once when you leave
  • Holiday Presence Simulator: Python switches lamps in different rooms at random times in the evening, so the house looks lived in

Challenge Yourself

Try these to get more out of the four channels:

  • Easy: Change the test sketch so the relays switch one after another (a chaser) instead of all at once.
  • Medium: Add a /toggle 1-4 Telegram command that reads get_states and flips just that relay.
  • Advanced: Add a timer command such as /on 3 10 that turns the pump on for 10 minutes and then switches it off by itself, even if you forget.

Function References

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!