# 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](https://docs.uniot.io/general-concepts/primitives#registers) 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

<div align="left"><figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-b8708e29200dd03c1c8b5dc6dcf2b2a79d6bba87%2Fprimitives_analog_read.png?alt=media" alt=""><figcaption></figcaption></figure></div>

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:**

<figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-20a19a20d5f9215fa15d0222c9a6a710d9e46e5b%2Fprimitives_analog_read_example.png?alt=media" alt=""><figcaption><p>Check light level and push event if it's too low</p></figcaption></figure>

## analog write

<div align="left"><figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-cfaea193604a634ac5aed6556ea7496cd870f8c3%2Fprimitives_analog_write.png?alt=media" alt=""><figcaption></figcaption></figure></div>

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:**

<figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-14928114f5f9689a9be8e6cb4cd471a752706938%2Fprimitives_analog_write_example.png?alt=media" alt=""><figcaption><p>Receive brightness value from dashboard and set LED accordingly</p></figcaption></figure>

## digital read

<div align="left"><figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-af6086e03d57a4c35ad4b038dc7871732700103b%2Fprimitives_digital_read.png?alt=media" alt=""><figcaption></figcaption></figure></div>

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:**

<figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-798421458a15813609f4c4269940f5f58a0ea6de%2Fprimitives_digital_read_example.png?alt=media" alt=""><figcaption><p>Read switch state and push event when changed</p></figcaption></figure>

## digital write

<div align="left"><figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-dbf16a33ea3e71c75f2cd449a63ea189673bfd39%2Fprimitives_digital_write.png?alt=media" alt=""><figcaption></figcaption></figure></div>

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:**

<figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-6658a6734bd819b56d19c79db2c97051b4ddbc27%2Fprimitives_digital_write_example.png?alt=media" alt=""><figcaption><p>Check for event and control LED state</p></figcaption></figure>

## button clicked

<div align="left"><figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-1c34bf830abfef5fbb5285f405b0121b47a0ce71%2Fprimitives_button_clicked.png?alt=media" alt=""><figcaption></figcaption></figure></div>

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:**

<figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-09c7db9604b4016f22e9ae4398ea0af1b18512a8%2Fprimitives_button_clicked_example.png?alt=media" alt=""><figcaption><p>Toggle LED state on button click</p></figcaption></figure>

## user primitive (template)

<div align="left"><figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-f3abfc9f1bc8dea491dece3086d0866bbc55ba92%2Fprimitives_user_primitive.png?alt=media" alt=""><figcaption></figcaption></figure></div>

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)

{% hint style="info" %}
**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.
{% endhint %}

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

## user primitive (autogenerated)

<div align="left"><figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-b830e16a1af4e9a54569b0afc159176c65f56d1d%2Fprimitives_user_primitive_auto.png?alt=media" alt=""><figcaption></figcaption></figure></div>

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

{% hint style="info" %}
**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.
{% endhint %}

**Example:**

<figure><img src="https://1776027180-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FsSE1iwGRAGqUrb5YXfFa%2Fuploads%2Fgit-blob-b9dabc0e778db6773d24ac176fcc4289c9d2d9a2%2Fprimitives_user_primitive_auto_example.png?alt=media" alt=""><figcaption><p>Custom LED strip control</p></figcaption></figure>
