Arduino UNO Q - Traffic Light

In this tutorial, you will learn how to control a traffic light module using Arduino UNO Q. We will cover multiple coding approaches — from a simple delay()-based sequence to a non-blocking millis() version — and then extend the project to allow remote control of light timing via Telegram.

In this tutorial, you will learn:

Arduino UNO Q - Traffic Light

Hardware Preparation

1×Arduino UNO Q
1×USB Cable for Arduino Uno Q
1×Traffic Light Module
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 Traffic Light Module

Pinout

A traffic light module has 4 pins:

  • GND pin: Connect to GND on the Arduino UNO Q
  • R pin: Controls the red light — connect to a digital output
  • Y pin: Controls the yellow light — connect to a digital output
  • G pin: Controls the green light — connect to a digital output
Traffic Light Pinout

Wiring Diagram

The wiring diagram between Arduino UNO Q Traffic Light

This image is created using Fritzing. Click to enlarge image

How To Program a Traffic Light Module

Set the signal pins as digital outputs:

pinMode(PIN_RED, OUTPUT); pinMode(PIN_YELLOW, OUTPUT); pinMode(PIN_GREEN, OUTPUT);

Activate the red light:

digitalWrite(PIN_RED, HIGH); // turn RED on digitalWrite(PIN_YELLOW, LOW); // turn YELLOW off digitalWrite(PIN_GREEN, LOW); // turn GREEN off delay(RED_TIME); // hold RED for the defined duration

MCU Code — Traffic Light (basic)

The Arduino UNO Q has two processors: the STM32 MCU (handles real-time hardware control) and the Qualcomm MPU (runs Debian Linux). In this section, only the STM32 MCU is programmed — the Linux side stays idle. A later section will show how both processors work together.

This example cycles through red, yellow, and green using delay():

/* * 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-traffic-light */ #define PIN_RED 2 // The Arduino UNO Q pin connected to R pin of traffic light module #define PIN_YELLOW 3 // The Arduino UNO Q pin connected to Y pin of traffic light module #define PIN_GREEN 4 // The Arduino UNO Q pin connected to G pin of traffic light module #define RED_TIME 4000 // RED time in millisecond #define YELLOW_TIME 4000 // YELLOW time in millisecond #define GREEN_TIME 4000 // GREEN time in millisecond void setup() { pinMode(PIN_RED, OUTPUT); pinMode(PIN_YELLOW, OUTPUT); pinMode(PIN_GREEN, OUTPUT); } // the loop function runs over and over again forever void loop() { // red light on digitalWrite(PIN_RED, HIGH); // turn on digitalWrite(PIN_YELLOW, LOW); // turn off digitalWrite(PIN_GREEN, LOW); // turn off delay(RED_TIME); // keep red light on during a period of time // yellow light on digitalWrite(PIN_RED, LOW); // turn off digitalWrite(PIN_YELLOW, HIGH); // turn on digitalWrite(PIN_GREEN, LOW); // turn off delay(YELLOW_TIME); // keep yellow light on during a period of time // green light on digitalWrite(PIN_RED, LOW); // turn off digitalWrite(PIN_YELLOW, LOW); // turn off digitalWrite(PIN_GREEN, HIGH); // turn on delay(GREEN_TIME); // keep green light on during a period of time }

Detailed Instructions

  • First time with Arduino UNO Q? Follow the Getting Started with Arduino UNO Q tutorial to get your development environment ready before proceeding.
  • Wire the module: Connect the traffic light module to pins 2, 3, and 4 according to the wiring diagram.
  • Connect: Plug the Arduino UNO Q into your computer with a USB-C cable.
  • Open Arduino App Lab: Launch Arduino App Lab and wait until it detects 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
  • Give the App a name, for example: DIYables_TrafficLight
  • Click Create to confirm.
  • You will see a set of folders and files generated inside your new App.
Arduino App Lab App folders and files on Arduino UNO Q
  • Find the sketch/sketch.ino file — this is where you will paste the MCU sketch.
  • Paste the sketch: Copy the MCU code above and paste it into the sketch file. Keep other files as default.
    • 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
    • Upload: Click the Run button in Arduino App Lab to compile and upload to the STM32.
    Click Run button in Arduino App Lab on Arduino UNO Q
    • Check the module: The traffic light module should cycle: red → yellow → green → red, repeating.
    • Pro Tip: Traffic light timing varies by location and intersection design. Adjust RED_TIME, YELLOW_TIME, and GREEN_TIME values to match the behavior you want.

    MCU Code — Cleaner Version with a Function

    Using a helper function makes the code shorter and easier to manage:

    /* * 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-traffic-light */ #define PIN_RED 2 // The Arduino UNO Q pin connected to R pin of traffic light module #define PIN_YELLOW 3 // The Arduino UNO Q pin connected to Y pin of traffic light module #define PIN_GREEN 4 // The Arduino UNO Q pin connected to G pin of traffic light module #define RED_TIME 2000 // RED time in millisecond #define YELLOW_TIME 1000 // YELLOW time in millisecond #define GREEN_TIME 2000 // GREEN time in millisecond #define RED 0 // Index in array #define YELLOW 1 // Index in array #define GREEN 2 // Index in array const int pins[] = { PIN_RED, PIN_YELLOW, PIN_GREEN }; const int times[] = { RED_TIME, YELLOW_TIME, GREEN_TIME }; void setup() { pinMode(PIN_RED, OUTPUT); pinMode(PIN_YELLOW, OUTPUT); pinMode(PIN_GREEN, OUTPUT); } // the loop function runs over and over again forever void loop() { trafic_light_on(RED); delay(times[RED]); // keep red light on during a period of time trafic_light_on(YELLOW); delay(times[YELLOW]); // keep yellow light on during a period of time trafic_light_on(GREEN); delay(times[GREEN]); // keep green light on during a period of time } void trafic_light_on(int light) { for (int i = RED; i <= GREEN; i++) { if (i == light) digitalWrite(pins[i], HIGH); // turn on else digitalWrite(pins[i], LOW); // turn off } }
    • Pro Tip: The trafic_light_on(int light) function turns on exactly one light and turns the others off — clean and reusable.

    MCU Code — Non-Blocking Version with millis()

    The delay() function blocks all other code while it waits. For responsive programs (e.g., reading buttons or sensors while the traffic light runs), use millis() instead:

    /* * 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-traffic-light */ #define PIN_RED 2 // The Arduino UNO Q pin connected to R pin of traffic light module #define PIN_YELLOW 3 // The Arduino UNO Q pin connected to Y pin of traffic light module #define PIN_GREEN 4 // The Arduino UNO Q pin connected to G pin of traffic light module #define RED 0 // Index in array #define YELLOW 1 // Index in array #define GREEN 2 // Index in array const int pins[] = { PIN_RED, PIN_YELLOW, PIN_GREEN }; int times[] = { 2000, 1000, 2000 }; // RED, YELLOW, GREEN durations in ms unsigned long last_time = 0; int light = RED; // start with RED light void setup() { pinMode(PIN_RED, OUTPUT); pinMode(PIN_YELLOW, OUTPUT); pinMode(PIN_GREEN, OUTPUT); trafic_light_on(light); last_time = millis(); } void loop() { if ((millis() - last_time) > (unsigned long)times[light]) { light++; if (light >= 3) light = RED; // new cycle trafic_light_on(light); last_time = millis(); } // TO DO: your other code here } void trafic_light_on(int light) { for (int i = RED; i <= GREEN; i++) { if (i == light) digitalWrite(pins[i], HIGH); // turn on else digitalWrite(pins[i], LOW); // turn off } }
    • Pro Tip: With millis(), you can add button or sensor code in loop() alongside the traffic light logic — they run concurrently without blocking each other.

    Linux + MCU Bridge Programming

    The Arduino UNO Q has two processors that work together: the MPU (Qualcomm, runs Debian Linux) and the MCU (STM32, runs Zephyr OS with your Arduino sketch). They communicate using RPC via the Arduino_RouterBridge library — never via raw serial ports.

    • The traffic light module is connected to the MCU (STM32) — wired to digital output pins on the STM32. The MCU cycles through the lights using non-blocking millis() timing.
    • The MPU cannot control the lights directly — it must send commands to the MCU via Bridge.call(). The MCU executes the registered Bridge.provide() functions.
    • The MPU has Wi-Fi — because the MPU runs full Debian Linux with Wi-Fi, it can receive Telegram commands and remotely update the light durations.
    • Communication: Bridge.call() on the Linux side invokes Bridge.provide() functions on the MCU side
    • ⚠️ Reserved: /dev/ttyHS1 (Linux) and Serial1 (MCU) are used by the Arduino Router — never open them directly

    In short: MPU sends timing commands → MCU receives them → MCU updates light durations in real time.

    MCU sketch — traffic light with Bridge timing control:

    /* * 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-traffic-light */ #include "Arduino_RouterBridge.h" #define PIN_RED 2 #define PIN_YELLOW 3 #define PIN_GREEN 4 #define RED 0 #define YELLOW 1 #define GREEN 2 const int pins[] = { PIN_RED, PIN_YELLOW, PIN_GREEN }; int times[] = { 2000, 1000, 2000 }; // RED, YELLOW, GREEN durations in ms unsigned long last_time = 0; int current_light = RED; const char* light_names[] = { "RED", "YELLOW", "GREEN" }; void trafic_light_on(int light) { for (int i = RED; i <= GREEN; i++) { if (i == light) digitalWrite(pins[i], HIGH); else digitalWrite(pins[i], LOW); } Monitor.println("Light changed to: " + String(light_names[light])); } void set_timing(int red_ms, int yellow_ms, int green_ms) { times[RED] = red_ms; times[YELLOW] = yellow_ms; times[GREEN] = green_ms; Monitor.println("Timings updated: RED=" + String(red_ms) + "ms, YELLOW=" + String(yellow_ms) + "ms, GREEN=" + String(green_ms) + "ms"); } void get_status() { Monitor.println("Current light: " + String(light_names[current_light])); } void setup() { pinMode(PIN_RED, OUTPUT); pinMode(PIN_YELLOW, OUTPUT); pinMode(PIN_GREEN, OUTPUT); Bridge.begin(); Monitor.begin(); Bridge.provide("set_timing", set_timing); Bridge.provide("get_status", get_status); trafic_light_on(current_light); last_time = millis(); Monitor.println("Traffic Light Bridge ready"); } void loop() { if ((millis() - last_time) > (unsigned long)times[current_light]) { current_light++; if (current_light >= 3) current_light = RED; trafic_light_on(current_light); last_time = millis(); } }

    Python script (Arduino App Lab) — control light timing from Linux:

    /* * 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-traffic-light */ from arduino.app_utils import * import time def loop(): print("Setting normal timing: RED=3s, YELLOW=1s, GREEN=3s") Bridge.call("set_timing", 3000, 1000, 3000) time.sleep(10) print("Setting fast timing: RED=1s, YELLOW=0.5s, GREEN=1s") Bridge.call("set_timing", 1000, 500, 1000) time.sleep(8) print("Restoring default timing: RED=2s, YELLOW=1s, GREEN=2s") Bridge.call("set_timing", 2000, 1000, 2000) App.run(user_loop=loop)
    • Note: Make sure Bridge.begin() is called in the MCU sketch and the sketch is uploaded before running the Python script on the Linux side.
    • ⚠️ Warning: Never directly open /dev/ttyHS1 (on Linux) or use Serial1 (on MCU) in your code — these are reserved by the Arduino Router and accessing them will break the Bridge.

    Detailed Instructions

    • Upload the MCU sketch: Open Arduino App Lab, create a new App, paste the Bridge MCU sketch above into sketch/sketch.ino, keep the default libraries (no additional library needed), and click Run.
    • Add the Python script: Paste the Python code above into the Python tab of the same App.
    • Run the App: Click Run — the Python side adjusts the traffic light timing automatically.
    • Check the console: Open the Console tab → Python Console subtab to see the timing updates.
    • Pro Tip: Modify the Python script to change timings based on a schedule (e.g., shorter cycle at night).

    App Lab Console Output

    DIYables_Apps
    Stop
    sketch.ino
    1#include "Arduino_RouterBridge.h"
    Serial Monitor
    Python
    Setting normal timing: RED=3s, YELLOW=1s, GREEN=3s Setting fast timing: RED=1s, YELLOW=0.5s, GREEN=1s Restoring default timing: RED=2s, YELLOW=1s, GREEN=2s

    Telegram Integration

    You can adjust the traffic light timing remotely over Telegram — change how long each light stays on from anywhere.

    If you do not have a Telegram bot yet, see How to Create a Telegram Bot to get your bot token before continuing.

    This section covers:

    • Running a Python script on the Linux side of Arduino UNO Q to listen for Telegram messages
    • Forwarding timing commands to the MCU via Bridge.call()
    • Sending a confirmation reply back to Telegram

    MCU sketch: Keep the same MCU sketch from the previous Bridge section — no changes needed. Make sure it is already uploaded and running on the STM32 before proceeding.

    Python script (Arduino App Lab) — Telegram bot for traffic light control:

    /* * 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-traffic-light */ from arduino.app_utils import * import requests import time BOT_TOKEN = "YOUR_BOT_TOKEN" API_URL = f"https://api.telegram.org/bot{BOT_TOKEN}" last_update_id = 0 def send_message(chat_id, text): requests.post(f"{API_URL}/sendMessage", json={"chat_id": chat_id, "text": text}) def get_updates(): global last_update_id resp = requests.get(f"{API_URL}/getUpdates", params={"offset": last_update_id + 1, "timeout": 5}) return resp.json().get("result", []) def loop(): global last_update_id updates = get_updates() for update in updates: last_update_id = update["update_id"] msg = update.get("message", {}) chat_id = msg.get("chat", {}).get("id") text = msg.get("text", "").strip() if text.startswith("/timing "): parts = text.split() try: red_ms = int(parts[1]) yellow_ms = int(parts[2]) green_ms = int(parts[3]) Bridge.call("set_timing", red_ms, yellow_ms, green_ms) send_message(chat_id, f"Timings set: RED={red_ms}ms, YELLOW={yellow_ms}ms, GREEN={green_ms}ms") except (ValueError, IndexError): send_message(chat_id, "Usage: /timing <red_ms> <yellow_ms> <green_ms>\nExample: /timing 3000 1000 3000") elif text == "/status": Bridge.call("get_status") send_message(chat_id, "Status requested — check the MCU monitor console") else: send_message(chat_id, "Commands:\n/timing <red_ms> <yellow_ms> <green_ms> — set light durations\n/status — check current light\n\nExample: /timing 3000 1000 3000") time.sleep(1) App.run(user_loop=loop)
    • Note: Replace YOUR_BOT_TOKEN with the token obtained from @BotFather on Telegram.
    • Send /timing 3000 1000 3000 to set RED=3s, YELLOW=1s, GREEN=3s.
    • Send /status to check which light is currently on (status logged to MCU monitor).

    Detailed Instructions

    • Upload the MCU sketch: Use the Bridge MCU sketch from the previous section (upload it first if not already done).
    • Paste the Telegram script: Copy the Python code above into the Python tab of your App in Arduino App Lab.
    • Set your token: Replace YOUR_BOT_TOKEN in the script with your actual bot token.
    • Run the App: Click Run — the bot starts listening for Telegram messages immediately.
    • Test it: Send /timing 1000 500 1000 for a fast cycle, or /timing 5000 2000 5000 for a slow one.
    • Pro Tip: Add a night mode command that applies a slow blinking yellow light — great for low-traffic hours.

    App Lab Console Output

    DIYables_Apps
    Stop
    sketch.ino
    1#include "Arduino_RouterBridge.h"
    Serial Monitor
    Python
    [2026-04-29 12:00:01] Telegram: /timing 3000 1000 3000 [2026-04-29 12:00:01] Timings set: RED=3000ms, YELLOW=1000ms, GREEN=3000ms [2026-04-29 12:05:20] Telegram: /timing 1000 500 1000 [2026-04-29 12:05:20] Timings set: RED=1000ms, YELLOW=500ms, GREEN=1000ms
    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
    /timing 3000 1000 3000
    10:15 AM ✓✓
    Timings set: RED=3000ms, YELLOW=1000ms, GREEN=3000ms
    10:16 AM
    /timing 1000 500 1000
    10:17 AM ✓✓
    Timings set: RED=1000ms, YELLOW=500ms, GREEN=1000ms
    10:18 AM

    OpenClaw Integration

    OpenClaw integration for Arduino UNO Q traffic light control is coming soon.

    • Coming Soon: OpenClaw support for remotely controlling a traffic light module on Arduino UNO Q will be covered in a future update.

    Application/Project Ideas

    Here are some project ideas you can build with a traffic light module and Arduino UNO Q:

    • Pedestrian crossing simulation: Add a button — pressing it triggers a walk signal after the green phase ends
    • Telegram-controlled intersection: Set timing remotely to simulate different traffic densities
    • Time-based schedule: Use the MPU's Linux clock to switch between day timing (short cycle) and night timing (longer red/green)
    • Model train crossing: Use the traffic light to gate a model train — green when train is away, red while it passes
    • Lab status indicator: Use red/yellow/green to show a lab room's availability status

    Challenge Yourself

    Try these challenges with the traffic light module and Arduino UNO Q:

    • Easy: Change the timing so the yellow phase is only 500ms long and the green phase is 4 seconds
    • Medium: Extend the Bridge sketch to expose a force_light(int light) function that immediately switches to a specific light (0=red, 1=yellow, 2=green) from Python
    • Advanced: Build a Telegram bot that supports a /schedule day and /schedule night command, each applying a different set of timings automatically

    ※ 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!