This series looks at DALI input devices. Everything worth saying about luminaires and control gear has been said; about sensors and push-button panels, very little — even though they usually decide whether an installation behaves sensibly. Part I covered push buttons. This part covers light sensors.
What a light sensor actually sends
Compared to a push button, a light sensor is simple. IEC 62386-304 gives it a single event: an illuminance level report. The event filter has one usable bit, which turns that report on or off, and that is the end of your options.
Everything interesting happens inside the report. The sensor does not put "420 lx" on the bus — it sends a number from its own scale. The standard is blunt about this: the reading is a relative value and does not represent lux.
Why 200 isn't always 200
Start with the part that trips people up. A light sensor event always carries 10 bits — no more will fit in a 24-bit frame. The standard normalises this: at resolutions up to 10 bits the reading is scaled into 10-bit form, and above that the 10 most significant bits go on the bus.
The consequence is convenient: the number in the report always falls between 0 and 1023, and it always means a percentage of that sensor's range. A sensor reporting 512 sees roughly half its range, whether it works internally on 10, 14 or 16 bits. The standard achieves this by msb-aligning the reading and padding the rest with a repeated pattern, precisely so a controller can always do the same arithmetic.
So where do the discrepancies between sensors come from? From the measurement range. The standard leaves that to the manufacturer, and the differences are large — one sensor measures up to 2,000 lx, another to 30,000, a third to 100,000.
Three sensors looking at the same desk lit to 500 lx:
| Sensor | Measurement range | Reports |
|---|---|---|
| A | 0–2,000 lx | ~256 |
| B | 0–30,000 lx | ~17 |
| C | 0–100,000 lx | ~5 |
All three work correctly, all three see the same light, and the readings differ fiftyfold. Nothing is broken — each is simply reporting a percentage of something different.
The arithmetic also runs backwards, which is where it becomes useful. A sensor with a 100,000 lx range reports 100: a hundred out of 1023 is just under 10% of the range, so roughly 10,000 lx at the sensor surface. Without knowing the range, that same 100 means nothing at all.
Resolution therefore doesn't change what the number means, only its precision — how many steps the sensor divides its range into. It does matter inside the device: the default minimum hysteresis band is specified separately for each resolution and works out to roughly one percent of full scale.
It's worth separating two routes to a reading, because they differ in precision. The event the sensor sends on its own is always clipped to those ten bits. But when a controller queries the sensor directly — QUERY INPUT VALUE, then further bytes via QUERY INPUT VALUE LATCH — it gets the full value at the device's resolution, several bytes if need be. Ten bits is plenty for daylight harvesting, so in practice you work with events.
What the controller does with that number
Here comes a layer the standard says nothing about, because it isn't its business — and it can overturn everything above.
An application controller may do as it likes with that ten-bit number. A common approach is to stretch it back out to the resolution the sensor declares: 512 arrives, the controller sees the device runs on 16 bits, and stores ~32,000 internally. With a ten-bit sensor, that same 512 stays 512.
The effect is that two sensors with identical ranges, looking at the same light and sending exactly the same number on the bus, look completely different inside the controller — because their resolutions differ. The standard did everything it could to make the reading resolution-independent, and the layer above undoes it.
This happens even between units of the same model. There have been production batches where a firmware update raised the sensor's resolution. You buy two identical sensors, same part number, same datasheet — and one declares 10 bits, the other 14, and the controller stretches their readings onto two different scales.
You will find the range in the datasheet, and that is the number you actually need. Just check what it refers to: for the DALI MSensor G3 PIR 5DPI, Tridonic gives 0.5–2,000 lx at the sensor head, which corresponds to roughly 3–6,300 lx on the lit surface. The sensor measures what reaches it, not what you see on the desk.
When the sensor sends a report
A report goes out for two independent reasons:
- the reading left the hysteresis band — above
hysteresisBandHighor belowhysteresisBandLow, tReporthas elapsed since the previous report, regardless of what the sensor sees.
The band width is max(hysteresis% × inputValue, hysteresisMin). The band is asymmetric — it spans upward or downward depending on the direction of the last change — and it is recalculated after every event.
That asymmetry has a concrete consequence. While the signal is rising, the upper bound sits exactly on the last reading, so every further rise fires an event — in that direction the band gives no protection at all. Only a reversal buys you margin: after a rise, the reading has to fall by the full band width before anything fires. And vice versa.
| Parameter | What it does | Default | Range |
|---|---|---|---|
hysteresis | band width as % of the reading | 5% | 0–25% |
hysteresisMin | lower limit on band width | depends on resolution | 0–255 |
tReport | cyclic report interval | 30 s | 1 s – 4 min 15 s |
tDeadtime | minimum gap between events | 1.5 s | 0 – 12.75 s |
You set them with SET REPORT TIMER (0x30), SET HYSTERESIS (0x31), SET DEADTIME TIMER (0x32) and SET HYSTERESIS MIN (0x33), and read them back with the matching QUERY commands (0x3C–0x3F). Writing zero to hysteresis disables change-triggered events and leaves only cyclic reports. Zero in tReport disables the cyclic report.
Two schools of daylight control
This is a decision worth making deliberately, because both routes give you a working installation with a completely different character.

First: cyclic reports only. You disable hysteresis triggering and base the control loop on tReport alone. You set the pace directly with that timer — it can be fast if you shorten the interval — but 20–40 seconds is what gets used in practice. It runs reliably and predictably.
And in most buildings that is exactly what you want. Daylight control doesn't need to keep up with every passing cloud, and nobody enjoys a disco overhead. Slower, less precise tracking of the sun is comfortable for the occupant and predictable for the bus.
Second: hysteresis. The sensor responds to actual changes, so the loop follows daylight more closely and holds the level more accurately. In exchange it demands a well-written control loop in the application controller. The sensor is measuring light from the very luminaires it regulates, so every correction changes what the sensor sees — implement that carelessly and the system starts to oscillate.
On this route tDeadtime stops being a secondary parameter. It is what keeps hysteresis triggering in check: until it expires, the instance sends no further events. Without it, a burst of rapid changes in the reading becomes a burst of frames. One more dependency that is easy to trip over: if you set tReport shorter than tDeadtime, tDeadtime wins.
What to watch out for
One room dims correctly, the next sits at 100%

Someone configures zones across a building, copies the settings, and assumes that if every sensor targets the same value, the result will be the same everywhere. But if the sensors differ in measurement range — or, with a controller that stretches the reading, in resolution — it won't be.
The symptom is that one zone dims more or less sensibly while the next sits at 100%, or drops straight to its minimum level. Nothing oscillates: the loop drives to its limit and stays there, because from the start it sees "far too bright" or "far too dark". It is easy to mistake for a failed sensor, since the luminaire runs at full output and responds to nothing.
How do you diagnose it? Compare the raw readings on the bus at a similar time of day, under similar light. If one sensor shows 10 and another 200, the first sees 1% of its range and the second 20% of its — so check the datasheets to see whether those ranges are the same at all. Usually they aren't. If the two numbers on the bus are close and the zones still behave differently, the discrepancy is being created in the controller — then compare the resolutions the two devices declare (QUERY RESOLUTION).
How do you fix it? Determine the target value separately for each sensor, based on what that sensor itself reports under the intended conditions.
System vendors treat this the same way. In its DALI Professional 3 guide, Inventronics requires that sensors working in one control loop be of the same type, mounted similarly, and return approximately the same individual calibration value — in their own example, two sensors in one zone give 1.4% and 5.9%. zencontrol has you set the target with a calibrated lux meter, meaning a physical measurement at each sensor. Neither assumes a number carried over from one sensor keeps its meaning on another.
A stray reflection throws the control loop

Light sensors ship with hysteresis enabled. On top of cyclic reports they therefore send events asynchronously, at any moment the change exceeds the band.
With a sensitive sensor and a narrow band, a brief reflection is enough to push the reading out of the band. Light bouncing off something mirrored — a window, a worktop, the face of someone's watch — sweeps across the sensor for a second, and that alone can momentarily flood it. The sensor reports a change, the controller acts, and the level in the zone jumps with no connection to how much daylight there actually is.
The narrower the band and the more sensitive the sensor, the more of these spurious events you get. Across several sensors on one line it adds up to noticeably more churn: unnecessary bus traffic and brightness changes the occupant notices and nothing explains.
Hysteresis works the opposite way to what the name suggests. It is not a smoothing filter — it is a trigger. A narrower band means more events, not fewer.
How do you spot it? The bus shows irregular reports from individual sensors, falling outside the rhythm of the cyclic report, while brightness in the zone shifts in steps with no visible external cause.
How do you fix it? Widen the band (hysteresis and hysteresisMin), lengthen tReport, and set tDeadtime so it cuts the bursts short. If the application doesn't need fast regulation, the simplest answer is to switch to the first school and stay with cyclic reports alone.
Both situations share a root: a number from a light sensor means nothing without knowing the device that sent it, and sensor configuration cannot be copied between zones as freely as groups or scenes.
Both are visible directly on the bus. The Monitor module in Pilo One shows how much traffic each sensor generates and whether its reports keep to the timer's rhythm or fall outside it — that is, whether your hysteresis settings are making the line busy for no reason. Pilo Agent reads the instance configuration and checks whether, at those values of hysteresis, tReport and tDeadtime, the control loop has any chance of running stably. Where it doesn't, it proposes specific settings and, once you approve them, writes them to the devices itself.
Next in the series: occupancy sensors (IEC 62386-303).


