Skip to main content

Sensors

Sensors provide real-time detection of train presence, turnout positions, and other physical events on your layout. Sensor data flows from hardware devices through Firebase Firestore and is used to trigger automated effects and update signal aspects. Sensor documents are stored at layouts/{layoutId}/sensors.

How Sensors Work

Sensors are hardware inputs (typically analog or digital pins on Arduino or Pico W devices) that detect physical changes on the layout. Common sensor types include:

  • Infrared detectors -- Detect train presence in a block by breaking an IR beam.
  • Current sensors -- Detect power draw on a section of track, indicating occupancy.
  • Reed switches -- Activated by magnets mounted under rolling stock.
  • Optical sensors -- Detect passing trains using light sensors.

Sensor Data Flow

Physical sensor (IR, current, reed, etc.)
       |
       v
Hardware device (Arduino / Pico W)
       |
       v
MQTT message (or serial report)
       |
       v
DEJA.js Server
       |
       v
Firebase Firestore: layouts/{layoutId}/sensors/{sensorId}
       |
       v
Cloud app (real-time display)
  1. A hardware device reads its sensor pins and detects a state change.
  2. The device publishes the sensor state over MQTT (for WiFi devices) or reports it over serial (for USB devices).
  3. The DEJA.js server receives the sensor data and writes it to Firestore.
  4. The Cloud app displays the updated state in real time through VueFire reactive bindings.

Sensor-to-Effect Automation

The primary automation feature of sensors is their ability to trigger effects. Each sensor document can reference an effectId that identifies an effect in the layout's effects collection. When the server detects a sensor state change, it automatically updates the linked effect's state to match.

The server-side handler (apps/server/src/modules/sensors.ts) works as follows:

  1. A Firestore snapshot listener watches the sensors subcollection for modifications.
  2. When a sensor document changes, the handler reads the sensor's effectId and state fields.
  3. The handler writes the sensor's boolean state to the linked effect document at layouts/{layoutId}/effects/{effectId}.
  4. The effect's state change then triggers the normal effect execution pipeline (sending DCC commands, playing sounds, etc.).

This creates an end-to-end automation chain: a train passes a sensor, the sensor activates, the linked effect triggers (for example, turning on a crossing signal), and the effect runs until the sensor deactivates.

Example: Block Occupancy Signal

  1. Configure an IR sensor on an Arduino board connected to pin A4.
  2. Create a sensor document in Firestore with effectId pointing to a signal effect.
  3. When a train enters the block, the sensor state changes to true.
  4. The server sets the linked signal effect to active, which changes the signal aspect to red.
  5. When the train exits, the sensor returns to false, and the signal returns to green.

Sensor Data Structure

Each sensor document in Firestore has the following shape:

FieldTypeDescription
idstringUnique sensor identifier
devicestringID of the hardware device reporting this sensor
pinnumberThe analog or digital input pin on the device
statebooleanCurrent sensor state (true = activated, false = deactivated)
effectIdstringID of the linked effect to trigger on state change
typestringSensor type (IR, current, reed, etc.)
namestringDisplay name for the sensor
timestampTimestampServer timestamp of the last state change

Sensor Configuration on Hardware

Sensor pins are defined in the device firmware configuration. For Arduino-based devices, sensor pins are configured in the config.h file:

int SENSORPINS[] = {A4, A8, A9};

The device firmware reads these pins at a regular interval and publishes state changes over MQTT or serial. The pin assignments in the firmware must match the pin numbers stored in the sensor documents in Firestore.

For Pico W devices running CircuitPython, sensor pins are configured in the device's Python configuration file under the io/layouts/ directory.

Real-Time Monitoring

The Cloud app displays sensor data in real time. As sensor states change on the layout, the UI updates immediately through VueFire's reactive Firestore bindings. This makes it easy to verify that sensors are working correctly during installation and testing.

When viewing a device's details page (/layout/device/:deviceId), you can see which sensors are assigned to that device alongside its turnouts and effects.

Sensor Tips

  • Debouncing -- Hardware sensors can produce noisy signals, especially current sensors. Implement debouncing in your device firmware to avoid rapid state toggling.
  • Pin placement -- For IR sensors, position the emitter and detector on opposite sides of the track, below rail height, to reliably detect all rolling stock.
  • Testing -- Use the Cloud app's real-time sensor display to verify sensor wiring before linking effects. Watch the sensor state change as you manually trigger the sensor.
  • Multiple effects -- To trigger multiple effects from a single sensor, create a Macro effect that sequences the desired actions, then link the sensor to the macro.

Related Pages