Learning Goals 5 min
The L03-34 smart lamp worked only on your local WiFi. Today's version works from anywhere on Earth with internet — same physical LED, but reachable from a coffee shop across town. By the end of this lesson you will:
- Add three Properties to a Cloud-controlled lamp:
powerOn(bool),brightness(int 0–255),colour(CloudColor). - Use callback functions to react instantly to dashboard changes (PWM on a real LED).
- Demonstrate "control from anywhere" — toggle the lamp from a different network than the device's WiFi.
Warm-Up 10 min
Hardware: supported Cloud-capable board + one LED (or RGB LED for the stretch). Wire LED + 220 Ω resistor to a PWM-capable pin (D3 on Nano ESP32).
Reuse the DeskMonitor pattern
This lesson is essentially the smart lamp rebuilt on top of the IoT Cloud's machinery. Three properties, three callbacks, ~50 lines of total sketch code (down from ~150 hand-rolled in L03-34).
New Concept · Multi-Property control 20 min
The Properties
| Property | Type | Permission | Effect |
|---|---|---|---|
powerOn | bool | READWRITE | Switch widget. When false, LED off regardless of brightness. |
brightness | int (0–255) | READWRITE | Slider widget. |
colour | CloudColor | READWRITE | Colour picker. Only used in stretch (RGB LED). |
uptime | int | READ | Value widget. Confirms device is alive. |
The callbacks
#include "thingProperties.h"
const int LED_PIN = 3;
void setup() {
Serial.begin(9600);
delay(1500);
pinMode(LED_PIN, OUTPUT);
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
}
void applyLed() {
int duty = powerOn ? brightness : 0;
analogWrite(LED_PIN, duty);
}
void onPowerOnChange() { applyLed(); }
void onBrightnessChange() { applyLed(); }
// onColourChange() — stretch, see §4.
void loop() {
ArduinoCloud.update();
uptime = millis() / 1000;
}Single applyLed() helper called by both callbacks. Single source of truth (powerOn + brightness). Clean.
Why callbacks, not polling
You could check the property values each loop iteration. But callbacks fire only when something changes — much more efficient, and naturally avoid redundant analogWrites.
Demonstrating "from anywhere"
Once running, the LED responds to the dashboard regardless of where the controlling phone / browser is. Test:
- Open dashboard on phone connected to home WiFi → toggle → LED responds.
- Switch phone to mobile data (turn off WiFi). Dashboard still works (it's served from arduino.cc, not from your home network). Toggle → LED still responds.
- Walk down the street. Same test. Still works.
The device is on your home WiFi. The dashboard is in the cloud. The phone talks to the cloud over mobile data. The cloud talks to the device over its home WiFi. Round trip ~1 s.
Worked Example · Lamp v3 25 min
Step 1 — set up the Thing
New Thing named "CloudLamp". Attach your board. Add the four properties (powerOn, brightness, colour, uptime) with the permissions / types from §3.
Step 2 — wire the LED
LED + 220 Ω on D3.
Step 3 — paste the sketch from §3
Upload.
Step 4 — build the dashboard
- Switch widget bound to powerOn — "Lamp".
- Slider bound to brightness (0..255) — "Brightness".
- Colour picker bound to colour (if you have an RGB LED) — "Colour".
- Value bound to uptime — "Uptime".
Step 5 — test
- Toggle the switch — LED on/off.
- Drag slider — LED dims.
- Drag colour picker — RGB LED colour changes (if hooked up).
Step 6 — go remote
Phone off WiFi (cellular data only). Open Arduino IoT Remote → CloudLamp dashboard → toggle. LED responds. You're now controlling a device on your home network from a phone that's on a different network entirely. Real cloud.
Try It Yourself 15 min
Goal: Add an onTime int property that increments each second the lamp is on. Reset to 0 when the lamp turns off.
Goal: Add a scheduleHour int property (0..23). If the current hour (from NTP — built into the Cloud library if your board supports it) equals scheduleHour, force powerOn = true.
Goal: Wire an RGB LED (3 PWM pins). Add a CloudColor property. Bind a Colour picker widget. The picker on the dashboard should drive the RGB live.
Hint
void onColourChange() {
uint8_t r, g, b;
colour.getValue().getRGB(r, g, b);
analogWrite(R_PIN, r);
analogWrite(G_PIN, g);
analogWrite(B_PIN, b);
}Mini-Challenge · "Control from a friend's phone" 10 min
- Generate a public share link for the dashboard.
- Text it to a friend / family member who's not on your network.
- Have them open the link and toggle the lamp.
- Record the latency: how long from their tap to your LED responding?
Typical: 1–3 seconds depending on the round-trip. Slower than local but workable for "am I home, who's there"-type uses.
Recap 5 min
Cloud-controlled LED = three properties (powerOn, brightness, colour) + their callbacks + a single applyLed helper. Sketch is ~50 lines (was 150+ hand-rolled in L03-34). Phone or browser anywhere on the internet can control your device on your home WiFi. Latency 1–3 s typical; not for real-time use. Tomorrow we polish sharing / permissions for multi-user demos.
- Callback-driven sketch
- Sketch reacts to events (property changes) rather than polling. Cleaner code and lower CPU.
- Cloud latency
- Round trip from one client to the device via the cloud. ~1 s typical; varies with network and load.
- Offline behaviour
- What the device does when WiFi is unavailable. Library keeps last state; physical outputs unchanged.
- Public link
- Read-only (and sometimes read-write) shareable URL to a dashboard. No login required for viewers.
- Single source of truth
- One
applyLed()helper called by every relevant callback. Avoids divergence between properties and hardware state.
Homework 5 min
- Build CloudLamp end-to-end. Screenshot.
- Demo to a friend / family member via your public link.
- Read ahead to ARD-L04-11 (Sharing a Dashboard).