Emulated sensors

The BenchPod can play the sensors your firmware talks to: I2C, SPI and UART sensors on its logic-analyzer channels, and analog sensors on its analog outputs. What a sensor does is a short YAML file, a sensor definition. Take one from the public library, change it, or write your own, then run it on your pod from the Sensors tab and change its readings while your firmware runs.

The Simulate tab

Open your pod on the BenchPod page and pick Sensors. It has three parts:

  • Sensors: your organization's sensors (My sensors) and the public sensor library. Start a new sensor from a template, upload a file, download one or all of them as a zip.
  • Stimuli: files that change a sensor's readings over time and inject faults.
  • On the pod: every sensor that runs now, with its bus counters, readings and faults.

The pull resistors of LA1-LA8 are on the same tab. I2C needs pull-ups on SDA and SCL, so put the bus on LA1-LA6; starting an I2C sensor switches them on.

The library

The library holds ready-made sensors such as the BMP280, BME280, SHT4x, MPU-6050 and a GPS receiver. Open one to see its file and preview it, or run it as is. Duplicate copies it to My sensors, where you can change it. The library is versioned: your organization uses the version the server pins unless an owner or admin picks the latest release or a specific version in the library's version menu.

Writing a definition

A definition names the sensor, the params you set (a temperature, a pressure) and what the DUT reads for them: registers for I2C and SPI, messages and answers for UART, an output value for analog. The format is documented in format.md. A small I2C sensor:

format: 1
kind: i2c
name: my_i2c_sensor
label: "My I2C sensor: temperature"

params:
  - { key: temperature_c, unit: C, min: -40, max: 125, default: 25, label: Temperature }

i2c:
  address: 0x48
  alt_addresses: [0x49]

let:
  - raw: "sat_s16(temperature_c * 100)"

registers:
  - { at: 0x00, s16be: "raw", name: TEMP }
  - { at: 0x0F, u8: 0xA5, name: WHO_AM_I, writable: false }

The editor checks the file as you type with the same compiler the pod runs, so an error shows with its line (click it to jump there). Next to it a preview shows what the DUT would see for the values on the sliders:

I2C, SPIThe 256-byte register image. Registers that follow the params are highlighted.
UARTThe next message the sensor sends, and its answer to a request you type.
AnalogThe output value and its curve over a param's range.

Files are YAML; JSON with the same structure works too. A definition is at most 32 KB.

Running a sensor

Under the editor, Run on the pod takes the pins (filled in from the Pins pane's profile when it names them), the I2C address or the UART baud rate, and an instance name. Start on the pod sends the definition and starts it. Then:

  • Move a slider and the DUT reads the new value on its next read or message.
  • Inject a fault (no response, stuck, offset, a corrupt register, garbage on a UART) for a while or until you clear it.
  • Read the registers back as the DUT sees them now, its own writes included.

Up to four I2C sensors, one SPI sensor, one UART sensor and two analog sensors (one on the voltage output, one on the 4-20 mA output) run at the same time. An instance name is 1 to 16 characters of a-z, 0-9 and _. The pod keeps nothing: a sensor is gone after Stop, a reboot or a firmware update. While an I2C, SPI or UART sensor runs, the closed DAC loop and deep DAC replay are not available; after Stop they come back once the pod switches its FPGA image back: the web app does that when you stop the last sensor, the SDK and the web app's Generator when you use them, and with the CLI you run benchpod sensor image loop.

What the pod plays today: a UART sensor is 8N1; the SPI target has no data-ready pin; one sensor with a FIFO runs at a time; an I2C sensor's conversion and command times are at most 65.535 ms (longer ones are cut); a fault that holds the I2C bus low lasts at most 1 s; an analog sensor with excitation: adc is not supported yet.

Stimuli and faults over time

A stimulus plays values for the running sensors' params over time, built from segments: hold, step, ramp, sine, saw, pulse, noise, data points and repeat. Faults switch on at a time for a while. The stimulus editor draws the signals and the fault windows as you edit; Start on the pod plays it. With several sensors running, name a signal instance.param.

format: 1
kind: stimulus
name: warm_afternoon
signals:
  temperature_c:
    - { shape: hold, value: 22, duration_s: 5 }
    - { shape: ramp, end: 35, duration_s: 30 }
    - { shape: sine, offset: 35, amplitude: 1.5, period_s: 10, duration_s: 20 }
faults:
  - { at_s: 40, duration_s: 5, type: stuck }

Firmware

Running your own sensors needs newer pod firmware. On older firmware the tab says so and offers the update; the library, the editor and the preview work either way. See Updating the firmware.