What you will learn
  • 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.

PartPurpose
Uno R3 and data-capable USB cableLow-voltage output and communication
Computer with Python 3Inference and command validation
Built-in LEDSafe 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 componentConnection or role
LDRBetween5V and A0
10kΩ resistorBetween A0 and GND
ButtonBetween D2 and GND; simulated occupancy
Breadboard and jumper wiresTemporary 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.

Python
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

  1. Measure four room conditions and write your preferred outputs before fitting.
  2. Collect at least20 examples across different sessions, reserving one session for testing.
  3. Fit the tree only on training examples and count errors on the held-out session.
  4. 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

  1. What makes the decision tree an ML component?

  2. Is the occupancy button a real presence sensor?

  3. Why print the tree?

  4. Why compare against a threshold?

  5. What does a raw value of700 mean?

  6. In your own words, what does “Feature” mean?

  7. In your own words, what does “Label” mean?

  8. In your own words, what does “Decision tree” mean?

  9. In your own words, what does “Baseline” mean?

  10. In your own words, what does “Voltage divider” mean?

Quiz answers

Reveal all 10 answers after your attempt
  1. Its decision boundaries are fitted from labeled examples.
  2. No; it is a deliberate simulation of that input.
  3. To inspect the learned conditions and catch surprising or incorrect behavior.
  4. To see whether learning improves the task enough to justify its complexity.
  5. An ADC reading for this circuit and supply, not700lux.
  6. A measured input supplied to a model.
  7. The desired output for a training example.
  8. A model that routes an input through learned tests.
  9. A simple reference method used for comparison.
  10. 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.

Choose a connected learning path

Sources and further reading

Prepared 2026-09-18. Editorial draft. Primary documentation checked; hardware, camera and audio behavior still require a physical test.