Primitives

Primitive blocks provide direct access to device hardware. Use these blocks to read sensors, control digital and analog outputs, handle button inputs, and create custom hardware interactions.

Understanding Registers

Primitives use register indices instead of physical pin numbers. The register system organizes pins into categories (digital input/output, analog input/output) and assigns each an index. View your device's pin-to-register mapping in the Registers tab on the Uniot Platform.

Return Values in Primitives

Primitives can either return a value or perform an action without returning meaningful data. The visual blocks for default primitives (like analog read, digital read, etc.) are predefined and correctly reflect whether they return values or not.

For user-defined primitives, the visual editor cannot automatically determine whether a primitive should return a value or just perform an action. Since primitives are C++ functions called by the UniotLisp Interpreter, every function must return something—even action-only primitives return a boolean value. Therefore, user primitive blocks are rendered with a return value by default. If your primitive doesn't need to return a meaningful value, you can disable the return value field in the block configuration.

analog read

Reads an analog value from the specified register. Use this for sensors that output variable voltage levels.

Parameters:

  • Register (Number): The analog input register index

Returns:

  • Number: Value between 0-1023 (10-bit ADC resolution)

Example:

Check light level and push event if it's too low

analog write

Writes an analog (PWM) value to the specified register. Use this to control LED brightness, motor speed, or other variable outputs.

Parameters:

  • Register (Number): The analog output register index

  • Value (Number): Value between 0-1023 (PWM duty cycle)

Example:

Receive brightness value from dashboard and set LED accordingly

digital read

Reads the digital state from the specified register (HIGH or LOW).

Parameters:

  • Register (Number): The digital input register index

Returns:

  • Boolean: #t for HIGH, () for LOW

Example:

Read switch state and push event when changed

digital write

Sets a digital register to HIGH or LOW. Use this to control LEDs, relays, or other on/off outputs.

Parameters:

  • Register (Number): The digital output register index

  • Value (Boolean): #t for HIGH, () for LOW

Example:

Check for event and control LED state

button clicked

Detects button press events on the specified register. Returns true when a press-and-release cycle is detected, then resets until the next click.

Parameters:

  • Register (Number): The digital input register index

Returns:

  • Boolean: #t if clicked since last check, () otherwise

Example:

Toggle LED state on button click

user primitive (template)

Creates a custom primitive definition that you'll implement in your firmware. Click the gear icon to configure parameters and return type.

Configuration:

  • Primitive Name: Unique identifier for your custom primitive

  • Parameters: Define input values the primitive accepts

  • Return Type: Configure what type of value it returns (boolean by default, or none for action-only primitives)

Note on return values: Since primitives are C++ functions called by the UniotLisp Interpreter, every function must return a value. If your primitive performs an action without needing to return a meaningful value, it should still return a boolean. The visual block is rendered with a return value by default. If you don't need to use the return value, you have to disable the corresponding field in the block configuration.

Use cases: Creating custom sensor drivers, protocol handlers, complex hardware control, or specialized operations not covered by standard primitives.

user primitive (autogenerated)

Calls a custom primitive already defined in your device firmware. These blocks are automatically generated based on primitives registered in your firmware code.

Parameters:

  • Arguments: Values matching the primitive's defined parameters

Returns:

  • Type varies: Depends on how the primitive was defined in firmware

Note on return values: Since the visual editor cannot determine whether a user primitive is intended to return a value or just perform an action, autogenerated blocks are rendered with a return value by default. This is because all C++ functions must return something—even action-only primitives return a boolean value. If your primitive doesn't need to return a meaningful value, you have to disable the return value field in the block configuration.

Example:

Custom LED strip control

Last updated