ESP8266 Magic Light Cup Module Project

This project utilizes the ESP8266 microcontroller to interface with a Magic Light Cup module, which is essentially a light-sensitive sensor. The module detects ambient light intensity and outputs a corresponding digital signal based on the light level detected.

How It Works

The magic light cup (KY-027) is a teaching module sold in pairs. Each board carries a tilt switch and an LED, and the trick is in how they are cross-wired: tilting one cup "pours" light into the other. It is a demonstration of reading an input on one module and driving a PWM output on another.

Each module exposes three pins — a signal input for the LED, a signal output from the tilt switch, and power. The illusion of liquid light comes from PWM fading rather than simple on/off switching: as one LED dims, the other brightens in step, so brightness appears to flow between them.

Because the effect depends on smooth brightness control, the LED pins must be on PWM-capable outputs. On the ESP8266 (NodeMCU) those are any GPIO via software PWM.

The tilt switch inside is the same mercury or ball type used in the KY-017, so it bounces as it settles and benefits from the same debouncing treatment.

Components Needed

  • ESP8266 (NodeMCU)
  • Magic Light Cup Module module
  • ESP8266 (NodeMCU)
  • USB cable for programming and power
  • ESP8266 (NodeMCU)

Wiring to the ESP8266 (NodeMCU)

Each cup needs two signal connections plus power. Put both LED pins on PWM-capable outputs — on this board any GPIO via software PWM — and the two tilt outputs on any digital pins. All four share the same 3.3 V and GND rails.

The LEDs on these carriers include series resistors, so they connect directly to a GPIO. Current draw is modest, well within what a pin can source.

Mount the two modules so they can be tilted independently; the effect only reads properly when each can be rotated on its own.

ConnectionESP8266 (NodeMCU) pinFunction
Cup A — LEDD5PWM brightness for the first cup
Cup A — tiltD5Tilt state of the first cup
Cup B — LEDD6PWM brightness for the second cup
Cup B — tiltD6Tilt state of the second cup
VCC / GND3V3 / GNDShared supply for both modules

Build and Upload

After uploading the code, open the Serial Monitor(baud rate: 9600).

The Serial Monitor will display the state of the Magic Light Cup module and whether light is detected based on the predefined threshold (threshold value in the code).

Adjust the threshold value in the code as necessary to adapt to different light conditions.

Example Code

Pouring light between two cups by cross-fading their LEDs on tilt. Upload it with the board set to ESP8266 (NodeMCU) and open the Serial Monitor at 115200 baud.

Pouring light between two cups by cross-fading their LEDs on tilt
const int LED_A  = 5;
const int TILT_A = 5;
const int LED_B  = 6;
const int TILT_B = 6;

int level = 128;                 // 0 = all in B, 255 = all in A
const int STEP = 4;

void setup() {
  Serial.begin(115200);
  pinMode(LED_A, OUTPUT);
  pinMode(LED_B, OUTPUT);
  pinMode(TILT_A, INPUT_PULLUP);
  pinMode(TILT_B, INPUT_PULLUP);
}

void loop() {
  // Tilting a cup pours its light towards the other
  if (digitalRead(TILT_A) == LOW && level > 0)   level -= STEP;
  if (digitalRead(TILT_B) == LOW && level < 255) level += STEP;

  level = constrain(level, 0, 255);
  analogWrite(LED_A, level);
  analogWrite(LED_B, 255 - level);

  delay(20);                     // sets how fast the light "flows"
}

Applications

A magic light cup module turns up in a wide range of projects. These are the uses where it is the right choice rather than a compromise:

  • Teaching PWM and analog output in a visually obvious way
  • Interactive art installations and desk toys
  • Demonstrating tilt sensing without needing an accelerometer
  • Turn-taking indicators in two-player games
  • Introducing the idea of coupled inputs and outputs to beginners

Working with the ESP8266 (NodeMCU)

The ESP8266 (NodeMCU) is built around the ESP8266 and runs on 3.3 V logic with roughly 80 KB usable of SRAM and 4 MB on most NodeMCU boards of program flash. These details change how this circuit is wired and what the sketch can do, so they are worth stating plainly before you build.

The ESP8266 is a 3.3 V part and is not 5 V tolerant — feeding a 5 V sensor output straight into a GPIO can damage the chip. Use a divider or level shifter.

There is only one ADC channel, so reading several analog sensors needs an external multiplexer such as a CD4051 or an ADS1115.

D3 (GPIO0), D4 (GPIO2) and D8 (GPIO15) are strapping pins sampled at boot; holding them at the wrong level stops the board starting.

Built-in WiFi means the same sketch can publish readings to a dashboard without extra hardware.

ESP8266 (NodeMCU) characteristicValueWhy it matters here
Logic voltage3.3 VSensor outputs above this level need a divider or level shifter
ADC resolution10-bit (0–1023)Sets how finely an analog reading can be resolved
Analog inputsa single analog channel, A0Determines how many analog sensors can share the board
PWM outputsany GPIO via software PWMNeeded for brightness, speed and tone control
I²C pinsD2 (SDA, GPIO4) and D1 (SCL, GPIO5) by defaultFixed by hardware — wiring copied from another board may not match
Interrupt pinsany GPIO except D0 (GPIO16)Required for counting fast or asynchronous events
Serialone hardware UART plus a transmit-only second portMonitor runs at 115200 baud by default

Troubleshooting

Most problems with this module fall into a handful of categories. Work through these before suspecting the part itself:

  • The LEDs only switch on and off instead of fading — they are on non-PWM pins. Move them to PWM-capable outputs.
  • Light pours in only one direction — one tilt switch is mounted at the wrong angle or its pull-up is missing.
  • The fade is jerky — reduce STEP and shorten the delay so brightness changes in finer increments.
  • Both LEDs stay lit at half brightness — neither tilt switch is being read as LOW; check INPUT_PULLUP is set.
  • The sketch compiles but the board resets or behaves erratically — a 5 V module output is being driven into a 3.3 V pin. Measure the signal before connecting it.
  • Readings differ from an Arduino tutorial for the same part — the 10-bit ADC returns 0–1023, not 0–1023, so any constant copied from an Uno example needs rescaling.

Taking It Further on the ESP8266 (NodeMCU)

Once the basic reading works, where you go next depends very much on which board you are using. These are the directions that suit the ESP8266 (NodeMCU) specifically:

The obvious extension on an ESP8266 is to stop printing to Serial and publish instead. A few lines using ESP8266WiFi and an HTTP client will push each reading to a dashboard such as ThingSpeak, or to an MQTT broker for home automation.

Running an onboard web server turns the board into its own display: serve a small HTML page that fetches the latest reading over AJAX, and any phone on the network becomes the instrument panel.

For battery operation, deep sleep is essential — the ESP8266 draws around 70 mA with WiFi active but under 20 µA asleep. Wire D0 (GPIO16) to RST so the board can wake itself, take a reading, publish and sleep again.

Notes and Practical Limits

Human brightness perception is logarithmic, so a linear PWM ramp looks like it changes quickly at the dim end and barely at all when bright. Squaring the level before writing it produces a visually smoother pour.

On ESP boards analogWrite() maps to the LEDC peripheral and the default resolution may differ from the 0–255 Arduino range; check what your core expects.