Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Monitor Remote

A distributed system that lets you control your external monitor's hardware settings (brightness, volume, contrast, input source) wirelessly from your Android phone — using your Mac as a bridge that communicates with the monitor via DDC/CI protocol over HDMI/DisplayPort.

Architecture

Android Phone (Flutter Client)
        |
        | HTTP Request over Wi-Fi
        v
Mac (Dart Server using shelf package)
        |
        | Executes m1ddc command
        v
External Monitor (DDC/CI over HDMI Pin 15 & 16)

The Mac runs a lightweight Dart HTTP server. The Android app sends commands like /luminance?value=70 over the local network. The server receives them and executes m1ddc which talks to the monitor through the I2C bus on HDMI pins 15 and 16.

Project Structure

Monitor Remote/
├── server/                  # Dart backend (runs on Mac)
│   ├── bin/
│   │   └── server.dart      # HTTP server with m1ddc integration
│   └── pubspec.yaml
├── monitor_remote/          # Flutter Android client
│   └── lib/
│       ├── main.dart
│       ├── home/
│       │   └── home.dart    # UI with sliders and buttons
│       └── server/
│           └── api.dart     # HTTP client to talk to Mac server
└── doc/                     # Personal research notes (not included in repo)

How to Run

Prerequisites

  • Mac with Apple Silicon (M1/M2/M3/M4)
  • External monitor connected via HDMI/DisplayPort/USB-C
  • m1ddc installed: brew install m1ddc
  • Mac and Android phone on the same Wi-Fi network

Step 1: Find your Mac's IP address

ipconfig getifaddr en0

Step 2: Update the IP in the client

Open monitor_remote/lib/server/api.dart and replace the IP address with yours.

Step 3: Start the server on Mac

cd server
dart run bin/server.dart

Step 4: Run the Flutter app on your phone

cd monitor_remote
flutter run

Features

  • Brightness control (slider, 0-100%)
  • Volume control (slider, 0-100%)
  • Contrast control (slider, 0-100%)
  • Input source switching (HDMI 1, HDMI 2)

How It Works

The monitor's hardware settings are controlled through the DDC/CI (Display Data Channel / Command Interface) protocol. This protocol runs over the I2C bus using two dedicated pins in the HDMI cable:

  • Pin 15 (SCL) — Clock signal
  • Pin 16 (SDA) — Data signal

The Mac acts as the I2C Master and the monitor is the I2C Slave. When you move a slider on your phone, the flow is:

Phone slider → HTTP request → Mac server → m1ddc command → I2C bus → Monitor adjusts

Design Decisions

I evaluated three approaches for this project:

  1. Method Channel Approach — Flutter UI talks to native Swift/IOKit code directly. Requires heavy low-level platform code.

  2. Backend API Approach (chosen) — Mac runs a Dart HTTP server, Android phone sends commands over Wi-Fi. Creates a distributed client-server system.

  3. Process.run Approach — Local macOS Flutter app executes terminal commands. Requires disabling the App Sandbox.

I chose the Backend API approach because it allows wireless control from any device on the network and demonstrates client-server architecture, HTTP API design, and hardware communication — all in one project.

Tech Stack

  • Client: Flutter (Dart), http package
  • Server: Dart, shelf package
  • Hardware Communication: m1ddc (DDC/CI over I2C)

Learning Highlights

Key concepts I researched and applied in this project:

  • What m1ddc is and how it works
  • HDMI pin layout and what each pin carries
  • I2C protocol (Master/Slave communication)
  • DDC/CI protocol and how it layers on top of I2C
  • The protocol stack: DDC/CI → I2C → Physical Pins
  • Comparison of all three architectural approaches

About

Control your external monitor's brightness, volume & contrast wirelessly from your phone — using DDC/CI protocol over Wi-Fi with a Dart server + Flutter client

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages