Office Occupancy and Comfort Monitoring System


Metanate's client was developing a range of sensors for monitoring occupancy and environmental comfort in offices for real-estate management purposes. The data gathered was transmitted to a central database and used to present statistics and visualisations to facilities managers via a web portal.

The system had to be cost-effective and operate with minimal impact on the customers' network infrastructure. Some sensors needed to be installed in locations from which cables could not readily be run to the mains or Ethernet, so these were battery-powered with wireless communications. Conversely for desk clusters and meeting rooms, the requirement was for a simple and flexible method of cabling without numerous mains adapters or batteries that would need periodic replacement.

For the latter scenario a system was developed based on Local Interconnect Network (LIN) Bus, a UART-based serial bus protocol originally designed for use in motor vehicles and specified in ISO 17987. This allowed multiple desk sensors to be wired to a single mains-powered controller in a daisychain or a tree with splitters, with their power supplied by the controller. The solution followed the LIN Bus standard for UART data transmission and framing, with a proprietary PDU protocol tailored to the application.

Metanate developed firmware for the following components of the system:

  1. A desk occupancy sensor (LIN Bus slave).
  2. A controller for polling the occupancy sensors and submitting their readings over Ethernet. This also forwarded readings from the standalone wireless sensors.
  3. A battery-powered, wireless environment sensor that transmitted readings to the controller.

System Architecture

Desk Occupancy Sensor

The desk occupancy sensor was designed to be a very low-cost device suitable for bulk deployment in offices with hundreds or thousands of desks.


  • It was based on an 8-bit PIC microprocessor.
  • It was fitted with two sockets to allow LIN Bus daisychaining without additional splitters.
  • It received DC power over the LIN Bus from the mains-powered controller. While not taking readings and the LIN Bus was idle it remained in a low power-usage state.

Occupancy Detection

  • The sensor took readings at regular intervals and retained the most recent values in RAM.
  • A distance sensor was used to measure the proximity of the closest obstruction. This was sufficiently precise to detect 'jitter' while a person was seated in front of it.
  • An infrared sensor was also used, to detect whether the sensor was looking towards a person (warmer than the surrounding air) or an inanimate object such as an unoccupied chair. This was read via an ADC.
  • An algorithm was devised to use the two sensors to indicate the state of desk occupancy and a level of certainty.
  • The algorithm also reported when operation of the sensor had been impeded, for example by sticking tape over it or obstructing its view by storing items under the desk.

LIN Bus Operation

  • The desk sensor was a LIN Bus Slave, which meant it transmitted values only when requested by the controller.
  • If it detected changes in the sensor readings, it could wake up the LIN Bus when idle, and the controller would then poll it.
  • LIN Bus slaves must transmit responses within a strict time window, so sensor readings had to be pre-cached in RAM rather than read from the hardware on demand.
  • Because of the very limited RAM, LIN Bus requests needed to be decoded as UART data arrived "on the fly", ignoring those for other slaves, and responses encoded and transmitted similarly, rather than using a more conventional "communications stack" layered design with packets assembled in RAM.

Sensor Controller

A sensor controller was used to gather readings from each cluster of desk sensors, and also from nearby standalone wireless sensors, and forward them over Ethernet to a concentrator PC (developed elsewhere).


  • The controller was based around an ARM Cortex-based System-on-Chip.
  • The design was modular, with sensors and I/O devices mounted on separate plug-in boards which the firmware detected automatically.
  • The firmware used a single-threaded, event-driven design suited to the limited RAM.
  • Although mains-powered, the core firmware was shared with the battery-operated variants and engaged power-saving features.
  • DC power was provided to connected desk sensors via the LIN Bus connector.

LIN Bus Operation

  • There was sufficient RAM to allow the implementation to be layered, with larger PDUs transmitted and received as LIN First and Continuation Frames transparently to the high-level code.
  • The controller operated as a LIN Bus Master. On startup, and whenever a new sensor was plugged into the LIN Bus, it used a proprietary algorithm to identify all the sensors connected to the bus.
  • The controller was designed to be sensor-independent, so future sensor types could be handled without changes to its firmware. Each sensor declared a set of properties and the frequency at which they should be polled, and the controller polled and forwarded these without needing to know what they represented.
  • There was also provision for alerting by Slave sensors on value changes. If a sensor woke the LIN Bus, the controller would broadcast a request asking which one had woken it and what properties were to be read from it.

UHF Receiver Operation

  • The controller received readings from nearby wireless environment sensors, and potentially other devices, for forwarding via the Ethernet.
  • This used a radio transceiver operating in the 868MHz UHF band.
  • The RF packets were small and in a fixed format, functionally similar to Bluetooth advertisement beacons.

Ethernet Operation

  • The controller used a UART-to-TCP module to transmit sensor readings and its own status to the concentrator PC.
  • The concentrator PC maintained TCP connections to all the controllers installed at the site.
  • Sensor readings and other data were encoded in a simple binary format. This was encapsulated in a JSON request, in anticipation of future direct HTTPS submission to a cloud server using a conventional JSON REST API, without a concentrator PC.
  • There was no onboard storage of events. If the TCP connection to the concentrator PC was lost, monitoring would cease until it was re-established.

Wireless Environment Sensor

These were placed in locations around the building to monitor air quality and noise levels, and transmitted their readings over UHF to nearby sensor controllers.

If an environment sensor was needed in a location with access to mains power and Ethernet, this could be achieved by fitting the environment sensor plug-in board in a mains-powered sensor controller in place of the UHF transceiver.


  • The environment sensor was based around the same ARM Cortex-based System-on-Chip as the sensor controller, but without the LIN Bus hardware.
  • Instead of mains PSU circuitry it had circuitry that allowed the battery voltage to be read using the ADC. As alkaline batteries' voltage decreases throughout their life, this could be used to report when the battery would soon need replacement, without needing logic to monitor power consumption.
  • Power-saving features in the main CPU and plug-in modules were used with the aim of achieving a battery life of several years.

Sensor Operation

  • The environment sensor plug-in board could be populated with any combination of noise, temperature, humidity and CO2 sensors, as desired for a deployment.
  • The air quality sensors were read using an I2C interface.
  • The noise sensor was read via the ADC. The percentage of time spent sampling could be configured, providing a trade-off between battery usage and detection of transient noise spikes.

UHF Transmitter Operation

  • The same UHF transceiver was used as in the sensor controller, but configured as a transmitter rather than a receiver.
  • Sensor readings were transmitted as RF packets in a simple fixed format.
  • The same packet could potentially be received by multiple nearby sensor controllers. The concentrator PC was responsible for discarding duplicates where it detected them.