- Define a lighting-preference label.
- Train an inspectable decision tree.
- Compare predictions against a threshold baseline.
- Separate a learned preference from an electrical safety limit.
Before you begin
Complete the LED bridge and understand a training example, feature and label.
A smart light needs a useful decision
A light that turns on below a fixed brightness threshold is useful automation, but the threshold alone is not machine learning. To build a learned system, provide examples of conditions and your preferred response. A model can then approximate that preference on a new condition.
Our input has two features: an ambient-light reading and whether someone is at the desk. The label is zero for off or one for on. These labels describe a person's chosen behavior; they are not universal facts about good lighting. A preference changes with the task, room and person, which makes the problem a good introduction to model scope.
We will use a shallow decision tree. It asks a few questions about feature values and chooses a class at a leaf. Its small size makes it easier to inspect than a complex model. The artificial training rows below demonstrate the mechanics, not a validated household lighting policy.
Prepare the computer and the LED bridge
The reference board is an Arduino Uno R3 connected by USB. Start with its built-in LED, so this output needs no external circuit. A laptop performs inference; the Arduino accepts a tiny set of commands. A Raspberry Pi can replace the laptop after its Python setup works. No cloud service is required.
Download bridge.py beside your Python script and the LED sketch. Save the sketch in a folder named led_bridge, open it in Arduino IDE, select Uno and your port, then upload. Close Serial Monitor before opening the port from Python. The kit guide supplies Windows and Raspberry Pi setup alternatives.
On macOS or Linux, create an environment with python3 -m venv .venv, activate it with source .venv/bin/activate, and install the serial library using python -m pip install pyserial. Find your port with python -m serial.tools.list_ports; replace the sample port in the code. Never install a package called bridge: that module is the downloaded file.
Commands are newline-terminated text at 115200 baud. LED_ON means illuminate the indicator; LED_OFF and STOP turn it off. The firmware acknowledges valid messages and turns the LED off after 600 milliseconds without a refreshed light command. Bridge.hold refreshes a requested action for a bounded interval and then sends STOP. An acknowledgement proves a message was parsed; looking at the board checks the physical output.
| Part | Purpose |
|---|---|
| Uno R3 and data-capable USB cable | Low-voltage output and communication |
| Computer with Python 3 | Inference and command validation |
| Built-in LED | Safe visible actuator substitute |
Collect readings with a safe divider
Add an LDR, a10kΩ resistor and a breadboard. With USB unplugged, wire Uno5V to the LDR, the other LDR lead to A0, and10kΩ from A0 to GND. This is a voltage divider: a changing sensor resistance changes the voltage at its midpoint. In this arrangement bright light usually produces a larger analog reading. Verify that direction before naming a feature dark or bright.
Add a push button between D2 and GND. The sketch's INPUT_PULLUP makes released read1 and pressed read0; treat a pressed button as a simulated occupied desk. This avoids pretending a button is a presence detector. The built-in LED stands in for a lamp. No mains circuit, relay or household wiring is part of the project.
READ returns raw A0, raw A1 and the button state. A1 is unused here and may float; do not interpret it as a temperature. Record several readings in your actual room, along with the output you want. Keep a separate group of test readings you do not train on.
| Extra component | Connection or role |
|---|---|
| LDR | Between5V and A0 |
| 10kΩ resistor | Between A0 and GND |
| Button | Between D2 and GND; simulated occupancy |
| Breadboard and jumper wires | Temporary unpowered assembly |
Fit a preference model and inspect one prediction
Install the model library with python -m pip install scikit-learn. Save this script beside bridge.py and change its serial port. The feature order is always brightness first, occupancy second. Training and prediction must use the same order and units.
from sklearn.tree import DecisionTreeClassifier, export_text
from bridge import Bridge
examples = [[80, 0], [80, 1], [200, 1], [700, 1], [900, 0], [900, 1]]
preferences = [0, 1, 1, 0, 0, 0]
model = DecisionTreeClassifier(max_depth=2, random_state=0)
model.fit(examples, preferences)
print(export_text(model, feature_names=['brightness', 'occupied']))
with Bridge('/dev/ttyACM0') as board:
brightness, unused, button = board.read()
occupied = int(button == 0)
prediction = int(model.predict([[brightness, occupied]])[0])
baseline = int(occupied == 1 and brightness < 400)
print('Model:', prediction, 'rule:', baseline)
board.hold('LED_ON' if prediction == 1 else 'LED_OFF', 1.0)fit learns tree splits from labeled examples. max_depth limits the number of decisions along a path. export_text prints the learned rules so you can inspect them. predict needs a table, hence the double brackets around one new row. The separate baseline is written directly by us and learns nothing.
Expected result: A readable decision tree, one model prediction and one rule decision appear. The LED reflects the model for a one-second demonstration, then turns off.
Decide whether learning added value
Try bright/empty, bright/occupied, dark/empty and dark/occupied conditions. If your tree and rule always make equally good decisions, keep the rule for this version. Machine learning adds collection, testing and maintenance work; a project does not improve merely because its name includes AI.
For a useful extension, collect preferences during different tasks, such as reading or watching a presentation. Decide how you will measure the task without spying on users. A model may become worthwhile when several measured factors influence the desired output and a simple rule becomes inadequate.
In a continuously running controller, smooth noisy readings and require a decision to persist before changing state. Otherwise a light near a boundary flickers. This demonstration deliberately evaluates a single observation so you can see the entire data-to-output path before building continuous control.
Important terms
- Feature
- A measured input supplied to a model.
- Label
- The desired output for a training example.
- Decision tree
- A model that routes an input through learned tests.
- Baseline
- A simple reference method used for comparison.
- Voltage divider
- Two series resistances producing a midpoint voltage.
Mini project: Compare a model with your own rule
- Measure four room conditions and write your preferred outputs before fitting.
- Collect at least20 examples across different sessions, reserving one session for testing.
- Fit the tree only on training examples and count errors on the held-out session.
- Evaluate your threshold rule on the same examples and explain which you would keep.
Common mistakes and debugging
- Swapping the feature order at prediction: keep a documented column order.
- Testing on training rows: this measures memorization more than useful generalization.
- Calling raw ADC values lux: the uncalibrated divider measures a board-dependent number, not a standard light unit.
Independent challenge
Add a second person's lighting preferences. Explain whether a single label per condition can represent both people, and design a better input or separate model.
Check your understanding: 10 questions
What makes the decision tree an ML component?
Is the occupancy button a real presence sensor?
Why print the tree?
Why compare against a threshold?
What does a raw value of700 mean?
In your own words, what does “Feature” mean?
In your own words, what does “Label” mean?
In your own words, what does “Decision tree” mean?
In your own words, what does “Baseline” mean?
In your own words, what does “Voltage divider” mean?
Quiz answers
Reveal all 10 answers after your attempt
- Its decision boundaries are fitted from labeled examples.
- No; it is a deliberate simulation of that input.
- To inspect the learned conditions and catch surprising or incorrect behavior.
- To see whether learning improves the task enough to justify its complexity.
- An ADC reading for this circuit and supply, not700lux.
- A measured input supplied to a model.
- The desired output for a training example.
- A model that routes an input through learned tests.
- A simple reference method used for comparison.
- Two series resistances producing a midpoint voltage.
Summary
A useful AI light begins with a defined preference and consistent measurements. A small decision tree makes learning visible, while a baseline reveals whether it is needed. Keep the physical output bounded while testing the model.
Continue learning
The temperature-monitoring lesson changes the task from predicting preferences to detecting unusual measurements.
- Build an Intelligent Temperature Monitoring System
- Build an Automatic Light Controller
- Training Data: Quality, Bias, Cleaning, and Data Splits
Sources and further reading
Prepared 2026-09-18. Editorial draft. Primary documentation checked; hardware, camera and audio behavior still require a physical test.